Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit98a30c9

Browse files
author
Nikita Glukhov
committed
Add nodes for IS JSON execution
1 parent6c13c76 commit98a30c9

File tree

17 files changed

+207
-220
lines changed

17 files changed

+207
-220
lines changed

‎src/backend/executor/execExpr.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2194,9 +2194,17 @@ ExecInitExprRec(Expr *node, ExprState *state,
21942194
break;
21952195

21962196
caseT_JsonIsPredicate:
2197-
ExecInitExprRec((Expr*) ((JsonIsPredicate*)node)->expr,state,resv,
2198-
resnull);
2199-
break;
2197+
{
2198+
JsonIsPredicate*pred= (JsonIsPredicate*)node;
2199+
2200+
ExecInitExprRec((Expr*)pred->expr,state,resv,resnull);
2201+
2202+
scratch.opcode=EEOP_IS_JSON;
2203+
scratch.d.is_json.pred=pred;
2204+
2205+
ExprEvalPushStep(state,&scratch);
2206+
break;
2207+
}
22002208

22012209
default:
22022210
elog(ERROR,"unrecognized node type: %d",

‎src/backend/executor/execExprInterp.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#include"utils/expandedrecord.h"
7474
#include"utils/json.h"
7575
#include"utils/jsonb.h"
76+
#include"utils/jsonfuncs.h"
7677
#include"utils/lsyscache.h"
7778
#include"utils/memutils.h"
7879
#include"utils/timestamp.h"
@@ -435,6 +436,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
435436
&&CASE_EEOP_SUBPLAN,
436437
&&CASE_EEOP_ALTERNATIVE_SUBPLAN,
437438
&&CASE_EEOP_JSON_CONSTRUCTOR,
439+
&&CASE_EEOP_IS_JSON,
438440
&&CASE_EEOP_AGG_STRICT_DESERIALIZE,
439441
&&CASE_EEOP_AGG_DESERIALIZE,
440442
&&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS,
@@ -1807,6 +1809,14 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
18071809
EEO_NEXT();
18081810
}
18091811

1812+
EEO_CASE(EEOP_IS_JSON)
1813+
{
1814+
/* too complex for an inline implementation */
1815+
ExecEvalJsonIsPredicate(state,op);
1816+
1817+
EEO_NEXT();
1818+
}
1819+
18101820
EEO_CASE(EEOP_LAST)
18111821
{
18121822
/* unreachable */
@@ -3862,6 +3872,91 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
38623872
}
38633873
}
38643874

3875+
void
3876+
ExecEvalJsonIsPredicate(ExprState*state,ExprEvalStep*op)
3877+
{
3878+
JsonIsPredicate*pred=op->d.is_json.pred;
3879+
Datumjs=*op->resvalue;
3880+
Oidexprtype;
3881+
boolres;
3882+
3883+
if (*op->resnull)
3884+
{
3885+
*op->resvalue=BoolGetDatum(false);
3886+
return;
3887+
}
3888+
3889+
exprtype=exprType(pred->expr);
3890+
3891+
if (exprtype==TEXTOID||exprtype==JSONOID)
3892+
{
3893+
text*json=DatumGetTextP(js);
3894+
3895+
if (pred->value_type==JS_TYPE_ANY)
3896+
res= true;
3897+
else
3898+
{
3899+
switch (json_get_first_token(json, false))
3900+
{
3901+
caseJSON_TOKEN_OBJECT_START:
3902+
res=pred->value_type==JS_TYPE_OBJECT;
3903+
break;
3904+
caseJSON_TOKEN_ARRAY_START:
3905+
res=pred->value_type==JS_TYPE_ARRAY;
3906+
break;
3907+
caseJSON_TOKEN_STRING:
3908+
caseJSON_TOKEN_NUMBER:
3909+
caseJSON_TOKEN_TRUE:
3910+
caseJSON_TOKEN_FALSE:
3911+
caseJSON_TOKEN_NULL:
3912+
res=pred->value_type==JS_TYPE_SCALAR;
3913+
break;
3914+
default:
3915+
res= false;
3916+
break;
3917+
}
3918+
}
3919+
3920+
/*
3921+
* Do full parsing pass only for uniqueness check or for
3922+
* JSON text validation.
3923+
*/
3924+
if (res&& (pred->unique_keys||exprtype==TEXTOID))
3925+
res=json_validate(json,pred->unique_keys);
3926+
}
3927+
elseif (exprtype==JSONBOID)
3928+
{
3929+
if (pred->value_type==JS_TYPE_ANY)
3930+
res= true;
3931+
else
3932+
{
3933+
Jsonb*jb=DatumGetJsonbP(js);
3934+
3935+
switch (pred->value_type)
3936+
{
3937+
caseJS_TYPE_OBJECT:
3938+
res=JB_ROOT_IS_OBJECT(jb);
3939+
break;
3940+
caseJS_TYPE_ARRAY:
3941+
res=JB_ROOT_IS_ARRAY(jb)&& !JB_ROOT_IS_SCALAR(jb);
3942+
break;
3943+
caseJS_TYPE_SCALAR:
3944+
res=JB_ROOT_IS_ARRAY(jb)&&JB_ROOT_IS_SCALAR(jb);
3945+
break;
3946+
default:
3947+
res= false;
3948+
break;
3949+
}
3950+
}
3951+
3952+
/* Key uniqueness check is redundant for jsonb */
3953+
}
3954+
else
3955+
res= false;
3956+
3957+
*op->resvalue=BoolGetDatum(res);
3958+
}
3959+
38653960
/*
38663961
* ExecEvalGroupingFunc
38673962
*

‎src/backend/nodes/makefuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -890,14 +890,15 @@ makeJsonKeyValue(Node *key, Node *value)
890890
*/
891891
Node*
892892
makeJsonIsPredicate(Node*expr,JsonFormat*format,JsonValueTypevalue_type,
893-
boolunique_keys)
893+
boolunique_keys,intlocation)
894894
{
895895
JsonIsPredicate*n=makeNode(JsonIsPredicate);
896896

897897
n->expr=expr;
898898
n->format=format;
899899
n->value_type=value_type;
900900
n->unique_keys=unique_keys;
901+
n->location=location;
901902

902903
return (Node*)n;
903904
}

‎src/backend/parser/gram.y

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13382,7 +13382,7 @@ a_expr:c_expr{ $$ = $1; }
1338213382
json_key_uniqueness_constraint_opt%precIS
1338313383
{
1338413384
JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
13385-
$$ = makeJsonIsPredicate($1, format,$4,$5);
13385+
$$ = makeJsonIsPredicate($1, format,$4,$5,@1);
1338613386
}
1338713387
/*
1338813388
* Required by standard, but it would conflict with expressions
@@ -13394,7 +13394,7 @@ a_expr:c_expr{ $$ = $1; }
1339413394
json_key_uniqueness_constraint_opt%prec FORMAT
1339513395
{
1339613396
$3.location = @2;
13397-
$$ = makeJsonIsPredicate($1, $3, $6, $7);
13397+
$$ = makeJsonIsPredicate($1, $3, $6, $7, @1);
1339813398
}
1339913399
*/
1340013400
|a_expr
@@ -13403,7 +13403,7 @@ a_expr:c_expr{ $$ = $1; }
1340313403
json_key_uniqueness_constraint_opt%precIS
1340413404
{
1340513405
JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1);
13406-
$$ = makeNotExpr(makeJsonIsPredicate($1, format,$5,$6),@1);
13406+
$$ = makeNotExpr(makeJsonIsPredicate($1, format,$5,$6,@1),@1);
1340713407
}
1340813408
/*
1340913409
* Required by standard, but it would conflict with expressions
@@ -13415,7 +13415,7 @@ a_expr:c_expr{ $$ = $1; }
1341513415
json_key_uniqueness_constraint_opt%prec FORMAT
1341613416
{
1341713417
$3.location = @2;
13418-
$$ = makeNotExpr(makeJsonIsPredicate($1, $3, $7, $8), @1);
13418+
$$ = makeNotExpr(makeJsonIsPredicate($1, $3, $7, $8, @1), @1);
1341913419
}
1342013420
*/
1342113421
|DEFAULT

