99 *
1010 *
1111 * IDENTIFICATION
12- * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.130 2009/11/05 16:58:36 tgl Exp $
12+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.131 2009/11/06 18:37:54 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -520,7 +520,9 @@ decl_aliasitem : any_identifier
520520
521521 plpgsql_ns_setlocal (false );
522522
523- nsi = plpgsql_ns_lookup(name, NULL , NULL , NULL );
523+ nsi = plpgsql_ns_lookup(plpgsql_ns_top(),
524+ name, NULL , NULL ,
525+ NULL );
524526 if (nsi == NULL )
525527 {
526528 plpgsql_error_lineno = plpgsql_scanner_lineno();
@@ -550,7 +552,7 @@ decl_varname : T_WORD
550552 {
551553 /*
552554 * Since the scanner is only searching the topmost
553- * namestack entry , getting T_SCALAR etc can only
555+ * namespace level , getting T_SCALAR etc can only
554556 * happen if the name is already declared in this
555557 * block.
556558 */
@@ -1046,12 +1048,6 @@ for_control :
10461048 (errcode(ERRCODE_SYNTAX_ERROR),
10471049 errmsg(" cursor FOR loop must have only one target variable" )));
10481050
1049- /* create loop's private RECORD variable */
1050- plpgsql_convert_ident ($2 .name, &varname, 1 );
1051- new ->rec = plpgsql_build_record(varname,
1052- $2 .lineno,
1053- true );
1054-
10551051 /* can't use an unbound cursor this way */
10561052 if (cursor->cursor_explicit_expr == NULL )
10571053 ereport (ERROR,
@@ -1063,6 +1059,12 @@ for_control :
10631059 K_LOOP,
10641060 " LOOP" );
10651061
1062+ /* create loop's private RECORD variable */
1063+ plpgsql_convert_ident ($2 .name, &varname, 1 );
1064+ new ->rec = plpgsql_build_record(varname,
1065+ $2 .lineno,
1066+ true );
1067+
10661068 $$ = (PLpgSQL_stmt *) new ;
10671069 }
10681070 else
@@ -1157,9 +1159,10 @@ for_control :
11571159 else
11581160 {
11591161 /*
1160- * No "..", so it must be a query loop. We've prefixed an
1161- * extra SELECT to the query text, so we need to remove that
1162- * before performing syntax checking.
1162+ * No "..", so it must be a query loop. We've
1163+ * prefixed an extra SELECT to the query text,
1164+ * so we need to remove that before performing
1165+ * syntax checking.
11631166 */
11641167 char *tmp_query;
11651168 PLpgSQL_stmt_fors *new ;
@@ -1700,7 +1703,9 @@ exception_sect :
17001703 /*
17011704 * We use a mid-rule action to add these
17021705 * special variables to the namespace before
1703- * parsing the WHEN clauses themselves.
1706+ * parsing the WHEN clauses themselves. The
1707+ * scope of the names extends to the end of the
1708+ * current block.
17041709 */
17051710 PLpgSQL_exception_block *new = palloc(sizeof (PLpgSQL_exception_block));
17061711 PLpgSQL_variable *var;
@@ -1937,8 +1942,6 @@ read_sql_construct(int until,
19371942 int lno;
19381943 StringInfoData ds;
19391944 int parenlevel = 0 ;
1940- Bitmapset *paramnos = NULL ;
1941- char buf[32 ];
19421945 PLpgSQL_expr *expr;
19431946
19441947 lno = plpgsql_scanner_lineno ();
@@ -1986,31 +1989,7 @@ read_sql_construct(int until,
19861989
19871990 if (plpgsql_SpaceScanned)
19881991 appendStringInfoChar (&ds, ' ' );
1989-
1990- switch (tok)
1991- {
1992- case T_SCALAR:
1993- snprintf (buf, sizeof (buf), " $%d " , yylval.scalar ->dno + 1 );
1994- appendStringInfoString (&ds, buf);
1995- paramnos = bms_add_member (paramnos, yylval.scalar ->dno );
1996- break ;
1997-
1998- case T_ROW:
1999- snprintf (buf, sizeof (buf), " $%d " , yylval.row ->dno + 1 );
2000- appendStringInfoString (&ds, buf);
2001- paramnos = bms_add_member (paramnos, yylval.row ->dno );
2002- break ;
2003-
2004- case T_RECORD:
2005- snprintf (buf, sizeof (buf), " $%d " , yylval.rec ->dno + 1 );
2006- appendStringInfoString (&ds, buf);
2007- paramnos = bms_add_member (paramnos, yylval.rec ->dno );
2008- break ;
2009-
2010- default :
2011- appendStringInfoString (&ds, yytext);
2012- break ;
2013- }
1992+ appendStringInfoString (&ds, yytext);
20141993 }
20151994
20161995 if (endtoken)
@@ -2020,7 +1999,8 @@ read_sql_construct(int until,
20201999 expr->dtype = PLPGSQL_DTYPE_EXPR;
20212000 expr->query = pstrdup (ds.data );
20222001 expr->plan = NULL ;
2023- expr->paramnos = paramnos;
2002+ expr->paramnos = NULL ;
2003+ expr->ns = plpgsql_ns_top ();
20242004 pfree (ds.data );
20252005
20262006 if (valid_sql)
@@ -2100,8 +2080,6 @@ static PLpgSQL_stmt *
21002080make_execsql_stmt (const char *sqlstart, int lineno)
21012081{
21022082 StringInfoData ds;
2103- Bitmapset *paramnos = NULL ;
2104- char buf[32 ];
21052083 PLpgSQL_stmt_execsql *execsql;
21062084 PLpgSQL_expr *expr;
21072085 PLpgSQL_row *row = NULL ;
@@ -2147,38 +2125,15 @@ make_execsql_stmt(const char *sqlstart, int lineno)
21472125
21482126 if (plpgsql_SpaceScanned)
21492127 appendStringInfoChar (&ds, ' ' );
2150-
2151- switch (tok)
2152- {
2153- case T_SCALAR:
2154- snprintf (buf, sizeof (buf), " $%d " , yylval.scalar ->dno + 1 );
2155- appendStringInfoString (&ds, buf);
2156- paramnos = bms_add_member (paramnos, yylval.scalar ->dno );
2157- break ;
2158-
2159- case T_ROW:
2160- snprintf (buf, sizeof (buf), " $%d " , yylval.row ->dno + 1 );
2161- appendStringInfoString (&ds, buf);
2162- paramnos = bms_add_member (paramnos, yylval.row ->dno );
2163- break ;
2164-
2165- case T_RECORD:
2166- snprintf (buf, sizeof (buf), " $%d " , yylval.rec ->dno + 1 );
2167- appendStringInfoString (&ds, buf);
2168- paramnos = bms_add_member (paramnos, yylval.rec ->dno );
2169- break ;
2170-
2171- default :
2172- appendStringInfoString (&ds, yytext);
2173- break ;
2174- }
2128+ appendStringInfoString (&ds, yytext);
21752129 }
21762130
21772131 expr = palloc0 (sizeof (PLpgSQL_expr));
21782132 expr->dtype = PLPGSQL_DTYPE_EXPR;
21792133 expr->query = pstrdup (ds.data );
21802134 expr->plan = NULL ;
2181- expr->paramnos = paramnos;
2135+ expr->paramnos = NULL ;
2136+ expr->ns = plpgsql_ns_top ();
21822137 pfree (ds.data );
21832138
21842139 check_sql_expr (expr->query );
@@ -2804,7 +2759,7 @@ check_label(const char *yytxt)
28042759 char *label_name;
28052760
28062761 plpgsql_convert_ident (yytxt, &label_name, 1 );
2807- if (plpgsql_ns_lookup_label (label_name) == NULL )
2762+ if (plpgsql_ns_lookup_label (plpgsql_ns_top (), label_name) == NULL )
28082763 yyerror (" label does not exist" );
28092764 return label_name;
28102765}
@@ -3005,42 +2960,43 @@ make_case(int lineno, PLpgSQL_expr *t_expr,
30052960 */
30062961 if (t_expr)
30072962 {
3008- ListCell *l ;
2963+ char varname[ 32 ] ;
30092964 PLpgSQL_var *t_var;
3010- int t_varno;
2965+ ListCell *l;
2966+
2967+ /* use a name unlikely to collide with any user names */
2968+ snprintf (varname, sizeof (varname), " __Case__Variable_%d__" ,
2969+ plpgsql_nDatums);
30112970
30122971 /*
30132972 * We don't yet know the result datatype of t_expr. Build the
30142973 * variable as if it were INT4; we'll fix this at runtime if needed.
30152974 */
30162975 t_var = (PLpgSQL_var *)
3017- plpgsql_build_variable (" *case* " , lineno,
2976+ plpgsql_build_variable (varname , lineno,
30182977 plpgsql_build_datatype (INT4OID, -1 ),
3019- false );
3020- t_varno = t_var->dno ;
3021- new ->t_varno = t_varno;
2978+ true );
2979+ new ->t_varno = t_var->dno ;
30222980
30232981 foreach (l, case_when_list)
30242982 {
30252983 PLpgSQL_case_when *cwt = (PLpgSQL_case_when *) lfirst (l);
30262984 PLpgSQL_expr *expr = cwt->expr ;
30272985 StringInfoData ds;
30282986
3029- /* Must add the CASE variable as an extra param to expression */
3030- expr->paramnos = bms_add_member (expr->paramnos , t_varno);
3031-
30322987 /* copy expression query without SELECT keyword (expr->query + 7) */
30332988 Assert (strncmp (expr->query , " SELECT " , 7 ) == 0 );
30342989
30352990 /* And do the string hacking */
30362991 initStringInfo (&ds);
30372992
3038- appendStringInfo (&ds, " SELECT $%d IN (%s)" ,
3039- t_varno + 1 ,
3040- expr->query + 7 );
2993+ appendStringInfo (&ds, " SELECT \" %s\" IN (%s)" ,
2994+ varname, expr->query + 7 );
30412995
30422996 pfree (expr->query );
30432997 expr->query = pstrdup (ds.data );
2998+ /* Adjust expr's namespace to include the case variable */
2999+ expr->ns = plpgsql_ns_top ();
30443000
30453001 pfree (ds.data );
30463002 }
0 commit comments