From 6ee30209a6f161d0a267a33f090c70c579c87c00 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Fri, 31 Mar 2023 22:34:04 +0200 Subject: SQL/JSON: support the IS JSON predicate This patch introduces the SQL standard IS JSON predicate. It operates on text and bytea values representing JSON, as well as on the json and jsonb types. Each test has IS and IS NOT variants and supports a WITH UNIQUE KEYS flag. The tests are: IS JSON [VALUE] IS JSON ARRAY IS JSON OBJECT IS JSON SCALAR These should be self-explanatory. The WITH UNIQUE KEYS flag makes these return false when duplicate keys exist in any object within the value, not necessarily directly contained in the outermost object. Author: Nikita Glukhov Author: Teodor Sigaev Author: Oleg Bartunov Author: Alexander Korotkov Author: Amit Langote Author: Andrew Dunstan Reviewers have included (in no particular order) Andres Freund, Alexander Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu, Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby. Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org --- src/backend/nodes/nodeFuncs.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/backend/nodes/nodeFuncs.c') diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 69907fbcde8..fdb0c6b3fef 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -261,6 +261,9 @@ exprType(const Node *expr) case T_JsonConstructorExpr: type = ((const JsonConstructorExpr *) expr)->returning->typid; break; + case T_JsonIsPredicate: + type = BOOLOID; + break; default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr)); type = InvalidOid; /* keep compiler quiet */ @@ -983,6 +986,9 @@ exprCollation(const Node *expr) coll = InvalidOid; } break; + case T_JsonIsPredicate: + coll = InvalidOid; /* result is always an boolean type */ + break; default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr)); coll = InvalidOid; /* keep compiler quiet */ @@ -1205,6 +1211,9 @@ exprSetCollation(Node *expr, Oid collation) * json[b] type */ } break; + case T_JsonIsPredicate: + Assert(!OidIsValid(collation)); /* result is always boolean */ + break; default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr)); break; @@ -1653,6 +1662,9 @@ exprLocation(const Node *expr) case T_JsonConstructorExpr: loc = ((const JsonConstructorExpr *) expr)->location; break; + case T_JsonIsPredicate: + loc = ((const JsonIsPredicate *) expr)->location; + break; default: /* for any other node type it's just unknown... */ loc = -1; @@ -2406,6 +2418,8 @@ expression_tree_walker_impl(Node *node, return true; } break; + case T_JsonIsPredicate: + return walker(((JsonIsPredicate *) node)->expr, context); default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); @@ -3413,6 +3427,16 @@ expression_tree_mutator_impl(Node *node, MUTATE(newnode->coercion, jve->coercion, Expr *); MUTATE(newnode->returning, jve->returning, JsonReturning *); + return (Node *) newnode; + } + case T_JsonIsPredicate: + { + JsonIsPredicate *pred = (JsonIsPredicate *) node; + JsonIsPredicate *newnode; + + FLATCOPY(newnode, pred, JsonIsPredicate); + MUTATE(newnode->expr, pred->expr, Node *); + return (Node *) newnode; } default: @@ -4261,6 +4285,8 @@ raw_expression_tree_walker_impl(Node *node, return true; } break; + case T_JsonIsPredicate: + return walker(((JsonIsPredicate *) node)->expr, context); default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); -- cgit v1.2.3