agora inbox for pgsql-bugs@postgresql.org  
help / color / mirror / Atom feed
BUG #19558: User-defined prefix operators "|" and "->" no longer parse in 19beta2 (SQL/PGQ grammar change)
5+ messages / 3 participants
[nested] [flat]

* BUG #19558: User-defined prefix operators "|" and "->" no longer parse in 19beta2 (SQL/PGQ grammar change)
@ 2026-07-18 08:39  PG Bug reporting form <noreply@postgresql.org>
  0 siblings, 1 reply; 5+ messages in thread

From: PG Bug reporting form @ 2026-07-18 08:39 UTC (permalink / raw)
  To: pgsql-bugs@lists.postgresql.org; +Cc: pierre@senellart.com

The following bug has been logged on the website:

Bug reference:      19558
Logged by:          Pierre Senellart
Email address:      pierre@senellart.com
PostgreSQL version: 19beta2
Operating system:   Linux
Description:        

The following works on PostgreSQL <= 18 but raises a syntax error on
19beta1/19beta2 (tested: PostgreSQL 19beta2, Ubuntu package
19~beta2-1.pgdg26.04+1, x86_64-linux):

    CREATE FUNCTION identity_int(int) RETURNS int
      LANGUAGE sql IMMUTABLE AS 'SELECT $1';
    CREATE OPERATOR |  (RIGHTARG = int, FUNCTION = identity_int);
    CREATE OPERATOR -> (RIGHTARG = int, FUNCTION = identity_int);

    SELECT | 5;    -- 18: returns 5;  19beta2: syntax error at or near "|"
    SELECT -> 5;   -- 18: returns 5;  19beta2: syntax error at or near "->"

Cause: the SQL/PGQ property graph patch turned "|" and "->" into dedicated
grammar tokens (RIGHT_ARROW), declared in the precedence list alongside Op.
Explicit binary productions (a_expr '|' a_expr, a_expr RIGHT_ARROW a_expr)
preserve infix use, and both tokens were added to the operator-name
productions, so binary use and the OPERATOR() syntax still work:

    SELECT OPERATOR(public.|) 5;    -- still returns 5 on 19beta2
    SELECT OPERATOR(public.->) 5;   -- still returns 5 on 19beta2

But no unary counterparts of these productions were added, so a user-defined
*prefix* operator spelled exactly "|" or "->" can no longer be invoked by
its bare name. Note the inconsistency: CREATE OPERATOR still accepts both
names for prefix operators; the resulting operator just cannot be called
except through OPERATOR().

If the tokenization is here to stay, could unary productions ('|' a_expr,
RIGHT_ARROW a_expr) be added to restore the pre-19 behaviour? Failing that,
this seems worth an entry in the release notes' incompatibilities section,
since nothing currently documents it.

Motivation: https://pgxn.org/dist/provsql/ which I am developing uses prefix
| as a probabilistic “given” operator. This works on all PostgreSQL versions
from 10 to 18, but fails on 19beta2.








^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re:[patch] BUG #19558: User-defined prefix operators "|" and "->" no longer parse in 19beta2 (SQL/PGQ grammar change)
@ 2026-07-18 15:38  Pierre Forstmann <pierre.forstmann@gmail.com>
  parent: PG Bug reporting form <noreply@postgresql.org>
  0 siblings, 1 reply; 5+ messages in thread

From: Pierre Forstmann @ 2026-07-18 15:38 UTC (permalink / raw)
  To: pierre@senellart.com; pgsql-bugs@lists.postgresql.org

Hello,

I propose following patch that adds missing grammar rules:

  src/backend/parser/gram.y | 9 +++++++++
  1 file changed, 9 insertions(+)

diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index ff4e138..331da79 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -15873,6 +15873,10 @@ a_expr:        c_expr                   { $$ = 
$1; }
                  { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, 
$2, @1); }
              | '-' a_expr                    %prec UMINUS
                  { $$ = doNegate($2, @1); }
