From 9a8a71f28fcb1f4fe453155902360eaebfc050dc Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 28 Dec 2016 12:00:00 -0500
Subject: [PATCH 4/6] Replace LookupFuncNameTypeNames() with
 LookupFuncWithArgs()

The old function took function name and function argument list as
separate arguments.  Now that all function signatures are passed around
as a FuncWithArgs struct, this is no longer necessary and can be
replaced by a function that takes FuncWithArgs directly.  Similarly for
aggregates and operators.
---
 src/backend/catalog/aclchk.c        |  3 +--
 src/backend/catalog/objectaddress.c | 40 +++++++++++--------------------------
 src/backend/commands/functioncmds.c | 12 ++++-------
 src/backend/commands/opclasscmds.c  | 30 +++++++---------------------
 src/backend/commands/operatorcmds.c |  5 +----
 src/backend/nodes/copyfuncs.c       |  2 --
 src/backend/nodes/equalfuncs.c      |  2 --
 src/backend/parser/gram.y           | 18 ++++++++---------
 src/backend/parser/parse_func.c     | 32 ++++++++++++++---------------
 src/backend/parser/parse_oper.c     | 24 ++++++++++++----------
 src/include/nodes/parsenodes.h      |  7 ++-----
 src/include/parser/parse_func.h     |  4 ++--
 src/include/parser/parse_oper.h     |  5 ++---
 13 files changed, 68 insertions(+), 116 deletions(-)

diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index fb6c276eaf..0f3e43de4c 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -661,8 +661,7 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
 				FuncWithArgs *func = (FuncWithArgs *) lfirst(cell);
 				Oid			funcid;
 
-				funcid = LookupFuncNameTypeNames(func->funcname,
-												 func->funcargs, false);
+				funcid = LookupFuncWithArgs(func, false);
 				objects = lappend_oid(objects, funcid);
 			}
 			break;
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index e444604071..e05cea7ab6 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -820,36 +820,20 @@ get_object_address(ObjectType objtype, Node *objname,
 				address = get_object_address_type(objtype, (TypeName *) objname, missing_ok);
 				break;
 			case OBJECT_AGGREGATE:
-				{
-					FuncWithArgs *fwa = (FuncWithArgs *) objname;
-					address.classId = ProcedureRelationId;
-					address.objectId =
-						LookupAggNameTypeNames(fwa->funcname, fwa->funcargs, missing_ok);
-					address.objectSubId = 0;
-					break;
-				}
+				address.classId = ProcedureRelationId;
+				address.objectId = LookupAggWithArgs((FuncWithArgs *) objname, missing_ok);
+				address.objectSubId = 0;
+				break;
 			case OBJECT_FUNCTION:
-				{
-					FuncWithArgs *fwa = (FuncWithArgs *) objname;
-					address.classId = ProcedureRelationId;
-					address.objectId =
-						LookupFuncNameTypeNames(fwa->funcname, fwa->funcargs, missing_ok);
-					address.objectSubId = 0;
-					break;
-				}
+				address.classId = ProcedureRelationId;
+				address.objectId = LookupFuncWithArgs((FuncWithArgs *) objname, missing_ok);
+				address.objectSubId = 0;
+				break;
 			case OBJECT_OPERATOR:
-				{
-					FuncWithArgs *fwa = (FuncWithArgs *) objname;
-					address.classId = OperatorRelationId;
-					Assert(list_length(fwa->funcargs) == 2);
-					address.objectId =
-						LookupOperNameTypeNames(NULL, fwa->funcname,
-												(TypeName *) linitial(fwa->funcargs),
-												(TypeName *) lsecond(fwa->funcargs),
-												missing_ok, -1);
-					address.objectSubId = 0;
-					break;
-				}
+				address.classId = OperatorRelationId;
+				address.objectId = LookupOperWithArgs((FuncWithArgs *) objname, missing_ok);
+				address.objectSubId = 0;
+				break;
 			case OBJECT_COLLATION:
 				address.classId = CollationRelationId;
 				address.objectId = get_collation_oid((List *) objname, missing_ok);
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index becafc3045..94aa34867c 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1184,9 +1184,7 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)
 
 	rel = heap_open(ProcedureRelationId, RowExclusiveLock);
 
