From 8f86ed1aceec8cff7e402e59f1dd49a140daf260 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Thu, 15 Sep 2016 12:00:00 -0400
Subject: [PATCH 4/7] Pass around function signatures as FuncWithArgs

Use the existing FuncWithArgs node type for passing around function
signatures, instead of always passing around name and argument list as
two separate variables.  This makes some things simpler, because only
one value has to be carried around.
---
 src/backend/catalog/objectaddress.c | 38 ++++++++++++++++-------
 src/backend/commands/dropcmds.c     | 30 +++++++++++--------
 src/backend/parser/gram.y           | 60 ++++++++++++++++---------------------
 3 files changed, 71 insertions(+), 57 deletions(-)

diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index d531d17..905a488 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -820,17 +820,23 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
 				address = get_object_address_type(objtype, list_head(objname), missing_ok);
 				break;
 			case OBJECT_AGGREGATE:
-				address.classId = ProcedureRelationId;
-				address.objectId =
-					LookupAggNameTypeNames(objname, objargs, missing_ok);
-				address.objectSubId = 0;
-				break;
+				{
+					FuncWithArgs *fwa = (FuncWithArgs *) linitial(objname);
+					address.classId = ProcedureRelationId;
+					address.objectId =
+						LookupAggNameTypeNames(fwa->funcname, fwa->funcargs, missing_ok);
+					address.objectSubId = 0;
+					break;
+				}
 			case OBJECT_FUNCTION:
-				address.classId = ProcedureRelationId;
-				address.objectId =
-					LookupFuncNameTypeNames(objname, objargs, missing_ok);
-				address.objectSubId = 0;
-				break;
+				{
+					FuncWithArgs *fwa = (FuncWithArgs *) linitial(objname);
+					address.classId = ProcedureRelationId;
+					address.objectId =
+						LookupFuncNameTypeNames(fwa->funcname, fwa->funcargs, missing_ok);
+					address.objectSubId = 0;
+					break;
+				}
 			case OBJECT_OPERATOR:
 				Assert(list_length(objargs) == 2);
 				address.classId = OperatorRelationId;
@@ -1992,6 +1998,16 @@ pg_get_object_address(PG_FUNCTION_ARGS)
 		args = textarray_to_strvaluelist(argsarr);
 	}
 
