v10-0009-Remove-support-of-DEFAULT-ON-EMPTY-in-SQL-JSON-f.patch
text/x-patch
Filename: v10-0009-Remove-support-of-DEFAULT-ON-EMPTY-in-SQL-JSON-f.patch
Type: text/x-patch
Part: 8
Message:
Re: SQL/JSON features for v15
Patch
Format: format-patch
Series: patch v10-0009
Subject: Remove support of DEFAULT ON EMPTY in SQL/JSON functions
| File | + | − |
|---|---|---|
| doc/src/sgml/func.sgml | 2 | 2 |
| src/backend/executor/execExpr.c | 0 | 21 |
| src/backend/executor/execExprInterp.c | 12 | 15 |
| src/backend/jit/llvm/llvmjit_expr.c | 10 | 22 |
| src/backend/optimizer/util/clauses.c | 0 | 13 |
| src/backend/parser/parse_expr.c | 7 | 26 |
| src/include/executor/execExpr.h | 1 | 2 |
| src/include/optimizer/clauses.h | 0 | 2 |
| src/test/regress/expected/jsonb_sqljson.out | 33 | 41 |
| src/test/regress/sql/jsonb_sqljson.sql | 17 | 17 |
From 358e7c7c83cb65f1eb310e2e78627dcc9d1b9bb3 Mon Sep 17 00:00:00 2001
From: Nikita Glukhov <n.gluhov@postgrespro.ru>
Date: Mon, 29 Aug 2022 23:23:02 +0300
Subject: [PATCH v10 09/10] Remove support of DEFAULT ON EMPTY in SQL/JSON
functions
---
doc/src/sgml/func.sgml | 4 +-
src/backend/executor/execExpr.c | 21 ------
src/backend/executor/execExprInterp.c | 27 ++++----
src/backend/jit/llvm/llvmjit_expr.c | 32 +++------
src/backend/optimizer/util/clauses.c | 13 ----
src/backend/parser/parse_expr.c | 33 ++-------
src/include/executor/execExpr.h | 3 +-
src/include/optimizer/clauses.h | 2 -
src/test/regress/expected/jsonb_sqljson.out | 74 +++++++++------------
src/test/regress/sql/jsonb_sqljson.sql | 34 +++++-----
10 files changed, 82 insertions(+), 161 deletions(-)
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 8dd63c04556..8e03a1831ab 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -17976,7 +17976,7 @@ FROM
<parameter>context_item</parameter>, <parameter>path_expression</parameter>
<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>DEFAULT</literal> <parameter>expression</parameter> } <literal>ON EMPTY</literal> </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>)
</para>
<para>
@@ -18017,7 +18017,7 @@ FROM
<optional> <literal>RETURNING</literal> <parameter>data_type</parameter> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>
<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>DEFAULT</literal> <parameter>expression</parameter> } <literal>ON EMPTY</literal> </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>)
</para>
<para>
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 68227ebee21..5ea7e6b421a 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -4166,9 +4166,7 @@ ExecInitJsonExpr(JsonExpr *jexpr, ExprState *state, ExprEvalStep *scratch,
int skip_step_off;
int execpath_step_off;
int done_step_off;
- int default_on_empty_step_off = -1;
int default_on_error_step_off = -1;
- int default_on_empty_jump_off = -1;
/* JSON_TABLE preudo-function returns context item as a result */
if (jexpr->op == JSON_TABLE_OP)
@@ -4235,16 +4233,6 @@ ExecInitJsonExpr(JsonExpr *jexpr, ExprState *state, ExprEvalStep *scratch,
execpath_step_off = state->steps_len;
ExprEvalPushStep(state, scratch);
- if (jexpr->on_empty && jexpr->on_empty->default_expr)
- {
- default_on_empty_step_off = state->steps_len;
- ExecInitExprRec((Expr *) jexpr->on_empty->default_expr, state, resv, resnull);
-
- scratch->opcode = EEOP_JUMP;
- default_on_empty_jump_off = state->steps_len;
- ExprEvalPushStep(state, scratch);
- }
-
if (jexpr->on_error->default_expr)
{
default_on_error_step_off = state->steps_len;
@@ -4261,15 +4249,6 @@ ExecInitJsonExpr(JsonExpr *jexpr, ExprState *state, ExprEvalStep *scratch,
/* EEOP_JSONEXPR_PATH */
step = &state->steps[execpath_step_off];
step->d.jsonexpr.jump_done = done_step_off;
- step->d.jsonexpr.jump_default_on_empty =
- default_on_empty_step_off > 0 ? default_on_empty_step_off : done_step_off;
step->d.jsonexpr.jump_default_on_error =
default_on_error_step_off > 0 ? default_on_error_step_off : done_step_off;
-
- /* EEOP_JUMP */
- if (default_on_empty_jump_off > 0)
- {
- step = &state->steps[default_on_empty_jump_off];
- step->d.jump.jumpdone = done_step_off;
- }
}
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 22959ae569c..35f20d88232 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -1855,14 +1855,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_CASE(EEOP_JSONEXPR_PATH)
{
/* too complex for an inline implementation */
- int res = ExecEvalJsonExpr(state, op);
-
- if (res == 0)
- EEO_JUMP(op->d.jsonexpr.jump_default_on_empty);
- else if (res == -1)
- EEO_JUMP(op->d.jsonexpr.jump_default_on_error);
- else
+ if (ExecEvalJsonExpr(state, op))
EEO_JUMP(op->d.jsonexpr.jump_done);
+ else
+ EEO_JUMP(op->d.jsonexpr.jump_default_on_error);
}
EEO_CASE(EEOP_LAST)
@@ -5403,11 +5399,10 @@ ExecEvalJsonExprSkip(ExprState *state, ExprEvalStep *op)
* ----------------------------------------------------------------
*
* Return value:
- * 1 - Ok, jump to the end of JsonExpr
- * 0 - empty result, need to execute DEFAULT ON EMPTY expression
- * -1 - error occured, need to execute DEFAULT ON ERROR expression
+ * true - Ok, jump to the end of JsonExpr
+ * false - error occured, need to execute DEFAULT ON ERROR expression
*/
-int
+bool
ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op)
{
JsonExprState *jsestate = op->d.jsonexpr.jsestate;
@@ -5439,14 +5434,16 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op)
error = true; /* fallback to error behavior */
}
- else if (jexpr->on_empty->btype == JSON_BEHAVIOR_DEFAULT)
- return 0; /* jump to DEFAULT ON EMPTY expression */
else
+ {
+ Assert(jexpr->on_empty->btype != JSON_BEHAVIOR_DEFAULT); /* not supported */
+
/* Execute ON EMPTY behavior */
res = ExecEvalJsonBehavior(jexpr->on_empty,
jexpr->returning->typid,
jexpr->returning->typmod,
op->resnull);
+ }
}
if (error)
@@ -5454,7 +5451,7 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op)
Assert(!throw_errors);
if (jexpr->on_error->btype == JSON_BEHAVIOR_DEFAULT)
- return -1; /* jump to DEFAULT ON ERROR expression */
+ return false; /* jump to DEFAULT ON ERROR expression */
/* Execute ON ERROR behavior */
res = ExecEvalJsonBehavior(jexpr->on_error,
@@ -5464,5 +5461,5 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op)
}
*op->resvalue = res;
- return 1; /* jump to the end of expression */
+ 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 ed53ad93443..69eb86aaf0a 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -2441,34 +2441,22 @@ llvm_compile_expr(ExprState *state)
case EEOP_JSONEXPR_PATH:
{
LLVMValueRef v_ret;
- LLVMValueRef v_switch;
- int n_jumps = 0;
v_ret = build_EvalXFunc(b, mod, "ExecEvalJsonExpr",
v_state, op);
-
- if (op->d.jsonexpr.jump_default_on_empty != op->d.jsonexpr.jump_done)
- n_jumps++;
+ v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
if (op->d.jsonexpr.jump_default_on_error != op->d.jsonexpr.jump_done)
- n_jumps++;
-
- if (!n_jumps)
- LLVMBuildBr(b, opblocks[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
- {
- v_switch = LLVMBuildSwitch(b, v_ret,
- opblocks[op->d.jsonexpr.jump_done],
- n_jumps);
-
- if (op->d.jsonexpr.jump_default_on_empty != op->d.jsonexpr.jump_done)
- LLVMAddCase(v_switch, l_int32_const(0),
- opblocks[op->d.jsonexpr.jump_default_on_empty]);
-
- if (op->d.jsonexpr.jump_default_on_error != op->d.jsonexpr.jump_done)
- LLVMAddCase(v_switch, l_int32_const(-1),
- opblocks[op->d.jsonexpr.jump_default_on_error]);
- }
+ LLVMBuildBr(b, opblocks[op->d.jsonexpr.jump_done]);
break;
}
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 6eb923892f4..b133dad10cf 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -5355,16 +5355,3 @@ pull_paramids_walker(Node *node, Bitmapset **context)
return expression_tree_walker(node, pull_paramids_walker,
(void *) context);
}
-
-bool
-expr_can_throw_errors(Node *expr)
-{
- if (!expr)
- return false;
-
- if (IsA(expr, Const))
- return false;
-
- /* TODO consider more cases */
- return true;
-}
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index c02530a3671..f96334ce088 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -4263,7 +4263,6 @@ static Node *
coerceDefaultJsonExpr(ParseState *pstate, JsonExpr *jsexpr,
bool is_on_empty, Node *defexpr)
{
- Node *orig_defexpr = defexpr;
int location;
Oid exprtype;
@@ -4276,6 +4275,12 @@ coerceDefaultJsonExpr(ParseState *pstate, JsonExpr *jsexpr,
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,
@@ -4293,31 +4298,7 @@ coerceDefaultJsonExpr(ParseState *pstate, JsonExpr *jsexpr,
format_type_be(jsexpr->returning->typid)),
parser_errposition(pstate, location)));
- /* Don't allow unsafe DEFAUL ON EMPTY expressions, unless ERROR ON ERROR */
- if (!is_on_empty ||
- jsexpr->on_error->btype == JSON_BEHAVIOR_ERROR)
- return defexpr;
-
- if (!expr_can_throw_errors(defexpr))
- return defexpr;
-
- /* Try to simplify expression if there is non-empty coercion */
- if (defexpr != orig_defexpr &&
- !expr_can_throw_errors(orig_defexpr))
- {
- defexpr = eval_const_expressions(NULL, defexpr);
-
- if (!expr_can_throw_errors(defexpr))
- return defexpr;
- }
-
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("unsafe DEFAULT ON EMPTY expressions are not supported"),
- errhint("Use ERROR ON ERROR clause or try to simplify expression into constant-like form."),
- parser_errposition(pstate, location)));
-
- return NULL;
+ return defexpr;
}
/*
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index b005bf440dd..d67419c66a9 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -698,7 +698,6 @@ typedef struct ExprEvalStep
{
struct JsonExprState *jsestate;
int jump_done;
- int jump_default_on_empty; /* ON EMPTY DEFAULT expression */
int jump_default_on_error; /* ON ERROR DEFAULT expression */
} jsonexpr;
@@ -839,7 +838,7 @@ extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op,
ExprContext *econtext, TupleTableSlot *slot);
extern void ExecEvalJsonConstructor(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
-extern int ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op);
+extern bool 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/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 4d61b88c161..6c5203dc448 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -55,6 +55,4 @@ extern Query *inline_set_returning_function(PlannerInfo *root,
extern Bitmapset *pull_paramids(Expr *expr);
-extern bool expr_can_throw_errors(Node *expr);
-
#endif /* CLAUSES_H */
diff --git a/src/test/regress/expected/jsonb_sqljson.out b/src/test/regress/expected/jsonb_sqljson.out
index 0e07bbc858f..fcd921130f5 100644
--- a/src/test/regress/expected/jsonb_sqljson.out
+++ b/src/test/regress/expected/jsonb_sqljson.out
@@ -537,11 +537,9 @@ SELECT JSON_VALUE(jsonb '1', 'lax $.a' NULL ON EMPTY DEFAULT '2' ON ERROR);
(1 row)
SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON EMPTY DEFAULT '3' ON ERROR);
- json_value
-------------
- 2
-(1 row)
-
+ERROR: DEFAULT ON EMPTY expressions are not supported
+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
------------
@@ -576,7 +574,7 @@ SELECT
jsonb '{"a": 1, "b": 2}',
'$.* ? (@ > $x)' PASSING x AS x
RETURNING int
- DEFAULT -1 ON EMPTY
+ NULL ON EMPTY
DEFAULT -2 ON ERROR
) y
FROM
@@ -585,7 +583,7 @@ FROM
---+----
0 | -2
1 | 2
- 2 | -1
+ 2 |
(3 rows)
SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a);
@@ -634,31 +632,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: unsafe DEFAULT ON EMPTY expressions are not supported
+ERROR: DEFAULT ON EMPTY expressions are not supported
LINE 2: DEFAULT 1 / x ON EMPTY
^
-HINT: Use ERROR ON ERROR clause or try to simplify expression into constant-like form.
SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT -1 ON EMPTY);
- json_value
-------------
- -1
-(1 row)
-
+ERROR: DEFAULT ON EMPTY expressions are not supported
+LINE 1: ...SON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT -1 ON EMPT...
+ ^
SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT '-1' ON EMPTY);
- json_value
-------------
- -1
-(1 row)
-
+ERROR: DEFAULT ON EMPTY expressions are not supported
+LINE 1: ...SON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT '-1' ON EM...
+ ^
SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT 'err' ON EMPTY);
-ERROR: invalid input syntax for type integer: "err"
+ERROR: DEFAULT ON EMPTY expressions are not supported
LINE 1: ...SON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT 'err' ON E...
^
SELECT JSON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT -1::float ON EMPTY);
-ERROR: unsafe DEFAULT ON EMPTY expressions are not supported
+ERROR: DEFAULT ON EMPTY expressions are not supported
LINE 1: ...SON_VALUE('1'::jsonb, '$.x' RETURNING int DEFAULT -1::float ...
^
-HINT: Use ERROR ON ERROR clause or try to simplify expression into constant-like form.
-- JSON_QUERY
SELECT
JSON_QUERY(js, '$'),
@@ -827,7 +819,7 @@ SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY);
(1 row)
-SELECT JSON_QUERY(jsonb '[]', '$[*]' DEFAULT '"empty"' ON EMPTY);
+SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY DEFAULT '"empty"' ON ERROR);
json_query
------------
"empty"
@@ -1055,7 +1047,7 @@ CREATE TABLE test_jsonb_constraints (
CONSTRAINT test_jsonb_constraint2
CHECK (JSON_EXISTS(js::jsonb, '$.a' PASSING i + 5 AS int, i::text AS txt, array[1,2,3] as arr))
CONSTRAINT test_jsonb_constraint3
- CHECK (JSON_VALUE(js::jsonb, '$.a' RETURNING int DEFAULT ('12' || i)::int ON EMPTY ERROR ON ERROR) > i)
+ CHECK (JSON_VALUE(js::jsonb, '$.a' RETURNING int NULL ON EMPTY ERROR ON ERROR) > i)
CONSTRAINT test_jsonb_constraint4
CHECK (JSON_QUERY(js::jsonb, '$.a' WITH CONDITIONAL WRAPPER EMPTY OBJECT ON ERROR) < jsonb '[10]')
CONSTRAINT test_jsonb_constraint5
@@ -1073,7 +1065,7 @@ CREATE TABLE test_jsonb_constraints (
Check constraints:
"test_jsonb_constraint1" CHECK (js IS JSON)
"test_jsonb_constraint2" CHECK (JSON_EXISTS(js::jsonb, '$."a"' PASSING i + 5 AS int, i::text AS txt, ARRAY[1, 2, 3] AS arr))
- "test_jsonb_constraint3" CHECK (JSON_VALUE(js::jsonb, '$."a"' RETURNING integer DEFAULT ('12'::text || i)::integer ON EMPTY ERROR ON ERROR) > i)
+ "test_jsonb_constraint3" CHECK (JSON_VALUE(js::jsonb, '$."a"' RETURNING integer ERROR ON ERROR) > i)
"test_jsonb_constraint4" CHECK (JSON_QUERY(js::jsonb, '$."a"' RETURNING jsonb WITH CONDITIONAL WRAPPER EMPTY OBJECT ON ERROR) < '[10]'::jsonb)
"test_jsonb_constraint5" CHECK (JSON_QUERY(js::jsonb, '$."a"' RETURNING character(5) OMIT QUOTES EMPTY ARRAY ON EMPTY) > ('a'::bpchar COLLATE "C"))
"test_jsonb_constraint6" CHECK (JSON_EXISTS(js::jsonb, 'strict $."a"' RETURNING integer TRUE ON ERROR) < 2)
@@ -1087,7 +1079,7 @@ ORDER BY 1;
((JSON_EXISTS((js)::jsonb, 'strict $."a"' RETURNING integer TRUE ON ERROR) < 2))
((JSON_QUERY((js)::jsonb, '$."a"' RETURNING character(5) OMIT QUOTES EMPTY ARRAY ON EMPTY) > ('a'::bpchar COLLATE "C")))
((JSON_QUERY((js)::jsonb, '$."a"' RETURNING jsonb WITH CONDITIONAL WRAPPER EMPTY OBJECT ON ERROR) < '[10]'::jsonb))
- ((JSON_VALUE((js)::jsonb, '$."a"' RETURNING integer DEFAULT (('12'::text || i))::integer ON EMPTY ERROR ON ERROR) > i))
+ ((JSON_VALUE((js)::jsonb, '$."a"' RETURNING integer ERROR ON ERROR) > i))
((js IS JSON))
(JSON_EXISTS((js)::jsonb, '$."a"' PASSING (i + 5) AS int, (i)::text AS txt, ARRAY[1, 2, 3] AS arr))
(6 rows)
@@ -1424,22 +1416,22 @@ SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH 'strict $.a' ERROR O
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 '$' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt;
+SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH '$' NULL ON EMPTY DEFAULT 2 ON ERROR)) jt;
a
---
2
(1 row)
-SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'strict $.a' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt;
+SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'strict $.a' NULL ON EMPTY DEFAULT 2 ON ERROR)) jt;
a
---
2
(1 row)
-SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'lax $.a' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt;
+SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'lax $.a' NULL ON EMPTY DEFAULT 2 ON ERROR)) jt;
a
---
- 1
+
(1 row)
-- JSON_TABLE: EXISTS PATH types
@@ -1761,7 +1753,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -1790,7 +1782,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -1820,7 +1812,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -1850,7 +1842,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -1880,7 +1872,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -1909,7 +1901,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -1938,7 +1930,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -1966,7 +1958,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -1994,7 +1986,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -2025,7 +2017,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -2195,7 +2187,7 @@ SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'a');
123
(1 row)
-SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'b' DEFAULT 'foo' ON EMPTY);
+SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'b' ERROR ON EMPTY DEFAULT 'foo' ON ERROR);
json_value
------------
foo
diff --git a/src/test/regress/sql/jsonb_sqljson.sql b/src/test/regress/sql/jsonb_sqljson.sql
index 43a194ad09f..76d4c9cc14e 100644
--- a/src/test/regress/sql/jsonb_sqljson.sql
+++ b/src/test/regress/sql/jsonb_sqljson.sql
@@ -148,7 +148,7 @@ SELECT
jsonb '{"a": 1, "b": 2}',
'$.* ? (@ > $x)' PASSING x AS x
RETURNING int
- DEFAULT -1 ON EMPTY
+ NULL ON EMPTY
DEFAULT -2 ON ERROR
) y
FROM
@@ -237,7 +237,7 @@ SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY ON EMPTY);
SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY ARRAY ON EMPTY);
SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY OBJECT ON EMPTY);
SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY);
-SELECT JSON_QUERY(jsonb '[]', '$[*]' DEFAULT '"empty"' ON EMPTY);
+SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY DEFAULT '"empty"' ON ERROR);
SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY NULL ON ERROR);
SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY EMPTY ARRAY ON ERROR);
@@ -309,7 +309,7 @@ CREATE TABLE test_jsonb_constraints (
CONSTRAINT test_jsonb_constraint2
CHECK (JSON_EXISTS(js::jsonb, '$.a' PASSING i + 5 AS int, i::text AS txt, array[1,2,3] as arr))
CONSTRAINT test_jsonb_constraint3
- CHECK (JSON_VALUE(js::jsonb, '$.a' RETURNING int DEFAULT ('12' || i)::int ON EMPTY ERROR ON ERROR) > i)
+ CHECK (JSON_VALUE(js::jsonb, '$.a' RETURNING int NULL ON EMPTY ERROR ON ERROR) > i)
CONSTRAINT test_jsonb_constraint4
CHECK (JSON_QUERY(js::jsonb, '$.a' WITH CONDITIONAL WRAPPER EMPTY OBJECT ON ERROR) < jsonb '[10]')
CONSTRAINT test_jsonb_constraint5
@@ -515,9 +515,9 @@ SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH '$.a' ERROR ON EMPTY
SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH 'strict $.a' ERROR ON EMPTY) ERROR ON ERROR) jt;
SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH 'lax $.a' ERROR ON EMPTY) ERROR ON ERROR) jt;
-SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH '$' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt;
-SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'strict $.a' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt;
-SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'lax $.a' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt;
+SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH '$' NULL ON EMPTY DEFAULT 2 ON ERROR)) jt;
+SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'strict $.a' NULL ON EMPTY DEFAULT 2 ON ERROR)) jt;
+SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'lax $.a' NULL ON EMPTY DEFAULT 2 ON ERROR)) jt;
-- JSON_TABLE: EXISTS PATH types
SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int4 EXISTS PATH '$.a'));
@@ -776,7 +776,7 @@ from
jtt.js,'strict $[*]' as p
columns (
n for ordinality,
- a int path 'lax $.a' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 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' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 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' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 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' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 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' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 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' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 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' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 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' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 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' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 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' default -1 on empty,
+ a int path 'lax $.a' error on empty default -1 on error,
nested path 'strict $.b[*]' as pb columns ( b int path '$' ),
nested path 'strict $.c[*]' as pc columns ( c int path '$' )
)
@@ -987,7 +987,7 @@ FROM JSON_TABLE(
-- Extension: non-constant JSON path
SELECT JSON_EXISTS(jsonb '{"a": 123}', '$' || '.' || 'a');
SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'a');
-SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'b' DEFAULT 'foo' ON EMPTY);
+SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'b' ERROR ON EMPTY DEFAULT 'foo' ON ERROR);
SELECT JSON_QUERY(jsonb '{"a": 123}', '$' || '.' || 'a');
SELECT JSON_QUERY(jsonb '{"a": 123}', '$' || '.' || 'a' WITH WRAPPER);
-- Should fail (invalid path)
--
2.17.1