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

Reply via email to