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

Commit a6aec1e

Browse files
author
Nikita Glukhov
committed
Add JSON_VALUE, JSON_EXISTS, JSON_QUERY
1 parent afaa5a4 commit a6aec1e

File tree

27 files changed

+3112
-13
lines changed

27 files changed

+3112
-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
@@ -2865,6 +2865,18 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
28652865
APP_JUMB(opts->value_type);
28662866
}
28672867
break;
2868+
case T_JsonExpr:
2869+
{
2870+
JsonExpr *jexpr = (JsonExpr *) node;
2871+
2872+
APP_JUMB(jexpr->op);
2873+
JumbleExpr(jstate, jexpr->raw_expr);
2874+
JumbleExpr(jstate, (Node *) jexpr->path_spec);
2875+
JumbleExpr(jstate, (Node *) jexpr->passing.values);
2876+
JumbleExpr(jstate, jexpr->on_empty.default_expr);
2877+
JumbleExpr(jstate, jexpr->on_error.default_expr);
2878+
}
2879+
break;
28682880
case T_List:
28692881
foreach(temp, (List *) node)
28702882
{

src/backend/executor/execExpr.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "optimizer/planner.h"
4444
#include "pgstat.h"
4545
#include "utils/builtins.h"
46+
#include "utils/jsonpath.h"
4647
#include "utils/lsyscache.h"
4748
#include "utils/typcache.h"
4849

@@ -2031,6 +2032,91 @@ ExecInitExprRec(Expr *node, PlanState *parent, ExprState *state,
20312032
parent, state, resv, resnull);
20322033
break;
20332034

2035+
case T_JsonExpr:
2036+
{
2037+
JsonExpr *jexpr = castNode(JsonExpr, node);
2038+
ListCell *argexprlc;
2039+
ListCell *argnamelc;
2040+
2041+
scratch.opcode = EEOP_JSONEXPR;
2042+
scratch.d.jsonexpr.jsexpr = jexpr;
2043+
2044+
scratch.d.jsonexpr.raw_expr =
2045+
palloc(sizeof(*scratch.d.jsonexpr.raw_expr));
2046+
2047+
ExecInitExprRec((Expr *) jexpr->raw_expr, parent, state,
2048+
&scratch.d.jsonexpr.raw_expr->value,
2049+
&scratch.d.jsonexpr.raw_expr->isnull);
2050+
2051+
scratch.d.jsonexpr.formatted_expr =
2052+
ExecInitExpr((Expr *) jexpr->formatted_expr, parent);
2053+
2054+
scratch.d.jsonexpr.result_expr = jexpr->result_coercion
2055+
? ExecInitExpr((Expr *) jexpr->result_coercion->expr, parent)
2056+
: NULL;
2057+
2058+
scratch.d.jsonexpr.default_on_empty =
2059+
ExecInitExpr((Expr *) jexpr->on_empty.default_expr, parent);
2060+
2061+
scratch.d.jsonexpr.default_on_error =
2062+
ExecInitExpr((Expr *) jexpr->on_error.default_expr, parent);
2063+
2064+
if (jexpr->omit_quotes ||
2065+
(jexpr->result_coercion && jexpr->result_coercion->via_io))
2066+
{
2067+
Oid typinput;
2068+
2069+
/* lookup the result type's input function */
2070+
getTypeInputInfo(jexpr->returning.typid, &typinput,
2071+
&scratch.d.jsonexpr.input.typioparam);
2072+
fmgr_info(typinput, &scratch.d.jsonexpr.input.func);
2073+
}
2074+
2075+
scratch.d.jsonexpr.args = NIL;
2076+
2077+
forboth(argexprlc, jexpr->passing.values,
2078+
argnamelc, jexpr->passing.names)
2079+
{
2080+
Expr *argexpr = (Expr *) lfirst(argexprlc);
2081+
Value *argname = (Value *) lfirst(argnamelc);
2082+
JsonPathVariableEvalContext *var = palloc(sizeof(*var));
2083+
2084+
var->var.varName = cstring_to_text(argname->val.str);
2085+
var->var.typid = exprType((Node *) argexpr);
2086+
var->var.typmod = exprTypmod((Node *) argexpr);
2087+
var->var.cb = EvalJsonPathVar;
2088+
var->var.cb_arg = var;
2089+
var->estate = ExecInitExpr(argexpr, parent);
2090+
var->econtext = NULL;
2091+
var->evaluated = false;
2092+
var->value = (Datum) 0;
2093+
var->isnull = true;
2094+
2095+
scratch.d.jsonexpr.args =
2096+
lappend(scratch.d.jsonexpr.args, var);
2097+
}
2098+
2099+
if (jexpr->coercions)
2100+
{
2101+
JsonCoercion **coercion;
2102+
struct JsonCoercionState *cstate;
2103+
2104+
for (cstate = &scratch.d.jsonexpr.coercions.null,
2105+
coercion = &jexpr->coercions->null;
2106+
coercion <= &jexpr->coercions->composite;
2107+
coercion++, cstate++)
2108+
{
2109+
cstate->coercion = *coercion;
2110+
cstate->estate = *coercion ?
2111+
ExecInitExpr((Expr *)(*coercion)->expr,
2112+
parent) : NULL;
2113+
}
2114+
}
2115+
2116+
ExprEvalPushStep(state, &scratch);
2117+
}
2118+
break;
2119+
20342120
default:
20352121
elog(ERROR, "unrecognized node type: %d",
20362122
(int) nodeTag(node));

0 commit comments

Comments
 (0)