diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index 1ab2e469ee..784d7553e8 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -254,7 +254,7 @@ 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, false, false);
 
 	/* 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..122573464f 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, false, false);
 
 	/* 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 e508334981..34f72114fa 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -239,7 +239,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, false, false);
 	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 5ada4a8594..16c9242241 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, false,
+								false);
 
 	/* 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, false,
+						  false);
 	/* validator's return value is ignored, so we don't check the type */
 }
 
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index f7c00e2f48..ade1a23550 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -208,7 +208,7 @@ DefineOperator(List *names, List *parameters)
 		typeId[1] = typeId2;
 		nargs = 2;
 	}
-	functionOid = LookupFuncName(functionName, nargs, typeId, false);
+	functionOid = LookupFuncName(functionName, nargs, typeId, false, false);
 
 	/*
 	 * We require EXECUTE rights for the function.  This isn't strictly
@@ -271,7 +271,7 @@ ValidateRestrictionEstimator(List *restrictionName)
 	typeId[2] = INTERNALOID;	/* args list */
 	typeId[3] = INT4OID;		/* varRelid */
 
-	restrictionOid = LookupFuncName(restrictionName, 4, typeId, false);
+	restrictionOid = LookupFuncName(restrictionName, 4, typeId, false, false);
 
 	/* estimators must return float8 */
 	if (get_func_rettype(restrictionOid) != FLOAT8OID)
@@ -312,12 +312,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, true, false);
 	if (!OidIsValid(joinOid))
-		joinOid = LookupFuncName(joinName, 4, typeId, true);
+		joinOid = LookupFuncName(joinName, 4, typeId, true, false);
 	/* 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, false, false);
 
 	/* 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 b010d23466..2fe4d84997 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -107,7 +107,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 		 * return type.
 		 */
 		funcname = SystemFuncName(pltemplate->tmplhandler);
