OSDN Git Service

Cause plpgsql to throw an error if "INTO rowtype_var" is followed by a comma.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 2 Mar 2010 16:14:39 +0000 (16:14 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 2 Mar 2010 16:14:39 +0000 (16:14 +0000)
Per bug #5352, this helps to provide a useful error message if the user
tries to do something presently unsupported, namely use a rowtype variable
as a member of a multiple-item INTO list.

src/pl/plpgsql/src/gram.y

index 46500ad..fbe1786 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.140 2010/01/19 01:35:30 tgl Exp $
+ *       $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.141 2010/03/02 16:14:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2881,6 +2881,13 @@ read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row, bool *strict)
                tok = yylex();
        }
 
+       /*
+        * Currently, a row or record variable can be the single INTO target,
+        * but not a member of a multi-target list.  So we throw error if there
+        * is a comma after it, because that probably means the user tried to
+        * write a multi-target list.  If this ever gets generalized, we should
+        * probably refactor read_into_scalar_list so it handles all cases.
+        */
        switch (tok)
        {
                case T_DATUM:
@@ -2888,11 +2895,25 @@ read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row, bool *strict)
                        {
                                check_assignable(yylval.wdatum.datum, yylloc);
                                *row = (PLpgSQL_row *) yylval.wdatum.datum;
+
+                               if ((tok = yylex()) == ',')
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_SYNTAX_ERROR),
+                                                        errmsg("record or row variable cannot be part of multiple-item INTO list"),
+                                                        parser_errposition(yylloc)));
+                               plpgsql_push_back_token(tok);
                        }
                        else if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
                        {
                                check_assignable(yylval.wdatum.datum, yylloc);
                                *rec = (PLpgSQL_rec *) yylval.wdatum.datum;
+
+                               if ((tok = yylex()) == ',')
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_SYNTAX_ERROR),
+                                                        errmsg("record or row variable cannot be part of multiple-item INTO list"),
+                                                        parser_errposition(yylloc)));
+                               plpgsql_push_back_token(tok);
                        }
                        else
                        {