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 *
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,
102103HeapTuple procTup ,
103104PLpgSQL_func_hashkey * hashkey );
104105static void plpgsql_compile_error_callback (void * arg );
106+ static char * * fetchArgNames (HeapTuple procTup ,int nargs );
105107static PLpgSQL_type * build_datatype (HeapTuple typeTup ,int32 typmod );
106108static void compute_function_hashkey (FunctionCallInfo fcinfo ,
107109Form_pg_proc procStruct ,
@@ -248,6 +250,7 @@ do_compile(FunctionCallInfo fcinfo,
248250ErrorContextCallback plerrcontext ;
249251int parse_rc ;
250252Oid 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+
411416for (i = 0 ;i < procStruct -> pronargs ;i ++ )
412417{
413418char buf [32 ];
414419Oid argtypeid ;
420+ PLpgSQL_datum * argdatum ;
421+ int argitemtype ;
415422
416- /* name for variable */
423+ /*Create $n name for variable */
417424snprintf (buf ,sizeof (buf ),"$%d" ,i + 1 );
418425
419426/*
@@ -424,7 +431,7 @@ do_compile(FunctionCallInfo fcinfo,
424431argtypeid = hashkey -> argtypes [i ];
425432
426433/*
427- * Get theparameters type
434+ * Get theparameter type
428435 */
429436typeTup = SearchSysCache (TYPEOID ,
430437ObjectIdGetDatum (argtypeid ),
@@ -448,14 +455,10 @@ do_compile(FunctionCallInfo fcinfo,
448455 * that type
449456 */
450457row = plpgsql_build_rowtype (typeStruct -> typrelid );
451-
452458row -> 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}
460463else
461464{
@@ -473,12 +476,22 @@ do_compile(FunctionCallInfo fcinfo,
473476var -> notnull = false;
474477var -> 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+
482495ReleaseSysCache (typeTup );
483496}
484497break ;
@@ -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_wordThe scanner calls this to postparse
735786 *any single word not found by a