PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
execExpr.h File Reference
#include "executor/nodeAgg.h"
#include "nodes/execnodes.h"
#include "nodes/miscnodes.h"
Include dependency graph for execExpr.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ExprEvalRowtypeCache
 
struct  ExprEvalStep
 
struct  SubscriptingRefState
 
struct  SubscriptExecSteps
 
struct  JsonConstructorExprState
 

Macros

#define EEO_FLAG_INTERPRETER_INITIALIZED   (1 << 1)
 
#define EEO_FLAG_DIRECT_THREADED   (1 << 2)
 

Typedefs

typedef void(* ExecEvalSubroutine) (ExprState *state, struct ExprEvalStep *op, ExprContext *econtext)
 
typedef bool(* ExecEvalBoolSubroutine) (ExprState *state, struct ExprEvalStep *op, ExprContext *econtext)
 
typedef struct ExprEvalRowtypeCache ExprEvalRowtypeCache
 
typedef enum ExprEvalOp ExprEvalOp
 
typedef struct ExprEvalStep ExprEvalStep
 
typedef struct SubscriptingRefState SubscriptingRefState
 
typedef struct SubscriptExecSteps SubscriptExecSteps
 
typedef struct JsonConstructorExprState JsonConstructorExprState
 

Enumerations

enum  ExprEvalOp {
  EEOP_DONE , EEOP_INNER_FETCHSOME , EEOP_OUTER_FETCHSOME , EEOP_SCAN_FETCHSOME ,
  EEOP_INNER_VAR , EEOP_OUTER_VAR , EEOP_SCAN_VAR , EEOP_INNER_SYSVAR ,
  EEOP_OUTER_SYSVAR , EEOP_SCAN_SYSVAR , EEOP_WHOLEROW , EEOP_ASSIGN_INNER_VAR ,
  EEOP_ASSIGN_OUTER_VAR , EEOP_ASSIGN_SCAN_VAR , EEOP_ASSIGN_TMP , EEOP_ASSIGN_TMP_MAKE_RO ,
  EEOP_CONST , EEOP_FUNCEXPR , EEOP_FUNCEXPR_STRICT , EEOP_FUNCEXPR_FUSAGE ,
  EEOP_FUNCEXPR_STRICT_FUSAGE , EEOP_BOOL_AND_STEP_FIRST , EEOP_BOOL_AND_STEP , EEOP_BOOL_AND_STEP_LAST ,
  EEOP_BOOL_OR_STEP_FIRST , EEOP_BOOL_OR_STEP , EEOP_BOOL_OR_STEP_LAST , EEOP_BOOL_NOT_STEP ,
  EEOP_QUAL , EEOP_JUMP , EEOP_JUMP_IF_NULL , EEOP_JUMP_IF_NOT_NULL ,
  EEOP_JUMP_IF_NOT_TRUE , EEOP_NULLTEST_ISNULL , EEOP_NULLTEST_ISNOTNULL , EEOP_NULLTEST_ROWISNULL ,
  EEOP_NULLTEST_ROWISNOTNULL , EEOP_BOOLTEST_IS_TRUE , EEOP_BOOLTEST_IS_NOT_TRUE , EEOP_BOOLTEST_IS_FALSE ,
  EEOP_BOOLTEST_IS_NOT_FALSE , EEOP_PARAM_EXEC , EEOP_PARAM_EXTERN , EEOP_PARAM_CALLBACK ,
  EEOP_PARAM_SET , EEOP_CASE_TESTVAL , EEOP_MAKE_READONLY , EEOP_IOCOERCE ,
  EEOP_IOCOERCE_SAFE , EEOP_DISTINCT , EEOP_NOT_DISTINCT , EEOP_NULLIF ,
  EEOP_SQLVALUEFUNCTION , EEOP_CURRENTOFEXPR , EEOP_NEXTVALUEEXPR , EEOP_ARRAYEXPR ,
  EEOP_ARRAYCOERCE , EEOP_ROW , EEOP_ROWCOMPARE_STEP , EEOP_ROWCOMPARE_FINAL ,
  EEOP_MINMAX , EEOP_FIELDSELECT , EEOP_FIELDSTORE_DEFORM , EEOP_FIELDSTORE_FORM ,
  EEOP_SBSREF_SUBSCRIPTS , EEOP_SBSREF_OLD , EEOP_SBSREF_ASSIGN , EEOP_SBSREF_FETCH ,
  EEOP_DOMAIN_TESTVAL , EEOP_DOMAIN_NOTNULL , EEOP_DOMAIN_CHECK , EEOP_HASHDATUM_SET_INITVAL ,
  EEOP_HASHDATUM_FIRST , EEOP_HASHDATUM_FIRST_STRICT , EEOP_HASHDATUM_NEXT32 , EEOP_HASHDATUM_NEXT32_STRICT ,
  EEOP_CONVERT_ROWTYPE , EEOP_SCALARARRAYOP , EEOP_HASHED_SCALARARRAYOP , EEOP_XMLEXPR ,
  EEOP_JSON_CONSTRUCTOR , EEOP_IS_JSON , EEOP_JSONEXPR_PATH , EEOP_JSONEXPR_COERCION ,
  EEOP_JSONEXPR_COERCION_FINISH , EEOP_AGGREF , EEOP_GROUPING_FUNC , EEOP_WINDOW_FUNC ,
  EEOP_MERGE_SUPPORT_FUNC , EEOP_SUBPLAN , EEOP_AGG_STRICT_DESERIALIZE , EEOP_AGG_DESERIALIZE ,
  EEOP_AGG_STRICT_INPUT_CHECK_ARGS , EEOP_AGG_STRICT_INPUT_CHECK_NULLS , EEOP_AGG_PLAIN_PERGROUP_NULLCHECK , EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL ,
  EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL , EEOP_AGG_PLAIN_TRANS_BYVAL , EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF , EEOP_AGG_PLAIN_TRANS_STRICT_BYREF ,
  EEOP_AGG_PLAIN_TRANS_BYREF , EEOP_AGG_PRESORTED_DISTINCT_SINGLE , EEOP_AGG_PRESORTED_DISTINCT_MULTI , EEOP_AGG_ORDERED_TRANS_DATUM ,
  EEOP_AGG_ORDERED_TRANS_TUPLE , EEOP_LAST
}
 

Functions

 StaticAssertDecl (sizeof(ExprEvalStep)<=64, "size of ExprEvalStep exceeds 64 bytes")
 
void ExprEvalPushStep (ExprState *es, const ExprEvalStep *s)
 
void ExecReadyInterpretedExpr (ExprState *state)
 
ExprEvalOp ExecEvalStepOp (ExprState *state, ExprEvalStep *op)
 
Datum ExecInterpExprStillValid (ExprState *state, ExprContext *econtext, bool *isNull)
 
void CheckExprStillValid (ExprState *state, ExprContext *econtext)
 
void ExecEvalFuncExprFusage (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalFuncExprStrictFusage (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalParamExec (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalParamSet (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalParamExtern (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalCoerceViaIOSafe (ExprState *state, ExprEvalStep *op)
 
void ExecEvalSQLValueFunction (ExprState *state, ExprEvalStep *op)
 
void ExecEvalCurrentOfExpr (ExprState *state, ExprEvalStep *op)
 
void ExecEvalNextValueExpr (ExprState *state, ExprEvalStep *op)
 
void ExecEvalRowNull (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalRowNotNull (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalArrayExpr (ExprState *state, ExprEvalStep *op)
 
void ExecEvalArrayCoerce (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalRow (ExprState *state, ExprEvalStep *op)
 
void ExecEvalMinMax (ExprState *state, ExprEvalStep *op)
 
void ExecEvalFieldSelect (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalFieldStoreDeForm (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalFieldStoreForm (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalConvertRowtype (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalScalarArrayOp (ExprState *state, ExprEvalStep *op)
 
void ExecEvalHashedScalarArrayOp (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalConstraintNotNull (ExprState *state, ExprEvalStep *op)
 
void ExecEvalConstraintCheck (ExprState *state, ExprEvalStep *op)
 
void ExecEvalXmlExpr (ExprState *state, ExprEvalStep *op)
 
void ExecEvalJsonConstructor (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalJsonIsPredicate (ExprState *state, ExprEvalStep *op)
 
int ExecEvalJsonExprPath (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalJsonCoercion (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalJsonCoercionFinish (ExprState *state, ExprEvalStep *op)
 
void ExecEvalGroupingFunc (ExprState *state, ExprEvalStep *op)
 
void ExecEvalMergeSupportFunc (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalSubPlan (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalWholeRowVar (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalSysVar (ExprState *state, ExprEvalStep *op, ExprContext *econtext, TupleTableSlot *slot)
 
void ExecAggInitGroup (AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup, ExprContext *aggcontext)
 
Datum ExecAggCopyTransValue (AggState *aggstate, AggStatePerTrans pertrans, Datum newValue, bool newValueIsNull, Datum oldValue, bool oldValueIsNull)
 
bool ExecEvalPreOrderedDistinctSingle (AggState *aggstate, AggStatePerTrans pertrans)
 
bool ExecEvalPreOrderedDistinctMulti (AggState *aggstate, AggStatePerTrans pertrans)
 
void ExecEvalAggOrderedTransDatum (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
void ExecEvalAggOrderedTransTuple (ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 

Macro Definition Documentation

◆ EEO_FLAG_DIRECT_THREADED

#define EEO_FLAG_DIRECT_THREADED   (1 << 2)

Definition at line 31 of file execExpr.h.

◆ EEO_FLAG_INTERPRETER_INITIALIZED

#define EEO_FLAG_INTERPRETER_INITIALIZED   (1 << 1)

Definition at line 29 of file execExpr.h.

Typedef Documentation

◆ ExecEvalBoolSubroutine

typedef bool(* ExecEvalBoolSubroutine) (ExprState *state, struct ExprEvalStep *op, ExprContext *econtext)

Definition at line 39 of file execExpr.h.

◆ ExecEvalSubroutine

typedef void(* ExecEvalSubroutine) (ExprState *state, struct ExprEvalStep *op, ExprContext *econtext)

Definition at line 34 of file execExpr.h.

◆ ExprEvalOp

typedef enum ExprEvalOp ExprEvalOp

◆ ExprEvalRowtypeCache

◆ ExprEvalStep

typedef struct ExprEvalStep ExprEvalStep

◆ JsonConstructorExprState

◆ SubscriptExecSteps

◆ SubscriptingRefState

Enumeration Type Documentation

◆ ExprEvalOp

enum ExprEvalOp
Enumerator
EEOP_DONE 
EEOP_INNER_FETCHSOME 
EEOP_OUTER_FETCHSOME 
EEOP_SCAN_FETCHSOME 
EEOP_INNER_VAR 
EEOP_OUTER_VAR 
EEOP_SCAN_VAR 
EEOP_INNER_SYSVAR 
EEOP_OUTER_SYSVAR 
EEOP_SCAN_SYSVAR 
EEOP_WHOLEROW 
EEOP_ASSIGN_INNER_VAR 
EEOP_ASSIGN_OUTER_VAR 
EEOP_ASSIGN_SCAN_VAR 
EEOP_ASSIGN_TMP 
EEOP_ASSIGN_TMP_MAKE_RO 
EEOP_CONST 
EEOP_FUNCEXPR 
EEOP_FUNCEXPR_STRICT 
EEOP_FUNCEXPR_FUSAGE 
EEOP_FUNCEXPR_STRICT_FUSAGE 
EEOP_BOOL_AND_STEP_FIRST 
EEOP_BOOL_AND_STEP 
EEOP_BOOL_AND_STEP_LAST 
EEOP_BOOL_OR_STEP_FIRST 
EEOP_BOOL_OR_STEP 
EEOP_BOOL_OR_STEP_LAST 
EEOP_BOOL_NOT_STEP 
EEOP_QUAL 
EEOP_JUMP 
EEOP_JUMP_IF_NULL 
EEOP_JUMP_IF_NOT_NULL 
EEOP_JUMP_IF_NOT_TRUE 
EEOP_NULLTEST_ISNULL 
EEOP_NULLTEST_ISNOTNULL 
EEOP_NULLTEST_ROWISNULL 
EEOP_NULLTEST_ROWISNOTNULL 
EEOP_BOOLTEST_IS_TRUE 
EEOP_BOOLTEST_IS_NOT_TRUE 
EEOP_BOOLTEST_IS_FALSE 
EEOP_BOOLTEST_IS_NOT_FALSE 
EEOP_PARAM_EXEC 
EEOP_PARAM_EXTERN 
EEOP_PARAM_CALLBACK 
EEOP_PARAM_SET 
EEOP_CASE_TESTVAL 
EEOP_MAKE_READONLY 
EEOP_IOCOERCE 
EEOP_IOCOERCE_SAFE 
EEOP_DISTINCT 
EEOP_NOT_DISTINCT 
EEOP_NULLIF 
EEOP_SQLVALUEFUNCTION 
EEOP_CURRENTOFEXPR 
EEOP_NEXTVALUEEXPR 
EEOP_ARRAYEXPR 
EEOP_ARRAYCOERCE 
EEOP_ROW 
EEOP_ROWCOMPARE_STEP 
EEOP_ROWCOMPARE_FINAL 
EEOP_MINMAX 
EEOP_FIELDSELECT 
EEOP_FIELDSTORE_DEFORM 
EEOP_FIELDSTORE_FORM 
EEOP_SBSREF_SUBSCRIPTS 
EEOP_SBSREF_OLD 
EEOP_SBSREF_ASSIGN 
EEOP_SBSREF_FETCH 
EEOP_DOMAIN_TESTVAL 
EEOP_DOMAIN_NOTNULL 
EEOP_DOMAIN_CHECK 
EEOP_HASHDATUM_SET_INITVAL 
EEOP_HASHDATUM_FIRST 
EEOP_HASHDATUM_FIRST_STRICT 
EEOP_HASHDATUM_NEXT32 
EEOP_HASHDATUM_NEXT32_STRICT 
EEOP_CONVERT_ROWTYPE 
EEOP_SCALARARRAYOP 
EEOP_HASHED_SCALARARRAYOP 
EEOP_XMLEXPR 
EEOP_JSON_CONSTRUCTOR 
EEOP_IS_JSON 
EEOP_JSONEXPR_PATH 
EEOP_JSONEXPR_COERCION 
EEOP_JSONEXPR_COERCION_FINISH 
EEOP_AGGREF 
EEOP_GROUPING_FUNC 
EEOP_WINDOW_FUNC 
EEOP_MERGE_SUPPORT_FUNC 
EEOP_SUBPLAN 
EEOP_AGG_STRICT_DESERIALIZE 
EEOP_AGG_DESERIALIZE 
EEOP_AGG_STRICT_INPUT_CHECK_ARGS 
EEOP_AGG_STRICT_INPUT_CHECK_NULLS 
EEOP_AGG_PLAIN_PERGROUP_NULLCHECK 
EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL 
EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL 
EEOP_AGG_PLAIN_TRANS_BYVAL 
EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF 
EEOP_AGG_PLAIN_TRANS_STRICT_BYREF 
EEOP_AGG_PLAIN_TRANS_BYREF 
EEOP_AGG_PRESORTED_DISTINCT_SINGLE 
EEOP_AGG_PRESORTED_DISTINCT_MULTI 
EEOP_AGG_ORDERED_TRANS_DATUM 
EEOP_AGG_ORDERED_TRANS_TUPLE 
EEOP_LAST 

Definition at line 66 of file execExpr.h.

67 {
68  /* entire expression has been evaluated completely, return */
69  EEOP_DONE,
70 
71  /* apply slot_getsomeattrs on corresponding tuple slot */
75 
76  /* compute non-system Var value */
80 
81  /* compute system Var value */
85 
86  /* compute wholerow Var */
88 
89  /*
90  * Compute non-system Var value, assign it into ExprState's resultslot.
91  * These are not used if a CheckVarSlotCompatibility() check would be
92  * needed.
93  */
97 
98  /* assign ExprState's resvalue/resnull to a column of its resultslot */
100  /* ditto, applying MakeExpandedObjectReadOnly() */
102 
103  /* evaluate Const value */
104  EEOP_CONST,
105 
106  /*
107  * Evaluate function call (including OpExprs etc). For speed, we
108  * distinguish in the opcode whether the function is strict and/or
109  * requires usage stats tracking.
110  */
115 
116  /*
117  * Evaluate boolean AND expression, one step per subexpression. FIRST/LAST
118  * subexpressions are special-cased for performance. Since AND always has
119  * at least two subexpressions, FIRST and LAST never apply to the same
120  * subexpression.
121  */
125 
126  /* similarly for boolean OR expression */
130 
131  /* evaluate boolean NOT expression */
133 
134  /* simplified version of BOOL_AND_STEP for use by ExecQual() */
135  EEOP_QUAL,
136 
137  /* unconditional jump to another step */
138  EEOP_JUMP,
139 
140  /* conditional jumps based on current result value */
144 
145  /* perform NULL tests for scalar values */
148 
149  /* perform NULL tests for row values */
152 
153  /* evaluate a BooleanTest expression */
158 
159  /* evaluate PARAM_EXEC/EXTERN parameters */
163  /* set PARAM_EXEC value */
165 
166  /* return CaseTestExpr value */
168 
169  /* apply MakeExpandedObjectReadOnly() to target value */
171 
172  /* evaluate assorted special-purpose expression types */
177  EEOP_NULLIF,
183  EEOP_ROW,
184 
185  /*
186  * Compare two individual elements of each of two compared ROW()
187  * expressions. Skip to ROWCOMPARE_FINAL if elements are not equal.
188  */
190 
191  /* evaluate boolean value based on previous ROWCOMPARE_STEP operations */
193 
194  /* evaluate GREATEST() or LEAST() */
195  EEOP_MINMAX,
196 
197  /* evaluate FieldSelect expression */
199 
200  /*
201  * Deform tuple before evaluating new values for individual fields in a
202  * FieldStore expression.
203  */
205 
206  /*
207  * Form the new tuple for a FieldStore expression. Individual fields will
208  * have been evaluated into columns of the tuple deformed by the preceding
209  * DEFORM step.
210  */
212 
213  /* Process container subscripts; possibly short-circuit result to NULL */
215 
216  /*
217  * Compute old container element/slice when a SubscriptingRef assignment
218  * expression contains SubscriptingRef/FieldStore subexpressions. Value is
219  * accessed using the CaseTest mechanism.
220  */
222 
223  /* compute new value for SubscriptingRef assignment expression */
225 
226  /* compute element/slice for SubscriptingRef fetch expression */
228 
229  /* evaluate value for CoerceToDomainValue */
231 
232  /* evaluate a domain's NOT NULL constraint */
234 
235  /* evaluate a single domain CHECK constraint */
237 
238  /* evaluation steps for hashing */
244 
245  /* evaluate assorted special-purpose expression types */
249  EEOP_XMLEXPR,
251  EEOP_IS_JSON,
255  EEOP_AGGREF,
259  EEOP_SUBPLAN,
260 
261  /* aggregation related nodes */
277 
278  /* non-existent operation, used e.g. to check array lengths */
279  EEOP_LAST
280 } ExprEvalOp;
ExprEvalOp
Definition: execExpr.h:67
@ EEOP_ASSIGN_TMP
Definition: execExpr.h:99
@ EEOP_SUBPLAN
Definition: execExpr.h:259
@ EEOP_CONVERT_ROWTYPE
Definition: execExpr.h:246
@ EEOP_FUNCEXPR_STRICT_FUSAGE
Definition: execExpr.h:114
@ EEOP_ARRAYEXPR
Definition: execExpr.h:181
@ EEOP_JSONEXPR_PATH
Definition: execExpr.h:252
@ EEOP_NOT_DISTINCT
Definition: execExpr.h:176
@ EEOP_DOMAIN_TESTVAL
Definition: execExpr.h:230
@ EEOP_PARAM_EXTERN
Definition: execExpr.h:161
@ EEOP_HASHDATUM_NEXT32_STRICT
Definition: execExpr.h:243
@ EEOP_IOCOERCE_SAFE
Definition: execExpr.h:174
@ EEOP_BOOL_AND_STEP
Definition: execExpr.h:123
@ EEOP_WHOLEROW
Definition: execExpr.h:87
@ EEOP_JSONEXPR_COERCION_FINISH
Definition: execExpr.h:254
@ EEOP_HASHDATUM_FIRST_STRICT
Definition: execExpr.h:241
@ EEOP_AGGREF
Definition: execExpr.h:255
@ EEOP_INNER_VAR
Definition: execExpr.h:77
@ EEOP_AGG_PLAIN_PERGROUP_NULLCHECK
Definition: execExpr.h:266
@ EEOP_HASHDATUM_NEXT32
Definition: execExpr.h:242
@ EEOP_ROWCOMPARE_FINAL
Definition: execExpr.h:192
@ EEOP_AGG_STRICT_DESERIALIZE
Definition: execExpr.h:262
@ EEOP_IOCOERCE
Definition: execExpr.h:173
@ EEOP_GROUPING_FUNC
Definition: execExpr.h:256
@ EEOP_DOMAIN_CHECK
Definition: execExpr.h:236
@ EEOP_BOOLTEST_IS_NOT_FALSE
Definition: execExpr.h:157
@ EEOP_PARAM_SET
Definition: execExpr.h:164
@ EEOP_NEXTVALUEEXPR
Definition: execExpr.h:180
@ EEOP_DONE
Definition: execExpr.h:69
@ EEOP_AGG_PLAIN_TRANS_BYREF
Definition: execExpr.h:272
@ EEOP_QUAL
Definition: execExpr.h:135
@ EEOP_AGG_PRESORTED_DISTINCT_MULTI
Definition: execExpr.h:274
@ EEOP_AGG_PLAIN_TRANS_BYVAL
Definition: execExpr.h:269
@ EEOP_SCAN_VAR
Definition: execExpr.h:79
@ EEOP_BOOL_NOT_STEP
Definition: execExpr.h:132
@ EEOP_ASSIGN_SCAN_VAR
Definition: execExpr.h:96
@ EEOP_SCAN_SYSVAR
Definition: execExpr.h:84
@ EEOP_SCALARARRAYOP
Definition: execExpr.h:247
@ EEOP_DOMAIN_NOTNULL
Definition: execExpr.h:233
@ EEOP_WINDOW_FUNC
Definition: execExpr.h:257
@ EEOP_INNER_FETCHSOME
Definition: execExpr.h:72
@ EEOP_NULLTEST_ROWISNOTNULL
Definition: execExpr.h:151
@ EEOP_ASSIGN_OUTER_VAR
Definition: execExpr.h:95
@ EEOP_ROW
Definition: execExpr.h:183
@ EEOP_MAKE_READONLY
Definition: execExpr.h:170
@ EEOP_FIELDSTORE_FORM
Definition: execExpr.h:211
@ EEOP_SBSREF_SUBSCRIPTS
Definition: execExpr.h:214
@ EEOP_SBSREF_FETCH
Definition: execExpr.h:227
@ EEOP_FUNCEXPR_STRICT
Definition: execExpr.h:112
@ EEOP_NULLIF
Definition: execExpr.h:177
@ EEOP_CURRENTOFEXPR
Definition: execExpr.h:179
@ EEOP_INNER_SYSVAR
Definition: execExpr.h:82
@ EEOP_ASSIGN_TMP_MAKE_RO
Definition: execExpr.h:101
@ EEOP_CONST
Definition: execExpr.h:104
@ EEOP_BOOL_OR_STEP_LAST
Definition: execExpr.h:129
@ EEOP_JSONEXPR_COERCION
Definition: execExpr.h:253
@ EEOP_BOOL_OR_STEP_FIRST
Definition: execExpr.h:127
@ EEOP_XMLEXPR
Definition: execExpr.h:249
@ EEOP_AGG_STRICT_INPUT_CHECK_NULLS
Definition: execExpr.h:265
@ EEOP_SBSREF_ASSIGN
Definition: execExpr.h:224
@ EEOP_OUTER_SYSVAR
Definition: execExpr.h:83
@ EEOP_ASSIGN_INNER_VAR
Definition: execExpr.h:94
@ EEOP_BOOL_OR_STEP
Definition: execExpr.h:128
@ EEOP_OUTER_FETCHSOME
Definition: execExpr.h:73
@ EEOP_AGG_STRICT_INPUT_CHECK_ARGS
Definition: execExpr.h:264
@ EEOP_NULLTEST_ROWISNULL
Definition: execExpr.h:150
@ EEOP_BOOLTEST_IS_TRUE
Definition: execExpr.h:154
@ EEOP_FUNCEXPR
Definition: execExpr.h:111
@ EEOP_NULLTEST_ISNOTNULL
Definition: execExpr.h:147
@ EEOP_ROWCOMPARE_STEP
Definition: execExpr.h:189
@ EEOP_MERGE_SUPPORT_FUNC
Definition: execExpr.h:258
@ EEOP_AGG_DESERIALIZE
Definition: execExpr.h:263
@ EEOP_LAST
Definition: execExpr.h:279
@ EEOP_HASHDATUM_FIRST
Definition: execExpr.h:240
@ EEOP_DISTINCT
Definition: execExpr.h:175
@ EEOP_JUMP_IF_NOT_TRUE
Definition: execExpr.h:143
@ EEOP_FUNCEXPR_FUSAGE
Definition: execExpr.h:113
@ EEOP_AGG_PRESORTED_DISTINCT_SINGLE
Definition: execExpr.h:273
@ EEOP_BOOL_AND_STEP_FIRST
Definition: execExpr.h:122
@ EEOP_JUMP
Definition: execExpr.h:138
@ EEOP_PARAM_CALLBACK
Definition: execExpr.h:162
@ EEOP_BOOL_AND_STEP_LAST
Definition: execExpr.h:124
@ EEOP_AGG_ORDERED_TRANS_DATUM
Definition: execExpr.h:275
@ EEOP_SBSREF_OLD
Definition: execExpr.h:221
@ EEOP_SQLVALUEFUNCTION
Definition: execExpr.h:178
@ EEOP_HASHDATUM_SET_INITVAL
Definition: execExpr.h:239
@ EEOP_JUMP_IF_NOT_NULL
Definition: execExpr.h:142
@ EEOP_AGG_PLAIN_TRANS_STRICT_BYREF
Definition: execExpr.h:271
@ EEOP_FIELDSTORE_DEFORM
Definition: execExpr.h:204
@ EEOP_BOOLTEST_IS_FALSE
Definition: execExpr.h:156
@ EEOP_BOOLTEST_IS_NOT_TRUE
Definition: execExpr.h:155
@ EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL
Definition: execExpr.h:267
@ EEOP_PARAM_EXEC
Definition: execExpr.h:160
@ EEOP_JSON_CONSTRUCTOR
Definition: execExpr.h:250
@ EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL
Definition: execExpr.h:268
@ EEOP_NULLTEST_ISNULL
Definition: execExpr.h:146
@ EEOP_MINMAX
Definition: execExpr.h:195
@ EEOP_JUMP_IF_NULL
Definition: execExpr.h:141
@ EEOP_ARRAYCOERCE
Definition: execExpr.h:182
@ EEOP_FIELDSELECT
Definition: execExpr.h:198
@ EEOP_CASE_TESTVAL
Definition: execExpr.h:167
@ EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF
Definition: execExpr.h:270
@ EEOP_HASHED_SCALARARRAYOP
Definition: execExpr.h:248
@ EEOP_OUTER_VAR
Definition: execExpr.h:78
@ EEOP_AGG_ORDERED_TRANS_TUPLE
Definition: execExpr.h:276
@ EEOP_SCAN_FETCHSOME
Definition: execExpr.h:74
@ EEOP_IS_JSON
Definition: execExpr.h:251

Function Documentation

◆ CheckExprStillValid()

void CheckExprStillValid ( ExprState state,
ExprContext econtext 
)

Definition at line 2055 of file execExprInterp.c.

2056 {
2057  TupleTableSlot *innerslot;
2058  TupleTableSlot *outerslot;
2059  TupleTableSlot *scanslot;
2060 
2061  innerslot = econtext->ecxt_innertuple;
2062  outerslot = econtext->ecxt_outertuple;
2063  scanslot = econtext->ecxt_scantuple;
2064 
2065  for (int i = 0; i < state->steps_len; i++)
2066  {
2067  ExprEvalStep *op = &state->steps[i];
2068 
2069  switch (ExecEvalStepOp(state, op))
2070  {
2071  case EEOP_INNER_VAR:
2072  {
2073  int attnum = op->d.var.attnum;
2074 
2075  CheckVarSlotCompatibility(innerslot, attnum + 1, op->d.var.vartype);
2076  break;
2077  }
2078 
2079  case EEOP_OUTER_VAR:
2080  {
2081  int attnum = op->d.var.attnum;
2082 
2083  CheckVarSlotCompatibility(outerslot, attnum + 1, op->d.var.vartype);
2084  break;
2085  }
2086 
2087  case EEOP_SCAN_VAR:
2088  {
2089  int attnum = op->d.var.attnum;
2090 
2091  CheckVarSlotCompatibility(scanslot, attnum + 1, op->d.var.vartype);
2092  break;
2093  }
2094  default:
2095  break;
2096  }
2097  }
2098 }
static void CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype)
ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op)
int i
Definition: isn.c:72
int16 attnum
Definition: pg_attribute.h:74
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:260
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:258
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:262
struct ExprEvalStep::@55::@57 var
union ExprEvalStep::@55 d
Definition: regguts.h:323

References attnum, CheckVarSlotCompatibility(), ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_scantuple, EEOP_INNER_VAR, EEOP_OUTER_VAR, EEOP_SCAN_VAR, ExecEvalStepOp(), i, and ExprEvalStep::op.

Referenced by ExecInterpExprStillValid(), and ExecRunCompiledExpr().

◆ ExecAggCopyTransValue()

Datum ExecAggCopyTransValue ( AggState aggstate,
AggStatePerTrans  pertrans,
Datum  newValue,
bool  newValueIsNull,
Datum  oldValue,
bool  oldValueIsNull 
)

Definition at line 5209 of file execExprInterp.c.

5212 {
5213  Assert(newValue != oldValue);
5214 
5215  if (!newValueIsNull)
5216  {
5218  if (DatumIsReadWriteExpandedObject(newValue,
5219  false,
5220  pertrans->transtypeLen) &&
5221  MemoryContextGetParent(DatumGetEOHP(newValue)->eoh_context) == CurrentMemoryContext)
5222  /* do nothing */ ;
5223  else
5224  newValue = datumCopy(newValue,
5225  pertrans->transtypeByVal,
5226  pertrans->transtypeLen);
5227  }
5228  else
5229  {
5230  /*
5231  * Ensure that AggStatePerGroup->transValue ends up being 0, so
5232  * callers can safely compare newValue/oldValue without having to
5233  * check their respective nullness.
5234  */
5235  newValue = (Datum) 0;
5236  }
5237 
5238  if (!oldValueIsNull)
5239  {
5240  if (DatumIsReadWriteExpandedObject(oldValue,
5241  false,
5242  pertrans->transtypeLen))
5243  DeleteExpandedObject(oldValue);
5244  else
5245  pfree(DatumGetPointer(oldValue));
5246  }
5247 
5248  return newValue;
5249 }
#define Assert(condition)
Definition: c.h:837
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
void DeleteExpandedObject(Datum d)
#define DatumIsReadWriteExpandedObject(d, isnull, typlen)
void pfree(void *pointer)
Definition: mcxt.c:1521
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
MemoryContext MemoryContextGetParent(MemoryContext context)
Definition: mcxt.c:731
uintptr_t Datum
Definition: postgres.h:64
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
MemoryContextSwitchTo(old_ctx)
ExprContext * curaggcontext
Definition: execnodes.h:2512
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:266

References Assert, AggState::curaggcontext, CurrentMemoryContext, datumCopy(), DatumGetEOHP(), DatumGetPointer(), DatumIsReadWriteExpandedObject, DeleteExpandedObject(), ExprContext::ecxt_per_tuple_memory, MemoryContextGetParent(), MemoryContextSwitchTo(), ExprEvalStep::pertrans, pfree(), AggStatePerTransData::transtypeByVal, and AggStatePerTransData::transtypeLen.

Referenced by advance_transition_function(), and ExecAggPlainTransByRef().

◆ ExecAggInitGroup()

void ExecAggInitGroup ( AggState aggstate,
AggStatePerTrans  pertrans,
AggStatePerGroup  pergroup,
ExprContext aggcontext 
)

Definition at line 5156 of file execExprInterp.c.

5158 {
5159  FunctionCallInfo fcinfo = pertrans->transfn_fcinfo;
5160  MemoryContext oldContext;
5161 
5162  /*
5163  * We must copy the datum into aggcontext if it is pass-by-ref. We do not
5164  * need to pfree the old transValue, since it's NULL. (We already checked
5165  * that the agg's input type is binary-compatible with its transtype, so
5166  * straight copy here is OK.)
5167  */
5168  oldContext = MemoryContextSwitchTo(aggcontext->ecxt_per_tuple_memory);
5169  pergroup->transValue = datumCopy(fcinfo->args[1].value,
5170  pertrans->transtypeByVal,
5171  pertrans->transtypeLen);
5172  pergroup->transValueIsNull = false;
5173  pergroup->noTransValue = false;
5174  MemoryContextSwitchTo(oldContext);
5175 }
FunctionCallInfo transfn_fcinfo
Definition: nodeAgg.h:170
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition: fmgr.h:95
Datum value
Definition: postgres.h:75

References ExprEvalStep::aggcontext, FunctionCallInfoBaseData::args, datumCopy(), ExprContext::ecxt_per_tuple_memory, MemoryContextSwitchTo(), AggStatePerGroupData::noTransValue, ExprEvalStep::pertrans, AggStatePerTransData::transfn_fcinfo, AggStatePerTransData::transtypeByVal, AggStatePerTransData::transtypeLen, AggStatePerGroupData::transValue, AggStatePerGroupData::transValueIsNull, and NullableDatum::value.

Referenced by ExecInterpExpr().

◆ ExecEvalAggOrderedTransDatum()

void ExecEvalAggOrderedTransDatum ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 5348 of file execExprInterp.c.

5350 {
5351  AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
5352  int setno = op->d.agg_trans.setno;
5353 
5354  tuplesort_putdatum(pertrans->sortstates[setno],
5355  *op->resvalue, *op->resnull);
5356 }
Tuplesortstate ** sortstates
Definition: nodeAgg.h:162
struct ExprEvalStep::@55::@100 agg_trans
Datum * resvalue
Definition: execExpr.h:293
bool * resnull
Definition: execExpr.h:294
void tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)

References ExprEvalStep::op, ExprEvalStep::pertrans, ExprEvalStep::setno, AggStatePerTransData::sortstates, and tuplesort_putdatum().

Referenced by ExecInterpExpr().

◆ ExecEvalAggOrderedTransTuple()

void ExecEvalAggOrderedTransTuple ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 5362 of file execExprInterp.c.

5364 {
5365  AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
5366  int setno = op->d.agg_trans.setno;
5367 
5368  ExecClearTuple(pertrans->sortslot);
5369  pertrans->sortslot->tts_nvalid = pertrans->numInputs;
5370  ExecStoreVirtualTuple(pertrans->sortslot);
5371  tuplesort_puttupleslot(pertrans->sortstates[setno], pertrans->sortslot);
5372 }
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1639
TupleTableSlot * sortslot
Definition: nodeAgg.h:141
AttrNumber tts_nvalid
Definition: tuptable.h:120
void tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:454

References ExecClearTuple(), ExecStoreVirtualTuple(), AggStatePerTransData::numInputs, ExprEvalStep::op, ExprEvalStep::pertrans, ExprEvalStep::setno, AggStatePerTransData::sortslot, AggStatePerTransData::sortstates, TupleTableSlot::tts_nvalid, and tuplesort_puttupleslot().

Referenced by ExecInterpExpr().

◆ ExecEvalArrayCoerce()

void ExecEvalArrayCoerce ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 3197 of file execExprInterp.c.

3198 {
3199  Datum arraydatum;
3200 
3201  /* NULL array -> NULL result */
3202  if (*op->resnull)
3203  return;
3204 
3205  arraydatum = *op->resvalue;
3206 
3207  /*
3208  * If it's binary-compatible, modify the element type in the array header,
3209  * but otherwise leave the array as we received it.
3210  */
3211  if (op->d.arraycoerce.elemexprstate == NULL)
3212  {
3213  /* Detoast input array if necessary, and copy in any case */
3214  ArrayType *array = DatumGetArrayTypePCopy(arraydatum);
3215 
3216  ARR_ELEMTYPE(array) = op->d.arraycoerce.resultelemtype;
3217  *op->resvalue = PointerGetDatum(array);
3218  return;
3219  }
3220 
3221  /*
3222  * Use array_map to apply the sub-expression to each array element.
3223  */
3224  *op->resvalue = array_map(arraydatum,
3225  op->d.arraycoerce.elemexprstate,
3226  econtext,
3227  op->d.arraycoerce.resultelemtype,
3228  op->d.arraycoerce.amstate);
3229 }
#define DatumGetArrayTypePCopy(X)
Definition: array.h:262
#define ARR_ELEMTYPE(a)
Definition: array.h:292
Datum array_map(Datum arrayd, ExprState *exprstate, ExprContext *econtext, Oid retType, ArrayMapState *amstate)
Definition: arrayfuncs.c:3201
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
struct ExprEvalStep::@55::@75 arraycoerce

References ARR_ELEMTYPE, array_map(), DatumGetArrayTypePCopy, ExprEvalStep::op, and PointerGetDatum().

Referenced by ExecInterpExpr().

◆ ExecEvalArrayExpr()

void ExecEvalArrayExpr ( ExprState state,
ExprEvalStep op 
)

Definition at line 2983 of file execExprInterp.c.

2984 {
2985  ArrayType *result;
2986  Oid element_type = op->d.arrayexpr.elemtype;
2987  int nelems = op->d.arrayexpr.nelems;
2988  int ndims = 0;
2989  int dims[MAXDIM];
2990  int lbs[MAXDIM];
2991 
2992  /* Set non-null as default */
2993  *op->resnull = false;
2994 
2995  if (!op->d.arrayexpr.multidims)
2996  {
2997  /* Elements are presumably of scalar type */
2998  Datum *dvalues = op->d.arrayexpr.elemvalues;
2999  bool *dnulls = op->d.arrayexpr.elemnulls;
3000 
3001  /* setup for 1-D array of the given length */
3002  ndims = 1;
3003  dims[0] = nelems;
3004  lbs[0] = 1;
3005 
3006  result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
3007  element_type,
3008  op->d.arrayexpr.elemlength,
3009  op->d.arrayexpr.elembyval,
3010  op->d.arrayexpr.elemalign);
3011  }
3012  else
3013  {
3014  /* Must be nested array expressions */
3015  int nbytes = 0;
3016  int nitems;
3017  int outer_nelems = 0;
3018  int elem_ndims = 0;
3019  int *elem_dims = NULL;
3020  int *elem_lbs = NULL;
3021  bool firstone = true;
3022  bool havenulls = false;
3023  bool haveempty = false;
3024  char **subdata;
3025  bits8 **subbitmaps;
3026  int *subbytes;
3027  int *subnitems;
3028  int32 dataoffset;
3029  char *dat;
3030  int iitem;
3031 
3032  subdata = (char **) palloc(nelems * sizeof(char *));
3033  subbitmaps = (bits8 **) palloc(nelems * sizeof(bits8 *));
3034  subbytes = (int *) palloc(nelems * sizeof(int));
3035  subnitems = (int *) palloc(nelems * sizeof(int));
3036 
3037  /* loop through and get data area from each element */
3038  for (int elemoff = 0; elemoff < nelems; elemoff++)
3039  {
3040  Datum arraydatum;
3041  bool eisnull;
3042  ArrayType *array;
3043  int this_ndims;
3044 
3045  arraydatum = op->d.arrayexpr.elemvalues[elemoff];
3046  eisnull = op->d.arrayexpr.elemnulls[elemoff];
3047 
3048  /* temporarily ignore null subarrays */
3049  if (eisnull)
3050  {
3051  haveempty = true;
3052  continue;
3053  }
3054 
3055  array = DatumGetArrayTypeP(arraydatum);
3056 
3057  /* run-time double-check on element type */
3058  if (element_type != ARR_ELEMTYPE(array))
3059  ereport(ERROR,
3060  (errcode(ERRCODE_DATATYPE_MISMATCH),
3061  errmsg("cannot merge incompatible arrays"),
3062  errdetail("Array with element type %s cannot be "
3063  "included in ARRAY construct with element type %s.",
3064  format_type_be(ARR_ELEMTYPE(array)),
3065  format_type_be(element_type))));
3066 
3067  this_ndims = ARR_NDIM(array);
3068  /* temporarily ignore zero-dimensional subarrays */
3069  if (this_ndims <= 0)
3070  {
3071  haveempty = true;
3072  continue;
3073  }
3074 
3075  if (firstone)
3076  {
3077  /* Get sub-array details from first member */
3078  elem_ndims = this_ndims;
3079  ndims = elem_ndims + 1;
3080  if (ndims <= 0 || ndims > MAXDIM)
3081  ereport(ERROR,
3082  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3083  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
3084  ndims, MAXDIM)));
3085 
3086  elem_dims = (int *) palloc(elem_ndims * sizeof(int));
3087  memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
3088  elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
3089  memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
3090 
3091  firstone = false;
3092  }
3093  else
3094  {
3095  /* Check other sub-arrays are compatible */
3096  if (elem_ndims != this_ndims ||
3097  memcmp(elem_dims, ARR_DIMS(array),
3098  elem_ndims * sizeof(int)) != 0 ||
3099  memcmp(elem_lbs, ARR_LBOUND(array),
3100  elem_ndims * sizeof(int)) != 0)
3101  ereport(ERROR,
3102  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3103  errmsg("multidimensional arrays must have array "
3104  "expressions with matching dimensions")));
3105  }
3106 
3107  subdata[outer_nelems] = ARR_DATA_PTR(array);
3108  subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
3109  subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
3110  nbytes += subbytes[outer_nelems];
3111  /* check for overflow of total request */
3112  if (!AllocSizeIsValid(nbytes))
3113  ereport(ERROR,
3114  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3115  errmsg("array size exceeds the maximum allowed (%d)",
3116  (int) MaxAllocSize)));
3117  subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
3118  ARR_DIMS(array));
3119  havenulls |= ARR_HASNULL(array);
3120  outer_nelems++;
3121  }
3122 
3123  /*
3124  * If all items were null or empty arrays, return an empty array;
3125  * otherwise, if some were and some weren't, raise error. (Note: we
3126  * must special-case this somehow to avoid trying to generate a 1-D
3127  * array formed from empty arrays. It's not ideal...)
3128  */
3129  if (haveempty)
3130  {
3131  if (ndims == 0) /* didn't find any nonempty array */
3132  {
3133  *op->resvalue = PointerGetDatum(construct_empty_array(element_type));
3134  return;
3135  }
3136  ereport(ERROR,
3137  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3138  errmsg("multidimensional arrays must have array "
3139  "expressions with matching dimensions")));
3140  }
3141 
3142  /* setup for multi-D array */
3143  dims[0] = outer_nelems;
3144  lbs[0] = 1;
3145  for (int i = 1; i < ndims; i++)
3146  {
3147  dims[i] = elem_dims[i - 1];
3148  lbs[i] = elem_lbs[i - 1];
3149  }
3150 
3151  /* check for subscript overflow */
3152  nitems = ArrayGetNItems(ndims, dims);
3153  ArrayCheckBounds(ndims, dims, lbs);
3154 
3155  if (havenulls)
3156  {
3157  dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
3158  nbytes += dataoffset;
3159  }
3160  else
3161  {
3162  dataoffset = 0; /* marker for no null bitmap */
3163  nbytes += ARR_OVERHEAD_NONULLS(ndims);
3164  }
3165 
3166  result = (ArrayType *) palloc0(nbytes);
3167  SET_VARSIZE(result, nbytes);
3168  result->ndim = ndims;
3169  result->dataoffset = dataoffset;
3170  result->elemtype = element_type;
3171  memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
3172  memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
3173 
3174  dat = ARR_DATA_PTR(result);
3175  iitem = 0;
3176  for (int i = 0; i < outer_nelems; i++)
3177  {
3178  memcpy(dat, subdata[i], subbytes[i]);
3179  dat += subbytes[i];
3180  if (havenulls)
3181  array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
3182  subbitmaps[i], 0,
3183  subnitems[i]);
3184  iitem += subnitems[i];
3185  }
3186  }
3187 
3188  *op->resvalue = PointerGetDatum(result);
3189 }
#define ARR_NDIM(a)
Definition: array.h:290
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define MAXDIM
Definition: array.h:75
#define ARR_NULLBITMAP(a)
Definition: array.h:300
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
Definition: array.h:312
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_SIZE(a)
Definition: array.h:289
#define ARR_OVERHEAD_NONULLS(ndims)
Definition: array.h:310
#define ARR_DATA_OFFSET(a)
Definition: array.h:316
#define ARR_DIMS(a)
Definition: array.h:294
#define ARR_HASNULL(a)
Definition: array.h:291
#define ARR_LBOUND(a)
Definition: array.h:296
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3580
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3494
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
Definition: arrayfuncs.c:4966
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
void ArrayCheckBounds(int ndim, const int *dims, const int *lb)
Definition: arrayutils.c:117
signed int int32
Definition: c.h:482
uint8 bits8
Definition: c.h:498
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define MaxAllocSize
Definition: fe_memutils.h:22
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
#define nitems(x)
Definition: indent.h:31
void * palloc0(Size size)
Definition: mcxt.c:1347
void * palloc(Size size)
Definition: mcxt.c:1317
#define AllocSizeIsValid(size)
Definition: memutils.h:42
unsigned int Oid
Definition: postgres_ext.h:31
Oid elemtype
Definition: array.h:97
int ndim
Definition: array.h:95
int32 dataoffset
Definition: array.h:96
struct ExprEvalStep::@55::@74 arrayexpr
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

References AllocSizeIsValid, ARR_DATA_OFFSET, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, ARR_SIZE, array_bitmap_copy(), ArrayCheckBounds(), ArrayGetNItems(), construct_empty_array(), construct_md_array(), ArrayType::dataoffset, DatumGetArrayTypeP, ExprEvalStep::element_type, ArrayType::elemtype, ereport, errcode(), errdetail(), errmsg(), ERROR, format_type_be(), i, MaxAllocSize, MAXDIM, ArrayType::ndim, ExprEvalStep::nelems, nitems, ExprEvalStep::op, palloc(), palloc0(), PointerGetDatum(), and SET_VARSIZE.

Referenced by ExecInterpExpr().

◆ ExecEvalCoerceViaIOSafe()

void ExecEvalCoerceViaIOSafe ( ExprState state,
ExprEvalStep op 
)

Definition at line 2717 of file execExprInterp.c.

2718 {
2719  char *str;
2720 
2721  /* call output function (similar to OutputFunctionCall) */
2722  if (*op->resnull)
2723  {
2724  /* output functions are not called on nulls */
2725  str = NULL;
2726  }
2727  else
2728  {
2729  FunctionCallInfo fcinfo_out;
2730 
2731  fcinfo_out = op->d.iocoerce.fcinfo_data_out;
2732  fcinfo_out->args[0].value = *op->resvalue;
2733  fcinfo_out->args[0].isnull = false;
2734 
2735  fcinfo_out->isnull = false;
2736  str = DatumGetCString(FunctionCallInvoke(fcinfo_out));
2737 
2738  /* OutputFunctionCall assumes result isn't null */
2739  Assert(!fcinfo_out->isnull);
2740  }
2741 
2742  /* call input function (similar to InputFunctionCallSafe) */
2743  if (!op->d.iocoerce.finfo_in->fn_strict || str != NULL)
2744  {
2745  FunctionCallInfo fcinfo_in;
2746 
2747  fcinfo_in = op->d.iocoerce.fcinfo_data_in;
2748  fcinfo_in->args[0].value = PointerGetDatum(str);
2749  fcinfo_in->args[0].isnull = *op->resnull;
2750  /* second and third arguments are already set up */
2751 
2752  /* ErrorSaveContext must be present. */
2753  Assert(IsA(fcinfo_in->context, ErrorSaveContext));
2754 
2755  fcinfo_in->isnull = false;
2756  *op->resvalue = FunctionCallInvoke(fcinfo_in);
2757 
2758  if (SOFT_ERROR_OCCURRED(fcinfo_in->context))
2759  {
2760  *op->resnull = true;
2761  *op->resvalue = (Datum) 0;
2762  return;
2763  }
2764 
2765  /* Should get null result if and only if str is NULL */
2766  if (str == NULL)
2767  Assert(*op->resnull);
2768  else
2769  Assert(!*op->resnull);
2770  }
2771 }
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:172
const char * str
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:53
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
struct ExprEvalStep::@55::@71 iocoerce
fmNodePtr context
Definition: fmgr.h:88
bool isnull
Definition: postgres.h:77

References FunctionCallInfoBaseData::args, Assert, FunctionCallInfoBaseData::context, DatumGetCString(), FunctionCallInvoke, IsA, FunctionCallInfoBaseData::isnull, NullableDatum::isnull, ExprEvalStep::op, PointerGetDatum(), SOFT_ERROR_OCCURRED, str, and NullableDatum::value.

Referenced by ExecInterpExpr().

◆ ExecEvalConstraintCheck()

void ExecEvalConstraintCheck ( ExprState state,
ExprEvalStep op 
)

Definition at line 4004 of file execExprInterp.c.

4005 {
4006  if (!*op->d.domaincheck.checknull &&
4007  !DatumGetBool(*op->d.domaincheck.checkvalue))
4008  errsave((Node *) op->d.domaincheck.escontext,
4009  (errcode(ERRCODE_CHECK_VIOLATION),
4010  errmsg("value for domain %s violates check constraint \"%s\"",
4011  format_type_be(op->d.domaincheck.resulttype),
4012  op->d.domaincheck.constraintname),
4013  errdomainconstraint(op->d.domaincheck.resulttype,
4014  op->d.domaincheck.constraintname)));
4015 }
int errdomainconstraint(Oid datatypeOid, const char *conname)
Definition: domains.c:431
#define errsave(context,...)
Definition: elog.h:261
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
struct ExprEvalStep::@55::@84 domaincheck
Definition: nodes.h:129

References DatumGetBool(), errcode(), errdomainconstraint(), errmsg(), errsave, format_type_be(), and ExprEvalStep::op.

Referenced by ExecInterpExpr().

◆ ExecEvalConstraintNotNull()

void ExecEvalConstraintNotNull ( ExprState state,
ExprEvalStep op 
)

Definition at line 3990 of file execExprInterp.c.

3991 {
3992  if (*op->resnull)
3993  errsave((Node *) op->d.domaincheck.escontext,
3994  (errcode(ERRCODE_NOT_NULL_VIOLATION),
3995  errmsg("domain %s does not allow null values",
3996  format_type_be(op->d.domaincheck.resulttype)),
3997  errdatatype(op->d.domaincheck.resulttype)));
3998 }
int errdatatype(Oid datatypeOid)
Definition: domains.c:407

References errcode(), errdatatype(), errmsg(), errsave, format_type_be(), and ExprEvalStep::op.

Referenced by ExecInterpExpr().

◆ ExecEvalConvertRowtype()

void ExecEvalConvertRowtype ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 3510 of file execExprInterp.c.

3511 {
3512  HeapTuple result;
3513  Datum tupDatum;
3514  HeapTupleHeader tuple;
3515  HeapTupleData tmptup;
3516  TupleDesc indesc,
3517  outdesc;
3518  bool changed = false;
3519 
3520  /* NULL in -> NULL out */
3521  if (*op->resnull)
3522  return;
3523 
3524  tupDatum = *op->resvalue;
3525  tuple = DatumGetHeapTupleHeader(tupDatum);
3526 
3527  /*
3528  * Lookup tupdescs if first time through or if type changes. We'd better
3529  * pin them since type conversion functions could do catalog lookups and
3530  * hence cause cache invalidation.
3531  */
3532  indesc = get_cached_rowtype(op->d.convert_rowtype.inputtype, -1,
3533  op->d.convert_rowtype.incache,
3534  &changed);
3535  IncrTupleDescRefCount(indesc);
3536  outdesc = get_cached_rowtype(op->d.convert_rowtype.outputtype, -1,
3537  op->d.convert_rowtype.outcache,
3538  &changed);
3539  IncrTupleDescRefCount(outdesc);
3540 
3541  /*
3542  * We used to be able to assert that incoming tuples are marked with
3543  * exactly the rowtype of indesc. However, now that ExecEvalWholeRowVar
3544  * might change the tuples' marking to plain RECORD due to inserting
3545  * aliases, we can only make this weak test:
3546  */
3547  Assert(HeapTupleHeaderGetTypeId(tuple) == indesc->tdtypeid ||
3548  HeapTupleHeaderGetTypeId(tuple) == RECORDOID);
3549 
3550  /* if first time through, or after change, initialize conversion map */
3551  if (changed)
3552  {
3553  MemoryContext old_cxt;
3554 
3555  /* allocate map in long-lived memory context */
3556  old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
3557 
3558  /* prepare map from old to new attribute numbers */
3559  op->d.convert_rowtype.map = convert_tuples_by_name(indesc, outdesc);
3560 
3561  MemoryContextSwitchTo(old_cxt);
3562  }
3563 
3564  /* Following steps need a HeapTuple not a bare HeapTupleHeader */
3565  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3566  tmptup.t_data = tuple;
3567 
3568  if (op->d.convert_rowtype.map != NULL)
3569  {
3570  /* Full conversion with attribute rearrangement needed */
3571  result = execute_attr_map_tuple(&tmptup, op->d.convert_rowtype.map);
3572  /* Result already has appropriate composite-datum header fields */
3573  *op->resvalue = HeapTupleGetDatum(result);
3574  }
3575  else
3576  {
3577  /*
3578  * The tuple is physically compatible as-is, but we need to insert the
3579  * destination rowtype OID in its composite-datum header field, so we
3580  * have to copy it anyway. heap_copy_tuple_as_datum() is convenient
3581  * for this since it will both make the physical copy and insert the
3582  * correct composite header fields. Note that we aren't expecting to
3583  * have to flatten any toasted fields: the input was a composite
3584  * datum, so it shouldn't contain any. So heap_copy_tuple_as_datum()
3585  * is overkill here, but its check for external fields is cheap.
3586  */
3587  *op->resvalue = heap_copy_tuple_as_datum(&tmptup, outdesc);
3588  }
3589 
3590  DecrTupleDescRefCount(indesc);
3591  DecrTupleDescRefCount(outdesc);
3592 }
static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod, ExprEvalRowtypeCache *rowcache, bool *changed)
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:295
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)
Definition: heaptuple.c:1080
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:456
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:450
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:265
struct ExprEvalStep::@55::@87 convert_rowtype
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
Oid tdtypeid
Definition: tupdesc.h:82
TupleConversionMap * convert_tuples_by_name(TupleDesc indesc, TupleDesc outdesc)
Definition: tupconvert.c:102
HeapTuple execute_attr_map_tuple(HeapTuple tuple, TupleConversionMap *map)
Definition: tupconvert.c:154
void DecrTupleDescRefCount(TupleDesc tupdesc)
Definition: tupdesc.c:406
void IncrTupleDescRefCount(TupleDesc tupdesc)
Definition: tupdesc.c:388

References Assert, convert_tuples_by_name(), DatumGetHeapTupleHeader, DecrTupleDescRefCount(), ExprContext::ecxt_per_query_memory, execute_attr_map_tuple(), get_cached_rowtype(), heap_copy_tuple_as_datum(), HeapTupleGetDatum(), HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, IncrTupleDescRefCount(), MemoryContextSwitchTo(), ExprEvalStep::op, HeapTupleData::t_data, HeapTupleData::t_len, and TupleDescData::tdtypeid.

Referenced by ExecInterpExpr().

◆ ExecEvalCurrentOfExpr()

void ExecEvalCurrentOfExpr ( ExprState state,
ExprEvalStep op 
)

Definition at line 2844 of file execExprInterp.c.

2845 {
2846  ereport(ERROR,
2847  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2848  errmsg("WHERE CURRENT OF is not supported for this table type")));
2849 }

References ereport, errcode(), errmsg(), and ERROR.

Referenced by ExecInterpExpr().

◆ ExecEvalFieldSelect()

void ExecEvalFieldSelect ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 3311 of file execExprInterp.c.

3312 {
3313  AttrNumber fieldnum = op->d.fieldselect.fieldnum;
3314  Datum tupDatum;
3315  HeapTupleHeader tuple;
3316  Oid tupType;
3317  int32 tupTypmod;
3318  TupleDesc tupDesc;
3319  Form_pg_attribute attr;
3320  HeapTupleData tmptup;
3321 
3322  /* NULL record -> NULL result */
3323  if (*op->resnull)
3324  return;
3325 
3326  tupDatum = *op->resvalue;
3327 
3328  /* We can special-case expanded records for speed */
3330  {
3332 
3333  Assert(erh->er_magic == ER_MAGIC);
3334 
3335  /* Extract record's TupleDesc */
3336  tupDesc = expanded_record_get_tupdesc(erh);
3337 
3338  /*
3339  * Find field's attr record. Note we don't support system columns
3340  * here: a datum tuple doesn't have valid values for most of the
3341  * interesting system columns anyway.
3342  */
3343  if (fieldnum <= 0) /* should never happen */
3344  elog(ERROR, "unsupported reference to system column %d in FieldSelect",
3345  fieldnum);
3346  if (fieldnum > tupDesc->natts) /* should never happen */
3347  elog(ERROR, "attribute number %d exceeds number of columns %d",
3348  fieldnum, tupDesc->natts);
3349  attr = TupleDescAttr(tupDesc, fieldnum - 1);
3350 
3351  /* Check for dropped column, and force a NULL result if so */
3352  if (attr->attisdropped)
3353  {
3354  *op->resnull = true;
3355  return;
3356  }
3357 
3358  /* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
3359  /* As in CheckVarSlotCompatibility, we should but can't check typmod */
3360  if (op->d.fieldselect.resulttype != attr->atttypid)
3361  ereport(ERROR,
3362  (errcode(ERRCODE_DATATYPE_MISMATCH),
3363  errmsg("attribute %d has wrong type", fieldnum),
3364  errdetail("Table has type %s, but query expects %s.",
3365  format_type_be(attr->atttypid),
3366  format_type_be(op->d.fieldselect.resulttype))));
3367 
3368  /* extract the field */
3369  *op->resvalue = expanded_record_get_field(erh, fieldnum,
3370  op->resnull);
3371  }
3372  else
3373  {
3374  /* Get the composite datum and extract its type fields */
3375  tuple = DatumGetHeapTupleHeader(tupDatum);
3376 
3377  tupType = HeapTupleHeaderGetTypeId(tuple);
3378  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3379 
3380  /* Lookup tupdesc if first time through or if type changes */
3381  tupDesc = get_cached_rowtype(tupType, tupTypmod,
3382  &op->d.fieldselect.rowcache, NULL);
3383 
3384  /*
3385  * Find field's attr record. Note we don't support system columns
3386  * here: a datum tuple doesn't have valid values for most of the
3387  * interesting system columns anyway.
3388  */
3389  if (fieldnum <= 0) /* should never happen */
3390  elog(ERROR, "unsupported reference to system column %d in FieldSelect",
3391  fieldnum);
3392  if (fieldnum > tupDesc->natts) /* should never happen */
3393  elog(ERROR, "attribute number %d exceeds number of columns %d",
3394  fieldnum, tupDesc->natts);
3395  attr = TupleDescAttr(tupDesc, fieldnum - 1);
3396 
3397  /* Check for dropped column, and force a NULL result if so */
3398  if (attr->attisdropped)
3399  {
3400  *op->resnull = true;
3401  return;
3402  }
3403 
3404  /* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
3405  /* As in CheckVarSlotCompatibility, we should but can't check typmod */
3406  if (op->d.fieldselect.resulttype != attr->atttypid)
3407  ereport(ERROR,
3408  (errcode(ERRCODE_DATATYPE_MISMATCH),
3409  errmsg("attribute %d has wrong type", fieldnum),
3410  errdetail("Table has type %s, but query expects %s.",
3411  format_type_be(attr->atttypid),
3412  format_type_be(op->d.fieldselect.resulttype))));
3413 
3414  /* heap_getattr needs a HeapTuple not a bare HeapTupleHeader */
3415  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3416  tmptup.t_data = tuple;
3417 
3418  /* extract the field */
3419  *op->resvalue = heap_getattr(&tmptup,
3420  fieldnum,
3421  tupDesc,
3422  op->resnull);
3423  }
3424 }
int16 AttrNumber
Definition: attnum.h:21
#define elog(elevel,...)
Definition: elog.h:225
static Datum expanded_record_get_field(ExpandedRecordHeader *erh, int fnumber, bool *isnull)
#define ER_MAGIC
static TupleDesc expanded_record_get_tupdesc(ExpandedRecordHeader *erh)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:466
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
struct ExprEvalStep::@55::@80 fieldselect
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: varatt.h:298

References Assert, DatumGetEOHP(), DatumGetHeapTupleHeader, DatumGetPointer(), elog, ER_MAGIC, ExpandedRecordHeader::er_magic, ereport, errcode(), errdetail(), errmsg(), ERROR, expanded_record_get_field(), expanded_record_get_tupdesc(), ExprEvalStep::fieldnum, format_type_be(), get_cached_rowtype(), heap_getattr(), HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, TupleDescData::natts, ExprEvalStep::op, HeapTupleData::t_data, HeapTupleData::t_len, TupleDescAttr, and VARATT_IS_EXTERNAL_EXPANDED.

Referenced by ExecInterpExpr().

◆ ExecEvalFieldStoreDeForm()

void ExecEvalFieldStoreDeForm ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 3436 of file execExprInterp.c.

3437 {
3438  if (*op->resnull)
3439  {
3440  /* Convert null input tuple into an all-nulls row */
3441  memset(op->d.fieldstore.nulls, true,
3442  op->d.fieldstore.ncolumns * sizeof(bool));
3443  }
3444  else
3445  {
3446  /*
3447  * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
3448  * set all the fields in the struct just in case.
3449  */
3450  Datum tupDatum = *op->resvalue;
3451  HeapTupleHeader tuphdr;
3452  HeapTupleData tmptup;
3453  TupleDesc tupDesc;
3454 
3455  tuphdr = DatumGetHeapTupleHeader(tupDatum);
3456  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
3457  ItemPointerSetInvalid(&(tmptup.t_self));
3458  tmptup.t_tableOid = InvalidOid;
3459  tmptup.t_data = tuphdr;
3460 
3461  /*
3462  * Lookup tupdesc if first time through or if type changes. Because
3463  * we don't pin the tupdesc, we must not do this lookup until after
3464  * doing DatumGetHeapTupleHeader: that could do database access while
3465  * detoasting the datum.
3466  */
3467  tupDesc = get_cached_rowtype(op->d.fieldstore.fstore->resulttype, -1,
3468  op->d.fieldstore.rowcache, NULL);
3469 
3470  /* Check that current tupdesc doesn't have more fields than allocated */
3471  if (unlikely(tupDesc->natts > op->d.fieldstore.ncolumns))
3472  elog(ERROR, "too many columns in composite type %u",
3473  op->d.fieldstore.fstore->resulttype);
3474 
3475  heap_deform_tuple(&tmptup, tupDesc,
3476  op->d.fieldstore.values,
3477  op->d.fieldstore.nulls);
3478  }
3479 }
#define unlikely(x)
Definition: c.h:326
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1345
static void ItemPointerSetInvalid(ItemPointerData *pointer)
Definition: itemptr.h:184
#define InvalidOid
Definition: postgres_ext.h:36
struct ExprEvalStep::@55::@81 fieldstore
ItemPointerData t_self
Definition: htup.h:65
Oid t_tableOid
Definition: htup.h:66

References DatumGetHeapTupleHeader, elog, ERROR, get_cached_rowtype(), heap_deform_tuple(), HeapTupleHeaderGetDatumLength, InvalidOid, ItemPointerSetInvalid(), TupleDescData::natts, ExprEvalStep::op, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, and unlikely.

Referenced by ExecInterpExpr().

◆ ExecEvalFieldStoreForm()

void ExecEvalFieldStoreForm ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 3486 of file execExprInterp.c.

3487 {
3488  TupleDesc tupDesc;
3489  HeapTuple tuple;
3490 
3491  /* Lookup tupdesc (should be valid already) */
3492  tupDesc = get_cached_rowtype(op->d.fieldstore.fstore->resulttype, -1,
3493  op->d.fieldstore.rowcache, NULL);
3494 
3495  tuple = heap_form_tuple(tupDesc,
3496  op->d.fieldstore.values,
3497  op->d.fieldstore.nulls);
3498 
3499  *op->resvalue = HeapTupleGetDatum(tuple);
3500  *op->resnull = false;
3501 }
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1116

References get_cached_rowtype(), heap_form_tuple(), HeapTupleGetDatum(), and ExprEvalStep::op.

Referenced by ExecInterpExpr().

◆ ExecEvalFuncExprFusage()

void ExecEvalFuncExprFusage ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 2572 of file execExprInterp.c.

2574 {
2575  FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
2576  PgStat_FunctionCallUsage fcusage;
2577  Datum d;
2578 
2579  pgstat_init_function_usage(fcinfo, &fcusage);
2580 
2581  fcinfo->isnull = false;
2582  d = op->d.func.fn_addr(fcinfo);
2583  *op->resvalue = d;
2584  *op->resnull = fcinfo->isnull;
2585 
2586  pgstat_end_function_usage(&fcusage, true);
2587 }
void pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)
void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
struct ExprEvalStep::@55::@62 func

References ExprEvalStep::d, FunctionCallInfoBaseData::isnull, ExprEvalStep::op, pgstat_end_function_usage(), and pgstat_init_function_usage().

Referenced by ExecInterpExpr().

◆ ExecEvalFuncExprStrictFusage()

void ExecEvalFuncExprStrictFusage ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 2593 of file execExprInterp.c.

2595 {
2596 
2597  FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
2598  PgStat_FunctionCallUsage fcusage;
2599  NullableDatum *args = fcinfo->args;
2600  int nargs = op->d.func.nargs;
2601  Datum d;
2602 
2603  /* strict function, so check for NULL args */
2604  for (int argno = 0; argno < nargs; argno++)
2605  {
2606  if (args[argno].isnull)
2607  {
2608  *op->resnull = true;
2609  return;
2610  }
2611  }
2612 
2613  pgstat_init_function_usage(fcinfo, &fcusage);
2614 
2615  fcinfo->isnull = false;
2616  d = op->d.func.fn_addr(fcinfo);
2617  *op->resvalue = d;
2618  *op->resnull = fcinfo->isnull;
2619 
2620  pgstat_end_function_usage(&fcusage, true);
2621 }

References generate_unaccent_rules::args, FunctionCallInfoBaseData::args, ExprEvalStep::d, ExprEvalStep::isnull, FunctionCallInfoBaseData::isnull, ExprEvalStep::nargs, ExprEvalStep::op, pgstat_end_function_usage(), and pgstat_init_function_usage().

Referenced by ExecInterpExpr().

◆ ExecEvalGroupingFunc()

void ExecEvalGroupingFunc ( ExprState state,
ExprEvalStep op 
)

Definition at line 4828 of file execExprInterp.c.

4829 {
4830  AggState *aggstate = castNode(AggState, state->parent);
4831  int result = 0;
4832  Bitmapset *grouped_cols = aggstate->grouped_cols;
4833  ListCell *lc;
4834 
4835  foreach(lc, op->d.grouping_func.clauses)
4836  {
4837  int attnum = lfirst_int(lc);
4838 
4839  result <<= 1;
4840 
4841  if (!bms_is_member(attnum, grouped_cols))
4842  result |= 1;
4843  }
4844 
4845  *op->resvalue = Int32GetDatum(result);
4846  *op->resnull = false;
4847 }
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:510
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
#define lfirst_int(lc)
Definition: pg_list.h:173
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
Bitmapset * grouped_cols
Definition: execnodes.h:2521
struct ExprEvalStep::@55::@93 grouping_func

References attnum, bms_is_member(), castNode, AggState::grouped_cols, Int32GetDatum(), lfirst_int, and ExprEvalStep::op.

Referenced by ExecInterpExpr().

◆ ExecEvalHashedScalarArrayOp()

void ExecEvalHashedScalarArrayOp ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 3808 of file execExprInterp.c.

3809 {
3810  ScalarArrayOpExprHashTable *elements_tab = op->d.hashedscalararrayop.elements_tab;
3811  FunctionCallInfo fcinfo = op->d.hashedscalararrayop.fcinfo_data;
3812  bool inclause = op->d.hashedscalararrayop.inclause;
3813  bool strictfunc = op->d.hashedscalararrayop.finfo->fn_strict;
3814  Datum scalar = fcinfo->args[0].value;
3815  bool scalar_isnull = fcinfo->args[0].isnull;
3816  Datum result;
3817  bool resultnull;
3818  bool hashfound;
3819 
3820  /* We don't setup a hashed scalar array op if the array const is null. */
3821  Assert(!*op->resnull);
3822 
3823  /*
3824  * If the scalar is NULL, and the function is strict, return NULL; no
3825  * point in executing the search.
3826  */
3827  if (fcinfo->args[0].isnull && strictfunc)
3828  {
3829  *op->resnull = true;
3830  return;
3831  }
3832 
3833  /* Build the hash table on first evaluation */
3834  if (elements_tab == NULL)
3835  {
3836  ScalarArrayOpExpr *saop;
3837  int16 typlen;
3838  bool typbyval;
3839  char typalign;
3840  int nitems;
3841  bool has_nulls = false;
3842  char *s;
3843  bits8 *bitmap;
3844  int bitmask;
3845  MemoryContext oldcontext;
3846  ArrayType *arr;
3847 
3848  saop = op->d.hashedscalararrayop.saop;
3849 
3850  arr = DatumGetArrayTypeP(*op->resvalue);
3851  nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
3852 
3854  &typlen,
3855  &typbyval,
3856  &typalign);
3857 
3858  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
3859 
3860  elements_tab = (ScalarArrayOpExprHashTable *)
3861  palloc0(offsetof(ScalarArrayOpExprHashTable, hash_fcinfo_data) +
3863  op->d.hashedscalararrayop.elements_tab = elements_tab;
3864  elements_tab->op = op;
3865 
3866  fmgr_info(saop->hashfuncid, &elements_tab->hash_finfo);
3867  fmgr_info_set_expr((Node *) saop, &elements_tab->hash_finfo);
3868 
3870  &elements_tab->hash_finfo,
3871  1,
3872  saop->inputcollid,
3873  NULL,
3874  NULL);
3875 
3876  /*
3877  * Create the hash table sizing it according to the number of elements
3878  * in the array. This does assume that the array has no duplicates.
3879  * If the array happens to contain many duplicate values then it'll
3880  * just mean that we sized the table a bit on the large side.
3881  */
3882  elements_tab->hashtab = saophash_create(CurrentMemoryContext, nitems,
3883  elements_tab);
3884 
3885  MemoryContextSwitchTo(oldcontext);
3886 
3887  s = (char *) ARR_DATA_PTR(arr);
3888  bitmap = ARR_NULLBITMAP(arr);
3889  bitmask = 1;
3890  for (int i = 0; i < nitems; i++)
3891  {
3892  /* Get array element, checking for NULL. */
3893  if (bitmap && (*bitmap & bitmask) == 0)
3894  {
3895  has_nulls = true;
3896  }
3897  else
3898  {
3899  Datum element;
3900 
3901  element = fetch_att(s, typbyval, typlen);
3902  s = att_addlength_pointer(s, typlen, s);
3903  s = (char *) att_align_nominal(s, typalign);
3904 
3905  saophash_insert(elements_tab->hashtab, element, &hashfound);
3906  }
3907 
3908  /* Advance bitmap pointer if any. */
3909  if (bitmap)
3910  {
3911  bitmask <<= 1;
3912  if (bitmask == 0x100)
3913  {
3914  bitmap++;
3915  bitmask = 1;
3916  }
3917  }
3918  }
3919 
3920  /*
3921  * Remember if we had any nulls so that we know if we need to execute
3922  * non-strict functions with a null lhs value if no match is found.
3923  */
3924  op->d.hashedscalararrayop.has_nulls = has_nulls;
3925  }
3926 
3927  /* Check the hash to see if we have a match. */
3928  hashfound = NULL != saophash_lookup(elements_tab->hashtab, scalar);
3929 
3930  /* the result depends on if the clause is an IN or NOT IN clause */
3931  if (inclause)
3932  result = BoolGetDatum(hashfound); /* IN */
3933  else
3934  result = BoolGetDatum(!hashfound); /* NOT IN */
3935 
3936  resultnull = false;
3937 
3938  /*
3939  * If we didn't find a match in the array, we still might need to handle
3940  * the possibility of null values. We didn't put any NULLs into the
3941  * hashtable, but instead marked if we found any when building the table
3942  * in has_nulls.
3943  */
3944  if (!hashfound && op->d.hashedscalararrayop.has_nulls)
3945  {
3946  if (strictfunc)
3947  {
3948 
3949  /*
3950  * We have nulls in the array so a non-null lhs and no match must
3951  * yield NULL.
3952  */
3953  result = (Datum) 0;
3954  resultnull = true;
3955  }
3956  else
3957  {
3958  /*
3959  * Execute function will null rhs just once.
3960  *
3961  * The hash lookup path will have scribbled on the lhs argument so
3962  * we need to set it up also (even though we entered this function
3963  * with it already set).
3964  */
3965  fcinfo->args[0].value = scalar;
3966  fcinfo->args[0].isnull = scalar_isnull;
3967  fcinfo->args[1].value = (Datum) 0;
3968  fcinfo->args[1].isnull = true;
3969 
3970  result = op->d.hashedscalararrayop.finfo->fn_addr(fcinfo);
3971  resultnull = fcinfo->isnull;
3972 
3973  /*
3974  * Reverse the result for NOT IN clauses since the above function
3975  * is the equality function and we need not-equals.
3976  */
3977  if (!inclause)
3978  result = !result;
3979  }
3980  }
3981 
3982  *op->resvalue = result;
3983  *op->resnull = resultnull;
3984 }
signed short int16
Definition: c.h:481
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:127
#define SizeForFunctionCallInfo(nargs)
Definition: fmgr.h:102
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:150
#define fmgr_info_set_expr(expr, finfo)
Definition: fmgr.h:135
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2271
char typalign
Definition: pg_type.h:176
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static chr element(struct vars *v, const chr *startp, const chr *endp)
Definition: regc_locale.c:376
struct ExprEvalStep::@55::@89 hashedscalararrayop
FunctionCallInfoBaseData hash_fcinfo_data
struct ExprEvalStep * op
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:129
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:157
static Datum fetch_att(const void *T, bool attbyval, int attlen)
Definition: tupmacs.h:52

References FunctionCallInfoBaseData::args, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, ARR_NULLBITMAP, ArrayGetNItems(), Assert, att_addlength_pointer, att_align_nominal, BoolGetDatum(), CurrentMemoryContext, DatumGetArrayTypeP, ExprContext::ecxt_per_query_memory, element(), ExprEvalStep::elements_tab, fetch_att(), fmgr_info(), fmgr_info_set_expr, get_typlenbyvalalign(), ExprEvalStep::has_nulls, ScalarArrayOpExprHashTable::hash_fcinfo_data, ScalarArrayOpExprHashTable::hash_finfo, ScalarArrayOpExprHashTable::hashtab, i, ExprEvalStep::inclause, InitFunctionCallInfoData, FunctionCallInfoBaseData::isnull, NullableDatum::isnull, MemoryContextSwitchTo(), nitems, ScalarArrayOpExprHashTable::op, ExprEvalStep::op, palloc0(), ExprEvalStep::saop, SizeForFunctionCallInfo, typalign, ExprEvalStep::typbyval, ExprEvalStep::typlen, and NullableDatum::value.

Referenced by ExecInterpExpr().

◆ ExecEvalJsonCoercion()

void ExecEvalJsonCoercion ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 4694 of file execExprInterp.c.

4696 {
4697  ErrorSaveContext *escontext = op->d.jsonexpr_coercion.escontext;
4698 
4699  /*
4700  * Prepare to call json_populate_type() to coerce the boolean result of
4701  * JSON_EXISTS_OP to the target type. If the target type is integer or a
4702  * domain over integer, call the boolean-to-integer cast function instead,
4703  * because the integer's input function (which is what
4704  * json_populate_type() calls to coerce to scalar target types) doesn't
4705  * accept boolean literals as valid input. We only have a special case
4706  * for integer and domains thereof as it seems common to use those types
4707  * for EXISTS columns in JSON_TABLE().
4708  */
4709  if (op->d.jsonexpr_coercion.exists_coerce)
4710  {
4711  if (op->d.jsonexpr_coercion.exists_cast_to_int)
4712  {
4713  /* Check domain constraints if any. */
4714  if (op->d.jsonexpr_coercion.exists_check_domain &&
4715  !domain_check_safe(*op->resvalue, *op->resnull,
4716  op->d.jsonexpr_coercion.targettype,
4717  &op->d.jsonexpr_coercion.json_coercion_cache,
4718  econtext->ecxt_per_query_memory,
4719  (Node *) escontext))
4720  {
4721  *op->resnull = true;
4722  *op->resvalue = (Datum) 0;
4723  }
4724  else
4726  return;
4727  }
4728 
4730  DatumGetBool(*op->resvalue) ?
4731  CStringGetDatum("true") :
4732  CStringGetDatum("false"));
4733  }
4734 
4735  *op->resvalue = json_populate_type(*op->resvalue, JSONBOID,
4736  op->d.jsonexpr_coercion.targettype,
4737  op->d.jsonexpr_coercion.targettypmod,
4738  &op->d.jsonexpr_coercion.json_coercion_cache,
4739  econtext->ecxt_per_query_memory,
4740  op->resnull,
4741  op->d.jsonexpr_coercion.omit_quotes,
4742  (Node *) escontext);
4743 }
bool domain_check_safe(Datum value, bool isnull, Oid domainType, void **extra, MemoryContext mcxt, Node *escontext)
Definition: domains.c:355
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
Datum bool_int4(PG_FUNCTION_ARGS)
Definition: int.c:372
Datum jsonb_in(PG_FUNCTION_ARGS)
Definition: jsonb.c:73
Datum json_populate_type(Datum json_val, Oid json_type, Oid typid, int32 typmod, void **cache, MemoryContext mcxt, bool *isnull, bool omit_quotes, Node *escontext)
Definition: jsonfuncs.c:3344
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
struct ExprEvalStep::@55::@103 jsonexpr_coercion

References bool_int4(), CStringGetDatum(), DatumGetBool(), DirectFunctionCall1, domain_check_safe(), ExprContext::ecxt_per_query_memory, ExprEvalStep::escontext, json_populate_type(), jsonb_in(), and ExprEvalStep::op.

Referenced by ExecInterpExpr().

◆ ExecEvalJsonCoercionFinish()

void ExecEvalJsonCoercionFinish ( ExprState state,
ExprEvalStep op 
)

Definition at line 4774 of file execExprInterp.c.

4775 {
4776  JsonExprState *jsestate = op->d.jsonexpr.jsestate;
4777 
4778  if (SOFT_ERROR_OCCURRED(&jsestate->escontext))
4779  {
4780  /*
4781  * jsestate->error or jsestate->empty being set means that the error
4782  * occurred when coercing the JsonBehavior value. Throw the error in
4783  * that case with the actual coercion error message shown in the
4784  * DETAIL part.
4785  */
4786  if (DatumGetBool(jsestate->error.value))
4787  ereport(ERROR,
4788  (errcode(ERRCODE_DATATYPE_MISMATCH),
4789  /*- translator: first %s is a SQL/JSON clause (e.g. ON ERROR) */
4790  errmsg("could not coerce %s expression (%s) to the RETURNING type",
4791  "ON ERROR",
4793  errdetail("%s", jsestate->escontext.error_data->message)));
4794  else if (DatumGetBool(jsestate->empty.value))
4795  ereport(ERROR,
4796  (errcode(ERRCODE_DATATYPE_MISMATCH),
4797  /*- translator: first %s is a SQL/JSON clause (e.g. ON ERROR) */
4798  errmsg("could not coerce %s expression (%s) to the RETURNING type",
4799  "ON EMPTY",
4801  errdetail("%s", jsestate->escontext.error_data->message)));
4802 
4803  *op->resvalue = (Datum) 0;
4804  *op->resnull = true;
4805 
4806  jsestate->error.value = BoolGetDatum(true);
4807 
4808  /*
4809  * Reset for next use such as for catching errors when coercing a
4810  * JsonBehavior expression.
4811  */
4812  jsestate->escontext.error_occurred = false;
4813  jsestate->escontext.error_occurred = false;
4814  jsestate->escontext.details_wanted = true;
4815  }
4816 }
static char * GetJsonBehaviorValueString(JsonBehavior *behavior)
char * message
Definition: elog.h:440
bool details_wanted
Definition: miscnodes.h:48
ErrorData * error_data
Definition: miscnodes.h:49
bool error_occurred
Definition: miscnodes.h:47
struct ExprEvalStep::@55::@102 jsonexpr
NullableDatum empty
Definition: execnodes.h:1055
JsonExpr * jsexpr
Definition: execnodes.h:1033
NullableDatum error
Definition: execnodes.h:1052
ErrorSaveContext escontext
Definition: execnodes.h:1092
JsonBehavior * on_empty
Definition: primnodes.h:1839
JsonBehavior * on_error
Definition: primnodes.h:1840

References BoolGetDatum(), DatumGetBool(), ErrorSaveContext::details_wanted, JsonExprState::empty, ereport, errcode(), errdetail(), errmsg(), JsonExprState::error, ERROR, ErrorSaveContext::error_data, ErrorSaveContext::error_occurred, JsonExprState::escontext, GetJsonBehaviorValueString(), ExprEvalStep::jsestate, JsonExprState::jsexpr, ErrorData::message, JsonExpr::on_empty, JsonExpr::on_error, ExprEvalStep::op, SOFT_ERROR_OCCURRED, and NullableDatum::value.

Referenced by ExecInterpExpr().

◆ ExecEvalJsonConstructor()

void ExecEvalJsonConstructor ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 4239 of file execExprInterp.c.

4241 {
4242  Datum res;
4243  JsonConstructorExprState *jcstate = op->d.json_constructor.jcstate;
4244  JsonConstructorExpr *ctor = jcstate->constructor;
4245  bool is_jsonb = ctor->returning->format->format_type == JS_FORMAT_JSONB;
4246  bool isnull = false;
4247 
4248  if (ctor->type == JSCTOR_JSON_ARRAY)
4249  res = (is_jsonb ?
4251  json_build_array_worker) (jcstate->nargs,
4252  jcstate->arg_values,
4253  jcstate->arg_nulls,
4254  jcstate->arg_types,
4255  jcstate->constructor->absent_on_null);
4256  else if (ctor->type == JSCTOR_JSON_OBJECT)
4257  res = (is_jsonb ?
4259  json_build_object_worker) (jcstate->nargs,
4260  jcstate->arg_values,
4261  jcstate->arg_nulls,
4262  jcstate->arg_types,
4263  jcstate->constructor->absent_on_null,
4264  jcstate->constructor->unique);
4265  else if (ctor->type == JSCTOR_JSON_SCALAR)
4266  {
4267  if (jcstate->arg_nulls[0])
4268  {
4269  res = (Datum) 0;
4270  isnull = true;
4271  }
4272  else
4273  {
4274  Datum value = jcstate->arg_values[0];
4275  Oid outfuncid = jcstate->arg_type_cache[0].outfuncid;
4276  JsonTypeCategory category = (JsonTypeCategory)
4277  jcstate->arg_type_cache[0].category;
4278 
4279  if (is_jsonb)
4280  res = datum_to_jsonb(value, category, outfuncid);
4281  else
4282  res = datum_to_json(value, category, outfuncid);
4283  }
4284  }
4285  else if (ctor->type == JSCTOR_JSON_PARSE)
4286  {
4287  if (jcstate->arg_nulls[0])
4288  {
4289  res = (Datum) 0;
4290  isnull = true;
4291  }
4292  else
4293  {
4294  Datum value = jcstate->arg_values[0];
4295  text *js = DatumGetTextP(value);
4296 
4297  if (is_jsonb)
4298  res = jsonb_from_text(js, true);
4299  else
4300  {
4301  (void) json_validate(js, true, true);
4302  res = value;
4303  }
4304  }
4305  }
4306  else
4307  elog(ERROR, "invalid JsonConstructorExpr type %d", ctor->type);
4308 
4309  *op->resvalue = res;
4310  *op->resnull = isnull;
4311 }
#define DatumGetTextP(X)
Definition: fmgr.h:332
static struct @160 value
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
Datum json_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Definition: json.c:1344
Datum json_build_object_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null, bool unique_keys)
Definition: json.c:1224
Datum datum_to_json(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
Definition: json.c:763
bool json_validate(text *json, bool check_unique_keys, bool throw_error)
Definition: json.c:1812
Datum jsonb_from_text(text *js, bool unique_keys)
Definition: jsonb.c:147
Datum jsonb_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Definition: jsonb.c:1210
Datum jsonb_build_object_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null, bool unique_keys)
Definition: jsonb.c:1125
Datum datum_to_jsonb(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
Definition: jsonb.c:1112
JsonTypeCategory
Definition: jsonfuncs.h:69
@ JS_FORMAT_JSONB
Definition: primnodes.h:1640
@ JSCTOR_JSON_PARSE
Definition: primnodes.h:1694
@ JSCTOR_JSON_OBJECT
Definition: primnodes.h:1690
@ JSCTOR_JSON_SCALAR
Definition: primnodes.h:1695
@ JSCTOR_JSON_ARRAY
Definition: primnodes.h:1691
struct ExprEvalStep::@55::@91 json_constructor
JsonConstructorExpr * constructor
Definition: execExpr.h:797
struct JsonConstructorExprState::@104 * arg_type_cache
JsonReturning * returning
Definition: primnodes.h:1710
JsonConstructorType type
Definition: primnodes.h:1706
JsonFormatType format_type
Definition: primnodes.h:1651
JsonFormat * format
Definition: primnodes.h:1663
Definition: c.h:666

References JsonConstructorExpr::absent_on_null, JsonConstructorExprState::arg_nulls, JsonConstructorExprState::arg_type_cache, JsonConstructorExprState::arg_types, JsonConstructorExprState::arg_values, JsonConstructorExprState::category, JsonConstructorExprState::constructor, datum_to_json(), datum_to_jsonb(), DatumGetTextP, elog, ERROR, JsonReturning::format, JsonFormat::format_type, if(), ExprEvalStep::isnull, ExprEvalStep::jcstate, JS_FORMAT_JSONB, JSCTOR_JSON_ARRAY, JSCTOR_JSON_OBJECT, JSCTOR_JSON_PARSE, JSCTOR_JSON_SCALAR, json_build_array_worker(), json_build_object_worker(), json_validate(), jsonb_build_array_worker(), jsonb_build_object_worker(), jsonb_from_text(), JsonConstructorExprState::nargs, ExprEvalStep::op, JsonConstructorExprState::outfuncid, res, JsonConstructorExpr::returning, JsonConstructorExpr::type, JsonConstructorExpr::unique, and value.

Referenced by ExecInterpExpr().

◆ ExecEvalJsonExprPath()

int ExecEvalJsonExprPath ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 4417 of file execExprInterp.c.

4419 {
4420  JsonExprState *jsestate = op->d.jsonexpr.jsestate;
4421  JsonExpr *jsexpr = jsestate->jsexpr;
4422  Datum item;
4423  JsonPath *path;
4424  bool throw_error = jsexpr->on_error->btype == JSON_BEHAVIOR_ERROR;
4425  bool error = false,
4426  empty = false;
4427  int jump_eval_coercion = jsestate->jump_eval_coercion;
4428  char *val_string = NULL;
4429 
4430  item = jsestate->formatted_expr.value;
4431  path = DatumGetJsonPathP(jsestate->pathspec.value);
4432 
4433  /* Set error/empty to false. */
4434  memset(&jsestate->error, 0, sizeof(NullableDatum));
4435  memset(&jsestate->empty, 0, sizeof(NullableDatum));
4436 
4437  /* Also reset ErrorSaveContext contents for the next row. */
4438  if (jsestate->escontext.details_wanted)
4439  {
4440  jsestate->escontext.error_data = NULL;
4441  jsestate->escontext.details_wanted = false;
4442  }
4443  jsestate->escontext.error_occurred = false;
4444 
4445  switch (jsexpr->op)
4446  {
4447  case JSON_EXISTS_OP:
4448  {
4449  bool exists = JsonPathExists(item, path,
4450  !throw_error ? &error : NULL,
4451  jsestate->args);
4452 
4453  if (!error)
4454  {
4455  *op->resnull = false;
4456  *op->resvalue = BoolGetDatum(exists);
4457  }
4458  }
4459  break;
4460 
4461  case JSON_QUERY_OP:
4462  *op->resvalue = JsonPathQuery(item, path, jsexpr->wrapper, &empty,
4463  !throw_error ? &error : NULL,
4464  jsestate->args,
4465  jsexpr->column_name);
4466 
4467  *op->resnull = (DatumGetPointer(*op->resvalue) == NULL);
4468  break;
4469 
4470  case JSON_VALUE_OP:
4471  {
4472  JsonbValue *jbv = JsonPathValue(item, path, &empty,
4473  !throw_error ? &error : NULL,
4474  jsestate->args,
4475  jsexpr->column_name);
4476 
4477  if (jbv == NULL)
4478  {
4479  /* Will be coerced with json_populate_type(), if needed. */
4480  *op->resvalue = (Datum) 0;
4481  *op->resnull = true;
4482  }
4483  else if (!error && !empty)
4484  {
4485  if (jsexpr->returning->typid == JSONOID ||
4486  jsexpr->returning->typid == JSONBOID)
4487  {
4490  }
4491  else if (jsexpr->use_json_coercion)
4492  {
4494  *op->resnull = false;
4495  }
4496  else
4497  {
4499 
4500  /*
4501  * Simply convert to the default RETURNING type (text)
4502  * if no coercion needed.
4503  */
4504  if (!jsexpr->use_io_coercion)
4507  }
4508  }
4509  break;
4510  }
4511 
4512  /* JSON_TABLE_OP can't happen here */
4513 
4514  default:
4515  elog(ERROR, "unrecognized SQL/JSON expression op %d",
4516  (int) jsexpr->op);
4517  return false;
4518  }
4519 
4520  /*
4521  * Coerce the result value to the RETURNING type by calling its input
4522  * function.
4523  */
4524  if (!*op->resnull && jsexpr->use_io_coercion)
4525  {
4526  FunctionCallInfo fcinfo;
4527 
4528  Assert(jump_eval_coercion == -1);
4529  fcinfo = jsestate->input_fcinfo;
4530  Assert(fcinfo != NULL);
4531  Assert(val_string != NULL);
4532  fcinfo->args[0].value = PointerGetDatum(val_string);
4533  fcinfo->args[0].isnull = *op->resnull;
4534 
4535  /*
4536  * Second and third arguments are already set up in
4537  * ExecInitJsonExpr().
4538  */
4539 
4540  fcinfo->isnull = false;
4541  *op->resvalue = FunctionCallInvoke(fcinfo);
4542  if (SOFT_ERROR_OCCURRED(&jsestate->escontext))
4543  error = true;
4544  }
4545 
4546  /*
4547  * When setting up the ErrorSaveContext (if needed) for capturing the
4548  * errors that occur when coercing the JsonBehavior expression, set
4549  * details_wanted to be able to show the actual error message as the
4550  * DETAIL of the error message that tells that it is the JsonBehavior
4551  * expression that caused the error; see ExecEvalJsonCoercionFinish().
4552  */
4553 
4554  /* Handle ON EMPTY. */
4555  if (empty)
4556  {
4557  *op->resvalue = (Datum) 0;
4558  *op->resnull = true;
4559  if (jsexpr->on_empty)
4560  {
4561  if (jsexpr->on_empty->btype != JSON_BEHAVIOR_ERROR)
4562  {
4563  jsestate->empty.value = BoolGetDatum(true);
4564  /* Set up to catch coercion errors of the ON EMPTY value. */
4565  jsestate->escontext.error_occurred = false;
4566  jsestate->escontext.details_wanted = true;
4567  /* Jump to end if the ON EMPTY behavior is to return NULL */
4568  return jsestate->jump_empty >= 0 ? jsestate->jump_empty : jsestate->jump_end;
4569  }
4570  }
4571  else if (jsexpr->on_error->btype != JSON_BEHAVIOR_ERROR)
4572  {
4573  jsestate->error.value = BoolGetDatum(true);
4574  /* Set up to catch coercion errors of the ON ERROR value. */
4575  jsestate->escontext.error_occurred = false;
4576  jsestate->escontext.details_wanted = true;
4577  Assert(!throw_error);
4578  /* Jump to end if the ON ERROR behavior is to return NULL */
4579  return jsestate->jump_error >= 0 ? jsestate->jump_error : jsestate->jump_end;
4580  }
4581 
4582  if (jsexpr->column_name)
4583  ereport(ERROR,
4584  errcode(ERRCODE_NO_SQL_JSON_ITEM),
4585  errmsg("no SQL/JSON item found for specified path of column \"%s\"",
4586  jsexpr->column_name));
4587  else
4588  ereport(ERROR,
4589  errcode(ERRCODE_NO_SQL_JSON_ITEM),
4590  errmsg("no SQL/JSON item found for specified path"));
4591  }
4592 
4593  /*
4594  * ON ERROR. Wouldn't get here if the behavior is ERROR, because they
4595  * would have already been thrown.
4596  */
4597  if (error)
4598  {
4599  Assert(!throw_error);
4600  *op->resvalue = (Datum) 0;
4601  *op->resnull = true;
4602  jsestate->error.value = BoolGetDatum(true);
4603  /* Set up to catch coercion errors of the ON ERROR value. */
4604  jsestate->escontext.error_occurred = false;
4605  jsestate->escontext.details_wanted = true;
4606  /* Jump to end if the ON ERROR behavior is to return NULL */
4607  return jsestate->jump_error >= 0 ? jsestate->jump_error : jsestate->jump_end;
4608  }
4609 
4610  return jump_eval_coercion >= 0 ? jump_eval_coercion : jsestate->jump_end;
4611 }
static char * ExecGetJsonValueItemString(JsonbValue *item, bool *resnull)
char * val_string
Definition: informix.c:694
Datum jsonb_out(PG_FUNCTION_ARGS)
Definition: jsonb.c:108
static Datum JsonbPGetDatum(const Jsonb *p)
Definition: jsonb.h:386
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:92
static JsonPath * DatumGetJsonPathP(Datum d)
Definition: jsonpath.h:35
bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars)
Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper, bool *empty, bool *error, List *vars, const char *column_name)
JsonbValue * JsonPathValue(Datum jb, JsonPath *jp, bool *empty, bool *error, List *vars, const char *column_name)
@ JSON_BEHAVIOR_ERROR
Definition: primnodes.h:1766
@ JSON_QUERY_OP
Definition: primnodes.h:1803
@ JSON_EXISTS_OP
Definition: primnodes.h:1802
@ JSON_VALUE_OP
Definition: primnodes.h:1804
static void error(void)
Definition: sql-dyntest.c:147
JsonBehaviorType btype
Definition: primnodes.h:1790
int jump_eval_coercion
Definition: execnodes.h:1069
FunctionCallInfo input_fcinfo
Definition: execnodes.h:1083
NullableDatum pathspec
Definition: execnodes.h:1039
NullableDatum formatted_expr
Definition: execnodes.h:1036
char * column_name
Definition: primnodes.h:1819
bool use_io_coercion
Definition: primnodes.h:1846
JsonReturning * returning
Definition: primnodes.h:1832
bool use_json_coercion
Definition: primnodes.h:1847
JsonWrapper wrapper
Definition: primnodes.h:1850
JsonExprOp op
Definition: primnodes.h:1817
Datum textin(PG_FUNCTION_ARGS)
Definition: varlena.c:579

References FunctionCallInfoBaseData::args, JsonExprState::args, Assert, BoolGetDatum(), JsonBehavior::btype, JsonExpr::column_name, CStringGetDatum(), DatumGetCString(), DatumGetJsonPathP(), DatumGetPointer(), ErrorSaveContext::details_wanted, DirectFunctionCall1, elog, JsonExprState::empty, ereport, errcode(), errmsg(), JsonExprState::error, ERROR, error(), ErrorSaveContext::error_data, ErrorSaveContext::error_occurred, JsonExprState::escontext, ExecGetJsonValueItemString(), JsonExprState::formatted_expr, FunctionCallInvoke, JsonExprState::input_fcinfo, FunctionCallInfoBaseData::isnull, NullableDatum::isnull, ExprEvalStep::jsestate, JsonExprState::jsexpr, JSON_BEHAVIOR_ERROR, JSON_EXISTS_OP, JSON_QUERY_OP, JSON_VALUE_OP, jsonb_out(), JsonbPGetDatum(), JsonbValueToJsonb(), JsonPathExists(), JsonPathQuery(), JsonPathValue(), JsonExprState::jump_empty, JsonExprState::jump_end, JsonExprState::jump_error, JsonExprState::jump_eval_coercion, JsonExpr::on_empty, JsonExpr::on_error, ExprEvalStep::op, JsonExpr::op, JsonExprState::pathspec, PointerGetDatum(), JsonExpr::returning, SOFT_ERROR_OCCURRED, textin(), JsonReturning::typid, JsonExpr::use_io_coercion, JsonExpr::use_json_coercion, val_string, NullableDatum::value, and JsonExpr::wrapper.

Referenced by ExecInterpExpr().

◆ ExecEvalJsonIsPredicate()

void ExecEvalJsonIsPredicate ( ExprState state,
ExprEvalStep op 
)

Definition at line 4317 of file execExprInterp.c.

4318 {
4319  JsonIsPredicate *pred = op->d.is_json.pred;
4320  Datum js = *op->resvalue;
4321  Oid exprtype;
4322  bool res;
4323 
4324  if (*op->resnull)
4325  {
4326  *op->resvalue = BoolGetDatum(false);
4327  return;
4328  }
4329 
4330  exprtype = exprType(pred->expr);
4331 
4332  if (exprtype == TEXTOID || exprtype == JSONOID)
4333  {
4334  text *json = DatumGetTextP(js);
4335 
4336  if (pred->item_type == JS_TYPE_ANY)
4337  res = true;
4338  else
4339  {
4340  switch (json_get_first_token(json, false))
4341  {
4343  res = pred->item_type == JS_TYPE_OBJECT;
4344  break;
4346  res = pred->item_type == JS_TYPE_ARRAY;
4347  break;
4348  case JSON_TOKEN_STRING:
4349  case JSON_TOKEN_NUMBER:
4350  case JSON_TOKEN_TRUE:
4351  case JSON_TOKEN_FALSE:
4352  case JSON_TOKEN_NULL:
4353  res = pred->item_type == JS_TYPE_SCALAR;
4354  break;
4355  default:
4356  res = false;
4357  break;
4358  }
4359  }
4360 
4361  /*
4362  * Do full parsing pass only for uniqueness check or for JSON text
4363  * validation.
4364  */
4365  if (res && (pred->unique_keys || exprtype == TEXTOID))
4366  res = json_validate(json, pred->unique_keys, false);
4367  }
4368  else if (exprtype == JSONBOID)
4369  {
4370  if (pred->item_type == JS_TYPE_ANY)
4371  res = true;
4372  else
4373  {
4374  Jsonb *jb = DatumGetJsonbP(js);
4375 
4376  switch (pred->item_type)
4377  {
4378  case JS_TYPE_OBJECT:
4379  res = JB_ROOT_IS_OBJECT(jb);
4380  break;
4381  case JS_TYPE_ARRAY:
4382  res = JB_ROOT_IS_ARRAY(jb) && !JB_ROOT_IS_SCALAR(jb);
4383  break;
4384  case JS_TYPE_SCALAR:
4385  res = JB_ROOT_IS_ARRAY(jb) && JB_ROOT_IS_SCALAR(jb);
4386  break;
4387  default:
4388  res = false;
4389  break;
4390  }
4391  }
4392 
4393  /* Key uniqueness check is redundant for jsonb */
4394  }
4395  else
4396  res = false;
4397 
4398  *op->resvalue = BoolGetDatum(res);
4399 }
@ JSON_TOKEN_FALSE
Definition: jsonapi.h:29
@ JSON_TOKEN_TRUE
Definition: jsonapi.h:28
@ JSON_TOKEN_NULL
Definition: jsonapi.h:30
@ JSON_TOKEN_OBJECT_START
Definition: jsonapi.h:22
@ JSON_TOKEN_NUMBER
Definition: jsonapi.h:21
@ JSON_TOKEN_STRING
Definition: jsonapi.h:20
@ JSON_TOKEN_ARRAY_START
Definition: jsonapi.h:24
static Jsonb * DatumGetJsonbP(Datum d)
Definition: jsonb.h:374
#define JB_ROOT_IS_OBJECT(jbp_)
Definition: jsonb.h:221
#define JB_ROOT_IS_ARRAY(jbp_)
Definition: jsonb.h:222
#define JB_ROOT_IS_SCALAR(jbp_)
Definition: jsonb.h:220
JsonTokenType json_get_first_token(text *json, bool throw_error)
Definition: jsonfuncs.c:5949
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
@ JS_TYPE_ANY
Definition: primnodes.h:1722
@ JS_TYPE_ARRAY
Definition: primnodes.h:1724
@ JS_TYPE_OBJECT
Definition: primnodes.h:1723
@ JS_TYPE_SCALAR
Definition: primnodes.h:1725
struct ExprEvalStep::@55::@101 is_json
JsonValueType item_type
Definition: primnodes.h:1737
Definition: jsonb.h:213

References BoolGetDatum(), DatumGetJsonbP(), DatumGetTextP, JsonIsPredicate::expr, exprType(), JsonIsPredicate::item_type, JB_ROOT_IS_ARRAY, JB_ROOT_IS_OBJECT, JB_ROOT_IS_SCALAR, JS_TYPE_ANY, JS_TYPE_ARRAY, JS_TYPE_OBJECT, JS_TYPE_SCALAR, json_get_first_token(), JSON_TOKEN_ARRAY_START, JSON_TOKEN_FALSE, JSON_TOKEN_NULL, JSON_TOKEN_NUMBER, JSON_TOKEN_OBJECT_START, JSON_TOKEN_STRING, JSON_TOKEN_TRUE, json_validate(), ExprEvalStep::op, ExprEvalStep::pred, res, and JsonIsPredicate::unique_keys.

Referenced by ExecInterpExpr().

◆ ExecEvalMergeSupportFunc()

void ExecEvalMergeSupportFunc ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 4855 of file execExprInterp.c.

4857 {
4858  ModifyTableState *mtstate = castNode(ModifyTableState, state->parent);
4859  MergeActionState *relaction = mtstate->mt_merge_action;
4860 
4861  if (!relaction)
4862  elog(ERROR, "no merge action in progress");
4863 
4864  /* Return the MERGE action ("INSERT", "UPDATE", or "DELETE") */
4865  switch (relaction->mas_action->commandType)
4866  {
4867  case CMD_INSERT:
4868  *op->resvalue = PointerGetDatum(cstring_to_text_with_len("INSERT", 6));
4869  *op->resnull = false;
4870  break;
4871  case CMD_UPDATE:
4872  *op->resvalue = PointerGetDatum(cstring_to_text_with_len("UPDATE", 6));
4873  *op->resnull = false;
4874  break;
4875  case CMD_DELETE:
4876  *op->resvalue = PointerGetDatum(cstring_to_text_with_len("DELETE", 6));
4877  *op->resnull = false;
4878  break;
4879  case CMD_NOTHING:
4880  elog(ERROR, "unexpected merge action: DO NOTHING");
4881  break;
4882  default:
4883  elog(ERROR, "unrecognized commandType: %d",
4884  (int) relaction->mas_action->commandType);
4885  }
4886 }
@ CMD_INSERT
Definition: nodes.h:267
@ CMD_DELETE
Definition: nodes.h:268
@ CMD_UPDATE
Definition: nodes.h:266
@ CMD_NOTHING
Definition: nodes.h:272
MergeAction * mas_action
Definition: execnodes.h:428
CmdType commandType
Definition: primnodes.h:2007
MergeActionState * mt_merge_action
Definition: execnodes.h:1413
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:196

References castNode, CMD_DELETE, CMD_INSERT, CMD_NOTHING, CMD_UPDATE, MergeAction::commandType, cstring_to_text_with_len(), elog, ERROR, MergeActionState::mas_action, ModifyTableState::mt_merge_action, ExprEvalStep::op, and PointerGetDatum().

Referenced by ExecInterpExpr().

◆ ExecEvalMinMax()

void ExecEvalMinMax ( ExprState state,
ExprEvalStep op 
)

Definition at line 3258 of file execExprInterp.c.

3259 {
3260  Datum *values = op->d.minmax.values;
3261  bool *nulls = op->d.minmax.nulls;
3262  FunctionCallInfo fcinfo = op->d.minmax.fcinfo_data;
3263  MinMaxOp operator = op->d.minmax.op;
3264 
3265  /* set at initialization */
3266  Assert(fcinfo->args[0].isnull == false);
3267  Assert(fcinfo->args[1].isnull == false);
3268 
3269  /* default to null result */
3270  *op->resnull = true;
3271 
3272  for (int off = 0; off < op->d.minmax.nelems; off++)
3273  {
3274  /* ignore NULL inputs */
3275  if (nulls[off])
3276  continue;
3277 
3278  if (*op->resnull)
3279  {
3280  /* first nonnull input, adopt value */
3281  *op->resvalue = values[off];
3282  *op->resnull = false;
3283  }
3284  else
3285  {
3286  int cmpresult;
3287 
3288  /* apply comparison function */
3289  fcinfo->args[0].value = *op->resvalue;
3290  fcinfo->args[1].value = values[off];
3291 
3292  fcinfo->isnull = false;
3293  cmpresult = DatumGetInt32(FunctionCallInvoke(fcinfo));
3294  if (fcinfo->isnull) /* probably should not happen */
3295  continue;
3296 
3297  if (cmpresult > 0 && operator == IS_LEAST)
3298  *op->resvalue = values[off];
3299  else if (cmpresult < 0 && operator == IS_GREATEST)
3300  *op->resvalue = values[off];
3301  }
3302  }
3303 }
static Datum values[MAXATTR]
Definition: bootstrap.c:151
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202
MinMaxOp
Definition: primnodes.h:1501
@ IS_LEAST
Definition: primnodes.h:1503
@ IS_GREATEST
Definition: primnodes.h:1502
struct ExprEvalStep::@55::@79 minmax

References FunctionCallInfoBaseData::args, Assert, DatumGetInt32(), FunctionCallInvoke, IS_GREATEST, IS_LEAST, FunctionCallInfoBaseData::isnull, NullableDatum::isnull, ExprEvalStep::nulls, ExprEvalStep::op, NullableDatum::value, and values.

Referenced by ExecInterpExpr().

◆ ExecEvalNextValueExpr()

void ExecEvalNextValueExpr ( ExprState state,
ExprEvalStep op 
)

Definition at line 2855 of file execExprInterp.c.

2856 {
2857  int64 newval = nextval_internal(op->d.nextvalueexpr.seqid, false);
2858 
2859  switch (op->d.nextvalueexpr.seqtypid)
2860  {
2861  case INT2OID:
2862  *op->resvalue = Int16GetDatum((int16) newval);
2863  break;
2864  case INT4OID:
2865  *op->resvalue = Int32GetDatum((int32) newval);
2866  break;
2867  case INT8OID:
2868  *op->resvalue = Int64GetDatum((int64) newval);
2869  break;
2870  default:
2871  elog(ERROR, "unsupported sequence type %u",
2872  op->d.nextvalueexpr.seqtypid);
2873  }
2874  *op->resnull = false;
2875 }
int64 nextval_internal(Oid relid, bool check_permissions)
Definition: sequence.c:623
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1807
#define newval
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
struct ExprEvalStep::@55::@73 nextvalueexpr

References elog, ERROR, Int16GetDatum(), Int32GetDatum(), Int64GetDatum(), newval, nextval_internal(), and ExprEvalStep::op.

Referenced by ExecInterpExpr().

◆ ExecEvalParamExec()

void ExecEvalParamExec ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 2630 of file execExprInterp.c.

2631 {
2632  ParamExecData *prm;
2633 
2634  prm = &(econtext->ecxt_param_exec_vals[op->d.param.paramid]);
2635  if (unlikely(prm->execPlan != NULL))
2636  {
2637  /* Parameter not evaluated yet, so go do it */
2638  ExecSetParamPlan(prm->execPlan, econtext);
2639  /* ExecSetParamPlan should have processed this param... */
2640  Assert(prm->execPlan == NULL);
2641  }
2642  *op->resvalue = prm->value;
2643  *op->resnull = prm->isnull;
2644 }
void ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
Definition: nodeSubplan.c:1083
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:269
struct ExprEvalStep::@55::@67 param
bool isnull
Definition: params.h:150
Datum value
Definition: params.h:149
void * execPlan
Definition: params.h:148

References Assert, ExprContext::ecxt_param_exec_vals, ParamExecData::execPlan, ExecSetParamPlan(), ParamExecData::isnull, ExprEvalStep::op, unlikely, and ParamExecData::value.

Referenced by ExecInterpExpr().

◆ ExecEvalParamExtern()

void ExecEvalParamExtern ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 2652 of file execExprInterp.c.

2653 {
2654  ParamListInfo paramInfo = econtext->ecxt_param_list_info;
2655  int paramId = op->d.param.paramid;
2656 
2657  if (likely(paramInfo &&
2658  paramId > 0 && paramId <= paramInfo->numParams))
2659  {
2660  ParamExternData *prm;
2661  ParamExternData prmdata;
2662 
2663  /* give hook a chance in case parameter is dynamic */
2664  if (paramInfo->paramFetch != NULL)
2665  prm = paramInfo->paramFetch(paramInfo, paramId, false, &prmdata);
2666  else
2667  prm = &paramInfo->params[paramId - 1];
2668 
2669  if (likely(OidIsValid(prm->ptype)))
2670  {
2671  /* safety check in case hook did something unexpected */
2672  if (unlikely(prm->ptype != op->d.param.paramtype))
2673  ereport(ERROR,
2674  (errcode(ERRCODE_DATATYPE_MISMATCH),
2675  errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
2676  paramId,
2677  format_type_be(prm->ptype),
2678  format_type_be(op->d.param.paramtype))));
2679  *op->resvalue = prm->value;
2680  *op->resnull = prm->isnull;
2681  return;
2682  }
2683  }
2684 
2685  ereport(ERROR,
2686  (errcode(ERRCODE_UNDEFINED_OBJECT),
2687  errmsg("no value found for parameter %d", paramId)));
2688 }
#define likely(x)
Definition: c.h:325
#define OidIsValid(objectId)
Definition: c.h:754
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:270
bool isnull
Definition: params.h:93
Datum value
Definition: params.h:92
ParamExternData params[FLEXIBLE_ARRAY_MEMBER]
Definition: params.h:125
ParamFetchHook paramFetch
Definition: params.h:112

References ExprContext::ecxt_param_list_info, ereport, errcode(), errmsg(), ERROR, format_type_be(), ParamExternData::isnull, likely, OidIsValid, ExprEvalStep::op, ParamListInfoData::paramFetch, ParamListInfoData::params, ParamExternData::ptype, unlikely, and ParamExternData::value.

Referenced by ExecInterpExpr().

◆ ExecEvalParamSet()

void ExecEvalParamSet ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 2695 of file execExprInterp.c.

2696 {
2697  ParamExecData *prm;
2698 
2699  prm = &(econtext->ecxt_param_exec_vals[op->d.param.paramid]);
2700 
2701  /* Shouldn't have a pending evaluation anymore */
2702  Assert(prm->execPlan == NULL);
2703 
2704  prm->value = state->resvalue;
2705  prm->isnull = state->resnull;
2706 }

References Assert, ExprContext::ecxt_param_exec_vals, ParamExecData::execPlan, ParamExecData::isnull, ExprEvalStep::op, and ParamExecData::value.

Referenced by ExecInterpExpr().

◆ ExecEvalPreOrderedDistinctMulti()

bool ExecEvalPreOrderedDistinctMulti ( AggState aggstate,
AggStatePerTrans  pertrans 
)

Definition at line 5301 of file execExprInterp.c.

5302 {
5303  ExprContext *tmpcontext = aggstate->tmpcontext;
5304  bool isdistinct = false; /* for now */
5305  TupleTableSlot *save_outer;
5306  TupleTableSlot *save_inner;
5307 
5308  for (int i = 0; i < pertrans->numTransInputs; i++)
5309  {
5310  pertrans->sortslot->tts_values[i] = pertrans->transfn_fcinfo->args[i + 1].value;
5311  pertrans->sortslot->tts_isnull[i] = pertrans->transfn_fcinfo->args[i + 1].isnull;
5312  }
5313 
5314  ExecClearTuple(pertrans->sortslot);
5315  pertrans->sortslot->tts_nvalid = pertrans->numInputs;
5316  ExecStoreVirtualTuple(pertrans->sortslot);
5317 
5318  /* save the previous slots before we overwrite them */
5319  save_outer = tmpcontext->ecxt_outertuple;
5320  save_inner = tmpcontext->ecxt_innertuple;
5321 
5322  tmpcontext->ecxt_outertuple = pertrans->sortslot;
5323  tmpcontext->ecxt_innertuple = pertrans->uniqslot;
5324 
5325  if (!pertrans->haslast ||
5326  !ExecQual(pertrans->equalfnMulti, tmpcontext))
5327  {
5328  if (pertrans->haslast)
5329  ExecClearTuple(pertrans->uniqslot);
5330 
5331  pertrans->haslast = true;
5332  ExecCopySlot(pertrans->uniqslot, pertrans->sortslot);
5333 
5334  isdistinct = true;
5335  }
5336 
5337  /* restore the original slots */
5338  tmpcontext->ecxt_outertuple = save_outer;
5339  tmpcontext->ecxt_innertuple = save_inner;
5340 
5341  return isdistinct;
5342 }
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:424
ExprState * equalfnMulti
Definition: nodeAgg.h:116
TupleTableSlot * uniqslot
Definition: nodeAgg.h:142
ExprContext * tmpcontext
Definition: execnodes.h:2510
bool * tts_isnull
Definition: tuptable.h:127
Datum * tts_values
Definition: tuptable.h:125
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition: tuptable.h:509

References FunctionCallInfoBaseData::args, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, AggStatePerTransData::equalfnMulti, ExecClearTuple(), ExecCopySlot(), ExecQual(), ExecStoreVirtualTuple(), AggStatePerTransData::haslast, i, NullableDatum::isnull, AggStatePerTransData::numInputs, AggStatePerTransData::numTransInputs, ExprEvalStep::pertrans, AggStatePerTransData::sortslot, AggState::tmpcontext, AggStatePerTransData::transfn_fcinfo, TupleTableSlot::tts_isnull, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_values, AggStatePerTransData::uniqslot, and NullableDatum::value.

Referenced by ExecInterpExpr().

◆ ExecEvalPreOrderedDistinctSingle()

bool ExecEvalPreOrderedDistinctSingle ( AggState aggstate,
AggStatePerTrans  pertrans 
)

Definition at line 5258 of file execExprInterp.c.

5259 {
5260  Datum value = pertrans->transfn_fcinfo->args[1].value;
5261  bool isnull = pertrans->transfn_fcinfo->args[1].isnull;
5262 
5263  if (!pertrans->haslast ||
5264  pertrans->lastisnull != isnull ||
5265  (!isnull && !DatumGetBool(FunctionCall2Coll(&pertrans->equalfnOne,
5266  pertrans->aggCollation,
5267  pertrans->lastdatum, value))))
5268  {
5269  if (pertrans->haslast && !pertrans->inputtypeByVal &&
5270  !pertrans->lastisnull)
5271  pfree(DatumGetPointer(pertrans->lastdatum));
5272 
5273  pertrans->haslast = true;
5274  if (!isnull)
5275  {
5276  MemoryContext oldContext;
5277 
5279 
5280  pertrans->lastdatum = datumCopy(value, pertrans->inputtypeByVal,
5281  pertrans->inputtypeLen);
5282 
5283  MemoryContextSwitchTo(oldContext);
5284  }
5285  else
5286  pertrans->lastdatum = (Datum) 0;
5287  pertrans->lastisnull = isnull;
5288  return true;
5289  }
5290 
5291  return false;
5292 }
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1149
FmgrInfo equalfnOne
Definition: nodeAgg.h:115

References AggStatePerTransData::aggCollation, FunctionCallInfoBaseData::args, AggState::curaggcontext, datumCopy(), DatumGetBool(), DatumGetPointer(), ExprContext::ecxt_per_tuple_memory, AggStatePerTransData::equalfnOne, FunctionCall2Coll(), AggStatePerTransData::haslast, AggStatePerTransData::inputtypeByVal, AggStatePerTransData::inputtypeLen, ExprEvalStep::isnull, NullableDatum::isnull, AggStatePerTransData::lastdatum, AggStatePerTransData::lastisnull, MemoryContextSwitchTo(), ExprEvalStep::pertrans, pfree(), AggStatePerTransData::transfn_fcinfo, NullableDatum::value, and value.

Referenced by ExecInterpExpr().

◆ ExecEvalRow()

void ExecEvalRow ( ExprState state,
ExprEvalStep op 
)

Definition at line 3238 of file execExprInterp.c.

3239 {
3240  HeapTuple tuple;
3241 
3242  /* build tuple from evaluated field values */
3243  tuple = heap_form_tuple(op->d.row.tupdesc,
3244  op->d.row.elemvalues,
3245  op->d.row.elemnulls);
3246 
3247  *op->resvalue = HeapTupleGetDatum(tuple);
3248  *op->resnull = false;
3249 }
struct ExprEvalStep::@55::@76 row

References heap_form_tuple(), HeapTupleGetDatum(), and ExprEvalStep::op.

Referenced by ExecInterpExpr().

◆ ExecEvalRowNotNull()

void ExecEvalRowNotNull ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 2890 of file execExprInterp.c.

2891 {
2892  ExecEvalRowNullInt(state, op, econtext, false);
2893 }
static void ExecEvalRowNullInt(ExprState *state, ExprEvalStep *op, ExprContext *econtext, bool checkisnull)

References ExecEvalRowNullInt(), and ExprEvalStep::op.

Referenced by ExecInterpExpr().

◆ ExecEvalRowNull()

void ExecEvalRowNull ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 2881 of file execExprInterp.c.

2882 {
2883  ExecEvalRowNullInt(state, op, econtext, true);
2884 }

References ExecEvalRowNullInt(), and ExprEvalStep::op.

Referenced by ExecInterpExpr().

◆ ExecEvalScalarArrayOp()

void ExecEvalScalarArrayOp ( ExprState state,
ExprEvalStep op 
)

Definition at line 3605 of file execExprInterp.c.

3606 {
3607  FunctionCallInfo fcinfo = op->d.scalararrayop.fcinfo_data;
3608  bool useOr = op->d.scalararrayop.useOr;
3609  bool strictfunc = op->d.scalararrayop.finfo->fn_strict;
3610  ArrayType *arr;
3611  int nitems;
3612  Datum result;
3613  bool resultnull;
3614  int16 typlen;
3615  bool typbyval;
3616  char typalign;
3617  char *s;
3618  bits8 *bitmap;
3619  int bitmask;
3620 
3621  /*
3622  * If the array is NULL then we return NULL --- it's not very meaningful
3623  * to do anything else, even if the operator isn't strict.
3624  */
3625  if (*op->resnull)
3626  return;
3627 
3628  /* Else okay to fetch and detoast the array */
3629  arr = DatumGetArrayTypeP(*op->resvalue);
3630 
3631  /*
3632  * If the array is empty, we return either FALSE or TRUE per the useOr
3633  * flag. This is correct even if the scalar is NULL; since we would
3634  * evaluate the operator zero times, it matters not whether it would want
3635  * to return NULL.
3636  */
3637  nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
3638  if (nitems <= 0)
3639  {
3640  *op->resvalue = BoolGetDatum(!useOr);
3641  *op->resnull = false;
3642  return;
3643  }
3644 
3645  /*
3646  * If the scalar is NULL, and the function is strict, return NULL; no
3647  * point in iterating the loop.
3648  */
3649  if (fcinfo->args[0].isnull && strictfunc)
3650  {
3651  *op->resnull = true;
3652  return;
3653  }
3654 
3655  /*
3656  * We arrange to look up info about the element type only once per series
3657  * of calls, assuming the element type doesn't change underneath us.
3658  */
3659  if (op->d.scalararrayop.element_type != ARR_ELEMTYPE(arr))
3660  {
3662  &op->d.scalararrayop.typlen,
3663  &op->d.scalararrayop.typbyval,
3664  &op->d.scalararrayop.typalign);
3665  op->d.scalararrayop.element_type = ARR_ELEMTYPE(arr);
3666  }
3667 
3668  typlen = op->d.scalararrayop.typlen;
3669  typbyval = op->d.scalararrayop.typbyval;
3670  typalign = op->d.scalararrayop.typalign;
3671 
3672  /* Initialize result appropriately depending on useOr */
3673  result = BoolGetDatum(!useOr);
3674  resultnull = false;
3675 
3676  /* Loop over the array elements */
3677  s = (char *) ARR_DATA_PTR(arr);
3678  bitmap = ARR_NULLBITMAP(arr);
3679  bitmask = 1;
3680 
3681  for (int i = 0; i < nitems; i++)
3682  {
3683  Datum elt;
3684  Datum thisresult;
3685 
3686  /* Get array element, checking for NULL */
3687  if (bitmap && (*bitmap & bitmask) == 0)
3688  {
3689  fcinfo->args[1].value = (Datum) 0;
3690  fcinfo->args[1].isnull = true;
3691  }
3692  else
3693  {
3694  elt = fetch_att(s, typbyval, typlen);
3695  s = att_addlength_pointer(s, typlen, s);
3696  s = (char *) att_align_nominal(s, typalign);
3697  fcinfo->args[1].value = elt;
3698  fcinfo->args[1].isnull = false;
3699  }
3700 
3701  /* Call comparison function */
3702  if (fcinfo->args[1].isnull && strictfunc)
3703  {
3704  fcinfo->isnull = true;
3705  thisresult = (Datum) 0;
3706  }
3707  else
3708  {
3709  fcinfo->isnull = false;
3710  thisresult = op->d.scalararrayop.fn_addr(fcinfo);
3711  }
3712 
3713  /* Combine results per OR or AND semantics */
3714  if (fcinfo->isnull)
3715  resultnull = true;
3716  else if (useOr)
3717  {
3718  if (DatumGetBool(thisresult))
3719  {
3720  result = BoolGetDatum(true);
3721  resultnull = false;
3722  break; /* needn't look at any more elements */
3723  }
3724  }
3725  else
3726  {
3727  if (!DatumGetBool(thisresult))
3728  {
3729  result = BoolGetDatum(false);
3730  resultnull = false;
3731  break; /* needn't look at any more elements */
3732  }
3733  }
3734 
3735  /* advance bitmap pointer if any */
3736  if (bitmap)
3737  {
3738  bitmask <<= 1;
3739  if (bitmask == 0x100)
3740  {
3741  bitmap++;
3742  bitmask = 1;
3743  }
3744  }
3745  }
3746 
3747  *op->resvalue = result;
3748  *op->resnull = resultnull;
3749 }
struct ExprEvalStep::@55::@88 scalararrayop

References FunctionCallInfoBaseData::args, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, ARR_NULLBITMAP, ArrayGetNItems(), att_addlength_pointer, att_align_nominal, BoolGetDatum(), DatumGetArrayTypeP, DatumGetBool(), fetch_att(), get_typlenbyvalalign(), i, FunctionCallInfoBaseData::isnull, NullableDatum::isnull, nitems, ExprEvalStep::op, typalign, ExprEvalStep::typbyval, ExprEvalStep::typlen, ExprEvalStep::useOr, and NullableDatum::value.

Referenced by ExecInterpExpr().

◆ ExecEvalSQLValueFunction()

void ExecEvalSQLValueFunction ( ExprState state,
ExprEvalStep op 
)

Definition at line 2777 of file execExprInterp.c.

2778 {
2779  LOCAL_FCINFO(fcinfo, 0);
2780  SQLValueFunction *svf = op->d.sqlvaluefunction.svf;
2781 
2782  *op->resnull = false;
2783 
2784  /*
2785  * Note: current_schema() can return NULL. current_user() etc currently
2786  * cannot, but might as well code those cases the same way for safety.
2787  */
2788  switch (svf->op)
2789  {
2790  case SVFOP_CURRENT_DATE:
2792  break;
2793  case SVFOP_CURRENT_TIME:
2794  case SVFOP_CURRENT_TIME_N:
2796  break;
2800  break;
2801  case SVFOP_LOCALTIME:
2802  case SVFOP_LOCALTIME_N:
2804  break;
2805  case SVFOP_LOCALTIMESTAMP:
2808  break;
2809  case SVFOP_CURRENT_ROLE:
2810  case SVFOP_CURRENT_USER:
2811  case SVFOP_USER:
2812  InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
2813  *op->resvalue = current_user(fcinfo);
2814  *op->resnull = fcinfo->isnull;
2815  break;
2816  case SVFOP_SESSION_USER:
2817  InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
2818  *op->resvalue = session_user(fcinfo);
2819  *op->resnull = fcinfo->isnull;
2820  break;
2821  case SVFOP_CURRENT_CATALOG:
2822  InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
2823  *op->resvalue = current_database(fcinfo);
2824  *op->resnull = fcinfo->isnull;
2825  break;
2826  case SVFOP_CURRENT_SCHEMA:
2827  InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
2828  *op->resvalue = current_schema(fcinfo);
2829  *op->resnull = fcinfo->isnull;
2830  break;
2831  }
2832 }
Datum current_database(PG_FUNCTION_ARGS)
Definition: misc.c:195
Timestamp GetSQLLocalTimestamp(int32 typmod)
Definition: timestamp.c:1676
TimestampTz GetSQLCurrentTimestamp(int32 typmod)
Definition: timestamp.c:1662
TimeTzADT * GetSQLCurrentTime(int32 typmod)
Definition: date.c:342
TimeADT GetSQLLocalTime(int32 typmod)
Definition: date.c:362
DateADT GetSQLCurrentDate(void)
Definition: date.c:309
static Datum DateADTGetDatum(DateADT X)
Definition: date.h:72
static Datum TimeTzADTPGetDatum(const TimeTzADT *X)
Definition: date.h:84
static Datum TimeADTGetDatum(TimeADT X)
Definition: date.h:78
#define LOCAL_FCINFO(name, nargs)
Definition: fmgr.h:110
Datum current_user(PG_FUNCTION_ARGS)
Definition: name.c:263
Datum session_user(PG_FUNCTION_ARGS)
Definition: name.c:269
Datum current_schema(PG_FUNCTION_ARGS)
Definition: name.c:279
@ SVFOP_CURRENT_CATALOG
Definition: primnodes.h:1549
@ SVFOP_LOCALTIME_N
Definition: primnodes.h:1542
@ SVFOP_CURRENT_TIMESTAMP
Definition: primnodes.h:1539
@ SVFOP_LOCALTIME
Definition: primnodes.h:1541
@ SVFOP_CURRENT_TIMESTAMP_N
Definition: primnodes.h:1540
@ SVFOP_CURRENT_ROLE
Definition: primnodes.h:1545
@ SVFOP_USER
Definition: primnodes.h:1547
@ SVFOP_CURRENT_SCHEMA
Definition: primnodes.h:1550
@ SVFOP_LOCALTIMESTAMP_N
Definition: primnodes.h:1544
@ SVFOP_CURRENT_DATE
Definition: primnodes.h:1536
@ SVFOP_CURRENT_TIME_N
Definition: primnodes.h:1538
@ SVFOP_CURRENT_TIME
Definition: primnodes.h:1537
@ SVFOP_LOCALTIMESTAMP
Definition: primnodes.h:1543
@ SVFOP_CURRENT_USER
Definition: primnodes.h:1546
@ SVFOP_SESSION_USER
Definition: primnodes.h:1548
struct ExprEvalStep::@55::@72 sqlvaluefunction
SQLValueFunctionOp op
Definition: primnodes.h:1556
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52
static Datum TimestampGetDatum(Timestamp X)
Definition: timestamp.h:46

References current_database(), current_schema(), current_user(), DateADTGetDatum(), GetSQLCurrentDate(), GetSQLCurrentTime(), GetSQLCurrentTimestamp(), GetSQLLocalTime(), GetSQLLocalTimestamp(), InitFunctionCallInfoData, InvalidOid, LOCAL_FCINFO, ExprEvalStep::op, SQLValueFunction::op, session_user(), ExprEvalStep::svf, SVFOP_CURRENT_CATALOG, SVFOP_CURRENT_DATE, SVFOP_CURRENT_ROLE, SVFOP_CURRENT_SCHEMA, SVFOP_CURRENT_TIME, SVFOP_CURRENT_TIME_N, SVFOP_CURRENT_TIMESTAMP, SVFOP_CURRENT_TIMESTAMP_N, SVFOP_CURRENT_USER, SVFOP_LOCALTIME, SVFOP_LOCALTIME_N, SVFOP_LOCALTIMESTAMP, SVFOP_LOCALTIMESTAMP_N, SVFOP_SESSION_USER, SVFOP_USER, TimeADTGetDatum(), TimestampGetDatum(), TimestampTzGetDatum(), TimeTzADTPGetDatum(), and SQLValueFunction::typmod.

Referenced by ExecInterpExpr().

◆ ExecEvalStepOp()

ExprEvalOp ExecEvalStepOp ( ExprState state,
ExprEvalStep op 
)

Definition at line 2542 of file execExprInterp.c.

2543 {
2544 #if defined(EEO_USE_COMPUTED_GOTO)
2545  if (state->flags & EEO_FLAG_DIRECT_THREADED)
2546  {
2547  ExprEvalOpLookup key;
2548  ExprEvalOpLookup *res;
2549 
2550  key.opcode = (void *) op->opcode;
2551  res = bsearch(&key,
2552  reverse_dispatch_table,
2553  EEOP_LAST /* nmembers */ ,
2554  sizeof(ExprEvalOpLookup),
2555  dispatch_compare_ptr);
2556  Assert(res); /* unknown ops shouldn't get looked up */
2557  return res->op;
2558  }
2559 #endif
2560  return (ExprEvalOp) op->opcode;
2561 }
#define EEO_FLAG_DIRECT_THREADED
Definition: execExpr.h:31
intptr_t opcode
Definition: execExpr.h:290

References Assert, EEO_FLAG_DIRECT_THREADED, EEOP_LAST, sort-test::key, ExprEvalStep::op, and res.

Referenced by CheckExprStillValid().

◆ ExecEvalSubPlan()

void ExecEvalSubPlan ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 4892 of file execExprInterp.c.

4893 {
4894  SubPlanState *sstate = op->d.subplan.sstate;
4895 
4896  /* could potentially be nested, so make sure there's enough stack */
4898 
4899  *op->resvalue = ExecSubPlan(sstate, econtext, op->resnull);
4900 }
Datum ExecSubPlan(SubPlanState *node, ExprContext *econtext, bool *isNull)
Definition: nodeSubplan.c:62
void check_stack_depth(void)
Definition: postgres.c:3574
struct ExprEvalStep::@55::@95 subplan

References check_stack_depth(), ExecSubPlan(), ExprEvalStep::op, and ExprEvalStep::sstate.

Referenced by ExecInterpExpr().

◆ ExecEvalSysVar()

void ExecEvalSysVar ( ExprState state,
ExprEvalStep op,
ExprContext econtext,
TupleTableSlot slot 
)

Definition at line 5136 of file execExprInterp.c.

5138 {
5139  Datum d;
5140 
5141  /* slot_getsysattr has sufficient defenses against bad attnums */
5142  d = slot_getsysattr(slot,
5143  op->d.var.attnum,
5144  op->resnull);
5145  *op->resvalue = d;
5146  /* this ought to be unreachable, but it's cheap enough to check */
5147  if (unlikely(*op->resnull))
5148  elog(ERROR, "failed to fetch attribute from slot");
5149 }
static Datum slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: tuptable.h:416

References ExprEvalStep::d, elog, ERROR, ExprEvalStep::op, slot_getsysattr(), and unlikely.

Referenced by ExecInterpExpr().

◆ ExecEvalWholeRowVar()

void ExecEvalWholeRowVar ( ExprState state,
ExprEvalStep op,
ExprContext econtext 
)

Definition at line 4909 of file execExprInterp.c.

4910 {
4911  Var *variable = op->d.wholerow.var;
4912  TupleTableSlot *slot;
4913  TupleDesc output_tupdesc;
4914  MemoryContext oldcontext;
4915  HeapTupleHeader dtuple;
4916  HeapTuple tuple;
4917 
4918  /* This was checked by ExecInitExpr */
4919  Assert(variable->varattno == InvalidAttrNumber);
4920 
4921  /* Get the input slot we want */
4922  switch (variable->varno)
4923  {
4924  case INNER_VAR:
4925  /* get the tuple from the inner node */
4926  slot = econtext->ecxt_innertuple;
4927  break;
4928 
4929  case OUTER_VAR:
4930  /* get the tuple from the outer node */
4931  slot = econtext->ecxt_outertuple;
4932  break;
4933 
4934  /* INDEX_VAR is handled by default case */
4935 
4936  default:
4937  /* get the tuple from the relation being scanned */
4938  slot = econtext->ecxt_scantuple;
4939  break;
4940  }
4941 
4942  /* Apply the junkfilter if any */
4943  if (op->d.wholerow.junkFilter != NULL)
4944  slot = ExecFilterJunk(op->d.wholerow.junkFilter, slot);
4945 
4946  /*
4947  * If first time through, obtain tuple descriptor and check compatibility.
4948  *
4949  * XXX: It'd be great if this could be moved to the expression
4950  * initialization phase, but due to using slots that's currently not
4951  * feasible.
4952  */
4953  if (op->d.wholerow.first)
4954  {
4955  /* optimistically assume we don't need slow path */
4956  op->d.wholerow.slow = false;
4957 
4958  /*
4959  * If the Var identifies a named composite type, we must check that
4960  * the actual tuple type is compatible with it.
4961  */
4962  if (variable->vartype != RECORDOID)
4963  {
4964  TupleDesc var_tupdesc;
4965  TupleDesc slot_tupdesc;
4966 
4967  /*
4968  * We really only care about numbers of attributes and data types.
4969  * Also, we can ignore type mismatch on columns that are dropped
4970  * in the destination type, so long as (1) the physical storage
4971  * matches or (2) the actual column value is NULL. Case (1) is
4972  * helpful in some cases involving out-of-date cached plans, while
4973  * case (2) is expected behavior in situations such as an INSERT
4974  * into a table with dropped columns (the planner typically
4975  * generates an INT4 NULL regardless of the dropped column type).
4976  * If we find a dropped column and cannot verify that case (1)
4977  * holds, we have to use the slow path to check (2) for each row.
4978  *
4979  * If vartype is a domain over composite, just look through that
4980  * to the base composite type.
4981  */
4982  var_tupdesc = lookup_rowtype_tupdesc_domain(variable->vartype,
4983  -1, false);
4984 
4985  slot_tupdesc = slot->tts_tupleDescriptor;
4986 
4987  if (var_tupdesc->natts != slot_tupdesc->natts)
4988  ereport(ERROR,
4989  (errcode(ERRCODE_DATATYPE_MISMATCH),
4990  errmsg("table row type and query-specified row type do not match"),
4991  errdetail_plural("Table row contains %d attribute, but query expects %d.",
4992  "Table row contains %d attributes, but query expects %d.",
4993  slot_tupdesc->natts,
4994  slot_tupdesc->natts,
4995  var_tupdesc->natts)));
4996 
4997  for (int i = 0; i < var_tupdesc->natts; i++)
4998  {
4999  Form_pg_attribute vattr = TupleDescAttr(var_tupdesc, i);
5000  Form_pg_attribute sattr = TupleDescAttr(slot_tupdesc, i);
5001 
5002  if (vattr->atttypid == sattr->atttypid)
5003  continue; /* no worries */
5004  if (!vattr->attisdropped)
5005  ereport(ERROR,
5006  (errcode(ERRCODE_DATATYPE_MISMATCH),
5007  errmsg("table row type and query-specified row type do not match"),
5008  errdetail("Table has type %s at ordinal position %d, but query expects %s.",
5009  format_type_be(sattr->atttypid),
5010  i + 1,
5011  format_type_be(vattr->atttypid))));
5012 
5013  if (vattr->attlen != sattr->attlen ||
5014  vattr->attalign != sattr->attalign)
5015  op->d.wholerow.slow = true; /* need to check for nulls */
5016  }
5017 
5018  /*
5019  * Use the variable's declared rowtype as the descriptor for the
5020  * output values. In particular, we *must* absorb any
5021  * attisdropped markings.
5022  */
5023  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
5024  output_tupdesc = CreateTupleDescCopy(var_tupdesc);
5025  MemoryContextSwitchTo(oldcontext);
5026 
5027  ReleaseTupleDesc(var_tupdesc);
5028  }
5029  else
5030  {
5031  /*
5032  * In the RECORD case, we use the input slot's rowtype as the
5033  * descriptor for the output values, modulo possibly assigning new
5034  * column names below.
5035  */
5036  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
5037  output_tupdesc = CreateTupleDescCopy(slot->tts_tupleDescriptor);
5038  MemoryContextSwitchTo(oldcontext);
5039 
5040  /*
5041  * It's possible that the input slot is a relation scan slot and
5042  * so is marked with that relation's rowtype. But we're supposed
5043  * to be returning RECORD, so reset to that.
5044  */
5045  output_tupdesc->tdtypeid = RECORDOID;
5046  output_tupdesc->tdtypmod = -1;
5047 
5048  /*
5049  * We already got the correct physical datatype info above, but
5050  * now we should try to find the source RTE and adopt its column
5051  * aliases, since it's unlikely that the input slot has the
5052  * desired names.
5053  *
5054  * If we can't locate the RTE, assume the column names we've got
5055  * are OK. (As of this writing, the only cases where we can't
5056  * locate the RTE are in execution of trigger WHEN clauses, and
5057  * then the Var will have the trigger's relation's rowtype, so its
5058  * names are fine.) Also, if the creator of the RTE didn't bother
5059  * to fill in an eref field, assume our column names are OK. (This
5060  * happens in COPY, and perhaps other places.)
5061  */
5062  if (econtext->ecxt_estate &&
5063  variable->varno <= econtext->ecxt_estate->es_range_table_size)
5064  {
5065  RangeTblEntry *rte = exec_rt_fetch(variable->varno,
5066  econtext->ecxt_estate);
5067 
5068  if (rte->eref)
5069  ExecTypeSetColNames(output_tupdesc, rte->eref->colnames);
5070  }
5071  }
5072 
5073  /* Bless the tupdesc if needed, and save it in the execution state */
5074  op->d.wholerow.tupdesc = BlessTupleDesc(output_tupdesc);
5075 
5076  op->d.wholerow.first = false;
5077  }
5078 
5079  /*
5080  * Make sure all columns of the slot are accessible in the slot's
5081  * Datum/isnull arrays.
5082  */
5083  slot_getallattrs(slot);
5084 
5085  if (op->d.wholerow.slow)
5086  {
5087  /* Check to see if any dropped attributes are non-null */
5088  TupleDesc tupleDesc = slot->tts_tupleDescriptor;
5089  TupleDesc var_tupdesc = op->d.wholerow.tupdesc;
5090 
5091  Assert(var_tupdesc->natts == tupleDesc->natts);
5092 
5093  for (int i = 0; i < var_tupdesc->natts; i++)
5094  {
5095  Form_pg_attribute vattr = TupleDescAttr(var_tupdesc, i);
5096  Form_pg_attribute sattr = TupleDescAttr(tupleDesc, i);
5097 
5098  if (!vattr->attisdropped)
5099  continue; /* already checked non-dropped cols */
5100  if (slot->tts_isnull[i])
5101  continue; /* null is always okay */
5102  if (vattr->attlen != sattr->attlen ||
5103  vattr->attalign != sattr->attalign)
5104  ereport(ERROR,
5105  (errcode(ERRCODE_DATATYPE_MISMATCH),
5106  errmsg("table row type and query-specified row type do not match"),
5107  errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
5108  i + 1)));
5109  }
5110  }
5111 
5112  /*
5113  * Build a composite datum, making sure any toasted fields get detoasted.
5114  *
5115  * (Note: it is critical that we not change the slot's state here.)
5116  */
5118  slot->tts_values,
5119  slot->tts_isnull);
5120  dtuple = tuple->t_data;
5121 
5122  /*
5123  * Label the datum with the composite type info we identified before.
5124  *
5125  * (Note: we could skip doing this by passing op->d.wholerow.tupdesc to
5126  * the tuple build step; but that seems a tad risky so let's not.)
5127  */
5128  HeapTupleHeaderSetTypeId(dtuple, op->d.wholerow.tupdesc->tdtypeid);
5129  HeapTupleHeaderSetTypMod(dtuple, op->d.wholerow.tupdesc->tdtypmod);
5130 
5131  *op->resvalue = PointerGetDatum(dtuple);
5132  *op->resnull = false;
5133 }
#define InvalidAttrNumber
Definition: attnum.h:23
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1295
TupleTableSlot * ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
Definition: execJunk.c:247
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2158
void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList)
Definition: execTuples.c:2117
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:598
HeapTuple toast_build_flattened_tuple(TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptoast.c:563
#define HeapTupleHeaderSetTypMod(tup, typmod)
Definition: htup_details.h:471
#define HeapTupleHeaderSetTypeId(tup, typeid)
Definition: htup_details.h:461
#define OUTER_VAR
Definition: primnodes.h:237
#define INNER_VAR
Definition: primnodes.h:236
Index es_range_table_size
Definition: execnodes.h:635
struct EState * ecxt_estate
Definition: execnodes.h:294
struct ExprEvalStep::@55::@58 wholerow
int32 tdtypmod
Definition: tupdesc.h:83
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:123
Definition: primnodes.h:248
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:133
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:368
TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, bool noError)
Definition: typcache.c:1976