-	funcOid = LookupFuncNameTypeNames(stmt->func->funcname,
-									  stmt->func->funcargs,
-									  false);
+	funcOid = LookupFuncWithArgs(stmt->func, false);
 
 	tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(funcOid));
 	if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -1461,9 +1459,7 @@ CreateCast(CreateCastStmt *stmt)
 	{
 		Form_pg_proc procstruct;
 
-		funcid = LookupFuncNameTypeNames(stmt->func->funcname,
-										 stmt->func->funcargs,
-										 false);
+		funcid = LookupFuncWithArgs(stmt->func, false);
 
 		tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
 		if (!HeapTupleIsValid(tuple))
@@ -1843,7 +1839,7 @@ CreateTransform(CreateTransformStmt *stmt)
 	 */
 	if (stmt->fromsql)
 	{
-		fromsqlfuncid = LookupFuncNameTypeNames(stmt->fromsql->funcname, stmt->fromsql->funcargs, false);
+		fromsqlfuncid = LookupFuncWithArgs(stmt->fromsql, false);
 
 		if (!pg_proc_ownercheck(fromsqlfuncid, GetUserId()))
 			aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, NameListToString(stmt->fromsql->funcname));
@@ -1868,7 +1864,7 @@ CreateTransform(CreateTransformStmt *stmt)
 
 	if (stmt->tosql)
 	{
-		tosqlfuncid = LookupFuncNameTypeNames(stmt->tosql->funcname, stmt->tosql->funcargs, false);
+		tosqlfuncid = LookupFuncWithArgs(stmt->tosql, false);
 
 		if (!pg_proc_ownercheck(tosqlfuncid, GetUserId()))
 			aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, NameListToString(stmt->tosql->funcname));
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 1d2f8d12c1..cfda571a3e 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -478,19 +478,12 @@ DefineOpClass(CreateOpClassStmt *stmt)
 							 errmsg("invalid operator number %d,"
 									" must be between 1 and %d",
 									item->number, maxOpNumber)));
-				if (item->args != NIL)
-				{
-					TypeName   *typeName1 = (TypeName *) linitial(item->args);
-					TypeName   *typeName2 = (TypeName *) lsecond(item->args);
-
-					operOid = LookupOperNameTypeNames(NULL, item->name,
-													  typeName1, typeName2,
-													  false, -1);
-				}
+				if (item->name->funcargs != NIL)
+					operOid = LookupOperWithArgs(item->name, false);
 				else
 				{
 					/* Default to binary op on input datatype */
-					operOid = LookupOperName(NULL, item->name,
+					operOid = LookupOperName(NULL, item->name->funcname,
 											 typeoid, typeoid,
 											 false, -1);
 				}
@@ -529,8 +522,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
 							 errmsg("invalid procedure number %d,"
 									" must be between 1 and %d",
 									item->number, maxProcNumber)));
-				funcOid = LookupFuncNameTypeNames(item->name, item->args,
-												  false);
+				funcOid = LookupFuncWithArgs(item->name, false);
 #ifdef NOT_USED
 				/* XXX this is unnecessary given the superuser check above */
 				/* Caller must own function */
@@ -863,15 +855,8 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
 							 errmsg("invalid operator number %d,"
 									" must be between 1 and %d",
 									item->number, maxOpNumber)));
-				if (item->args != NIL)
-				{
-					TypeName   *typeName1 = (TypeName *) linitial(item->args);
-					TypeName   *typeName2 = (TypeName *) lsecond(item->args);
-
-					operOid = LookupOperNameTypeNames(NULL, item->name,
-													  typeName1, typeName2,
-													  false, -1);
-				}
+				if (item->name->funcargs != NIL)
+					operOid = LookupOperWithArgs(item->name, false);
 				else
 				{
 					ereport(ERROR,
@@ -914,8 +899,7 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
 							 errmsg("invalid procedure number %d,"
 									" must be between 1 and %d",
 									item->number, maxProcNumber)));
