Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 36f36ce

Browse files
author
Nikita Glukhov
committed
Add JSON_VALUE, JSON_EXISTS, JSON_QUERY
1 parent c83cde3 commit 36f36ce

28 files changed

+3252
-12
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3134,6 +3134,27 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
31343134
APP_JUMB(pred->value_type);
31353135
}
31363136
break;
3137+
case T_JsonExpr:
3138+
{
3139+
JsonExpr *jexpr = (JsonExpr *) node;
3140+
3141+
APP_JUMB(jexpr->op);
3142+
JumbleExpr(jstate, jexpr->raw_expr);
3143+
JumbleExpr(jstate, (Node *) jexpr->path_spec);
3144+
foreach(temp, jexpr->passing_names)
3145+
{
3146+
APP_JUMB_STRING(castNode(Value, temp)->val.str);
3147+
}
3148+
JumbleExpr(jstate, (Node *) jexpr->passing_values);
3149+
if (jexpr->on_empty)
3150+
{
3151+
APP_JUMB(jexpr->on_empty->btype);
3152+
JumbleExpr(jstate, jexpr->on_empty->default_expr);
3153+
}
3154+
APP_JUMB(jexpr->on_error->btype);
3155+
JumbleExpr(jstate, jexpr->on_error->default_expr);
3156+
}
3157+
break;
31373158
case T_List:
31383159
foreach(temp, (List *) node)
31393160
{

src/backend/executor/execExpr.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "utils/array.h"
4747
#include "utils/builtins.h"
4848
#include "utils/datum.h"
49+
#include "utils/jsonpath.h"
4950
#include "utils/lsyscache.h"
5051
#include "utils/typcache.h"
5152

@@ -2206,6 +2207,92 @@ ExecInitExprRec(Expr *node, ExprState *state,
22062207
break;
22072208
}
22082209

2210+
case T_JsonExpr:
2211+
{
2212+
JsonExpr *jexpr = castNode(JsonExpr, node);
2213+
ListCell *argexprlc;
2214+
ListCell *argnamelc;
2215+
2216+
scratch.opcode = EEOP_JSONEXPR;
2217+
scratch.d.jsonexpr.jsexpr = jexpr;
2218+
2219+
scratch.d.jsonexpr.raw_expr =
2220+
palloc(sizeof(*scratch.d.jsonexpr.raw_expr));
2221+
2222+
ExecInitExprRec((Expr *) jexpr->raw_expr, state,
2223+
&scratch.d.jsonexpr.raw_expr->value,
2224+
&scratch.d.jsonexpr.raw_expr->isnull);
2225+
2226+
scratch.d.jsonexpr.formatted_expr =
2227+
ExecInitExpr((Expr *) jexpr->formatted_expr, state->parent);
2228+
2229+
scratch.d.jsonexpr.result_expr = jexpr->result_coercion
2230+
? ExecInitExpr((Expr *) jexpr->result_coercion->expr,
2231+
state->parent)
2232+
: NULL;
2233+
2234+
scratch.d.jsonexpr.default_on_empty = !jexpr->on_empty ? NULL :
2235+
ExecInitExpr((Expr *) jexpr->on_empty->default_expr,
2236+
state->parent);
2237+
2238+
scratch.d.jsonexpr.default_on_error =
2239+
ExecInitExpr((Expr *) jexpr->on_error->default_expr,
2240+
state->parent);
2241+
2242+
if (jexpr->omit_quotes ||
2243+
(jexpr->result_coercion && jexpr->result_coercion->via_io))
2244+
{
2245+
Oid typinput;
2246+
2247+
/* lookup the result type's input function */
2248+
getTypeInputInfo(jexpr->returning->typid, &typinput,
2249+
&scratch.d.jsonexpr.input.typioparam);
2250+
fmgr_info(typinput, &scratch.d.jsonexpr.input.func);
2251+
}
2252+
2253+
scratch.d.jsonexpr.args = NIL;
2254+
2255+
forboth(argexprlc, jexpr->passing_values,
2256+
argnamelc, jexpr->passing_names)
2257+
{
2258+
Expr *argexpr = (Expr *) lfirst(argexprlc);
2259+
Value *argname = (Value *) lfirst(argnamelc);
2260+
JsonPathVariableEvalContext *var = palloc(sizeof(*var));
2261+
2262+
var->name = pstrdup(argname->val.str);
2263+
var->typid = exprType((Node *) argexpr);
2264+
var->typmod = exprTypmod((Node *) argexpr);
2265+
var->estate = ExecInitExpr(argexpr, state->parent);
2266+
var->econtext = NULL;
2267+
var->evaluated = false;
2268+
var->value = (Datum) 0;
2269+
var->isnull = true;
2270+
2271+
scratch.d.jsonexpr.args =
2272+
lappend(scratch.d.jsonexpr.args, var);
2273+
}
2274+
2275+
if (jexpr->coercions)
2276+
{
2277+
JsonCoercion **coercion;
2278+
struct JsonCoercionState *cstate;
2279+
2280+
for (cstate = &scratch.d.jsonexpr.coercions.null,
2281+
coercion = &jexpr->coercions->null;
2282+
coercion <= &jexpr->coercions->composite;
2283+
coercion++, cstate++)
2284+
{
2285+
cstate->coercion = *coercion;
2286+
cstate->estate = *coercion ?
2287+
ExecInitExpr((Expr *)(*coercion)->expr,
2288+
state->parent) : NULL;
2289+
}
2290+
}
2291+
2292+
ExprEvalPushStep(state, &scratch);
2293+
break;
2294+
}
2295+
22092296
default:
22102297
elog(ERROR, "unrecognized node type: %d",
22112298
(int) nodeTag(node));

0 commit comments

Comments
 (0)