References Assert, BlessTupleDesc(), CreateTupleDescCopy(), ExprContext::ecxt_estate, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_per_query_memory, ExprContext::ecxt_scantuple, ereport, errcode(), errdetail(), errdetail_plural(), errmsg(), ERROR, EState::es_range_table_size, exec_rt_fetch(), ExecFilterJunk(), ExecTypeSetColNames(), format_type_be(), HeapTupleHeaderSetTypeId, HeapTupleHeaderSetTypMod, i, INNER_VAR, InvalidAttrNumber, lookup_rowtype_tupdesc_domain(), MemoryContextSwitchTo(), TupleDescData::natts, ExprEvalStep::op, OUTER_VAR, PointerGetDatum(), ReleaseTupleDesc, slot_getallattrs(), HeapTupleData::t_data, TupleDescData::tdtypeid, TupleDescData::tdtypmod, toast_build_flattened_tuple(), TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, TupleTableSlot::tts_values, and TupleDescAttr.

Referenced by ExecInterpExpr().

◆ ExecEvalXmlExpr()

void ExecEvalXmlExpr ( ExprState state,
ExprEvalStep op 
)

Definition at line 4024 of file execExprInterp.c.

4025 {
4026  XmlExpr *xexpr = op->d.xmlexpr.xexpr;
4027  Datum value;
4028 
4029  *op->resnull = true; /* until we get a result */
4030  *op->resvalue = (Datum) 0;
4031 
4032  switch (xexpr->op)
4033  {
4034  case IS_XMLCONCAT:
4035  {
4036  Datum *argvalue = op->d.xmlexpr.argvalue;
4037  bool *argnull = op->d.xmlexpr.argnull;
4038  List *values = NIL;
4039 
4040  for (int i = 0; i < list_length(xexpr->args); i++)
4041  {
4042  if (!argnull[i])
4043  values = lappend(values, DatumGetPointer(argvalue[i]));
4044  }
4045 
4046  if (values != NIL)
4047  {
4049  *op->resnull = false;
4050  }
4051  }
4052  break;
4053 
4054  case IS_XMLFOREST:
4055  {
4056  Datum *argvalue = op->d.xmlexpr.named_argvalue;
4057  bool *argnull = op->d.xmlexpr.named_argnull;
4059  ListCell *lc;
4060  ListCell *lc2;
4061  int i;
4062 
4063  initStringInfo(&buf);
4064 
4065  i = 0;
4066  forboth(lc, xexpr->named_args, lc2, xexpr->arg_names)
4067  {
4068  Expr *e = (Expr *) lfirst(lc);
4069  char *argname = strVal(lfirst(lc2));
4070 
4071  if (!argnull[i])
4072  {
4073  value = argvalue[i];
4074  appendStringInfo(&buf, "<%s>%s</%s>",
4075  argname,
4077  exprType((Node *) e), true),
4078  argname);
4079  *op->resnull = false;
4080  }
4081  i++;
4082  }
4083 
4084  if (!*op->resnull)
4085  {
4086  text *result;
4087 
4088  result = cstring_to_text_with_len(buf.data, buf.len);
4089  *op->resvalue = PointerGetDatum(result);
4090  }
4091 
4092  pfree(buf.data);
4093  }
4094  break;
4095 
4096  case IS_XMLELEMENT:
4097  *op->resvalue = PointerGetDatum(xmlelement(xexpr,
4098  op->d.xmlexpr.named_argvalue,
4099  op->d.xmlexpr.named_argnull,
4100  op->d.xmlexpr.argvalue,
4101  op->d.xmlexpr.argnull));
4102  *op->resnull = false;
4103  break;
4104 
4105  case IS_XMLPARSE:
4106  {
4107  Datum *argvalue = op->d.xmlexpr.argvalue;
4108  bool *argnull = op->d.xmlexpr.argnull;
4109  text *data;
4110  bool preserve_whitespace;
4111 
4112  /* arguments are known to be text, bool */
4113  Assert(list_length(xexpr->args) == 2);
4114 
4115  if (argnull[0])
4116  return;
4117  value = argvalue[0];
4119 
4120  if (argnull[1]) /* probably can't happen */
4121  return;
4122  value = argvalue[1];
4123  preserve_whitespace = DatumGetBool(value);
4124 
4126  xexpr->xmloption,
4127  preserve_whitespace));
4128  *op->resnull = false;
4129  }
4130  break;
4131 
4132  case IS_XMLPI:
4133  {
4134  text *arg;
4135  bool isnull;
4136 
4137  /* optional argument is known to be text */
4138  Assert(list_length(xexpr->args) <= 1);
4139 
4140  if (xexpr->args)
4141  {
4142  isnull = op->d.xmlexpr.argnull[0];
4143  if (isnull)
4144  arg = NULL;
4145  else
4146  arg = DatumGetTextPP(op->d.xmlexpr.argvalue[0]);
4147  }
4148  else
4149  {
4150  arg = NULL;
4151  isnull = false;
4152  }
4153 
4154  *op->resvalue = PointerGetDatum(xmlpi(xexpr->name,
4155  arg,
4156  isnull,
4157  op->resnull));
4158  }
4159  break;
4160 
4161  case IS_XMLROOT:
4162  {
4163  Datum *argvalue = op->d.xmlexpr.argvalue;
4164  bool *argnull = op->d.xmlexpr.argnull;
4165  xmltype *data;
4166  text *version;
4167  int standalone;
4168 
4169  /* arguments are known to be xml, text, int */
4170  Assert(list_length(xexpr->args) == 3);
4171 
4172  if (argnull[0])
4173  return;
4174  data = DatumGetXmlP(argvalue[0]);
4175 
4176  if (argnull[1])
4177  version = NULL;
4178  else
4179  version = DatumGetTextPP(argvalue[1]);
4180 
4181  Assert(!argnull[2]); /* always present */
4182  standalone = DatumGetInt32(argvalue[2]);
4183 
4185  version,
4186  standalone));
4187  *op->resnull = false;
4188  }
4189  break;
4190 
4191  case IS_XMLSERIALIZE:
4192  {
4193  Datum *argvalue = op->d.xmlexpr.argvalue;
4194  bool *argnull = op->d.xmlexpr.argnull;
4195 
4196  /* argument type is known to be xml */
4197  Assert(list_length(xexpr->args) == 1);
4198 
4199  if (argnull[0])
4200  return;
4201  value = argvalue[0];
4202 
4203  *op->resvalue =
4205  xexpr->xmloption,
4206  xexpr->indent));
4207  *op->resnull = false;
4208  }
4209  break;
4210 
4211  case IS_DOCUMENT:
4212  {
4213  Datum *argvalue = op->d.xmlexpr.argvalue;
4214  bool *argnull = op->d.xmlexpr.argnull;
4215 
4216  /* optional argument is known to be xml */
4217  Assert(list_length(xexpr->args) == 1);
4218 
4219  if (argnull[0])
4220  return;
4221  value = argvalue[0];
4222 
4223  *op->resvalue =
4225  *op->resnull = false;
4226  }
4227  break;
4228 
4229  default:
4230  elog(ERROR, "unrecognized XML operation");
4231  break;
4232  }
4233 }
#define DatumGetTextPP(X)
Definition: fmgr.h:292
List * lappend(List *list, void *datum)
Definition: list.c:339
void * arg
const void * data
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:518
static char * buf
Definition: pg_test_fsync.c:72
e
Definition: preproc-init.c:82
@ IS_DOCUMENT
Definition: primnodes.h:1587
@ IS_XMLFOREST
Definition: primnodes.h:1582
@ IS_XMLCONCAT
Definition: primnodes.h:1580
@ IS_XMLPI
Definition: primnodes.h:1584
@ IS_XMLPARSE
Definition: primnodes.h:1583
@ IS_XMLSERIALIZE
Definition: primnodes.h:1586
@ IS_XMLROOT
Definition: primnodes.h:1585
@ IS_XMLELEMENT
Definition: primnodes.h:1581
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:94
void initStringInfo(StringInfo str)
Definition: stringinfo.c:56
struct ExprEvalStep::@55::@90 xmlexpr
Definition: pg_list.h:54
List * args
Definition: primnodes.h:1608
bool indent
Definition: primnodes.h:1612
List * named_args
Definition: primnodes.h:1604
XmlExprOp op
Definition: primnodes.h:1600
#define strVal(v)
Definition: value.h:82
xmltype * xmlconcat(List *args)
Definition: xml.c:553
text * xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
Definition: xml.c:656
xmltype * xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
Definition: xml.c:981
bool xml_is_document(xmltype *arg)
Definition: xml.c:1117
xmltype * xmlpi(const char *target, text *arg, bool arg_is_null, bool *result_is_null)
Definition: xml.c:999
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2476
xmltype * xmlelement(XmlExpr *xexpr, Datum *named_argvalue, bool *named_argnull, Datum *argvalue, bool *argnull)
Definition: xml.c:857
xmltype * xmlroot(xmltype *data, text *version, int standalone)
Definition: xml.c:1051
static xmltype * DatumGetXmlP(Datum X)
Definition: xml.h:51