-		handlerOid = LookupFuncName(funcname, 0, funcargtypes, true);
+		handlerOid = LookupFuncName(funcname, 0, funcargtypes, true, false);
 		if (OidIsValid(handlerOid))
 		{
 			funcrettype = get_func_rettype(handlerOid);
@@ -155,7 +155,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 		{
 			funcname = SystemFuncName(pltemplate->tmplinline);
 			funcargtypes[0] = INTERNALOID;
-			inlineOid = LookupFuncName(funcname, 1, funcargtypes, true);
+			inlineOid = LookupFuncName(funcname, 1, funcargtypes, true,
+									   false);
 			if (!OidIsValid(inlineOid))
 			{
 				tmpAddr = ProcedureCreate(pltemplate->tmplinline,
@@ -197,7 +198,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 		{
 			funcname = SystemFuncName(pltemplate->tmplvalidator);
 			funcargtypes[0] = OIDOID;
-			valOid = LookupFuncName(funcname, 1, funcargtypes, true);
+			valOid = LookupFuncName(funcname, 1, funcargtypes, true, false);
 			if (!OidIsValid(valOid))
 			{
 				tmpAddr = ProcedureCreate(pltemplate->tmplvalidator,
@@ -262,7 +263,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, false,
+									false);
 		funcrettype = get_func_rettype(handlerOid);
 		if (funcrettype != LANGUAGE_HANDLEROID)
 		{
@@ -291,7 +293,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 		if (stmt->plinline)
 		{
 			funcargtypes[0] = INTERNALOID;
-			inlineOid = LookupFuncName(stmt->plinline, 1, funcargtypes, false);
+			inlineOid = LookupFuncName(stmt->plinline, 1, funcargtypes, false,
+									   false);
 			/* return value is ignored, so we don't check the type */
 		}
 		else
@@ -301,7 +304,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 		if (stmt->plvalidator)
 		{
 			funcargtypes[0] = OIDOID;
-			valOid = LookupFuncName(stmt->plvalidator, 1, funcargtypes, false);
+			valOid = LookupFuncName(stmt->plvalidator, 1, funcargtypes, false,
+									false);
 			/* 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 2daffae8cd..b1a4850406 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -669,7 +669,7 @@ 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, false, false);
 	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 cda21675f0..41f2ab3f58 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -109,7 +109,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, false, false);
 	if (get_func_rettype(procOid) != retTypeId)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
@@ -680,7 +680,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, false, false);
 	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 9ca30b0443..b4f9c8897a 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1699,28 +1699,28 @@ findTypeInputFunction(List *procname, Oid typeOid)
 	 */
 	argList[0] = CSTRINGOID;
 
-	procOid = LookupFuncName(procname, 1, argList, true);
+	procOid = LookupFuncName(procname, 1, argList, true, false);
 	if (OidIsValid(procOid))
 		return procOid;
 
 	argList[1] = OIDOID;
 	argList[2] = INT4OID;
 
-	procOid = LookupFuncName(procname, 3, argList, true);
+	procOid = LookupFuncName(procname, 3, argList, true, false);
 	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, true, false);
 
 	if (!OidIsValid(procOid))
 	{
 		argList[1] = OIDOID;
 		argList[2] = INT4OID;
 
-		procOid = LookupFuncName(procname, 3, argList, true);
+		procOid = LookupFuncName(procname, 3, argList, true, false);
 	}
 
 	if (OidIsValid(procOid))
@@ -1765,14 +1765,14 @@ findTypeOutputFunction(List *procname, Oid typeOid)
 	 */
 	argList[0] = typeOid;
 
-	procOid = LookupFuncName(procname, 1, argList, true);
+	procOid = LookupFuncName(procname, 1, argList, true, false);
 	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, true, false);
 
 	if (OidIsValid(procOid))
 	{
@@ -1814,14 +1814,14 @@ findTypeReceiveFunction(List *procname, Oid typeOid)
 	 */
 	argList[0] = INTERNALOID;
 
-	procOid = LookupFuncName(procname, 1, argList, true);
+	procOid = LookupFuncName(procname, 1, argList, true, false);
 	if (OidIsValid(procOid))
 		return procOid;
 
 	argList[1] = OIDOID;
 	argList[2] = INT4OID;
 
-	procOid = LookupFuncName(procname, 3, argList, true);
+	procOid = LookupFuncName(procname, 3, argList, true, false);
 	if (OidIsValid(procOid))
 		return procOid;
 
@@ -1844,7 +1844,7 @@ findTypeSendFunction(List *procname, Oid typeOid)
 	 */
 	argList[0] = typeOid;
 
-	procOid = LookupFuncName(procname, 1, argList, true);
+	procOid = LookupFuncName(procname, 1, argList, true, false);
 	if (OidIsValid(procOid))
 		return procOid;
 
@@ -1867,7 +1867,7 @@ findTypeTypmodinFunction(List *procname)
 	 */
 	argList[0] = CSTRINGARRAYOID;
 
-	procOid = LookupFuncName(procname, 1, argList, true);
+	procOid = LookupFuncName(procname, 1, argList, true, false);
 	if (!OidIsValid(procOid))
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_FUNCTION),
@@ -1894,7 +1894,7 @@ findTypeTypmodoutFunction(List *procname)
 	 */
 	argList[0] = INT4OID;
 
-	procOid = LookupFuncName(procname, 1, argList, true);
+	procOid = LookupFuncName(procname, 1, argList, true, false);
 	if (!OidIsValid(procOid))
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_FUNCTION),
@@ -1921,7 +1921,7 @@ findTypeAnalyzeFunction(List *procname, Oid typeOid)
 	 */
 	argList[0] = INTERNALOID;
 
-	procOid = LookupFuncName(procname, 1, argList, true);
+	procOid = LookupFuncName(procname, 1, argList, true, false);
 	if (!OidIsValid(procOid))
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_FUNCTION),
@@ -1997,7 +1997,7 @@ findRangeCanonicalFunction(List *procname, Oid typeOid)
 	 */
 	argList[0] = typeOid;
 
-	procOid = LookupFuncName(procname, 1, argList, true);
+	procOid = LookupFuncName(procname, 1, argList, true, false);
 
 	if (!OidIsValid(procOid))
 		ereport(ERROR,
@@ -2039,7 +2039,7 @@ findRangeSubtypeDiffFunction(List *procname, Oid subtype)
 	argList[0] = subtype;
 	argList[1] = subtype;
 
-	procOid = LookupFuncName(procname, 2, argList, true);
+	procOid = LookupFuncName(procname, 2, argList, true, false);
 
 	if (!OidIsValid(procOid))
 		ereport(ERROR,
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 6963922b0e..752f1cc43a 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -934,7 +934,7 @@ transformRangeTableSample(ParseState *pstate, RangeTableSample *rts)
 	 */
 	funcargtypes[0] = INTERNALOID;
 
-	handlerOid = LookupFuncName(rts->method, 1, funcargtypes, true);
+	handlerOid = LookupFuncName(rts->method, 1, funcargtypes, true, false);
 
 	/* 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 4661fc4f62..6f69d360f6 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -2032,17 +2032,21 @@ func_signature_string(List *funcname, int nargs,
  * namespace search path.
  *
  * If the function is not found, we return InvalidOid if noError is true,
- * else raise an error.
+ * else raise an error.  missing_ok is similar to noError except we still
+ * raise an error for an ambigious function, regardless of what missing_ok is
+ * set to.
  */
 Oid
-LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
+LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError,
+			   bool missing_ok)
 {
 	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,
+								  noError || missing_ok);
 
 	/*
 	 * If no arguments were specified, the name must yield a unique candidate.
@@ -2065,7 +2069,7 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
 		}
 		else
 		{
-			if (!noError)
+			if (!noError && !missing_ok)
 				ereport(ERROR,
 						(errcode(ERRCODE_UNDEFINED_FUNCTION),
 						 errmsg("could not find a function named \"%s\"",
@@ -2080,7 +2084,7 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
 		clist = clist->next;
 	}
 
-	if (!noError)
+	if (!noError && !missing_ok)
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_FUNCTION),
 				 errmsg("function %s does not exist",
@@ -2135,10 +2139,11 @@ LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool noError)
 
 	/*
 	 * When looking for a function or routine, we pass noError through to
-	 * LookupFuncName and let it make any error messages.  Otherwise, we make
-	 * our own errors for the aggregate and procedure cases.
+	 * LookupFuncName's missing_ok parameter 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,
+	oid = LookupFuncName(func->objname, func->args_unspecified ? -1 : argcount, argoids, false,
 						 (objtype == OBJECT_FUNCTION || objtype == OBJECT_ROUTINE) ? noError : true);
 
 	if (objtype == OBJECT_FUNCTION)
diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h
index ff1477e64f..4e8f7af0f3 100644
--- a/src/include/parser/parse_func.h
+++ b/src/include/parser/parse_func.h
@@ -63,7 +63,7 @@ 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);
+			   bool noError, bool missing_ok);
 extern Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func,
 				   bool noError);
 
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(*);
