drop_func_if_not_exists_fix_v7.patch
application/octet-stream
Filename: drop_func_if_not_exists_fix_v7.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v7
| File | + | − |
|---|---|---|
| src/backend/catalog/aclchk.c | 6 | 3 |
| src/backend/catalog/objectaddress.c | 3 | 1 |
| src/backend/commands/amcmds.c | 2 | 1 |
| src/backend/commands/conversioncmds.c | 1 | 1 |
| src/backend/commands/event_trigger.c | 1 | 1 |
| src/backend/commands/foreigncmds.c | 4 | 2 |
| src/backend/commands/functioncmds.c | 9 | 5 |
| src/backend/commands/opclasscmds.c | 4 | 2 |
| src/backend/commands/operatorcmds.c | 7 | 5 |
| src/backend/commands/proclang.c | 12 | 6 |
| src/backend/commands/trigger.c | 2 | 1 |
| src/backend/commands/tsearchcmds.c | 2 | 2 |
| src/backend/commands/typecmds.c | 14 | 14 |
| src/backend/parser/parse_clause.c | 1 | 1 |
| src/backend/parser/parse_func.c | 26 | 11 |
| src/include/parser/parse_func.h | 9 | 2 |
| src/pl/tcl/pltcl.c | 1 | 1 |
| src/test/regress/expected/drop_if_exists.out | 10 | 0 |
| src/test/regress/sql/drop_if_exists.sql | 10 | 0 |
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 11ddce2a8b..f92f2f0a25 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -681,7 +681,8 @@ objectNamesToOids(ObjectType objtype, List *objnames)
ObjectWithArgs *func = (ObjectWithArgs *) lfirst(cell);
Oid funcid;
- funcid = LookupFuncWithArgs(OBJECT_FUNCTION, func, false);
+ funcid = LookupFuncWithArgs(OBJECT_FUNCTION, func,
+ FUNCLOOKUP_NORMAL);
objects = lappend_oid(objects, funcid);
}
break;
@@ -725,7 +726,8 @@ objectNamesToOids(ObjectType objtype, List *objnames)
ObjectWithArgs *func = (ObjectWithArgs *) lfirst(cell);
Oid procid;
- procid = LookupFuncWithArgs(OBJECT_PROCEDURE, func, false);
+ procid = LookupFuncWithArgs(OBJECT_PROCEDURE, func,
+ FUNCLOOKUP_NORMAL);
objects = lappend_oid(objects, procid);
}
break;
@@ -735,7 +737,8 @@ objectNamesToOids(ObjectType objtype, List *objnames)
ObjectWithArgs *func = (ObjectWithArgs *) lfirst(cell);
Oid routid;
- routid = LookupFuncWithArgs(OBJECT_ROUTINE, func, false);
+ routid = LookupFuncWithArgs(OBJECT_ROUTINE, func,
+ FUNCLOOKUP_NORMAL);
objects = lappend_oid(objects, routid);
}
break;
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index ab3ec7e356..2f6fd892bf 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -926,7 +926,9 @@ get_object_address(ObjectType objtype, Node *object,
case OBJECT_PROCEDURE:
case OBJECT_ROUTINE:
address.classId = ProcedureRelationId;
- address.objectId = LookupFuncWithArgs(objtype, castNode(ObjectWithArgs, object), missing_ok);
+ address.objectId = LookupFuncWithArgs(objtype, castNode(ObjectWithArgs, object),
+ missing_ok ? FUNCLOOKUP_ERRIFAMBIGUOUS :
+ FUNCLOOKUP_NORMAL);
address.objectSubId = 0;
break;
case OBJECT_OPERATOR:
diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index c84507b5d0..db27616f32 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -254,7 +254,8 @@ lookup_index_am_handler_func(List *handler_name, char amtype)
errmsg("handler function is not specified")));
/* handlers have one argument of type internal */
- handlerOid = LookupFuncName(handler_name, 1, funcargtypes, false);
+ handlerOid = LookupFuncName(handler_name, 1, funcargtypes,
+ FUNCLOOKUP_NORMAL);
/* check that handler has the correct return type */
switch (amtype)
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index 5afe86712f..1329c58d27 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -77,7 +77,7 @@ CreateConversionCommand(CreateConversionStmt *stmt)
* a qualified name.
*/
funcoid = LookupFuncName(func_name, sizeof(funcargs) / sizeof(Oid),
- funcargs, false);
+ funcargs, FUNCLOOKUP_NORMAL);
/* Check it returns VOID, else it's probably the wrong function */
if (get_func_rettype(funcoid) != VOIDOID)
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index adb77d8f69..8e922e6c2a 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -238,7 +238,7 @@ CreateEventTrigger(CreateEventTrigStmt *stmt)
stmt->trigname)));
/* Find and validate the trigger function. */
- funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
+ funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, FUNCLOOKUP_NORMAL);
funcrettype = get_func_rettype(funcoid);
if (funcrettype != EVTTRIGGEROID)
ereport(ERROR,
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 413ce3fcb6..9cb4dadfc4 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -484,7 +484,8 @@ lookup_fdw_handler_func(DefElem *handler)
return InvalidOid;
/* handlers have no arguments */
- handlerOid = LookupFuncName((List *) handler->arg, 0, funcargtypes, false);
+ handlerOid = LookupFuncName((List *) handler->arg, 0, funcargtypes,
+ FUNCLOOKUP_NORMAL);
/* check that handler has correct return type */
if (get_func_rettype(handlerOid) != FDW_HANDLEROID)
@@ -511,7 +512,8 @@ lookup_fdw_validator_func(DefElem *validator)
funcargtypes[0] = TEXTARRAYOID;
funcargtypes[1] = OIDOID;
- return LookupFuncName((List *) validator->arg, 2, funcargtypes, false);
+ return LookupFuncName((List *) validator->arg, 2, funcargtypes,
+ FUNCLOOKUP_NORMAL);
/* validator's return value is ignored, so we don't check the type */
}
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 4f62e48d98..76a4212e05 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -658,7 +658,7 @@ interpret_func_support(DefElem *defel)
*/
argList[0] = INTERNALOID;
- procOid = LookupFuncName(procName, 1, argList, true);
+ procOid = LookupFuncName(procName, 1, argList, FUNCLOOKUP_NOERROR);
if (!OidIsValid(procOid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
@@ -1251,7 +1251,8 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)
rel = table_open(ProcedureRelationId, RowExclusiveLock);
- funcOid = LookupFuncWithArgs(stmt->objtype, stmt->func, false);
+ funcOid = LookupFuncWithArgs(stmt->objtype, stmt->func,
+ FUNCLOOKUP_NORMAL);
ObjectAddressSet(address, ProcedureRelationId, funcOid);
@@ -1567,7 +1568,8 @@ CreateCast(CreateCastStmt *stmt)
{
Form_pg_proc procstruct;
- funcid = LookupFuncWithArgs(OBJECT_FUNCTION, stmt->func, false);
+ funcid = LookupFuncWithArgs(OBJECT_FUNCTION, stmt->func,
+ FUNCLOOKUP_NORMAL);
tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
if (!HeapTupleIsValid(tuple))
@@ -1942,7 +1944,8 @@ CreateTransform(CreateTransformStmt *stmt)
*/
if (stmt->fromsql)
{
- fromsqlfuncid = LookupFuncWithArgs(OBJECT_FUNCTION, stmt->fromsql, false);
+ fromsqlfuncid = LookupFuncWithArgs(OBJECT_FUNCTION, stmt->fromsql,
+ FUNCLOOKUP_NORMAL);
if (!pg_proc_ownercheck(fromsqlfuncid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(stmt->fromsql->objname));
@@ -1968,7 +1971,8 @@ CreateTransform(CreateTransformStmt *stmt)
if (stmt->tosql)
{
- tosqlfuncid = LookupFuncWithArgs(OBJECT_FUNCTION, stmt->tosql, false);
+ tosqlfuncid = LookupFuncWithArgs(OBJECT_FUNCTION, stmt->tosql,
+ FUNCLOOKUP_NORMAL);
if (!pg_proc_ownercheck(tosqlfuncid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(stmt->tosql->objname));
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 5d73848a8b..34312e5e72 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -529,7 +529,8 @@ DefineOpClass(CreateOpClassStmt *stmt)
errmsg("invalid function number %d,"
" must be between 1 and %d",
item->number, maxProcNumber)));
- funcOid = LookupFuncWithArgs(OBJECT_FUNCTION, item->name, false);
+ funcOid = LookupFuncWithArgs(OBJECT_FUNCTION, item->name,
+ FUNCLOOKUP_NORMAL);
#ifdef NOT_USED
/* XXX this is unnecessary given the superuser check above */
/* Caller must own function */
@@ -908,7 +909,8 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
errmsg("invalid function number %d,"
" must be between 1 and %d",
item->number, maxProcNumber)));
- funcOid = LookupFuncWithArgs(OBJECT_FUNCTION, item->name, false);
+ funcOid = LookupFuncWithArgs(OBJECT_FUNCTION, item->name,
+ FUNCLOOKUP_NORMAL);
#ifdef NOT_USED
/* XXX this is unnecessary given the superuser check above */
/* Caller must own function */
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index 7b98e4b910..6c1bc5208e 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -208,7 +208,8 @@ DefineOperator(List *names, List *parameters)
typeId[1] = typeId2;
nargs = 2;
}
- functionOid = LookupFuncName(functionName, nargs, typeId, false);
+ functionOid = LookupFuncName(functionName, nargs, typeId,
+ FUNCLOOKUP_NORMAL);
/*
* We require EXECUTE rights for the function. This isn't strictly
@@ -271,7 +272,8 @@ ValidateRestrictionEstimator(List *restrictionName)
typeId[2] = INTERNALOID; /* args list */
typeId[3] = INT4OID; /* varRelid */
- restrictionOid = LookupFuncName(restrictionName, 4, typeId, false);
+ restrictionOid = LookupFuncName(restrictionName, 4, typeId,
+ FUNCLOOKUP_NORMAL);
/* estimators must return float8 */
if (get_func_rettype(restrictionOid) != FLOAT8OID)
@@ -312,12 +314,12 @@ ValidateJoinEstimator(List *joinName)
* arguments, but we still allow the old 4-argument form. Try the
* preferred form first.
*/
- joinOid = LookupFuncName(joinName, 5, typeId, true);
+ joinOid = LookupFuncName(joinName, 5, typeId, FUNCLOOKUP_NOERROR);
if (!OidIsValid(joinOid))
- joinOid = LookupFuncName(joinName, 4, typeId, true);
+ joinOid = LookupFuncName(joinName, 4, typeId, FUNCLOOKUP_NOERROR);
/* If not found, reference the 5-argument signature in error msg */
if (!OidIsValid(joinOid))
- joinOid = LookupFuncName(joinName, 5, typeId, false);
+ joinOid = LookupFuncName(joinName, 5, typeId, FUNCLOOKUP_NORMAL);
/* estimators must return float8 */
if (get_func_rettype(joinOid) != FLOAT8OID)
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 59c4e8dfd0..e94ca419be 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -106,7 +106,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
* return type.
*/
funcname = SystemFuncName(pltemplate->tmplhandler);
- handlerOid = LookupFuncName(funcname, 0, funcargtypes, true);
+ handlerOid = LookupFuncName(funcname, 0, funcargtypes,
+ FUNCLOOKUP_NOERROR);
if (OidIsValid(handlerOid))
{
funcrettype = get_func_rettype(handlerOid);
@@ -155,7 +156,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
{
funcname = SystemFuncName(pltemplate->tmplinline);
funcargtypes[0] = INTERNALOID;
- inlineOid = LookupFuncName(funcname, 1, funcargtypes, true);
+ inlineOid = LookupFuncName(funcname, 1, funcargtypes,
+ FUNCLOOKUP_NOERROR);
if (!OidIsValid(inlineOid))
{
tmpAddr = ProcedureCreate(pltemplate->tmplinline,
@@ -198,7 +200,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
{
funcname = SystemFuncName(pltemplate->tmplvalidator);
funcargtypes[0] = OIDOID;
- valOid = LookupFuncName(funcname, 1, funcargtypes, true);
+ valOid = LookupFuncName(funcname, 1, funcargtypes,
+ FUNCLOOKUP_NOERROR);
if (!OidIsValid(valOid))
{
tmpAddr = ProcedureCreate(pltemplate->tmplvalidator,
@@ -264,7 +267,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
* Lookup the PL handler function and check that it is of the expected
* return type
*/
- handlerOid = LookupFuncName(stmt->plhandler, 0, funcargtypes, false);
+ handlerOid = LookupFuncName(stmt->plhandler, 0, funcargtypes,
+ FUNCLOOKUP_NORMAL);
funcrettype = get_func_rettype(handlerOid);
if (funcrettype != LANGUAGE_HANDLEROID)
{
@@ -293,7 +297,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
if (stmt->plinline)
{
funcargtypes[0] = INTERNALOID;
- inlineOid = LookupFuncName(stmt->plinline, 1, funcargtypes, false);
+ inlineOid = LookupFuncName(stmt->plinline, 1, funcargtypes,
+ FUNCLOOKUP_NORMAL);
/* return value is ignored, so we don't check the type */
}
else
@@ -303,7 +308,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
if (stmt->plvalidator)
{
funcargtypes[0] = OIDOID;
- valOid = LookupFuncName(stmt->plvalidator, 1, funcargtypes, false);
+ valOid = LookupFuncName(stmt->plvalidator, 1, funcargtypes,
+ FUNCLOOKUP_NORMAL);
/* return value is ignored, so we don't check the type */
}
else
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 409bee24f8..60798722a1 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -667,7 +667,8 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
* Find and validate the trigger function.
*/
if (!OidIsValid(funcoid))
- funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
+ funcoid = LookupFuncName(stmt->funcname, 0, fargtypes,
+ FUNCLOOKUP_NORMAL);
if (!isInternal)
{
aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 8e5eec22b5..30d3635598 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -108,7 +108,7 @@ get_ts_parser_func(DefElem *defel, int attnum)
nargs = 0; /* keep compiler quiet */
}
- procOid = LookupFuncName(funcName, nargs, typeId, false);
+ procOid = LookupFuncName(funcName, nargs, typeId, FUNCLOOKUP_NORMAL);
if (get_func_rettype(procOid) != retTypeId)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
@@ -679,7 +679,7 @@ get_ts_template_func(DefElem *defel, int attnum)
nargs = 0; /* keep compiler quiet */
}
- procOid = LookupFuncName(funcName, nargs, typeId, false);
+ procOid = LookupFuncName(funcName, nargs, typeId, FUNCLOOKUP_NORMAL);
if (get_func_rettype(procOid) != retTypeId)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 448926db12..fe7a5c1017 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1700,28 +1700,28 @@ findTypeInputFunction(List *procname, Oid typeOid)
*/
argList[0] = CSTRINGOID;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, FUNCLOOKUP_NOERROR);
if (OidIsValid(procOid))
return procOid;
argList[1] = OIDOID;
argList[2] = INT4OID;
- procOid = LookupFuncName(procname, 3, argList, true);
+ procOid = LookupFuncName(procname, 3, argList, FUNCLOOKUP_NOERROR);
if (OidIsValid(procOid))
return procOid;
/* No luck, try it with OPAQUE */
argList[0] = OPAQUEOID;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, FUNCLOOKUP_NOERROR);
if (!OidIsValid(procOid))
{
argList[1] = OIDOID;
argList[2] = INT4OID;
- procOid = LookupFuncName(procname, 3, argList, true);
+ procOid = LookupFuncName(procname, 3, argList, FUNCLOOKUP_NOERROR);
}
if (OidIsValid(procOid))
@@ -1766,14 +1766,14 @@ findTypeOutputFunction(List *procname, Oid typeOid)
*/
argList[0] = typeOid;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, FUNCLOOKUP_NOERROR);
if (OidIsValid(procOid))
return procOid;
/* No luck, try it with OPAQUE */
argList[0] = OPAQUEOID;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, FUNCLOOKUP_NOERROR);
if (OidIsValid(procOid))
{
@@ -1815,14 +1815,14 @@ findTypeReceiveFunction(List *procname, Oid typeOid)
*/
argList[0] = INTERNALOID;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, FUNCLOOKUP_NOERROR);
if (OidIsValid(procOid))
return procOid;
argList[1] = OIDOID;
argList[2] = INT4OID;
- procOid = LookupFuncName(procname, 3, argList, true);
+ procOid = LookupFuncName(procname, 3, argList, FUNCLOOKUP_NOERROR);
if (OidIsValid(procOid))
return procOid;
@@ -1845,7 +1845,7 @@ findTypeSendFunction(List *procname, Oid typeOid)
*/
argList[0] = typeOid;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, FUNCLOOKUP_NOERROR);
if (OidIsValid(procOid))
return procOid;
@@ -1868,7 +1868,7 @@ findTypeTypmodinFunction(List *procname)
*/
argList[0] = CSTRINGARRAYOID;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, FUNCLOOKUP_NOERROR);
if (!OidIsValid(procOid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
@@ -1895,7 +1895,7 @@ findTypeTypmodoutFunction(List *procname)
*/
argList[0] = INT4OID;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, FUNCLOOKUP_NOERROR);
if (!OidIsValid(procOid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
@@ -1922,7 +1922,7 @@ findTypeAnalyzeFunction(List *procname, Oid typeOid)
*/
argList[0] = INTERNALOID;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, FUNCLOOKUP_NOERROR);
if (!OidIsValid(procOid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
@@ -1998,7 +1998,7 @@ findRangeCanonicalFunction(List *procname, Oid typeOid)
*/
argList[0] = typeOid;
- procOid = LookupFuncName(procname, 1, argList, true);
+ procOid = LookupFuncName(procname, 1, argList, FUNCLOOKUP_NOERROR);
if (!OidIsValid(procOid))
ereport(ERROR,
@@ -2040,7 +2040,7 @@ findRangeSubtypeDiffFunction(List *procname, Oid subtype)
argList[0] = subtype;
argList[1] = subtype;
- procOid = LookupFuncName(procname, 2, argList, true);
+ procOid = LookupFuncName(procname, 2, argList, FUNCLOOKUP_NOERROR);
if (!OidIsValid(procOid))
ereport(ERROR,
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index c6ce1011e2..35fc73b493 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -933,7 +933,7 @@ transformRangeTableSample(ParseState *pstate, RangeTableSample *rts)
*/
funcargtypes[0] = INTERNALOID;
- handlerOid = LookupFuncName(rts->method, 1, funcargtypes, true);
+ handlerOid = LookupFuncName(rts->method, 1, funcargtypes, FUNCLOOKUP_NOERROR);
/* we want error to complain about no-such-method, not no-such-function */
if (!OidIsValid(handlerOid))
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 5222231b51..907b2d7062 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -2031,18 +2031,25 @@ func_signature_string(List *funcname, int nargs,
* If the function name is not schema-qualified, it is sought in the current
* namespace search path.
*
- * If the function is not found, we return InvalidOid if noError is true,
- * else raise an error.
+ * If the function is not found the behavior depends on the value of
+ * 'checktype'. When it's set to FUNCLOOKUP_NORMAL, we report errors for each
+ * of the possible error situations. When set to FUNCLOOKUP_ERRIFAMBIGUOUS,
+ * the only error we raise is for an ambiguous function definition, otherwise
+ * if set to FUNCLOOKUP_NOERROR we don't raise any errors. In each of the
+ * cases we skip reporting an error, we return InvalidOid to indicate to the
+ * caller that the lookup has failed.
*/
Oid
-LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
+LookupFuncName(List *funcname, int nargs, const Oid *argtypes,
+ FuncLookupCheckType checktype)
{
FuncCandidateList clist;
/* Passing NULL for argtypes is no longer allowed */
Assert(argtypes);
- clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false, noError);
+ clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false,
+ (checktype != FUNCLOOKUP_NORMAL));
/*
* If no arguments were specified, the name must yield a unique candidate.
@@ -2053,7 +2060,11 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
{
if (clist->next)
{
- if (!noError)
+ /*
+ * Raise this error on FUNCLOOKUP_NORMAL and
+ * FUNCLOOKUP_ERRIFAMBIGUOUS
+ */
+ if (checktype != FUNCLOOKUP_NOERROR)
ereport(ERROR,
(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
errmsg("function name \"%s\" is not unique",
@@ -2065,7 +2076,7 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
}
else
{
- if (!noError)
+ if (checktype == FUNCLOOKUP_NORMAL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("could not find a function named \"%s\"",
@@ -2080,7 +2091,7 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
clist = clist->next;
}
- if (!noError)
+ if (checktype == FUNCLOOKUP_NORMAL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function %s does not exist",
@@ -2102,10 +2113,12 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
* function.
*/
Oid
-LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool noError)
+LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func,
+ FuncLookupCheckType checktype)
{
Oid argoids[FUNC_MAX_ARGS];
int argcount;
+ bool noError = (checktype != FUNCLOOKUP_NORMAL);
int i;
ListCell *args_item;
Oid oid;
@@ -2134,12 +2147,14 @@ LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool noError)
}
/*
- * When looking for a function or routine, we pass noError through to
+ * When looking for a function or routine, we pass checktype through to
* LookupFuncName and let it make any error messages. Otherwise, we make
* our own errors for the aggregate and procedure cases.
*/
- oid = LookupFuncName(func->objname, func->args_unspecified ? -1 : argcount, argoids,
- (objtype == OBJECT_FUNCTION || objtype == OBJECT_ROUTINE) ? noError : true);
+ oid = LookupFuncName(func->objname,
+ func->args_unspecified ? -1 : argcount,
+ argoids,
+ (objtype == OBJECT_FUNCTION || objtype == OBJECT_ROUTINE) ? checktype : FUNCLOOKUP_NOERROR);
if (objtype == OBJECT_FUNCTION)
{
diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h
index ff1477e64f..d279183f17 100644
--- a/src/include/parser/parse_func.h
+++ b/src/include/parser/parse_func.h
@@ -30,6 +30,13 @@ typedef enum
FUNCDETAIL_COERCION /* it's a type coercion request */
} FuncDetailCode;
+/* Error checking types for LookupFuncName and LookupFuncWithArgs */
+typedef enum
+{
+ FUNCLOOKUP_NORMAL, /* Full error checking */
+ FUNCLOOKUP_NOERROR, /* Don't raise error for lookup failure */
+ FUNCLOOKUP_ERRIFAMBIGUOUS /* Only raise ambiguous function errors */
+} FuncLookupCheckType;
extern Node *ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
Node *last_srf, FuncCall *fn, bool proc_call,
@@ -63,9 +70,9 @@ extern const char *func_signature_string(List *funcname, int nargs,
List *argnames, const Oid *argtypes);
extern Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes,
- bool noError);
+ FuncLookupCheckType checktype);
extern Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func,
- bool noError);
+ FuncLookupCheckType checktype);
extern void check_srf_call_placement(ParseState *pstate, Node *last_srf,
int location);
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 76c9afc339..1e651203da 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -616,7 +616,7 @@ call_pltcl_start_proc(Oid prolang, bool pltrusted)
/* Parse possibly-qualified identifier and look up the function */
namelist = stringToQualifiedNameList(start_proc);
- procOid = LookupFuncName(namelist, 0, fargtypes, false);
+ procOid = LookupFuncName(namelist, 0, fargtypes, FUNCLOOKUP_NORMAL);
/* Current user must have permission to call function */
aclresult = pg_proc_aclcheck(procOid, GetUserId(), ACL_EXECUTE);
diff --git a/src/test/regress/expected/drop_if_exists.out b/src/test/regress/expected/drop_if_exists.out
index b80c5ed2d8..dd4e6c0f6d 100644
--- a/src/test/regress/expected/drop_if_exists.out
+++ b/src/test/regress/expected/drop_if_exists.out
@@ -138,6 +138,16 @@ DROP FUNCTION test_function_exists(int, text, int[]);
ERROR: function test_function_exists(integer, text, integer[]) does not exist
DROP FUNCTION IF EXISTS test_function_exists(int, text, int[]);
NOTICE: function test_function_exists(pg_catalog.int4,text,pg_catalog.int4[]) does not exist, skipping
+-- Ensure we still receive an ambiguous function error when there are
+-- multiple matching functions.
+CREATE FUNCTION test_ambiguous_funcname(int) returns int as $$ select $1; $$ language sql;
+CREATE FUNCTION test_ambiguous_funcname(text) returns text as $$ select $1; $$ language sql;
+DROP FUNCTION IF EXISTS test_ambiguous_funcname;
+ERROR: function name "test_ambiguous_funcname" is not unique
+HINT: Specify the argument list to select the function unambiguously.
+-- cleanup
+DROP FUNCTION test_ambiguous_funcname(int);
+DROP FUNCTION test_ambiguous_funcname(text);
-- aggregate
DROP AGGREGATE test_aggregate_exists(*);
ERROR: aggregate test_aggregate_exists(*) does not exist
diff --git a/src/test/regress/sql/drop_if_exists.sql b/src/test/regress/sql/drop_if_exists.sql
index c1d30bc4a5..ad4ef76460 100644
--- a/src/test/regress/sql/drop_if_exists.sql
+++ b/src/test/regress/sql/drop_if_exists.sql
@@ -153,6 +153,16 @@ DROP FUNCTION IF EXISTS test_function_exists();
DROP FUNCTION test_function_exists(int, text, int[]);
DROP FUNCTION IF EXISTS test_function_exists(int, text, int[]);
+-- Ensure we still receive an ambiguous function error when there are
+-- multiple matching functions.
+CREATE FUNCTION test_ambiguous_funcname(int) returns int as $$ select $1; $$ language sql;
+CREATE FUNCTION test_ambiguous_funcname(text) returns text as $$ select $1; $$ language sql;
+DROP FUNCTION IF EXISTS test_ambiguous_funcname;
+
+-- cleanup
+DROP FUNCTION test_ambiguous_funcname(int);
+DROP FUNCTION test_ambiguous_funcname(text);
+
-- aggregate
DROP AGGREGATE test_aggregate_exists(*);
DROP AGGREGATE IF EXISTS test_aggregate_exists(*);