Commit 304d6d5b authored by Tom Lane's avatar Tom Lane

Support function parameter names in plpgsql. This is the last of

Dennis Bjorklund's original patch for function parameter names, but
there's still plenty left to do (documentation for instance...)
parent a95df8f2
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.71 2004/01/06 23:55:19 tgl Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.72 2004/01/07 06:20:02 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "parser/gramparse.h" #include "parser/gramparse.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
#include "tcop/tcopprot.h" #include "tcop/tcopprot.h"
#include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/syscache.h" #include "utils/syscache.h"
...@@ -102,6 +103,7 @@ static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo, ...@@ -102,6 +103,7 @@ static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo,
HeapTuple procTup, HeapTuple procTup,
PLpgSQL_func_hashkey *hashkey); PLpgSQL_func_hashkey *hashkey);
static void plpgsql_compile_error_callback(void *arg); static void plpgsql_compile_error_callback(void *arg);
static char **fetchArgNames(HeapTuple procTup, int nargs);
static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod); static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod);
static void compute_function_hashkey(FunctionCallInfo fcinfo, static void compute_function_hashkey(FunctionCallInfo fcinfo,
Form_pg_proc procStruct, Form_pg_proc procStruct,
...@@ -248,6 +250,7 @@ do_compile(FunctionCallInfo fcinfo, ...@@ -248,6 +250,7 @@ do_compile(FunctionCallInfo fcinfo,
ErrorContextCallback plerrcontext; ErrorContextCallback plerrcontext;
int parse_rc; int parse_rc;
Oid rettypeid; Oid rettypeid;
char **argnames;
/* /*
* Setup the scanner input and error info. We assume that this * Setup the scanner input and error info. We assume that this
...@@ -408,12 +411,16 @@ do_compile(FunctionCallInfo fcinfo, ...@@ -408,12 +411,16 @@ do_compile(FunctionCallInfo fcinfo,
/* /*
* Create the variables for the procedure's parameters * Create the variables for the procedure's parameters
*/ */
argnames = fetchArgNames(procTup, procStruct->pronargs);
for (i = 0; i < procStruct->pronargs; i++) for (i = 0; i < procStruct->pronargs; i++)
{ {
char buf[32]; char buf[32];
Oid argtypeid; Oid argtypeid;
PLpgSQL_datum *argdatum;
int argitemtype;
/* name for variable */ /* Create $n name for variable */
snprintf(buf, sizeof(buf), "$%d", i + 1); snprintf(buf, sizeof(buf), "$%d", i + 1);
/* /*
...@@ -424,7 +431,7 @@ do_compile(FunctionCallInfo fcinfo, ...@@ -424,7 +431,7 @@ do_compile(FunctionCallInfo fcinfo,
argtypeid = hashkey->argtypes[i]; argtypeid = hashkey->argtypes[i];
/* /*
* Get the parameters type * Get the parameter type
*/ */
typeTup = SearchSysCache(TYPEOID, typeTup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(argtypeid), ObjectIdGetDatum(argtypeid),
...@@ -448,14 +455,10 @@ do_compile(FunctionCallInfo fcinfo, ...@@ -448,14 +455,10 @@ do_compile(FunctionCallInfo fcinfo,
* that type * that type
*/ */
row = plpgsql_build_rowtype(typeStruct->typrelid); row = plpgsql_build_rowtype(typeStruct->typrelid);
row->refname = strdup(buf); row->refname = strdup(buf);
plpgsql_adddatum((PLpgSQL_datum *) row); argdatum = (PLpgSQL_datum *) row;
plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, row->rowno, argitemtype = PLPGSQL_NSTYPE_ROW;
row->refname);
arg_varnos[i] = row->rowno;
} }
else else
{ {
...@@ -473,12 +476,22 @@ do_compile(FunctionCallInfo fcinfo, ...@@ -473,12 +476,22 @@ do_compile(FunctionCallInfo fcinfo,
var->notnull = false; var->notnull = false;
var->default_val = NULL; var->default_val = NULL;
plpgsql_adddatum((PLpgSQL_datum *) var); argdatum = (PLpgSQL_datum *) var;
plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno, argitemtype = PLPGSQL_NSTYPE_VAR;
var->refname);
arg_varnos[i] = var->varno;
} }
/* Add it to datum list, and remember datum number */
plpgsql_adddatum(argdatum);
arg_varnos[i] = argdatum->dno;
/* Add to namespace under the $n name */
plpgsql_ns_additem(argitemtype, argdatum->dno, buf);
/* If there's a name for the argument, make an alias */
if (argnames && argnames[i] && argnames[i][0])
plpgsql_ns_additem(argitemtype, argdatum->dno,
argnames[i]);
ReleaseSysCache(typeTup); ReleaseSysCache(typeTup);
} }
break; break;
...@@ -730,6 +743,44 @@ plpgsql_compile_error_callback(void *arg) ...@@ -730,6 +743,44 @@ plpgsql_compile_error_callback(void *arg)
} }
/*
* Fetch the argument names, if any, from the proargnames field of the
* pg_proc tuple. Results are palloc'd.
*/
static char **
fetchArgNames(HeapTuple procTup, int nargs)
{
Datum argnamesDatum;
bool isNull;
Datum *elems;
int nelems;
char **result;
int i;
if (nargs == 0)
return NULL;
argnamesDatum = SysCacheGetAttr(PROCOID, procTup, Anum_pg_proc_proargnames,
&isNull);
if (isNull)
return NULL;
deconstruct_array(DatumGetArrayTypeP(argnamesDatum),
TEXTOID, -1, false, 'i',
&elems, &nelems);
if (nelems != nargs) /* should not happen */
elog(ERROR, "proargnames must have the same number of elements as the function has arguments");
result = (char **) palloc(sizeof(char *) * nargs);
for (i=0; i < nargs; i++)
result[i] = DatumGetCString(DirectFunctionCall1(textout, elems[i]));
return result;
}
/* ---------- /* ----------
* plpgsql_parse_word The scanner calls this to postparse * plpgsql_parse_word The scanner calls this to postparse
* any single word not found by a * any single word not found by a
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment