Skip to content

Commit 3578661

Browse files
author
Nikita Glukhov
committed
Add SQL/JSON IS JSON parsing
1 parent 549d98a commit 3578661

File tree

6 files changed

+104
-4
lines changed

6 files changed

+104
-4
lines changed

src/backend/nodes/makefuncs.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,3 +883,21 @@ makeJsonKeyValue(Node *key, Node *value)
883883

884884
return (Node *) n;
885885
}
886+
887+
/*
888+
* makeJsonIsPredicate -
889+
* creates a JsonIsPredicate node
890+
*/
891+
Node *
892+
makeJsonIsPredicate(Node *expr, JsonFormat *format, JsonValueType value_type,
893+
bool unique_keys)
894+
{
895+
JsonIsPredicate *n = makeNode(JsonIsPredicate);
896+
897+
n->expr = expr;
898+
n->format = format;
899+
n->value_type = value_type;
900+
n->unique_keys = unique_keys;
901+
902+
return (Node *) n;
903+
}

src/backend/parser/gram.y

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
622622

623623
%type <ival> json_encoding
624624
json_encoding_clause_opt
625+
json_predicate_type_constraint_opt
625626

626627
%type <boolean> json_key_uniqueness_constraint_opt
627628
json_object_constructor_null_clause_opt
@@ -691,7 +692,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
691692

692693
JOIN JSON JSON_ARRAY JSON_ARRAYAGG JSON_OBJECT JSON_OBJECTAGG
693694

694-
KEY KEYS
695+
KEY KEYS KEEP
695696

696697
LABEL LANGUAGE LARGE_P LAST_P LATERAL_P
697698
LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL
@@ -719,9 +720,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
719720
RESET RESTART RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP
720721
ROUTINE ROUTINES ROW ROWS RULE
721722

722-
SAVEPOINT SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES
723-
SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW
724-
SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SQL_P STABLE STANDALONE_P
723+
SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT
724+
SEQUENCE SEQUENCES SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF
725+
SHARE SHOW SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SQL_P STABLE STANDALONE_P
725726
START STATEMENT STATISTICS STDIN STDOUT STORAGE STORED STRICT_P STRIP_P
726727
SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P
727728

@@ -13375,6 +13376,48 @@ a_expr: c_expr { $$ = $1; }
1337513376
{
1337613377
$$ = makeNotExpr((Node *) makeFuncCall(SystemFuncName("is_normalized"), list_make2($1, makeStringConst($4, @4)), @2), @2);
1337713378
}
13379+
| a_expr
13380+
IS JSON
13381+
json_predicate_type_constraint_opt
13382+
json_key_uniqueness_constraint_opt %prec IS
13383+
{
13384+
JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
13385+
$$ = makeJsonIsPredicate($1, format, $4, $5);
13386+
}
13387+
/*
13388+
* Required by standard, but it would conflict with expressions
13389+
* like: 'str' || format(...)
13390+
| a_expr
13391+
FORMAT json_representation
13392+
IS JSON
13393+
json_predicate_type_constraint_opt
13394+
json_key_uniqueness_constraint_opt %prec FORMAT
13395+
{
13396+
$3.location = @2;
13397+
$$ = makeJsonIsPredicate($1, $3, $6, $7);
13398+
}
13399+
*/
13400+
| a_expr
13401+
IS NOT JSON
13402+
json_predicate_type_constraint_opt
13403+
json_key_uniqueness_constraint_opt %prec IS
13404+
{
13405+
JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
13406+
$$ = makeNotExpr(makeJsonIsPredicate($1, format, $5, $6), @1);
13407+
}
13408+
/*
13409+
* Required by standard, but it would conflict with expressions
13410+
* like: 'str' || format(...)
13411+
| a_expr
13412+
FORMAT json_representation
13413+
IS NOT JSON
13414+
json_predicate_type_constraint_opt
13415+
json_key_uniqueness_constraint_opt %prec FORMAT
13416+
{
13417+
$3.location = @2;
13418+
$$ = makeNotExpr(makeJsonIsPredicate($1, $3, $7, $8), @1);
13419+
}
13420+
*/
1337813421
| DEFAULT
1337913422
{
1338013423
/*
@@ -13467,6 +13510,14 @@ b_expr: c_expr
1346713510
}
1346813511
;
1346913512

13513+
json_predicate_type_constraint_opt:
13514+
VALUE_P { $$ = JS_TYPE_ANY; }
13515+
| ARRAY { $$ = JS_TYPE_ARRAY; }
13516+
| OBJECT_P { $$ = JS_TYPE_OBJECT; }
13517+
| SCALAR { $$ = JS_TYPE_SCALAR; }
13518+
| /* EMPTY */ { $$ = JS_TYPE_ANY; }
13519+
;
13520+
1347013521
json_key_uniqueness_constraint_opt:
1347113522
WITH_LA_UNIQUE UNIQUE opt_keys { $$ = true; }
1347213523
| WITHOUT UNIQUE opt_keys { $$ = false; }
@@ -15540,6 +15591,7 @@ unreserved_keyword:
1554015591
| ROWS
1554115592
| RULE
1554215593
| SAVEPOINT
15594+
| SCALAR
1554315595
| SCHEMA
1554415596
| SCHEMAS
1554515597
| SCROLL

src/include/nodes/makefuncs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ extern JsonFormat *makeJsonFormat(JsonFormatType type, JsonEncoding encoding,
109109
int location);
110110
extern JsonValueExpr *makeJsonValueExpr(Expr *expr, JsonFormat *format);
111111
extern Node *makeJsonKeyValue(Node *key, Node *value);
112+
extern Node *makeJsonIsPredicate(Node *expr, JsonFormat *format,
113+
JsonValueType vtype, bool unique_keys);
112114
extern JsonEncoding makeJsonEncoding(char *name);
113115

114116
#endif /* MAKEFUNC_H */

src/include/nodes/nodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ typedef enum NodeTag
491491
T_JsonAggConstructor,
492492
T_JsonObjectAgg,
493493
T_JsonArrayAgg,
494+
T_JsonIsPredicate,
494495
T_JsonKeyValue,
495496
T_JsonOutput,
496497

src/include/nodes/parsenodes.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,32 @@ typedef struct JsonOutput
14991499
JsonReturning *returning; /* RETURNING FORMAT clause and type Oids */
15001500
} JsonOutput;
15011501

1502+
/*
1503+
* JsonValueType -
1504+
* representation of JSON item type in IS JSON predicate
1505+
*/
1506+
typedef enum JsonValueType
1507+
{
1508+
JS_TYPE_ANY, /* IS JSON [VALUE] */
1509+
JS_TYPE_OBJECT, /* IS JSON OBJECT */
1510+
JS_TYPE_ARRAY, /* IS JSON ARRAY*/
1511+
JS_TYPE_SCALAR /* IS JSON SCALAR */
1512+
} JsonValueType;
1513+
1514+
/*
1515+
* JsonIsPredicate -
1516+
* untransformed representation of IS JSON predicate
1517+
*/
1518+
typedef struct JsonIsPredicate
1519+
{
1520+
NodeTag type;
1521+
Node *expr; /* untransformed expression */
1522+
JsonFormat *format; /* FORMAT clause, if specified */
1523+
JsonValueType value_type; /* JSON item type */
1524+
bool unique_keys; /* check key uniqueness? */
1525+
int location; /* token location, or -1 if unknown */
1526+
} JsonIsPredicate;
1527+
15021528
/*
15031529
* JsonKeyValue -
15041530
* untransformed representation of JSON object key-value pair for

src/include/parser/kwlist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ PG_KEYWORD("row", ROW, COL_NAME_KEYWORD)
365365
PG_KEYWORD("rows", ROWS, UNRESERVED_KEYWORD)
366366
PG_KEYWORD("rule", RULE, UNRESERVED_KEYWORD)
367367
PG_KEYWORD("savepoint", SAVEPOINT, UNRESERVED_KEYWORD)
368+
PG_KEYWORD("scalar", SCALAR, UNRESERVED_KEYWORD)
368369
PG_KEYWORD("schema", SCHEMA, UNRESERVED_KEYWORD)
369370
PG_KEYWORD("schemas", SCHEMAS, UNRESERVED_KEYWORD)
370371
PG_KEYWORD("scroll", SCROLL, UNRESERVED_KEYWORD)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy