|
46 | 46 | #include "utils/array.h"
|
47 | 47 | #include "utils/builtins.h"
|
48 | 48 | #include "utils/datum.h"
|
| 49 | +#include "utils/jsonpath.h" |
49 | 50 | #include "utils/lsyscache.h"
|
50 | 51 | #include "utils/typcache.h"
|
51 | 52 |
|
@@ -2206,6 +2207,92 @@ ExecInitExprRec(Expr *node, ExprState *state,
|
2206 | 2207 | break;
|
2207 | 2208 | }
|
2208 | 2209 |
|
| 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 | + |
2209 | 2296 | default:
|
2210 | 2297 | elog(ERROR, "unrecognized node type: %d",
|
2211 | 2298 | (int) nodeTag(node));
|
|
0 commit comments