+	if (type == OBJECT_FUNCTION || type == OBJECT_AGGREGATE)
+	{
+		FuncWithArgs *fwa = makeNode(FuncWithArgs);
+
+		fwa->funcname = name;
+		fwa->funcargs = args;
+		name = list_make1(fwa);
+		args = NIL;
+	}
+
 	/*
 	 * get_object_name is pretty sensitive to the length its input lists;
 	 * check that they're what it wants.
@@ -2100,7 +2116,7 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
 		case OBJECT_FUNCTION:
 			if (!pg_proc_ownercheck(address.objectId, roleid))
 				aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
-							   NameListToString(objname));
+							   NameListToString(((FuncWithArgs *) linitial(objname))->funcname));
 			break;
 		case OBJECT_OPERATOR:
 			if (!pg_oper_ownercheck(address.objectId, roleid))
diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c
index 61ff8f2..ecf1428 100644
--- a/src/backend/commands/dropcmds.c
+++ b/src/backend/commands/dropcmds.c
@@ -110,7 +110,7 @@ RemoveObjects(DropStmt *stmt)
 				ereport(ERROR,
 						(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 						 errmsg("\"%s\" is an aggregate function",
-								NameListToString(objname)),
+								NameListToString(((FuncWithArgs *) linitial(objname))->funcname)),
 				errhint("Use DROP AGGREGATE to drop aggregate functions.")));
 
 			ReleaseSysCache(tup);
@@ -329,21 +329,27 @@ does_not_exist_skipping(ObjectType objtype, List *objname, List *objargs)
 			name = NameListToString(objname);
 			break;
 		case OBJECT_FUNCTION:
-			if (!schema_does_not_exist_skipping(objname, &msg, &name) &&
-				!type_in_list_does_not_exist_skipping(objargs, &msg, &name))
 			{
-				msg = gettext_noop("function %s(%s) does not exist, skipping");
-				name = NameListToString(objname);
-				args = TypeNameListToString(objargs);
+				FuncWithArgs *fwa = (FuncWithArgs *) linitial(objname);
+				if (!schema_does_not_exist_skipping(fwa->funcname, &msg, &name) &&
+					!type_in_list_does_not_exist_skipping(fwa->funcargs, &msg, &name))
+				{
+					msg = gettext_noop("function %s(%s) does not exist, skipping");
+					name = NameListToString(fwa->funcname);
+					args = TypeNameListToString(fwa->funcargs);
+				}
+				break;
 			}
-			break;
 		case OBJECT_AGGREGATE:
-			if (!schema_does_not_exist_skipping(objname, &msg, &name) &&
-				!type_in_list_does_not_exist_skipping(objargs, &msg, &name))
 			{
-				msg = gettext_noop("aggregate %s(%s) does not exist, skipping");
-				name = NameListToString(objname);
-				args = TypeNameListToString(objargs);
+				FuncWithArgs *fwa = (FuncWithArgs *) linitial(objname);
+				if (!schema_does_not_exist_skipping(fwa->funcname, &msg, &name) &&
+					!type_in_list_does_not_exist_skipping(fwa->funcargs, &msg, &name))
+				{
+					msg = gettext_noop("aggregate %s(%s) does not exist, skipping");
+					name = NameListToString(fwa->funcname);
+					args = TypeNameListToString(fwa->funcargs);
+				}
 			}
 			break;
 		case OBJECT_OPERATOR:
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index d4d5467..27110a5 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -3946,8 +3946,7 @@ AlterExtensionContentsStmt:
 					n->extname = $3;
 					n->action = $4;
 					n->objtype = OBJECT_AGGREGATE;
-					n->objname = $6->funcname;
-					n->objargs = $6->funcargs;
+					n->objname = list_make1($6);
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop CAST '(' Typename AS Typename ')'
@@ -3993,8 +3992,7 @@ AlterExtensionContentsStmt:
 					n->extname = $3;
 					n->action = $4;
 					n->objtype = OBJECT_FUNCTION;
-					n->objname = $6->funcname;
-					n->objargs = $6->funcargs;
+					n->objname = list_make1($6);
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop opt_procedural LANGUAGE name
@@ -5775,8 +5773,8 @@ CommentStmt:
 				{
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_AGGREGATE;
-					n->objname = $4->funcname;
-					n->objargs = $4->funcargs;
+					n->objname = list_make1($4);
+					n->objargs = NIL;
 					n->comment = $6;
 					$$ = (Node *) n;
 				}
@@ -5784,8 +5782,8 @@ CommentStmt:
 				{
 					CommentStmt *n = makeNode(CommentStmt);
 					n->objtype = OBJECT_FUNCTION;
-					n->objname = $4->funcname;
-					n->objargs = $4->funcargs;
+					n->objname = list_make1($4);
+					n->objargs = NIL;
 					n->comment = $6;
 					$$ = (Node *) n;
 				}
@@ -5993,8 +5991,8 @@ SecLabelStmt:
 					SecLabelStmt *n = makeNode(SecLabelStmt);
 					n->provider = $3;
 					n->objtype = OBJECT_AGGREGATE;
-					n->objname = $6->funcname;
-					n->objargs = $6->funcargs;
+					n->objname = list_make1($6);
+					n->objargs = NIL;
 					n->label = $8;
 					$$ = (Node *) n;
 				}
@@ -6004,8 +6002,8 @@ SecLabelStmt:
 					SecLabelStmt *n = makeNode(SecLabelStmt);
 					n->provider = $3;
 					n->objtype = OBJECT_FUNCTION;
-					n->objname = $6->funcname;
-					n->objargs = $6->funcargs;
+					n->objname = list_make1($6);
+					n->objargs = NIL;
 					n->label = $8;
 					$$ = (Node *) n;
 				}
@@ -7250,8 +7248,8 @@ RemoveFuncStmt:
 				{
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_FUNCTION;
-					n->objects = list_make1($3->funcname);
-					n->arguments = list_make1($3->funcargs);
+					n->objects = list_make1(list_make1($3));
+					n->arguments = NIL;
 					n->behavior = $4;
 					n->missing_ok = false;
 					n->concurrent = false;
@@ -7261,8 +7259,8 @@ RemoveFuncStmt:
 				{
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_FUNCTION;
-					n->objects = list_make1($5->funcname);
-					n->arguments = list_make1($5->funcargs);
+					n->objects = list_make1(list_make1($5));
+					n->arguments = NIL;
 					n->behavior = $6;
 					n->missing_ok = true;
 					n->concurrent = false;
@@ -7275,8 +7273,8 @@ RemoveAggrStmt:
 				{
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_AGGREGATE;
-					n->objects = list_make1($3->funcname);
-					n->arguments = list_make1($3->funcargs);
+					n->objects = list_make1(list_make1($3));
+					n->arguments = NIL;
 					n->behavior = $4;
 					n->missing_ok = false;
 					n->concurrent = false;
@@ -7286,8 +7284,8 @@ RemoveAggrStmt:
 				{
 					DropStmt *n = makeNode(DropStmt);
 					n->removeType = OBJECT_AGGREGATE;
-					n->objects = list_make1($5->funcname);
-					n->arguments = list_make1($5->funcargs);
+					n->objects = list_make1(list_make1($5));
+					n->arguments = NIL;
 					n->behavior = $6;
 					n->missing_ok = true;
 					n->concurrent = false;
@@ -7591,8 +7589,7 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name
 				{
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_AGGREGATE;
-					n->object = $3->funcname;
-					n->objarg = $3->funcargs;
+					n->object = list_make1($3);
 					n->newname = $6;
 					n->missing_ok = false;
 					$$ = (Node *)n;
@@ -7655,8 +7652,7 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name
 				{
 					RenameStmt *n = makeNode(RenameStmt);
 					n->renameType = OBJECT_FUNCTION;
-					n->object = $3->funcname;
-					n->objarg = $3->funcargs;
+					n->object = list_make1($3);
 					n->newname = $6;
 					n->missing_ok = false;
 					$$ = (Node *)n;
@@ -8075,8 +8071,8 @@ AlterObjectDependsStmt:
 					AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
 					n->objectType = OBJECT_FUNCTION;
 					n->relation = NULL;
-					n->objname = $3->funcname;
-					n->objargs = $3->funcargs;
+					n->objname = list_make1($3);
+					n->objargs = NIL;
 					n->extname = makeString($7);
 					$$ = (Node *)n;
 				}
@@ -8123,8 +8119,7 @@ AlterObjectSchemaStmt:
 				{
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_AGGREGATE;
-					n->object = $3->funcname;
-					n->objarg = $3->funcargs;
+					n->object = list_make1($3);
 					n->newschema = $6;
 					n->missing_ok = false;
 					$$ = (Node *)n;
@@ -8169,8 +8164,7 @@ AlterObjectSchemaStmt:
 				{
 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
 					n->objectType = OBJECT_FUNCTION;
-					n->object = $3->funcname;
-					n->objarg = $3->funcargs;
+					n->object = list_make1($3);
 					n->newschema = $6;
 					n->missing_ok = false;
 					$$ = (Node *)n;
@@ -8377,8 +8371,7 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec
 				{
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_AGGREGATE;
-					n->object = $3->funcname;
-					n->objarg = $3->funcargs;
+					n->object = list_make1($3);
 					n->newowner = $6;
 					$$ = (Node *)n;
 				}
@@ -8418,8 +8411,7 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec
 				{
 					AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
 					n->objectType = OBJECT_FUNCTION;
-					n->object = $3->funcname;
-					n->objarg = $3->funcargs;
+					n->object = list_make1($3);
 					n->newowner = $6;
 					$$ = (Node *)n;
 				}
-- 
2.10.2

