Skip to content

Commit 304d6d5

Browse files
committed
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...)
1 parent a95df8f commit 304d6d5

File tree

1 file changed

+65
-14
lines changed

1 file changed

+65
-14
lines changed

src/pl/plpgsql/src/pl_comp.c

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.71 2004/01/06 23:55:19 tgl Exp $
6+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.72 2004/01/07 06:20:02 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -54,6 +54,7 @@
5454
#include "parser/gramparse.h"
5555
#include "parser/parse_type.h"
5656
#include "tcop/tcopprot.h"
57+
#include "utils/array.h"
5758
#include "utils/builtins.h"
5859
#include "utils/syscache.h"
5960

@@ -102,6 +103,7 @@ static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo,
102103
HeapTuple procTup,
103104
PLpgSQL_func_hashkey *hashkey);
104105
static void plpgsql_compile_error_callback(void *arg);
106+
static char **fetchArgNames(HeapTuple procTup, int nargs);
105107
static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod);
106108
static void compute_function_hashkey(FunctionCallInfo fcinfo,
107109
Form_pg_proc procStruct,
@@ -248,6 +250,7 @@ do_compile(FunctionCallInfo fcinfo,
248250
ErrorContextCallback plerrcontext;
249251
int parse_rc;
250252
Oid rettypeid;
253+
char **argnames;
251254

252255
/*
253256
* Setup the scanner input and error info. We assume that this
@@ -408,12 +411,16 @@ do_compile(FunctionCallInfo fcinfo,
408411
/*
409412
* Create the variables for the procedure's parameters
410413
*/
414+
argnames = fetchArgNames(procTup, procStruct->pronargs);
415+
411416
for (i = 0; i < procStruct->pronargs; i++)
412417
{
413418
char buf[32];
414419
Oid argtypeid;
420+
PLpgSQL_datum *argdatum;
421+
int argitemtype;
415422

416-
/* name for variable */
423+
/* Create $n name for variable */
417424
snprintf(buf, sizeof(buf), "$%d", i + 1);
418425

419426
/*
@@ -424,7 +431,7 @@ do_compile(FunctionCallInfo fcinfo,
424431
argtypeid = hashkey->argtypes[i];
425432

426433
/*
427-
* Get the parameters type
434+
* Get the parameter type
428435
*/
429436
typeTup = SearchSysCache(TYPEOID,
430437
ObjectIdGetDatum(argtypeid),
@@ -448,14 +455,10 @@ do_compile(FunctionCallInfo fcinfo,
448455
* that type
449456
*/
450457
row = plpgsql_build_rowtype(typeStruct->typrelid);
451-
452458
row->refname = strdup(buf);
453459

454-
plpgsql_adddatum((PLpgSQL_datum *) row);
455-
plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, row->rowno,
456-
row->refname);
457-
458-
arg_varnos[i] = row->rowno;
460+
argdatum = (PLpgSQL_datum *) row;
461+
argitemtype = PLPGSQL_NSTYPE_ROW;
459462
}
460463
else
461464
{
@@ -473,12 +476,22 @@ do_compile(FunctionCallInfo fcinfo,
473476
var->notnull = false;
474477
var->default_val = NULL;
475478

476-
plpgsql_adddatum((PLpgSQL_datum *) var);
477-
plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, var->varno,
478-
var->refname);
479-
480-
arg_varnos[i] = var->varno;
479+
argdatum = (PLpgSQL_datum *) var;
480+
argitemtype = PLPGSQL_NSTYPE_VAR;
481481
}
482+
483+
/* Add it to datum list, and remember datum number */
484+
plpgsql_adddatum(argdatum);
485+
arg_varnos[i] = argdatum->dno;
486+
487+
/* Add to namespace under the $n name */
488+
plpgsql_ns_additem(argitemtype, argdatum->dno, buf);
489+
490+
/* If there's a name for the argument, make an alias */
491+
if (argnames && argnames[i] && argnames[i][0])
492+
plpgsql_ns_additem(argitemtype, argdatum->dno,
493+
argnames[i]);
494+
482495
ReleaseSysCache(typeTup);
483496
}
484497
break;
@@ -730,6 +743,44 @@ plpgsql_compile_error_callback(void *arg)
730743
}
731744

732745

746+
/*
747+
* Fetch the argument names, if any, from the proargnames field of the
748+
* pg_proc tuple. Results are palloc'd.
749+
*/
750+
static char **
751+
fetchArgNames(HeapTuple procTup, int nargs)
752+
{
753+
Datum argnamesDatum;
754+
bool isNull;
755+
Datum *elems;
756+
int nelems;
757+
char **result;
758+
int i;
759+
760+
if (nargs == 0)
761+
return NULL;
762+
763+
argnamesDatum = SysCacheGetAttr(PROCOID, procTup, Anum_pg_proc_proargnames,
764+
&isNull);
765+
if (isNull)
766+
return NULL;
767+
768+
deconstruct_array(DatumGetArrayTypeP(argnamesDatum),
769+
TEXTOID, -1, false, 'i',
770+
&elems, &nelems);
771+
772+
if (nelems != nargs) /* should not happen */
773+
elog(ERROR, "proargnames must have the same number of elements as the function has arguments");
774+
775+
result = (char **) palloc(sizeof(char *) * nargs);
776+
777+
for (i=0; i < nargs; i++)
778+
result[i] = DatumGetCString(DirectFunctionCall1(textout, elems[i]));
779+
780+
return result;
781+
}
782+
783+
733784
/* ----------
734785
* plpgsql_parse_word The scanner calls this to postparse
735786
* any single word not found by a

0 commit comments

Comments
 (0)