PostgreSQL Source Code  git master
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_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_CONVERT_ROWTYPE , EEOP_SCALARARRAYOP ,
  EEOP_HASHED_SCALARARRAYOP , EEOP_XMLEXPR , EEOP_JSON_CONSTRUCTOR , EEOP_IS_JSON ,
  EEOP_AGGREF , EEOP_GROUPING_FUNC , EEOP_WINDOW_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 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)
 
void ExecEvalGroupingFunc (ExprState *state, ExprEvalStep *op)
 
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_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_CONVERT_ROWTYPE 
EEOP_SCALARARRAYOP 
EEOP_HASHED_SCALARARRAYOP 
EEOP_XMLEXPR 
EEOP_JSON_CONSTRUCTOR 
EEOP_IS_JSON 
EEOP_AGGREF 
EEOP_GROUPING_FUNC 
EEOP_WINDOW_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 
164  /* return CaseTestExpr value */
166 
167  /* apply MakeExpandedObjectReadOnly() to target value */
169 
170  /* evaluate assorted special-purpose expression types */
175  EEOP_NULLIF,
181  EEOP_ROW,
182 
183  /*
184  * Compare two individual elements of each of two compared ROW()
185  * expressions. Skip to ROWCOMPARE_FINAL if elements are not equal.
186  */
188 
189  /* evaluate boolean value based on previous ROWCOMPARE_STEP operations */
191 
192  /* evaluate GREATEST() or LEAST() */
193  EEOP_MINMAX,
194 
195  /* evaluate FieldSelect expression */
197 
198  /*
199  * Deform tuple before evaluating new values for individual fields in a
200  * FieldStore expression.
201  */
203 
204  /*
205  * Form the new tuple for a FieldStore expression. Individual fields will
206  * have been evaluated into columns of the tuple deformed by the preceding
207  * DEFORM step.
208  */
210 
211  /* Process container subscripts; possibly short-circuit result to NULL */
213 
214  /*
215  * Compute old container element/slice when a SubscriptingRef assignment
216  * expression contains SubscriptingRef/FieldStore subexpressions. Value is
217  * accessed using the CaseTest mechanism.
218  */
220 
221  /* compute new value for SubscriptingRef assignment expression */
223 
224  /* compute element/slice for SubscriptingRef fetch expression */
226 
227  /* evaluate value for CoerceToDomainValue */
229 
230  /* evaluate a domain's NOT NULL constraint */
232 
233  /* evaluate a single domain CHECK constraint */
235 
236  /* evaluate assorted special-purpose expression types */
240  EEOP_XMLEXPR,
242  EEOP_IS_JSON,
243  EEOP_AGGREF,
246  EEOP_SUBPLAN,
247 
248  /* aggregation related nodes */
264 
265  /* non-existent operation, used e.g. to check array lengths */
266  EEOP_LAST
267 } ExprEvalOp;
ExprEvalOp
Definition: execExpr.h:67
@ EEOP_ASSIGN_TMP
Definition: execExpr.h:99
@ EEOP_SUBPLAN
Definition: execExpr.h:246
@ EEOP_CONVERT_ROWTYPE
Definition: execExpr.h:237
@ EEOP_FUNCEXPR_STRICT_FUSAGE
Definition: execExpr.h:114
@ EEOP_ARRAYEXPR
Definition: execExpr.h:179
@ EEOP_NOT_DISTINCT
Definition: execExpr.h:174
@ EEOP_DOMAIN_TESTVAL
Definition: execExpr.h:228
@ EEOP_PARAM_EXTERN
Definition: execExpr.h:161
@ EEOP_IOCOERCE_SAFE
Definition: execExpr.h:172
@ EEOP_BOOL_AND_STEP
Definition: execExpr.h:123
@ EEOP_WHOLEROW
Definition: execExpr.h:87
@ EEOP_AGGREF
Definition: execExpr.h:243
@ EEOP_INNER_VAR
Definition: execExpr.h:77
@ EEOP_AGG_PLAIN_PERGROUP_NULLCHECK
Definition: execExpr.h:253
@ EEOP_ROWCOMPARE_FINAL
Definition: execExpr.h:190
@ EEOP_AGG_STRICT_DESERIALIZE
Definition: execExpr.h:249
@ EEOP_IOCOERCE
Definition: execExpr.h:171
@ EEOP_GROUPING_FUNC
Definition: execExpr.h:244
@ EEOP_DOMAIN_CHECK
Definition: execExpr.h:234
@ EEOP_BOOLTEST_IS_NOT_FALSE
Definition: execExpr.h:157
@ EEOP_NEXTVALUEEXPR
Definition: execExpr.h:178
@ EEOP_DONE
Definition: execExpr.h:69
@ EEOP_AGG_PLAIN_TRANS_BYREF
Definition: execExpr.h:259
@ EEOP_QUAL
Definition: execExpr.h:135
@ EEOP_AGG_PRESORTED_DISTINCT_MULTI
Definition: execExpr.h:261
@ EEOP_AGG_PLAIN_TRANS_BYVAL
Definition: execExpr.h:256
@ 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:238
@ EEOP_DOMAIN_NOTNULL
Definition: execExpr.h:231
@ EEOP_WINDOW_FUNC
Definition: execExpr.h:245
@ 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:181
@ EEOP_MAKE_READONLY
Definition: execExpr.h:168
@ EEOP_FIELDSTORE_FORM
Definition: execExpr.h:209
@ EEOP_SBSREF_SUBSCRIPTS
Definition: execExpr.h:212
@ EEOP_SBSREF_FETCH
Definition: execExpr.h:225
@ EEOP_FUNCEXPR_STRICT
Definition: execExpr.h:112
@ EEOP_NULLIF
Definition: execExpr.h:175
@ EEOP_CURRENTOFEXPR
Definition: execExpr.h:177
@ 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_BOOL_OR_STEP_FIRST
Definition: execExpr.h:127
@ EEOP_XMLEXPR
Definition: execExpr.h:240
@ EEOP_AGG_STRICT_INPUT_CHECK_NULLS
Definition: execExpr.h:252
@ EEOP_SBSREF_ASSIGN
Definition: execExpr.h:222
@ 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:251
@ 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:187
@ EEOP_AGG_DESERIALIZE
Definition: execExpr.h:250
@ EEOP_LAST
Definition: execExpr.h:266
@ EEOP_DISTINCT
Definition: execExpr.h:173
@ EEOP_JUMP_IF_NOT_TRUE
Definition: execExpr.h:143
@ EEOP_FUNCEXPR_FUSAGE
Definition: execExpr.h:113
@ EEOP_AGG_PRESORTED_DISTINCT_SINGLE
Definition: execExpr.h:260
@ 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:262
@ EEOP_SBSREF_OLD
Definition: execExpr.h:219
@ EEOP_SQLVALUEFUNCTION
Definition: execExpr.h:176
@ EEOP_JUMP_IF_NOT_NULL
Definition: execExpr.h:142
@ EEOP_AGG_PLAIN_TRANS_STRICT_BYREF
Definition: execExpr.h:258
@ EEOP_FIELDSTORE_DEFORM
Definition: execExpr.h:202
@ 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:254
@ EEOP_PARAM_EXEC
Definition: execExpr.h:160
@ EEOP_JSON_CONSTRUCTOR
Definition: execExpr.h:241
@ EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL
Definition: execExpr.h:255
@ EEOP_NULLTEST_ISNULL
Definition: execExpr.h:146
@ EEOP_MINMAX
Definition: execExpr.h:193
@ EEOP_JUMP_IF_NULL
Definition: execExpr.h:141
@ EEOP_ARRAYCOERCE
Definition: execExpr.h:180
@ EEOP_FIELDSELECT
Definition: execExpr.h:196
@ EEOP_CASE_TESTVAL
Definition: execExpr.h:165
@ EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF
Definition: execExpr.h:257
@ EEOP_HASHED_SCALARARRAYOP
Definition: execExpr.h:239
@ EEOP_OUTER_VAR
Definition: execExpr.h:78
@ EEOP_AGG_ORDERED_TRANS_TUPLE
Definition: execExpr.h:263
@ EEOP_SCAN_FETCHSOME
Definition: execExpr.h:74
@ EEOP_IS_JSON
Definition: execExpr.h:242

Function Documentation

◆ CheckExprStillValid()

void CheckExprStillValid ( ExprState state,
ExprContext econtext 
)

Definition at line 1889 of file execExprInterp.c.

1890 {
1891  TupleTableSlot *innerslot;
1892  TupleTableSlot *outerslot;
1893  TupleTableSlot *scanslot;
1894 
1895  innerslot = econtext->ecxt_innertuple;
1896  outerslot = econtext->ecxt_outertuple;
1897  scanslot = econtext->ecxt_scantuple;
1898 
1899  for (int i = 0; i < state->steps_len; i++)
1900  {
1901  ExprEvalStep *op = &state->steps[i];
1902 
1903  switch (ExecEvalStepOp(state, op))
1904  {
1905  case EEOP_INNER_VAR:
1906  {
1907  int attnum = op->d.var.attnum;
1908 
1909  CheckVarSlotCompatibility(innerslot, attnum + 1, op->d.var.vartype);
1910  break;
1911  }
1912 
1913  case EEOP_OUTER_VAR:
1914  {
1915  int attnum = op->d.var.attnum;
1916 
1917  CheckVarSlotCompatibility(outerslot, attnum + 1, op->d.var.vartype);
1918  break;
1919  }
1920 
1921  case EEOP_SCAN_VAR:
1922  {
1923  int attnum = op->d.var.attnum;
1924 
1925  CheckVarSlotCompatibility(scanslot, attnum + 1, op->d.var.vartype);
1926  break;
1927  }
1928  default:
1929  break;
1930  }
1931  }
1932 }
static void CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype)
ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op)
int i
Definition: isn.c:73
int16 attnum
Definition: pg_attribute.h:74
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:257
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:255
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:259
union ExprEvalStep::@51 d
struct ExprEvalStep::@51::@53 var
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 4570 of file execExprInterp.c.

4573 {
4574  Assert(newValue != oldValue);
4575 
4576  if (!newValueIsNull)
4577  {
4579  if (DatumIsReadWriteExpandedObject(newValue,
4580  false,
4581  pertrans->transtypeLen) &&
4582  MemoryContextGetParent(DatumGetEOHP(newValue)->eoh_context) == CurrentMemoryContext)
4583  /* do nothing */ ;
4584  else
4585  newValue = datumCopy(newValue,
4586  pertrans->transtypeByVal,
4587  pertrans->transtypeLen);
4588  }
4589  else
4590  {
4591  /*
4592  * Ensure that AggStatePerGroup->transValue ends up being 0, so
4593  * callers can safely compare newValue/oldValue without having to
4594  * check their respective nullness.
4595  */
4596  newValue = (Datum) 0;
4597  }
4598 
4599  if (!oldValueIsNull)
4600  {
4601  if (DatumIsReadWriteExpandedObject(oldValue,
4602  false,
4603  pertrans->transtypeLen))
4604  DeleteExpandedObject(oldValue);
4605  else
4606  pfree(DatumGetPointer(oldValue));
4607  }
4608 
4609  return newValue;
4610 }
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)
Assert(fmt[strlen(fmt) - 1] !='\n')
void pfree(void *pointer)
Definition: mcxt.c:1431
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
MemoryContext MemoryContextGetParent(MemoryContext context)
Definition: mcxt.c:640
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
uintptr_t Datum
Definition: postgres.h:64
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
ExprContext * curaggcontext
Definition: execnodes.h:2400
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:263

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 4517 of file execExprInterp.c.

4519 {
4520  FunctionCallInfo fcinfo = pertrans->transfn_fcinfo;
4521  MemoryContext oldContext;
4522 
4523  /*
4524  * We must copy the datum into aggcontext if it is pass-by-ref. We do not
4525  * need to pfree the old transValue, since it's NULL. (We already checked
4526  * that the agg's input type is binary-compatible with its transtype, so
4527  * straight copy here is OK.)
4528  */
4529  oldContext = MemoryContextSwitchTo(aggcontext->ecxt_per_tuple_memory);
4530  pergroup->transValue = datumCopy(fcinfo->args[1].value,
4531  pertrans->transtypeByVal,
4532  pertrans->transtypeLen);
4533  pergroup->transValueIsNull = false;
4534  pergroup->noTransValue = false;
4535  MemoryContextSwitchTo(oldContext);
4536 }
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 4709 of file execExprInterp.c.

4711 {
4712  AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
4713  int setno = op->d.agg_trans.setno;
4714 
4715  tuplesort_putdatum(pertrans->sortstates[setno],
4716  *op->resvalue, *op->resnull);
4717 }
Tuplesortstate ** sortstates
Definition: nodeAgg.h:162
Datum * resvalue
Definition: execExpr.h:280
struct ExprEvalStep::@51::@94 agg_trans
bool * resnull
Definition: execExpr.h:281
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 4723 of file execExprInterp.c.

4725 {
4726  AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
4727  int setno = op->d.agg_trans.setno;
4728 
4729  ExecClearTuple(pertrans->sortslot);
4730  pertrans->sortslot->tts_nvalid = pertrans->numInputs;
4731  ExecStoreVirtualTuple(pertrans->sortslot);
4732  tuplesort_puttupleslot(pertrans->sortstates[setno], pertrans->sortslot);
4733 }
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1551
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:433

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 3013 of file execExprInterp.c.

3014 {
3015  Datum arraydatum;
3016 
3017  /* NULL array -> NULL result */
3018  if (*op->resnull)
3019  return;
3020 
3021  arraydatum = *op->resvalue;
3022 
3023  /*
3024  * If it's binary-compatible, modify the element type in the array header,
3025  * but otherwise leave the array as we received it.
3026  */
3027  if (op->d.arraycoerce.elemexprstate == NULL)
3028  {
3029  /* Detoast input array if necessary, and copy in any case */
3030  ArrayType *array = DatumGetArrayTypePCopy(arraydatum);
3031 
3032  ARR_ELEMTYPE(array) = op->d.arraycoerce.resultelemtype;
3033  *op->resvalue = PointerGetDatum(array);
3034  return;
3035  }
3036 
3037  /*
3038  * Use array_map to apply the sub-expression to each array element.
3039  */
3040  *op->resvalue = array_map(arraydatum,
3041  op->d.arraycoerce.elemexprstate,
3042  econtext,
3043  op->d.arraycoerce.resultelemtype,
3044  op->d.arraycoerce.amstate);
3045 }
#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:3195
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
struct ExprEvalStep::@51::@71 arraycoerce

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

Referenced by ExecInterpExpr().

◆ ExecEvalArrayExpr()

void ExecEvalArrayExpr ( ExprState state,
ExprEvalStep op 
)

Definition at line 2799 of file execExprInterp.c.

2800 {
2801  ArrayType *result;
2802  Oid element_type = op->d.arrayexpr.elemtype;
2803  int nelems = op->d.arrayexpr.nelems;
2804  int ndims = 0;
2805  int dims[MAXDIM];
2806  int lbs[MAXDIM];
2807 
2808  /* Set non-null as default */
2809  *op->resnull = false;
2810 
2811  if (!op->d.arrayexpr.multidims)
2812  {
2813  /* Elements are presumably of scalar type */
2814  Datum *dvalues = op->d.arrayexpr.elemvalues;
2815  bool *dnulls = op->d.arrayexpr.elemnulls;
2816 
2817  /* setup for 1-D array of the given length */
2818  ndims = 1;
2819  dims[0] = nelems;
2820  lbs[0] = 1;
2821 
2822  result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
2823  element_type,
2824  op->d.arrayexpr.elemlength,
2825  op->d.arrayexpr.elembyval,
2826  op->d.arrayexpr.elemalign);
2827  }
2828  else
2829  {
2830  /* Must be nested array expressions */
2831  int nbytes = 0;
2832  int nitems;
2833  int outer_nelems = 0;
2834  int elem_ndims = 0;
2835  int *elem_dims = NULL;
2836  int *elem_lbs = NULL;
2837  bool firstone = true;
2838  bool havenulls = false;
2839  bool haveempty = false;
2840  char **subdata;
2841  bits8 **subbitmaps;
2842  int *subbytes;
2843  int *subnitems;
2844  int32 dataoffset;
2845  char *dat;
2846  int iitem;
2847 
2848  subdata = (char **) palloc(nelems * sizeof(char *));
2849  subbitmaps = (bits8 **) palloc(nelems * sizeof(bits8 *));
2850  subbytes = (int *) palloc(nelems * sizeof(int));
2851  subnitems = (int *) palloc(nelems * sizeof(int));
2852 
2853  /* loop through and get data area from each element */
2854  for (int elemoff = 0; elemoff < nelems; elemoff++)
2855  {
2856  Datum arraydatum;
2857  bool eisnull;
2858  ArrayType *array;
2859  int this_ndims;
2860 
2861  arraydatum = op->d.arrayexpr.elemvalues[elemoff];
2862  eisnull = op->d.arrayexpr.elemnulls[elemoff];
2863 
2864  /* temporarily ignore null subarrays */
2865  if (eisnull)
2866  {
2867  haveempty = true;
2868  continue;
2869  }
2870 
2871  array = DatumGetArrayTypeP(arraydatum);
2872 
2873  /* run-time double-check on element type */
2874  if (element_type != ARR_ELEMTYPE(array))
2875  ereport(ERROR,
2876  (errcode(ERRCODE_DATATYPE_MISMATCH),
2877  errmsg("cannot merge incompatible arrays"),
2878  errdetail("Array with element type %s cannot be "
2879  "included in ARRAY construct with element type %s.",
2880  format_type_be(ARR_ELEMTYPE(array)),
2881  format_type_be(element_type))));
2882 
2883  this_ndims = ARR_NDIM(array);
2884  /* temporarily ignore zero-dimensional subarrays */
2885  if (this_ndims <= 0)
2886  {
2887  haveempty = true;
2888  continue;
2889  }
2890 
2891  if (firstone)
2892  {
2893  /* Get sub-array details from first member */
2894  elem_ndims = this_ndims;
2895  ndims = elem_ndims + 1;
2896  if (ndims <= 0 || ndims > MAXDIM)
2897  ereport(ERROR,
2898  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2899  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
2900  ndims, MAXDIM)));
2901 
2902  elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2903  memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2904  elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2905  memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2906 
2907  firstone = false;
2908  }
2909  else
2910  {
2911  /* Check other sub-arrays are compatible */
2912  if (elem_ndims != this_ndims ||
2913  memcmp(elem_dims, ARR_DIMS(array),
2914  elem_ndims * sizeof(int)) != 0 ||
2915  memcmp(elem_lbs, ARR_LBOUND(array),
2916  elem_ndims * sizeof(int)) != 0)
2917  ereport(ERROR,
2918  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2919  errmsg("multidimensional arrays must have array "
2920  "expressions with matching dimensions")));
2921  }
2922 
2923  subdata[outer_nelems] = ARR_DATA_PTR(array);
2924  subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
2925  subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
2926  nbytes += subbytes[outer_nelems];
2927  /* check for overflow of total request */
2928  if (!AllocSizeIsValid(nbytes))
2929  ereport(ERROR,
2930  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2931  errmsg("array size exceeds the maximum allowed (%d)",
2932  (int) MaxAllocSize)));
2933  subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
2934  ARR_DIMS(array));
2935  havenulls |= ARR_HASNULL(array);
2936  outer_nelems++;
2937  }
2938 
2939  /*
2940  * If all items were null or empty arrays, return an empty array;
2941  * otherwise, if some were and some weren't, raise error. (Note: we
2942  * must special-case this somehow to avoid trying to generate a 1-D
2943  * array formed from empty arrays. It's not ideal...)
2944  */
2945  if (haveempty)
2946  {
2947  if (ndims == 0) /* didn't find any nonempty array */
2948  {
2949  *op->resvalue = PointerGetDatum(construct_empty_array(element_type));
2950  return;
2951  }
2952  ereport(ERROR,
2953  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2954  errmsg("multidimensional arrays must have array "
2955  "expressions with matching dimensions")));
2956  }
2957 
2958  /* setup for multi-D array */
2959  dims[0] = outer_nelems;
2960  lbs[0] = 1;
2961  for (int i = 1; i < ndims; i++)
2962  {
2963  dims[i] = elem_dims[i - 1];
2964  lbs[i] = elem_lbs[i - 1];
2965  }
2966 
2967  /* check for subscript overflow */
2968  nitems = ArrayGetNItems(ndims, dims);
2969  ArrayCheckBounds(ndims, dims, lbs);
2970 
2971  if (havenulls)
2972  {
2973  dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
2974  nbytes += dataoffset;
2975  }
2976  else
2977  {
2978  dataoffset = 0; /* marker for no null bitmap */
2979  nbytes += ARR_OVERHEAD_NONULLS(ndims);
2980  }
2981 
2982  result = (ArrayType *) palloc0(nbytes);
2983  SET_VARSIZE(result, nbytes);
2984  result->ndim = ndims;
2985  result->dataoffset = dataoffset;
2986  result->elemtype = element_type;
2987  memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
2988  memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
2989 
2990  dat = ARR_DATA_PTR(result);
2991  iitem = 0;
2992  for (int i = 0; i < outer_nelems; i++)
2993  {
2994  memcpy(dat, subdata[i], subbytes[i]);
2995  dat += subbytes[i];
2996  if (havenulls)
2997  array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
2998  subbitmaps[i], 0,
2999  subnitems[i]);
3000  iitem += subnitems[i];
3001  }
3002  }
3003 
3004  *op->resvalue = PointerGetDatum(result);
3005 }
#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:3562
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:3476
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
Definition: arrayfuncs.c:4948
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:483
uint8 bits8
Definition: c.h:502
int errdetail(const char *fmt,...)
Definition: elog.c:1208
int errcode(int sqlerrcode)
Definition: elog.c:860
int errmsg(const char *fmt,...)
Definition: elog.c:1075
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
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:1232
void * palloc(Size size)
Definition: mcxt.c:1201
#define AllocSizeIsValid(size)
Definition: memutils.h:42
#define MaxAllocSize
Definition: memutils.h:40
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::@51::@70 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 2533 of file execExprInterp.c.

