|
43 | 43 | #include "optimizer/planner.h"
|
44 | 44 | #include "pgstat.h"
|
45 | 45 | #include "utils/builtins.h"
|
| 46 | +#include "utils/jsonpath.h" |
46 | 47 | #include "utils/lsyscache.h"
|
47 | 48 | #include "utils/typcache.h"
|
48 | 49 |
|
@@ -2031,6 +2032,91 @@ ExecInitExprRec(Expr *node, PlanState *parent, ExprState *state,
|
2031 | 2032 | parent, state, resv, resnull);
|
2032 | 2033 | break;
|
2033 | 2034 |
|
| 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 | + |
2034 | 2120 | default:
|
2035 | 2121 | elog(ERROR, "unrecognized node type: %d",
|
2036 | 2122 | (int) nodeTag(node));
|
|
0 commit comments