diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/extension.c | 21 | ||||
-rw-r--r-- | src/backend/commands/operatorcmds.c | 27 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 69 |
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", |