‎src/backend/parser/parse_expr.c

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4346,24 +4346,6 @@ transformJsonArrayConstructor(ParseState *pstate, JsonArrayConstructor *ctor)
43464346
ctor->location);
43474347
}
43484348

4349-
staticconstchar*
4350-
JsonValueTypeStrings[]=
4351-
{
4352-
"any",
4353-
"object",
4354-
"array",
4355-
"scalar",
4356-
};
4357-
4358-
staticConst*
4359-
makeJsonValueTypeConst(JsonValueTypetype)
4360-
{
4361-
returnmakeConst(TEXTOID,-1,InvalidOid,-1,
4362-
PointerGetDatum(cstring_to_text(
4363-
JsonValueTypeStrings[(int)type])),
4364-
false, false);
4365-
}
4366-
43674349
/*
43684350
* Transform IS JSON predicate into
43694351
* json[b]_is_valid(json, value_type [, check_key_uniqueness]) call.
@@ -4373,7 +4355,6 @@ transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
43734355
{
43744356
Node*expr=transformExprRecurse(pstate,pred->expr);
43754357
Oidexprtype=exprType(expr);
4376-
FuncExpr*fexpr;
43774358

43784359
/* prepare input document */
43794360
if (exprtype==BYTEAOID)
@@ -4408,38 +4389,12 @@ transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
44084389
expr= (Node*)makeJsonValueExpr((Expr*)expr,pred->format);
44094390

44104391
/* make resulting expression */
4411-
if (exprtype==TEXTOID||exprtype==JSONOID)
4412-
{
4413-
fexpr=makeFuncExpr(F_JSON_IS_VALID,BOOLOID,
4414-
list_make3(expr,
4415-
makeJsonValueTypeConst(pred->value_type),
4416-
makeBoolConst(pred->unique_keys, false)),
4417-
InvalidOid,InvalidOid,COERCE_EXPLICIT_CALL);
4418-
4419-
fexpr->location=pred->location;
4420-
}
4421-
elseif (exprtype==JSONBOID)
4422-
{
4423-
/* XXX the following expressions also can be used here:
4424-
* jsonb_type(jsonb) = 'type' (for object and array checks)
4425-
* CASE jsonb_type(jsonb) WHEN ... END (for scalars checks)
4426-
*/
4427-
fexpr=makeFuncExpr(F_JSONB_IS_VALID,BOOLOID,
4428-
list_make2(expr,
4429-
makeJsonValueTypeConst(pred->value_type)),
4430-
InvalidOid,InvalidOid,COERCE_EXPLICIT_CALL);
4431-
4432-
fexpr->location=pred->location;
4433-
}
4434-
else
4435-
{
4392+
if (exprtype!=TEXTOID&&exprtype!=JSONOID&&exprtype!=JSONBOID)
44364393
ereport(ERROR,
44374394
(errcode(ERRCODE_DATATYPE_MISMATCH),
44384395
errmsg("cannot use type %s in IS JSON predicate",
44394396
format_type_be(exprtype))));
4440-
returnNULL;
4441-
}
44424397

4443-
returnmakeJsonIsPredicate((Node*)fexpr,NULL,pred->value_type,
4444-
pred->unique_keys);
4398+
returnmakeJsonIsPredicate((Node*)expr,NULL,pred->value_type,
4399+
pred->unique_keys,pred->location);
44454400
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp