diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/extension.c | 21 | ||||
-rw-r--r-- | src/backend/commands/operatorcmds.c | 26 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 50 |
3 files changed, 72 insertions, 25 deletions
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index c796fcd8da0..b5630b4c8d9 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -908,9 +908,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 @@ -924,9 +936,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 0a53e9b93e2..bf23937849c 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -297,6 +297,7 @@ ValidateJoinEstimator(List *joinName) { Oid typeId[5]; Oid joinOid; + Oid joinOid2; AclResult aclresult; typeId[0] = INTERNALOID; /* PlannerInfo */ @@ -307,15 +308,26 @@ ValidateJoinEstimator(List *joinName) /* * 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. + * 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 2e107ace39b..483bb65ddc8 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -1627,21 +1627,31 @@ findTypeInputFunction(List *procname, Oid typeOid) { Oid argList[3]; Oid procOid; + Oid procOid2; /* * Input functions can take a single argument of type CSTRING, or three - * arguments (string, typioparam OID, typmod). They must return the - * target type. + * arguments (string, typioparam OID, typmod). Whine about ambiguity if + * both forms exist. */ argList[0] = CSTRINGOID; + argList[1] = OIDOID; + argList[2] = INT4OID; procOid = LookupFuncName(procname, 1, argList, true); - if (!OidIsValid(procOid)) + procOid2 = LookupFuncName(procname, 3, argList, true); + if (OidIsValid(procOid)) { - argList[1] = OIDOID; - argList[2] = INT4OID; - - procOid = LookupFuncName(procname, 3, argList, true); + if (OidIsValid(procOid2)) + ereport(ERROR, + (errcode(ERRCODE_AMBIGUOUS_FUNCTION), + errmsg("type input function %s has multiple matches", + NameListToString(procname)))); + } + else + { + procOid = procOid2; + /* If not found, reference the 1-argument signature in error msg */ if (!OidIsValid(procOid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), @@ -1649,6 +1659,7 @@ findTypeInputFunction(List *procname, Oid typeOid) func_signature_string(procname, 1, NIL, argList)))); } + /* Input functions must return the target type. */ if (get_func_rettype(procOid) != typeOid) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), @@ -1714,21 +1725,31 @@ 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). They must return the - * target type. + * arguments (internal, typioparam OID, typmod). Whine about ambiguity if + * both forms exist. */ argList[0] = INTERNALOID; + argList[1] = OIDOID; + argList[2] = INT4OID; procOid = LookupFuncName(procname, 1, argList, true); - if (!OidIsValid(procOid)) + procOid2 = LookupFuncName(procname, 3, argList, true); + if (OidIsValid(procOid)) { - argList[1] = OIDOID; - argList[2] = INT4OID; - - procOid = LookupFuncName(procname, 3, argList, true); + if (OidIsValid(procOid2)) + ereport(ERROR, + (errcode(ERRCODE_AMBIGUOUS_FUNCTION), + errmsg("type receive function %s has multiple matches", + NameListToString(procname)))); + } + else + { + procOid = procOid2; + /* If not found, reference the 1-argument signature in error msg */ if (!OidIsValid(procOid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), @@ -1736,6 +1757,7 @@ findTypeReceiveFunction(List *procname, Oid typeOid) func_signature_string(procname, 1, NIL, argList)))); } + /* Receive functions must return the target type. */ if (get_func_rettype(procOid) != typeOid) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), |