Skip to content

Commit fc47250

Browse files
author
Nikita Glukhov
committed
Add JSON_VALUE, JSON_EXISTS, JSON_QUERY
1 parent 564dc52 commit fc47250

27 files changed

+3059
-13
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,6 +2841,18 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
28412841
APP_JUMB(opts->value_type);
28422842
}
28432843
break;
2844+
case T_JsonExpr:
2845+
{
2846+
JsonExpr *jexpr = (JsonExpr *) node;
2847+
2848+
APP_JUMB(jexpr->op);
2849+
JumbleExpr(jstate, jexpr->raw_expr);
2850+
JumbleExpr(jstate, (Node *) jexpr->path_spec);
2851+
JumbleExpr(jstate, (Node *) jexpr->passing.values);
2852+
JumbleExpr(jstate, jexpr->on_empty.default_expr);
2853+
JumbleExpr(jstate, jexpr->on_error.default_expr);
2854+
}
2855+
break;
28442856
case T_List:
28452857
foreach(temp, (List *) node)
28462858
{

src/backend/executor/execExpr.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "pgstat.h"
4646
#include "utils/builtins.h"
4747
#include "utils/datum.h"
48+
#include "utils/jsonpath.h"
4849
#include "utils/lsyscache.h"
4950
#include "utils/typcache.h"
5051

@@ -2118,6 +2119,95 @@ ExecInitExprRec(Expr *node, ExprState *state,
21182119
resnull);
21192120
break;
21202121

2122+
case T_JsonExpr:
2123+
{
2124+
JsonExpr *jexpr = castNode(JsonExpr, node);
2125+
ListCell *argexprlc;
2126+
ListCell *argnamelc;
2127+
2128+
scratch.opcode = EEOP_JSONEXPR;
2129+
scratch.d.jsonexpr.jsexpr = jexpr;
2130+
2131+
scratch.d.jsonexpr.raw_expr =
2132+
palloc(sizeof(*scratch.d.jsonexpr.raw_expr));
2133+
2134+
ExecInitExprRec((Expr *) jexpr->raw_expr, state,
2135+
&scratch.d.jsonexpr.raw_expr->value,
2136+
&scratch.d.jsonexpr.raw_expr->isnull);
2137+
2138+
scratch.d.jsonexpr.formatted_expr =
2139+
ExecInitExpr((Expr *) jexpr->formatted_expr,
2140+
state->parent);
2141+
2142+
scratch.d.jsonexpr.result_expr = jexpr->result_coercion
2143+
? ExecInitExpr((Expr *) jexpr->result_coercion->expr,
2144+
state->parent)
2145+
: NULL;
2146+
2147+
scratch.d.jsonexpr.default_on_empty =
2148+
ExecInitExpr((Expr *) jexpr->on_empty.default_expr,
2149+
state->parent);
2150+
2151+
scratch.d.jsonexpr.default_on_error =
2152+
ExecInitExpr((Expr *) jexpr->on_error.default_expr,
2153+
state->parent);
2154+
2155+
if (jexpr->omit_quotes ||
2156+
(jexpr->result_coercion && jexpr->result_coercion->via_io))
2157+
{
2158+
Oid typinput;
2159+
2160+
/* lookup the result type's input function */
2161+
getTypeInputInfo(jexpr->returning.typid, &typinput,
2162+
&scratch.d.jsonexpr.input.typioparam);
2163+
fmgr_info(typinput, &scratch.d.jsonexpr.input.func);
2164+
}
2165+
2166+
scratch.d.jsonexpr.args = NIL;
2167+
2168+
forboth(argexprlc, jexpr->passing.values,
2169+
argnamelc, jexpr->passing.names)
2170+
{
2171+
Expr *argexpr = (Expr *) lfirst(argexprlc);
2172+
Value *argname = (Value *) lfirst(argnamelc);
2173+
JsonPathVariableEvalContext *var = palloc(sizeof(*var));
2174+
2175+
var->var.varName = cstring_to_text(argname->val.str);
2176+
var->var.typid = exprType((Node *) argexpr);
2177+
var->var.typmod = exprTypmod((Node *) argexpr);
2178+
var->var.cb = EvalJsonPathVar;
2179+
var->var.cb_arg = var;
2180+
var->estate = ExecInitExpr(argexpr, state->parent);
2181+
var->econtext = NULL;
2182+
var->evaluated = false;
2183+
var->value = (Datum) 0;
2184+
var->isnull = true;
2185+
2186+
scratch.d.jsonexpr.args =
2187+
lappend(scratch.d.jsonexpr.args, var);
2188+
}
2189+
2190+
if (jexpr->coercions)
2191+
{
2192+
JsonCoercion **coercion;
2193+
struct JsonCoercionState *cstate;
2194+
2195+
for (cstate = &scratch.d.jsonexpr.coercions.null,
2196+
coercion = &jexpr->coercions->null;
2197+
coercion <= &jexpr->coercions->composite;
2198+
coercion++, cstate++)
2199+
{
2200+
cstate->coercion = *coercion;
2201+
cstate->estate = *coercion ?
2202+
ExecInitExpr((Expr *)(*coercion)->expr,
2203+
state->parent) : NULL;
2204+
}
2205+
}
2206+
2207+
ExprEvalPushStep(state, &scratch);
2208+
}
2209+
break;
2210+
21212211
default:
21222212
elog(ERROR, "unrecognized node type: %d",
21232213
(int) nodeTag(node));

0 commit comments

Comments
 (0)