Revert recent SQL/JSON related commits
authorAmit Langote <amitlan@postgresql.org>
Fri, 6 Sep 2024 03:51:26 +0000 (12:51 +0900)
committerAmit Langote <amitlan@postgresql.org>
Fri, 6 Sep 2024 03:52:39 +0000 (12:52 +0900)
Reverts c88ce386c4d5067c230b8e, and  e4e27976a68, because a few BF
animals didn't like one or all of them.

src/backend/executor/execExpr.c
src/backend/parser/parse_expr.c
src/backend/utils/adt/ruleutils.c
src/test/regress/expected/sqljson_jsontable.out
src/test/regress/sql/sqljson_jsontable.sql

index 3db700dabf1a2e9af84f6394dfcb9f776eefdc50..9b52bab52fcb0fc03078f07f7cd589be42957365 100644 (file)
@@ -4236,8 +4236,6 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
    ErrorSaveContext *escontext =
        jsexpr->on_error->btype != JSON_BEHAVIOR_ERROR ?
        &jsestate->escontext : NULL;
-   bool        returning_domain =
-       get_typtype(jsexpr->returning->typid) == TYPTYPE_DOMAIN;
 
    jsestate->jsexpr = jsexpr;
 
@@ -4380,27 +4378,20 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
        ExprEvalPushStep(state, scratch);
    }
 
+   jsestate->jump_empty = jsestate->jump_error = -1;
+
    /*
     * Step to check jsestate->error and return the ON ERROR expression if
     * there is one.  This handles both the errors that occur during jsonpath
     * evaluation in EEOP_JSONEXPR_PATH and subsequent coercion evaluation.
-    *
-    * Speed up common cases by avoiding extra steps for a NULL-valued ON
-    * ERROR expression unless RETURNING a domain type, where constraints must
-    * be checked. ExecEvalJsonExprPath() already returns NULL on error,
-    * making additional steps unnecessary in typical scenarios. Note that the
-    * default ON ERROR behavior for JSON_VALUE() and JSON_QUERY() is to
-    * return NULL.
     */
-   jsestate->jump_error = state->steps_len;
    if (jsexpr->on_error &&
-       jsexpr->on_error->btype != JSON_BEHAVIOR_ERROR &&
-       (!(IsA(jsexpr->on_error->expr, Const) &&
-          ((Const *) jsexpr->on_error->expr)->constisnull) ||
-        returning_domain))
+       jsexpr->on_error->btype != JSON_BEHAVIOR_ERROR)
    {
        ErrorSaveContext *saved_escontext;
 
+       jsestate->jump_error = state->steps_len;
+
        /* JUMP to end if false, that is, skip the ON ERROR expression. */
        jumps_to_end = lappend_int(jumps_to_end, state->steps_len);
        scratch->opcode = EEOP_JUMP_IF_NOT_TRUE;
@@ -4450,19 +4441,14 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
    /*
     * Step to check jsestate->empty and return the ON EMPTY expression if
     * there is one.
-    *
-    * See the comment above for details on the optimization for NULL-valued
-    * expressions.
     */
-   jsestate->jump_empty = state->steps_len;
    if (jsexpr->on_empty != NULL &&
-       jsexpr->on_empty->btype != JSON_BEHAVIOR_ERROR &&
-       (!(IsA(jsexpr->on_empty->expr, Const) &&
-          ((Const *) jsexpr->on_empty->expr)->constisnull) ||
-        returning_domain))
+       jsexpr->on_empty->btype != JSON_BEHAVIOR_ERROR)
    {
        ErrorSaveContext *saved_escontext;
 
+       jsestate->jump_empty = state->steps_len;
+
        /* JUMP to end if false, that is, skip the ON EMPTY expression. */
        jumps_to_end = lappend_int(jumps_to_end, state->steps_len);
        scratch->opcode = EEOP_JUMP_IF_NOT_TRUE;
index 36c1b7a88f2c3684d6d58dac5c5e27a5d885e783..56e413da9f51f6c802ed40612d091df0cb9b8306 100644 (file)
@@ -4603,13 +4603,13 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
            }
 
            /*
-            * Assume EMPTY ARRAY ON ERROR when ON ERROR is not specified.
+            * Assume EMPTY ON ERROR when ON ERROR is not specified.
             *
             * ON EMPTY cannot be specified at the top level but it can be for
             * the individual columns.
             */
            jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
-                                                    JSON_BEHAVIOR_EMPTY_ARRAY,
+                                                    JSON_BEHAVIOR_EMPTY,
                                                     jsexpr->returning);
            break;
 