References appendStringInfo(), arg, ExprEvalStep::argnull, XmlExpr::args, ExprEvalStep::argvalue, Assert, BoolGetDatum(), buf, cstring_to_text_with_len(), data, DatumGetBool(), DatumGetInt32(), DatumGetPointer(), DatumGetTextPP, DatumGetXmlP(), elog, ERROR, exprType(), forboth, i, XmlExpr::indent, initStringInfo(), IS_DOCUMENT, IS_XMLCONCAT, IS_XMLELEMENT, IS_XMLFOREST, IS_XMLPARSE, IS_XMLPI, IS_XMLROOT, IS_XMLSERIALIZE, ExprEvalStep::isnull, lappend(), lfirst, list_length(), map_sql_value_to_xml_value(), XmlExpr::named_args, NIL, ExprEvalStep::op, XmlExpr::op, pfree(), PointerGetDatum(), strVal, value, values, ExprEvalStep::xexpr, xml_is_document(), xmlconcat(), xmlelement(), xmlparse(), xmlpi(), xmlroot(), and xmltotext_with_options().

Referenced by ExecInterpExpr().

◆ ExecInterpExprStillValid()

Datum ExecInterpExprStillValid ( ExprState state,
ExprContext econtext,
bool *  isNull 
)

Definition at line 2035 of file execExprInterp.c.

