v10-0010-Remove-support-of-DEFAULT-ON-ERROR-in-SQL-JSON-f.patch
text/x-patch
Filename: v10-0010-Remove-support-of-DEFAULT-ON-ERROR-in-SQL-JSON-f.patch
Type: text/x-patch
Part: 9
Message:
Re: SQL/JSON features for v15
Patch
Format: format-patch
Series: patch v10-0010
Subject: Remove support of DEFAULT ON ERROR in SQL/JSON functions
| File | + | − |
|---|---|---|
| doc/src/sgml/func.sgml | 3 | 6 |
| src/backend/executor/execExpr.c | 0 | 15 |
| src/backend/executor/execExprInterp.c | 13 | 18 |
| src/backend/jit/llvm/llvmjit_expr.c | 3 | 21 |
| src/backend/nodes/makefuncs.c | 0 | 15 |
| src/backend/nodes/nodeFuncs.c | 0 | 27 |
| src/backend/parser/gram.y | 21 | 28 |
| src/backend/parser/parse_expr.c | 9 | 76 |
| src/backend/parser/parse_jsontable.c | 4 | 7 |
| src/backend/utils/adt/ruleutils.c | 10 | 13 |
| src/backend/utils/misc/queryjumble.c | 2 | 7 |
| src/include/executor/execExpr.h | 1 | 3 |
| src/include/nodes/makefuncs.h | 0 | 1 |
| src/include/nodes/parsenodes.h | 5 | 5 |
| src/include/nodes/primnodes.h | 5 | 16 |
| src/test/regress/expected/jsonb_sqljson.out | 197 | 235 |
| src/test/regress/sql/jsonb_sqljson.sql | 12 | 12 |
| src/tools/pgindent/typedefs.list | 0 | 1 |
From f2e7583b51bb529d09bb4e80bd993d1991470f37 Mon Sep 17 00:00:00 2001
From: Nikita Glukhov <n.gluhov@postgrespro.ru>
Date: Tue, 30 Aug 2022 22:32:06 +0300
Subject: [PATCH v10 10/10] Remove support of DEFAULT ON ERROR in SQL/JSON
functions
---
doc/src/sgml/func.sgml | 9 +-
src/backend/executor/execExpr.c | 15 -
src/backend/executor/execExprInterp.c | 31 +-
src/backend/jit/llvm/llvmjit_expr.c | 24 +-
src/backend/nodes/makefuncs.c | 15 -
src/backend/nodes/nodeFuncs.c | 27 --
src/backend/parser/gram.y | 49 +--
src/backend/parser/parse_expr.c | 85 +---
src/backend/parser/parse_jsontable.c | 11 +-
src/backend/utils/adt/ruleutils.c | 23 +-
src/backend/utils/misc/queryjumble.c | 9 +-
src/include/executor/execExpr.h | 4 +-
src/include/nodes/makefuncs.h | 1 -
src/include/nodes/parsenodes.h | 10 +-
src/include/nodes/primnodes.h | 21 +-
src/test/regress/expected/jsonb_sqljson.out | 432 +++++++++-----------
src/test/regress/sql/jsonb_sqljson.sql | 24 +-
src/tools/pgindent/typedefs.list | 1 -
18 files changed, 285 insertions(+), 506 deletions(-)
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 8e03a1831ab..a374b6b011c 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -17977,7 +17977,7 @@ FROM
<optional> <literal>PASSING</literal> { <parameter>value</parameter> <literal>AS</literal> <parameter>varname</parameter> } <optional>, ...</optional></optional>
<optional> <literal>RETURNING</literal> <parameter>data_type</parameter> </optional>
<optional> { <literal>ERROR</literal> | <literal>NULL</literal> } <literal>ON EMPTY</literal> </optional>
- <optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>DEFAULT</literal> <parameter>expression</parameter> } <literal>ON ERROR</literal> </optional>)
+ <optional> { <literal>ERROR</literal> | <literal>NULL</literal> } <literal>ON ERROR</literal> </optional>)
</para>
<para>
Returns the result of applying the
@@ -18004,10 +18004,7 @@ FROM
<literal>json_value(jsonb '"03:04 2015-02-01"', '$.datetime("HH24:MI YYYY-MM-DD")' RETURNING date)</literal>
<returnvalue>2015-02-01</returnvalue>
</para>
- <para>
- <literal>json_value(jsonb '[1,2]', 'strict $[*]' DEFAULT 9 ON ERROR)</literal>
- <returnvalue>9</returnvalue>
- </para></entry>
+ </entry>
</row>
<row>
<entry role="func_table_entry"><para role="func_signature">
@@ -18018,7 +18015,7 @@ FROM
<optional> { <literal>WITHOUT</literal> | <literal>WITH</literal> { <literal>CONDITIONAL</literal> | <optional><literal>UNCONDITIONAL</literal></optional> } } <optional> <literal>ARRAY</literal> </optional> <literal>WRAPPER</literal> </optional>
<optional> { <literal>KEEP</literal> | <literal>OMIT</literal> } <literal>QUOTES</literal> <optional> <literal>ON SCALAR STRING</literal> </optional> </optional>
<optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>EMPTY</literal> { <optional> <literal>ARRAY</literal> </optional> | <literal>OBJECT</literal> } } <literal>ON EMPTY</literal> </optional>
- <optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>EMPTY</literal> { <optional> <literal>ARRAY</literal> </optional> | <literal>OBJECT</literal> } | <literal>DEFAULT</literal> <parameter>expression</parameter> } <literal>ON ERROR</literal> </optional>)
+ <optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>EMPTY</literal> { <optional> <literal>ARRAY</literal> </optional> | <literal>OBJECT</literal> } } <literal>ON ERROR</literal> </optional>)
</para>
<para>
Returns the result of applying the
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 5ea7e6b421a..91efa259657 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -4164,9 +4164,7 @@ ExecInitJsonExpr(JsonExpr *jexpr, ExprState *state, ExprEvalStep *scratch,
ListCell *argexprlc;
ListCell *argnamelc;
int skip_step_off;
- int execpath_step_off;
int done_step_off;
- int default_on_error_step_off = -1;
/* JSON_TABLE preudo-function returns context item as a result */
if (jexpr->op == JSON_TABLE_OP)
@@ -4230,25 +4228,12 @@ ExecInitJsonExpr(JsonExpr *jexpr, ExprState *state, ExprEvalStep *scratch,
/* Step for the actual JSON path evaluation. */
scratch->opcode = EEOP_JSONEXPR_PATH;
scratch->d.jsonexpr.jsestate = jsestate;
- execpath_step_off = state->steps_len;
ExprEvalPushStep(state, scratch);
- if (jexpr->on_error->default_expr)
- {
- default_on_error_step_off = state->steps_len;
- ExecInitExprRec((Expr *) jexpr->on_error->default_expr, state, resv, resnull);
- }
-
/* Adjust jump locations */
done_step_off = state->steps_len;
/* EEOP_JSONEXPR_SKIP */
step = &state->steps[skip_step_off];
step->d.jsonexpr_skip.jump_done = done_step_off;
-
- /* EEOP_JSONEXPR_PATH */
- step = &state->steps[execpath_step_off];
- step->d.jsonexpr.jump_done = done_step_off;
- step->d.jsonexpr.jump_default_on_error =
- default_on_error_step_off > 0 ? default_on_error_step_off : done_step_off;
}
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 35f20d88232..a27887b3cb6 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -1855,10 +1855,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_CASE(EEOP_JSONEXPR_PATH)
{
/* too complex for an inline implementation */
- if (ExecEvalJsonExpr(state, op))
- EEO_JUMP(op->d.jsonexpr.jump_done);
- else
- EEO_JUMP(op->d.jsonexpr.jump_default_on_error);
+ ExecEvalJsonExpr(state, op);
+ EEO_NEXT();
}
EEO_CASE(EEOP_LAST)
@@ -5234,12 +5232,12 @@ ExecJsonQueryCoercion(JsonExpr *jexpr, Oid typid, int32 typmod,
* type.
*/
static Datum
-ExecEvalJsonBehavior(JsonBehavior *behavior, Oid ret_typid,
+ExecEvalJsonBehavior(JsonBehaviorType behavior, Oid ret_typid,
int32 ret_typmod, bool *is_null)
{
*is_null = false;
- switch (behavior->btype)
+ switch (behavior)
{
case JSON_BEHAVIOR_EMPTY_ARRAY:
if (ret_typid == JSONBOID)
@@ -5270,7 +5268,7 @@ ExecEvalJsonBehavior(JsonBehavior *behavior, Oid ret_typid,
{
Datum res;
bool ok PG_USED_FOR_ASSERTS_ONLY =
- ExecJsonCoerceBool(behavior->btype == JSON_BEHAVIOR_TRUE,
+ ExecJsonCoerceBool(behavior == JSON_BEHAVIOR_TRUE,
ret_typid, ret_typmod, &res);
Assert(ok); /* returning type must be checked in parser */
@@ -5284,12 +5282,13 @@ ExecEvalJsonBehavior(JsonBehavior *behavior, Oid ret_typid,
*is_null = true;
return (Datum) 0;
- case JSON_BEHAVIOR_DEFAULT:
+ case JSON_BEHAVIOR_UNSPEC:
+ case JSON_BEHAVIOR_ERROR:
Assert(0);
return (Datum) 0; /* must be handled by caller */
default:
- elog(ERROR, "unrecognized SQL/JSON behavior %d", behavior->btype);
+ elog(ERROR, "unrecognized SQL/JSON behavior %d", behavior);
return (Datum) 0;
}
}
@@ -5402,7 +5401,7 @@ ExecEvalJsonExprSkip(ExprState *state, ExprEvalStep *op)
* true - Ok, jump to the end of JsonExpr
* false - error occured, need to execute DEFAULT ON ERROR expression
*/
-bool
+void
ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op)
{
JsonExprState *jsestate = op->d.jsonexpr.jsestate;
@@ -5412,7 +5411,7 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op)
JsonPath *path;
bool empty = false;
bool error = false;
- bool throw_errors = jexpr->on_error->btype == JSON_BEHAVIOR_ERROR;
+ bool throw_errors = jexpr->on_error == JSON_BEHAVIOR_ERROR;
item = jsestate->formatted_expr.value;
path = DatumGetJsonPathP(jsestate->pathspec.value);
@@ -5423,9 +5422,9 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op)
if (empty && !error)
{
- Assert(jexpr->on_empty); /* it is not JSON_EXISTS */
+ Assert(jexpr->on_empty != JSON_BEHAVIOR_UNSPEC); /* it is not JSON_EXISTS */
- if (jexpr->on_empty->btype == JSON_BEHAVIOR_ERROR)
+ if (jexpr->on_empty == JSON_BEHAVIOR_ERROR)
{
if (throw_errors)
ereport(ERROR,
@@ -5436,7 +5435,7 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op)
}
else
{
- Assert(jexpr->on_empty->btype != JSON_BEHAVIOR_DEFAULT); /* not supported */
+ Assert(jexpr->on_empty != JSON_BEHAVIOR_DEFAULT); /* not supported */
/* Execute ON EMPTY behavior */
res = ExecEvalJsonBehavior(jexpr->on_empty,
@@ -5450,9 +5449,6 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op)
{
Assert(!throw_errors);
- if (jexpr->on_error->btype == JSON_BEHAVIOR_DEFAULT)
- return false; /* jump to DEFAULT ON ERROR expression */
-
/* Execute ON ERROR behavior */
res = ExecEvalJsonBehavior(jexpr->on_error,
jexpr->returning->typid,
@@ -5461,5 +5457,4 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op)
}
*op->resvalue = res;
- return true; /* jump to the end of expression */
}
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index 69eb86aaf0a..d517ed480f5 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -2439,27 +2439,9 @@ llvm_compile_expr(ExprState *state)
}
case EEOP_JSONEXPR_PATH:
- {
- LLVMValueRef v_ret;
-
- v_ret = build_EvalXFunc(b, mod, "ExecEvalJsonExpr",
- v_state, op);
- v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
-
- if (op->d.jsonexpr.jump_default_on_error != op->d.jsonexpr.jump_done)
- LLVMBuildCondBr(b,
- LLVMBuildICmp(b,
- LLVMIntEQ,
- v_ret,
- l_sbool_const(0),
- ""),
- opblocks[op->d.jsonexpr.jump_default_on_error],
- opblocks[op->d.jsonexpr.jump_done]);
- else
- LLVMBuildBr(b, opblocks[op->d.jsonexpr.jump_done]);
-
- break;
- }
+ build_EvalXFunc(b, mod, "ExecEvalJsonExpr", v_state, op);
+ LLVMBuildBr(b, opblocks[opno + 1]);
+ break;
case EEOP_LAST:
Assert(false);
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 28288dcfc10..f05e7f79627 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -852,21 +852,6 @@ makeJsonValueExpr(Expr *expr, JsonFormat *format)
return jve;
}
-/*
- * makeJsonBehavior -
- * creates a JsonBehavior node
- */
-JsonBehavior *
-makeJsonBehavior(JsonBehaviorType type, Node *default_expr)
-{
- JsonBehavior *behavior = makeNode(JsonBehavior);
-
- behavior->btype = type;
- behavior->default_expr = default_expr;
-
- return behavior;
-}
-
/*
* makeJsonTableJoinedPlan -
* creates a joined JsonTablePlan node
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index e0240beeeab..01f02eb78b1 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -2501,11 +2501,6 @@ expression_tree_walker(Node *node,
if (walker(jexpr->passing_values, context))
return true;
/* we assume walker doesn't care about passing_names */
- if (jexpr->on_empty &&
- walker(jexpr->on_empty->default_expr, context))
- return true;
- if (walker(jexpr->on_error->default_expr, context))
- return true;
}
break;
default:
@@ -3537,11 +3532,6 @@ expression_tree_mutator(Node *node,
MUTATE(newnode->formatted_expr, jexpr->formatted_expr, Node *);
MUTATE(newnode->passing_values, jexpr->passing_values, List *);
/* assume mutator does not care about passing_names */
- if (newnode->on_empty)
- MUTATE(newnode->on_empty->default_expr,
- jexpr->on_empty->default_expr, Node *);
- MUTATE(newnode->on_error->default_expr,
- jexpr->on_error->default_expr, Node *);
return (Node *) newnode;
}
break;
@@ -4438,15 +4428,6 @@ raw_expression_tree_walker(Node *node,
return true;
}
break;
- case T_JsonBehavior:
- {
- JsonBehavior *jb = (JsonBehavior *) node;
-
- if (jb->btype == JSON_BEHAVIOR_DEFAULT &&
- walker(jb->default_expr, context))
- return true;
- }
- break;
case T_JsonFuncExpr:
{
JsonFuncExpr *jfe = (JsonFuncExpr *) node;
@@ -4455,10 +4436,6 @@ raw_expression_tree_walker(Node *node,
return true;
if (jfe->output && walker(jfe->output, context))
return true;
- if (walker(jfe->on_empty, context))
- return true;
- if (walker(jfe->on_error, context))
- return true;
}
break;
case T_JsonTable:
@@ -4477,10 +4454,6 @@ raw_expression_tree_walker(Node *node,
if (walker(jtc->typeName, context))
return true;
- if (walker(jtc->on_empty, context))
- return true;
- if (walker(jtc->on_error, context))
- return true;
if (jtc->coltype == JTC_NESTED && walker(jtc->columns, context))
return true;
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index f9037761f96..3ab323bd791 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -281,11 +281,11 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
MergeWhenClause *mergewhen;
struct KeyActions *keyactions;
struct KeyAction *keyaction;
- JsonBehavior *jsbehavior;
+ JsonBehaviorType jsbehavior;
struct
{
- JsonBehavior *on_empty;
- JsonBehavior *on_error;
+ JsonBehaviorType on_empty;
+ JsonBehaviorType on_error;
} on_behavior;
JsonQuotes js_quotes;
}
@@ -730,7 +730,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
json_behavior_empty
json_behavior_empty_array
json_behavior_empty_object
- json_behavior_default
json_value_behavior
json_query_behavior
json_exists_error_behavior
@@ -16532,59 +16531,54 @@ json_encoding:
;
json_behavior_error:
- ERROR_P { $$ = makeJsonBehavior(JSON_BEHAVIOR_ERROR, NULL); }
+ ERROR_P { $$ = JSON_BEHAVIOR_ERROR; }
;
json_behavior_null:
- NULL_P { $$ = makeJsonBehavior(JSON_BEHAVIOR_NULL, NULL); }
+ NULL_P { $$ = JSON_BEHAVIOR_NULL; }
;
json_behavior_true:
- TRUE_P { $$ = makeJsonBehavior(JSON_BEHAVIOR_TRUE, NULL); }
+ TRUE_P { $$ = JSON_BEHAVIOR_TRUE; }
;
json_behavior_false:
- FALSE_P { $$ = makeJsonBehavior(JSON_BEHAVIOR_FALSE, NULL); }
+ FALSE_P { $$ = JSON_BEHAVIOR_FALSE; }
;
json_behavior_unknown:
- UNKNOWN { $$ = makeJsonBehavior(JSON_BEHAVIOR_UNKNOWN, NULL); }
+ UNKNOWN { $$ = JSON_BEHAVIOR_UNKNOWN; }
;
json_behavior_empty:
- EMPTY_P { $$ = makeJsonBehavior(JSON_BEHAVIOR_EMPTY_OBJECT, NULL); }
+ EMPTY_P { $$ = JSON_BEHAVIOR_EMPTY_OBJECT; }
;
json_behavior_empty_array:
- EMPTY_P ARRAY { $$ = makeJsonBehavior(JSON_BEHAVIOR_EMPTY_ARRAY, NULL); }
+ EMPTY_P ARRAY { $$ = JSON_BEHAVIOR_EMPTY_ARRAY; }
/* non-standard, for Oracle compatibility only */
- | EMPTY_P { $$ = makeJsonBehavior(JSON_BEHAVIOR_EMPTY_ARRAY, NULL); }
+ | EMPTY_P { $$ = JSON_BEHAVIOR_EMPTY_ARRAY; }
;
json_behavior_empty_object:
- EMPTY_P OBJECT_P { $$ = makeJsonBehavior(JSON_BEHAVIOR_EMPTY_OBJECT, NULL); }
- ;
-
-json_behavior_default:
- DEFAULT a_expr { $$ = makeJsonBehavior(JSON_BEHAVIOR_DEFAULT, $2); }
+ EMPTY_P OBJECT_P { $$ = JSON_BEHAVIOR_EMPTY_OBJECT; }
;
json_value_behavior:
json_behavior_null
| json_behavior_error
- | json_behavior_default
;
json_value_on_behavior_clause_opt:
json_value_behavior ON EMPTY_P
- { $$.on_empty = $1; $$.on_error = NULL; }
+ { $$.on_empty = $1; $$.on_error = JSON_BEHAVIOR_UNSPEC; }
| json_value_behavior ON EMPTY_P json_value_behavior ON ERROR_P
{ $$.on_empty = $1; $$.on_error = $4; }
| json_value_behavior ON ERROR_P
- { $$.on_empty = NULL; $$.on_error = $1; }
+ { $$.on_empty = JSON_BEHAVIOR_UNSPEC; $$.on_error = $1; }
| /* EMPTY */
- { $$.on_empty = NULL; $$.on_error = NULL; }
+ { $$.on_empty = JSON_BEHAVIOR_UNSPEC; $$.on_error = JSON_BEHAVIOR_UNSPEC; }
;
json_query_expr:
@@ -16656,18 +16650,17 @@ json_query_behavior:
| json_behavior_null
| json_behavior_empty_array
| json_behavior_empty_object
- | json_behavior_default
;
json_query_on_behavior_clause_opt:
json_query_behavior ON EMPTY_P
- { $$.on_empty = $1; $$.on_error = NULL; }
+ { $$.on_empty = $1; $$.on_error = JSON_BEHAVIOR_UNSPEC; }
| json_query_behavior ON EMPTY_P json_query_behavior ON ERROR_P
{ $$.on_empty = $1; $$.on_error = $4; }
| json_query_behavior ON ERROR_P
- { $$.on_empty = NULL; $$.on_error = $1; }
+ { $$.on_empty = JSON_BEHAVIOR_UNSPEC; $$.on_error = $1; }
| /* EMPTY */
- { $$.on_empty = NULL; $$.on_error = NULL; }
+ { $$.on_empty = JSON_BEHAVIOR_UNSPEC; $$.on_error = JSON_BEHAVIOR_UNSPEC; }
;
json_table:
@@ -16757,7 +16750,7 @@ json_table_exists_column_definition:
n->wrapper = JSW_NONE;
n->omit_quotes = false;
n->pathspec = $4;
- n->on_empty = NULL;
+ n->on_empty = JSON_BEHAVIOR_UNSPEC;
n->on_error = $5;
n->location = @1;
$$ = (Node *) n;
@@ -16771,7 +16764,7 @@ json_table_error_behavior:
json_table_error_clause_opt:
json_table_error_behavior ON ERROR_P { $$ = $1; }
- | /* EMPTY */ { $$ = NULL; }
+ | /* EMPTY */ { $$ = JSON_BEHAVIOR_UNSPEC; }
;
json_table_column_path_specification_clause_opt:
@@ -16977,7 +16970,7 @@ json_exists_predicate:
json_exists_error_clause_opt:
json_exists_error_behavior ON ERROR_P { $$ = $1; }
- | /* EMPTY */ { $$ = NULL; }
+ | /* EMPTY */ { $$ = JSON_BEHAVIOR_UNSPEC; }
;
json_exists_error_behavior:
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index f96334ce088..d1cedf222d7 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -4067,20 +4067,14 @@ transformJsonPassingArgs(ParseState *pstate, JsonFormatType format, List *args,
/*
* Transform a JSON BEHAVIOR clause.
*/
-static JsonBehavior *
-transformJsonBehavior(ParseState *pstate, JsonBehavior *behavior,
+static JsonBehaviorType
+transformJsonBehavior(JsonBehaviorType behavior,
JsonBehaviorType default_behavior)
{
- JsonBehaviorType behavior_type = default_behavior;
- Node *default_expr = NULL;
+ if (behavior == JSON_BEHAVIOR_UNSPEC)
+ return default_behavior;
- if (behavior)
- {
- behavior_type = behavior->btype;
- if (behavior_type == JSON_BEHAVIOR_DEFAULT)
- default_expr = transformExprRecurse(pstate, behavior->default_expr);
- }
- return makeJsonBehavior(behavior_type, default_expr);
+ return behavior;
}
/*
@@ -4132,17 +4126,17 @@ transformJsonExprCommon(ParseState *pstate, JsonFuncExpr *func)
&jsexpr->passing_values, &jsexpr->passing_names);
if (func->op != JSON_EXISTS_OP && func->op != JSON_TABLE_OP)
- jsexpr->on_empty = transformJsonBehavior(pstate, func->on_empty,
+ jsexpr->on_empty = transformJsonBehavior(func->on_empty,
JSON_BEHAVIOR_NULL);
if (func->op == JSON_EXISTS_OP)
- jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
+ jsexpr->on_error = transformJsonBehavior(func->on_error,
JSON_BEHAVIOR_FALSE);
else if (func->op == JSON_TABLE_OP)
- jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
+ jsexpr->on_error = transformJsonBehavior(func->on_error,
JSON_BEHAVIOR_EMPTY);
else
- jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
+ jsexpr->on_error = transformJsonBehavior(func->on_error,
JSON_BEHAVIOR_NULL);
return jsexpr;
@@ -4256,51 +4250,6 @@ transformJsonFuncExprOutput(ParseState *pstate, JsonFuncExpr *func,
jsexpr->returning);
}
-/*
- * Coerce an expression in JSON DEFAULT behavior to the target output type.
- */
-static Node *
-coerceDefaultJsonExpr(ParseState *pstate, JsonExpr *jsexpr,
- bool is_on_empty, Node *defexpr)
-{
- int location;
- Oid exprtype;
-
- if (!defexpr)
- return NULL;
-
- exprtype = exprType(defexpr);
- location = exprLocation(defexpr);
-
- if (location < 0)
- location = jsexpr->location;
-
- if (is_on_empty)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("DEFAULT ON EMPTY expressions are not supported"),
- parser_errposition(pstate, location)));
-
- defexpr = coerce_to_target_type(pstate,
- defexpr,
- exprtype,
- jsexpr->returning->typid,
- jsexpr->returning->typmod,
- COERCION_EXPLICIT,
- COERCE_IMPLICIT_CAST,
- location);
-
- if (!defexpr)
- ereport(ERROR,
- (errcode(ERRCODE_CANNOT_COERCE),
- errmsg("cannot cast DEFAULT expression type %s to %s",
- format_type_be(exprtype),
- format_type_be(jsexpr->returning->typid)),
- parser_errposition(pstate, location)));
-
- return defexpr;
-}
-
/*
* Transform JSON_VALUE, JSON_QUERY, JSON_EXISTS functions into a JsonExpr node.
*/
@@ -4321,14 +4270,6 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
jsexpr->returning->format->format_type = JS_FORMAT_DEFAULT;
jsexpr->returning->format->encoding = JS_ENC_DEFAULT;
- jsexpr->on_empty->default_expr =
- coerceDefaultJsonExpr(pstate, jsexpr, true,
- jsexpr->on_empty->default_expr);
-
- jsexpr->on_error->default_expr =
- coerceDefaultJsonExpr(pstate, jsexpr, false,
- jsexpr->on_error->default_expr);
-
break;
case JSON_QUERY_OP:
@@ -4336,14 +4277,6 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
transformJsonFuncExprOutput(pstate, func, jsexpr);
- jsexpr->on_empty->default_expr =
- coerceDefaultJsonExpr(pstate, jsexpr, true,
- jsexpr->on_empty->default_expr);
-
- jsexpr->on_error->default_expr =
- coerceDefaultJsonExpr(pstate, jsexpr, false,
- jsexpr->on_error->default_expr);
-
jsexpr->wrapper = func->wrapper;
jsexpr->omit_quotes = func->omit_quotes;
diff --git a/src/backend/parser/parse_jsontable.c b/src/backend/parser/parse_jsontable.c
index bc3272017ef..db1cb99ed40 100644
--- a/src/backend/parser/parse_jsontable.c
+++ b/src/backend/parser/parse_jsontable.c
@@ -83,8 +83,8 @@ transformJsonTableColumn(JsonTableColumn *jtc, Node *contextItemExpr,
jfexpr->output = output;
jfexpr->on_empty = jtc->on_empty;
jfexpr->on_error = jtc->on_error;
- if (!jfexpr->on_error && errorOnError)
- jfexpr->on_error = makeJsonBehavior(JSON_BEHAVIOR_ERROR, NULL);
+ if (jfexpr->on_error == JSON_BEHAVIOR_UNSPEC && errorOnError)
+ jfexpr->on_error = JSON_BEHAVIOR_ERROR;
jfexpr->omit_quotes = jtc->omit_quotes;
jfexpr->wrapper = jtc->wrapper;
jfexpr->location = jtc->location;
@@ -423,8 +423,7 @@ appendJsonTableColumns(JsonTableContext *cxt, List *columns)
ParseState *pstate = cxt->pstate;
JsonTable *jt = cxt->table;
TableFunc *tf = cxt->tablefunc;
- bool errorOnError = jt->on_error &&
- jt->on_error->btype == JSON_BEHAVIOR_ERROR;
+ bool errorOnError = jt->on_error == JSON_BEHAVIOR_ERROR;
foreach(col, columns)
{
@@ -542,9 +541,7 @@ makeParentJsonTableNode(JsonTableContext *cxt, char *pathSpec, List *columns)
/* save end of column range */
node->colMax = list_length(cxt->tablefunc->colvalexprs) - 1;
- node->errorOnError =
- cxt->table->on_error &&
- cxt->table->on_error->btype == JSON_BEHAVIOR_ERROR;
+ node->errorOnError = cxt->table->on_error == JSON_BEHAVIOR_ERROR;
return node;
}
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 8964f73b929..23bbb09c712 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -8544,7 +8544,7 @@ get_json_returning(JsonReturning *returning, StringInfo buf,
}
static void
-get_json_behavior(JsonBehavior *behavior, deparse_context *context,
+get_json_behavior(JsonBehaviorType behavior, deparse_context *context,
const char *on)
{
/*
@@ -8553,6 +8553,7 @@ get_json_behavior(JsonBehavior *behavior, deparse_context *context,
*/
const char *behavior_names[] =
{
+ " UNSPECIFIED",
" NULL",
" ERROR",
" EMPTY",
@@ -8560,17 +8561,13 @@ get_json_behavior(JsonBehavior *behavior, deparse_context *context,
" FALSE",
" UNKNOWN",
" EMPTY ARRAY",
- " EMPTY OBJECT",
- " DEFAULT "
+ " EMPTY OBJECT"
};
- if ((int) behavior->btype < 0 || behavior->btype >= lengthof(behavior_names))
- elog(ERROR, "invalid json behavior type: %d", behavior->btype);
+ if ((int) behavior < 1 || behavior >= lengthof(behavior_names))
+ elog(ERROR, "invalid json behavior type: %d", behavior);
- appendStringInfoString(context->buf, behavior_names[behavior->btype]);
-
- if (behavior->btype == JSON_BEHAVIOR_DEFAULT)
- get_rule_expr(behavior->default_expr, context, false);
+ appendStringInfoString(context->buf, behavior_names[behavior]);
appendStringInfo(context->buf, " ON %s", on);
}
@@ -8597,10 +8594,10 @@ get_json_expr_options(JsonExpr *jsexpr, deparse_context *context,
}
if (jsexpr->op != JSON_EXISTS_OP &&
- jsexpr->on_empty->btype != default_behavior)
+ jsexpr->on_empty != default_behavior)
get_json_behavior(jsexpr->on_empty, context, "EMPTY");
- if (jsexpr->on_error->btype != default_behavior)
+ if (jsexpr->on_error != default_behavior)
get_json_behavior(jsexpr->on_error, context, "ERROR");
}
@@ -11364,7 +11361,7 @@ get_json_table_columns(TableFunc *tf, JsonTableParent *node,
default_behavior = JSON_BEHAVIOR_NULL;
}
- if (jexpr->on_error->btype == JSON_BEHAVIOR_ERROR)
+ if (jexpr->on_error == JSON_BEHAVIOR_ERROR)
default_behavior = JSON_BEHAVIOR_ERROR;
appendStringInfoString(buf, " PATH ");
@@ -11447,7 +11444,7 @@ get_json_table(TableFunc *tf, deparse_context *context, bool showimplicit)
appendContextKeyword(context, "PLAN ", 0, 0, 0);
get_json_table_plan(tf, (Node *) root, context, true);
- if (jexpr->on_error->btype != JSON_BEHAVIOR_EMPTY)
+ if (jexpr->on_error != JSON_BEHAVIOR_EMPTY)
get_json_behavior(jexpr->on_error, context, "ERROR");
if (PRETTY_INDENT(context))
diff --git a/src/backend/utils/misc/queryjumble.c b/src/backend/utils/misc/queryjumble.c
index eeaa0b31fe2..aab74345a80 100644
--- a/src/backend/utils/misc/queryjumble.c
+++ b/src/backend/utils/misc/queryjumble.c
@@ -798,13 +798,8 @@ JumbleExpr(JumbleState *jstate, Node *node)
APP_JUMB_STRING(lfirst_node(String, temp)->sval);
}
JumbleExpr(jstate, (Node *) jexpr->passing_values);
- if (jexpr->on_empty)
- {
- APP_JUMB(jexpr->on_empty->btype);
- JumbleExpr(jstate, jexpr->on_empty->default_expr);
- }
- APP_JUMB(jexpr->on_error->btype);
- JumbleExpr(jstate, jexpr->on_error->default_expr);
+ APP_JUMB(jexpr->on_empty);
+ APP_JUMB(jexpr->on_error);
}
break;
case T_List:
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index d67419c66a9..4d2159ba7ef 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -697,8 +697,6 @@ typedef struct ExprEvalStep
struct
{
struct JsonExprState *jsestate;
- int jump_done;
- int jump_default_on_error; /* ON ERROR DEFAULT expression */
} jsonexpr;
/* for EEOP_JSONEXPR_SKIP */
@@ -838,7 +836,7 @@ extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op,
ExprContext *econtext, TupleTableSlot *slot);
extern void ExecEvalJsonConstructor(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
-extern bool ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op);
+extern void ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op);
extern bool ExecEvalJsonExprSkip(ExprState *state, ExprEvalStep *op);
extern void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup,
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index 06e6369026a..303b66e0a27 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -109,7 +109,6 @@ extern VacuumRelation *makeVacuumRelation(RangeVar *relation, Oid oid, List *va_
extern JsonFormat *makeJsonFormat(JsonFormatType type, JsonEncoding encoding,
int location);
extern JsonValueExpr *makeJsonValueExpr(Expr *expr, JsonFormat *format);
-extern JsonBehavior *makeJsonBehavior(JsonBehaviorType type, Node *expr);
extern Node *makeJsonTableJoinedPlan(JsonTablePlanJoinType type,
Node *plan1, Node *plan2, int location);
extern Node *makeJsonKeyValue(Node *key, Node *value);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index b3760318562..3a663cde89c 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1678,8 +1678,8 @@ typedef struct JsonFuncExpr
JsonExprOp op; /* expression type */
JsonCommon *common; /* common syntax */
JsonOutput *output; /* output clause, if specified */
- JsonBehavior *on_empty; /* ON EMPTY behavior, if specified */
- JsonBehavior *on_error; /* ON ERROR behavior, if specified */
+ JsonBehaviorType on_empty; /* ON EMPTY behavior, if specified */
+ JsonBehaviorType on_error; /* ON ERROR behavior, if specified */
JsonWrapper wrapper; /* array wrapper behavior (JSON_QUERY only) */
bool omit_quotes; /* omit or keep quotes? (JSON_QUERY only) */
int location; /* token location, or -1 if unknown */
@@ -1701,8 +1701,8 @@ typedef struct JsonTableColumn
JsonWrapper wrapper; /* WRAPPER behavior for formatted columns */
bool omit_quotes; /* omit or keep quotes on scalar strings? */
List *columns; /* nested columns */
- JsonBehavior *on_empty; /* ON EMPTY behavior */
- JsonBehavior *on_error; /* ON ERROR behavior */
+ JsonBehaviorType on_empty; /* ON EMPTY behavior */
+ JsonBehaviorType on_error; /* ON ERROR behavior */
int location; /* token location, or -1 if unknown */
} JsonTableColumn;
@@ -1756,7 +1756,7 @@ typedef struct JsonTable
JsonCommon *common; /* common JSON path syntax fields */
List *columns; /* list of JsonTableColumn */
JsonTablePlan *plan; /* join plan, if specified */
- JsonBehavior *on_error; /* ON ERROR behavior, if specified */
+ JsonBehaviorType on_error; /* ON ERROR behavior, if specified */
Alias *alias; /* table alias in FROM clause */
bool lateral; /* does it have LATERAL prefix? */
int location; /* token location, or -1 if unknown */
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 25a0fb8a445..e00c403fde7 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1428,15 +1428,15 @@ typedef enum JsonFormatType
*/
typedef enum JsonBehaviorType
{
- JSON_BEHAVIOR_NULL = 0,
+ JSON_BEHAVIOR_UNSPEC = 0,
+ JSON_BEHAVIOR_NULL,
JSON_BEHAVIOR_ERROR,
JSON_BEHAVIOR_EMPTY,
JSON_BEHAVIOR_TRUE,
JSON_BEHAVIOR_FALSE,
JSON_BEHAVIOR_UNKNOWN,
JSON_BEHAVIOR_EMPTY_ARRAY,
- JSON_BEHAVIOR_EMPTY_OBJECT,
- JSON_BEHAVIOR_DEFAULT
+ JSON_BEHAVIOR_EMPTY_OBJECT
} JsonBehaviorType;
/*
@@ -1540,17 +1540,6 @@ typedef struct JsonIsPredicate
int location; /* token location, or -1 if unknown */
} JsonIsPredicate;
-/*
- * JsonBehavior -
- * representation of JSON ON ... BEHAVIOR clause
- */
-typedef struct JsonBehavior
-{
- NodeTag type;
- JsonBehaviorType btype; /* behavior type */
- Node *default_expr; /* default expression, if any */
-} JsonBehavior;
-
/*
* JsonExpr -
* transformed representation of JSON_VALUE(), JSON_QUERY(), JSON_EXISTS()
@@ -1565,8 +1554,8 @@ typedef struct JsonExpr
List *passing_names; /* PASSING argument names */
List *passing_values; /* PASSING argument values */
JsonReturning *returning; /* RETURNING clause type/format info */
- JsonBehavior *on_empty; /* ON EMPTY behavior */
- JsonBehavior *on_error; /* ON ERROR behavior */
+ JsonBehaviorType on_empty; /* ON EMPTY behavior */
+ JsonBehaviorType on_error; /* ON ERROR behavior */
JsonWrapper wrapper; /* WRAPPER for JSON_QUERY */
Oid collation; /* Collation of result, or InvalidOid if none */
bool omit_quotes; /* KEEP/OMIT QUOTES for JSON_QUERY */
diff --git a/src/test/regress/expected/jsonb_sqljson.out b/src/test/regress/expected/jsonb_sqljson.out
index fcd921130f5..5610a94f3dd 100644
--- a/src/test/regress/expected/jsonb_sqljson.out
+++ b/src/test/regress/expected/jsonb_sqljson.out
@@ -334,11 +334,9 @@ SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int);
SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int ERROR ON ERROR);
ERROR: invalid input syntax for type integer: "aaa"
SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int DEFAULT 111 ON ERROR);
- json_value
-------------
- 111
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...ELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int DEFAULT 11...
+ ^
SELECT JSON_VALUE(jsonb '"123"', '$' RETURNING int) + 234;
?column?
----------
@@ -376,11 +374,9 @@ SELECT JSON_VALUE(jsonb '"-inf"', '$' RETURNING float4);
(1 row)
SELECT JSON_VALUE(jsonb '"err"', '$' RETURNING float4 DEFAULT -1 ON ERROR);
- json_value
-------------
- -1
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...CT JSON_VALUE(jsonb '"err"', '$' RETURNING float4 DEFAULT -1...
+ ^
SELECT JSON_VALUE(jsonb '"err"', '$' RETURNING float4 ERROR ON ERROR);
ERROR: invalid input syntax for type real: "err"
SELECT JSON_VALUE(jsonb '1.23', '$' RETURNING float8);
@@ -408,11 +404,9 @@ SELECT JSON_VALUE(jsonb '"-inf"', '$' RETURNING float8);
(1 row)
SELECT JSON_VALUE(jsonb '"err"', '$' RETURNING float8 DEFAULT -1 ON ERROR);
- json_value
-------------
- -1
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...CT JSON_VALUE(jsonb '"err"', '$' RETURNING float8 DEFAULT -1...
+ ^
SELECT JSON_VALUE(jsonb '"err"', '$' RETURNING float8 ERROR ON ERROR);
ERROR: invalid input syntax for type double precision: "err"
SELECT JSON_VALUE(jsonb '1.23', '$' RETURNING numeric);
@@ -440,11 +434,9 @@ SELECT JSON_VALUE(jsonb '"-inf"', '$' RETURNING numeric);
(1 row)
SELECT JSON_VALUE(jsonb '"err"', '$' RETURNING numeric DEFAULT -1 ON ERROR);
- json_value
-------------
- -1
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...T JSON_VALUE(jsonb '"err"', '$' RETURNING numeric DEFAULT -1...
+ ^
SELECT JSON_VALUE(jsonb '"err"', '$' RETURNING numeric ERROR ON ERROR);
ERROR: invalid input syntax for type numeric: "err"
-- Test for domain types
@@ -470,9 +462,9 @@ ERROR: returning type sqljsonb_int_not_null is not supported in JSON_VALUE()
LINE 1: SELECT JSON_VALUE(jsonb '1', '$.a' RETURNING sqljsonb_int_no...
^
SELECT JSON_VALUE(jsonb '1', '$.a' RETURNING sqljsonb_int_not_null DEFAULT NULL ON ERROR);
-ERROR: returning type sqljsonb_int_not_null is not supported in JSON_VALUE()
-LINE 1: SELECT JSON_VALUE(jsonb '1', '$.a' RETURNING sqljsonb_int_no...
- ^
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...(jsonb '1', '$.a' RETURNING sqljsonb_int_not_null DEFAULT NU...
+ ^
-- Test returning of non-scalar items
SELECT JSON_VALUE(jsonb '[]', '$');
json_value
@@ -499,11 +491,9 @@ SELECT JSON_VALUE(jsonb '1', '$.a');
SELECT JSON_VALUE(jsonb '1', 'strict $.a' ERROR ON ERROR);
ERROR: jsonpath member accessor can only be applied to an object
SELECT JSON_VALUE(jsonb '1', 'strict $.a' DEFAULT 'error' ON ERROR);
- json_value
-------------
- error
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: SELECT JSON_VALUE(jsonb '1', 'strict $.a' DEFAULT 'error' ON...
+ ^
SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON ERROR);
json_value
------------
@@ -513,61 +503,45 @@ SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON ERROR);
SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON EMPTY ERROR ON ERROR);
ERROR: no SQL/JSON item
SELECT JSON_VALUE(jsonb '1', 'strict $.a' DEFAULT 2 ON ERROR);
- json_value
-------------
- 2
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: SELECT JSON_VALUE(jsonb '1', 'strict $.a' DEFAULT 2 ON ERROR...
+ ^
SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT 2 ON ERROR);
- json_value
-------------
-
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT 2 ON ERROR);
+ ^
SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON ERROR);
- json_value
-------------
-
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON ERROR)...
+ ^
SELECT JSON_VALUE(jsonb '1', 'lax $.a' NULL ON EMPTY DEFAULT '2' ON ERROR);
- json_value
-------------
-
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...ECT JSON_VALUE(jsonb '1', 'lax $.a' NULL ON EMPTY DEFAULT '2...
+ ^
SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON EMPTY DEFAULT '3' ON ERROR);
-ERROR: DEFAULT ON EMPTY expressions are not supported
+ERROR: syntax error at or near "DEFAULT"
LINE 1: SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON EMPTY ...
- ^
+ ^
SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON EMPTY DEFAULT '3' ON ERROR);
- json_value
-------------
- 3
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...CT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON EMPTY DEFAULT '3...
+ ^
SELECT JSON_VALUE(jsonb '[1,2]', '$[*]' ERROR ON ERROR);
ERROR: JSON path expression in JSON_VALUE should return singleton scalar item
SELECT JSON_VALUE(jsonb '[1,2]', '$[*]' DEFAULT '0' ON ERROR);
- json_value
-------------
- 0
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: SELECT JSON_VALUE(jsonb '[1,2]', '$[*]' DEFAULT '0' ON ERROR...
+ ^
SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int ERROR ON ERROR);
ERROR: invalid input syntax for type integer: " "
SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR);
- json_value
-------------
- 5
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...CT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int DEFAULT 2 ...
+ ^
SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR);
- json_value
-------------
- 1
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...CT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int DEFAULT 2 ...
+ ^
SELECT
x,
JSON_VALUE(
@@ -575,15 +549,15 @@ SELECT
'$.* ? (@ > $x)' PASSING x AS x
RETURNING int
NULL ON EMPTY
- DEFAULT -2 ON ERROR
+ NULL ON ERROR
) y
FROM
generate_series(0, 2) x;
- x | y
----+----
- 0 | -2
- 1 | 2
- 2 |
+ x | y
+---+---
+ 0 |
+ 1 | 2
+ 2 |
(3 rows)
SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a);
@@ -632,25 +606,25 @@ SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int
DEFAULT 1 / x ON EMPTY
DEFAULT 2 ON ERROR)
FROM (VALUES (1::int), (0)) x(x);
-ERROR: DEFAULT ON EMPTY expressions are not supported
+ERROR: syntax error at or near "DEFAULT"
LINE 2: DEFAULT 1 / x ON EMPTY
- ^
+ ^
SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT -1 ON EMPTY);
-ERROR: DEFAULT ON EMPTY expressions are not supported
-LINE 1: ...SON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT -1 ON EMPT...
- ^
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT -1...
+ ^
SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT '-1' ON EMPTY);
-ERROR: DEFAULT ON EMPTY expressions are not supported
-LINE 1: ...SON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT '-1' ON EM...
- ^
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT '-...
+ ^
SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT 'err' ON EMPTY);
-ERROR: DEFAULT ON EMPTY expressions are not supported
-LINE 1: ...SON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT 'err' ON E...
- ^
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT 'e...
+ ^
SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT -1::float ON EMPTY);
-ERROR: DEFAULT ON EMPTY expressions are not supported
-LINE 1: ...SON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT -1::float ...
- ^
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT -1...
+ ^
-- JSON_QUERY
SELECT
JSON_QUERY(js, '$'),
@@ -820,11 +794,9 @@ SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY);
(1 row)
SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY DEFAULT '"empty"' ON ERROR);
- json_query
-------------
- "empty"
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...LECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY DEFAULT '"...
+ ^
SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY NULL ON ERROR);
json_query
------------
@@ -855,11 +827,9 @@ SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' ERROR ON ERROR);
ERROR: JSON path expression in JSON_QUERY should return singleton item without wrapper
HINT: Use WITH WRAPPER clause to wrap SQL/JSON item sequence into array.
SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' DEFAULT '"empty"' ON ERROR);
- json_query
-------------
- "empty"
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' DEFAULT '"empty"' ON...
+ ^
SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING json);
json_query
------------
@@ -1417,23 +1387,17 @@ ERROR: jsonpath member accessor can only be applied to an object
SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH 'lax $.a' ERROR ON EMPTY) ERROR ON ERROR) jt;
ERROR: no SQL/JSON item
SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH '$' NULL ON EMPTY DEFAULT 2 ON ERROR)) jt;
- a
----
- 2
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ..."a"', '$' COLUMNS (a int PATH '$' NULL ON EMPTY DEFAULT 2 ...
+ ^
SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'strict $.a' NULL ON EMPTY DEFAULT 2 ON ERROR)) jt;
- a
----
- 2
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...$' COLUMNS (a int PATH 'strict $.a' NULL ON EMPTY DEFAULT 2 ...
+ ^
SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'lax $.a' NULL ON EMPTY DEFAULT 2 ON ERROR)) jt;
- a
----
-
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ..., '$' COLUMNS (a int PATH 'lax $.a' NULL ON EMPTY DEFAULT 2 ...
+ ^
-- JSON_TABLE: EXISTS PATH types
SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int4 EXISTS PATH '$.a'));
a
@@ -1753,24 +1717,24 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
) jt;
- n | a | b | c
----+----+---+----
- 1 | 1 | |
- 2 | 2 | 1 |
- 2 | 2 | 2 |
- 2 | 2 | 3 |
- 2 | 2 | | 10
- 2 | 2 | |
- 2 | 2 | | 20
- 3 | 3 | 1 |
- 3 | 3 | 2 |
- 4 | -1 | 1 |
- 4 | -1 | 2 |
+ n | a | b | c
+---+---+---+----
+ 1 | 1 | |
+ 2 | 2 | 1 |
+ 2 | 2 | 2 |
+ 2 | 2 | 3 |
+ 2 | 2 | | 10
+ 2 | 2 | |
+ 2 | 2 | | 20
+ 3 | 3 | 1 |
+ 3 | 3 | 2 |
+ 4 | | 1 |
+ 4 | | 2 |
(11 rows)
-- default plan (outer, union)
@@ -1782,25 +1746,25 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
plan default (outer, union)
) jt;
- n | a | b | c
----+----+---+----
- 1 | 1 | |
- 2 | 2 | 1 |
- 2 | 2 | 2 |
- 2 | 2 | 3 |
- 2 | 2 | | 10
- 2 | 2 | |
- 2 | 2 | | 20
- 3 | 3 | 1 |
- 3 | 3 | 2 |
- 4 | -1 | 1 |
- 4 | -1 | 2 |
+ n | a | b | c
+---+---+---+----
+ 1 | 1 | |
+ 2 | 2 | 1 |
+ 2 | 2 | 2 |
+ 2 | 2 | 3 |
+ 2 | 2 | | 10
+ 2 | 2 | |
+ 2 | 2 | | 20
+ 3 | 3 | 1 |
+ 3 | 3 | 2 |
+ 4 | | 1 |
+ 4 | | 2 |
(11 rows)
-- specific plan (p outer (pb union pc))
@@ -1812,25 +1776,25 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
plan (p outer (pb union pc))
) jt;
- n | a | b | c
----+----+---+----
- 1 | 1 | |
- 2 | 2 | 1 |
- 2 | 2 | 2 |
- 2 | 2 | 3 |
- 2 | 2 | | 10
- 2 | 2 | |
- 2 | 2 | | 20
- 3 | 3 | 1 |
- 3 | 3 | 2 |
- 4 | -1 | 1 |
- 4 | -1 | 2 |
+ n | a | b | c
+---+---+---+----
+ 1 | 1 | |
+ 2 | 2 | 1 |
+ 2 | 2 | 2 |
+ 2 | 2 | 3 |
+ 2 | 2 | | 10
+ 2 | 2 | |
+ 2 | 2 | | 20
+ 3 | 3 | 1 |
+ 3 | 3 | 2 |
+ 4 | | 1 |
+ 4 | | 2 |
(11 rows)
-- specific plan (p outer (pc union pb))
@@ -1842,25 +1806,25 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
plan (p outer (pc union pb))
) jt;
- n | a | c | b
----+----+----+---
- 1 | 1 | |
- 2 | 2 | 10 |
- 2 | 2 | |
- 2 | 2 | 20 |
- 2 | 2 | | 1
- 2 | 2 | | 2
- 2 | 2 | | 3
- 3 | 3 | | 1
- 3 | 3 | | 2
- 4 | -1 | | 1
- 4 | -1 | | 2
+ n | a | c | b
+---+---+----+---
+ 1 | 1 | |
+ 2 | 2 | 10 |
+ 2 | 2 | |
+ 2 | 2 | 20 |
+ 2 | 2 | | 1
+ 2 | 2 | | 2
+ 2 | 2 | | 3
+ 3 | 3 | | 1
+ 3 | 3 | | 2
+ 4 | | | 1
+ 4 | | | 2
(11 rows)
-- default plan (inner, union)
@@ -1872,24 +1836,24 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
plan default (inner)
) jt;
- n | a | b | c
----+----+---+----
- 2 | 2 | 1 |
- 2 | 2 | 2 |
- 2 | 2 | 3 |
- 2 | 2 | | 10
- 2 | 2 | |
- 2 | 2 | | 20
- 3 | 3 | 1 |
- 3 | 3 | 2 |
- 4 | -1 | 1 |
- 4 | -1 | 2 |
+ n | a | b | c
+---+---+---+----
+ 2 | 2 | 1 |
+ 2 | 2 | 2 |
+ 2 | 2 | 3 |
+ 2 | 2 | | 10
+ 2 | 2 | |
+ 2 | 2 | | 20
+ 3 | 3 | 1 |
+ 3 | 3 | 2 |
+ 4 | | 1 |
+ 4 | | 2 |
(10 rows)
-- specific plan (p inner (pb union pc))
@@ -1901,24 +1865,24 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
plan (p inner (pb union pc))
) jt;
- n | a | b | c
----+----+---+----
- 2 | 2 | 1 |
- 2 | 2 | 2 |
- 2 | 2 | 3 |
- 2 | 2 | | 10
- 2 | 2 | |
- 2 | 2 | | 20
- 3 | 3 | 1 |
- 3 | 3 | 2 |
- 4 | -1 | 1 |
- 4 | -1 | 2 |
+ n | a | b | c
+---+---+---+----
+ 2 | 2 | 1 |
+ 2 | 2 | 2 |
+ 2 | 2 | 3 |
+ 2 | 2 | | 10
+ 2 | 2 | |
+ 2 | 2 | | 20
+ 3 | 3 | 1 |
+ 3 | 3 | 2 |
+ 4 | | 1 |
+ 4 | | 2 |
(10 rows)
-- default plan (inner, cross)
@@ -1930,7 +1894,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -1958,7 +1922,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -1986,26 +1950,26 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
plan default (outer, cross)
) jt;
- n | a | b | c
----+----+---+----
- 1 | 1 | |
- 2 | 2 | 1 | 10
- 2 | 2 | 1 |
- 2 | 2 | 1 | 20
- 2 | 2 | 2 | 10
- 2 | 2 | 2 |
- 2 | 2 | 2 | 20
- 2 | 2 | 3 | 10
- 2 | 2 | 3 |
- 2 | 2 | 3 | 20
- 3 | 3 | |
- 4 | -1 | |
+ n | a | b | c
+---+---+---+----
+ 1 | 1 | |
+ 2 | 2 | 1 | 10
+ 2 | 2 | 1 |
+ 2 | 2 | 1 | 20
+ 2 | 2 | 2 | 10
+ 2 | 2 | 2 |
+ 2 | 2 | 2 | 20
+ 2 | 2 | 3 | 10
+ 2 | 2 | 3 |
+ 2 | 2 | 3 | 20
+ 3 | 3 | |
+ 4 | | |
(12 rows)
-- specific plan (p outer (pb cross pc))
@@ -2017,26 +1981,26 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
plan (p outer (pb cross pc))
) jt;
- n | a | b | c
----+----+---+----
- 1 | 1 | |
- 2 | 2 | 1 | 10
- 2 | 2 | 1 |
- 2 | 2 | 1 | 20
- 2 | 2 | 2 | 10
- 2 | 2 | 2 |
- 2 | 2 | 2 | 20
- 2 | 2 | 3 | 10
- 2 | 2 | 3 |
- 2 | 2 | 3 | 20
- 3 | 3 | |
- 4 | -1 | |
+ n | a | b | c
+---+---+---+----
+ 1 | 1 | |
+ 2 | 2 | 1 | 10
+ 2 | 2 | 1 |
+ 2 | 2 | 1 | 20
+ 2 | 2 | 2 | 10
+ 2 | 2 | 2 |
+ 2 | 2 | 2 | 20
+ 2 | 2 | 3 | 10
+ 2 | 2 | 3 |
+ 2 | 2 | 3 | 20
+ 3 | 3 | |
+ 4 | | |
(12 rows)
select
@@ -2051,7 +2015,7 @@ from
'$[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on error,
+ a int path 'lax $.a' null on error,
nested path 'strict $.b[*]' as pb columns (
b text format json path '$',
nested path 'strict $[*]' as pb1 columns (
@@ -2188,11 +2152,9 @@ SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'a');
(1 row)
SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'b' ERROR ON EMPTY DEFAULT 'foo' ON ERROR);
- json_value
-------------
- foo
-(1 row)
-
+ERROR: syntax error at or near "DEFAULT"
+LINE 1: ...nb '{"a": 123}', '$' || '.' || 'b' ERROR ON EMPTY DEFAULT 'f...
+ ^
SELECT JSON_QUERY(jsonb '{"a": 123}', '$' || '.' || 'a');
json_query
------------
diff --git a/src/test/regress/sql/jsonb_sqljson.sql b/src/test/regress/sql/jsonb_sqljson.sql
index 76d4c9cc14e..6442fa0bc64 100644
--- a/src/test/regress/sql/jsonb_sqljson.sql
+++ b/src/test/regress/sql/jsonb_sqljson.sql
@@ -149,7 +149,7 @@ SELECT
'$.* ? (@ > $x)' PASSING x AS x
RETURNING int
NULL ON EMPTY
- DEFAULT -2 ON ERROR
+ NULL ON ERROR
) y
FROM
generate_series(0, 2) x;
@@ -776,7 +776,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -791,7 +791,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -807,7 +807,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -823,7 +823,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -839,7 +839,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -855,7 +855,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -871,7 +871,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -887,7 +887,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -903,7 +903,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -919,7 +919,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' error on empty default -1 on error,
+ a int path 'lax $.a' error on empty null on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -939,7 +939,7 @@ from
'$[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on error,
+ a int path 'lax $.a' null on error,
nested path 'strict $.b[*]' as pb columns (
b text format json path '$',
nested path 'strict $[*]' as pb1 columns (
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 8a0585994ee..21e7fd48131 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -1232,7 +1232,6 @@ JsonArrayAgg
JsonArrayConstructor
JsonArrayQueryConstructor
JsonBaseObjectInfo
-JsonBehavior
JsonBehaviorType
JsonCommon
JsonConstructorExpr
--
2.17.1