index cd9c3eddd1dd0232e90afd9da9cbe142f9e079cb..b31be31321dc3c6bbc36a5be8e8495e835c4cea3 100644 (file)
@@ -11719,6 +11719,7 @@ get_json_table_columns(TableFunc *tf, JsonTablePathScan *scan,
                       bool showimplicit)
 {
    StringInfo  buf = context->buf;
+   JsonExpr   *jexpr = castNode(JsonExpr, tf->docexpr);
    ListCell   *lc_colname;
    ListCell   *lc_coltype;
    ListCell   *lc_coltypmod;
@@ -11771,10 +11772,6 @@ get_json_table_columns(TableFunc *tf, JsonTablePathScan *scan,
        if (ordinality)
            continue;
 
-       /*
-        * Set default_behavior to guide get_json_expr_options() on whether to
-        * to emit the ON ERROR / EMPTY clauses.
-        */
        if (colexpr->op == JSON_EXISTS_OP)
        {
            appendStringInfoString(buf, " EXISTS");
@@ -11798,6 +11795,9 @@ get_json_table_columns(TableFunc *tf, JsonTablePathScan *scan,
            default_behavior = JSON_BEHAVIOR_NULL;
        }
 
+       if (jexpr->on_error->btype == JSON_BEHAVIOR_ERROR)
+           default_behavior = JSON_BEHAVIOR_ERROR;
+
        appendStringInfoString(buf, " PATH ");
 
        get_json_path_spec(colexpr->path_spec, context, showimplicit);
@@ -11875,7 +11875,7 @@ get_json_table(TableFunc *tf, deparse_context *context, bool showimplicit)
    get_json_table_columns(tf, castNode(JsonTablePathScan, tf->plan), context,
                           showimplicit);
 
-   if (jexpr->on_error->btype != JSON_BEHAVIOR_EMPTY_ARRAY)
+   if (jexpr->on_error->btype != JSON_BEHAVIOR_EMPTY)
        get_json_behavior(jexpr->on_error, context, "ERROR");
 
    if (PRETTY_INDENT(context))
index 5c7aaa6159db5e15baf37defd2dd6cba91efbc52..721e01d6ad079802a650a9c3e47563da346b4649 100644 (file)
@@ -1132,46 +1132,3 @@ ERROR:  invalid ON ERROR behavior for column "a"
 LINE 1: ...M JSON_TABLE(jsonb '1', '$' COLUMNS (a int exists empty obje...
                                                              ^
 DETAIL:  Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in ON ERROR for EXISTS columns.
--- Test JSON_TABLE() column deparsing -- don't emit default ON ERROR / EMPTY
--- behavior
-EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$'));
-                                             QUERY PLAN                                              
------------------------------------------------------------------------------------------------------
- Table Function Scan on "json_table"  (cost=0.01..1.00 rows=100 width=32)
-   Output: a
-   Table Function Call: JSON_TABLE('"a"'::jsonb, '$' AS json_table_path_0 COLUMNS (a text PATH '$'))
-(3 rows)
-
-EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') ERROR ON ERROR);
-                                                     QUERY PLAN                                                     
---------------------------------------------------------------------------------------------------------------------
- Table Function Scan on "json_table"  (cost=0.01..1.00 rows=100 width=32)
-   Output: a
-   Table Function Call: JSON_TABLE('"a"'::jsonb, '$' AS json_table_path_0 COLUMNS (a text PATH '$') ERROR ON ERROR)
-(3 rows)
-
--- Test JSON_TABLE() deparsing -- don't emit default ON ERROR behavior
-EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$'));
-                                             QUERY PLAN                                              
------------------------------------------------------------------------------------------------------
- Table Function Scan on "json_table"  (cost=0.01..1.00 rows=100 width=32)
-   Output: a
-   Table Function Call: JSON_TABLE('"a"'::jsonb, '$' AS json_table_path_0 COLUMNS (a text PATH '$'))
-(3 rows)
-
-EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ON ERROR);
-                                             QUERY PLAN                                              
------------------------------------------------------------------------------------------------------
- Table Function Scan on "json_table"  (cost=0.01..1.00 rows=100 width=32)
-   Output: a
-   Table Function Call: JSON_TABLE('"a"'::jsonb, '$' AS json_table_path_0 COLUMNS (a text PATH '$'))
-(3 rows)
-
-EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ARRAY ON ERROR);
-                                             QUERY PLAN                                              
------------------------------------------------------------------------------------------------------
- Table Function Scan on "json_table"  (cost=0.01..1.00 rows=100 width=32)
-   Output: a
-   Table Function Call: JSON_TABLE('"a"'::jsonb, '$' AS json_table_path_0 COLUMNS (a text PATH '$'))
-(3 rows)
-
index 31bc9c9ea0c30175c6b2ccbd8c82e16939217bb5..38992316f5afeb28947bce8879840364e9895e16 100644 (file)
@@ -542,13 +542,3 @@ SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int) NULL ON ERROR);
 SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int true on empty));
 SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int omit quotes true on error));
 SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int exists empty object on error));
-
--- Test JSON_TABLE() column deparsing -- don't emit default ON ERROR / EMPTY
--- behavior
-EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$'));
-EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') ERROR ON ERROR);
-
--- Test JSON_TABLE() deparsing -- don't emit default ON ERROR behavior
-EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$'));
-EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ON ERROR);
-EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ARRAY ON ERROR);