+            | '|' a_expr                  %prec UMINUS
+                 { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", NULL , 
$2, @1); }
+            | RIGHT_ARROW a_expr                  %prec UMINUS
+                 { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", NULL 
, $2, @1); }
              | a_expr '+' a_expr
                  { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, 
$3, @2); }
              | a_expr '-' a_expr
@@ -15902,6 +15906,7 @@ a_expr:        c_expr                 { $$ = $1; }
              | a_expr '|' a_expr
                  { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", $1, 
$3, @2); }

+
              | a_expr qual_Op a_expr                %prec Op
                  { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
              | qual_Op a_expr                    %prec Op
@@ -16355,6 +16360,10 @@ b_expr:        c_expr
                  { $$ = makeTypeCast($1, $3, @2); }
              | '+' b_expr                    %prec UMINUS
                  { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, 
$2, @1); }
+            | '|' b_expr                    %prec UMINUS
+                { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", NULL, 
$2, @1); }
+            | RIGHT_ARROW b_expr                    %prec UMINUS
+                { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", NULL, 
$2, @1); }
              | '-' b_expr                    %prec UMINUS
                  { $$ = doNegate($2, @1); }
              | b_expr '+' b_expr
-- 
2.52.0

Test case says:


CREATE FUNCTION identity_int(int) RETURNS int
       LANGUAGE sql IMMUTABLE AS 'SELECT $1';
CREATE FUNCTION
CREATE OPERATOR |  (RIGHTARG = int, FUNCTION = identity_int);
CREATE OPERATOR
CREATE OPERATOR -> (RIGHTARG = int, FUNCTION = identity_int);
CREATE OPERATOR
SELECT | 5;
  ?column?
----------
         5
(1 row)

SELECT -> 5;
  ?column?
----------
         5
(1 row)


Le 18/07/2026 à 10:39, PG Bug reporting form a écrit :
> The following bug has been logged on the website:
>
> Bug reference:      19558
> Logged by:          Pierre Senellart
> Email address:      pierre@senellart.com
> PostgreSQL version: 19beta2
> Operating system:   Linux
> Description:
>
> The following works on PostgreSQL <= 18 but raises a syntax error on
> 19beta1/19beta2 (tested: PostgreSQL 19beta2, Ubuntu package
> 19~beta2-1.pgdg26.04+1, x86_64-linux):
>
>      CREATE FUNCTION identity_int(int) RETURNS int
>        LANGUAGE sql IMMUTABLE AS 'SELECT $1';
>      CREATE OPERATOR |  (RIGHTARG = int, FUNCTION = identity_int);
>      CREATE OPERATOR -> (RIGHTARG = int, FUNCTION = identity_int);
>
>      SELECT | 5;    -- 18: returns 5;  19beta2: syntax error at or near "|"
>      SELECT -> 5;   -- 18: returns 5;  19beta2: syntax error at or near "->"
>
> Cause: the SQL/PGQ property graph patch turned "|" and "->" into dedicated
> grammar tokens (RIGHT_ARROW), declared in the precedence list alongside Op.
> Explicit binary productions (a_expr '|' a_expr, a_expr RIGHT_ARROW a_expr)
> preserve infix use, and both tokens were added to the operator-name
> productions, so binary use and the OPERATOR() syntax still work:
>
>      SELECT OPERATOR(public.|) 5;    -- still returns 5 on 19beta2
>      SELECT OPERATOR(public.->) 5;   -- still returns 5 on 19beta2
>
> But no unary counterparts of these productions were added, so a user-defined
> *prefix* operator spelled exactly "|" or "->" can no longer be invoked by
> its bare name. Note the inconsistency: CREATE OPERATOR still accepts both
> names for prefix operators; the resulting operator just cannot be called
> except through OPERATOR().
>
> If the tokenization is here to stay, could unary productions ('|' a_expr,
> RIGHT_ARROW a_expr) be added to restore the pre-19 behaviour? Failing that,
> this seems worth an entry in the release notes' incompatibilities section,
> since nothing currently documents it.
>
> Motivation: https://pgxn.org/dist/provsql/ which I am developing uses prefix
> | as a probabilistic “given” operator. This works on all PostgreSQL versions
> from 10 to 18, but fails on 19beta2.
>
>
>
>

