Re: remaining sql/json patches
jian he <jian.universality@gmail.com>
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
SQL/JSON: Various improvements to SQL/JSON query function docs
- ce416fadb4b6 17.0 landed
- 42de72fa7b80 18.0 landed
-
SQL/JSON: Fix some obsolete comments.
- 290a6d800d90 17.0 landed
- 7768b6569de9 16.4 landed
- 3a8a1f3254b2 18.0 landed
-
SQL/JSON: Fix issues with DEFAULT .. ON ERROR / EMPTY
- c0fc0751862d 17.0 landed
-
JSON_TABLE: Add support for NESTED paths and columns
- bb766cde63b4 17.0 landed
-
Fix JsonExpr deparsing to emit QUOTES and WRAPPER correctly
- f6a2529920cf 17.0 landed
-
Fix typo introduced in 6185c9737
- 2f6e78b0619a 17.0 landed
-
Add basic JSON_TABLE() functionality
- de3600452b61 17.0 landed
-
Avoid splitting errmsg string to span multiple lines
- 085e759e9da7 17.0 landed
-
Add SQL/JSON query functions
- 6185c9737cf4 17.0 landed
-
Implement various jsonpath methods
- 66ea94e8e606 17.0 cited
-
Add soft error handling to some expression nodes
- aaaf9449ec6b 17.0 landed
- 7fbc75b26ed8 17.0 landed
-
Adjust populate_record_field() to handle errors softly
- 1edb3b491bee 17.0 landed
-
Refactor code used by jsonpath executor to fetch variables
- faa2b953ba3b 17.0 landed
-
Test EXPLAIN (FORMAT JSON) ... XMLTABLE
- 752533d40fd5 17.0 landed
-
Simplify productions for FORMAT JSON [ ENCODING name ]
- d3fe6e90bab5 17.0 landed
-
Add trailing commas to enum definitions
- 611806cd726f 17.0 cited
-
doc: add missing <returnvalue> and whitespace
- e055b6be7ebb 17.0 landed
-
Add more SQL/JSON constructor functions
- 03734a7fed7d 17.0 landed
-
Rename a nonterminal used in SQL/JSON grammar
- 254ac5a7c31f 17.0 landed
-
Some refactoring to export json(b) conversion functions
- b22391a2ff7b 17.0 landed
-
Don't include CaseTestExpr in JsonValueExpr.formatted_expr
- 66a9003e2e3e 16.0 landed
- b6e1157e7d33 17.0 landed
-
Code review for commit b6e1157e7d
- 7c7412cae3ea 17.0 landed
-
Pass constructName to transformJsonValueExpr()
- 7825a1b01e40 16.0 landed
- 785480c9533d 17.0 landed
-
Unify JSON categorize type API and export for external use
- 3c152a27b063 17.0 landed
-
Make some indentation in gram.y consistent
- 5edf438eeb00 17.0 landed
- 01f1f789df56 16.0 landed
-
Allow most keywords to be used as column labels without requiring AS.
- 06a7c3154f5b 14.0 cited
-
Reduce size of backend scanner's tables.
- 7f380c59f800 13.0 cited
-
Use perfect hashing, instead of binary search, for keyword lookup.
- c64d0cd5ce24 12.0 cited
Attachments
- v1-0001-refactor-ExecInitJsonExpr.no-cfnot (application/octet-stream)
- v1-0002-refactor-QUOTE-behavior-for-json_query.no-cfbot (application/octet-stream)
- v1-0004-refactor-json_table-wrapper-and-quotes-behavior.no-cfbot (application/octet-stream)
- v1-0003-refactor-the-QUOTE-behavior-for-json_value.no-cfbot (application/octet-stream)
- test.sql (application/sql)
- without_patch.out (application/octet-stream)
- with_patch.out (application/octet-stream)
On Fri, Dec 22, 2023 at 9:01 PM jian he <jian.universality@gmail.com> wrote:
>
> Hi
>
> + /* FALLTHROUGH */
> + case JTC_EXISTS:
> + case JTC_FORMATTED:
> + {
> + Node *je;
> + CaseTestExpr *param = makeNode(CaseTestExpr);
> +
> + param->collation = InvalidOid;
> + param->typeId = cxt->contextItemTypid;
> + param->typeMod = -1;
> +
> + if (rawc->wrapper != JSW_NONE &&
> + rawc->quotes != JS_QUOTES_UNSPEC)
> + ereport(ERROR,
> + (errcode(ERRCODE_SYNTAX_ERROR),
> + errmsg("cannot use WITH WRAPPER clause for formatted colunmns"
> + " without also specifying OMIT/KEEP QUOTES"),
> + parser_errposition(pstate, rawc->location)));
>
> typo, should be "formatted columns".
> I suspect people will be confused with the meaning of "formatted column".
> maybe we can replace this part:"cannot use WITH WRAPPER clause for
> formatted column"
> to
> "SQL/JSON WITH WRAPPER behavior must not be specified when FORMAT
> clause is used"
>
> SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text
> FORMAT JSON PATH '$' with wrapper KEEP QUOTES));
> ERROR: cannot use WITH WRAPPER clause for formatted colunmns without
> also specifying OMIT/KEEP QUOTES
> LINE 1: ...T * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text ...
> ^
> this error is misleading, since now I am using WITH WRAPPER clause for
> formatted columns and specified KEEP QUOTES.
>
Hi. still based on v33.
JSON_TABLE:
I also refactor parse_jsontable.c error reporting, now the error
message will be consistent with json_query.
now you can specify wrapper freely as long as you don't specify
wrapper and quote at the same time.
overall, json_table behavior is more consistent with json_query and json_value.
I also added some tests.
+void
+ExecEvalJsonCoercion(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext)
+{
+ JsonCoercion *coercion = op->d.jsonexpr_coercion.coercion;
+ ErrorSaveContext *escontext = op->d.jsonexpr_coercion.escontext;
+ Datum res = *op->resvalue;
+ bool resnull = *op->resnull;
+
+ if (coercion->via_populate)
+ {
+ void *cache = op->d.jsonexpr_coercion.json_populate_type_cache;
+
+ *op->resvalue = json_populate_type(res, JSONBOID,
+ coercion->targettype,
+ coercion->targettypmod,
+ &cache,
+ econtext->ecxt_per_query_memory,
+ op->resnull, (Node *) escontext);
+ }
+ else if (coercion->via_io)
+ {
+ FmgrInfo *input_finfo = op->d.jsonexpr_coercion.input_finfo;
+ Oid typioparam = op->d.jsonexpr_coercion.typioparam;
+ char *val_string = resnull ? NULL :
+ JsonbUnquote(DatumGetJsonbP(res));
+
+ (void) InputFunctionCallSafe(input_finfo, val_string, typioparam,
+ coercion->targettypmod,
+ (Node *) escontext,
+ op->resvalue);
+ }
via_populate, via_io should be mutually exclusive.
your patch, in some cases, both (coercion->via_io) and
(coercion->via_populate) are true.
(we can use elog find out).
I refactor coerceJsonFuncExprOutput, so now it will be mutually exclusive.
I also add asserts to it.
By default, json_query keeps quotes, json_value omit quotes.
However, json_table will be transformed to json_value or json_query
based on certain criteria,
that means we need to explicitly set the JsonExpr->omit_quotes in the
function transformJsonFuncExpr
for case JSON_QUERY_OP and JSON_VALUE_OP.
We need to know the QUOTE behavior in the function ExecEvalJsonCoercion.
Because for ExecEvalJsonCoercion, the coercion datum source can be a
scalar string item,
scalar items means RETURNING clause is dependent on QUOTE behavior.
keep quotes, omit quotes the results are different.
consider
JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range omit quotes);
and
JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range omit quotes);
to make sure ExecEvalJsonCoercion can distinguish keep and omit quotes,
I added a bool keep_quotes to struct JsonCoercion.
(maybe there is a more simple way, so far, that's what I come up with).
the keep_quotes value will be settled in the function transformJsonFuncExpr.
After refactoring, in ExecEvalJsonCoercion, keep_quotes is true then
call JsonbToCString, else call JsonbUnquote.
example:
SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[]
omit quotes);
without my changes, return NULL
with my changes:
{1,2,3}
JSON_VALUE:
main changes:
--- a/src/test/regress/expected/jsonb_sqljson.out
+++ b/src/test/regress/expected/jsonb_sqljson.out
@@ -301,7 +301,11 @@ SELECT JSON_VALUE(jsonb '"2017-02-20"', '$'
RETURNING date) + 9;
-- Test NULL checks execution in domain types
CREATE DOMAIN sqljsonb_int_not_null AS int NOT NULL;
SELECT JSON_VALUE(jsonb 'null', '$' RETURNING sqljsonb_int_not_null);
-ERROR: domain sqljsonb_int_not_null does not allow null values
+ json_value
+------------
+
+(1 row)
+
I think the change is correct, given `SELECT JSON_VALUE(jsonb 'null',
'$' RETURNING int4range);` returns NULL.
I also attached a test.sql, without_patch.out (apply v33 only),
with_patch.out (my changes based on v33).
So you can see the difference after applying the patch, in case, my
wording is not clear.