PLpgSQL_expr *expr;
PLpgSQL_row *row;
int tok;
- int argc = 0;
+ int argc;
char **argv;
StringInfoData ds;
char *sqlstart = "SELECT ";
- bool named = false;
+ bool any_named = false;
tok = yylex();
if (cursor->cursor_explicit_argrow < 0)
return NULL;
}
- row = (PLpgSQL_row *) plpgsql_Datums[cursor->cursor_explicit_argrow];
- argv = (char **) palloc0(row->nfields * sizeof(char *));
-
/* Else better provide arguments */
if (tok != '(')
ereport(ERROR,
/*
* Read the arguments, one by one.
*/
+ row = (PLpgSQL_row *) plpgsql_Datums[cursor->cursor_explicit_argrow];
+ argv = (char **) palloc0(row->nfields * sizeof(char *));
+
for (argc = 0; argc < row->nfields; argc++)
{
PLpgSQL_expr *item;
if (tok1 == IDENT && tok2 == COLON_EQUALS)
{
char *argname;
+ IdentifierLookup save_IdentifierLookup;
- /* Read the argument name, and find its position */
+ /* Read the argument name, ignoring any matching variable */
+ save_IdentifierLookup = plpgsql_IdentifierLookup;
+ plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_DECLARE;
yylex();
argname = yylval.str;
+ plpgsql_IdentifierLookup = save_IdentifierLookup;
+ /* Match argument name to cursor arguments */
for (argpos = 0; argpos < row->nfields; argpos++)
{
if (strcmp(row->fieldnames[argpos], argname) == 0)
if (tok2 != COLON_EQUALS)
yyerror("syntax error");
- named = true;
+ any_named = true;
}
else
argpos = argc;
+ if (argv[argpos] != NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("duplicate value for cursor \"%s\" parameter \"%s\"",
+ cursor->refname, row->fieldnames[argpos]),
+ parser_errposition(arglocation)));
+
/*
* Read the value expression. To provide the user with meaningful
* parse error positions, we check the syntax immediately, instead of
false, /* do not trim */
NULL, &endtoken);
+ argv[argpos] = item->query + strlen(sqlstart);
+
if (endtoken == ')' && !(argc == row->nfields - 1))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("too many arguments for cursor \"%s\"",
cursor->refname),
parser_errposition(yylloc)));
-
- if (argv[argpos] != NULL)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("duplicate value for cursor \"%s\" parameter \"%s\"",
- cursor->refname, row->fieldnames[argpos]),
- parser_errposition(arglocation)));
-
- argv[argpos] = item->query + strlen(sqlstart);
}
/* Make positional argument list */
* the parameter name for meaningful runtime errors.
*/
appendStringInfoString(&ds, argv[argc]);
- if (named)
+ if (any_named)
appendStringInfo(&ds, " AS %s",
quote_identifier(row->fieldnames[argc]));
if (argc < row->nfields - 1)
end $$ language plpgsql;
select namedparmcursor_test8();
+-- cursor parameter name can match plpgsql variable or unreserved keyword
+create function namedparmcursor_test9(p1 int) returns int4 as $$
+declare
+ c1 cursor (p1 int, p2 int, debug int) for
+ select count(*) from tenk1 where thousand = p1 and tenthous = p2
+ and four = debug;
+ p2 int4 := 1006;
+ n int4;
+begin
+ open c1 (p1 := p1, p2 := p2, debug := 2);
+ fetch c1 into n;
+ return n;
+end $$ language plpgsql;
+select namedparmcursor_test9(6);
+
--
-- tests for "raise" processing
--