2534 {
2535  char *str;
2536 
2537  /* call output function (similar to OutputFunctionCall) */
2538  if (*op->resnull)
2539  {
2540  /* output functions are not called on nulls */
2541  str = NULL;
2542  }
2543  else
2544  {
2545  FunctionCallInfo fcinfo_out;
2546 
2547  fcinfo_out = op->d.iocoerce.fcinfo_data_out;
2548  fcinfo_out->args[0].value = *op->resvalue;
2549  fcinfo_out->args[0].isnull = false;
2550 
2551  fcinfo_out->isnull = false;
2552  str = DatumGetCString(FunctionCallInvoke(fcinfo_out));
2553 
2554  /* OutputFunctionCall assumes result isn't null */
2555  Assert(!fcinfo_out->isnull);
2556  }
2557 
2558  /* call input function (similar to InputFunctionCallSafe) */
2559  if (!op->d.iocoerce.finfo_in->fn_strict || str != NULL)
2560  {
2561  FunctionCallInfo fcinfo_in;
2562 
2563  fcinfo_in = op->d.iocoerce.fcinfo_data_in;
2564  fcinfo_in->args[0].value = PointerGetDatum(str);
2565  fcinfo_in->args[0].isnull = *op->resnull;
2566  /* second and third arguments are already set up */
2567 
2568  /* ErrorSaveContext must be present. */
2569  Assert(IsA(fcinfo_in->context, ErrorSaveContext));
2570 
2571  fcinfo_in->isnull = false;
2572  *op->resvalue = FunctionCallInvoke(fcinfo_in);
2573 
2574  if (SOFT_ERROR_OCCURRED(fcinfo_in->context))
2575  {
2576  *op->resnull = true;
2577  *op->resvalue = (Datum) 0;
2578  return;
2579  }
2580 
2581  /* Should get null result if and only if str is NULL */
2582  if (str == NULL)
2583  Assert(*op->resnull);
2584  else
2585  Assert(!*op->resnull);
2586  }
2587 }
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:172
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:52
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
struct ExprEvalStep::@51::@67 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, generate_unaccent_rules::str, and NullableDatum::value.

Referenced by ExecInterpExpr().

◆ ExecEvalConstraintCheck()

void ExecEvalConstraintCheck ( ExprState state,
ExprEvalStep op 
)

Definition at line 3820 of file execExprInterp.c.

3821 {
3822  if (!*op->d.domaincheck.checknull &&
3823  !DatumGetBool(*op->d.domaincheck.checkvalue))
3824  errsave((Node *) op->d.domaincheck.escontext,
3825  (errcode(ERRCODE_CHECK_VIOLATION),
3826  errmsg("value for domain %s violates check constraint \"%s\"",
3827  format_type_be(op->d.domaincheck.resulttype),
3828  op->d.domaincheck.constraintname),
3829  errdomainconstraint(op->d.domaincheck.resulttype,
3830  op->d.domaincheck.constraintname)));
3831 }
int errdomainconstraint(Oid datatypeOid, const char *conname)
Definition: domains.c:431
#define errsave(context,...)
Definition: elog.h:260
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
struct ExprEvalStep::@51::@80 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 3806 of file execExprInterp.c.

3807 {
3808  if (*op->resnull)
3809  errsave((Node *) op->d.domaincheck.escontext,
3810  (errcode(ERRCODE_NOT_NULL_VIOLATION),
3811  errmsg("domain %s does not allow null values",
3812  format_type_be(op->d.domaincheck.resulttype)),
3813  errdatatype(op->d.domaincheck.resulttype)));
3814 }
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 3326 of file execExprInterp.c.

3327 {
3328  HeapTuple result;
3329  Datum tupDatum;
3330  HeapTupleHeader tuple;
3331  HeapTupleData tmptup;
3332  TupleDesc indesc,
3333  outdesc;
3334  bool changed = false;
3335 
3336  /* NULL in -> NULL out */
3337  if (*op->resnull)
3338  return;
3339 
3340  tupDatum = *op->resvalue;
3341  tuple = DatumGetHeapTupleHeader(tupDatum);
3342 
3343  /*
3344  * Lookup tupdescs if first time through or if type changes. We'd better
3345  * pin them since type conversion functions could do catalog lookups and
3346  * hence cause cache invalidation.
3347  */
3348  indesc = get_cached_rowtype(op->d.convert_rowtype.inputtype, -1,
3349  op->d.convert_rowtype.incache,
3350  &changed);
3351  IncrTupleDescRefCount(indesc);
3352  outdesc = get_cached_rowtype(op->d.convert_rowtype.outputtype, -1,
3353  op->d.convert_rowtype.outcache,
3354  &changed);
3355  IncrTupleDescRefCount(outdesc);
3356 
3357  /*
3358  * We used to be able to assert that incoming tuples are marked with
3359  * exactly the rowtype of indesc. However, now that ExecEvalWholeRowVar
3360  * might change the tuples' marking to plain RECORD due to inserting
3361  * aliases, we can only make this weak test:
3362  */
3363  Assert(HeapTupleHeaderGetTypeId(tuple) == indesc->tdtypeid ||
3364  HeapTupleHeaderGetTypeId(tuple) == RECORDOID);
3365 
3366  /* if first time through, or after change, initialize conversion map */
3367  if (changed)
3368  {
3369  MemoryContext old_cxt;
3370 
3371  /* allocate map in long-lived memory context */
3372  old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
3373 
3374  /* prepare map from old to new attribute numbers */
3375  op->d.convert_rowtype.map = convert_tuples_by_name(indesc, outdesc);
3376 
3377  MemoryContextSwitchTo(old_cxt);
3378  }
3379 
3380  /* Following steps need a HeapTuple not a bare HeapTupleHeader */
3381  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3382  tmptup.t_data = tuple;
3383 
3384  if (op->d.convert_rowtype.map != NULL)
3385  {
3386  /* Full conversion with attribute rearrangement needed */
3387  result = execute_attr_map_tuple(&tmptup, op->d.convert_rowtype.map);
3388  /* Result already has appropriate composite-datum header fields */
3389  *op->resvalue = HeapTupleGetDatum(result);
3390  }
3391  else
3392  {
3393  /*
3394  * The tuple is physically compatible as-is, but we need to insert the
3395  * destination rowtype OID in its composite-datum header field, so we
3396  * have to copy it anyway. heap_copy_tuple_as_datum() is convenient
3397  * for this since it will both make the physical copy and insert the
3398  * correct composite header fields. Note that we aren't expecting to
3399  * have to flatten any toasted fields: the input was a composite
3400  * datum, so it shouldn't contain any. So heap_copy_tuple_as_datum()
3401  * is overkill here, but its check for external fields is cheap.
3402  */
3403  *op->resvalue = heap_copy_tuple_as_datum(&tmptup, outdesc);
3404  }
3405 
3406  DecrTupleDescRefCount(indesc);
3407  DecrTupleDescRefCount(outdesc);
3408 }
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:1081
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:456
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:450
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:262
struct ExprEvalStep::@51::@81 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 2660 of file execExprInterp.c.

2661 {
2662  ereport(ERROR,
2663  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2664  errmsg("WHERE CURRENT OF is not supported for this table type")));
2665 }

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

Referenced by ExecInterpExpr().

◆ ExecEvalFieldSelect()

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

Definition at line 3127 of file execExprInterp.c.

3128 {
3129  AttrNumber fieldnum = op->d.fieldselect.fieldnum;
3130  Datum tupDatum;
3131  HeapTupleHeader tuple;
3132  Oid tupType;
3133  int32 tupTypmod;
3134  TupleDesc tupDesc;
3135  Form_pg_attribute attr;
3136  HeapTupleData tmptup;
3137 
3138  /* NULL record -> NULL result */
3139  if (*op->resnull)
3140  return;
3141 
3142  tupDatum = *op->resvalue;
3143 
3144  /* We can special-case expanded records for speed */
3146  {
3148 
3149  Assert(erh->er_magic == ER_MAGIC);
3150 
3151  /* Extract record's TupleDesc */
3152  tupDesc = expanded_record_get_tupdesc(erh);
3153 
3154  /*
3155  * Find field's attr record. Note we don't support system columns
3156  * here: a datum tuple doesn't have valid values for most of the
3157  * interesting system columns anyway.
3158  */
3159  if (fieldnum <= 0) /* should never happen */
3160  elog(ERROR, "unsupported reference to system column %d in FieldSelect",
3161  fieldnum);
3162  if (fieldnum > tupDesc->natts) /* should never happen */
3163  elog(ERROR, "attribute number %d exceeds number of columns %d",
3164  fieldnum, tupDesc->natts);
3165  attr = TupleDescAttr(tupDesc, fieldnum - 1);
3166 
3167  /* Check for dropped column, and force a NULL result if so */
3168  if (attr->attisdropped)
3169  {
3170  *op->resnull = true;
3171  return;
3172  }
3173 
3174  /* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
3175  /* As in CheckVarSlotCompatibility, we should but can't check typmod */
3176  if (op->d.fieldselect.resulttype != attr->atttypid)
3177  ereport(ERROR,
3178  (errcode(ERRCODE_DATATYPE_MISMATCH),
3179  errmsg("attribute %d has wrong type", fieldnum),
3180  errdetail("Table has type %s, but query expects %s.",
3181  format_type_be(attr->atttypid),
3182  format_type_be(op->d.fieldselect.resulttype))));
3183 
3184  /* extract the field */
3185  *op->resvalue = expanded_record_get_field(erh, fieldnum,
3186  op->resnull);
3187  }
3188  else
3189  {
3190  /* Get the composite datum and extract its type fields */
3191  tuple = DatumGetHeapTupleHeader(tupDatum);
3192 
3193  tupType = HeapTupleHeaderGetTypeId(tuple);
3194  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3195 
3196  /* Lookup tupdesc if first time through or if type changes */
3197  tupDesc = get_cached_rowtype(tupType, tupTypmod,
3198  &op->d.fieldselect.rowcache, NULL);
3199 
3200  /*
3201  * Find field's attr record. Note we don't support system columns
3202  * here: a datum tuple doesn't have valid values for most of the
3203  * interesting system columns anyway.
3204  */
3205  if (fieldnum <= 0) /* should never happen */
3206  elog(ERROR, "unsupported reference to system column %d in FieldSelect",
3207  fieldnum);
3208  if (fieldnum > tupDesc->natts) /* should never happen */
3209  elog(ERROR, "attribute number %d exceeds number of columns %d",
3210  fieldnum, tupDesc->natts);
3211  attr = TupleDescAttr(tupDesc, fieldnum - 1);
3212 
3213  /* Check for dropped column, and force a NULL result if so */
3214  if (attr->attisdropped)
3215  {
3216  *op->resnull = true;
3217  return;
3218  }
3219 
3220  /* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
3221  /* As in CheckVarSlotCompatibility, we should but can't check typmod */
3222  if (op->d.fieldselect.resulttype != attr->atttypid)
3223  ereport(ERROR,
3224  (errcode(ERRCODE_DATATYPE_MISMATCH),
3225  errmsg("attribute %d has wrong type", fieldnum),
3226  errdetail("Table has type %s, but query expects %s.",
3227  format_type_be(attr->atttypid),
3228  format_type_be(op->d.fieldselect.resulttype))));
3229 
3230  /* heap_getattr needs a HeapTuple not a bare HeapTupleHeader */
3231  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3232  tmptup.t_data = tuple;
3233 
3234  /* extract the field */
3235  *op->resvalue = heap_getattr(&tmptup,
3236  fieldnum,
3237  tupDesc,
3238  op->resnull);
3239  }
3240 }
int16 AttrNumber
Definition: attnum.h:21
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::@51::@76 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 3252 of file execExprInterp.c.

3253 {
3254  if (*op->resnull)
3255  {
3256  /* Convert null input tuple into an all-nulls row */
3257  memset(op->d.fieldstore.nulls, true,
3258  op->d.fieldstore.ncolumns * sizeof(bool));
3259  }
3260  else
3261  {
3262  /*
3263  * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
3264  * set all the fields in the struct just in case.
3265  */
3266  Datum tupDatum = *op->resvalue;
3267  HeapTupleHeader tuphdr;
3268  HeapTupleData tmptup;
3269  TupleDesc tupDesc;
3270 
3271  tuphdr = DatumGetHeapTupleHeader(tupDatum);
3272  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
3273  ItemPointerSetInvalid(&(tmptup.t_self));
3274  tmptup.t_tableOid = InvalidOid;
3275  tmptup.t_data = tuphdr;
3276 
3277  /*
3278  * Lookup tupdesc if first time through or if type changes. Because
3279  * we don't pin the tupdesc, we must not do this lookup until after
3280  * doing DatumGetHeapTupleHeader: that could do database access while
3281  * detoasting the datum.
3282  */
3283  tupDesc = get_cached_rowtype(op->d.fieldstore.fstore->resulttype, -1,
3284  op->d.fieldstore.rowcache, NULL);
3285 
3286  /* Check that current tupdesc doesn't have more fields than allocated */
3287  if (unlikely(tupDesc->natts > op->d.fieldstore.ncolumns))
3288  elog(ERROR, "too many columns in composite type %u",
3289  op->d.fieldstore.fstore->resulttype);
3290 
3291  heap_deform_tuple(&tmptup, tupDesc,
3292  op->d.fieldstore.values,
3293  op->d.fieldstore.nulls);
3294  }
3295 }
#define unlikely(x)
Definition: c.h:300
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1346
static void ItemPointerSetInvalid(ItemPointerData *pointer)
Definition: itemptr.h:184
#define InvalidOid
Definition: postgres_ext.h:36
struct ExprEvalStep::@51::@77 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 3302 of file execExprInterp.c.

3303 {
3304  TupleDesc tupDesc;
3305  HeapTuple tuple;
3306 
3307  /* Lookup tupdesc (should be valid already) */
3308  tupDesc = get_cached_rowtype(op->d.fieldstore.fstore->resulttype, -1,
3309  op->d.fieldstore.rowcache, NULL);
3310 
3311  tuple = heap_form_tuple(tupDesc,
3312  op->d.fieldstore.values,
3313  op->d.fieldstore.nulls);
3314 
3315  *op->resvalue = HeapTupleGetDatum(tuple);
3316  *op->resnull = false;
3317 }
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117

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 2406 of file execExprInterp.c.

2408 {
2409  FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
2410  PgStat_FunctionCallUsage fcusage;
2411  Datum d;
2412 
2413  pgstat_init_function_usage(fcinfo, &fcusage);
2414 
2415  fcinfo->isnull = false;
2416  d = op->d.func.fn_addr(fcinfo);
2417  *op->resvalue = d;
2418  *op->resnull = fcinfo->isnull;
2419 
2420  pgstat_end_function_usage(&fcusage, true);
2421 }
void pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu)
void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
struct ExprEvalStep::@51::@58 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 2427 of file execExprInterp.c.

2429 {
2430 
2431  FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
2432  PgStat_FunctionCallUsage fcusage;
2433  NullableDatum *args = fcinfo->args;
2434  int nargs = op->d.func.nargs;
2435  Datum d;
2436 
2437  /* strict function, so check for NULL args */
2438  for (int argno = 0; argno < nargs; argno++)
2439  {
2440  if (args[argno].isnull)
2441  {
2442  *op->resnull = true;
2443  return;
2444  }
2445  }
2446 
2447  pgstat_init_function_usage(fcinfo, &fcusage);
2448 
2449  fcinfo->isnull = false;
2450  d = op->d.func.fn_addr(fcinfo);
2451  *op->resvalue = d;
2452  *op->resnull = fcinfo->isnull;
2453 
2454  pgstat_end_function_usage(&fcusage, true);
2455 }

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 4228 of file execExprInterp.c.

4229 {
4230  AggState *aggstate = castNode(AggState, state->parent);
4231  int result = 0;
4232  Bitmapset *grouped_cols = aggstate->grouped_cols;
4233  ListCell *lc;
4234 
4235  foreach(lc, op->d.grouping_func.clauses)
4236  {
4237  int attnum = lfirst_int(lc);
4238 
4239  result <<= 1;
4240 
4241  if (!bms_is_member(attnum, grouped_cols))
4242  result |= 1;
4243  }
4244 
4245  *op->resvalue = Int32GetDatum(result);
4246  *op->resnull = false;
4247 }
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:523
#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:2409
struct ExprEvalStep::@51::@87 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 3624 of file execExprInterp.c.

3625 {
3626  ScalarArrayOpExprHashTable *elements_tab = op->d.hashedscalararrayop.elements_tab;
3627  FunctionCallInfo fcinfo = op->d.hashedscalararrayop.fcinfo_data;
3628  bool inclause = op->d.hashedscalararrayop.inclause;
3629  bool strictfunc = op->d.hashedscalararrayop.finfo->fn_strict;
3630  Datum scalar = fcinfo->args[0].value;
3631  bool scalar_isnull = fcinfo->args[0].isnull;
3632  Datum result;
3633  bool resultnull;
3634  bool hashfound;
3635 
3636  /* We don't setup a hashed scalar array op if the array const is null. */
3637  Assert(!*op->resnull);
3638 
3639  /*
3640  * If the scalar is NULL, and the function is strict, return NULL; no
3641  * point in executing the search.
3642  */
3643  if (fcinfo->args[0].isnull && strictfunc)
3644  {
3645  *op->resnull = true;
3646  return;
3647  }
3648 
3649  /* Build the hash table on first evaluation */
3650  if (elements_tab == NULL)
3651  {
3652  ScalarArrayOpExpr *saop;
3653  int16 typlen;
3654  bool typbyval;
3655  char typalign;
3656  int nitems;
3657  bool has_nulls = false;
3658  char *s;
3659  bits8 *bitmap;
3660  int bitmask;
3661  MemoryContext oldcontext;
3662  ArrayType *arr;
3663 
3664  saop = op->d.hashedscalararrayop.saop;
3665 
3666  arr = DatumGetArrayTypeP(*op->resvalue);
3667  nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
3668 
3670  &typlen,
3671  &typbyval,
3672  &typalign);
3673 
3674  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
3675 
3676  elements_tab = (ScalarArrayOpExprHashTable *)
3677  palloc0(offsetof(ScalarArrayOpExprHashTable, hash_fcinfo_data) +
3679  op->d.hashedscalararrayop.elements_tab = elements_tab;
3680  elements_tab->op = op;
3681 
3682  fmgr_info(saop->hashfuncid, &elements_tab->hash_finfo);
3683  fmgr_info_set_expr((Node *) saop, &elements_tab->hash_finfo);
3684 
3686  &elements_tab->hash_finfo,
3687  1,
3688  saop->inputcollid,
3689  NULL,
3690  NULL);
3691 
3692  /*
3693  * Create the hash table sizing it according to the number of elements
3694  * in the array. This does assume that the array has no duplicates.
3695  * If the array happens to contain many duplicate values then it'll
3696  * just mean that we sized the table a bit on the large side.
3697  */
3698  elements_tab->hashtab = saophash_create(CurrentMemoryContext, nitems,
3699  elements_tab);
3700 
3701  MemoryContextSwitchTo(oldcontext);
3702 
3703  s = (char *) ARR_DATA_PTR(arr);
3704  bitmap = ARR_NULLBITMAP(arr);
3705  bitmask = 1;
3706  for (int i = 0; i < nitems; i++)
3707  {
3708  /* Get array element, checking for NULL. */
3709  if (bitmap && (*bitmap & bitmask) == 0)
3710  {
3711  has_nulls = true;
3712  }
3713  else
3714  {
3715  Datum element;
3716 
3717  element = fetch_att(s, typbyval, typlen);
3718  s = att_addlength_pointer(s, typlen, s);
3719  s = (char *) att_align_nominal(s, typalign);
3720 
3721  saophash_insert(elements_tab->hashtab, element, &hashfound);
3722  }
3723 
3724  /* Advance bitmap pointer if any. */
3725  if (bitmap)
3726  {
3727  bitmask <<= 1;
3728  if (bitmask == 0x100)
3729  {
3730  bitmap++;
3731  bitmask = 1;
3732  }
3733  }
3734  }
3735 
3736  /*
3737  * Remember if we had any nulls so that we know if we need to execute
3738  * non-strict functions with a null lhs value if no match is found.
3739  */
3740  op->d.hashedscalararrayop.has_nulls = has_nulls;
3741  }
3742 
3743  /* Check the hash to see if we have a match. */
3744  hashfound = NULL != saophash_lookup(elements_tab->hashtab, scalar);
3745 
3746  /* the result depends on if the clause is an IN or NOT IN clause */
3747  if (inclause)
3748  result = BoolGetDatum(hashfound); /* IN */
3749  else
3750  result = BoolGetDatum(!hashfound); /* NOT IN */
3751 
3752  resultnull = false;
3753 
3754  /*
3755  * If we didn't find a match in the array, we still might need to handle
3756  * the possibility of null values. We didn't put any NULLs into the
3757  * hashtable, but instead marked if we found any when building the table
3758  * in has_nulls.
3759  */
3760  if (!hashfound && op->d.hashedscalararrayop.has_nulls)
3761  {
3762  if (strictfunc)
3763  {
3764 
3765  /*
3766  * We have nulls in the array so a non-null lhs and no match must
3767  * yield NULL.
3768  */
3769  result = (Datum) 0;
3770  resultnull = true;
3771  }
3772  else
3773  {
3774  /*
3775  * Execute function will null rhs just once.
3776  *
3777  * The hash lookup path will have scribbled on the lhs argument so
3778  * we need to set it up also (even though we entered this function
3779  * with it already set).
3780  */
3781  fcinfo->args[0].value = scalar;
3782  fcinfo->args[0].isnull = scalar_isnull;
3783  fcinfo->args[1].value = (Datum) 0;
3784  fcinfo->args[1].isnull = true;
3785 
3786  result = op->d.hashedscalararrayop.finfo->fn_addr(fcinfo);
3787  resultnull = fcinfo->isnull;
3788 
3789  /*
3790  * Reverse the result for NOT IN clauses since the above function
3791  * is the equality function and we need not-equals.
3792  */
3793  if (!inclause)
3794  result = !result;
3795  }
3796  }
3797 
3798  *op->resvalue = result;
3799  *op->resnull = resultnull;
3800 }
signed short int16
Definition: c.h:482
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:2226
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::@51::@83 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().

◆ ExecEvalJsonConstructor()

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

Definition at line 4055 of file execExprInterp.c.

4057 {
4058  Datum res;
4059  JsonConstructorExprState *jcstate = op->d.json_constructor.jcstate;
4060  JsonConstructorExpr *ctor = jcstate->constructor;
4061  bool is_jsonb = ctor->returning->format->format_type == JS_FORMAT_JSONB;
4062  bool isnull = false;
4063 
4064  if (ctor->type == JSCTOR_JSON_ARRAY)
4065  res = (is_jsonb ?
4067  json_build_array_worker) (jcstate->nargs,
4068  jcstate->arg_values,
4069  jcstate->arg_nulls,
4070  jcstate->arg_types,
4071  jcstate->constructor->absent_on_null);
4072  else if (ctor->type == JSCTOR_JSON_OBJECT)
4073  res = (is_jsonb ?
4075  json_build_object_worker) (jcstate->nargs,
4076  jcstate->arg_values,
4077  jcstate->arg_nulls,
4078  jcstate->arg_types,
4079  jcstate->constructor->absent_on_null,
4080  jcstate->constructor->unique);
4081  else if (ctor->type == JSCTOR_JSON_SCALAR)
4082  {
4083  if (jcstate->arg_nulls[0])
4084  {
4085  res = (Datum) 0;
4086  isnull = true;
4087  }
4088  else
4089  {
4090  Datum value = jcstate->arg_values[0];
4091  Oid outfuncid = jcstate->arg_type_cache[0].outfuncid;
4092  JsonTypeCategory category = (JsonTypeCategory)
4093  jcstate->arg_type_cache[0].category;
4094 
4095  if (is_jsonb)
4096  res = datum_to_jsonb(value, category, outfuncid);
4097  else
4098  res = datum_to_json(value, category, outfuncid);
4099  }
4100  }
4101  else if (ctor->type == JSCTOR_JSON_PARSE)
4102  {
4103  if (jcstate->arg_nulls[0])
4104  {
4105  res = (Datum) 0;
4106  isnull = true;
4107  }
4108  else
4109  {
4110  Datum value = jcstate->arg_values[0];
4111  text *js = DatumGetTextP(value);
4112 
4113  if (is_jsonb)
4114  res = jsonb_from_text(js, true);
4115  else
4116  {
4117  (void) json_validate(js, true, true);
4118  res = value;
4119  }
4120  }
4121  }
4122  else
4123  elog(ERROR, "invalid JsonConstructorExpr type %d", ctor->type);
4124 
4125  *op->resvalue = res;
4126  *op->resnull = isnull;
4127 }
#define DatumGetTextP(X)
Definition: fmgr.h:332
static struct @148 value
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
Datum json_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Definition: json.c:1321
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:1208
Datum datum_to_json(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
Definition: json.c:754
bool json_validate(text *json, bool check_unique_keys, bool throw_error)
Definition: json.c:1650
Datum jsonb_from_text(text *js, bool unique_keys)
Definition: jsonb.c:152
Datum jsonb_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Definition: jsonb.c:1215
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:1130
Datum datum_to_jsonb(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
Definition: jsonb.c:1117
JsonTypeCategory
Definition: jsonfuncs.h:68
@ JS_FORMAT_JSONB
Definition: primnodes.h:1575
@ JSCTOR_JSON_PARSE
Definition: primnodes.h:1625
@ JSCTOR_JSON_OBJECT
Definition: primnodes.h:1621
@ JSCTOR_JSON_SCALAR
Definition: primnodes.h:1626
@ JSCTOR_JSON_ARRAY
Definition: primnodes.h:1622
struct ExprEvalStep::@51::@85 json_constructor
JsonConstructorExpr * constructor
Definition: execExpr.h:746
struct JsonConstructorExprState::@96 * arg_type_cache
JsonReturning * returning
Definition: primnodes.h:1641
JsonConstructorType type
Definition: primnodes.h:1637
JsonFormatType format_type
Definition: primnodes.h:1586
JsonFormat * format
Definition: primnodes.h:1598
Definition: c.h:676

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().

◆ ExecEvalJsonIsPredicate()

void ExecEvalJsonIsPredicate ( ExprState state,
ExprEvalStep op 
)

Definition at line 4133 of file execExprInterp.c.

4134 {
4135  JsonIsPredicate *pred = op->d.is_json.pred;
4136  Datum js = *op->resvalue;
4137  Oid exprtype;
4138  bool res;
4139 
4140  if (*op->resnull)
4141  {
4142  *op->resvalue = BoolGetDatum(false);
4143  return;
4144  }
4145 
4146  exprtype = exprType(pred->expr);
4147 
4148  if (exprtype == TEXTOID || exprtype == JSONOID)
4149  {
4150  text *json = DatumGetTextP(js);
4151 
4152  if (pred->item_type == JS_TYPE_ANY)
4153  res = true;
4154  else
4155  {
4156  switch (json_get_first_token(json, false))
4157  {
4159  res = pred->item_type == JS_TYPE_OBJECT;
4160  break;
4162  res = pred->item_type == JS_TYPE_ARRAY;
4163  break;
4164  case JSON_TOKEN_STRING:
4165  case JSON_TOKEN_NUMBER:
4166  case JSON_TOKEN_TRUE:
4167  case JSON_TOKEN_FALSE:
4168  case JSON_TOKEN_NULL:
4169  res = pred->item_type == JS_TYPE_SCALAR;
4170  break;
4171  default:
4172  res = false;
4173  break;
4174  }
4175  }
4176 
4177  /*
4178  * Do full parsing pass only for uniqueness check or for JSON text
4179  * validation.
4180  */
4181  if (res && (pred->unique_keys || exprtype == TEXTOID))
4182  res = json_validate(json, pred->unique_keys, false);
4183  }
4184  else if (exprtype == JSONBOID)
4185  {
4186  if (pred->item_type == JS_TYPE_ANY)
4187  res = true;
4188  else
4189  {
4190  Jsonb *jb = DatumGetJsonbP(js);
4191 
4192  switch (pred->item_type)
4193  {
4194  case JS_TYPE_OBJECT:
4195  res = JB_ROOT_IS_OBJECT(jb);
4196  break;
4197  case JS_TYPE_ARRAY:
4198  res = JB_ROOT_IS_ARRAY(jb) && !JB_ROOT_IS_SCALAR(jb);
4199  break;
4200  case JS_TYPE_SCALAR:
4201  res = JB_ROOT_IS_ARRAY(jb) && JB_ROOT_IS_SCALAR(jb);
4202  break;
4203  default:
4204  res = false;
4205  break;
4206  }
4207  }
4208 
4209  /* Key uniqueness check is redundant for jsonb */
4210  }
4211  else
4212  res = false;
4213 
4214  *op->resvalue = BoolGetDatum(res);
4215 }
@ JSON_TOKEN_FALSE
Definition: jsonapi.h:31
@ JSON_TOKEN_TRUE
Definition: jsonapi.h:30
@ JSON_TOKEN_NULL
Definition: jsonapi.h:32
@ JSON_TOKEN_OBJECT_START
Definition: jsonapi.h:24
@ JSON_TOKEN_NUMBER
Definition: jsonapi.h:23
@ JSON_TOKEN_STRING
Definition: jsonapi.h:22
@ JSON_TOKEN_ARRAY_START
Definition: jsonapi.h:26
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:5870
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:43
@ JS_TYPE_ANY
Definition: primnodes.h:1653
@ JS_TYPE_ARRAY
Definition: primnodes.h:1655
@ JS_TYPE_OBJECT
Definition: primnodes.h:1654
@ JS_TYPE_SCALAR
Definition: primnodes.h:1656
struct ExprEvalStep::@51::@95 is_json
JsonValueType item_type
Definition: primnodes.h:1668
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().

◆ ExecEvalMinMax()

void ExecEvalMinMax ( ExprState state,
ExprEvalStep op 
)

Definition at line 3074 of file execExprInterp.c.

3075 {
3076  Datum *values = op->d.minmax.values;
3077  bool *nulls = op->d.minmax.nulls;
3078  FunctionCallInfo fcinfo = op->d.minmax.fcinfo_data;
3079  MinMaxOp operator = op->d.minmax.op;
3080 
3081  /* set at initialization */
3082  Assert(fcinfo->args[0].isnull == false);
3083  Assert(fcinfo->args[1].isnull == false);
3084 
3085  /* default to null result */
3086  *op->resnull = true;
3087 
3088  for (int off = 0; off < op->d.minmax.nelems; off++)
3089  {
3090  /* ignore NULL inputs */
3091  if (nulls[off])
3092  continue;
3093 
3094  if (*op->resnull)
3095  {
3096  /* first nonnull input, adopt value */
3097  *op->resvalue = values[off];
3098  *op->resnull = false;
3099  }
3100  else
3101  {
3102  int cmpresult;
3103 
3104  /* apply comparison function */
3105  fcinfo->args[0].value = *op->resvalue;
3106  fcinfo->args[1].value = values[off];
3107 
3108  fcinfo->isnull = false;
3109  cmpresult = DatumGetInt32(FunctionCallInvoke(fcinfo));
3110  if (fcinfo->isnull) /* probably should not happen */
3111  continue;
3112 
3113  if (cmpresult > 0 && operator == IS_LEAST)
3114  *op->resvalue = values[off];
3115  else if (cmpresult < 0 && operator == IS_GREATEST)
3116  *op->resvalue = values[off];
3117  }
3118  }
3119 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202
MinMaxOp
Definition: primnodes.h:1436
@ IS_LEAST
Definition: primnodes.h:1438
@ IS_GREATEST
Definition: primnodes.h:1437
struct ExprEvalStep::@51::@75 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 2671 of file execExprInterp.c.

2672 {
2673  int64 newval = nextval_internal(op->d.nextvalueexpr.seqid, false);
2674 
2675  switch (op->d.nextvalueexpr.seqtypid)
2676  {
2677  case INT2OID:
2678  *op->resvalue = Int16GetDatum((int16) newval);
2679  break;
2680  case INT4OID:
2681  *op->resvalue = Int32GetDatum((int32) newval);
2682  break;
2683  case INT8OID:
2684  *op->resvalue = Int64GetDatum((int64) newval);
2685  break;
2686  default:
2687  elog(ERROR, "unsupported sequence type %u",
2688  op->d.nextvalueexpr.seqtypid);
2689  }
2690  *op->resnull = false;
2691 }
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1807
#define newval
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
int64 nextval_internal(Oid relid, bool check_permissions)
Definition: sequence.c:615
struct ExprEvalStep::@51::@69 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 2464 of file execExprInterp.c.

2465 {
2466  ParamExecData *prm;
2467 
2468  prm = &(econtext->ecxt_param_exec_vals[op->d.param.paramid]);
2469  if (unlikely(prm->execPlan != NULL))
2470  {
2471  /* Parameter not evaluated yet, so go do it */
2472  ExecSetParamPlan(prm->execPlan, econtext);
2473  /* ExecSetParamPlan should have processed this param... */
2474  Assert(prm->execPlan == NULL);
2475  }
2476  *op->resvalue = prm->value;
2477  *op->resnull = prm->isnull;
2478 }
void ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
Definition: nodeSubplan.c:1092
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:266
struct ExprEvalStep::@51::@63 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 2486 of file execExprInterp.c.

2487 {
2488  ParamListInfo paramInfo = econtext->ecxt_param_list_info;
2489  int paramId = op->d.param.paramid;
2490 
2491  if (likely(paramInfo &&
2492  paramId > 0 && paramId <= paramInfo->numParams))
2493  {
2494  ParamExternData *prm;
2495  ParamExternData prmdata;
2496 
2497  /* give hook a chance in case parameter is dynamic */
2498  if (paramInfo->paramFetch != NULL)
2499  prm = paramInfo->paramFetch(paramInfo, paramId, false, &prmdata);
2500  else
2501  prm = &paramInfo->params[paramId - 1];
2502 
2503  if (likely(OidIsValid(prm->ptype)))
2504  {
2505  /* safety check in case hook did something unexpected */
2506  if (unlikely(prm->ptype != op->d.param.paramtype))
2507  ereport(ERROR,
2508  (errcode(ERRCODE_DATATYPE_MISMATCH),
2509  errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
2510  paramId,
2511  format_type_be(prm->ptype),
2512  format_type_be(op->d.param.paramtype))));
2513  *op->resvalue = prm->value;
2514  *op->resnull = prm->isnull;
2515  return;
2516  }
2517  }
2518 
2519  ereport(ERROR,
2520  (errcode(ERRCODE_UNDEFINED_OBJECT),
2521  errmsg("no value found for parameter %d", paramId)));
2522 }
#define likely(x)
Definition: c.h:299
#define OidIsValid(objectId)
Definition: c.h:764
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:267
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().

◆ ExecEvalPreOrderedDistinctMulti()

bool ExecEvalPreOrderedDistinctMulti ( AggState aggstate,
AggStatePerTrans  pertrans 
)

Definition at line 4662 of file execExprInterp.c.

4663 {
4664  ExprContext *tmpcontext = aggstate->tmpcontext;
4665  bool isdistinct = false; /* for now */
4666  TupleTableSlot *save_outer;
4667  TupleTableSlot *save_inner;
4668 
4669  for (int i = 0; i < pertrans->numTransInputs; i++)
4670  {
4671  pertrans->sortslot->tts_values[i] = pertrans->transfn_fcinfo->args[i + 1].value;
4672  pertrans->sortslot->tts_isnull[i] = pertrans->transfn_fcinfo->args[i + 1].isnull;
4673  }
4674 
4675  ExecClearTuple(pertrans->sortslot);
4676  pertrans->sortslot->tts_nvalid = pertrans->numInputs;
4677  ExecStoreVirtualTuple(pertrans->sortslot);
4678 
4679  /* save the previous slots before we overwrite them */
4680  save_outer = tmpcontext->ecxt_outertuple;
4681  save_inner = tmpcontext->ecxt_innertuple;
4682 
4683  tmpcontext->ecxt_outertuple = pertrans->sortslot;
4684  tmpcontext->ecxt_innertuple = pertrans->uniqslot;
4685 
4686  if (!pertrans->haslast ||
4687  !ExecQual(pertrans->equalfnMulti, tmpcontext))
4688  {
4689  if (pertrans->haslast)
4690  ExecClearTuple(pertrans->uniqslot);
4691 
4692  pertrans->haslast = true;
4693  ExecCopySlot(pertrans->uniqslot, pertrans->sortslot);
4694 
4695  isdistinct = true;
4696  }
4697 
4698  /* restore the original slots */
4699  tmpcontext->ecxt_outertuple = save_outer;
4700  tmpcontext->ecxt_innertuple = save_inner;
4701 
4702  return isdistinct;
4703 }
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:412
ExprState * equalfnMulti
Definition: nodeAgg.h:116
TupleTableSlot * uniqslot
Definition: nodeAgg.h:142
ExprContext * tmpcontext
Definition: execnodes.h:2398
bool * tts_isnull
Definition: tuptable.h:127
Datum * tts_values
Definition: tuptable.h:125
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition: tuptable.h:488

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 4619 of file execExprInterp.c.

4620 {
4621  Datum value = pertrans->transfn_fcinfo->args[1].value;
4622  bool isnull = pertrans->transfn_fcinfo->args[1].isnull;
4623 
4624  if (!pertrans->haslast ||
4625  pertrans->lastisnull != isnull ||
4626  (!isnull && !DatumGetBool(FunctionCall2Coll(&pertrans->equalfnOne,
4627  pertrans->aggCollation,
4628  pertrans->lastdatum, value))))
4629  {
4630  if (pertrans->haslast && !pertrans->inputtypeByVal &&
4631  !pertrans->lastisnull)
4632  pfree(DatumGetPointer(pertrans->lastdatum));
4633 
4634  pertrans->haslast = true;
4635  if (!isnull)
4636  {
4637  MemoryContext oldContext;
4638 
4640 
4641  pertrans->lastdatum = datumCopy(value, pertrans->inputtypeByVal,
4642  pertrans->inputtypeLen);
4643 
4644  MemoryContextSwitchTo(oldContext);
4645  }
4646  else
4647  pertrans->lastdatum = (Datum) 0;
4648  pertrans->lastisnull = isnull;
4649  return true;
4650  }
4651 
4652  return false;
4653 }
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 3054 of file execExprInterp.c.

3055 {
3056  HeapTuple tuple;
3057 
3058  /* build tuple from evaluated field values */
3059  tuple = heap_form_tuple(op->d.row.tupdesc,
3060  op->d.row.elemvalues,
3061  op->d.row.elemnulls);
3062 
3063  *op->resvalue = HeapTupleGetDatum(tuple);
3064  *op->resnull = false;
3065 }
struct ExprEvalStep::@51::@72 row

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

Referenced by ExecInterpExpr().

◆ ExecEvalRowNotNull()

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

Definition at line 2706 of file execExprInterp.c.

2707 {
2708  ExecEvalRowNullInt(state, op, econtext, false);
2709 }
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 2697 of file execExprInterp.c.

2698 {
2699  ExecEvalRowNullInt(state, op, econtext, true);
2700 }

References ExecEvalRowNullInt(), and ExprEvalStep::op.

Referenced by ExecInterpExpr().

◆ ExecEvalScalarArrayOp()

void ExecEvalScalarArrayOp ( ExprState state,
ExprEvalStep op 
)

Definition at line 3421 of file execExprInterp.c.

3422 {
3423  FunctionCallInfo fcinfo = op->d.scalararrayop.fcinfo_data;
3424  bool useOr = op->d.scalararrayop.useOr;
3425  bool strictfunc = op->d.scalararrayop.finfo->fn_strict;
3426  ArrayType *arr;
3427  int nitems;
3428  Datum result;
3429  bool resultnull;
3430  int16 typlen;
3431  bool typbyval;
3432  char typalign;
3433  char *s;
3434  bits8 *bitmap;
3435  int bitmask;
3436 
3437  /*
3438  * If the array is NULL then we return NULL --- it's not very meaningful
3439  * to do anything else, even if the operator isn't strict.
3440  */
3441  if (*op->resnull)
3442  return;
3443 
3444  /* Else okay to fetch and detoast the array */
3445  arr = DatumGetArrayTypeP(*op->resvalue);
3446 
3447  /*
3448  * If the array is empty, we return either FALSE or TRUE per the useOr
3449  * flag. This is correct even if the scalar is NULL; since we would
3450  * evaluate the operator zero times, it matters not whether it would want
3451  * to return NULL.
3452  */
3453  nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
3454  if (nitems <= 0)
3455  {
3456  *op->resvalue = BoolGetDatum(!useOr);
3457  *op->resnull = false;
3458  return;
3459  }
3460 
3461  /*
3462  * If the scalar is NULL, and the function is strict, return NULL; no
3463  * point in iterating the loop.
3464  */
3465  if (fcinfo->args[0].isnull && strictfunc)
3466  {
3467  *op->resnull = true;
3468  return;
3469  }
3470 
3471  /*
3472  * We arrange to look up info about the element type only once per series
3473  * of calls, assuming the element type doesn't change underneath us.
3474  */
3475  if (op->d.scalararrayop.element_type != ARR_ELEMTYPE(arr))
3476  {
3478  &op->d.scalararrayop.typlen,
3479  &op->d.scalararrayop.typbyval,
3480  &op->d.scalararrayop.typalign);
3481  op->d.scalararrayop.element_type = ARR_ELEMTYPE(arr);
3482  }
3483 
3484  typlen = op->d.scalararrayop.typlen;
3485  typbyval = op->d.scalararrayop.typbyval;
3486  typalign = op->d.scalararrayop.typalign;
3487 
3488  /* Initialize result appropriately depending on useOr */
3489  result = BoolGetDatum(!useOr);
3490  resultnull = false;
3491 
3492  /* Loop over the array elements */
3493  s = (char *) ARR_DATA_PTR(arr);
3494  bitmap = ARR_NULLBITMAP(arr);
3495  bitmask = 1;
3496 
3497  for (int i = 0; i < nitems; i++)
3498  {
3499  Datum elt;
3500  Datum thisresult;
3501 
3502  /* Get array element, checking for NULL */
3503  if (bitmap && (*bitmap & bitmask) == 0)
3504  {
3505  fcinfo->args[1].value = (Datum) 0;
3506  fcinfo->args[1].isnull = true;
3507  }
3508  else
3509  {
3510  elt = fetch_att(s, typbyval, typlen);
3511  s = att_addlength_pointer(s, typlen, s);
3512  s = (char *) att_align_nominal(s, typalign);
3513  fcinfo->args[1].value = elt;
3514  fcinfo->args[1].isnull = false;
3515  }
3516 
3517  /* Call comparison function */
3518  if (fcinfo->args[1].isnull && strictfunc)
3519  {
3520  fcinfo->isnull = true;
3521  thisresult = (Datum) 0;
3522  }
3523  else
3524  {
3525  fcinfo->isnull = false;
3526  thisresult = op->d.scalararrayop.fn_addr(fcinfo);
3527  }
3528 
3529  /* Combine results per OR or AND semantics */
3530  if (fcinfo->isnull)
3531  resultnull = true;
3532  else if (useOr)
3533  {
3534  if (DatumGetBool(thisresult))
3535  {
3536  result = BoolGetDatum(true);
3537  resultnull = false;
3538  break; /* needn't look at any more elements */
3539  }
3540  }
3541  else
3542  {
3543  if (!DatumGetBool(thisresult))
3544  {
3545  result = BoolGetDatum(false);
3546  resultnull = false;
3547  break; /* needn't look at any more elements */
3548  }
3549  }
3550 
3551  /* advance bitmap pointer if any */
3552  if (bitmap)
3553  {
3554  bitmask <<= 1;
3555  if (bitmask == 0x100)
3556  {
3557  bitmap++;
3558  bitmask = 1;
3559  }
3560  }
3561  }
3562 
3563  *op->resvalue = result;
3564  *op->resnull = resultnull;
3565 }
struct ExprEvalStep::@51::@82 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 2593 of file execExprInterp.c.

2594 {
2595  LOCAL_FCINFO(fcinfo, 0);
2596  SQLValueFunction *svf = op->d.sqlvaluefunction.svf;
2597 
2598  *op->resnull = false;
2599 
2600  /*
2601  * Note: current_schema() can return NULL. current_user() etc currently
2602  * cannot, but might as well code those cases the same way for safety.
2603  */
2604  switch (svf->op)
2605  {
2606  case SVFOP_CURRENT_DATE:
2608  break;
2609  case SVFOP_CURRENT_TIME:
2610  case SVFOP_CURRENT_TIME_N:
2612  break;
2616  break;
2617  case SVFOP_LOCALTIME:
2618  case SVFOP_LOCALTIME_N:
2620  break;
2621  case SVFOP_LOCALTIMESTAMP:
2624  break;
2625  case SVFOP_CURRENT_ROLE:
2626  case SVFOP_CURRENT_USER:
2627  case SVFOP_USER:
2628  InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
2629  *op->resvalue = current_user(fcinfo);
2630  *op->resnull = fcinfo->isnull;
2631  break;
2632  case SVFOP_SESSION_USER:
2633  InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
2634  *op->resvalue = session_user(fcinfo);
2635  *op->resnull = fcinfo->isnull;
2636  break;
2637  case SVFOP_CURRENT_CATALOG:
2638  InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
2639  *op->resvalue = current_database(fcinfo);
2640  *op->resnull = fcinfo->isnull;
2641  break;
2642  case SVFOP_CURRENT_SCHEMA:
2643  InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
2644  *op->resvalue = current_schema(fcinfo);
2645  *op->resnull = fcinfo->isnull;
2646  break;
2647  }
2648 }
Datum current_database(PG_FUNCTION_ARGS)
Definition: misc.c:195
Timestamp GetSQLLocalTimestamp(int32 typmod)
Definition: timestamp.c:1687
TimestampTz GetSQLCurrentTimestamp(int32 typmod)
Definition: timestamp.c:1673
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:1484
@ SVFOP_LOCALTIME_N
Definition: primnodes.h:1477
@ SVFOP_CURRENT_TIMESTAMP
Definition: primnodes.h:1474
@ SVFOP_LOCALTIME
Definition: primnodes.h:1476
@ SVFOP_CURRENT_TIMESTAMP_N
Definition: primnodes.h:1475
@ SVFOP_CURRENT_ROLE
Definition: primnodes.h:1480
@ SVFOP_USER
Definition: primnodes.h:1482
@ SVFOP_CURRENT_SCHEMA
Definition: primnodes.h:1485
@ SVFOP_LOCALTIMESTAMP_N
Definition: primnodes.h:1479
@ SVFOP_CURRENT_DATE
Definition: primnodes.h:1471
@ SVFOP_CURRENT_TIME_N
Definition: primnodes.h:1473
@ SVFOP_CURRENT_TIME
Definition: primnodes.h:1472
@ SVFOP_LOCALTIMESTAMP
Definition: primnodes.h:1478
@ SVFOP_CURRENT_USER
Definition: primnodes.h:1481
@ SVFOP_SESSION_USER
Definition: primnodes.h:1483
struct ExprEvalStep::@51::@68 sqlvaluefunction
SQLValueFunctionOp op
Definition: primnodes.h:1491
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 2376 of file execExprInterp.c.

2377 {
2378 #if defined(EEO_USE_COMPUTED_GOTO)
2379  if (state->flags & EEO_FLAG_DIRECT_THREADED)
2380  {
2381  ExprEvalOpLookup key;
2382  ExprEvalOpLookup *res;
2383 
2384  key.opcode = (void *) op->opcode;
2385  res = bsearch(&key,
2386  reverse_dispatch_table,
2387  EEOP_LAST /* nmembers */ ,
2388  sizeof(ExprEvalOpLookup),
2389  dispatch_compare_ptr);
2390  Assert(res); /* unknown ops shouldn't get looked up */
2391  return res->op;
2392  }
2393 #endif
2394  return (ExprEvalOp) op->opcode;
2395 }
#define EEO_FLAG_DIRECT_THREADED
Definition: execExpr.h:31
intptr_t opcode
Definition: execExpr.h:277

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 4253 of file execExprInterp.c.

4254 {
4255  SubPlanState *sstate = op->d.subplan.sstate;
4256 
4257  /* could potentially be nested, so make sure there's enough stack */
4259 
4260  *op->resvalue = ExecSubPlan(sstate, econtext, op->resnull);
4261 }
Datum ExecSubPlan(SubPlanState *node, ExprContext *econtext, bool *isNull)
Definition: nodeSubplan.c:62
void check_stack_depth(void)
Definition: postgres.c:3523
struct ExprEvalStep::@51::@89 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 4497 of file execExprInterp.c.

4499 {
4500  Datum d;
4501 
4502  /* slot_getsysattr has sufficient defenses against bad attnums */
4503  d = slot_getsysattr(slot,
4504  op->d.var.attnum,
4505  op->resnull);
4506  *op->resvalue = d;
4507  /* this ought to be unreachable, but it's cheap enough to check */
4508  if (unlikely(*op->resnull))
4509  elog(ERROR, "failed to fetch attribute from slot");
4510 }
static Datum slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: tuptable.h:410

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 4270 of file execExprInterp.c.

4271 {
4272  Var *variable = op->d.wholerow.var;
4273  TupleTableSlot *slot;
4274  TupleDesc output_tupdesc;
4275  MemoryContext oldcontext;
4276  HeapTupleHeader dtuple;
4277  HeapTuple tuple;
4278 
4279  /* This was checked by ExecInitExpr */
4280  Assert(variable->varattno == InvalidAttrNumber);
4281 
4282  /* Get the input slot we want */
4283  switch (variable->varno)
4284  {
4285  case INNER_VAR:
4286  /* get the tuple from the inner node */
4287  slot = econtext->ecxt_innertuple;
4288  break;
4289 
4290  case OUTER_VAR:
4291  /* get the tuple from the outer node */
4292  slot = econtext->ecxt_outertuple;
4293  break;
4294 
4295  /* INDEX_VAR is handled by default case */
4296 
4297  default:
4298  /* get the tuple from the relation being scanned */
4299  slot = econtext->ecxt_scantuple;
4300  break;
4301  }
4302 
4303  /* Apply the junkfilter if any */
4304  if (op->d.wholerow.junkFilter != NULL)
4305  slot = ExecFilterJunk(op->d.wholerow.junkFilter, slot);
4306 
4307  /*
4308  * If first time through, obtain tuple descriptor and check compatibility.
4309  *
4310  * XXX: It'd be great if this could be moved to the expression
4311  * initialization phase, but due to using slots that's currently not
4312  * feasible.
4313  */
4314  if (op->d.wholerow.first)
4315  {
4316  /* optimistically assume we don't need slow path */
4317  op->d.wholerow.slow = false;
4318 
4319  /*
4320  * If the Var identifies a named composite type, we must check that
4321  * the actual tuple type is compatible with it.
4322  */
4323  if (variable->vartype != RECORDOID)
4324  {
4325  TupleDesc var_tupdesc;
4326  TupleDesc slot_tupdesc;
4327 
4328  /*
4329  * We really only care about numbers of attributes and data types.
4330  * Also, we can ignore type mismatch on columns that are dropped
4331  * in the destination type, so long as (1) the physical storage
4332  * matches or (2) the actual column value is NULL. Case (1) is
4333  * helpful in some cases involving out-of-date cached plans, while
4334  * case (2) is expected behavior in situations such as an INSERT
4335  * into a table with dropped columns (the planner typically
4336  * generates an INT4 NULL regardless of the dropped column type).
4337  * If we find a dropped column and cannot verify that case (1)
4338  * holds, we have to use the slow path to check (2) for each row.
4339  *
4340  * If vartype is a domain over composite, just look through that
4341  * to the base composite type.
4342  */
4343  var_tupdesc = lookup_rowtype_tupdesc_domain(variable->vartype,
4344  -1, false);
4345 
4346  slot_tupdesc = slot->tts_tupleDescriptor;
4347 
4348  if (var_tupdesc->natts != slot_tupdesc->natts)
4349  ereport(ERROR,
4350  (errcode(ERRCODE_DATATYPE_MISMATCH),
4351  errmsg("table row type and query-specified row type do not match"),
4352  errdetail_plural("Table row contains %d attribute, but query expects %d.",
4353  "Table row contains %d attributes, but query expects %d.",
4354  slot_tupdesc->natts,
4355  slot_tupdesc->natts,
4356  var_tupdesc->natts)));
4357 
4358  for (int i = 0; i < var_tupdesc->natts; i++)
4359  {
4360  Form_pg_attribute vattr = TupleDescAttr(var_tupdesc, i);
4361  Form_pg_attribute sattr = TupleDescAttr(slot_tupdesc, i);
4362 
4363  if (vattr->atttypid == sattr->atttypid)
4364  continue; /* no worries */
4365  if (!vattr->attisdropped)
4366  ereport(ERROR,
4367  (errcode(ERRCODE_DATATYPE_MISMATCH),
4368  errmsg("table row type and query-specified row type do not match"),
4369  errdetail("Table has type %s at ordinal position %d, but query expects %s.",
4370  format_type_be(sattr->atttypid),
4371  i + 1,
4372  format_type_be(vattr->atttypid))));
4373 
4374  if (vattr->attlen != sattr->attlen ||
4375  vattr->attalign != sattr->attalign)
4376  op->d.wholerow.slow = true; /* need to check for nulls */
4377  }
4378 
4379  /*
4380  * Use the variable's declared rowtype as the descriptor for the
4381  * output values. In particular, we *must* absorb any
4382  * attisdropped markings.
4383  */
4384  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
4385  output_tupdesc = CreateTupleDescCopy(var_tupdesc);
4386  MemoryContextSwitchTo(oldcontext);
4387 
4388  ReleaseTupleDesc(var_tupdesc);
4389  }
4390  else
4391  {
4392  /*
4393  * In the RECORD case, we use the input slot's rowtype as the
4394  * descriptor for the output values, modulo possibly assigning new
4395  * column names below.
4396  */
4397  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
4398  output_tupdesc = CreateTupleDescCopy(slot->tts_tupleDescriptor);
4399  MemoryContextSwitchTo(oldcontext);
4400 
4401  /*
4402  * It's possible that the input slot is a relation scan slot and
4403  * so is marked with that relation's rowtype. But we're supposed
4404  * to be returning RECORD, so reset to that.
4405  */
4406  output_tupdesc->tdtypeid = RECORDOID;
4407  output_tupdesc->tdtypmod = -1;
4408 
4409  /*
4410  * We already got the correct physical datatype info above, but
4411  * now we should try to find the source RTE and adopt its column
4412  * aliases, since it's unlikely that the input slot has the
4413  * desired names.
4414  *
4415  * If we can't locate the RTE, assume the column names we've got
4416  * are OK. (As of this writing, the only cases where we can't
4417  * locate the RTE are in execution of trigger WHEN clauses, and
4418  * then the Var will have the trigger's relation's rowtype, so its
4419  * names are fine.) Also, if the creator of the RTE didn't bother
4420  * to fill in an eref field, assume our column names are OK. (This
4421  * happens in COPY, and perhaps other places.)
4422  */
4423  if (econtext->ecxt_estate &&
4424  variable->varno <= econtext->ecxt_estate->es_range_table_size)
4425  {
4426  RangeTblEntry *rte = exec_rt_fetch(variable->varno,
4427  econtext->ecxt_estate);
4428 
4429  if (rte->eref)
4430  ExecTypeSetColNames(output_tupdesc, rte->eref->colnames);
4431  }
4432  }
4433 
4434  /* Bless the tupdesc if needed, and save it in the execution state */
4435  op->d.wholerow.tupdesc = BlessTupleDesc(output_tupdesc);
4436 
4437  op->d.wholerow.first = false;
4438  }
4439 
4440  /*
4441  * Make sure all columns of the slot are accessible in the slot's
4442  * Datum/isnull arrays.
4443  */
4444  slot_getallattrs(slot);
4445 
4446  if (op->d.wholerow.slow)
4447  {
4448  /* Check to see if any dropped attributes are non-null */
4449  TupleDesc tupleDesc = slot->tts_tupleDescriptor;
4450  TupleDesc var_tupdesc = op->d.wholerow.tupdesc;
4451 
4452  Assert(var_tupdesc->natts == tupleDesc->natts);
4453 
4454  for (int i = 0; i < var_tupdesc->natts; i++)
4455  {
4456  Form_pg_attribute vattr = TupleDescAttr(var_tupdesc, i);
4457  Form_pg_attribute sattr = TupleDescAttr(tupleDesc, i);
4458 
4459  if (!vattr->attisdropped)
4460  continue; /* already checked non-dropped cols */
4461  if (slot->tts_isnull[i])
4462  continue; /* null is always okay */
4463  if (vattr->attlen != sattr->attlen ||
4464  vattr->attalign != sattr->attalign)
4465  ereport(ERROR,
4466  (errcode(ERRCODE_DATATYPE_MISMATCH),
4467  errmsg("table row type and query-specified row type do not match"),
4468  errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
4469  i + 1)));
4470  }
4471  }
4472 
4473  /*
4474  * Build a composite datum, making sure any toasted fields get detoasted.
4475  *
4476  * (Note: it is critical that we not change the slot's state here.)
4477  */
4479  slot->tts_values,
4480  slot->tts_isnull);
4481  dtuple = tuple->t_data;
4482 
4483  /*
4484  * Label the datum with the composite type info we identified before.
4485  *
4486  * (Note: we could skip doing this by passing op->d.wholerow.tupdesc to
4487  * the tuple build step; but that seems a tad risky so let's not.)
4488  */
4489  HeapTupleHeaderSetTypeId(dtuple, op->d.wholerow.tupdesc->tdtypeid);
4490  HeapTupleHeaderSetTypMod(dtuple, op->d.wholerow.tupdesc->tdtypmod);
4491 
4492  *op->resvalue = PointerGetDatum(dtuple);
4493  *op->resnull = false;
4494 }
#define InvalidAttrNumber
Definition: attnum.h:23
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1300
TupleTableSlot * ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
Definition: execJunk.c:247
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2070
void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList)
Definition: execTuples.c:2029
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:586
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:223
#define INNER_VAR
Definition: primnodes.h:222
List * colnames
Definition: primnodes.h:51
Index es_range_table_size
Definition: execnodes.h:625
struct EState * ecxt_estate
Definition: execnodes.h:291
struct ExprEvalStep::@51::@54 wholerow
Alias * eref
Definition: parsenodes.h:1192
int32 tdtypmod
Definition: tupdesc.h:83
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:123
Definition: primnodes.h:234
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:133
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:362
TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, bool noError)
Definition: typcache.c:1888

References Assert(), BlessTupleDesc(), Alias::colnames, CreateTupleDescCopy(), ExprContext::ecxt_estate, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_per_query_memory, ExprContext::ecxt_scantuple, RangeTblEntry::eref, 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 3840 of file execExprInterp.c.

3841 {
3842  XmlExpr *xexpr = op->d.xmlexpr.xexpr;
3843  Datum value;
3844 
3845  *op->resnull = true; /* until we get a result */
3846  *op->resvalue = (Datum) 0;
3847 
3848  switch (xexpr->op)
3849  {
3850  case IS_XMLCONCAT:
3851  {
3852  Datum *argvalue = op->d.xmlexpr.argvalue;
3853  bool *argnull = op->d.xmlexpr.argnull;
3854  List *values = NIL;
3855 
3856  for (int i = 0; i < list_length(xexpr->args); i++)
3857  {
3858  if (!argnull[i])
3859  values = lappend(values, DatumGetPointer(argvalue[i]));
3860  }
3861 
3862  if (values != NIL)
3863  {
3865  *op->resnull = false;
3866  }
3867  }
3868  break;
3869 
3870  case IS_XMLFOREST:
3871  {
3872  Datum *argvalue = op->d.xmlexpr.named_argvalue;
3873  bool *argnull = op->d.xmlexpr.named_argnull;
3875  ListCell *lc;
3876  ListCell *lc2;
3877  int i;
3878 
3879  initStringInfo(&buf);
3880 
3881  i = 0;
3882  forboth(lc, xexpr->named_args, lc2, xexpr->arg_names)
3883  {
3884  Expr *e = (Expr *) lfirst(lc);
3885  char *argname = strVal(lfirst(lc2));
3886 
3887  if (!argnull[i])
3888  {
3889  value = argvalue[i];
3890  appendStringInfo(&buf, "<%s>%s</%s>",
3891  argname,
3893  exprType((Node *) e), true),
3894  argname);
3895  *op->resnull = false;
3896  }
3897  i++;
3898  }
3899 
3900  if (!*op->resnull)
3901  {
3902  text *result;
3903 
3904  result = cstring_to_text_with_len(buf.data, buf.len);
3905  *op->resvalue = PointerGetDatum(result);
3906  }
3907 
3908  pfree(buf.data);
3909  }
3910  break;
3911 
3912  case IS_XMLELEMENT:
3913  *op->resvalue = PointerGetDatum(xmlelement(xexpr,
3914  op->d.xmlexpr.named_argvalue,
3915  op->d.xmlexpr.named_argnull,
3916  op->d.xmlexpr.argvalue,
3917  op->d.xmlexpr.argnull));
3918  *op->resnull = false;
3919  break;
3920 
3921  case IS_XMLPARSE:
3922  {
3923  Datum *argvalue = op->d.xmlexpr.argvalue;
3924  bool *argnull = op->d.xmlexpr.argnull;
3925  text *data;
3926  bool preserve_whitespace;
3927 
3928  /* arguments are known to be text, bool */
3929  Assert(list_length(xexpr->args) == 2);
3930 
3931  if (argnull[0])
3932  return;
3933  value = argvalue[0];
3935 
3936  if (argnull[1]) /* probably can't happen */
3937  return;
3938  value = argvalue[1];
3939  preserve_whitespace = DatumGetBool(value);
3940 
3942  xexpr->xmloption,
3943  preserve_whitespace));
3944  *op->resnull = false;
3945  }
3946  break;
3947 
3948  case IS_XMLPI:
3949  {
3950  text *arg;
3951  bool isnull;
3952 
3953  /* optional argument is known to be text */
3954  Assert(list_length(xexpr->args) <= 1);
3955 
3956  if (xexpr->args)
3957  {
3958  isnull = op->d.xmlexpr.argnull[0];
3959  if (isnull)
3960  arg = NULL;
3961  else
3962  arg = DatumGetTextPP(op->d.xmlexpr.argvalue[0]);
3963  }
3964  else
3965  {
3966  arg = NULL;
3967  isnull = false;
3968  }
3969 
3970  *op->resvalue = PointerGetDatum(xmlpi(xexpr->name,
3971  arg,
3972  isnull,
3973  op->resnull));
3974  }
3975  break;
3976 
3977  case IS_XMLROOT:
3978  {
3979  Datum *argvalue = op->d.xmlexpr.argvalue;
3980  bool *argnull = op->d.xmlexpr.argnull;
3981  xmltype *data;
3982  text *version;
3983  int standalone;
3984 
3985  /* arguments are known to be xml, text, int */
3986  Assert(list_length(xexpr->args) == 3);
3987 
3988  if (argnull[0])
3989  return;
3990  data = DatumGetXmlP(argvalue[0]);
3991 
3992  if (argnull[1])
3993  version = NULL;
3994  else
3995  version = DatumGetTextPP(argvalue[1]);
3996 
3997  Assert(!argnull[2]); /* always present */
3998  standalone = DatumGetInt32(argvalue[2]);
3999 
4001  version,
4002  standalone));
4003  *op->resnull = false;
4004  }
4005  break;
4006 
4007  case IS_XMLSERIALIZE:
4008  {
4009  Datum *argvalue = op->d.xmlexpr.argvalue;
4010  bool *argnull = op->d.xmlexpr.argnull;
4011 
4012  /* argument type is known to be xml */
4013  Assert(list_length(xexpr->args) == 1);
4014 
4015  if (argnull[0])
4016  return;
4017  value = argvalue[0];
4018 
4019  *op->resvalue =
4021  xexpr->xmloption,
4022  xexpr->indent));
4023  *op->resnull = false;
4024  }
4025  break;
4026 
4027  case IS_DOCUMENT:
4028  {
4029  Datum *argvalue = op->d.xmlexpr.argvalue;
4030  bool *argnull = op->d.xmlexpr.argnull;
4031 
4032  /* optional argument is known to be xml */
4033  Assert(list_length(xexpr->args) == 1);
4034 
4035  if (argnull[0])
4036  return;
4037  value = argvalue[0];
4038 
4039  *op->resvalue =
4041  *op->resnull = false;
4042  }
4043  break;
4044 
4045  default:
4046  elog(ERROR, "unrecognized XML operation");
4047  break;
4048  }
4049 }
#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:73
e
Definition: preproc-init.c:82
@ IS_DOCUMENT
Definition: primnodes.h:1522
@ IS_XMLFOREST
Definition: primnodes.h:1517
@ IS_XMLCONCAT
Definition: primnodes.h:1515
@ IS_XMLPI
Definition: primnodes.h:1519
@ IS_XMLPARSE
Definition: primnodes.h:1518
@ IS_XMLSERIALIZE
Definition: primnodes.h:1521
@ IS_XMLROOT
Definition: primnodes.h:1520
@ IS_XMLELEMENT
Definition: primnodes.h:1516
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
struct ExprEvalStep::@51::@84 xmlexpr
Definition: pg_list.h:54
List * args
Definition: primnodes.h:1543
bool indent
Definition: primnodes.h:1547
List * named_args
Definition: primnodes.h:1539
XmlExprOp op
Definition: primnodes.h:1535
#define strVal(v)
Definition: value.h:82
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:196
xmltype * xmlconcat(List *args)
Definition: xml.c:554
text * xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
Definition: xml.c:657
xmltype * xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
Definition: xml.c:961
bool xml_is_document(xmltype *arg)
Definition: xml.c:1097
xmltype * xmlpi(const char *target, text *arg, bool arg_is_null, bool *result_is_null)
Definition: xml.c:979
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:2416
xmltype * xmlelement(XmlExpr *xexpr, Datum *named_argvalue, bool *named_argnull, Datum *argvalue, bool *argnull)
Definition: xml.c:837
xmltype * xmlroot(xmltype *data, text *version, int standalone)
Definition: xml.c:1031
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 1869 of file execExprInterp.c.

1870 {
1871  /*
1872  * First time through, check whether attribute matches Var. Might not be
1873  * ok anymore, due to schema changes.
1874  */
1875  CheckExprStillValid(state, econtext);
1876 
1877  /* skip the check during further executions */
1878  state->evalfunc = (ExprStateEvalFunc) state->evalfunc_private;
1879 
1880  /* and actually execute */
1881  return state->evalfunc(state, econtext, isNull);
1882 }
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 = (void *) ExecJustInnerVar;
285  return;
286  }
287  else if (step0 == EEOP_OUTER_FETCHSOME &&
288  step1 == EEOP_OUTER_VAR)
289  {
290  state->evalfunc_private = (void *) ExecJustOuterVar;
291  return;
292  }
293  else if (step0 == EEOP_SCAN_FETCHSOME &&
294  step1 == EEOP_SCAN_VAR)
295  {
296  state->evalfunc_private = (void *) ExecJustScanVar;
297  return;
298  }
299  else if (step0 == EEOP_INNER_FETCHSOME &&
300  step1 == EEOP_ASSIGN_INNER_VAR)
301  {
302  state->evalfunc_private = (void *) ExecJustAssignInnerVar;
303  return;
304  }
305  else if (step0 == EEOP_OUTER_FETCHSOME &&
306  step1 == EEOP_ASSIGN_OUTER_VAR)
307  {
308  state->evalfunc_private = (void *) ExecJustAssignOuterVar;
309  return;
310  }
311  else if (step0 == EEOP_SCAN_FETCHSOME &&
312  step1 == EEOP_ASSIGN_SCAN_VAR)
313  {
314  state->evalfunc_private = (void *) 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 = (void *) 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 = (void *) ExecJustConst;
332  return;
333  }
334  else if (step0 == EEOP_INNER_VAR)
335  {
336  state->evalfunc_private = (void *) ExecJustInnerVarVirt;
337  return;
338  }
339  else if (step0 == EEOP_OUTER_VAR)
340  {
341  state->evalfunc_private = (void *) ExecJustOuterVarVirt;
342  return;
343  }
344  else if (step0 == EEOP_SCAN_VAR)
345  {
346  state->evalfunc_private = (void *) ExecJustScanVarVirt;
347  return;
348  }
349  else if (step0 == EEOP_ASSIGN_INNER_VAR)
350  {
351  state->evalfunc_private = (void *) ExecJustAssignInnerVarVirt;
352  return;
353  }
354  else if (step0 == EEOP_ASSIGN_OUTER_VAR)
355  {
356  state->evalfunc_private = (void *) ExecJustAssignOuterVarVirt;
357  return;
358  }
359  else if (step0 == EEOP_ASSIGN_SCAN_VAR)
360  {
361  state->evalfunc_private = (void *) 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 = (void *) 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 2555 of file execExpr.c.

2556 {
2557  if (es->steps_alloc == 0)
2558  {
2559  es->steps_alloc = 16;
2560  es->steps = palloc(sizeof(ExprEvalStep) * es->steps_alloc);
2561  }
2562  else if (es->steps_alloc == es->steps_len)
2563  {
2564  es->steps_alloc *= 2;
2565  es->steps = repalloc(es->steps,
2566  sizeof(ExprEvalStep) * es->steps_alloc);
2567  }
2568 
2569  memcpy(&es->steps[es->steps_len++], s, sizeof(ExprEvalStep));
2570 }
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1451
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(), ExecBuildParamSetEqual(), ExecBuildProjectionInfo(), ExecBuildUpdateProjection(), ExecInitCoerceToDomain(), ExecInitExpr(), ExecInitExprRec(), ExecInitExprWithParams(), ExecInitQual(), ExecInitSubscriptingRef(), ExecPushExprSetupSteps(), and plpgsql_param_compile().

◆ StaticAssertDecl()

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