Index: src/backend/catalog/pg_proc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_proc.c,v
retrieving revision 1.168
diff -u -r1.168 pg_proc.c
--- src/backend/catalog/pg_proc.c	8 Oct 2009 02:39:18 -0000	1.168
+++ src/backend/catalog/pg_proc.c	18 Nov 2009 14:46:25 -0000
@@ -780,6 +780,31 @@
 	/* Postpone body checks if !check_function_bodies */
 	if (check_function_bodies)
 	{
+		char	  **argnames = NULL;
+		Datum		proargnames;
+		
+		/* Fetch and parse the param names */
+		proargnames = SysCacheGetAttr(PROCOID, tuple,
+									  Anum_pg_proc_proargnames,
+									  &isnull);
+		if (!isnull)
+		{
+			int n_arg_names;
+			Datum proargmodes;
+
+			proargmodes = SysCacheGetAttr(PROCOID, tuple,
+										  Anum_pg_proc_proargmodes,
+										  &isnull);
+			if (isnull)
+				proargmodes = PointerGetDatum(NULL);
+
+			n_arg_names = get_func_input_arg_names(proargnames,
+												   proargmodes,
+												   &argnames);
+
+			Assert(n_arg_names == func->pronargs);
+		}
+
 		tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
 		if (isnull)
 			elog(ERROR, "null prosrc");
@@ -806,7 +831,9 @@
 		if (!haspolyarg)
 		{
 			querytree_list = pg_parse_and_rewrite(prosrc,
+												  NameStr(proc->proname),
 												  proc->proargtypes.values,
+												  argnames,
 												  proc->pronargs);
 			(void) check_sql_fn_retval(funcoid, proc->prorettype,
 									   querytree_list,
Index: src/backend/commands/copy.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/copy.c,v
retrieving revision 1.317
diff -u -r1.317 copy.c
--- src/backend/commands/copy.c	21 Sep 2009 20:10:21 -0000	1.317
+++ src/backend/commands/copy.c	18 Nov 2009 14:46:25 -0000
@@ -1061,7 +1061,7 @@
 		 * DECLARE CURSOR and PREPARE.)  XXX FIXME someday.
 		 */
 		rewritten = pg_analyze_and_rewrite((Node *) copyObject(stmt->query),
-										   queryString, NULL, 0);
+										   queryString, NULL, NULL, NULL, 0);
 
 		/* We don't expect more or less than one result query */
 		if (list_length(rewritten) != 1)
Index: src/backend/commands/prepare.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/prepare.c,v
retrieving revision 1.100
diff -u -r1.100 prepare.c
--- src/backend/commands/prepare.c	4 Nov 2009 22:26:05 -0000	1.100
+++ src/backend/commands/prepare.c	18 Nov 2009 14:46:26 -0000
@@ -467,7 +467,9 @@
 	plansource = CreateCachedPlan(raw_parse_tree,
 								  query_string,
 								  commandTag,
+								  NULL,
 								  param_types,
+								  NULL,
 								  num_params,
 								  cursor_options,
 								  stmt_list,
Index: src/backend/commands/view.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/view.c,v
retrieving revision 1.119
diff -u -r1.119 view.c
--- src/backend/commands/view.c	5 Nov 2009 23:24:23 -0000	1.119
+++ src/backend/commands/view.c	18 Nov 2009 14:46:26 -0000
@@ -403,7 +403,7 @@
 	 * this ensures we don't corrupt a prepared statement, for example.
 	 */
 	viewParse = parse_analyze((Node *) copyObject(stmt->query),
-							  queryString, NULL, 0);
+							  queryString, NULL, NULL, NULL, 0);
 
 	/*
 	 * The grammar should ensure that the result is a single SELECT Query.
Index: src/backend/executor/functions.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/executor/functions.c,v
retrieving revision 1.136
diff -u -r1.136 functions.c
--- src/backend/executor/functions.c	4 Nov 2009 22:26:05 -0000	1.136
+++ src/backend/executor/functions.c	18 Nov 2009 14:46:26 -0000
@@ -77,6 +77,7 @@
 	char	   *src;			/* function body text (for error msgs) */
 
 	Oid		   *argtypes;		/* resolved types of arguments */
+	char	  **argnames;		/* names of arguments */
 	Oid			rettype;		/* actual return type */
 	int16		typlen;			/* length of the return type */
 	bool		typbyval;		/* true if return type is pass by value */
@@ -222,6 +223,7 @@
 	Form_pg_proc procedureStruct;
 	SQLFunctionCachePtr fcache;
 	Oid		   *argOidVect;
+	char	  **argNameVect;
 	int			nargs;
 	List	   *queryTree_list;
 	Datum		tmp;
@@ -274,6 +276,7 @@
 	if (nargs > 0)
 	{
 		int			argnum;
+		Datum		proargnames;
 
 		argOidVect = (Oid *) palloc(nargs * sizeof(Oid));
 		memcpy(argOidVect,
@@ -295,10 +298,37 @@
 				argOidVect[argnum] = argtype;
 			}
 		}
+
+		proargnames = SysCacheGetAttr(PROCOID, procedureTuple,
+									  Anum_pg_proc_proargnames,
+									  &isNull);
+		if (!isNull)
+		{
+			int n_arg_names;
+			Datum proargmodes;
+
+			proargmodes = SysCacheGetAttr(PROCOID, procedureTuple,
+										  Anum_pg_proc_proargmodes,
+										  &isNull);
+			if (isNull)
+				proargmodes = PointerGetDatum(NULL);
+
+			n_arg_names = get_func_input_arg_names(proargnames,
+												   proargmodes,
+												   &argNameVect);
+
+			Assert(n_arg_names == funcform->pronargs);
+		} else {
+			argNameVect = NULL;
+		}
 	}
 	else
+	{
 		argOidVect = NULL;
+		argNameVect = NULL;
+	}
 	fcache->argtypes = argOidVect;
+	fcache->argnames = argNameVect;
 
 	/*
 	 * And of course we need the function body text.
@@ -314,7 +344,10 @@
 	/*
 	 * Parse and rewrite the queries in the function text.
 	 */
-	queryTree_list = pg_parse_and_rewrite(fcache->src, argOidVect, nargs);
+	queryTree_list = pg_parse_and_rewrite(fcache->src,
+										  NameStr(procedureStruct->proname),
+										  argOidVect, argNameVect,
+										  nargs);
 
 	/*
 	 * Check that the function returns the type it claims to.  Although in
Index: src/backend/executor/spi.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/executor/spi.c,v
retrieving revision 1.211
diff -u -r1.211 spi.c
--- src/backend/executor/spi.c	4 Nov 2009 22:26:06 -0000	1.211
+++ src/backend/executor/spi.c	18 Nov 2009 14:46:27 -0000
@@ -1714,7 +1714,9 @@
 			/* Need a copyObject here to keep parser from modifying raw tree */
 			stmt_list = pg_analyze_and_rewrite(copyObject(parsetree),
 											   src,
+											   NULL,
 											   plan->argtypes,
+											   NULL,
 											   plan->nargs);
 		}
 		stmt_list = pg_plan_queries(stmt_list, cursor_options, boundParams);
@@ -2403,7 +2405,9 @@
 		newsource = CreateCachedPlan(plansource->raw_parse_tree,
 									 plansource->query_string,
 									 plansource->commandTag,
+									 NULL,
 									 newplan->argtypes,
+									 NULL,
 									 newplan->nargs,
 									 newplan->cursor_options,
 									 cplan->stmt_list,
Index: src/backend/nodes/params.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/params.c,v
retrieving revision 1.12
diff -u -r1.12 params.c
--- src/backend/nodes/params.c	4 Nov 2009 22:26:06 -0000	1.12
+++ src/backend/nodes/params.c	18 Nov 2009 14:46:27 -0000
@@ -116,6 +116,6 @@
 
 			ptypes[i] = prm->ptype;
 		}
-		parse_fixed_parameters(pstate, ptypes, params->numParams);
+		parse_fixed_parameters(pstate, NULL, ptypes, NULL, params->numParams);
 	}
 }
Index: src/backend/optimizer/util/clauses.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v
retrieving revision 1.279
diff -u -r1.279 clauses.c
--- src/backend/optimizer/util/clauses.c	8 Oct 2009 02:39:21 -0000	1.279
+++ src/backend/optimizer/util/clauses.c	18 Nov 2009 14:46:28 -0000
@@ -3670,8 +3670,10 @@
 {
 	Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
 	Oid		   *argtypes;
+	char	  **argnames;
 	char	   *src;
 	Datum		tmp;
+	Datum       proargnames;
 	bool		isNull;
 	MemoryContext oldcxt;
 	MemoryContext mycxt;
@@ -3734,6 +3736,32 @@
 		}
 	}
 
+	/* Fetch and parse the param names */
+	proargnames = SysCacheGetAttr(PROCOID, func_tuple,
+								  Anum_pg_proc_proargnames,
+								  &isNull);
+	if (!isNull)
+	{
+		int n_arg_names;
+        Datum proargmodes;
+
+		proargmodes = SysCacheGetAttr(PROCOID, func_tuple,
+									  Anum_pg_proc_proargmodes,
+									  &isNull);
+		if (isNull)
+			proargmodes = PointerGetDatum(NULL);
+
+		n_arg_names = get_func_input_arg_names(proargnames,
+											   proargmodes,
+											   &argnames);
+
+		Assert(n_arg_names == funcform->pronargs);
+	}
+	else
+	{
+		argnames = NULL;
+	}
+
 	/* Fetch and parse the function body */
 	tmp = SysCacheGetAttr(PROCOID,
 						  func_tuple,
@@ -3754,7 +3782,8 @@
 		goto fail;
 
 	querytree = parse_analyze(linitial(raw_parsetree_list), src,
-							  argtypes, funcform->pronargs);
+							  NameStr(funcform->proname), argtypes, argnames,
+							  funcform->pronargs);
 
 	/*
 	 * The single command must be a simple "SELECT expression".
@@ -4085,8 +4114,10 @@
 	HeapTuple	func_tuple;
 	Form_pg_proc funcform;
 	Oid		   *argtypes;
+	char	  **argnames;
 	char	   *src;
 	Datum		tmp;
+	Datum		proargnames;
 	bool		isNull;
 	MemoryContext oldcxt;
 	MemoryContext mycxt;
@@ -4216,6 +4247,32 @@
 		}
 	}
 
+	/* Fetch and parse the param names */
+	proargnames = SysCacheGetAttr(PROCOID, func_tuple,
+								  Anum_pg_proc_proargnames,
+								  &isNull);
+	if (!isNull)
+	{
+		int n_arg_names;
+        Datum proargmodes;
+
+		proargmodes = SysCacheGetAttr(PROCOID, func_tuple,
+									  Anum_pg_proc_proargmodes,
+									  &isNull);
+		if (isNull)
+			proargmodes = PointerGetDatum(NULL);
+
+		n_arg_names = get_func_input_arg_names(proargnames,
+											   proargmodes,
+											   &argnames);
+
+		Assert(n_arg_names == funcform->pronargs);
+	}
+	else
+	{
+		argnames = NULL;
+	}
+
 	/* Fetch and parse the function body */
 	tmp = SysCacheGetAttr(PROCOID,
 						  func_tuple,
@@ -4235,7 +4292,9 @@
 		goto fail;
 
 	querytree_list = pg_analyze_and_rewrite(linitial(raw_parsetree_list), src,
-											argtypes, funcform->pronargs);
+											NameStr(funcform->proname),
+											argtypes, argnames,
+											funcform->pronargs);
 	if (list_length(querytree_list) != 1)
 		goto fail;
 	querytree = linitial(querytree_list);
Index: src/backend/parser/analyze.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/analyze.c,v
retrieving revision 1.396
diff -u -r1.396 analyze.c
--- src/backend/parser/analyze.c	31 Oct 2009 01:41:31 -0000	1.396
+++ src/backend/parser/analyze.c	18 Nov 2009 14:46:28 -0000
@@ -77,8 +77,8 @@
  * a dummy CMD_UTILITY Query node.
  */
 Query *
-parse_analyze(Node *parseTree, const char *sourceText,
-			  Oid *paramTypes, int numParams)
+parse_analyze(Node *parseTree, const char *sourceText, char *funcName,
+			  Oid *paramTypes, char **paramNames, int numParams)
 {
 	ParseState *pstate = make_parsestate(NULL);
 	Query	   *query;
@@ -88,7 +88,8 @@
 	pstate->p_sourcetext = sourceText;
 
 	if (numParams > 0)
-		parse_fixed_parameters(pstate, paramTypes, numParams);
+		parse_fixed_parameters(pstate, funcName, paramTypes, paramNames,
+							   numParams);
 
 	query = transformStmt(pstate, parseTree);
 
Index: src/backend/parser/parse_param.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/parse_param.c,v
retrieving revision 2.1
diff -u -r2.1 parse_param.c
--- src/backend/parser/parse_param.c	31 Oct 2009 01:41:31 -0000	2.1
+++ src/backend/parser/parse_param.c	18 Nov 2009 14:46:29 -0000
@@ -34,7 +34,9 @@
 
 typedef struct FixedParamState
 {
+	char       *funcName;		/* name of the current function */
 	Oid		   *paramTypes;		/* array of parameter type OIDs */
+	char	  **paramNames;		/* array of parameter name strings */
 	int			numParams;		/* number of array entries */
 } FixedParamState;
 
@@ -51,6 +53,7 @@
 } VarParamState;
 
 static Node *fixed_paramref_hook(ParseState *pstate, ParamRef *pref);
+static Node *fixed_pnameref_hook(ParseState *pstate, ColumnRef *pref, Node *var);
 static Node *variable_paramref_hook(ParseState *pstate, ParamRef *pref);
 static Node *variable_coerce_param_hook(ParseState *pstate, Param *param,
 										Oid targetTypeId, int32 targetTypeMod,
@@ -62,15 +65,19 @@
  * Set up to process a query containing references to fixed parameters.
  */
 void
-parse_fixed_parameters(ParseState *pstate,
-					   Oid *paramTypes, int numParams)
+parse_fixed_parameters(ParseState *pstate, char *funcName,
+					   Oid *paramTypes, char **paramNames, int numParams)
 {
 	FixedParamState *parstate = palloc(sizeof(FixedParamState));
 
+	parstate->funcName = funcName;
 	parstate->paramTypes = paramTypes;
+	parstate->paramNames = paramNames;
 	parstate->numParams = numParams;
 	pstate->p_ref_hook_state = (void *) parstate;
 	pstate->p_paramref_hook = fixed_paramref_hook;
+	Assert(!pstate->p_post_columnref_hook);
+	pstate->p_post_columnref_hook = fixed_pnameref_hook;
 	/* no need to use p_coerce_param_hook */
 }
 
@@ -118,6 +125,76 @@
 }
 
 /*
+ * Transform a PNameRef using fixed parameter types.
+ */
+static Node *
+fixed_pnameref_hook(ParseState *pstate, ColumnRef *cref, Node *var)
+{
+	FixedParamState *parstate = (FixedParamState *) pstate->p_ref_hook_state;
+	char	   *pname;
+	Param	   *param;
+	int         i;
+
+	/* this was something of a judgement call: if another column reference
+	 * is qualified before our argument, don't look up a param */
+	/* can't do anything without a list of parameter names */
+	if (var != NULL || parstate->paramNames == NULL)
+		return NULL;
+
+	switch (list_length(cref->fields))
+	{
+		case 1:
+			{
+				Node	   *field1 = (Node *) linitial(cref->fields);
+
+				Assert(IsA(field1, String));
+				pname = strVal(field1);
+				break;
+			}
+		case 2:
+			{
+				char	   *fname;
+				Node	   *field1 = (Node *) linitial(cref->fields);
+				Node	   *field2 = (Node *) lsecond(cref->fields);
+
+				Assert(IsA(field1, String));
+				fname = strVal(field1);
+
+				if (parstate->funcName == NULL ||
+					fname == NULL ||
+					strcmp(fname, parstate->funcName))
+					return NULL;
+
+				Assert(IsA(field2, String));
+				pname = strVal(field2);
+				break;
+			}
+		default:
+			/* too many names, ignore */
+			return NULL;
+	}
+
+	/* Find parameter in name list */
+	for ( i = 0; i < parstate->numParams; i++ )
+	{
+		if (parstate->paramNames[i] != NULL &&
+			pname != NULL &&
+			!strcmp(pname, parstate->paramNames[i]))
+		{
+			param = makeNode(Param);
+			param->paramkind = PARAM_EXTERN;
+			param->paramid = i + 1;
+			param->paramtype = parstate->paramTypes[i];
+			param->paramtypmod = -1;
+			param->location = cref->location;
+			return (Node *) param;
+		}
+	}
+
+	return NULL;
+}
+
+/*
  * Transform a ParamRef using variable parameter types.
  *
  * The only difference here is we must enlarge the parameter type array
Index: src/backend/tcop/postgres.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/tcop/postgres.c,v
retrieving revision 1.575
diff -u -r1.575 postgres.c
--- src/backend/tcop/postgres.c	4 Nov 2009 22:26:06 -0000	1.575
+++ src/backend/tcop/postgres.c	18 Nov 2009 14:46:30 -0000
@@ -512,7 +512,9 @@
  */
 List *
 pg_parse_and_rewrite(const char *query_string,	/* string to execute */
+					 char *funcName,	/* function name */
 					 Oid *paramTypes,	/* parameter types */
+					 char **paramNames, /* parameter names */
 					 int numParams)		/* number of parameters */
 {
 	List	   *raw_parsetree_list;
@@ -535,7 +537,9 @@
 		querytree_list = list_concat(querytree_list,
 									 pg_analyze_and_rewrite(parsetree,
 															query_string,
+															funcName,
 															paramTypes,
+															paramNames,
 															numParams));
 	}
 
@@ -599,7 +603,8 @@
  */
 List *
 pg_analyze_and_rewrite(Node *parsetree, const char *query_string,
-					   Oid *paramTypes, int numParams)
+					   char *funcName, Oid *paramTypes, char **paramNames,
+					   int numParams)
 {
 	Query	   *query;
 	List	   *querytree_list;
@@ -612,7 +617,8 @@
 	if (log_parser_stats)
 		ResetUsage();
 
-	query = parse_analyze(parsetree, query_string, paramTypes, numParams);
+	query = parse_analyze(parsetree, query_string, funcName,
+						  paramTypes, paramNames, numParams);
 
 	if (log_parser_stats)
 		ShowUsage("PARSE ANALYSIS STATISTICS");
@@ -970,7 +976,7 @@
 		oldcontext = MemoryContextSwitchTo(MessageContext);
 
 		querytree_list = pg_analyze_and_rewrite(parsetree, query_string,
-												NULL, 0);
+												NULL, NULL, NULL, 0);
 
 		plantree_list = pg_plan_queries(querytree_list, 0, NULL);
 
Index: src/backend/utils/cache/plancache.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/cache/plancache.c,v
retrieving revision 1.31
diff -u -r1.31 plancache.c
--- src/backend/utils/cache/plancache.c	4 Nov 2009 22:26:06 -0000	1.31
+++ src/backend/utils/cache/plancache.c	18 Nov 2009 14:46:30 -0000
@@ -110,7 +110,9 @@
 CreateCachedPlan(Node *raw_parse_tree,
 				 const char *query_string,
 				 const char *commandTag,
+				 char *func_name,
 				 Oid *param_types,
+				 char **param_names,
 				 int num_params,
 				 int cursor_options,
 				 List *stmt_list,
@@ -148,13 +150,26 @@
 	plansource->raw_parse_tree = copyObject(raw_parse_tree);
 	plansource->query_string = pstrdup(query_string);
 	plansource->commandTag = commandTag;		/* no copying needed */
+	plansource->func_name = func_name;
 	if (num_params > 0)
 	{
 		plansource->param_types = (Oid *) palloc(num_params * sizeof(Oid));
 		memcpy(plansource->param_types, param_types, num_params * sizeof(Oid));
+
+		if( param_names != NULL ) {
+			plansource->param_names =
+				(char **) palloc(num_params * sizeof(char **));
+			memcpy(plansource->param_names, param_names,
+				   num_params * sizeof(char *));
+		} else {
+			plansource->param_names = NULL;
+		}
 	}
 	else
+    {
 		plansource->param_types = NULL;
+		plansource->param_names = NULL;
+	}
 	plansource->num_params = num_params;
 	/* these can be set later with CachedPlanSetParserHook: */
 	plansource->parserSetup = NULL;
@@ -530,7 +545,9 @@
 		else
 			slist = pg_analyze_and_rewrite(rawtree,
 										   plansource->query_string,
+										   plansource->func_name,
 										   plansource->param_types,
+										   plansource->param_names,
 										   plansource->num_params);
 
 		if (plansource->fully_planned)
Index: src/include/nodes/params.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/params.h,v
retrieving revision 1.39
diff -u -r1.39 params.h
--- src/include/nodes/params.h	4 Nov 2009 22:26:06 -0000	1.39
+++ src/include/nodes/params.h	18 Nov 2009 14:46:30 -0000
@@ -56,6 +56,7 @@
 	bool		isnull;			/* is it NULL? */
 	uint16		pflags;			/* flag bits, see above */
 	Oid			ptype;			/* parameter's datatype, or 0 */
+	char	   *pname;			/* parameter's name, or NULL */
 } ParamExternData;
 
 typedef struct ParamListInfoData *ParamListInfo;
Index: src/include/parser/analyze.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/parser/analyze.h,v
retrieving revision 1.43
diff -u -r1.43 analyze.h
--- src/include/parser/analyze.h	28 Oct 2009 14:55:47 -0000	1.43
+++ src/include/parser/analyze.h	18 Nov 2009 14:46:30 -0000
@@ -18,7 +18,8 @@
 
 
 extern Query *parse_analyze(Node *parseTree, const char *sourceText,
-			  Oid *paramTypes, int numParams);
+							char *funcName, Oid *paramTypes, char **paramNames,
+							int numParams);
 extern Query *parse_analyze_varparams(Node *parseTree, const char *sourceText,
 						Oid **paramTypes, int *numParams);
 
Index: src/include/parser/parse_param.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/parser/parse_param.h,v
retrieving revision 1.1
diff -u -r1.1 parse_param.h
--- src/include/parser/parse_param.h	31 Oct 2009 01:41:31 -0000	1.1
+++ src/include/parser/parse_param.h	18 Nov 2009 14:46:30 -0000
@@ -15,8 +15,8 @@
 
 #include "parser/parse_node.h"
 
-extern void parse_fixed_parameters(ParseState *pstate,
-								   Oid *paramTypes, int numParams);
+extern void parse_fixed_parameters(ParseState *pstate, char *funcName,
+								   Oid *paramTypes, char **paramNames, int numParams);
 extern void parse_variable_parameters(ParseState *pstate,
 									  Oid **paramTypes, int *numParams);
 extern void check_variable_parameters(ParseState *pstate, Query *query);
Index: src/include/tcop/tcopprot.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/tcop/tcopprot.h,v
retrieving revision 1.101
diff -u -r1.101 tcopprot.h
--- src/include/tcop/tcopprot.h	4 Nov 2009 22:26:07 -0000	1.101
+++ src/include/tcop/tcopprot.h	18 Nov 2009 14:46:30 -0000
@@ -44,11 +44,13 @@
 
 extern int	log_statement;
 
-extern List *pg_parse_and_rewrite(const char *query_string,
-					 Oid *paramTypes, int numParams);
+extern List *pg_parse_and_rewrite(const char *query_string, char *funcName,
+								  Oid *paramTypes, char **paramNames,
+								  int numParams);
 extern List *pg_parse_query(const char *query_string);
 extern List *pg_analyze_and_rewrite(Node *parsetree, const char *query_string,
-					   Oid *paramTypes, int numParams);
+									char *funcName, Oid *paramTypes,
+									char **paramNames, int numParams);
 extern List *pg_analyze_and_rewrite_params(Node *parsetree,
 										   const char *query_string,
 										   ParserSetupHook parserSetup,
Index: src/include/utils/plancache.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/plancache.h,v
retrieving revision 1.16
diff -u -r1.16 plancache.h
--- src/include/utils/plancache.h	4 Nov 2009 22:26:07 -0000	1.16
+++ src/include/utils/plancache.h	18 Nov 2009 14:46:30 -0000
@@ -49,7 +49,9 @@
 	Node	   *raw_parse_tree; /* output of raw_parser() */
 	char	   *query_string;	/* text of query (as of 8.4, never NULL) */
 	const char *commandTag;		/* command tag (a constant!), or NULL */
+	char       *func_name;      /* function name or NULL */
 	Oid		   *param_types;	/* array of parameter type OIDs, or NULL */
+	char	  **param_names;	/* array of parameter names, or NULL */
 	int			num_params;		/* length of param_types array */
 	ParserSetupHook parserSetup;	/* alternative parameter spec method */
 	void	   *parserSetupArg;	
@@ -92,7 +94,9 @@
 extern CachedPlanSource *CreateCachedPlan(Node *raw_parse_tree,
 				 const char *query_string,
 				 const char *commandTag,
+				 char *func_name,
 				 Oid *param_types,
+				 char **param_names,
 				 int num_params,
 				 int cursor_options,
 				 List *stmt_list,