Hi so 8. 2. 2025 v 11:27 odesÃlatel Japin Li <japi...@hotmail.com> napsal:
> On Sat, 08 Feb 2025 at 16:34, Julien Rouhaud <rjuju...@gmail.com> wrote: > > Hi, > > > > On Sat, Feb 08, 2025 at 07:47:23AM +0100, Pavel Stehule wrote: > >> Hi > >> > >> when I worked on strict expr check patch I found so syntax for named > >> arguments of cursors supports only our legacy proprietary syntax > `argname > >> := value` > >> > >> https://www.postgresql.org/docs/current/plpgsql-cursors.html > >> > >> I propose to enhancing to ANSI/SQL standard syntax for named arguments > >> `argname => value` > > > > Seems sensible to me. > > > >> The patch is almost trivial > > > > Documentation and tests are updated, and the patch LGTM. > > Maybe we should also update the comments? > > diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y > index 867017d8ed9..43186c8e85e 100644 > --- a/src/pl/plpgsql/src/pl_gram.y > +++ b/src/pl/plpgsql/src/pl_gram.y > @@ -3911,7 +3911,7 @@ read_cursor_args(PLpgSQL_var *cursor, int until, > YYSTYPE *yylvalp, YYLTYPE *yyll > tok2; > int arglocation; > > - /* Check if it's a named parameter: "param := value" */ > + /* Check if it's a named parameter: "param := value" or > "param => value" */ > plpgsql_peek2(&tok1, &tok2, &arglocation, NULL, yyscanner); > if (tok1 == IDENT && (tok2 == COLON_EQUALS || tok2 == > EQUALS_GREATER)) > { > @@ -3939,7 +3939,7 @@ read_cursor_args(PLpgSQL_var *cursor, int until, > YYSTYPE *yylvalp, YYLTYPE *yyll > > parser_errposition(*yyllocp))); > > /* > - * Eat the ":=". We already peeked, so the error > should never > + * Eat the ":=" and "=>". We already peeked, so > the error should never > * happen. > */ > tok2 = yylex(yylvalp, yyllocp, yyscanner); > good idea done Regards Pavel > -- > Regrads, > Japin Li >
From 3eb6e29eacbe2ad1dd0d2b7847ca1eccde71594f Mon Sep 17 00:00:00 2001 From: "ok...@github.com" <pavel.steh...@gmail.com> Date: Sat, 8 Feb 2025 07:45:58 +0100 Subject: [PATCH] allow to use standard syntax for named arguments for plpgsql cursor arguments --- doc/src/sgml/plpgsql.sgml | 3 ++- src/pl/plpgsql/src/pl_gram.y | 13 ++++++++----- src/test/regress/expected/plpgsql.out | 19 +++++++++++++++++++ src/test/regress/sql/plpgsql.sql | 15 +++++++++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 78e4983139b..60af57712b7 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -3317,7 +3317,7 @@ OPEN curs1 FOR EXECUTE format('SELECT * FROM %I WHERE col1 = $1',tabname) USING <title>Opening a Bound Cursor</title> <synopsis> -OPEN <replaceable>bound_cursorvar</replaceable> <optional> ( <optional> <replaceable>argument_name</replaceable> := </optional> <replaceable>argument_value</replaceable> <optional>, ...</optional> ) </optional>; +OPEN <replaceable>bound_cursorvar</replaceable> <optional> ( <optional> <replaceable>argument_name</replaceable> { := | => } </optional> <replaceable>argument_value</replaceable> <optional>, ...</optional> ) </optional>; </synopsis> <para> @@ -3352,6 +3352,7 @@ OPEN <replaceable>bound_cursorvar</replaceable> <optional> ( <optional> <replace OPEN curs2; OPEN curs3(42); OPEN curs3(key := 42); +OPEN curs3(Key => 42); </programlisting> </para> diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y index 64d2c362bf9..618a97b64f2 100644 --- a/src/pl/plpgsql/src/pl_gram.y +++ b/src/pl/plpgsql/src/pl_gram.y @@ -3911,9 +3911,12 @@ read_cursor_args(PLpgSQL_var *cursor, int until, YYSTYPE *yylvalp, YYLTYPE *yyll tok2; int arglocation; - /* Check if it's a named parameter: "param := value" */ + /* + * Check if it's a named parameter: "param := value" + * or "param => value" + */ plpgsql_peek2(&tok1, &tok2, &arglocation, NULL, yyscanner); - if (tok1 == IDENT && tok2 == COLON_EQUALS) + if (tok1 == IDENT && (tok2 == COLON_EQUALS || tok2 == EQUALS_GREATER)) { char *argname; IdentifierLookup save_IdentifierLookup; @@ -3939,11 +3942,11 @@ read_cursor_args(PLpgSQL_var *cursor, int until, YYSTYPE *yylvalp, YYLTYPE *yyll parser_errposition(*yyllocp))); /* - * Eat the ":=". We already peeked, so the error should never - * happen. + * Eat the ":=" and the "=>". We already peeked, so the error should + * never happen. */ tok2 = yylex(yylvalp, yyllocp, yyscanner); - if (tok2 != COLON_EQUALS) + if (tok2 != COLON_EQUALS && tok2 != EQUALS_GREATER) yyerror(yyllocp, NULL, yyscanner, "syntax error"); any_named = true; diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 0a6945581bd..4549019f103 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -2429,6 +2429,25 @@ select namedparmcursor_test9(6); 1 (1 row) +-- check standard syntax for named parameters +create or replace 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); + namedparmcursor_test9 +----------------------- + 1 +(1 row) + -- -- tests for "raise" processing -- diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index 18c91572ae1..76da0a364c5 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -2078,6 +2078,21 @@ begin end $$ language plpgsql; select namedparmcursor_test9(6); +-- check standard syntax for named parameters +create or replace 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 -- -- 2.48.1