-				funcOid = LookupFuncNameTypeNames(item->name, item->args,
-												  false);
+				funcOid = LookupFuncWithArgs(item->name, false);
 #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 67d08d862b..35b18b0577 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -402,10 +402,7 @@ AlterOperator(AlterOperatorStmt *stmt)
 	Oid			joinOid;
 
 	/* Look up the operator */
-	oprId = LookupOperNameTypeNames(NULL, stmt->opername,
-									(TypeName *) linitial(stmt->operargs),
-									(TypeName *) lsecond(stmt->operargs),
-									false, -1);
+	oprId = LookupOperWithArgs(stmt->opername, false);
 	catalog = heap_open(OperatorRelationId, RowExclusiveLock);
 	tup = SearchSysCacheCopy1(OPEROID, ObjectIdGetDatum(oprId));
 	if (tup == NULL)
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 13f7f110fb..b36718ad93 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3278,7 +3278,6 @@ _copyAlterOperatorStmt(const AlterOperatorStmt *from)
 	AlterOperatorStmt *newnode = makeNode(AlterOperatorStmt);
 
 	COPY_NODE_FIELD(opername);
-	COPY_NODE_FIELD(operargs);
 	COPY_NODE_FIELD(options);
 
 	return newnode;
@@ -3451,7 +3450,6 @@ _copyCreateOpClassItem(const CreateOpClassItem *from)
 
 	COPY_SCALAR_FIELD(itemtype);
 	COPY_NODE_FIELD(name);