Attachments:

  [text/x-patch] 0001-bug-19558-Fix-user-defined-prefix-operators-and.patch (1.8K, ../../02aea982-c656-462d-a412-1fb2e388f754@gmail.com/2-0001-bug-19558-Fix-user-defined-prefix-operators-and.patch)
  download | inline diff:
From e7032368270b9ac58698e9249f766739b66c848a Mon Sep 17 00:00:00 2001
From: Pierre Forstmann <pierre.forstmann@gmail.com>
Date: Sat, 18 Jul 2026 17:33:33 +0200
Subject: [PATCH] bug#19558: Fix user-defined prefix operators '|' and '->'

---
 src/backend/parser/gram.y | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index ff4e138..331da79 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -15873,6 +15873,10 @@ a_expr:		c_expr									{ $$ = $1; }
 				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
 			| '-' a_expr					%prec UMINUS
 				{ $$ = doNegate($2, @1); }
+			| '|' a_expr                  %prec UMINUS 
+				 { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", NULL , $2, @1); }
+			| RIGHT_ARROW a_expr                  %prec UMINUS 
+				 { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", NULL , $2, @1); }
 			| a_expr '+' a_expr
 				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }
 			| a_expr '-' a_expr
@@ -15902,6 +15906,7 @@ a_expr:		c_expr									{ $$ = $1; }
 			| a_expr '|' a_expr
 				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", $1, $3, @2); }
 
+
 			| a_expr qual_Op a_expr				%prec Op
 				{ $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
 			| qual_Op a_expr					%prec Op
@@ -16355,6 +16360,10 @@ b_expr:		c_expr
 				{ $$ = makeTypeCast($1, $3, @2); }
 			| '+' b_expr					%prec UMINUS
 				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
+			| '|' b_expr					%prec UMINUS
+				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", NULL, $2, @1); }
+			| RIGHT_ARROW b_expr					%prec UMINUS
+				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", NULL, $2, @1); }
 			| '-' b_expr					%prec UMINUS
 				{ $$ = doNegate($2, @1); }
 			| b_expr '+' b_expr
-- 
2.52.0



^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: [patch] BUG #19558: User-defined prefix operators "|" and "->" no longer parse in 19beta2 (SQL/PGQ grammar change)
@ 2026-07-18 15:42  Tom Lane <tgl@sss.pgh.pa.us>
  parent: Pierre Forstmann <pierre.forstmann@gmail.com>
  0 siblings, 1 reply; 5+ messages in thread

From: Tom Lane @ 2026-07-18 15:42 UTC (permalink / raw)
  To: Pierre Forstmann <pierre.forstmann@gmail.com>; +Cc: pierre@senellart.com; pgsql-bugs@lists.postgresql.org

Pierre Forstmann <pierre.forstmann@gmail.com> writes:
> I propose following patch that adds missing grammar rules:

Why are you promoting these to UMINUS binding precedence?
AFAICS they would have had Op precedence before v19
(and still do, as binary operators).

			regards, tom lane





^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: [patch] BUG #19558: User-defined prefix operators "|" and "->" no longer parse in 19beta2 (SQL/PGQ grammar change)
@ 2026-07-18 16:01  Pierre Forstmann <pierre.forstmann@gmail.com>
  parent: Tom Lane <tgl@sss.pgh.pa.us>
  0 siblings, 1 reply; 5+ messages in thread

From: Pierre Forstmann @ 2026-07-18 16:01 UTC (permalink / raw)
  To: Tom Lane <tgl@sss.pgh.pa.us>; +Cc: pierre@senellart.com; pgsql-bugs@lists.postgresql.org

No good reason: I have fixed my mistake in patch v002.

Thanks.

Le 18/07/2026 à 17:42, Tom Lane a écrit :
> Pierre Forstmann <pierre.forstmann@gmail.com> writes:
>> I propose following patch that adds missing grammar rules:
> Why are you promoting these to UMINUS binding precedence?
> AFAICS they would have had Op precedence before v19
> (and still do, as binary operators).
>
> 			regards, tom lane

Attachments:

  [text/x-patch] 0002-bug-19558-Fix-user-defined-prefix-operators-and-fixe.patch (1.5K, ../../1b69cad1-19b4-4334-bb6e-a343151e8b78@gmail.com/2-0002-bug-19558-Fix-user-defined-prefix-operators-and-fixe.patch)
  download | inline diff:
From 8481b482ab23fee014d3a0277a275749990f19a9 Mon Sep 17 00:00:00 2001
From: Pierre Forstmann <pierre.forstmann@gmail.com>
Date: Sat, 18 Jul 2026 17:53:55 +0200
Subject: [PATCH 2/2] bug#19558: Fix user-defined prefix operators '|' and
 '->': fixed %prec

---
 src/backend/parser/gram.y | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 331da79..071bbf2 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -15873,9 +15873,9 @@ a_expr:		c_expr									{ $$ = $1; }
 				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
 			| '-' a_expr					%prec UMINUS
 				{ $$ = doNegate($2, @1); }
-			| '|' a_expr                  %prec UMINUS 
+			| '|' a_expr                  %prec Op 
 				 { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", NULL , $2, @1); }
-			| RIGHT_ARROW a_expr                  %prec UMINUS 
+			| RIGHT_ARROW a_expr                  %prec Op 
 				 { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", NULL , $2, @1); }
 			| a_expr '+' a_expr
 				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }
@@ -15905,8 +15905,6 @@ a_expr:		c_expr									{ $$ = $1; }
 				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "->", $1, $3, @2); }
 			| a_expr '|' a_expr
 				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "|", $1, $3, @2); }
-
-
 			| a_expr qual_Op a_expr				%prec Op
 				{ $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
 			| qual_Op a_expr					%prec Op
-- 
2.52.0



^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: [patch] BUG #19558: User-defined prefix operators "|" and "->" no longer parse in 19beta2 (SQL/PGQ grammar change)
@ 2026-07-18 17:03  Tom Lane <tgl@sss.pgh.pa.us>
  parent: Pierre Forstmann <pierre.forstmann@gmail.com>
  0 siblings, 0 replies; 5+ messages in thread

From: Tom Lane @ 2026-07-18 17:03 UTC (permalink / raw)
  To: Pierre Forstmann <pierre.forstmann@gmail.com>; +Cc: pierre@senellart.com; pgsql-bugs@lists.postgresql.org

Pierre Forstmann <pierre.forstmann@gmail.com> writes:
> Le 18/07/2026 à 17:42, Tom Lane a écrit :
>> Why are you promoting these to UMINUS binding precedence?
>> AFAICS they would have had Op precedence before v19
>> (and still do, as binary operators).

> No good reason: I have fixed my mistake in patch v002.

OK.  You don't need the explicit %prec specs, because these operators
already have the same precedence as Op:

%left		Op OPERATOR RIGHT_ARROW '|'	/* multi-character ops and user-defined operators */

and a bison rule takes the precedence of its rightmost terminal
symbol by default.  More importantly, you missed adding the
same productions to b_expr, so that there would have been contexts
where these symbols still didn't work like they used to.

I fixed both those things and pushed it.  Thanks for the
report and the patch!

			regards, tom lane






^ permalink  raw  reply  [nested|flat] 5+ messages in thread


end of thread, other threads:[~2026-07-18 17:03 UTC | newest]

Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-07-18 08:39 BUG #19558: User-defined prefix operators "|" and "->" no longer parse in 19beta2 (SQL/PGQ grammar change) PG Bug reporting form <noreply@postgresql.org>
2026-07-18 15:38 ` Pierre Forstmann <pierre.forstmann@gmail.com>
2026-07-18 15:42   ` Tom Lane <tgl@sss.pgh.pa.us>
2026-07-18 16:01     ` Pierre Forstmann <pierre.forstmann@gmail.com>
2026-07-18 17:03       ` Tom Lane <tgl@sss.pgh.pa.us>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox