I looked a bit at the parser additions, because there were some concerns expressed that they are quite big.

It looks like the parser rules were mostly literally copied from the BNF in the SQL standard. That's probably a reasonable place to start, but now at the end, there is some room for simplification.

Attached are a few patches that apply on top of the 0003 patch. (I haven't gotten to 0004 in detail yet.) Some explanations:

0001-Put-keywords-in-right-order.patch

This is just an unrelated cleanup.

0002-Remove-js_quotes-union-entry.patch

We usually don't want to put every single node type into the gram.y %union. This one can be trivially removed.

0003-Move-some-code-from-gram.y-to-parse-analysis.patch

Code like this can be postponed to parse analysis, keeping gram.y smaller. The error pointer loses a bit of precision, but I think that's ok. (There is similar code in your 0004 patch, which could be similarly moved.)

0004-Remove-JsonBehavior-stuff-from-union.patch

Similar to my 0002. This adds a few casts as a result, but that is the typical style in gram.y.

0005-Get-rid-of-JsonBehaviorClause.patch

I think this two-level wrapping of the behavior clauses is both confusing and overkill. I was trying to just list the on-empty and on-error clauses separately in the top-level productions (JSON_VALUE etc.), but that led to shift/reduce errors. So the existing rule structure is probably ok. But we don't need a separate node type just to combine two values and then unpack them again shortly thereafter. So I just replaced all this with a list.

0006-Get-rid-of-JsonCommon.patch

This is an example where the SQL standard BNF is not sensible to apply literally. I moved those clauses up directly into their callers, thus removing one intermediate levels of rules and also nodes. Also, the path name (AS name) stuff is only for JSON_TABLE, so it's not needed in this patch. I removed it here, but it would have to be readded in your 0004 patch.

Another thing: In your patch, JSON_EXISTS has a RETURNING clause (json_returning_clause_opt), but I don't see that in the standard, and also not in the Oracle or Db2 docs. Where did this come from?

With these changes, I think the grammar complexity in your 0003 patch is at an acceptable level. Similar simplification opportunities exist in the 0004 patch, but I haven't worked on that yet. I suggest that you focus on getting 0001..0003 committed around this commit fest and then deal with 0004 in the next one. (Also split up the 0005 patch into the pieces that apply to 0003 and 0004, respectively.)
From 90cd46c91231a29a41118861d5a6122d78f93379 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 21 Nov 2023 05:19:03 +0100
Subject: [PATCH 1/6] Put keywords in right order

---
 src/backend/parser/gram.y | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 1dc3300fde..9a7058b767 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -735,7 +735,7 @@ static Node *makeRecursiveViewSelect(char *relname, List 
*aliases, Node *query);
        JOIN JSON JSON_ARRAY JSON_ARRAYAGG JSON_EXISTS JSON_OBJECT 
JSON_OBJECTAGG
        JSON_QUERY JSON_SCALAR JSON_SERIALIZE JSON_VALUE
 
-       KEY KEYS KEEP
+       KEEP KEY KEYS
 
        LABEL LANGUAGE LARGE_P LAST_P LATERAL_P
        LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL
-- 
2.42.1

From b669a45c9603a23db240cf1566b3f2e726254ac4 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 21 Nov 2023 05:28:17 +0100
Subject: [PATCH 2/6] Remove js_quotes %union entry

---
 src/backend/parser/gram.y | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 9a7058b767..a8cce5b00e 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -280,7 +280,6 @@ static Node *makeRecursiveViewSelect(char *relname, List 
*aliases, Node *query);
        struct KeyAction *keyaction;
        JsonBehavior *jsbehavior;
        JsonBehaviorClause *jsbehaviorclause;
-       JsonQuotes      js_quotes;
 }
 
 %type <node>   stmt toplevel_stmt schema_stmt routine_body_stmt
@@ -662,12 +661,12 @@ static Node *makeRecursiveViewSelect(char *relname, List 
*aliases, Node *query);
 %type <ival>   json_encoding_clause_opt
                                json_predicate_type_constraint
                                json_wrapper_behavior
+                               json_quotes_clause_opt
 %type <boolean>        json_key_uniqueness_constraint_opt
                                json_object_constructor_null_clause_opt
                                json_array_constructor_null_clause_opt
 %type <jsbehavior>     json_behavior
 %type <jsbehaviorclause> json_behavior_clause_opt
-%type <js_quotes>      json_quotes_clause_opt
 
 
 /*
-- 
2.42.1

From 7fb1906bab90e539697e6d66d3f2754eb3031603 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 21 Nov 2023 05:43:10 +0100
Subject: [PATCH 3/6] Move some code from gram.y to parse analysis

---
 src/backend/parser/gram.y                   |  5 -----
 src/backend/parser/parse_expr.c             |  6 ++++++
 src/test/regress/expected/jsonb_sqljson.out | 12 ++++++------
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index a8cce5b00e..a2d482ab70 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -15778,11 +15778,6 @@ func_expr_common_subexpr:
                                        n->common = (JsonCommon *) $3;
                                        n->output = (JsonOutput *) $4;
                                        n->wrapper = $5;
-                                       if (n->wrapper != JSW_NONE && $6 != 
JS_QUOTES_UNSPEC)
-                                               ereport(ERROR,
-                                                               
(errcode(ERRCODE_SYNTAX_ERROR),
-                                                                
errmsg("SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is 
used"),
-                                                                
parser_errposition(@6)));
                                        n->quotes = $6;
                                        n->behavior = $7;
                                        n->location = @1;
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 64571562c5..1c1f38a808 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -4302,6 +4302,12 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr 
*func)
                case JSON_QUERY_OP:
                        func_name = "JSON_QUERY";
 
+                       if (func->wrapper != JSW_NONE && func->quotes != 
JS_QUOTES_UNSPEC)
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_SYNTAX_ERROR),
+                                                errmsg("SQL/JSON QUOTES 
behavior must not be specified when WITH WRAPPER is used"),
+                                                parser_errposition(pstate, 
func->location)));
+
                        jsexpr = transformJsonExprCommon(pstate, func, 
func_name);
                        jsexpr->wrapper = func->wrapper;
                        jsexpr->omit_quotes = (func->quotes == JS_QUOTES_OMIT);
diff --git a/src/test/regress/expected/jsonb_sqljson.out 
b/src/test/regress/expected/jsonb_sqljson.out
index b467971ed9..9bf3fb21db 100644
--- a/src/test/regress/expected/jsonb_sqljson.out
+++ b/src/test/regress/expected/jsonb_sqljson.out
@@ -658,19 +658,19 @@ SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING bytea 
FORMAT JSON OMIT QUOTES ERR
 SELECT JSON_QUERY(jsonb '[1]', '$' WITH WRAPPER OMIT QUOTES);
 ERROR:  SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is 
used
 LINE 1: SELECT JSON_QUERY(jsonb '[1]', '$' WITH WRAPPER OMIT QUOTES)...
-                                                        ^
+               ^
 SELECT JSON_QUERY(jsonb '[1]', '$' WITH WRAPPER KEEP QUOTES);
 ERROR:  SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is 
used
 LINE 1: SELECT JSON_QUERY(jsonb '[1]', '$' WITH WRAPPER KEEP QUOTES)...
-                                                        ^
+               ^
 SELECT JSON_QUERY(jsonb '[1]', '$' WITH CONDITIONAL WRAPPER KEEP QUOTES);
 ERROR:  SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is 
used
-LINE 1: ...N_QUERY(jsonb '[1]', '$' WITH CONDITIONAL WRAPPER KEEP QUOTE...
-                                                             ^
+LINE 1: SELECT JSON_QUERY(jsonb '[1]', '$' WITH CONDITIONAL WRAPPER ...
+               ^
 SELECT JSON_QUERY(jsonb '[1]', '$' WITH CONDITIONAL WRAPPER OMIT QUOTES);
 ERROR:  SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is 
used
-LINE 1: ...N_QUERY(jsonb '[1]', '$' WITH CONDITIONAL WRAPPER OMIT QUOTE...
-                                                             ^
+LINE 1: SELECT JSON_QUERY(jsonb '[1]', '$' WITH CONDITIONAL WRAPPER ...
+               ^
 -- Should succeed
 SELECT JSON_QUERY(jsonb '[1]', '$' WITHOUT WRAPPER OMIT QUOTES);
  json_query 
-- 
2.42.1

From a7e78b5e9c5cfa191a9580a7b98f6ea663edaa36 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 21 Nov 2023 05:53:55 +0100
Subject: [PATCH 4/6] Remove JsonBehavior stuff from %union

---
 src/backend/parser/gram.y | 36 +++++++++++++++++-------------------
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index a2d482ab70..2866d1345c 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -278,8 +278,6 @@ static Node *makeRecursiveViewSelect(char *relname, List 
*aliases, Node *query);
        MergeWhenClause *mergewhen;
        struct KeyActions *keyactions;
        struct KeyAction *keyaction;
-       JsonBehavior *jsbehavior;
-       JsonBehaviorClause *jsbehaviorclause;
 }
 
 %type <node>   stmt toplevel_stmt schema_stmt routine_body_stmt
@@ -654,6 +652,8 @@ static Node *makeRecursiveViewSelect(char *relname, List 
*aliases, Node *query);
                                json_aggregate_func
                                json_api_common_syntax
                                json_argument
+                               json_behavior
+                               json_behavior_clause_opt
 %type <list>   json_name_and_value_list
                                json_value_expr_list
                                json_array_aggregate_order_by_clause_opt
@@ -665,8 +665,6 @@ static Node *makeRecursiveViewSelect(char *relname, List 
*aliases, Node *query);
 %type <boolean>        json_key_uniqueness_constraint_opt
                                json_object_constructor_null_clause_opt
                                json_array_constructor_null_clause_opt
-%type <jsbehavior>     json_behavior
-%type <jsbehaviorclause> json_behavior_clause_opt
 
 
 /*
@@ -15779,7 +15777,7 @@ func_expr_common_subexpr:
                                        n->output = (JsonOutput *) $4;
                                        n->wrapper = $5;
                                        n->quotes = $6;
-                                       n->behavior = $7;
+                                       n->behavior = (JsonBehaviorClause *) $7;
                                        n->location = @1;
                                        $$ = (Node *) n;
                                }
@@ -15794,7 +15792,7 @@ func_expr_common_subexpr:
                                        p->op = JSON_EXISTS_OP;
                                        p->common = (JsonCommon *) $3;
                                        p->output = (JsonOutput *) $4;
-                                       p->behavior = $5;
+                                       p->behavior = (JsonBehaviorClause *) $5;
                                        p->location = @1;
                                        $$ = (Node *) p;
                                }
@@ -15809,7 +15807,7 @@ func_expr_common_subexpr:
                                        n->op = JSON_VALUE_OP;
                                        n->common = (JsonCommon *) $3;
                                        n->output = (JsonOutput *) $4;
-                                       n->behavior = $5;
+                                       n->behavior = (JsonBehaviorClause *) $5;
                                        n->location = @1;
                                        $$ = (Node *) n;
                                }
@@ -16665,25 +16663,25 @@ json_returning_clause_opt:
                ;
 
 json_behavior:
-                       DEFAULT a_expr  { $$ = 
makeJsonBehavior(JSON_BEHAVIOR_DEFAULT, $2, @1); }
-                       | ERROR_P               { $$ = 
makeJsonBehavior(JSON_BEHAVIOR_ERROR, NULL, @1); }
-                       | NULL_P                { $$ = 
makeJsonBehavior(JSON_BEHAVIOR_NULL, NULL, @1); }
-                       | TRUE_P                { $$ = 
makeJsonBehavior(JSON_BEHAVIOR_TRUE, NULL, @1); }
-                       | FALSE_P               { $$ = 
makeJsonBehavior(JSON_BEHAVIOR_FALSE, NULL, @1); }
-                       | UNKNOWN               { $$ = 
makeJsonBehavior(JSON_BEHAVIOR_UNKNOWN, NULL, @1); }
-                       | EMPTY_P ARRAY { $$ = 
makeJsonBehavior(JSON_BEHAVIOR_EMPTY_ARRAY, NULL, @1); }
-                       | EMPTY_P OBJECT_P      { $$ = 
makeJsonBehavior(JSON_BEHAVIOR_EMPTY_OBJECT, NULL, @1); }
+                       DEFAULT a_expr  { $$ = (Node *) 
makeJsonBehavior(JSON_BEHAVIOR_DEFAULT, $2, @1); }
+                       | ERROR_P               { $$ = (Node *) 
makeJsonBehavior(JSON_BEHAVIOR_ERROR, NULL, @1); }
+                       | NULL_P                { $$ = (Node *) 
makeJsonBehavior(JSON_BEHAVIOR_NULL, NULL, @1); }
+                       | TRUE_P                { $$ = (Node *) 
makeJsonBehavior(JSON_BEHAVIOR_TRUE, NULL, @1); }
+                       | FALSE_P               { $$ = (Node *) 
makeJsonBehavior(JSON_BEHAVIOR_FALSE, NULL, @1); }
+                       | UNKNOWN               { $$ = (Node *) 
makeJsonBehavior(JSON_BEHAVIOR_UNKNOWN, NULL, @1); }
+                       | EMPTY_P ARRAY { $$ = (Node *) 
makeJsonBehavior(JSON_BEHAVIOR_EMPTY_ARRAY, NULL, @1); }
+                       | EMPTY_P OBJECT_P      { $$ = (Node *) 
makeJsonBehavior(JSON_BEHAVIOR_EMPTY_OBJECT, NULL, @1); }
                        /* non-standard, for Oracle compatibility only */
-                       | EMPTY_P               { $$ = 
makeJsonBehavior(JSON_BEHAVIOR_EMPTY_ARRAY, NULL, @1); }
+                       | EMPTY_P               { $$ = (Node *) 
makeJsonBehavior(JSON_BEHAVIOR_EMPTY_ARRAY, NULL, @1); }
                ;
 
 json_behavior_clause_opt:
                        json_behavior ON EMPTY_P
-                               { $$ = makeJsonBehaviorClause($1, NULL, @1); }
+                               { $$ = (Node *) 
makeJsonBehaviorClause((JsonBehavior *) $1, NULL, @1); }
                        | json_behavior ON ERROR_P
-                               { $$ = makeJsonBehaviorClause(NULL, $1, @1); }
+                               { $$ = (Node *) makeJsonBehaviorClause(NULL, 
(JsonBehavior *) $1, @1); }
                        | json_behavior ON EMPTY_P json_behavior ON ERROR_P
-                               { $$ = makeJsonBehaviorClause($1, $4, @1); }
+                               { $$ = (Node *) 
makeJsonBehaviorClause((JsonBehavior *) $1, (JsonBehavior *) $4, @1); }
                        | /* EMPTY */
                                { $$ = NULL; }
                ;
-- 
2.42.1

From 34795db318b16892926dae9ebc848827771136fa Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 21 Nov 2023 07:21:03 +0100
Subject: [PATCH 5/6] Get rid of JsonBehaviorClause

---
 src/backend/nodes/makefuncs.c    | 17 -----------------
 src/backend/nodes/nodeFuncs.c    | 10 ----------
 src/backend/parser/gram.y        | 16 ++++++++--------
 src/backend/parser/parse_expr.c  |  4 ++--
 src/include/nodes/makefuncs.h    |  3 ---
 src/include/nodes/parsenodes.h   | 14 +-------------
 src/tools/pgindent/typedefs.list |  1 -
 7 files changed, 11 insertions(+), 54 deletions(-)

diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 746ed3d1da..a3757af6cf 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -857,23 +857,6 @@ makeJsonValueExpr(Expr *raw_expr, Expr *formatted_expr,
        return jve;
 }
 
-/*
- * makeJsonBehaviorClause -
- *       creates a JsonBehaviorClause node
- */
-JsonBehaviorClause *
-makeJsonBehaviorClause(JsonBehavior *on_empty, JsonBehavior *on_error,
-                                          int location)
-{
-       JsonBehaviorClause *behavior = makeNode(JsonBehaviorClause);
-
-       behavior->on_empty = on_empty;
-       behavior->on_error = on_error;
-       behavior->location = location;
-
-       return behavior;
-}
-
 /*
  * makeJsonBehavior -
  *       creates a JsonBehavior node
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 8e49ef6b95..7cad662e28 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -4093,16 +4093,6 @@ raw_expression_tree_walker_impl(Node *node,
                                        return true;
                        }
                        break;
-               case T_JsonBehaviorClause:
-                       {
-                               JsonBehaviorClause *jbc = (JsonBehaviorClause 
*) node;
-
-                               if (WALK(jbc->on_empty))
-                                       return true;
-                               if (WALK(jbc->on_error))
-                                       return true;
-                       }
-                       break;
                case T_JsonBehavior:
                        {
                                JsonBehavior *jb = (JsonBehavior *) node;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 2866d1345c..99585308c8 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -653,11 +653,11 @@ static Node *makeRecursiveViewSelect(char *relname, List 
*aliases, Node *query);
                                json_api_common_syntax
                                json_argument
                                json_behavior
-                               json_behavior_clause_opt
 %type <list>   json_name_and_value_list
                                json_value_expr_list
                                json_array_aggregate_order_by_clause_opt
                                json_arguments
+                               json_behavior_clause_opt
 %type <ival>   json_encoding_clause_opt
                                json_predicate_type_constraint
                                json_wrapper_behavior
@@ -15777,7 +15777,7 @@ func_expr_common_subexpr:
                                        n->output = (JsonOutput *) $4;
                                        n->wrapper = $5;
                                        n->quotes = $6;
-                                       n->behavior = (JsonBehaviorClause *) $7;
+                                       n->behavior = $7;
                                        n->location = @1;
                                        $$ = (Node *) n;
                                }
@@ -15792,7 +15792,7 @@ func_expr_common_subexpr:
                                        p->op = JSON_EXISTS_OP;
                                        p->common = (JsonCommon *) $3;
                                        p->output = (JsonOutput *) $4;
-                                       p->behavior = (JsonBehaviorClause *) $5;
+                                       p->behavior = $5;
                                        p->location = @1;
                                        $$ = (Node *) p;
                                }
@@ -15807,7 +15807,7 @@ func_expr_common_subexpr:
                                        n->op = JSON_VALUE_OP;
                                        n->common = (JsonCommon *) $3;
                                        n->output = (JsonOutput *) $4;
-                                       n->behavior = (JsonBehaviorClause *) $5;
+                                       n->behavior = $5;
                                        n->location = @1;
                                        $$ = (Node *) n;
                                }
@@ -16677,13 +16677,13 @@ json_behavior:
 
 json_behavior_clause_opt:
                        json_behavior ON EMPTY_P
-                               { $$ = (Node *) 
makeJsonBehaviorClause((JsonBehavior *) $1, NULL, @1); }
+                               { $$ = list_make2($1, NULL); }
                        | json_behavior ON ERROR_P
-                               { $$ = (Node *) makeJsonBehaviorClause(NULL, 
(JsonBehavior *) $1, @1); }
+                               { $$ = list_make2(NULL, $1); }
                        | json_behavior ON EMPTY_P json_behavior ON ERROR_P
-                               { $$ = (Node *) 
makeJsonBehaviorClause((JsonBehavior *) $1, (JsonBehavior *) $4, @1); }
+                               { $$ = list_make2($1, $4); }
                        | /* EMPTY */