-	COPY_NODE_FIELD(args);
 	COPY_SCALAR_FIELD(number);
 	COPY_NODE_FIELD(order_family);
 	COPY_NODE_FIELD(class_args);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 3538932662..dcaac81975 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1375,7 +1375,6 @@ static bool
 _equalAlterOperatorStmt(const AlterOperatorStmt *a, const AlterOperatorStmt *b)
 {
 	COMPARE_NODE_FIELD(opername);
-	COMPARE_NODE_FIELD(operargs);
 	COMPARE_NODE_FIELD(options);
 
 	return true;
@@ -1520,7 +1519,6 @@ _equalCreateOpClassItem(const CreateOpClassItem *a, const CreateOpClassItem *b)
 {
 	COMPARE_SCALAR_FIELD(itemtype);
 	COMPARE_NODE_FIELD(name);
-	COMPARE_NODE_FIELD(args);
 	COMPARE_SCALAR_FIELD(number);
 	COMPARE_NODE_FIELD(order_family);
 	COMPARE_NODE_FIELD(class_args);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c7d08784f4..6d15297bee 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -5715,9 +5715,11 @@ opclass_item:
 			OPERATOR Iconst any_operator opclass_purpose opt_recheck
 				{
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
+					FuncWithArgs *fwa = makeNode(FuncWithArgs);
+					fwa->funcname = $3;
+					fwa->funcargs = NIL;
 					n->itemtype = OPCLASS_ITEM_OPERATOR;
-					n->name = $3;
-					n->args = NIL;
+					n->name = fwa;
 					n->number = $2;
 					n->order_family = $4;
 					$$ = (Node *) n;
@@ -5727,8 +5729,7 @@ opclass_item:
 				{
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_OPERATOR;
-					n->name = $3->funcname;
-					n->args = $3->funcargs;
+					n->name = $3;
 					n->number = $2;
 					n->order_family = $4;
 					$$ = (Node *) n;
@@ -5737,8 +5738,7 @@ opclass_item:
 				{
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_FUNCTION;
-					n->name = $3->funcname;
-					n->args = $3->funcargs;
+					n->name = $3;
 					n->number = $2;
 					$$ = (Node *) n;
 				}
@@ -5746,8 +5746,7 @@ opclass_item:
 				{
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_FUNCTION;
-					n->name = $6->funcname;
-					n->args = $6->funcargs;
+					n->name = $6;
 					n->number = $2;
 					n->class_args = $4;
 					$$ = (Node *) n;
@@ -8714,8 +8713,7 @@ AlterOperatorStmt:
 			ALTER OPERATOR operator_with_argtypes SET '(' operator_def_list ')'
 				{
 					AlterOperatorStmt *n = makeNode(AlterOperatorStmt);
-					n->opername = $3->funcname;
-					n->operargs = $3->funcargs;
+					n->opername = $3;
 					n->options = $6;
 					$$ = (Node *)n;
 				}
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 7d9b4157d4..c46b226cfd 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -1933,19 +1933,19 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
 }
 
 /*
- * LookupFuncNameTypeNames
+ * LookupFuncWithArgs
  *		Like LookupFuncName, but the argument types are specified by a
- *		list of TypeName nodes.
+ *		FuncWithArgs node.
  */
 Oid
-LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
+LookupFuncWithArgs(FuncWithArgs *func, bool noError)
 {
 	Oid			argoids[FUNC_MAX_ARGS];
 	int			argcount;
 	int			i;
 	ListCell   *args_item;
 
-	argcount = list_length(argtypes);
+	argcount = list_length(func->funcargs);
 	if (argcount > FUNC_MAX_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
@@ -1954,7 +1954,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
 							   FUNC_MAX_ARGS,
 							   FUNC_MAX_ARGS)));
 
-	args_item = list_head(argtypes);
+	args_item = list_head(func->funcargs);
 	for (i = 0; i < argcount; i++)
 	{
 		TypeName   *t = (TypeName *) lfirst(args_item);
@@ -1963,19 +1963,19 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
 		args_item = lnext(args_item);
 	}
 
-	return LookupFuncName(funcname, argcount, argoids, noError);
+	return LookupFuncName(func->funcname, argcount, argoids, noError);
 }
 
 /*
- * LookupAggNameTypeNames
- *		Find an aggregate function given a name and list of TypeName nodes.
+ * LookupAggWithArgs
+ *		Find an aggregate function from a given FuncWithArgs node.
  *
- * This is almost like LookupFuncNameTypeNames, but the error messages refer
+ * This is almost like LookupFuncWithArgs, but the error messages refer
  * to aggregates rather than plain functions, and we verify that the found
  * function really is an aggregate.
  */
 Oid
-LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
+LookupAggWithArgs(FuncWithArgs *agg, bool noError)
 {
 	Oid			argoids[FUNC_MAX_ARGS];
 	int			argcount;
@@ -1985,7 +1985,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
 	HeapTuple	ftup;
 	Form_pg_proc pform;
 
-	argcount = list_length(argtypes);
+	argcount = list_length(agg->funcargs);
 	if (argcount > FUNC_MAX_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
@@ -1995,7 +1995,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
 							   FUNC_MAX_ARGS)));
 
 	i = 0;
-	foreach(lc, argtypes)
+	foreach(lc, agg->funcargs)
 	{
 		TypeName   *t = (TypeName *) lfirst(lc);
 
@@ -2003,7 +2003,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
 		i++;
 	}
 
-	oid = LookupFuncName(aggname, argcount, argoids, true);
+	oid = LookupFuncName(agg->funcname, argcount, argoids, true);
 
 	if (!OidIsValid(oid))
 	{
@@ -2013,12 +2013,12 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
 			ereport(ERROR,
 					(errcode(ERRCODE_UNDEFINED_FUNCTION),
 					 errmsg("aggregate %s(*) does not exist",
-							NameListToString(aggname))));
+							NameListToString(agg->funcname))));
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_UNDEFINED_FUNCTION),
 					 errmsg("aggregate %s does not exist",
-							func_signature_string(aggname, argcount,
+							func_signature_string(agg->funcname, argcount,
 												  NIL, argoids))));
 	}
 
@@ -2037,7 +2037,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
 		ereport(ERROR,
 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 				 errmsg("function %s is not an aggregate",
-						func_signature_string(aggname, argcount,
+						func_signature_string(agg->funcname, argcount,
 											  NIL, argoids))));
 	}
 
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index aecda6d933..3747a870f3 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -132,32 +132,34 @@ LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright,
 }
 
 /*
- * LookupOperNameTypeNames
+ * LookupOperWithArgs
  *		Like LookupOperName, but the argument types are specified by
- *		TypeName nodes.
- *
- * Pass oprleft = NULL for a prefix op, oprright = NULL for a postfix op.
+ *		a FuncWithArg node.
  */
 Oid
-LookupOperNameTypeNames(ParseState *pstate, List *opername,
-						TypeName *oprleft, TypeName *oprright,
-						bool noError, int location)
+LookupOperWithArgs(FuncWithArgs *oper, bool noError)
 {
+	TypeName   *oprleft,
+			   *oprright;
 	Oid			leftoid,
 				rightoid;
 
+	Assert(list_length(oper->funcargs) == 2);
+	oprleft = linitial(oper->funcargs);
+	oprright = lsecond(oper->funcargs);
+
 	if (oprleft == NULL)
 		leftoid = InvalidOid;
 	else
-		leftoid = LookupTypeNameOid(pstate, oprleft, noError);
+		leftoid = LookupTypeNameOid(NULL, oprleft, noError);
 
 	if (oprright == NULL)
 		rightoid = InvalidOid;
 	else
-		rightoid = LookupTypeNameOid(pstate, oprright, noError);
+		rightoid = LookupTypeNameOid(NULL, oprright, noError);
 
-	return LookupOperName(pstate, opername, leftoid, rightoid,
-						  noError, location);
+	return LookupOperName(NULL, oper->funcname, leftoid, rightoid,
+						  noError, -1);
 }
 
 /*
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 9fe6e9ed09..e10b8da99f 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2379,9 +2379,7 @@ typedef struct CreateOpClassItem
 {
 	NodeTag		type;
 	int			itemtype;		/* see codes above */
-	/* fields used for an operator or function item: */
-	List	   *name;			/* operator or function name */
-	List	   *args;			/* argument types */
+	FuncWithArgs *name;			/* operator or function name and args */
 	int			number;			/* strategy num or support proc num */
 	List	   *order_family;	/* only used for ordering operators */
 	List	   *class_args;		/* only used for functions */
@@ -2690,8 +2688,7 @@ typedef struct AlterOwnerStmt
 typedef struct AlterOperatorStmt
 {
 	NodeTag		type;
-	List	   *opername;		/* operator name */
-	List	   *operargs;		/* operator's argument TypeNames */
+	FuncWithArgs *opername;		/* operator name and argument types */
 	List	   *options;		/* List of DefElem nodes */
 } AlterOperatorStmt;
 
diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h
index ed16d36982..b1a5494d73 100644
--- a/src/include/parser/parse_func.h
+++ b/src/include/parser/parse_func.h
@@ -62,9 +62,9 @@ extern const char *func_signature_string(List *funcname, int nargs,
 
 extern Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes,
 			   bool noError);
-extern Oid LookupFuncNameTypeNames(List *funcname, List *argtypes,
+extern Oid LookupFuncWithArgs(FuncWithArgs *func,
 						bool noError);
-extern Oid LookupAggNameTypeNames(List *aggname, List *argtypes,
+extern Oid LookupAggWithArgs(FuncWithArgs *agg,
 					   bool noError);
 
 extern void check_srf_call_placement(ParseState *pstate, int location);
diff --git a/src/include/parser/parse_oper.h b/src/include/parser/parse_oper.h
index 03bb5b9a14..51c1247a61 100644
--- a/src/include/parser/parse_oper.h
+++ b/src/include/parser/parse_oper.h
@@ -15,6 +15,7 @@
 #define PARSE_OPER_H
 
 #include "access/htup.h"
+#include "nodes/parsenodes.h"
 #include "parser/parse_node.h"
 
 
@@ -24,9 +25,7 @@ typedef HeapTuple Operator;
 extern Oid LookupOperName(ParseState *pstate, List *opername,
 			   Oid oprleft, Oid oprright,
 			   bool noError, int location);
-extern Oid LookupOperNameTypeNames(ParseState *pstate, List *opername,
-						TypeName *oprleft, TypeName *oprright,
-						bool noError, int location);
+extern Oid LookupOperWithArgs(FuncWithArgs *oper, bool noError);
 
 /* Routines to find operators matching a name and given input types */
 /* NB: the selected operator may require coercion of the input types! */
-- 
2.11.0