2036 {
2037  /*
2038  * First time through, check whether attribute matches Var. Might not be
2039  * ok anymore, due to schema changes.
2040  */
2041  CheckExprStillValid(state, econtext);
2042 
2043  /* skip the check during further executions */
2044  state->evalfunc = (ExprStateEvalFunc) state->evalfunc_private;
2045 
2046  /* and actually execute */
2047  return state->evalfunc(state, econtext, isNull);
2048 }
void CheckExprStillValid(ExprState *state, ExprContext *econtext)
Datum(* ExprStateEvalFunc)(struct ExprState *expression, struct ExprContext *econtext, bool *isNull)
Definition: execnodes.h:70

References CheckExprStillValid().

Referenced by ExecReadyInterpretedExpr().

◆ ExecReadyInterpretedExpr()

void ExecReadyInterpretedExpr ( ExprState state)

Definition at line 236 of file execExprInterp.c.

237 {
238  /* Ensure one-time interpreter setup has been done */
240 
241  /* Simple validity checks on expression */
242  Assert(state->steps_len >= 1);
243  Assert(state->steps[state->steps_len - 1].opcode == EEOP_DONE);
244 
245  /*
246  * Don't perform redundant initialization. This is unreachable in current
247  * cases, but might be hit if there's additional expression evaluation
248  * methods that rely on interpreted execution to work.
249  */
251  return;
252 
253  /*
254  * First time through, check whether attribute matches Var. Might not be
255  * ok anymore, due to schema changes. We do that by setting up a callback
256  * that does checking on the first call, which then sets the evalfunc
257  * callback to the actual method of execution.
258  */
259  state->evalfunc = ExecInterpExprStillValid;
260 
261  /* DIRECT_THREADED should not already be set */
262  Assert((state->flags & EEO_FLAG_DIRECT_THREADED) == 0);
263 
264  /*
265  * There shouldn't be any errors before the expression is fully
266  * initialized, and even if so, it'd lead to the expression being
267  * abandoned. So we can set the flag now and save some code.
268  */
270 
271  /*
272  * Select fast-path evalfuncs for very simple expressions. "Starting up"
273  * the full interpreter is a measurable overhead for these, and these
274  * patterns occur often enough to be worth optimizing.
275  */
276  if (state->steps_len == 3)
277  {
278  ExprEvalOp step0 = state->steps[0].opcode;
279  ExprEvalOp step1 = state->steps[1].opcode;
280 
281  if (step0 == EEOP_INNER_FETCHSOME &&
282  step1 == EEOP_INNER_VAR)
283  {
284  state->evalfunc_private = ExecJustInnerVar;
285  return;
286  }
287  else if (step0 == EEOP_OUTER_FETCHSOME &&
288  step1 == EEOP_OUTER_VAR)
289  {
290  state->evalfunc_private = ExecJustOuterVar;
291  return;
292  }
293  else if (step0 == EEOP_SCAN_FETCHSOME &&
294  step1 == EEOP_SCAN_VAR)
295  {
296  state->evalfunc_private = ExecJustScanVar;
297  return;
298  }
299  else if (step0 == EEOP_INNER_FETCHSOME &&
300  step1 == EEOP_ASSIGN_INNER_VAR)
301  {
302  state->evalfunc_private = ExecJustAssignInnerVar;
303  return;
304  }
305  else if (step0 == EEOP_OUTER_FETCHSOME &&
306  step1 == EEOP_ASSIGN_OUTER_VAR)
307  {
308  state->evalfunc_private = ExecJustAssignOuterVar;
309  return;
310  }
311  else if (step0 == EEOP_SCAN_FETCHSOME &&
312  step1 == EEOP_ASSIGN_SCAN_VAR)
313  {
314  state->evalfunc_private = ExecJustAssignScanVar;
315  return;
316  }
317  else if (step0 == EEOP_CASE_TESTVAL &&
318  step1 == EEOP_FUNCEXPR_STRICT &&
319  state->steps[0].d.casetest.value)
320  {
321  state->evalfunc_private = ExecJustApplyFuncToCase;
322  return;
323  }
324  }
325  else if (state->steps_len == 2)
326  {
327  ExprEvalOp step0 = state->steps[0].opcode;
328 
329  if (step0 == EEOP_CONST)
330  {
331  state->evalfunc_private = ExecJustConst;
332  return;
333  }
334  else if (step0 == EEOP_INNER_VAR)
335  {
336  state->evalfunc_private = ExecJustInnerVarVirt;
337  return;
338  }
339  else if (step0 == EEOP_OUTER_VAR)
340  {
341  state->evalfunc_private = ExecJustOuterVarVirt;
342  return;
343  }
344  else if (step0 == EEOP_SCAN_VAR)
345  {
346  state->evalfunc_private = ExecJustScanVarVirt;
347  return;
348  }
349  else if (step0 == EEOP_ASSIGN_INNER_VAR)
350  {
351  state->evalfunc_private = ExecJustAssignInnerVarVirt;
352  return;
353  }
354  else if (step0 == EEOP_ASSIGN_OUTER_VAR)
355  {
356  state->evalfunc_private = ExecJustAssignOuterVarVirt;
357  return;
358  }
359  else if (step0 == EEOP_ASSIGN_SCAN_VAR)
360  {
361  state->evalfunc_private = ExecJustAssignScanVarVirt;
362  return;
363  }
364  }
365 
366 #if defined(EEO_USE_COMPUTED_GOTO)
367 
368  /*
369  * In the direct-threaded implementation, replace each opcode with the
370  * address to jump to. (Use ExecEvalStepOp() to get back the opcode.)
371  */
372  for (int off = 0; off < state->steps_len; off++)
373  {
374  ExprEvalStep *op = &state->steps[off];
375 
376  op->opcode = EEO_OPCODE(op->opcode);
377  }
378 
380 #endif /* EEO_USE_COMPUTED_GOTO */
381 
382  state->evalfunc_private = ExecInterpExpr;
383 }
static Datum ExecJustAssignInnerVarVirt(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustScanVarVirt(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull)
Datum ExecInterpExprStillValid(ExprState *state, ExprContext *econtext, bool *isNull)
static Datum ExecJustAssignScanVar(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustInnerVarVirt(ExprState *state, ExprContext *econtext, bool *isnull)
static void ExecInitInterpreter(void)
static Datum ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustOuterVar(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustInnerVar(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustAssignInnerVar(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustAssignScanVarVirt(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustAssignOuterVar(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustAssignOuterVarVirt(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustOuterVarVirt(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecJustScanVar(ExprState *state, ExprContext *econtext, bool *isnull)
static Datum ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
#define EEO_OPCODE(opcode)
#define EEO_FLAG_INTERPRETER_INITIALIZED
Definition: execExpr.h:29

References Assert, EEO_FLAG_DIRECT_THREADED, EEO_FLAG_INTERPRETER_INITIALIZED, EEO_OPCODE, EEOP_ASSIGN_INNER_VAR, EEOP_ASSIGN_OUTER_VAR, EEOP_ASSIGN_SCAN_VAR, EEOP_CASE_TESTVAL, EEOP_CONST, EEOP_DONE, EEOP_FUNCEXPR_STRICT, EEOP_INNER_FETCHSOME, EEOP_INNER_VAR, EEOP_OUTER_FETCHSOME, EEOP_OUTER_VAR, EEOP_SCAN_FETCHSOME, EEOP_SCAN_VAR, ExecInitInterpreter(), ExecInterpExpr(), ExecInterpExprStillValid(), ExecJustApplyFuncToCase(), ExecJustAssignInnerVar(), ExecJustAssignInnerVarVirt(), ExecJustAssignOuterVar(), ExecJustAssignOuterVarVirt(), ExecJustAssignScanVar(), ExecJustAssignScanVarVirt(), ExecJustConst(), ExecJustInnerVar(), ExecJustInnerVarVirt(), ExecJustOuterVar(), ExecJustOuterVarVirt(), ExecJustScanVar(), ExecJustScanVarVirt(), and ExprEvalStep::op.

Referenced by ExecReadyExpr().

◆ ExprEvalPushStep()

void ExprEvalPushStep ( ExprState es,
const ExprEvalStep s 
)

Definition at line 2592 of file execExpr.c.

2593 {
2594  if (es->steps_alloc == 0)
2595  {
2596  es->steps_alloc = 16;
2597  es->steps = palloc(sizeof(ExprEvalStep) * es->steps_alloc);
2598  }
2599  else if (es->steps_alloc == es->steps_len)
2600  {
2601  es->steps_alloc *= 2;
2602  es->steps = repalloc(es->steps,
2603  sizeof(ExprEvalStep) * es->steps_alloc);
2604  }
2605 
2606  memcpy(&es->steps[es->steps_len++], s, sizeof(ExprEvalStep));
2607 }
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
struct ExprEvalStep * steps
Definition: execnodes.h:102
int steps_alloc
Definition: execnodes.h:122
int steps_len
Definition: execnodes.h:121

References palloc(), repalloc(), ExprState::steps, ExprState::steps_alloc, and ExprState::steps_len.

Referenced by ExecBuildAggTrans(), ExecBuildAggTransCall(), ExecBuildGroupingEqual(), ExecBuildHash32Expr(), ExecBuildParamSetEqual(), ExecBuildProjectionInfo(), ExecBuildUpdateProjection(), ExecInitCoerceToDomain(), ExecInitExpr(), ExecInitExprRec(), ExecInitExprWithParams(), ExecInitJsonCoercion(), ExecInitJsonExpr(), ExecInitQual(), ExecInitSubPlanExpr(), ExecInitSubscriptingRef(), ExecPushExprSetupSteps(), and plpgsql_param_compile().

◆ StaticAssertDecl()

StaticAssertDecl ( sizeof(ExprEvalStep)<=  64,
"size of ExprEvalStep exceeds 64 bytes"   
)