-                               { $$ = NULL; }
+                               { $$ = list_make2(NULL, NULL); }
                ;
 
 json_predicate_type_constraint:
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 1c1f38a808..2f4d3cb118 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -4240,8 +4240,8 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr 
*func)
 
        if (func->behavior)
        {
-               on_error = func->behavior->on_error;
-               on_empty = func->behavior->on_empty;
+               on_empty = linitial(func->behavior);
+               on_error = lsecond(func->behavior);
        }
 
        switch (func->op)
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index 783e82ac92..a850a1928b 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -113,9 +113,6 @@ extern JsonFormat *makeJsonFormat(JsonFormatType type, 
JsonEncoding encoding,
 extern JsonValueExpr *makeJsonValueExpr(Expr *raw_expr, Expr *formatted_expr,
                                                                                
JsonFormat *format);
 extern JsonBehavior *makeJsonBehavior(JsonBehaviorType type, Node *expr, int 
location);
-extern JsonBehaviorClause *makeJsonBehaviorClause(JsonBehavior *on_empty,
-                                                                               
                  JsonBehavior *on_error,
-                                                                               
                  int location);
 extern Node *makeJsonKeyValue(Node *key, Node *value);
 extern Node *makeJsonIsPredicate(Node *expr, JsonFormat *format,
                                                                 JsonValueType 
item_type, bool unique_keys,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index ce6893fb91..0f977f935e 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1703,18 +1703,6 @@ typedef enum JsonQuotes
        JS_QUOTES_OMIT                          /* OMIT QUOTES */
 } JsonQuotes;
 
-/*
- * JsonBehaviorClause -
- *             representation of JSON ON ERROR / ON EMPTY clause
- */
-typedef struct JsonBehaviorClause
-{
-       NodeTag         type;
-       JsonBehavior *on_empty;         /* behavior ON EMPTY */
-       JsonBehavior *on_error;         /* behavior ON ERROR */
-       int                     location;               /* token location, or 
-1 if unknown */
-} JsonBehaviorClause;
-
 /*
  * JsonPathSpec -
  *             representation of JSON path constant
@@ -1767,7 +1755,7 @@ typedef struct JsonFuncExpr
        JsonExprOp      op;                             /* expression type */
        JsonCommon *common;                     /* common syntax */
        JsonOutput *output;                     /* output clause, if specified 
*/
-       JsonBehaviorClause *behavior;   /* ON ERROR / EMPTY behavior, if 
specified */
+       List       *behavior;           /* ON EMPTY / ERROR behavior, list of 
two JsonBehavior nodes */
        JsonWrapper wrapper;            /* array wrapper behavior (JSON_QUERY 
only) */
        JsonQuotes      quotes;                 /* omit or keep quotes? 
(JSON_QUERY only) */
        int                     location;               /* token location, or 
-1 if unknown */
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 3cfa9d756e..9258576b4c 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -1260,7 +1260,6 @@ JsonArrayConstructor
 JsonArrayQueryConstructor
 JsonBaseObjectInfo
 JsonBehavior
-JsonBehaviorClause
 JsonBehaviorType
 JsonCoercion
 JsonCoercionState
-- 
2.42.1

From 87f6b4ad2d85a243b106c933c3f8830e5f64451f Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 21 Nov 2023 07:25:41 +0100
Subject: [PATCH 6/6] Get rid of JsonCommon

---
 src/backend/nodes/nodeFuncs.c    | 18 ++----
 src/backend/parser/gram.y        | 95 ++++++++++----------------------
 src/backend/parser/parse_expr.c  |  8 +--
 src/include/nodes/parsenodes.h   | 18 +-----
 src/tools/pgindent/typedefs.list |  1 -
 5 files changed, 40 insertions(+), 100 deletions(-)

diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 7cad662e28..b6cd8c38d2 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -4081,18 +4081,6 @@ raw_expression_tree_walker_impl(Node *node,
                        return WALK(((JsonIsPredicate *) node)->expr);
                case T_JsonArgument:
                        return WALK(((JsonArgument *) node)->val);
-               case T_JsonCommon:
-                       {
-                               JsonCommon *jc = (JsonCommon *) node;
-
-                               if (WALK(jc->expr))
-                                       return true;
-                               if (WALK(jc->pathspec))
-                                       return true;
-                               if (WALK(jc->passing))
-                                       return true;
-                       }
-                       break;
                case T_JsonBehavior:
                        {
                                JsonBehavior *jb = (JsonBehavior *) node;
@@ -4106,7 +4094,11 @@ raw_expression_tree_walker_impl(Node *node,
                        {
                                JsonFuncExpr *jfe = (JsonFuncExpr *) node;
 
-                               if (WALK(jfe->common))
+                               if (WALK(jfe->context_item))
+                                       return true;
+                               if (WALK(jfe->pathspec))
+                                       return true;
+                               if (WALK(jfe->passing))
                                        return true;
                                if (jfe->output && WALK(jfe->output))
                                        return true;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 99585308c8..4cdf086a42 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -650,7 +650,6 @@ static Node *makeRecursiveViewSelect(char *relname, List 
*aliases, Node *query);
                                json_returning_clause_opt
                                json_name_and_value
                                json_aggregate_func
-                               json_api_common_syntax
                                json_argument
                                json_behavior
 %type <list>   json_name_and_value_list
@@ -658,6 +657,7 @@ static Node *makeRecursiveViewSelect(char *relname, List 
*aliases, Node *query);
                                json_array_aggregate_order_by_clause_opt
                                json_arguments
                                json_behavior_clause_opt
+                               json_passing_clause_opt
 %type <ival>   json_encoding_clause_opt
                                json_predicate_type_constraint
                                json_wrapper_behavior
@@ -15763,7 +15763,7 @@ func_expr_common_subexpr:
                                        $$ = (Node *) n;
                                }
                        | JSON_QUERY '('
-                               json_api_common_syntax
+                               json_value_expr ',' a_expr 
json_passing_clause_opt
                                json_returning_clause_opt
                                json_wrapper_behavior
                                json_quotes_clause_opt
@@ -15773,31 +15773,35 @@ func_expr_common_subexpr:
                                        JsonFuncExpr *n = 
makeNode(JsonFuncExpr);
 
                                        n->op = JSON_QUERY_OP;
-                                       n->common = (JsonCommon *) $3;
-                                       n->output = (JsonOutput *) $4;
-                                       n->wrapper = $5;
-                                       n->quotes = $6;
-                                       n->behavior = $7;
+                                       n->context_item = (JsonValueExpr *) $3;
+                                       n->pathspec = $5;
+                                       n->passing = $6;
+                                       n->output = (JsonOutput *) $7;
+                                       n->wrapper = $8;
+                                       n->quotes = $9;
+                                       n->behavior = $10;
                                        n->location = @1;
                                        $$ = (Node *) n;
                                }
                        | JSON_EXISTS '('
-                               json_api_common_syntax
+                               json_value_expr ',' a_expr 
json_passing_clause_opt
                                json_returning_clause_opt
                                json_behavior_clause_opt
                        ')'
                                {
-                                       JsonFuncExpr *p = 
makeNode(JsonFuncExpr);
+                                       JsonFuncExpr *n = 
makeNode(JsonFuncExpr);
 
-                                       p->op = JSON_EXISTS_OP;
-                                       p->common = (JsonCommon *) $3;
-                                       p->output = (JsonOutput *) $4;
-                                       p->behavior = $5;
-                                       p->location = @1;
-                                       $$ = (Node *) p;
+                                       n->op = JSON_EXISTS_OP;
+                                       n->context_item = (JsonValueExpr *) $3;
+                                       n->pathspec = $5;
+                                       n->passing = $6;
+                                       n->output = (JsonOutput *) $7;
+                                       n->behavior = $8;
+                                       n->location = @1;
+                                       $$ = (Node *) n;
                                }
                        | JSON_VALUE '('
-                               json_api_common_syntax
+                               json_value_expr ',' a_expr 
json_passing_clause_opt
                                json_returning_clause_opt
                                json_behavior_clause_opt
                        ')'
@@ -15805,9 +15809,11 @@ func_expr_common_subexpr:
                                        JsonFuncExpr *n = 
makeNode(JsonFuncExpr);
 
                                        n->op = JSON_VALUE_OP;
-                                       n->common = (JsonCommon *) $3;
-                                       n->output = (JsonOutput *) $4;
-                                       n->behavior = $5;
+                                       n->context_item = (JsonValueExpr *) $3;
+                                       n->pathspec = $5;
+                                       n->passing = $6;
+                                       n->output = (JsonOutput *) $7;
+                                       n->behavior = $8;
                                        n->location = @1;
                                        $$ = (Node *) n;
                                }
@@ -16537,54 +16543,9 @@ opt_asymmetric: ASYMMETRIC
                ;
 
 /* SQL/JSON support */
-json_api_common_syntax:
-                       json_value_expr ',' a_expr /* i.e. a json_path */
-                               {
-                                       JsonCommon *n = makeNode(JsonCommon);
-
-                                       n->expr = (JsonValueExpr *) $1;
-                                       n->pathspec = $3;
-                                       n->pathname = NULL;
-                                       n->passing = NULL;
-                                       n->location = @1;
-                                       $$ = (Node *) n;
-                               }
-                       | json_value_expr ',' a_expr AS name
-                               {
-                                       JsonCommon *n = makeNode(JsonCommon);
-
-                                       n->expr = (JsonValueExpr *) $1;
-                                       n->pathspec = $3;
-                                       n->pathname = $5;
-                                       n->passing = NULL;
-                                       n->location = @1;
-                                       $$ = (Node *) n;
-                               }
-
-                       | json_value_expr ',' a_expr /* i.e. a json_path */
-                               PASSING json_arguments
-                               {
-                                       JsonCommon *n = makeNode(JsonCommon);
-
-                                       n->expr = (JsonValueExpr *) $1;
-                                       n->pathspec = $3;
-                                       n->pathname = NULL;
-                                       n->passing = $5;
-                                       n->location = @1;
-                                       $$ = (Node *) n;
-                               }
-                       | json_value_expr ',' a_expr AS name
-                               PASSING json_arguments
-                               {
-                                       JsonCommon *n = makeNode(JsonCommon);
-
-                                       n->expr = (JsonValueExpr *) $1;
-                                       n->pathspec = $3;
-                                       n->pathname = $5;
-                                       n->passing = $7;
-                                       n->location = @1;
-                                       $$ = (Node *) n;
-                               }
+json_passing_clause_opt:
+                       PASSING json_arguments                                  
{ $$ = $2; }
+                       | /*EMPTY*/                                             
                { $$ = NIL; }
                ;
 
 json_arguments:
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 2f4d3cb118..af0843aa3c 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -4384,17 +4384,17 @@ transformJsonExprCommon(ParseState *pstate, 
JsonFuncExpr *func,
        jsexpr->location = func->location;
        jsexpr->op = func->op;
        jsexpr->formatted_expr = transformJsonValueExpr(pstate, constructName,
-                                                                               
                        func->common->expr,
+                                                                               
                        func->context_item,
                                                                                
                        JS_FORMAT_JSON,
                                                                                
                        InvalidOid, false);
 
-       jsexpr->format = func->common->expr->format;
+       jsexpr->format = func->context_item->format;
 
        /* Both set in the caller. */
        jsexpr->result_coercion = NULL;
        jsexpr->omit_quotes = false;
 
-       pathspec = transformExprRecurse(pstate, func->common->pathspec);
+       pathspec = transformExprRecurse(pstate, func->pathspec);
 
        jsexpr->path_spec =
                coerce_to_target_type(pstate, pathspec, exprType(pathspec),
@@ -4415,7 +4415,7 @@ transformJsonExprCommon(ParseState *pstate, JsonFuncExpr 
*func,
        transformJsonPassingArgs(pstate, constructName,
                                                         
exprType(jsexpr->formatted_expr) == JSONBOID ?
                                                         JS_FORMAT_JSONB : 
JS_FORMAT_JSON,
-                                                        func->common->passing,
+                                                        func->passing,
                                                         
&jsexpr->passing_values,
                                                         
&jsexpr->passing_names);
 
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 0f977f935e..83acd17ad4 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1731,20 +1731,6 @@ typedef struct JsonArgument
        char       *name;                       /* argument name */
 } JsonArgument;
 
-/*
- * JsonCommon -
- *             representation of common syntax of functions using JSON path
- */
-typedef struct JsonCommon
-{
-       NodeTag         type;
-       JsonValueExpr *expr;            /* context item expression */
-       Node       *pathspec;           /* JSON path specification expression */
-       char       *pathname;           /* path name, if any */
-       List       *passing;            /* list of PASSING clause arguments, if 
any */
-       int                     location;               /* token location, or 
-1 if unknown */
-} JsonCommon;
-
 /*
  * JsonFuncExpr -
  *             untransformed representation of JSON function expressions
@@ -1753,7 +1739,9 @@ typedef struct JsonFuncExpr
 {
        NodeTag         type;
        JsonExprOp      op;                             /* expression type */
-       JsonCommon *common;                     /* common syntax */
+       JsonValueExpr *context_item;    /* context item expression */
+       Node       *pathspec;           /* JSON path specification expression */
+       List       *passing;            /* list of PASSING clause arguments, if 
any */
        JsonOutput *output;                     /* output clause, if specified 
*/
        List       *behavior;           /* ON EMPTY / ERROR behavior, list of 
two JsonBehavior nodes */
        JsonWrapper wrapper;            /* array wrapper behavior (JSON_QUERY 
only) */
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 9258576b4c..8186a42659 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -1263,7 +1263,6 @@ JsonBehavior
 JsonBehaviorType
 JsonCoercion
 JsonCoercionState
-JsonCommon
 JsonConstructorExpr
 JsonConstructorExprState
 JsonConstructorType
-- 
2.42.1

Reply via email to