diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-07-16 17:01:11 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-07-16 17:01:11 +0000 |
commit | ae1b7e298cd99e808ec8410a808fcb2e44f8520e (patch) | |
tree | 376b2467d687762eb59c7d74e3b9a3deca18009f /src | |
parent | 9f6f51d5d45444c1459ec9564c29a3c205d689f6 (diff) | |
download | postgresql-ae1b7e298cd99e808ec8410a808fcb2e44f8520e.tar.gz postgresql-ae1b7e298cd99e808ec8410a808fcb2e44f8520e.zip |
Allow plpgsql function parameter names to be qualified with the function's
name. With this patch, it is always possible for the user to qualify a
plpgsql variable name if needed to avoid ambiguity. While there is much more
work to be done in this area, this simple change removes one unnecessary
incompatibility with Oracle. Per discussion.
Diffstat (limited to 'src')
-rw-r--r-- | src/pl/plpgsql/src/gram.y | 4 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_comp.c | 8 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_funcs.c | 22 | ||||
-rw-r--r-- | src/pl/plpgsql/src/plpgsql.h | 6 | ||||
-rw-r--r-- | src/test/regress/expected/plpgsql.out | 28 | ||||
-rw-r--r-- | src/test/regress/sql/plpgsql.sql | 22 |
6 files changed, 70 insertions, 20 deletions
diff --git a/src/pl/plpgsql/src/gram.y b/src/pl/plpgsql/src/gram.y index 0f41c999724..795d3c4c4bd 100644 --- a/src/pl/plpgsql/src/gram.y +++ b/src/pl/plpgsql/src/gram.y @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.103 2007/07/15 02:15:04 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.104 2007/07/16 17:01:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -366,7 +366,7 @@ decl_statement : decl_varname decl_const decl_datatype decl_notnull decl_defval plpgsql_ns_rename($2, $4); } | decl_varname opt_scrollable K_CURSOR - { plpgsql_ns_push(NULL); } + { plpgsql_ns_push($1.name); } decl_cursor_args decl_is_for decl_cursor_query { PLpgSQL_var *new; diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 0293bc3fe07..db150632f05 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.116 2007/06/26 16:48:09 alvherre Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.117 2007/07/16 17:01:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -306,10 +306,12 @@ do_compile(FunctionCallInfo fcinfo, error_context_stack = &plerrcontext; /* - * Initialize the compiler + * Initialize the compiler, particularly the namespace stack. The + * outermost namespace contains function parameters and other special + * variables (such as FOUND), and is named after the function itself. */ plpgsql_ns_init(); - plpgsql_ns_push(NULL); + plpgsql_ns_push(NameStr(procStruct->proname)); plpgsql_DumpExecTree = false; datums_alloc = 128; diff --git a/src/pl/plpgsql/src/pl_funcs.c b/src/pl/plpgsql/src/pl_funcs.c index 4d5eba73e3b..da128daa7f7 100644 --- a/src/pl/plpgsql/src/pl_funcs.c +++ b/src/pl/plpgsql/src/pl_funcs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.60 2007/07/15 02:15:04 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.61 2007/07/16 17:01:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -147,15 +147,14 @@ plpgsql_ns_setlocal(bool flag) * ---------- */ void -plpgsql_ns_push(char *label) +plpgsql_ns_push(const char *label) { PLpgSQL_ns *new; if (label == NULL) label = ""; - new = palloc(sizeof(PLpgSQL_ns)); - memset(new, 0, sizeof(PLpgSQL_ns)); + new = palloc0(sizeof(PLpgSQL_ns)); new->upper = ns_current; ns_current = new; @@ -224,7 +223,7 @@ plpgsql_ns_additem(int itemtype, int itemno, const char *name) * ---------- */ PLpgSQL_nsitem * -plpgsql_ns_lookup(char *name, char *label) +plpgsql_ns_lookup(const char *name, const char *label) { PLpgSQL_ns *ns; int i; @@ -236,11 +235,11 @@ plpgsql_ns_lookup(char *name, char *label) { for (ns = ns_current; ns != NULL; ns = ns->upper) { - if (!strcmp(ns->items[0]->name, label)) + if (strcmp(ns->items[0]->name, label) == 0) { for (i = 1; i < ns->items_used; i++) { - if (!strcmp(ns->items[i]->name, name)) + if (strcmp(ns->items[i]->name, name) == 0) return ns->items[i]; } return NULL; /* name not found in specified label */ @@ -254,7 +253,7 @@ plpgsql_ns_lookup(char *name, char *label) */ for (ns = ns_current; ns != NULL; ns = ns->upper) { - if (!strcmp(ns->items[0]->name, name)) + if (strcmp(ns->items[0]->name, name) == 0) return ns->items[0]; } @@ -265,7 +264,7 @@ plpgsql_ns_lookup(char *name, char *label) { for (i = 1; i < ns->items_used; i++) { - if (!strcmp(ns->items[i]->name, name)) + if (strcmp(ns->items[i]->name, name) == 0) return ns->items[i]; } if (ns_localmode) @@ -288,14 +287,13 @@ plpgsql_ns_rename(char *oldname, char *newname) int i; /* - * Lookup name in the namestack; do the lookup in the current namespace - * only. + * Lookup name in the namestack */ for (ns = ns_current; ns != NULL; ns = ns->upper) { for (i = 1; i < ns->items_used; i++) { - if (!strcmp(ns->items[i]->name, oldname)) + if (strcmp(ns->items[i]->name, oldname) == 0) { newitem = palloc(sizeof(PLpgSQL_nsitem) + strlen(newname)); newitem->itemtype = ns->items[i]->itemtype; diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h index dce7be2b1bd..6ffb8b41958 100644 --- a/src/pl/plpgsql/src/plpgsql.h +++ b/src/pl/plpgsql/src/plpgsql.h @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.89 2007/07/15 02:15:04 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.90 2007/07/16 17:01:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -770,10 +770,10 @@ extern char *plpgsql_dstring_get(PLpgSQL_dstring *ds); */ extern void plpgsql_ns_init(void); extern bool plpgsql_ns_setlocal(bool flag); -extern void plpgsql_ns_push(char *label); +extern void plpgsql_ns_push(const char *label); extern void plpgsql_ns_pop(void); extern void plpgsql_ns_additem(int itemtype, int itemno, const char *name); -extern PLpgSQL_nsitem *plpgsql_ns_lookup(char *name, char *nsname); +extern PLpgSQL_nsitem *plpgsql_ns_lookup(const char *name, const char *nsname); extern void plpgsql_ns_rename(char *oldname, char *newname); /* ---------- diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index ddb44a72527..6d97b63e5c9 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -3051,3 +3051,31 @@ select * from sc_test(); (3 rows) drop function sc_test(); +-- test qualified variable names +create function pl_qual_names (param1 int) returns void as $$ +<<outerblock>> +declare + param1 int := 1; +begin + <<innerblock>> + declare + param1 int := 2; + begin + raise notice 'param1 = %', param1; + raise notice 'pl_qual_names.param1 = %', pl_qual_names.param1; + raise notice 'outerblock.param1 = %', outerblock.param1; + raise notice 'innerblock.param1 = %', innerblock.param1; + end; +end; +$$ language plpgsql; +select pl_qual_names(42); +NOTICE: param1 = 2 +NOTICE: pl_qual_names.param1 = 42 +NOTICE: outerblock.param1 = 1 +NOTICE: innerblock.param1 = 2 + pl_qual_names +--------------- + +(1 row) + +drop function pl_qual_names(int); diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index ee9de0a5838..d1c715e8d4c 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -2535,3 +2535,25 @@ select * from sc_test(); drop function sc_test(); +-- test qualified variable names + +create function pl_qual_names (param1 int) returns void as $$ +<<outerblock>> +declare + param1 int := 1; +begin + <<innerblock>> + declare + param1 int := 2; + begin + raise notice 'param1 = %', param1; + raise notice 'pl_qual_names.param1 = %', pl_qual_names.param1; + raise notice 'outerblock.param1 = %', outerblock.param1; + raise notice 'innerblock.param1 = %', innerblock.param1; + end; +end; +$$ language plpgsql; + +select pl_qual_names(42); + +drop function pl_qual_names(int); |