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
521521plpgsql_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 );
524526if (nsi ==NULL )
525527{
526528plpgsql_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*/
10561052if (cursor->cursor_explicit_expr ==NULL )
10571053ereport (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}
10681070else
@@ -1157,9 +1159,10 @@ for_control:
11571159else
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*/
11641167char *tmp_query;
11651168PLpgSQL_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*/
17051710PLpgSQL_exception_block *new = palloc(sizeof (PLpgSQL_exception_block));
17061711PLpgSQL_variable *var;
@@ -1937,8 +1942,6 @@ read_sql_construct(int until,
19371942int lno;
19381943StringInfoDatads;
19391944int parenlevel =0 ;
1940- Bitmapset *paramnos =NULL ;
1941- char buf[32 ];
19421945PLpgSQL_expr*expr;
19431946
19441947lno =plpgsql_scanner_lineno ();
@@ -1986,31 +1989,7 @@ read_sql_construct(int until,
19861989
19871990if (plpgsql_SpaceScanned)
19881991appendStringInfoChar (&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
20161995if (endtoken)
@@ -2020,7 +1999,8 @@ read_sql_construct(int until,
20201999expr->dtype = PLPGSQL_DTYPE_EXPR;
20212000expr->query =pstrdup (ds.data );
20222001expr->plan =NULL ;
2023- expr->paramnos = paramnos;
2002+ expr->paramnos =NULL ;
2003+ expr->ns =plpgsql_ns_top ();
20242004pfree (ds.data );
20252005
20262006if (valid_sql)
@@ -2100,8 +2080,6 @@ static PLpgSQL_stmt *
21002080make_execsql_stmt (const char *sqlstart,int lineno)
21012081{
21022082StringInfoDatads;
2103- Bitmapset *paramnos =NULL ;
2104- char buf[32 ];
21052083PLpgSQL_stmt_execsql *execsql;
21062084PLpgSQL_expr*expr;
21072085PLpgSQL_row*row =NULL ;
@@ -2147,38 +2125,15 @@ make_execsql_stmt(const char *sqlstart, int lineno)
21472125
21482126if (plpgsql_SpaceScanned)
21492127appendStringInfoChar (&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
21772131expr =palloc0 (sizeof (PLpgSQL_expr));
21782132expr->dtype = PLPGSQL_DTYPE_EXPR;
21792133expr->query =pstrdup (ds.data );
21802134expr->plan =NULL ;
2181- expr->paramnos = paramnos;
2135+ expr->paramnos =NULL ;
2136+ expr->ns =plpgsql_ns_top ();
21822137pfree (ds.data );
21832138
21842139check_sql_expr (expr->query );
@@ -2804,7 +2759,7 @@ check_label(const char *yytxt)
28042759char *label_name;
28052760
28062761plpgsql_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 )
28082763yyerror (" label does not exist" );
28092764return label_name;
28102765}
@@ -3005,42 +2960,43 @@ make_case(int lineno, PLpgSQL_expr *t_expr,
30052960*/
30062961if (t_expr)
30072962{
3008- ListCell *l ;
2963+ char varname[ 32 ] ;
30092964PLpgSQL_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*/
30162975t_var = (PLpgSQL_var *)
3017- plpgsql_build_variable (" *case* " , lineno,
2976+ plpgsql_build_variable (varname , lineno,
30182977plpgsql_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
30232981foreach (l, case_when_list)
30242982{
30252983PLpgSQL_case_when *cwt = (PLpgSQL_case_when *)lfirst (l);
30262984PLpgSQL_expr *expr = cwt->expr ;
30272985StringInfoDatads;
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)*/
30332988Assert (strncmp (expr->query ," SELECT" ,7 ) ==0 );
30342989
30352990/* And do the string hacking*/
30362991initStringInfo (&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
30422996pfree (expr->query );
30432997expr->query =pstrdup (ds.data );
2998+ /* Adjust expr's namespace to include the case variable*/
2999+ expr->ns =plpgsql_ns_top ();
30443000
30453001pfree (ds.data );
30463002}