aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/extension.c21
-rw-r--r--src/backend/commands/operatorcmds.c27
-rw-r--r--src/backend/commands/typecmds.c69
3 files changed, 84 insertions, 33 deletions
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 39c9411367a..a4ab97cf5c4 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -821,9 +821,21 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
GUC_ACTION_SAVE, true, 0, false);
/*
- * Set up the search path to contain the target schema, then the schemas
- * of any prerequisite extensions, and nothing else. In particular this
- * makes the target schema be the default creation target namespace.
+ * Similarly disable check_function_bodies, to ensure that SQL functions
+ * won't be parsed during creation.
+ */
+ if (check_function_bodies)
+ (void) set_config_option("check_function_bodies", "off",
+ PGC_USERSET, PGC_S_SESSION,
+ GUC_ACTION_SAVE, true, 0, false);
+
+ /*
+ * Set up the search path to have the target schema first, making it be
+ * the default creation target namespace. Then add the schemas of any
+ * prerequisite extensions, unless they are in pg_catalog which would be
+ * searched anyway. (Listing pg_catalog explicitly in a non-first
+ * position would be bad for security.) Finally add pg_temp to ensure
+ * that temp objects can't take precedence over others.
*
* Note: it might look tempting to use PushOverrideSearchPath for this,
* but we cannot do that. We have to actually set the search_path GUC in
@@ -837,9 +849,10 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
Oid reqschema = lfirst_oid(lc);
char *reqname = get_namespace_name(reqschema);
- if (reqname)
+ if (reqname && strcmp(reqname, "pg_catalog") != 0)
appendStringInfo(&pathbuf, ", %s", quote_identifier(reqname));
}
+ appendStringInfoString(&pathbuf, ", pg_temp");
(void) set_config_option("search_path", pathbuf.data,
PGC_USERSET, PGC_S_SESSION,
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index 2257c562567..3a19db583b9 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -249,6 +249,8 @@ DefineOperator(List *names, List *parameters)
*/
if (joinName)
{
+ Oid joinOid2;
+
typeId[0] = INTERNALOID; /* PlannerInfo */
typeId[1] = OIDOID; /* operator OID */
typeId[2] = INTERNALOID; /* args list */
@@ -257,15 +259,26 @@ DefineOperator(List *names, List *parameters)
/*
* As of Postgres 8.4, the preferred signature for join estimators has
- * 5 arguments, but we still allow the old 4-argument form. Try the
- * preferred form first.
+ * 5 arguments, but we still allow the old 4-argument form. Whine
+ * about ambiguity if both forms exist.
*/
joinOid = LookupFuncName(joinName, 5, typeId, true);
- if (!OidIsValid(joinOid))
- joinOid = LookupFuncName(joinName, 4, typeId, true);
- /* If not found, reference the 5-argument signature in error msg */
- if (!OidIsValid(joinOid))
- joinOid = LookupFuncName(joinName, 5, typeId, false);
+ joinOid2 = LookupFuncName(joinName, 4, typeId, true);
+ if (OidIsValid(joinOid))
+ {
+ if (OidIsValid(joinOid2))
+ ereport(ERROR,
+ (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
+ errmsg("join estimator function %s has multiple matches",
+ NameListToString(joinName))));
+ }
+ else
+ {
+ joinOid = joinOid2;
+ /* If not found, reference the 5-argument signature in error msg */
+ if (!OidIsValid(joinOid))
+ joinOid = LookupFuncName(joinName, 5, typeId, false);
+ }
/* estimators must return float8 */
if (get_func_rettype(joinOid) != FLOAT8OID)
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index cedd42433d6..b5875405f0c 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1642,7 +1642,11 @@ static Oid
findTypeInputFunction(List *procname, Oid typeOid)
{
Oid argList[3];
+ int nmatches = 0;
Oid procOid;
+ Oid procOid2;
+ Oid procOid3;
+ Oid procOid4;
/*
* Input functions can take a single argument of type CSTRING, or three
@@ -1650,32 +1654,45 @@ findTypeInputFunction(List *procname, Oid typeOid)
*
* For backwards compatibility we allow OPAQUE in place of CSTRING; if we
* see this, we issue a warning and fix up the pg_proc entry.
+ *
+ * Whine about ambiguity if multiple forms exist.
*/
argList[0] = CSTRINGOID;
-
- procOid = LookupFuncName(procname, 1, argList, true);
- if (OidIsValid(procOid))
- return procOid;
-
argList[1] = OIDOID;
argList[2] = INT4OID;
- procOid = LookupFuncName(procname, 3, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, true);
if (OidIsValid(procOid))
- return procOid;
+ nmatches++;
+ procOid2 = LookupFuncName(procname, 3, argList, true);
+ if (OidIsValid(procOid2))
+ nmatches++;
- /* No luck, try it with OPAQUE */
argList[0] = OPAQUEOID;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid3 = LookupFuncName(procname, 1, argList, true);
+ if (OidIsValid(procOid3))
+ nmatches++;
+ procOid4 = LookupFuncName(procname, 3, argList, true);
+ if (OidIsValid(procOid4))
+ nmatches++;
- if (!OidIsValid(procOid))
- {
- argList[1] = OIDOID;
- argList[2] = INT4OID;
+ if (nmatches > 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
+ errmsg("type input function %s has multiple matches",
+ NameListToString(procname))));
- procOid = LookupFuncName(procname, 3, argList, true);
- }
+ if (OidIsValid(procOid))
+ return procOid;
+ if (OidIsValid(procOid2))
+ return procOid2;
+
+ /* Cases with OPAQUE need adjustment */
+ if (OidIsValid(procOid3))
+ procOid = procOid3;
+ else
+ procOid = procOid4;
if (OidIsValid(procOid))
{
@@ -1761,24 +1778,32 @@ findTypeReceiveFunction(List *procname, Oid typeOid)
{
Oid argList[3];
Oid procOid;
+ Oid procOid2;
/*
* Receive functions can take a single argument of type INTERNAL, or three
- * arguments (internal, typioparam OID, typmod).
+ * arguments (internal, typioparam OID, typmod). Whine about ambiguity if
+ * both forms exist.
*/
argList[0] = INTERNALOID;
-
- procOid = LookupFuncName(procname, 1, argList, true);
- if (OidIsValid(procOid))
- return procOid;
-
argList[1] = OIDOID;
argList[2] = INT4OID;
- procOid = LookupFuncName(procname, 3, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, true);
+ procOid2 = LookupFuncName(procname, 3, argList, true);
if (OidIsValid(procOid))
+ {
+ if (OidIsValid(procOid2))
+ ereport(ERROR,
+ (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
+ errmsg("type receive function %s has multiple matches",
+ NameListToString(procname))));
return procOid;
+ }
+ else if (OidIsValid(procOid2))
+ return procOid2;
+ /* If not found, reference the 1-argument signature in error msg */
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function %s does not exist",