|
45 | 45 | #include "pgstat.h"
|
46 | 46 | #include "utils/builtins.h"
|
47 | 47 | #include "utils/datum.h"
|
| 48 | +#include "utils/jsonpath.h" |
48 | 49 | #include "utils/lsyscache.h"
|
49 | 50 | #include "utils/typcache.h"
|
50 | 51 |
|
@@ -2118,6 +2119,95 @@ ExecInitExprRec(Expr *node, ExprState *state,
|
2118 | 2119 | resnull);
|
2119 | 2120 | break;
|
2120 | 2121 |
|
| 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 | + |
2121 | 2211 | default:
|
2122 | 2212 | elog(ERROR, "unrecognized node type: %d",
|
2123 | 2213 | (int) nodeTag(node));
|
|
0 commit comments