PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
execQual.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/nbtree.h"
#include "access/tupconvert.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_type.h"
#include "executor/execdebug.h"
#include "executor/nodeSubplan.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/planner.h"
#include "parser/parse_coerce.h"
#include "parser/parsetree.h"
#include "pgstat.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/timestamp.h"
#include "utils/typcache.h"
#include "utils/xml.h"
Include dependency graph for execQual.c:

Go to the source code of this file.

Functions

static Datum ExecEvalArrayRef (ArrayRefExprState *astate, ExprContext *econtext, bool *isNull)
 
static bool isAssignmentIndirectionExpr (ExprState *exprstate)
 
static Datum ExecEvalAggref (AggrefExprState *aggref, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalWindowFunc (WindowFuncExprState *wfunc, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalScalarVar (ExprState *exprstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalScalarVarFast (ExprState *exprstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalWholeRowVar (WholeRowVarExprState *wrvstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalWholeRowFast (WholeRowVarExprState *wrvstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalWholeRowSlow (WholeRowVarExprState *wrvstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalConst (ExprState *exprstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalParamExec (ExprState *exprstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalParamExtern (ExprState *exprstate, ExprContext *econtext, bool *isNull)
 
static void init_fcache (Oid foid, Oid input_collation, FuncExprState *fcache, MemoryContext fcacheCxt, bool allowSRF, bool needDescForSRF)
 
static void ShutdownFuncExpr (Datum arg)
 
static TupleDesc get_cached_rowtype (Oid type_id, int32 typmod, TupleDesc *cache_field, ExprContext *econtext)
 
static void ShutdownTupleDescRef (Datum arg)
 
static void ExecEvalFuncArgs (FunctionCallInfo fcinfo, List *argList, ExprContext *econtext)
 
static void ExecPrepareTuplestoreResult (FuncExprState *fcache, ExprContext *econtext, Tuplestorestate *resultStore, TupleDesc resultDesc)
 
static void tupledesc_match (TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
 
static Datum ExecMakeFunctionResultNoSets (FuncExprState *fcache, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalFunc (FuncExprState *fcache, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalOper (FuncExprState *fcache, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalDistinct (FuncExprState *fcache, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalScalarArrayOp (ScalarArrayOpExprState *sstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalNot (BoolExprState *notclause, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalOr (BoolExprState *orExpr, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalAnd (BoolExprState *andExpr, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalConvertRowtype (ConvertRowtypeExprState *cstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalCase (CaseExprState *caseExpr, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalCaseTestExpr (ExprState *exprstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalArray (ArrayExprState *astate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalRow (RowExprState *rstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalRowCompare (RowCompareExprState *rstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalCoalesce (CoalesceExprState *coalesceExpr, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalMinMax (MinMaxExprState *minmaxExpr, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalSQLValueFunction (ExprState *svfExpr, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalXml (XmlExprState *xmlExpr, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalNullIf (FuncExprState *nullIfExpr, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalNullTest (NullTestState *nstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalBooleanTest (GenericExprState *bstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalCoerceToDomain (CoerceToDomainState *cstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalCoerceToDomainValue (ExprState *exprstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalFieldSelect (FieldSelectState *fstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalFieldStore (FieldStoreState *fstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalRelabelType (GenericExprState *exprstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalCoerceViaIO (CoerceViaIOState *iostate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalArrayCoerceExpr (ArrayCoerceExprState *astate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalCurrentOfExpr (ExprState *exprstate, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalGroupingFuncExpr (GroupingFuncExprState *gstate, ExprContext *econtext, bool *isNull)
 
Datum GetAttributeByNum (HeapTupleHeader tuple, AttrNumber attrno, bool *isNull)
 
Datum GetAttributeByName (HeapTupleHeader tuple, const char *attname, bool *isNull)
 
Datum ExecMakeFunctionResultSet (FuncExprState *fcache, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone)
 
TuplestorestateExecMakeTableFunctionResult (ExprState *funcexpr, ExprContext *econtext, MemoryContext argContext, TupleDesc expectedDesc, bool randomAccess)
 
Datum ExecEvalExprSwitchContext (ExprState *expression, ExprContext *econtext, bool *isNull)
 
ExprStateExecInitExpr (Expr *node, PlanState *parent)
 
ExprStateExecPrepareExpr (Expr *node, EState *estate)
 
bool ExecQual (List *qual, ExprContext *econtext, bool resultForNull)
 
int ExecTargetListLength (List *targetlist)
 
int ExecCleanTargetListLength (List *targetlist)
 
static void ExecTargetList (List *targetlist, TupleDesc tupdesc, ExprContext *econtext, Datum *values, bool *isnull)
 
TupleTableSlotExecProject (ProjectionInfo *projInfo)
 

Function Documentation

int ExecCleanTargetListLength ( List targetlist)

Definition at line 5132 of file execQual.c.

References castNode, lfirst, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), and ExecTypeFromTLInternal().

5133 {
5134  int len = 0;
5135  ListCell *tl;
5136 
5137  foreach(tl, targetlist)
5138  {
5139  TargetEntry *curTle = castNode(TargetEntry, lfirst(tl));
5140 
5141  if (!curTle->resjunk)
5142  len++;
5143  }
5144  return len;
5145 }
#define castNode(_type_, nodeptr)
Definition: nodes.h:577
bool resjunk
Definition: primnodes.h:1337
#define lfirst(lc)
Definition: pg_list.h:106
static Datum ExecEvalAggref ( AggrefExprState aggref,
ExprContext econtext,
bool isNull 
)
static

Definition at line 520 of file execQual.c.

References AggrefExprState::aggno, ExprContext::ecxt_aggnulls, ExprContext::ecxt_aggvalues, elog, ERROR, and NULL.

Referenced by ExecInitExpr().

522 {
523  if (econtext->ecxt_aggvalues == NULL) /* safety check */
524  elog(ERROR, "no aggregates in this expression context");
525 
526  *isNull = econtext->ecxt_aggnulls[aggref->aggno];
527  return econtext->ecxt_aggvalues[aggref->aggno];
528 }
Datum * ecxt_aggvalues
Definition: execnodes.h:144
#define ERROR
Definition: elog.h:43
bool * ecxt_aggnulls
Definition: execnodes.h:145
#define NULL
Definition: c.h:226
#define elog
Definition: elog.h:219
static Datum ExecEvalAnd ( BoolExprState andExpr,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2591 of file execQual.c.

References BoolExprState::args, BoolGetDatum, DatumGetBool, ExecEvalExpr, and lfirst.

Referenced by ExecInitExpr().

2593 {
2594  List *clauses = andExpr->args;
2595  ListCell *clause;
2596  bool AnyNull;
2597 
2598  AnyNull = false;
2599 
2600  /*
2601  * If any of the clauses is FALSE, the AND result is FALSE regardless of
2602  * the states of the rest of the clauses, so we can stop evaluating and
2603  * return FALSE immediately. If none are FALSE and one or more is NULL,
2604  * we return NULL; otherwise we return TRUE. This makes sense when you
2605  * interpret NULL as "don't know", using the same sort of reasoning as for
2606  * OR, above.
2607  */
2608 
2609  foreach(clause, clauses)
2610  {
2611  ExprState *clausestate = (ExprState *) lfirst(clause);
2612  Datum clause_value;
2613 
2614  clause_value = ExecEvalExpr(clausestate, econtext, isNull);
2615 
2616  /*
2617  * if we have a non-null false result, then return it.
2618  */
2619  if (*isNull)
2620  AnyNull = true; /* remember we got a null */
2621  else if (!DatumGetBool(clause_value))
2622  return clause_value;
2623  }
2624 
2625  /* AnyNull is true if at least one clause evaluated to NULL */
2626  *isNull = AnyNull;
2627  return BoolGetDatum(!AnyNull);
2628 }
List * args
Definition: execnodes.h:775
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define DatumGetBool(X)
Definition: postgres.h:401
uintptr_t Datum
Definition: postgres.h:374
#define BoolGetDatum(X)
Definition: postgres.h:410
#define lfirst(lc)
Definition: pg_list.h:106
Definition: pg_list.h:45
static Datum ExecEvalArray ( ArrayExprState astate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2861 of file execQual.c.

References 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(), ArrayGetNItems(), construct_empty_array(), construct_md_array(), DatumGetArrayTypeP, ArrayExprState::elemalign, ArrayExprState::elembyval, element(), ArrayExpr::element_typeid, ArrayExprState::elements, ArrayExprState::elemlength, ereport, errcode(), errdetail(), errmsg(), ERROR, ExecEvalExpr, ExprState::expr, format_type_be(), i, lfirst, list_length(), MAXDIM, ArrayExpr::multidims, NULL, palloc(), PointerGetDatum, SET_VARSIZE, and ArrayExprState::xprstate.

Referenced by ExecInitExpr().

2863 {
2864  ArrayExpr *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
2865  ArrayType *result;
2866  ListCell *element;
2867  Oid element_type = arrayExpr->element_typeid;
2868  int ndims = 0;
2869  int dims[MAXDIM];
2870  int lbs[MAXDIM];
2871 
2872  /* Set non-null as default */
2873  *isNull = false;
2874 
2875  if (!arrayExpr->multidims)
2876  {
2877  /* Elements are presumably of scalar type */
2878  int nelems;
2879  Datum *dvalues;
2880  bool *dnulls;
2881  int i = 0;
2882 
2883  ndims = 1;
2884  nelems = list_length(astate->elements);
2885 
2886  /* Shouldn't happen here, but if length is 0, return empty array */
2887  if (nelems == 0)
2888  return PointerGetDatum(construct_empty_array(element_type));
2889 
2890  dvalues = (Datum *) palloc(nelems * sizeof(Datum));
2891  dnulls = (bool *) palloc(nelems * sizeof(bool));
2892 
2893  /* loop through and build array of datums */
2894  foreach(element, astate->elements)
2895  {
2897 
2898  dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i]);
2899  i++;
2900  }
2901 
2902  /* setup for 1-D array of the given length */
2903  dims[0] = nelems;
2904  lbs[0] = 1;
2905 
2906  result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
2907  element_type,
2908  astate->elemlength,
2909  astate->elembyval,
2910  astate->elemalign);
2911  }
2912  else
2913  {
2914  /* Must be nested array expressions */
2915  int nbytes = 0;
2916  int nitems = 0;
2917  int outer_nelems = 0;
2918  int elem_ndims = 0;
2919  int *elem_dims = NULL;
2920  int *elem_lbs = NULL;
2921  bool firstone = true;
2922  bool havenulls = false;
2923  bool haveempty = false;
2924  char **subdata;
2925  bits8 **subbitmaps;
2926  int *subbytes;
2927  int *subnitems;
2928  int i;
2929  int32 dataoffset;
2930  char *dat;
2931  int iitem;
2932 
2933  i = list_length(astate->elements);
2934  subdata = (char **) palloc(i * sizeof(char *));
2935  subbitmaps = (bits8 **) palloc(i * sizeof(bits8 *));
2936  subbytes = (int *) palloc(i * sizeof(int));
2937  subnitems = (int *) palloc(i * sizeof(int));
2938 
2939  /* loop through and get data area from each element */
2940  foreach(element, astate->elements)
2941  {
2943  bool eisnull;
2944  Datum arraydatum;
2945  ArrayType *array;
2946  int this_ndims;
2947 
2948  arraydatum = ExecEvalExpr(e, econtext, &eisnull);
2949  /* temporarily ignore null subarrays */
2950  if (eisnull)
2951  {
2952  haveempty = true;
2953  continue;
2954  }
2955 
2956  array = DatumGetArrayTypeP(arraydatum);
2957 
2958  /* run-time double-check on element type */
2959  if (element_type != ARR_ELEMTYPE(array))
2960  ereport(ERROR,
2961  (errcode(ERRCODE_DATATYPE_MISMATCH),
2962  errmsg("cannot merge incompatible arrays"),
2963  errdetail("Array with element type %s cannot be "
2964  "included in ARRAY construct with element type %s.",
2965  format_type_be(ARR_ELEMTYPE(array)),
2966  format_type_be(element_type))));
2967 
2968  this_ndims = ARR_NDIM(array);
2969  /* temporarily ignore zero-dimensional subarrays */
2970  if (this_ndims <= 0)
2971  {
2972  haveempty = true;
2973  continue;
2974  }
2975 
2976  if (firstone)
2977  {
2978  /* Get sub-array details from first member */
2979  elem_ndims = this_ndims;
2980  ndims = elem_ndims + 1;
2981  if (ndims <= 0 || ndims > MAXDIM)
2982  ereport(ERROR,
2983  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2984  errmsg("number of array dimensions (%d) exceeds " \
2985  "the maximum allowed (%d)", ndims, MAXDIM)));
2986 
2987  elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2988  memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2989  elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2990  memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2991 
2992  firstone = false;
2993  }
2994  else
2995  {
2996  /* Check other sub-arrays are compatible */
2997  if (elem_ndims != this_ndims ||
2998  memcmp(elem_dims, ARR_DIMS(array),
2999  elem_ndims * sizeof(int)) != 0 ||
3000  memcmp(elem_lbs, ARR_LBOUND(array),
3001  elem_ndims * sizeof(int)) != 0)
3002  ereport(ERROR,
3003  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3004  errmsg("multidimensional arrays must have array "
3005  "expressions with matching dimensions")));
3006  }
3007 
3008  subdata[outer_nelems] = ARR_DATA_PTR(array);
3009  subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
3010  subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
3011  nbytes += subbytes[outer_nelems];
3012  subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
3013  ARR_DIMS(array));
3014  nitems += subnitems[outer_nelems];
3015  havenulls |= ARR_HASNULL(array);
3016  outer_nelems++;
3017  }
3018 
3019  /*
3020  * If all items were null or empty arrays, return an empty array;
3021  * otherwise, if some were and some weren't, raise error. (Note: we
3022  * must special-case this somehow to avoid trying to generate a 1-D
3023  * array formed from empty arrays. It's not ideal...)
3024  */
3025  if (haveempty)
3026  {
3027  if (ndims == 0) /* didn't find any nonempty array */
3028  return PointerGetDatum(construct_empty_array(element_type));
3029  ereport(ERROR,
3030  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3031  errmsg("multidimensional arrays must have array "
3032  "expressions with matching dimensions")));
3033  }
3034 
3035  /* setup for multi-D array */
3036  dims[0] = outer_nelems;
3037  lbs[0] = 1;
3038  for (i = 1; i < ndims; i++)
3039  {
3040  dims[i] = elem_dims[i - 1];
3041  lbs[i] = elem_lbs[i - 1];
3042  }
3043 
3044  if (havenulls)
3045  {
3046  dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
3047  nbytes += dataoffset;
3048  }
3049  else
3050  {
3051  dataoffset = 0; /* marker for no null bitmap */
3052  nbytes += ARR_OVERHEAD_NONULLS(ndims);
3053  }
3054 
3055  result = (ArrayType *) palloc(nbytes);
3056  SET_VARSIZE(result, nbytes);
3057  result->ndim = ndims;
3058  result->dataoffset = dataoffset;
3059  result->elemtype = element_type;
3060  memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
3061  memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
3062 
3063  dat = ARR_DATA_PTR(result);
3064  iitem = 0;
3065  for (i = 0; i < outer_nelems; i++)
3066  {
3067  memcpy(dat, subdata[i], subbytes[i]);
3068  dat += subbytes[i];
3069  if (havenulls)
3070  array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
3071  subbitmaps[i], 0,
3072  subnitems[i]);
3073  iitem += subnitems[i];
3074  }
3075  }
3076 
3077  return PointerGetDatum(result);
3078 }
bool multidims
Definition: primnodes.h:932
#define ARR_OVERHEAD_NONULLS(ndims)
Definition: array.h:291
#define ARR_SIZE(a)
Definition: array.h:270
#define MAXDIM
Definition: c.h:415
#define PointerGetDatum(X)
Definition: postgres.h:564
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
Definition: arrayfuncs.c:4624
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
List * elements
Definition: execnodes.h:918
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3424
unsigned int Oid
Definition: postgres_ext.h:31
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
Definition: array.h:293
signed int int32
Definition: c.h:253
#define ARR_DATA_OFFSET(a)
Definition: array.h:297
#define ARR_LBOUND(a)
Definition: array.h:277
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:597
#define ARR_DIMS(a)
Definition: array.h:275
int16 elemlength
Definition: execnodes.h:919
#define ARR_DATA_PTR(a)
Definition: array.h:303
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ARR_HASNULL(a)
Definition: array.h:272
#define ereport(elevel, rest)
Definition: elog.h:122
static chr element(struct vars *v, const chr *startp, const chr *endp)
Definition: regc_locale.c:380
uint8 bits8
Definition: c.h:272
uintptr_t Datum
Definition: postgres.h:374
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
static int list_length(const List *l)
Definition: pg_list.h:89
#define ARR_NDIM(a)
Definition: array.h:271
Oid element_typeid
Definition: primnodes.h:930
e
Definition: preproc-init.c:82
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
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:3340
#define ARR_ELEMTYPE(a)
Definition: array.h:273
#define ARR_NULLBITMAP(a)
Definition: array.h:281
#define DatumGetArrayTypeP(X)
Definition: array.h:242
ExprState xprstate
Definition: execnodes.h:917
static Datum ExecEvalArrayCoerceExpr ( ArrayCoerceExprState astate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 4127 of file execQual.c.

References ACL_EXECUTE, ACL_KIND_PROC, aclcheck_error(), ACLCHECK_OK, ArrayCoerceExprState::amstate, ArrayCoerceExprState::arg, ARR_ELEMTYPE, array_map(), BoolGetDatum, DatumGetArrayTypePCopy, ExprContext::ecxt_per_query_memory, ArrayCoerceExprState::elemfunc, ArrayCoerceExpr::elemfuncid, ExecEvalExpr, ExprState::expr, fmgr_info_cxt(), fmgr_info_set_expr, FmgrInfo::fn_oid, get_func_name(), GetUserId(), InitFunctionCallInfoData, Int32GetDatum, InvalidOid, InvokeFunctionExecuteHook, ArrayCoerceExpr::isExplicit, NULL, OidIsValid, pg_proc_aclcheck(), PG_RETURN_ARRAYTYPE_P, ArrayCoerceExprState::resultelemtype, ArrayCoerceExpr::resulttypmod, and ArrayCoerceExprState::xprstate.

Referenced by ExecInitExpr().

4130 {
4131  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) astate->xprstate.expr;
4132  Datum result;
4133  FunctionCallInfoData locfcinfo;
4134 
4135  result = ExecEvalExpr(astate->arg, econtext, isNull);
4136 
4137  if (*isNull)
4138  return result; /* nothing to do */
4139 
4140  /*
4141  * If it's binary-compatible, modify the element type in the array header,
4142  * but otherwise leave the array as we received it.
4143  */
4144  if (!OidIsValid(acoerce->elemfuncid))
4145  {
4146  /* Detoast input array if necessary, and copy in any case */
4147  ArrayType *array = DatumGetArrayTypePCopy(result);
4148 
4149  ARR_ELEMTYPE(array) = astate->resultelemtype;
4150  PG_RETURN_ARRAYTYPE_P(array);
4151  }
4152 
4153  /* Initialize function cache if first time through */
4154  if (astate->elemfunc.fn_oid == InvalidOid)
4155  {
4156  AclResult aclresult;
4157 
4158  /* Check permission to call function */
4159  aclresult = pg_proc_aclcheck(acoerce->elemfuncid, GetUserId(),
4160  ACL_EXECUTE);
4161  if (aclresult != ACLCHECK_OK)
4162  aclcheck_error(aclresult, ACL_KIND_PROC,
4163  get_func_name(acoerce->elemfuncid));
4165 
4166  /* Set up the primary fmgr lookup information */
4167  fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc),
4168  econtext->ecxt_per_query_memory);
4169  fmgr_info_set_expr((Node *) acoerce, &(astate->elemfunc));
4170  }
4171 
4172  /*
4173  * Use array_map to apply the function to each array element.
4174  *
4175  * We pass on the desttypmod and isExplicit flags whether or not the
4176  * function wants them.
4177  *
4178  * Note: coercion functions are assumed to not use collation.
4179  */
4180  InitFunctionCallInfoData(locfcinfo, &(astate->elemfunc), 3,
4181  InvalidOid, NULL, NULL);
4182  locfcinfo.arg[0] = result;
4183  locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod);
4184  locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit);
4185  locfcinfo.argnull[0] = false;
4186  locfcinfo.argnull[1] = false;
4187  locfcinfo.argnull[2] = false;
4188 
4189  return array_map(&locfcinfo, astate->resultelemtype, astate->amstate);
4190 }
Datum array_map(FunctionCallInfo fcinfo, Oid retType, ArrayMapState *amstate)
Definition: arrayfuncs.c:3120
Oid GetUserId(void)
Definition: miscinit.c:283
Definition: nodes.h:508
ExprState xprstate
Definition: execnodes.h:861
#define OidIsValid(objectId)
Definition: c.h:533
struct ArrayMapState * amstate
Definition: execnodes.h:866
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
Expr * expr
Definition: execnodes.h:597
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1380
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define fmgr_info_set_expr(expr, finfo)
Definition: fmgr.h:96
ExprState * arg
Definition: execnodes.h:862
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:169
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:246
#define InvokeFunctionExecuteHook(objectId)
Definition: objectaccess.h:179
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:374
#define DatumGetArrayTypePCopy(X)
Definition: array.h:243
#define BoolGetDatum(X)
Definition: postgres.h:410
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:56
#define NULL
Definition: c.h:226
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:112
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
#define Int32GetDatum(X)
Definition: postgres.h:487
#define ACL_EXECUTE
Definition: parsenodes.h:72
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4421
int32 resulttypmod
Definition: primnodes.h:813
#define ARR_ELEMTYPE(a)
Definition: array.h:273
static Datum ExecEvalArrayRef ( ArrayRefExprState astate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 244 of file execQual.c.

References array_get_element(), array_get_slice(), array_set_element(), array_set_slice(), Assert, ExprContext::caseValue_datum, ExprContext::caseValue_isNull, construct_empty_array(), DatumGetInt32, elog, ereport, errcode(), errmsg(), ERROR, ExecEvalExpr, ExprState::expr, i, IntArray::indx, isAssignmentIndirectionExpr(), lfirst, lower(), MAXDIM, NIL, NULL, PointerGetDatum, ArrayRef::refassgnexpr, ArrayRefExprState::refassgnexpr, ArrayRefExprState::refattrlength, ArrayRefExprState::refelemalign, ArrayRefExprState::refelembyval, ArrayRefExprState::refelemlength, ArrayRef::refelemtype, ArrayRefExprState::refexpr, ArrayRefExprState::reflowerindexpr, ArrayRefExprState::refupperindexpr, upper(), and ArrayRefExprState::xprstate.

Referenced by ExecInitExpr().

247 {
248  ArrayRef *arrayRef = (ArrayRef *) astate->xprstate.expr;
249  Datum array_source;
250  bool isAssignment = (arrayRef->refassgnexpr != NULL);
251  bool eisnull;
252  ListCell *l;
253  int i = 0,
254  j = 0;
255  IntArray upper,
256  lower;
257  bool upperProvided[MAXDIM],
258  lowerProvided[MAXDIM];
259  int *lIndex;
260 
261  array_source = ExecEvalExpr(astate->refexpr,
262  econtext,
263  isNull);
264 
265  /*
266  * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
267  * assignment case, we'll cons up something below.
268  */
269  if (*isNull)
270  {
271  if (!isAssignment)
272  return (Datum) NULL;
273  }
274 
275  foreach(l, astate->refupperindexpr)
276  {
277  ExprState *eltstate = (ExprState *) lfirst(l);
278 
279  if (i >= MAXDIM)
280  ereport(ERROR,
281  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
282  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
283  i + 1, MAXDIM)));
284 
285  if (eltstate == NULL)
286  {
287  /* Slice bound is omitted, so use array's upper bound */
288  Assert(astate->reflowerindexpr != NIL);
289  upperProvided[i++] = false;
290  continue;
291  }
292  upperProvided[i] = true;
293 
294  upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
295  econtext,
296  &eisnull));
297  /* If any index expr yields NULL, result is NULL or error */
298  if (eisnull)
299  {
300  if (isAssignment)
301  ereport(ERROR,
302  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
303  errmsg("array subscript in assignment must not be null")));
304  *isNull = true;
305  return (Datum) NULL;
306  }
307  }
308 
309  if (astate->reflowerindexpr != NIL)
310  {
311  foreach(l, astate->reflowerindexpr)
312  {
313  ExprState *eltstate = (ExprState *) lfirst(l);
314 
315  if (j >= MAXDIM)
316  ereport(ERROR,
317  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
318  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
319  j + 1, MAXDIM)));
320 
321  if (eltstate == NULL)
322  {
323  /* Slice bound is omitted, so use array's lower bound */
324  lowerProvided[j++] = false;
325  continue;
326  }
327  lowerProvided[j] = true;
328 
329  lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
330  econtext,
331  &eisnull));
332  /* If any index expr yields NULL, result is NULL or error */
333  if (eisnull)
334  {
335  if (isAssignment)
336  ereport(ERROR,
337  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
338  errmsg("array subscript in assignment must not be null")));
339  *isNull = true;
340  return (Datum) NULL;
341  }
342  }
343  /* this can't happen unless parser messed up */
344  if (i != j)
345  elog(ERROR, "upper and lower index lists are not same length");
346  lIndex = lower.indx;
347  }
348  else
349  lIndex = NULL;
350 
351  if (isAssignment)
352  {
353  Datum sourceData;
354  Datum save_datum;
355  bool save_isNull;
356 
357  /*
358  * We might have a nested-assignment situation, in which the
359  * refassgnexpr is itself a FieldStore or ArrayRef that needs to
360  * obtain and modify the previous value of the array element or slice
361  * being replaced. If so, we have to extract that value from the
362  * array and pass it down via the econtext's caseValue. It's safe to
363  * reuse the CASE mechanism because there cannot be a CASE between
364  * here and where the value would be needed, and an array assignment
365  * can't be within a CASE either. (So saving and restoring the
366  * caseValue is just paranoia, but let's do it anyway.)
367  *
368  * Since fetching the old element might be a nontrivial expense, do it
369  * only if the argument appears to actually need it.
370  */
371  save_datum = econtext->caseValue_datum;
372  save_isNull = econtext->caseValue_isNull;
373 
375  {
376  if (*isNull)
377  {
378  /* whole array is null, so any element or slice is too */
379  econtext->caseValue_datum = (Datum) 0;
380  econtext->caseValue_isNull = true;
381  }
382  else if (lIndex == NULL)
383  {
384  econtext->caseValue_datum =
385  array_get_element(array_source, i,
386  upper.indx,
387  astate->refattrlength,
388  astate->refelemlength,
389  astate->refelembyval,
390  astate->refelemalign,
391  &econtext->caseValue_isNull);
392  }
393  else
394  {
395  econtext->caseValue_datum =
396  array_get_slice(array_source, i,
397  upper.indx, lower.indx,
398  upperProvided, lowerProvided,
399  astate->refattrlength,
400  astate->refelemlength,
401  astate->refelembyval,
402  astate->refelemalign);
403  econtext->caseValue_isNull = false;
404  }
405  }
406  else
407  {
408  /* argument shouldn't need caseValue, but for safety set it null */
409  econtext->caseValue_datum = (Datum) 0;
410  econtext->caseValue_isNull = true;
411  }
412 
413  /*
414  * Evaluate the value to be assigned into the array.
415  */
416  sourceData = ExecEvalExpr(astate->refassgnexpr,
417  econtext,
418  &eisnull);
419 
420  econtext->caseValue_datum = save_datum;
421  econtext->caseValue_isNull = save_isNull;
422 
423  /*
424  * For an assignment to a fixed-length array type, both the original
425  * array and the value to be assigned into it must be non-NULL, else
426  * we punt and return the original array.
427  */
428  if (astate->refattrlength > 0) /* fixed-length array? */
429  if (eisnull || *isNull)
430  return array_source;
431 
432  /*
433  * For assignment to varlena arrays, we handle a NULL original array
434  * by substituting an empty (zero-dimensional) array; insertion of the
435  * new element will result in a singleton array value. It does not
436  * matter whether the new element is NULL.
437  */
438  if (*isNull)
439  {
440  array_source = PointerGetDatum(construct_empty_array(arrayRef->refelemtype));
441  *isNull = false;
442  }
443 
444  if (lIndex == NULL)
445  return array_set_element(array_source, i,
446  upper.indx,
447  sourceData,
448  eisnull,
449  astate->refattrlength,
450  astate->refelemlength,
451  astate->refelembyval,
452  astate->refelemalign);
453  else
454  return array_set_slice(array_source, i,
455  upper.indx, lower.indx,
456  upperProvided, lowerProvided,
457  sourceData,
458  eisnull,
459  astate->refattrlength,
460  astate->refelemlength,
461  astate->refelembyval,
462  astate->refelemalign);
463  }
464 
465  if (lIndex == NULL)
466  return array_get_element(array_source, i,
467  upper.indx,
468  astate->refattrlength,
469  astate->refelemlength,
470  astate->refelembyval,
471  astate->refelemalign,
472  isNull);
473  else
474  return array_get_slice(array_source, i,
475  upper.indx, lower.indx,
476  upperProvided, lowerProvided,
477  astate->refattrlength,
478  astate->refelemlength,
479  astate->refelembyval,
480  astate->refelemalign);
481 }
int indx[MAXDIM]
Definition: c.h:418
#define NIL
Definition: pg_list.h:69
Datum array_get_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:2015
Expr * refassgnexpr
Definition: primnodes.h:387
ExprState xprstate
Definition: execnodes.h:674
#define DatumGetInt32(X)
Definition: postgres.h:480
#define MAXDIM
Definition: c.h:415
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
ExprState * refexpr
Definition: execnodes.h:677
#define PointerGetDatum(X)
Definition: postgres.h:564
int errcode(int sqlerrcode)
Definition: elog.c:575
Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:2186
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3424
ExprState * refassgnexpr
Definition: execnodes.h:678
Datum array_set_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, Datum srcArrayDatum, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:2746
List * refupperindexpr
Definition: execnodes.h:675
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:597
Datum caseValue_datum
Definition: execnodes.h:148
#define ereport(elevel, rest)
Definition: elog.h:122
Oid refelemtype
Definition: primnodes.h:378
uintptr_t Datum
Definition: postgres.h:374
static bool isAssignmentIndirectionExpr(ExprState *exprstate)
Definition: execQual.c:491
List * reflowerindexpr
Definition: execnodes.h:676
Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
Definition: arrayfuncs.c:1806
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
#define lfirst(lc)
Definition: pg_list.h:106
Definition: c.h:416
bool caseValue_isNull
Definition: execnodes.h:149
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define elog
Definition: elog.h:219
static Datum ExecEvalBooleanTest ( GenericExprState bstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3726 of file execQual.c.

References GenericExprState::arg, BoolGetDatum, BooleanTest::booltesttype, DatumGetBool, elog, ERROR, ExecEvalExpr, ExprState::expr, IS_FALSE, IS_NOT_FALSE, IS_NOT_TRUE, IS_NOT_UNKNOWN, IS_TRUE, IS_UNKNOWN, and GenericExprState::xprstate.

Referenced by ExecInitExpr().

3729 {
3730  BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
3731  Datum result;
3732 
3733  result = ExecEvalExpr(bstate->arg, econtext, isNull);
3734 
3735  switch (btest->booltesttype)
3736  {
3737  case IS_TRUE:
3738  if (*isNull)
3739  {
3740  *isNull = false;
3741  return BoolGetDatum(false);
3742  }
3743  else if (DatumGetBool(result))
3744  return BoolGetDatum(true);
3745  else
3746  return BoolGetDatum(false);
3747  case IS_NOT_TRUE:
3748  if (*isNull)
3749  {
3750  *isNull = false;
3751  return BoolGetDatum(true);
3752  }
3753  else if (DatumGetBool(result))
3754  return BoolGetDatum(false);
3755  else
3756  return BoolGetDatum(true);
3757  case IS_FALSE:
3758  if (*isNull)
3759  {
3760  *isNull = false;
3761  return BoolGetDatum(false);
3762  }
3763  else if (DatumGetBool(result))
3764  return BoolGetDatum(false);
3765  else
3766  return BoolGetDatum(true);
3767  case IS_NOT_FALSE:
3768  if (*isNull)
3769  {
3770  *isNull = false;
3771  return BoolGetDatum(true);
3772  }
3773  else if (DatumGetBool(result))
3774  return BoolGetDatum(true);
3775  else
3776  return BoolGetDatum(false);
3777  case IS_UNKNOWN:
3778  if (*isNull)
3779  {
3780  *isNull = false;
3781  return BoolGetDatum(true);
3782  }
3783  else
3784  return BoolGetDatum(false);
3785  case IS_NOT_UNKNOWN:
3786  if (*isNull)
3787  {
3788  *isNull = false;
3789  return BoolGetDatum(false);
3790  }
3791  else
3792  return BoolGetDatum(true);
3793  default:
3794  elog(ERROR, "unrecognized booltesttype: %d",
3795  (int) btest->booltesttype);
3796  return (Datum) 0; /* keep compiler quiet */
3797  }
3798 }
ExprState xprstate
Definition: execnodes.h:610
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:597
#define DatumGetBool(X)
Definition: postgres.h:401
ExprState * arg
Definition: execnodes.h:611
BoolTestType booltesttype
Definition: primnodes.h:1180
uintptr_t Datum
Definition: postgres.h:374
#define BoolGetDatum(X)
Definition: postgres.h:410
#define elog
Definition: elog.h:219
static Datum ExecEvalCase ( CaseExprState caseExpr,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2723 of file execQual.c.

References CaseExprState::arg, CaseExprState::args, CaseExprState::argtyplen, ExprContext::caseValue_datum, ExprContext::caseValue_isNull, DatumGetBool, CaseExprState::defresult, ExecEvalExpr, CaseWhenState::expr, lfirst, MakeExpandedObjectReadOnly, and CaseWhenState::result.

Referenced by ExecInitExpr().

2725 {
2726  List *clauses = caseExpr->args;
2727  ListCell *clause;
2728  Datum save_datum;
2729  bool save_isNull;
2730 
2731  /*
2732  * If there's a test expression, we have to evaluate it and save the value
2733  * where the CaseTestExpr placeholders can find it. We must save and
2734  * restore prior setting of econtext's caseValue fields, in case this node
2735  * is itself within a larger CASE. Furthermore, don't assign to the
2736  * econtext fields until after returning from evaluation of the test
2737  * expression. We used to pass &econtext->caseValue_isNull to the
2738  * recursive call, but that leads to aliasing that variable within said
2739  * call, which can (and did) produce bugs when the test expression itself
2740  * contains a CASE.
2741  *
2742  * If there's no test expression, we don't actually need to save and
2743  * restore these fields; but it's less code to just do so unconditionally.
2744  */
2745  save_datum = econtext->caseValue_datum;
2746  save_isNull = econtext->caseValue_isNull;
2747 
2748  if (caseExpr->arg)
2749  {
2750  Datum arg_value;
2751  bool arg_isNull;
2752 
2753  arg_value = ExecEvalExpr(caseExpr->arg,
2754  econtext,
2755  &arg_isNull);
2756  /* Since caseValue_datum may be read multiple times, force to R/O */
2757  econtext->caseValue_datum =
2758  MakeExpandedObjectReadOnly(arg_value,
2759  arg_isNull,
2760  caseExpr->argtyplen);
2761  econtext->caseValue_isNull = arg_isNull;
2762  }
2763 
2764  /*
2765  * we evaluate each of the WHEN clauses in turn, as soon as one is true we
2766  * return the corresponding result. If none are true then we return the
2767  * value of the default clause, or NULL if there is none.
2768  */
2769  foreach(clause, clauses)
2770  {
2771  CaseWhenState *wclause = lfirst(clause);
2772  Datum clause_value;
2773  bool clause_isNull;
2774 
2775  clause_value = ExecEvalExpr(wclause->expr,
2776  econtext,
2777  &clause_isNull);
2778 
2779  /*
2780  * if we have a true test, then we return the result, since the case
2781  * statement is satisfied. A NULL result from the test is not
2782  * considered true.
2783  */
2784  if (DatumGetBool(clause_value) && !clause_isNull)
2785  {
2786  econtext->caseValue_datum = save_datum;
2787  econtext->caseValue_isNull = save_isNull;
2788  return ExecEvalExpr(wclause->result,
2789  econtext,
2790  isNull);
2791  }
2792  }
2793 
2794  econtext->caseValue_datum = save_datum;
2795  econtext->caseValue_isNull = save_isNull;
2796 
2797  if (caseExpr->defresult)
2798  {
2799  return ExecEvalExpr(caseExpr->defresult,
2800  econtext,
2801  isNull);
2802  }
2803 
2804  *isNull = true;
2805  return (Datum) 0;
2806 }
ExprState * arg
Definition: execnodes.h:891
ExprState * expr
Definition: execnodes.h:904
List * args
Definition: execnodes.h:892
ExprState * defresult
Definition: execnodes.h:893
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
Datum caseValue_datum
Definition: execnodes.h:148
ExprState * result
Definition: execnodes.h:905
#define DatumGetBool(X)
Definition: postgres.h:401
#define MakeExpandedObjectReadOnly(d, isnull, typlen)
int16 argtyplen
Definition: execnodes.h:894
uintptr_t Datum
Definition: postgres.h:374
#define lfirst(lc)
Definition: pg_list.h:106
bool caseValue_isNull
Definition: execnodes.h:149
Definition: pg_list.h:45
static Datum ExecEvalCaseTestExpr ( ExprState exprstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2814 of file execQual.c.

References ExprContext::caseValue_datum, and ExprContext::caseValue_isNull.

Referenced by ExecInitExpr().

2817 {
2818  *isNull = econtext->caseValue_isNull;
2819  return econtext->caseValue_datum;
2820 }
Datum caseValue_datum
Definition: execnodes.h:148
bool caseValue_isNull
Definition: execnodes.h:149
static Datum ExecEvalCoalesce ( CoalesceExprState coalesceExpr,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3199 of file execQual.c.

References arg, CoalesceExprState::args, ExecEvalExpr, lfirst, and value.

Referenced by ExecInitExpr().

3201 {
3202  ListCell *arg;
3203 
3204  /* Simply loop through until something NOT NULL is found */
3205  foreach(arg, coalesceExpr->args)
3206  {
3207  ExprState *e = (ExprState *) lfirst(arg);
3208  Datum value;
3209 
3210  value = ExecEvalExpr(e, econtext, isNull);
3211  if (!*isNull)
3212  return value;
3213  }
3214 
3215  /* Else return NULL */
3216  *isNull = true;
3217  return (Datum) 0;
3218 }
static struct @76 value
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
uintptr_t Datum
Definition: postgres.h:374
#define lfirst(lc)
Definition: pg_list.h:106
e
Definition: preproc-init.c:82
void * arg
static Datum ExecEvalCoerceToDomain ( CoerceToDomainState cstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3808 of file execQual.c.

References CoerceToDomainState::arg, DomainConstraintState::check_expr, CoerceToDomainState::constraint_ref, DomainConstraintRef::constraints, DomainConstraintState::constrainttype, DatumGetBool, DOM_CONSTRAINT_CHECK, DOM_CONSTRAINT_NOTNULL, ExprContext::domainValue_datum, ExprContext::domainValue_isNull, elog, ereport, errcode(), errdatatype(), errdomainconstraint(), errmsg(), ERROR, ExecEvalExpr, ExprState::expr, format_type_be(), lfirst, MakeExpandedObjectReadOnly, DomainConstraintState::name, CoerceToDomain::resulttype, DomainConstraintRef::tcache, TypeCacheEntry::typlen, UpdateDomainConstraintRef(), and CoerceToDomainState::xprstate.

Referenced by ExecInitExpr().

3810 {
3811  CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
3812  Datum result;
3813  ListCell *l;
3814 
3815  result = ExecEvalExpr(cstate->arg, econtext, isNull);
3816 
3817  /* Make sure we have up-to-date constraints */
3819 
3820  foreach(l, cstate->constraint_ref->constraints)
3821  {
3823 
3824  switch (con->constrainttype)
3825  {
3827  if (*isNull)
3828  ereport(ERROR,
3829  (errcode(ERRCODE_NOT_NULL_VIOLATION),
3830  errmsg("domain %s does not allow null values",
3831  format_type_be(ctest->resulttype)),
3832  errdatatype(ctest->resulttype)));
3833  break;
3834  case DOM_CONSTRAINT_CHECK:
3835  {
3836  Datum conResult;
3837  bool conIsNull;
3838  Datum save_datum;
3839  bool save_isNull;
3840 
3841  /*
3842  * Set up value to be returned by CoerceToDomainValue
3843  * nodes. We must save and restore prior setting of
3844  * econtext's domainValue fields, in case this node is
3845  * itself within a check expression for another domain.
3846  *
3847  * Also, if we are working with a read-write expanded
3848  * datum, be sure that what we pass to CHECK expressions
3849  * is a read-only pointer; else called functions might
3850  * modify or even delete the expanded object.
3851  */
3852  save_datum = econtext->domainValue_datum;
3853  save_isNull = econtext->domainValue_isNull;
3854 
3855  econtext->domainValue_datum =
3856  MakeExpandedObjectReadOnly(result, *isNull,
3857  cstate->constraint_ref->tcache->typlen);
3858  econtext->domainValue_isNull = *isNull;
3859 
3860  conResult = ExecEvalExpr(con->check_expr, econtext,
3861  &conIsNull);
3862 
3863  if (!conIsNull &&
3864  !DatumGetBool(conResult))
3865  ereport(ERROR,
3866  (errcode(ERRCODE_CHECK_VIOLATION),
3867  errmsg("value for domain %s violates check constraint \"%s\"",
3868  format_type_be(ctest->resulttype),
3869  con->name),
3871  con->name)));
3872  econtext->domainValue_datum = save_datum;
3873  econtext->domainValue_isNull = save_isNull;
3874 
3875  break;
3876  }
3877  default:
3878  elog(ERROR, "unrecognized constraint type: %d",
3879  (int) con->constrainttype);
3880  break;
3881  }
3882  }
3883 
3884  /* If all has gone well (constraints did not fail) return the datum */
3885  return result;
3886 }
ExprState xprstate
Definition: execnodes.h:998
void UpdateDomainConstraintRef(DomainConstraintRef *ref)
Definition: typcache.c:1001
DomainConstraintType constrainttype
Definition: execnodes.h:1021
struct DomainConstraintRef * constraint_ref
Definition: execnodes.h:1002
ExprState * check_expr
Definition: execnodes.h:1023
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
Datum domainValue_datum
Definition: execnodes.h:152
int16 typlen
Definition: typcache.h:35
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define ERROR
Definition: elog.h:43
int errdomainconstraint(Oid datatypeOid, const char *conname)
Definition: domains.c:388
Expr * expr
Definition: execnodes.h:597
#define DatumGetBool(X)
Definition: postgres.h:401
#define MakeExpandedObjectReadOnly(d, isnull, typlen)
#define ereport(elevel, rest)
Definition: elog.h:122
bool domainValue_isNull
Definition: execnodes.h:153
uintptr_t Datum
Definition: postgres.h:374
int errdatatype(Oid datatypeOid)
Definition: domains.c:364
#define lfirst(lc)
Definition: pg_list.h:106
TypeCacheEntry * tcache
Definition: typcache.h:134
int errmsg(const char *fmt,...)
Definition: elog.c:797
ExprState * arg
Definition: execnodes.h:999
#define elog
Definition: elog.h:219
static Datum ExecEvalCoerceToDomainValue ( ExprState exprstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3894 of file execQual.c.

References ExprContext::domainValue_datum, and ExprContext::domainValue_isNull.

Referenced by ExecInitExpr().

3897 {
3898  *isNull = econtext->domainValue_isNull;
3899  return econtext->domainValue_datum;
3900 }
Datum domainValue_datum
Definition: execnodes.h:152
bool domainValue_isNull
Definition: execnodes.h:153
static Datum ExecEvalCoerceViaIO ( CoerceViaIOState iostate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 4096 of file execQual.c.

References CoerceViaIOState::arg, ExecEvalExpr, CoerceViaIOState::infunc, InputFunctionCall(), CoerceViaIOState::intypioparam, NULL, CoerceViaIOState::outfunc, and OutputFunctionCall().

Referenced by ExecInitExpr().

4099 {
4100  Datum result;
4101  Datum inputval;
4102  char *string;
4103 
4104  inputval = ExecEvalExpr(iostate->arg, econtext, isNull);
4105 
4106  if (*isNull)
4107  string = NULL; /* output functions are not called on nulls */
4108  else
4109  string = OutputFunctionCall(&iostate->outfunc, inputval);
4110 
4111  result = InputFunctionCall(&iostate->infunc,
4112  string,
4113  iostate->intypioparam,
4114  -1);
4115 
4116  /* The input function cannot change the null/not-null status */
4117  return result;
4118 }
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1926
FmgrInfo outfunc
Definition: execnodes.h:850
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
char string[11]
Definition: preproc-type.c:46
FmgrInfo infunc
Definition: execnodes.h:851
ExprState * arg
Definition: execnodes.h:849
uintptr_t Datum
Definition: postgres.h:374
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1882
#define NULL
Definition: c.h:226
static Datum ExecEvalConst ( ExprState exprstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 1056 of file execQual.c.

References Const::constisnull, Const::constvalue, and ExprState::expr.

Referenced by ExecInitExpr().

1058 {
1059  Const *con = (Const *) exprstate->expr;
1060 
1061  *isNull = con->constisnull;
1062  return con->constvalue;
1063 }
Datum constvalue
Definition: primnodes.h:174
Expr * expr
Definition: execnodes.h:597
bool constisnull
Definition: primnodes.h:175
static Datum ExecEvalConvertRowtype ( ConvertRowtypeExprState cstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2638 of file execQual.c.

References ConvertRowtypeExpr::arg, ConvertRowtypeExprState::arg, Assert, convert(), convert_tuples_by_name(), DatumGetHeapTupleHeader, do_convert_tuple(), ExprContext::ecxt_per_query_memory, ExecEvalExpr, ExprState::expr, exprType(), get_cached_rowtype(), gettext_noop, HeapTupleGetDatum, HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, ConvertRowtypeExprState::indesc, ConvertRowtypeExprState::initialized, ConvertRowtypeExprState::map, MemoryContextSwitchTo(), NULL, ConvertRowtypeExprState::outdesc, RECORDOID, ConvertRowtypeExpr::resulttype, tupleDesc::tdtypeid, and ConvertRowtypeExprState::xprstate.

Referenced by ExecInitExpr().

2641 {
2643  HeapTuple result;
2644  Datum tupDatum;
2645  HeapTupleHeader tuple;
2646  HeapTupleData tmptup;
2647 
2648  tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull);
2649 
2650  /* this test covers the isDone exception too: */
2651  if (*isNull)
2652  return tupDatum;
2653 
2654  tuple = DatumGetHeapTupleHeader(tupDatum);
2655 
2656  /* Lookup tupdescs if first time through or after rescan */
2657  if (cstate->indesc == NULL)
2658  {
2659  get_cached_rowtype(exprType((Node *) convert->arg), -1,
2660  &cstate->indesc, econtext);
2661  cstate->initialized = false;
2662  }
2663  if (cstate->outdesc == NULL)
2664  {
2665  get_cached_rowtype(convert->resulttype, -1,
2666  &cstate->outdesc, econtext);
2667  cstate->initialized = false;
2668  }
2669 
2670  /*
2671  * We used to be able to assert that incoming tuples are marked with
2672  * exactly the rowtype of cstate->indesc. However, now that
2673  * ExecEvalWholeRowVar might change the tuples' marking to plain RECORD
2674  * due to inserting aliases, we can only make this weak test:
2675  */
2676  Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid ||
2678 
2679  /* if first time through, initialize conversion map */
2680  if (!cstate->initialized)
2681  {
2682  MemoryContext old_cxt;
2683 
2684  /* allocate map in long-lived memory context */
2685  old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2686 
2687  /* prepare map from old to new attribute numbers */
2688  cstate->map = convert_tuples_by_name(cstate->indesc,
2689  cstate->outdesc,
2690  gettext_noop("could not convert row type"));
2691  cstate->initialized = true;
2692 
2693  MemoryContextSwitchTo(old_cxt);
2694  }
2695 
2696  /*
2697  * No-op if no conversion needed (not clear this can happen here).
2698  */
2699  if (cstate->map == NULL)
2700  return tupDatum;
2701 
2702  /*
2703  * do_convert_tuple needs a HeapTuple not a bare HeapTupleHeader.
2704  */
2705  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2706  tmptup.t_data = tuple;
2707 
2708  result = do_convert_tuple(&tmptup, cstate->map);
2709 
2710  return HeapTupleGetDatum(result);
2711 }
struct TupleConversionMap * map
Definition: execnodes.h:880
Oid tdtypeid
Definition: tupdesc.h:77
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define gettext_noop(x)
Definition: c.h:139
Definition: nodes.h:508
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:254
static void convert(const int32 val, char *const buf)
Definition: zic.c:1811
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
Expr * expr
Definition: execnodes.h:597
#define RECORDOID
Definition: pg_type.h:668
TupleConversionMap * convert_tuples_by_name(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:204
static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod, TupleDesc *cache_field, ExprContext *econtext)
Definition: execQual.c:1413
uintptr_t Datum
Definition: postgres.h:374
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:445
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:222
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
HeapTuple do_convert_tuple(HeapTuple tuple, TupleConversionMap *map)
Definition: tupconvert.c:341
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
static Datum ExecEvalCurrentOfExpr ( ExprState exprstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 4203 of file execQual.c.

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

Referenced by ExecInitExpr().

4205 {
4206  ereport(ERROR,
4207  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4208  errmsg("WHERE CURRENT OF is not supported for this table type")));
4209  return 0; /* keep compiler quiet */
4210 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
static Datum ExecEvalDistinct ( FuncExprState fcache,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2277 of file execQual.c.

References FunctionCallInfoData::argnull, FuncExprState::args, Assert, BoolGetDatum, DatumGetBool, ExprContext::ecxt_per_query_memory, ExecEvalFuncArgs(), ExprState::expr, FALSE, FuncExprState::fcinfo_data, FmgrInfo::fn_oid, FuncExprState::func, FunctionCallInvoke, init_fcache(), OpExpr::inputcollid, InvalidOid, FunctionCallInfoData::isnull, FunctionCallInfoData::nargs, OpExpr::opfuncid, TRUE, and FuncExprState::xprstate.

Referenced by ExecInitExpr().

2280 {
2281  Datum result;
2282  FunctionCallInfo fcinfo;
2283 
2284  /* Set non-null as default */
2285  *isNull = false;
2286 
2287  /*
2288  * Initialize function cache if first time through
2289  */
2290  if (fcache->func.fn_oid == InvalidOid)
2291  {
2292  DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
2293 
2294  init_fcache(op->opfuncid, op->inputcollid, fcache,
2295  econtext->ecxt_per_query_memory, false, false);
2296  }
2297 
2298  /*
2299  * Evaluate arguments
2300  */
2301  fcinfo = &fcache->fcinfo_data;
2302  ExecEvalFuncArgs(fcinfo, fcache->args, econtext);
2303  Assert(fcinfo->nargs == 2);
2304 
2305  if (fcinfo->argnull[0] && fcinfo->argnull[1])
2306  {
2307  /* Both NULL? Then is not distinct... */
2308  result = BoolGetDatum(FALSE);
2309  }
2310  else if (fcinfo->argnull[0] || fcinfo->argnull[1])
2311  {
2312  /* Only one is NULL? Then is distinct... */
2313  result = BoolGetDatum(TRUE);
2314  }
2315  else
2316  {
2317  fcinfo->isnull = false;
2318  result = FunctionCallInvoke(fcinfo);
2319  *isNull = fcinfo->isnull;
2320  /* Must invert result of "=" */
2321  result = BoolGetDatum(!DatumGetBool(result));
2322  }
2323 
2324  return result;
2325 }
static void ExecEvalFuncArgs(FunctionCallInfo fcinfo, List *argList, ExprContext *econtext)
Definition: execQual.c:1459
List * args
Definition: execnodes.h:696
static void init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache, MemoryContext fcacheCxt, bool allowSRF, bool needDescForSRF)
Definition: execQual.c:1273
Expr * expr
Definition: execnodes.h:597
#define FALSE
Definition: c.h:218
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:129
#define DatumGetBool(X)
Definition: postgres.h:401
bool argnull[FUNC_MAX_ARGS]
Definition: fmgr.h:78
FunctionCallInfoData fcinfo_data
Definition: execnodes.h:749
uintptr_t Datum
Definition: postgres.h:374
Oid opfuncid
Definition: primnodes.h:474
#define BoolGetDatum(X)
Definition: postgres.h:410
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:56
#define Assert(condition)
Definition: c.h:670
Oid inputcollid
Definition: primnodes.h:478
ExprState xprstate
Definition: execnodes.h:695
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
#define TRUE
Definition: c.h:214
FmgrInfo func
Definition: execnodes.h:703
Datum ExecEvalExprSwitchContext ( ExprState expression,
ExprContext econtext,
bool isNull 
)

Definition at line 4219 of file execQual.c.

References ExprContext::ecxt_per_tuple_memory, ExecEvalExpr, and MemoryContextSwitchTo().

Referenced by advance_aggregates(), domain_check_input(), evaluate_expr(), EvaluateParams(), ExecScanSubPlan(), ExecSetParamPlan(), ExecWindowAgg(), FormIndexDatum(), FormPartitionKeyDatum(), get_qual_for_range(), operator_predicate_proof(), recompute_limits(), tablesample_init(), TidListCreate(), and validateDomainConstraint().

4222 {
4223  Datum retDatum;
4224  MemoryContext oldContext;
4225 
4226  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4227  retDatum = ExecEvalExpr(expression, econtext, isNull);
4228  MemoryContextSwitchTo(oldContext);
4229  return retDatum;
4230 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:134
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
uintptr_t Datum
Definition: postgres.h:374
static Datum ExecEvalFieldSelect ( FieldSelectState fstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3909 of file execQual.c.

References FieldSelectState::arg, FieldSelectState::argdesc, DatumGetHeapTupleHeader, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, ExecEvalExpr, ExprState::expr, FieldSelect::fieldnum, format_type_be(), get_cached_rowtype(), heap_getattr, HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, FieldSelect::resulttype, and FieldSelectState::xprstate.

Referenced by ExecInitExpr().

3912 {
3913  FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
3914  AttrNumber fieldnum = fselect->fieldnum;
3915  Datum result;
3916  Datum tupDatum;
3917  HeapTupleHeader tuple;
3918  Oid tupType;
3919  int32 tupTypmod;
3920  TupleDesc tupDesc;
3921  Form_pg_attribute attr;
3922  HeapTupleData tmptup;
3923 
3924  tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull);
3925 
3926  if (*isNull)
3927  return tupDatum;
3928 
3929  tuple = DatumGetHeapTupleHeader(tupDatum);
3930 
3931  tupType = HeapTupleHeaderGetTypeId(tuple);
3932  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3933 
3934  /* Lookup tupdesc if first time through or if type changes */
3935  tupDesc = get_cached_rowtype(tupType, tupTypmod,
3936  &fstate->argdesc, econtext);
3937 
3938  /*
3939  * Find field's attr record. Note we don't support system columns here: a
3940  * datum tuple doesn't have valid values for most of the interesting
3941  * system columns anyway.
3942  */
3943  if (fieldnum <= 0) /* should never happen */
3944  elog(ERROR, "unsupported reference to system column %d in FieldSelect",
3945  fieldnum);
3946  if (fieldnum > tupDesc->natts) /* should never happen */
3947  elog(ERROR, "attribute number %d exceeds number of columns %d",
3948  fieldnum, tupDesc->natts);
3949  attr = tupDesc->attrs[fieldnum - 1];
3950 
3951  /* Check for dropped column, and force a NULL result if so */
3952  if (attr->attisdropped)
3953  {
3954  *isNull = true;
3955  return (Datum) 0;
3956  }
3957 
3958  /* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
3959  /* As in ExecEvalScalarVar, we should but can't check typmod */
3960  if (fselect->resulttype != attr->atttypid)
3961  ereport(ERROR,
3962  (errcode(ERRCODE_DATATYPE_MISMATCH),
3963  errmsg("attribute %d has wrong type", fieldnum),
3964  errdetail("Table has type %s, but query expects %s.",
3965  format_type_be(attr->atttypid),
3966  format_type_be(fselect->resulttype))));
3967 
3968  /* heap_getattr needs a HeapTuple not a bare HeapTupleHeader */
3969  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3970  tmptup.t_data = tuple;
3971 
3972  result = heap_getattr(&tmptup,
3973  fieldnum,
3974  tupDesc,
3975  isNull);
3976  return result;
3977 }
Oid resulttype
Definition: primnodes.h:720
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:254
signed int int32
Definition: c.h:253
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:455
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:597
TupleDesc argdesc
Definition: execnodes.h:827
int errdetail(const char *fmt,...)
Definition: elog.c:873
ExprState * arg
Definition: execnodes.h:826
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
#define ereport(elevel, rest)
Definition: elog.h:122
ExprState xprstate
Definition: execnodes.h:825
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod, TupleDesc *cache_field, ExprContext *econtext)
Definition: execQual.c:1413
uintptr_t Datum
Definition: postgres.h:374
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:445
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
int16 AttrNumber
Definition: attnum.h:21
AttrNumber fieldnum
Definition: primnodes.h:719
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
static Datum ExecEvalFieldStore ( FieldStoreState fstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3986 of file execQual.c.

References FieldStoreState::arg, FieldStoreState::argdesc, Assert, ExprContext::caseValue_datum, ExprContext::caseValue_isNull, DatumGetHeapTupleHeader, ExecEvalExpr, ExprState::expr, FieldStore::fieldnums, forboth, get_cached_rowtype(), heap_deform_tuple(), heap_form_tuple(), HeapTupleGetDatum, HeapTupleHeaderGetDatumLength, InvalidOid, ItemPointerSetInvalid, lfirst, lfirst_int, newval, FieldStoreState::newvals, palloc(), pfree(), FieldStore::resulttype, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, values, and FieldStoreState::xprstate.

Referenced by ExecInitExpr().

3989 {
3990  FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
3991  HeapTuple tuple;
3992  Datum tupDatum;
3993  TupleDesc tupDesc;
3994  Datum *values;
3995  bool *isnull;
3996  Datum save_datum;
3997  bool save_isNull;
3998  ListCell *l1,
3999  *l2;
4000 
4001  tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull);
4002 
4003  /* Lookup tupdesc if first time through or after rescan */
4004  tupDesc = get_cached_rowtype(fstore->resulttype, -1,
4005  &fstate->argdesc, econtext);
4006 
4007  /* Allocate workspace */
4008  values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
4009  isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
4010 
4011  if (!*isNull)
4012  {
4013  /*
4014  * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
4015  * set all the fields in the struct just in case.
4016  */
4017  HeapTupleHeader tuphdr;
4018  HeapTupleData tmptup;
4019 
4020  tuphdr = DatumGetHeapTupleHeader(tupDatum);
4021  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
4022  ItemPointerSetInvalid(&(tmptup.t_self));
4023  tmptup.t_tableOid = InvalidOid;
4024  tmptup.t_data = tuphdr;
4025 
4026  heap_deform_tuple(&tmptup, tupDesc, values, isnull);
4027  }
4028  else
4029  {
4030  /* Convert null input tuple into an all-nulls row */
4031  memset(isnull, true, tupDesc->natts * sizeof(bool));
4032  }
4033 
4034  /* Result is never null */
4035  *isNull = false;
4036 
4037  save_datum = econtext->caseValue_datum;
4038  save_isNull = econtext->caseValue_isNull;
4039 
4040  forboth(l1, fstate->newvals, l2, fstore->fieldnums)
4041  {
4042  ExprState *newval = (ExprState *) lfirst(l1);
4043  AttrNumber fieldnum = lfirst_int(l2);
4044 
4045  Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
4046 
4047  /*
4048  * Use the CaseTestExpr mechanism to pass down the old value of the
4049  * field being replaced; this is needed in case the newval is itself a
4050  * FieldStore or ArrayRef that has to obtain and modify the old value.
4051  * It's safe to reuse the CASE mechanism because there cannot be a
4052  * CASE between here and where the value would be needed, and a field
4053  * assignment can't be within a CASE either. (So saving and restoring
4054  * the caseValue is just paranoia, but let's do it anyway.)
4055  */
4056  econtext->caseValue_datum = values[fieldnum - 1];
4057  econtext->caseValue_isNull = isnull[fieldnum - 1];
4058 
4059  values[fieldnum - 1] = ExecEvalExpr(newval,
4060  econtext,
4061  &isnull[fieldnum - 1]);
4062  }
4063 
4064  econtext->caseValue_datum = save_datum;
4065  econtext->caseValue_isNull = save_isNull;
4066 
4067  tuple = heap_form_tuple(tupDesc, values, isnull);
4068 
4069  pfree(values);
4070  pfree(isnull);
4071 
4072  return HeapTupleGetDatum(tuple);
4073 }
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:174
ExprState xprstate
Definition: execnodes.h:836
ExprState * arg
Definition: execnodes.h:837
TupleDesc argdesc
Definition: execnodes.h:839
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:254
HeapTupleHeader t_data
Definition: htup.h:67
void pfree(void *pointer)
Definition: mcxt.c:992
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
Expr * expr
Definition: execnodes.h:597
#define lfirst_int(lc)
Definition: pg_list.h:107
Datum caseValue_datum
Definition: execnodes.h:148
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
Oid t_tableOid
Definition: htup.h:66
Oid resulttype
Definition: primnodes.h:747
List * newvals
Definition: execnodes.h:838
static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod, TupleDesc *cache_field, ExprContext *econtext)
Definition: execQual.c:1413
uintptr_t Datum
Definition: postgres.h:374
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:670
#define lfirst(lc)
Definition: pg_list.h:106
#define newval
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:222
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:935
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:131
bool caseValue_isNull
Definition: execnodes.h:149
void * palloc(Size size)
Definition: mcxt.c:891
List * fieldnums
Definition: primnodes.h:746
int16 AttrNumber
Definition: attnum.h:21
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
static Datum ExecEvalFunc ( FuncExprState fcache,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2228 of file execQual.c.

References ExprContext::ecxt_per_query_memory, ExprState::evalfunc, ExecMakeFunctionResultNoSets(), ExprState::expr, FuncExpr::funcid, init_fcache(), FuncExpr::inputcollid, and FuncExprState::xprstate.

Referenced by ExecInitExpr().

2231 {
2232  /* This is called only the first time through */
2233  FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
2234 
2235  /* Initialize function lookup info */
2236  init_fcache(func->funcid, func->inputcollid, fcache,
2237  econtext->ecxt_per_query_memory, false, false);
2238 
2239  /* Change the evalfunc pointer to save a few cycles in additional calls */
2241  return ExecMakeFunctionResultNoSets(fcache, econtext, isNull);
2242 }
Datum(* ExprStateEvalFunc)(ExprState *expression, ExprContext *econtext, bool *isNull)
Definition: execnodes.h:590
static void init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache, MemoryContext fcacheCxt, bool allowSRF, bool needDescForSRF)
Definition: execQual.c:1273
Oid funcid
Definition: primnodes.h:426
Expr * expr
Definition: execnodes.h:597
ExprStateEvalFunc evalfunc
Definition: execnodes.h:598
Oid inputcollid
Definition: primnodes.h:433
ExprState xprstate
Definition: execnodes.h:695
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache, ExprContext *econtext, bool *isNull)
Definition: execQual.c:1820
static void ExecEvalFuncArgs ( FunctionCallInfo  fcinfo,
List argList,
ExprContext econtext 
)
static

Definition at line 1459 of file execQual.c.

References arg, FunctionCallInfoData::arg, FunctionCallInfoData::argnull, Assert, ExecEvalExpr, i, lfirst, and FunctionCallInfoData::nargs.

Referenced by ExecEvalDistinct(), ExecEvalNullIf(), ExecEvalScalarArrayOp(), ExecMakeFunctionResultSet(), and ExecMakeTableFunctionResult().

1462 {
1463  int i;
1464  ListCell *arg;
1465 
1466  i = 0;
1467  foreach(arg, argList)
1468  {
1469  ExprState *argstate = (ExprState *) lfirst(arg);
1470 
1471  fcinfo->arg[i] = ExecEvalExpr(argstate,
1472  econtext,
1473  &fcinfo->argnull[i]);
1474  i++;
1475  }
1476 
1477  Assert(i == fcinfo->nargs);
1478 }
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
bool argnull[FUNC_MAX_ARGS]
Definition: fmgr.h:78
Datum arg[FUNC_MAX_ARGS]
Definition: fmgr.h:77
#define Assert(condition)
Definition: c.h:670
#define lfirst(lc)
Definition: pg_list.h:106
int i
void * arg
static Datum ExecEvalGroupingFuncExpr ( GroupingFuncExprState gstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2832 of file execQual.c.

References GroupingFuncExprState::aggstate, bms_is_member(), GroupingFuncExprState::clauses, AggState::grouped_cols, and lfirst_int.

Referenced by ExecInitExpr().

2835 {
2836  int result = 0;
2837  int attnum = 0;
2838  Bitmapset *grouped_cols = gstate->aggstate->grouped_cols;
2839  ListCell *lc;
2840 
2841  *isNull = false;
2842 
2843  foreach(lc, (gstate->clauses))
2844  {
2845  attnum = lfirst_int(lc);
2846 
2847  result = result << 1;
2848 
2849  if (!bms_is_member(attnum, grouped_cols))
2850  result = result | 1;
2851  }
2852 
2853  return (Datum) result;
2854 }
struct AggState * aggstate
Definition: execnodes.h:648
#define lfirst_int(lc)
Definition: pg_list.h:107
Bitmapset * grouped_cols
Definition: execnodes.h:1884
uintptr_t Datum
Definition: postgres.h:374
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:419
static Datum ExecEvalMinMax ( MinMaxExprState minmaxExpr,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3225 of file execQual.c.

References arg, MinMaxExprState::args, MinMaxExprState::cfunc, DatumGetInt32, ExecEvalExpr, ExprState::expr, FunctionCallInvoke, InitFunctionCallInfoData, MinMaxExpr::inputcollid, IS_GREATEST, IS_LEAST, lfirst, NULL, MinMaxExpr::op, value, and MinMaxExprState::xprstate.

Referenced by ExecInitExpr().

3227 {
3228  Datum result = (Datum) 0;
3229  MinMaxExpr *minmax = (MinMaxExpr *) minmaxExpr->xprstate.expr;
3230  Oid collation = minmax->inputcollid;
3231  MinMaxOp op = minmax->op;
3232  FunctionCallInfoData locfcinfo;
3233  ListCell *arg;
3234 
3235  *isNull = true; /* until we get a result */
3236 
3237  InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2,
3238  collation, NULL, NULL);
3239  locfcinfo.argnull[0] = false;
3240  locfcinfo.argnull[1] = false;
3241 
3242  foreach(arg, minmaxExpr->args)
3243  {
3244  ExprState *e = (ExprState *) lfirst(arg);
3245  Datum value;
3246  bool valueIsNull;
3247  int32 cmpresult;
3248 
3249  value = ExecEvalExpr(e, econtext, &valueIsNull);
3250  if (valueIsNull)
3251  continue; /* ignore NULL inputs */
3252 
3253  if (*isNull)
3254  {
3255  /* first nonnull input, adopt value */
3256  result = value;
3257  *isNull = false;
3258  }
3259  else
3260  {
3261  /* apply comparison function */
3262  locfcinfo.arg[0] = result;
3263  locfcinfo.arg[1] = value;
3264  locfcinfo.isnull = false;
3265  cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3266  if (locfcinfo.isnull) /* probably should not happen */
3267  continue;
3268  if (cmpresult > 0 && op == IS_LEAST)
3269  result = value;
3270  else if (cmpresult < 0 && op == IS_GREATEST)
3271  result = value;
3272  }
3273  }
3274 
3275  return result;
3276 }
static struct @76 value
#define DatumGetInt32(X)
Definition: postgres.h:480
ExprState xprstate
Definition: execnodes.h:964
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:253
FmgrInfo cfunc
Definition: execnodes.h:966
MinMaxOp
Definition: primnodes.h:1030
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
Expr * expr
Definition: execnodes.h:597
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:129
uintptr_t Datum
Definition: postgres.h:374
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:112
Oid inputcollid
Definition: primnodes.h:1041
e
Definition: preproc-init.c:82
void * arg
MinMaxOp op
Definition: primnodes.h:1042
static Datum ExecEvalNot ( BoolExprState notclause,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2516 of file execQual.c.

References BoolExprState::args, BoolGetDatum, DatumGetBool, ExecEvalExpr, and linitial.

Referenced by ExecInitExpr().

2518 {
2519  ExprState *clause = linitial(notclause->args);
2520  Datum expr_value;
2521 
2522  expr_value = ExecEvalExpr(clause, econtext, isNull);
2523 
2524  /*
2525  * if the expression evaluates to null, then we just cascade the null back
2526  * to whoever called us.
2527  */
2528  if (*isNull)
2529  return expr_value;
2530 
2531  /*
2532  * evaluation of 'not' is simple.. expr is false, then return 'true' and
2533  * vice versa.
2534  */
2535  return BoolGetDatum(!DatumGetBool(expr_value));
2536 }
List * args
Definition: execnodes.h:775
#define linitial(l)
Definition: pg_list.h:110
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define DatumGetBool(X)
Definition: postgres.h:401
uintptr_t Datum
Definition: postgres.h:374
#define BoolGetDatum(X)
Definition: postgres.h:410
static Datum ExecEvalNullIf ( FuncExprState nullIfExpr,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3571 of file execQual.c.

References FunctionCallInfoData::arg, FunctionCallInfoData::argnull, FuncExprState::args, Assert, DatumGetBool, ExprContext::ecxt_per_query_memory, ExecEvalFuncArgs(), ExprState::expr, FuncExprState::fcinfo_data, FmgrInfo::fn_oid, FuncExprState::func, FunctionCallInvoke, init_fcache(), OpExpr::inputcollid, InvalidOid, FunctionCallInfoData::isnull, FunctionCallInfoData::nargs, OpExpr::opfuncid, and FuncExprState::xprstate.

Referenced by ExecInitExpr().

3574 {
3575  Datum result;
3576  FunctionCallInfo fcinfo;
3577 
3578  /*
3579  * Initialize function cache if first time through
3580  */
3581  if (nullIfExpr->func.fn_oid == InvalidOid)
3582  {
3583  NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
3584 
3585  init_fcache(op->opfuncid, op->inputcollid, nullIfExpr,
3586  econtext->ecxt_per_query_memory, false, false);
3587  }
3588 
3589  /*
3590  * Evaluate arguments
3591  */
3592  fcinfo = &nullIfExpr->fcinfo_data;
3593  ExecEvalFuncArgs(fcinfo, nullIfExpr->args, econtext);
3594  Assert(fcinfo->nargs == 2);
3595 
3596  /* if either argument is NULL they can't be equal */
3597  if (!fcinfo->argnull[0] && !fcinfo->argnull[1])
3598  {
3599  fcinfo->isnull = false;
3600  result = FunctionCallInvoke(fcinfo);
3601  /* if the arguments are equal return null */
3602  if (!fcinfo->isnull && DatumGetBool(result))
3603  {
3604  *isNull = true;
3605  return (Datum) 0;
3606  }
3607  }
3608 
3609  /* else return first argument */
3610  *isNull = fcinfo->argnull[0];
3611  return fcinfo->arg[0];
3612 }
static void ExecEvalFuncArgs(FunctionCallInfo fcinfo, List *argList, ExprContext *econtext)
Definition: execQual.c:1459
List * args
Definition: execnodes.h:696
static void init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache, MemoryContext fcacheCxt, bool allowSRF, bool needDescForSRF)
Definition: execQual.c:1273
Expr * expr
Definition: execnodes.h:597
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:129
#define DatumGetBool(X)
Definition: postgres.h:401
bool argnull[FUNC_MAX_ARGS]
Definition: fmgr.h:78
FunctionCallInfoData fcinfo_data
Definition: execnodes.h:749
uintptr_t Datum
Definition: postgres.h:374
Oid opfuncid
Definition: primnodes.h:474
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:56
Datum arg[FUNC_MAX_ARGS]
Definition: fmgr.h:77
#define Assert(condition)
Definition: c.h:670
Oid inputcollid
Definition: primnodes.h:478
ExprState xprstate
Definition: execnodes.h:695
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
FmgrInfo func
Definition: execnodes.h:703
static Datum ExecEvalNullTest ( NullTestState nstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3621 of file execQual.c.

References NullTestState::arg, NullTestState::argdesc, NullTest::argisrow, tupleDesc::attrs, BoolGetDatum, DatumGetHeapTupleHeader, elog, ERROR, ExecEvalExpr, ExprState::expr, get_cached_rowtype(), heap_attisnull(), HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, IS_NOT_NULL, IS_NULL, tupleDesc::natts, NullTest::nulltesttype, HeapTupleData::t_data, HeapTupleData::t_len, and NullTestState::xprstate.

Referenced by ExecInitExpr().

3624 {
3625  NullTest *ntest = (NullTest *) nstate->xprstate.expr;
3626  Datum result;
3627 
3628  result = ExecEvalExpr(nstate->arg, econtext, isNull);
3629 
3630  if (ntest->argisrow && !(*isNull))
3631  {
3632  /*
3633  * The SQL standard defines IS [NOT] NULL for a non-null rowtype
3634  * argument as:
3635  *
3636  * "R IS NULL" is true if every field is the null value.
3637  *
3638  * "R IS NOT NULL" is true if no field is the null value.
3639  *
3640  * This definition is (apparently intentionally) not recursive; so our
3641  * tests on the fields are primitive attisnull tests, not recursive
3642  * checks to see if they are all-nulls or no-nulls rowtypes.
3643  *
3644  * The standard does not consider the possibility of zero-field rows,
3645  * but here we consider them to vacuously satisfy both predicates.
3646  */
3647  HeapTupleHeader tuple;
3648  Oid tupType;
3649  int32 tupTypmod;
3650  TupleDesc tupDesc;
3651  HeapTupleData tmptup;
3652  int att;
3653 
3654  tuple = DatumGetHeapTupleHeader(result);
3655 
3656  tupType = HeapTupleHeaderGetTypeId(tuple);
3657  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3658 
3659  /* Lookup tupdesc if first time through or if type changes */
3660  tupDesc = get_cached_rowtype(tupType, tupTypmod,
3661  &nstate->argdesc, econtext);
3662 
3663  /*
3664  * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
3665  */
3666  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3667  tmptup.t_data = tuple;
3668 
3669  for (att = 1; att <= tupDesc->natts; att++)
3670  {
3671  /* ignore dropped columns */
3672  if (tupDesc->attrs[att - 1]->attisdropped)
3673  continue;
3674  if (heap_attisnull(&tmptup, att))
3675  {
3676  /* null field disproves IS NOT NULL */
3677  if (ntest->nulltesttype == IS_NOT_NULL)
3678  return BoolGetDatum(false);
3679  }
3680  else
3681  {
3682  /* non-null field disproves IS NULL */
3683  if (ntest->nulltesttype == IS_NULL)
3684  return BoolGetDatum(false);
3685  }
3686  }
3687 
3688  return BoolGetDatum(true);
3689  }
3690  else
3691  {
3692  /* Simple scalar-argument case, or a null rowtype datum */
3693  switch (ntest->nulltesttype)
3694  {
3695  case IS_NULL:
3696  if (*isNull)
3697  {
3698  *isNull = false;
3699  return BoolGetDatum(true);
3700  }
3701  else
3702  return BoolGetDatum(false);
3703  case IS_NOT_NULL:
3704  if (*isNull)
3705  {
3706  *isNull = false;
3707  return BoolGetDatum(false);
3708  }
3709  else
3710  return BoolGetDatum(true);
3711  default:
3712  elog(ERROR, "unrecognized nulltesttype: %d",
3713  (int) ntest->nulltesttype);
3714  return (Datum) 0; /* keep compiler quiet */
3715  }
3716  }
3717 }
Form_pg_attribute * attrs
Definition: tupdesc.h:74
unsigned int Oid
Definition: postgres_ext.h:31
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:254
int natts
Definition: tupdesc.h:73
signed int int32
Definition: c.h:253
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:455
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:597
uint32 t_len
Definition: htup.h:64
bool heap_attisnull(HeapTuple tup, int attnum)
Definition: heaptuple.c:297
ExprState xprstate
Definition: execnodes.h:986
TupleDesc argdesc
Definition: execnodes.h:989
ExprState * arg
Definition: execnodes.h:987
static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod, TupleDesc *cache_field, ExprContext *econtext)
Definition: execQual.c:1413
uintptr_t Datum
Definition: postgres.h:374
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:445
NullTestType nulltesttype
Definition: primnodes.h:1157
#define BoolGetDatum(X)
Definition: postgres.h:410
bool argisrow
Definition: primnodes.h:1158
#define elog
Definition: elog.h:219
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
static Datum ExecEvalOper ( FuncExprState fcache,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2249 of file execQual.c.

References ExprContext::ecxt_per_query_memory, ExprState::evalfunc, ExecMakeFunctionResultNoSets(), ExprState::expr, init_fcache(), OpExpr::inputcollid, OpExpr::opfuncid, and FuncExprState::xprstate.

Referenced by ExecInitExpr().

2252 {
2253  /* This is called only the first time through */
2254  OpExpr *op = (OpExpr *) fcache->xprstate.expr;
2255 
2256  /* Initialize function lookup info */
2257  init_fcache(op->opfuncid, op->inputcollid, fcache,
2258  econtext->ecxt_per_query_memory, false, false);
2259 
2260  /* Change the evalfunc pointer to save a few cycles in additional calls */
2262  return ExecMakeFunctionResultNoSets(fcache, econtext, isNull);
2263 }
Datum(* ExprStateEvalFunc)(ExprState *expression, ExprContext *econtext, bool *isNull)
Definition: execnodes.h:590
static void init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache, MemoryContext fcacheCxt, bool allowSRF, bool needDescForSRF)
Definition: execQual.c:1273
Expr * expr
Definition: execnodes.h:597
ExprStateEvalFunc evalfunc
Definition: execnodes.h:598
Oid opfuncid
Definition: primnodes.h:474
Oid inputcollid
Definition: primnodes.h:478
ExprState xprstate
Definition: execnodes.h:695
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache, ExprContext *econtext, bool *isNull)
Definition: execQual.c:1820
static Datum ExecEvalOr ( BoolExprState orExpr,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2543 of file execQual.c.

References BoolExprState::args, BoolGetDatum, DatumGetBool, ExecEvalExpr, and lfirst.

Referenced by ExecInitExpr().

2545 {
2546  List *clauses = orExpr->args;
2547  ListCell *clause;
2548  bool AnyNull;
2549 
2550  AnyNull = false;
2551 
2552  /*
2553  * If any of the clauses is TRUE, the OR result is TRUE regardless of the
2554  * states of the rest of the clauses, so we can stop evaluating and return
2555  * TRUE immediately. If none are TRUE and one or more is NULL, we return
2556  * NULL; otherwise we return FALSE. This makes sense when you interpret
2557  * NULL as "don't know": if we have a TRUE then the OR is TRUE even if we
2558  * aren't sure about some of the other inputs. If all the known inputs are
2559  * FALSE, but we have one or more "don't knows", then we have to report
2560  * that we "don't know" what the OR's result should be --- perhaps one of
2561  * the "don't knows" would have been TRUE if we'd known its value. Only
2562  * when all the inputs are known to be FALSE can we state confidently that
2563  * the OR's result is FALSE.
2564  */
2565  foreach(clause, clauses)
2566  {
2567  ExprState *clausestate = (ExprState *) lfirst(clause);
2568  Datum clause_value;
2569 
2570  clause_value = ExecEvalExpr(clausestate, econtext, isNull);
2571 
2572  /*
2573  * if we have a non-null true result, then return it.
2574  */
2575  if (*isNull)
2576  AnyNull = true; /* remember we got a null */
2577  else if (DatumGetBool(clause_value))
2578  return clause_value;
2579  }
2580 
2581  /* AnyNull is true if at least one clause evaluated to NULL */
2582  *isNull = AnyNull;
2583  return BoolGetDatum(false);
2584 }
List * args
Definition: execnodes.h:775
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define DatumGetBool(X)
Definition: postgres.h:401
uintptr_t Datum
Definition: postgres.h:374
#define BoolGetDatum(X)
Definition: postgres.h:410
#define lfirst(lc)
Definition: pg_list.h:106
Definition: pg_list.h:45
static Datum ExecEvalParamExec ( ExprState exprstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 1072 of file execQual.c.

References Assert, ExprContext::ecxt_param_exec_vals, ExecSetParamPlan(), ExprState::expr, NULL, and Param::paramid.

Referenced by ExecInitExpr().

1074 {
1075  Param *expression = (Param *) exprstate->expr;
1076  int thisParamId = expression->paramid;
1077  ParamExecData *prm;
1078 
1079  /*
1080  * PARAM_EXEC params (internal executor parameters) are stored in the
1081  * ecxt_param_exec_vals array, and can be accessed by array index.
1082  */
1083  prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
1084  if (prm->execPlan != NULL)
1085  {
1086  /* Parameter not evaluated yet, so go do it */
1087  ExecSetParamPlan(prm->execPlan, econtext);
1088  /* ExecSetParamPlan should have processed this param... */
1089  Assert(prm->execPlan == NULL);
1090  }
1091  *isNull = prm->isnull;
1092  return prm->value;
1093 }
Expr * expr
Definition: execnodes.h:597
void ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
Definition: nodeSubplan.c:935
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:137
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
int paramid
Definition: primnodes.h:223
static Datum ExecEvalParamExtern ( ExprState exprstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 1102 of file execQual.c.

References ExprContext::ecxt_param_list_info, ereport, errcode(), errmsg(), ERROR, ExprState::expr, format_type_be(), ParamExternData::isnull, NULL, OidIsValid, Param::paramid, Param::paramtype, ParamExternData::ptype, and ParamExternData::value.

Referenced by ExecInitExpr().

1104 {
1105  Param *expression = (Param *) exprstate->expr;
1106  int thisParamId = expression->paramid;
1107  ParamListInfo paramInfo = econtext->ecxt_param_list_info;
1108 
1109  /*
1110  * PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
1111  */
1112  if (paramInfo &&
1113  thisParamId > 0 && thisParamId <= paramInfo->numParams)
1114  {
1115  ParamExternData *prm = &paramInfo->params[thisParamId - 1];
1116 
1117  /* give hook a chance in case parameter is dynamic */
1118  if (!OidIsValid(prm->ptype) && paramInfo->paramFetch != NULL)
1119  (*paramInfo->paramFetch) (paramInfo, thisParamId);
1120 
1121  if (OidIsValid(prm->ptype))
1122  {
1123  /* safety check in case hook did something unexpected */
1124  if (prm->ptype != expression->paramtype)
1125  ereport(ERROR,
1126  (errcode(ERRCODE_DATATYPE_MISMATCH),
1127  errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
1128  thisParamId,
1129  format_type_be(prm->ptype),
1130  format_type_be(expression->paramtype))));
1131 
1132  *isNull = prm->isnull;
1133  return prm->value;
1134  }
1135  }
1136 
1137  ereport(ERROR,
1138  (errcode(ERRCODE_UNDEFINED_OBJECT),
1139  errmsg("no value found for parameter %d", thisParamId)));
1140  return (Datum) 0; /* keep compiler quiet */
1141 }
Datum value
Definition: params.h:56
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
#define OidIsValid(objectId)
Definition: c.h:533
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:597
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:374
#define NULL
Definition: c.h:226
int paramid
Definition: primnodes.h:223
int errmsg(const char *fmt,...)
Definition: elog.c:797
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:138
bool isnull
Definition: params.h:57
Oid paramtype
Definition: primnodes.h:224
static Datum ExecEvalRelabelType ( GenericExprState exprstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 4082 of file execQual.c.

References GenericExprState::arg, and ExecEvalExpr.

Referenced by ExecInitExpr().

4085 {
4086  return ExecEvalExpr(exprstate->arg, econtext, isNull);
4087 }
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
ExprState * arg
Definition: execnodes.h:611
static Datum ExecEvalRow ( RowExprState rstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3085 of file execQual.c.

References arg, RowExprState::args, ExecEvalExpr, heap_form_tuple(), HeapTupleGetDatum, i, lfirst, tupleDesc::natts, palloc(), palloc0(), pfree(), RowExprState::tupdesc, and values.

Referenced by ExecInitExpr().

3088 {
3089  HeapTuple tuple;
3090  Datum *values;
3091  bool *isnull;
3092  int natts;
3093  ListCell *arg;
3094  int i;
3095 
3096  /* Set non-null as default */
3097  *isNull = false;
3098 
3099  /* Allocate workspace */
3100  natts = rstate->tupdesc->natts;
3101  values = (Datum *) palloc0(natts * sizeof(Datum));
3102  isnull = (bool *) palloc(natts * sizeof(bool));
3103 
3104  /* preset to nulls in case rowtype has some later-added columns */
3105  memset(isnull, true, natts * sizeof(bool));
3106 
3107  /* Evaluate field values */
3108  i = 0;
3109  foreach(arg, rstate->args)
3110  {
3111  ExprState *e = (ExprState *) lfirst(arg);
3112 
3113  values[i] = ExecEvalExpr(e, econtext, &isnull[i]);
3114  i++;
3115  }
3116 
3117  tuple = heap_form_tuple(rstate->tupdesc, values, isnull);
3118 
3119  pfree(values);
3120  pfree(isnull);
3121 
3122  return HeapTupleGetDatum(tuple);
3123 }
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
int natts
Definition: tupdesc.h:73
void pfree(void *pointer)
Definition: mcxt.c:992
List * args
Definition: execnodes.h:931
TupleDesc tupdesc
Definition: execnodes.h:932
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
void * palloc0(Size size)
Definition: mcxt.c:920
uintptr_t Datum
Definition: postgres.h:374
#define lfirst(lc)
Definition: pg_list.h:106
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:222
static Datum values[MAXATTR]
Definition: bootstrap.c:162
e
Definition: preproc-init.c:82
void * palloc(Size size)
Definition: mcxt.c:891
int i
void * arg
static Datum ExecEvalRowCompare ( RowCompareExprState rstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3130 of file execQual.c.

References FunctionCallInfoData::arg, FunctionCallInfoData::argnull, BoolGetDatum, RowCompareExprState::collations, DatumGetInt32, elog, ERROR, ExecEvalExpr, ExprState::expr, FmgrInfo::fn_strict, forboth, RowCompareExprState::funcs, FunctionCallInvoke, i, InitFunctionCallInfoData, FunctionCallInfoData::isnull, RowCompareExprState::largs, lfirst, NULL, RowCompareExprState::rargs, ROWCOMPARE_GE, ROWCOMPARE_GT, ROWCOMPARE_LE, ROWCOMPARE_LT, and RowCompareExprState::xprstate.

Referenced by ExecInitExpr().

3133 {
3134  bool result;
3135  RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
3136  int32 cmpresult = 0;
3137  ListCell *l;
3138  ListCell *r;
3139  int i;
3140 
3141  *isNull = true; /* until we get a result */
3142 
3143  i = 0;
3144  forboth(l, rstate->largs, r, rstate->rargs)
3145  {
3146  ExprState *le = (ExprState *) lfirst(l);
3147  ExprState *re = (ExprState *) lfirst(r);
3148  FunctionCallInfoData locfcinfo;
3149 
3150  InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
3151  rstate->collations[i],
3152  NULL, NULL);
3153  locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
3154  &locfcinfo.argnull[0]);
3155  locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
3156  &locfcinfo.argnull[1]);
3157  if (rstate->funcs[i].fn_strict &&
3158  (locfcinfo.argnull[0] || locfcinfo.argnull[1]))
3159  return (Datum) 0; /* force NULL result */
3160  locfcinfo.isnull = false;
3161  cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3162  if (locfcinfo.isnull)
3163  return (Datum) 0; /* force NULL result */
3164  if (cmpresult != 0)
3165  break; /* no need to compare remaining columns */
3166  i++;
3167  }
3168 
3169  switch (rctype)
3170  {
3171  /* EQ and NE cases aren't allowed here */
3172  case ROWCOMPARE_LT:
3173  result = (cmpresult < 0);
3174  break;
3175  case ROWCOMPARE_LE:
3176  result = (cmpresult <= 0);
3177  break;
3178  case ROWCOMPARE_GE:
3179  result = (cmpresult >= 0);
3180  break;
3181  case ROWCOMPARE_GT:
3182  result = (cmpresult > 0);
3183  break;
3184  default:
3185  elog(ERROR, "unrecognized RowCompareType: %d", (int) rctype);
3186  result = 0; /* keep compiler quiet */
3187  break;
3188  }
3189 
3190  *isNull = false;
3191  return BoolGetDatum(result);
3192 }
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:174
#define DatumGetInt32(X)
Definition: postgres.h:480
FmgrInfo * funcs
Definition: execnodes.h:944
signed int int32
Definition: c.h:253
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define ERROR
Definition: elog.h:43
bool fn_strict
Definition: fmgr.h:58
Expr * expr
Definition: execnodes.h:597
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:129
bool argnull[FUNC_MAX_ARGS]
Definition: fmgr.h:78
ExprState xprstate
Definition: execnodes.h:941
uintptr_t Datum
Definition: postgres.h:374
#define BoolGetDatum(X)
Definition: postgres.h:410
RowCompareType
Definition: primnodes.h:993
Datum arg[FUNC_MAX_ARGS]
Definition: fmgr.h:77
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:112
int i
#define elog
Definition: elog.h:219
static Datum ExecEvalScalarArrayOp ( ScalarArrayOpExprState sstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 2336 of file execQual.c.

References FuncExprState::args, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, ARR_NULLBITMAP, ArrayGetNItems(), Assert, att_addlength_pointer, att_align_nominal, BoolGetDatum, DatumGetArrayTypeP, DatumGetBool, ExprContext::ecxt_per_query_memory, ScalarArrayOpExprState::element_type, ExecEvalFuncArgs(), ExprState::expr, FuncExprState::fcinfo_data, fetch_att, FmgrInfo::fn_oid, FmgrInfo::fn_strict, FuncExprState::func, FunctionCallInvoke, ScalarArrayOpExprState::fxprstate, get_typlenbyvalalign(), i, init_fcache(), ScalarArrayOpExpr::inputcollid, InvalidOid, ScalarArrayOpExpr::opfuncid, ScalarArrayOpExprState::typalign, ScalarArrayOpExprState::typbyval, ScalarArrayOpExprState::typlen, ScalarArrayOpExpr::useOr, and FuncExprState::xprstate.

Referenced by ExecInitExpr().

2339 {
2341  bool useOr = opexpr->useOr;
2342  ArrayType *arr;
2343  int nitems;
2344  Datum result;
2345  bool resultnull;
2346  FunctionCallInfo fcinfo;
2347  int i;
2348  int16 typlen;
2349  bool typbyval;
2350  char typalign;
2351  char *s;
2352  bits8 *bitmap;
2353  int bitmask;
2354 
2355  /* Set non-null as default */
2356  *isNull = false;
2357 
2358  /*
2359  * Initialize function cache if first time through
2360  */
2361  if (sstate->fxprstate.func.fn_oid == InvalidOid)
2362  {
2363  init_fcache(opexpr->opfuncid, opexpr->inputcollid, &sstate->fxprstate,
2364  econtext->ecxt_per_query_memory, false, false);
2365  }
2366 
2367  /*
2368  * Evaluate arguments
2369  */
2370  fcinfo = &sstate->fxprstate.fcinfo_data;
2371  ExecEvalFuncArgs(fcinfo, sstate->fxprstate.args, econtext);
2372  Assert(fcinfo->nargs == 2);
2373 
2374  /*
2375  * If the array is NULL then we return NULL --- it's not very meaningful
2376  * to do anything else, even if the operator isn't strict.
2377  */
2378  if (fcinfo->argnull[1])
2379  {
2380  *isNull = true;
2381  return (Datum) 0;
2382  }
2383  /* Else okay to fetch and detoast the array */
2384  arr = DatumGetArrayTypeP(fcinfo->arg[1]);
2385 
2386  /*
2387  * If the array is empty, we return either FALSE or TRUE per the useOr
2388  * flag. This is correct even if the scalar is NULL; since we would
2389  * evaluate the operator zero times, it matters not whether it would want
2390  * to return NULL.
2391  */
2392  nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2393  if (nitems <= 0)
2394  return BoolGetDatum(!useOr);
2395 
2396  /*
2397  * If the scalar is NULL, and the function is strict, return NULL; no
2398  * point in iterating the loop.
2399  */
2400  if (fcinfo->argnull[0] && sstate->fxprstate.func.fn_strict)
2401  {
2402  *isNull = true;
2403  return (Datum) 0;
2404  }
2405 
2406  /*
2407  * We arrange to look up info about the element type only once per series
2408  * of calls, assuming the element type doesn't change underneath us.
2409  */
2410  if (sstate->element_type != ARR_ELEMTYPE(arr))
2411  {
2413  &sstate->typlen,
2414  &sstate->typbyval,
2415  &sstate->typalign);
2416  sstate->element_type = ARR_ELEMTYPE(arr);
2417  }
2418  typlen = sstate->typlen;
2419  typbyval = sstate->typbyval;
2420  typalign = sstate->typalign;
2421 
2422  result = BoolGetDatum(!useOr);
2423  resultnull = false;
2424 
2425  /* Loop over the array elements */
2426  s = (char *) ARR_DATA_PTR(arr);
2427  bitmap = ARR_NULLBITMAP(arr);
2428  bitmask = 1;
2429 
2430  for (i = 0; i < nitems; i++)
2431  {
2432  Datum elt;
2433  Datum thisresult;
2434 
2435  /* Get array element, checking for NULL */
2436  if (bitmap && (*bitmap & bitmask) == 0)
2437  {
2438  fcinfo->arg[1] = (Datum) 0;
2439  fcinfo->argnull[1] = true;
2440  }
2441  else
2442  {
2443  elt = fetch_att(s, typbyval, typlen);
2444  s = att_addlength_pointer(s, typlen, s);
2445  s = (char *) att_align_nominal(s, typalign);
2446  fcinfo->arg[1] = elt;
2447  fcinfo->argnull[1] = false;
2448  }
2449 
2450  /* Call comparison function */
2451  if (fcinfo->argnull[1] && sstate->fxprstate.func.fn_strict)
2452  {
2453  fcinfo->isnull = true;
2454  thisresult = (Datum) 0;
2455  }
2456  else
2457  {
2458  fcinfo->isnull = false;
2459  thisresult = FunctionCallInvoke(fcinfo);
2460  }
2461 
2462  /* Combine results per OR or AND semantics */
2463  if (fcinfo->isnull)
2464  resultnull = true;
2465  else if (useOr)
2466  {
2467  if (DatumGetBool(thisresult))
2468  {
2469  result = BoolGetDatum(true);
2470  resultnull = false;
2471  break; /* needn't look at any more elements */
2472  }
2473  }
2474  else
2475  {
2476  if (!DatumGetBool(thisresult))
2477  {
2478  result = BoolGetDatum(false);
2479  resultnull = false;
2480  break; /* needn't look at any more elements */
2481  }
2482  }
2483 
2484  /* advance bitmap pointer if any */
2485  if (bitmap)
2486  {
2487  bitmask <<= 1;
2488  if (bitmask == 0x100)
2489  {
2490  bitmap++;
2491  bitmask = 1;
2492  }
2493  }
2494  }
2495 
2496  *isNull = resultnull;
2497  return result;
2498 }
signed short int16
Definition: c.h:252
static void ExecEvalFuncArgs(FunctionCallInfo fcinfo, List *argList, ExprContext *econtext)
Definition: execQual.c:1459
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:144
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:1989
List * args
Definition: execnodes.h:696
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
static void init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache, MemoryContext fcacheCxt, bool allowSRF, bool needDescForSRF)
Definition: execQual.c:1273
bool fn_strict
Definition: fmgr.h:58
Expr * expr
Definition: execnodes.h:597
#define ARR_DIMS(a)
Definition: array.h:275
#define ARR_DATA_PTR(a)
Definition: array.h:303
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:129
#define DatumGetBool(X)
Definition: postgres.h:401
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:172
uint8 bits8
Definition: c.h:272
FunctionCallInfoData fcinfo_data
Definition: execnodes.h:749
uintptr_t Datum
Definition: postgres.h:374
#define BoolGetDatum(X)
Definition: postgres.h:410
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:56
#define Assert(condition)
Definition: c.h:670
FuncExprState fxprstate
Definition: execnodes.h:760
ExprState xprstate
Definition: execnodes.h:695
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
#define ARR_NDIM(a)
Definition: array.h:271
#define fetch_att(T, attbyval, attlen)
Definition: tupmacs.h:71
int i
FmgrInfo func
Definition: execnodes.h:703
#define ARR_ELEMTYPE(a)
Definition: array.h:273
#define ARR_NULLBITMAP(a)
Definition: array.h:281
#define DatumGetArrayTypeP(X)
Definition: array.h:242
static Datum ExecEvalScalarVar ( ExprState exprstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 560 of file execQual.c.

References Assert, tupleDesc::attrs, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_scantuple, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, ExprState::evalfunc, ExecEvalScalarVarFast(), ExprState::expr, format_type_be(), INNER_VAR, InvalidAttrNumber, tupleDesc::natts, OUTER_VAR, slot_getattr(), Var::varattno, Var::varno, and Var::vartype.

Referenced by ExecInitExpr().

562 {
563  Var *variable = (Var *) exprstate->expr;
564  TupleTableSlot *slot;
565  AttrNumber attnum;
566 
567  /* Get the input slot and attribute number we want */
568  switch (variable->varno)
569  {
570  case INNER_VAR: /* get the tuple from the inner node */
571  slot = econtext->ecxt_innertuple;
572  break;
573 
574  case OUTER_VAR: /* get the tuple from the outer node */
575  slot = econtext->ecxt_outertuple;
576  break;
577 
578  /* INDEX_VAR is handled by default case */
579 
580  default: /* get the tuple from the relation being
581  * scanned */
582  slot = econtext->ecxt_scantuple;
583  break;
584  }
585 
586  attnum = variable->varattno;
587 
588  /* This was checked by ExecInitExpr */
589  Assert(attnum != InvalidAttrNumber);
590 
591  /*
592  * If it's a user attribute, check validity (bogus system attnums will be
593  * caught inside slot_getattr). What we have to check for here is the
594  * possibility of an attribute having been changed in type since the plan
595  * tree was created. Ideally the plan will get invalidated and not
596  * re-used, but just in case, we keep these defenses. Fortunately it's
597  * sufficient to check once on the first time through.
598  *
599  * Note: we allow a reference to a dropped attribute. slot_getattr will
600  * force a NULL result in such cases.
601  *
602  * Note: ideally we'd check typmod as well as typid, but that seems
603  * impractical at the moment: in many cases the tupdesc will have been
604  * generated by ExecTypeFromTL(), and that can't guarantee to generate an
605  * accurate typmod in all cases, because some expression node types don't
606  * carry typmod.
607  */
608  if (attnum > 0)
609  {
610  TupleDesc slot_tupdesc = slot->tts_tupleDescriptor;
611  Form_pg_attribute attr;
612 
613  if (attnum > slot_tupdesc->natts) /* should never happen */
614  elog(ERROR, "attribute number %d exceeds number of columns %d",
615  attnum, slot_tupdesc->natts);
616 
617  attr = slot_tupdesc->attrs[attnum - 1];
618 
619  /* can't check type if dropped, since atttypid is probably 0 */
620  if (!attr->attisdropped)
621  {
622  if (variable->vartype != attr->atttypid)
623  ereport(ERROR,
624  (errcode(ERRCODE_DATATYPE_MISMATCH),
625  errmsg("attribute %d has wrong type", attnum),
626  errdetail("Table has type %s, but query expects %s.",
627  format_type_be(attr->atttypid),
628  format_type_be(variable->vartype))));
629  }
630  }
631 
632  /* Skip the checking on future executions of node */
633  exprstate->evalfunc = ExecEvalScalarVarFast;
634 
635  /* Fetch the value from the slot */
636  return slot_getattr(slot, attnum, isNull);
637 }
static Datum ExecEvalScalarVarFast(ExprState *exprstate, ExprContext *econtext, bool *isNull)
Definition: execQual.c:646
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int errcode(int sqlerrcode)
Definition: elog.c:575
AttrNumber varattno
Definition: primnodes.h:146
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
Definition: primnodes.h:141
int natts
Definition: tupdesc.h:73
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:597
Oid vartype
Definition: primnodes.h:148
ExprStateEvalFunc evalfunc
Definition: execnodes.h:598
int errdetail(const char *fmt,...)
Definition: elog.c:873
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:129
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
#define ereport(elevel, rest)
Definition: elog.h:122
Index varno
Definition: primnodes.h:144
#define INNER_VAR
Definition: primnodes.h:131
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:130
#define Assert(condition)
Definition: c.h:670
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
#define InvalidAttrNumber
Definition: attnum.h:23
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: heaptuple.c:1143
#define elog
Definition: elog.h:219
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:132
static Datum ExecEvalScalarVarFast ( ExprState exprstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 646 of file execQual.c.

References ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_scantuple, ExprState::expr, INNER_VAR, OUTER_VAR, slot_getattr(), Var::varattno, and Var::varno.

Referenced by ExecEvalScalarVar().

648 {
649  Var *variable = (Var *) exprstate->expr;
650  TupleTableSlot *slot;
651  AttrNumber attnum;
652 
653  /* Get the input slot and attribute number we want */
654  switch (variable->varno)
655  {
656  case INNER_VAR: /* get the tuple from the inner node */
657  slot = econtext->ecxt_innertuple;
658  break;
659 
660  case OUTER_VAR: /* get the tuple from the outer node */
661  slot = econtext->ecxt_outertuple;
662  break;
663 
664  /* INDEX_VAR is handled by default case */
665 
666  default: /* get the tuple from the relation being
667  * scanned */
668  slot = econtext->ecxt_scantuple;
669  break;
670  }
671 
672  attnum = variable->varattno;
673 
674  /* Fetch the value from the slot */
675  return slot_getattr(slot, attnum, isNull);
676 }
AttrNumber varattno
Definition: primnodes.h:146
Definition: primnodes.h:141
Expr * expr
Definition: execnodes.h:597
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:129
Index varno
Definition: primnodes.h:144
#define INNER_VAR
Definition: primnodes.h:131
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:130
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: heaptuple.c:1143
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:132
static Datum ExecEvalSQLValueFunction ( ExprState svfExpr,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3283 of file execQual.c.

References current_database(), current_schema(), current_user(), DateADTGetDatum, ExprState::expr, GetSQLCurrentDate(), GetSQLCurrentTime(), GetSQLCurrentTimestamp(), GetSQLLocalTime(), GetSQLLocalTimestamp(), InitFunctionCallInfoData, InvalidOid, NULL, SQLValueFunction::op, session_user(), 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 ExecInitExpr().

3286 {
3287  Datum result = (Datum) 0;
3288  SQLValueFunction *svf = (SQLValueFunction *) svfExpr->expr;
3289  FunctionCallInfoData fcinfo;
3290 
3291  *isNull = false;
3292 
3293  /*
3294  * Note: current_schema() can return NULL. current_user() etc currently
3295  * cannot, but might as well code those cases the same way for safety.
3296  */
3297  switch (svf->op)
3298  {
3299  case SVFOP_CURRENT_DATE:
3300  result = DateADTGetDatum(GetSQLCurrentDate());
3301  break;
3302  case SVFOP_CURRENT_TIME:
3303  case SVFOP_CURRENT_TIME_N:
3305  break;
3309  break;
3310  case SVFOP_LOCALTIME:
3311  case SVFOP_LOCALTIME_N:
3312  result = TimeADTGetDatum(GetSQLLocalTime(svf->typmod));
3313  break;
3314  case SVFOP_LOCALTIMESTAMP:
3317  break;
3318  case SVFOP_CURRENT_ROLE:
3319  case SVFOP_CURRENT_USER:
3320  case SVFOP_USER:
3322  result = current_user(&fcinfo);
3323  *isNull = fcinfo.isnull;
3324  break;
3325  case SVFOP_SESSION_USER:
3327  result = session_user(&fcinfo);
3328  *isNull = fcinfo.isnull;
3329  break;
3330  case SVFOP_CURRENT_CATALOG:
3332  result = current_database(&fcinfo);
3333  *isNull = fcinfo.isnull;
3334  break;
3335  case SVFOP_CURRENT_SCHEMA:
3337  result = current_schema(&fcinfo);
3338  *isNull = fcinfo.isnull;
3339  break;
3340  }
3341 
3342  return result;
3343 }
Datum current_schema(PG_FUNCTION_ARGS)
Definition: name.c:280
#define TimeTzADTPGetDatum(X)
Definition: date.h:79
TimestampTz GetSQLCurrentTimestamp(int32 typmod)
Definition: timestamp.c:1754
#define DateADTGetDatum(X)
Definition: date.h:77
DateADT GetSQLCurrentDate(void)
Definition: date.c:314
SQLValueFunctionOp op
Definition: primnodes.h:1080
Datum current_database(PG_FUNCTION_ARGS)
Definition: misc.c:176
Expr * expr
Definition: execnodes.h:597
#define TimestampTzGetDatum(X)
Definition: timestamp.h:52
TimeTzADT * GetSQLCurrentTime(int32 typmod)
Definition: date.c:336
Datum current_user(PG_FUNCTION_ARGS)
Definition: name.c:264
#define TimestampGetDatum(X)
Definition: timestamp.h:51
TimeADT GetSQLLocalTime(int32 typmod)
Definition: date.c:362
Datum session_user(PG_FUNCTION_ARGS)
Definition: name.c:270
uintptr_t Datum
Definition: postgres.h:374
#define TimeADTGetDatum(X)
Definition: date.h:78
Timestamp GetSQLLocalTimestamp(int32 typmod)
Definition: timestamp.c:1768
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:226
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:112
static Datum ExecEvalWholeRowFast ( WholeRowVarExprState wrvstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 915 of file execQual.c.

References DatumGetHeapTupleHeader, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_scantuple, ExecFetchSlotTupleDatum(), ExecFilterJunk(), ExprState::expr, HeapTupleHeaderSetTypeId, HeapTupleHeaderSetTypMod, INNER_VAR, NULL, OUTER_VAR, PointerGetDatum, tupleDesc::tdtypeid, tupleDesc::tdtypmod, Var::varno, WholeRowVarExprState::wrv_junkFilter, WholeRowVarExprState::wrv_tupdesc, and WholeRowVarExprState::xprstate.

Referenced by ExecEvalWholeRowVar().

917 {
918  Var *variable = (Var *) wrvstate->xprstate.expr;
919  TupleTableSlot *slot;
920  HeapTupleHeader dtuple;
921 
922  *isNull = false;
923 
924  /* Get the input slot we want */
925  switch (variable->varno)
926  {
927  case INNER_VAR: /* get the tuple from the inner node */
928  slot = econtext->ecxt_innertuple;
929  break;
930 
931  case OUTER_VAR: /* get the tuple from the outer node */
932  slot = econtext->ecxt_outertuple;
933  break;
934 
935  /* INDEX_VAR is handled by default case */
936 
937  default: /* get the tuple from the relation being
938  * scanned */
939  slot = econtext->ecxt_scantuple;
940  break;
941  }
942 
943  /* Apply the junkfilter if any */
944  if (wrvstate->wrv_junkFilter != NULL)
945  slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
946 
947  /*
948  * Copy the slot tuple and make sure any toasted fields get detoasted.
949  */
951 
952  /*
953  * Label the datum with the composite type info we identified before.
954  */
955  HeapTupleHeaderSetTypeId(dtuple, wrvstate->wrv_tupdesc->tdtypeid);
956  HeapTupleHeaderSetTypMod(dtuple, wrvstate->wrv_tupdesc->tdtypmod);
957 
958  return PointerGetDatum(dtuple);
959 }
Oid tdtypeid
Definition: tupdesc.h:77
#define HeapTupleHeaderSetTypeId(tup, typeid)
Definition: htup_details.h:450
ExprState xprstate
Definition: execnodes.h:620
#define PointerGetDatum(X)
Definition: postgres.h:564
Definition: primnodes.h:141
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:254
int32 tdtypmod
Definition: tupdesc.h:78
Expr * expr
Definition: execnodes.h:597
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:129
Index varno
Definition: primnodes.h:144
TupleTableSlot * ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
Definition: execJunk.c:262
#define HeapTupleHeaderSetTypMod(tup, typmod)
Definition: htup_details.h:460
#define INNER_VAR
Definition: primnodes.h:131
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:130
#define NULL
Definition: c.h:226
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
JunkFilter * wrv_junkFilter
Definition: execnodes.h:623
Datum ExecFetchSlotTupleDatum(TupleTableSlot *slot)
Definition: execTuples.c:698
#define OUTER_VAR
Definition: primnodes.h:132
TupleDesc wrv_tupdesc
Definition: execnodes.h:622
static Datum ExecEvalWholeRowSlow ( WholeRowVarExprState wrvstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 969 of file execQual.c.

References Assert, tupleDesc::attrs, DatumGetHeapTupleHeader, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_scantuple, ereport, errcode(), errdetail(), errmsg(), ERROR, ExecFetchSlotTuple(), ExecFetchSlotTupleDatum(), ExecFilterJunk(), ExprState::expr, heap_attisnull(), HeapTupleHeaderSetTypeId, HeapTupleHeaderSetTypMod, i, INNER_VAR, NULL, OUTER_VAR, PointerGetDatum, RECORDOID, tupleDesc::tdtypeid, tupleDesc::tdtypmod, Var::varno, Var::vartype, WholeRowVarExprState::wrv_junkFilter, WholeRowVarExprState::wrv_tupdesc, and WholeRowVarExprState::xprstate.

Referenced by ExecEvalWholeRowVar().

971 {
972  Var *variable = (Var *) wrvstate->xprstate.expr;
973  TupleTableSlot *slot;
974  HeapTuple tuple;
976  TupleDesc var_tupdesc;
977  HeapTupleHeader dtuple;
978  int i;
979 
980  *isNull = false;
981 
982  /* Get the input slot we want */
983  switch (variable->varno)
984  {
985  case INNER_VAR: /* get the tuple from the inner node */
986  slot = econtext->ecxt_innertuple;
987  break;
988 
989  case OUTER_VAR: /* get the tuple from the outer node */
990  slot = econtext->ecxt_outertuple;
991  break;
992 
993  /* INDEX_VAR is handled by default case */
994 
995  default: /* get the tuple from the relation being
996  * scanned */
997  slot = econtext->ecxt_scantuple;
998  break;
999  }
1000 
1001  /* Apply the junkfilter if any */
1002  if (wrvstate->wrv_junkFilter != NULL)
1003  slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
1004 
1005  tuple = ExecFetchSlotTuple(slot);
1006  tupleDesc = slot->tts_tupleDescriptor;
1007 
1008  /* wrv_tupdesc is a good enough representation of the Var's rowtype */
1009  Assert(variable->vartype != RECORDOID);
1010  var_tupdesc = wrvstate->wrv_tupdesc;
1011 
1012  /* Check to see if any dropped attributes are non-null */
1013  for (i = 0; i < var_tupdesc->natts; i++)
1014  {
1015  Form_pg_attribute vattr = var_tupdesc->attrs[i];
1016  Form_pg_attribute sattr = tupleDesc->attrs[i];
1017 
1018  if (!vattr->attisdropped)
1019  continue; /* already checked non-dropped cols */
1020  if (heap_attisnull(tuple, i + 1))
1021  continue; /* null is always okay */
1022  if (vattr->attlen != sattr->attlen ||
1023  vattr->attalign != sattr->attalign)
1024  ereport(ERROR,
1025  (errcode(ERRCODE_DATATYPE_MISMATCH),
1026  errmsg("table row type and query-specified row type do not match"),
1027  errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
1028  i + 1)));
1029  }
1030 
1031  /*
1032  * Copy the slot tuple and make sure any toasted fields get detoasted.
1033  */
1035 
1036  /*
1037  * Label the datum with the composite type info we identified before.
1038  */
1039  HeapTupleHeaderSetTypeId(dtuple, wrvstate->wrv_tupdesc->tdtypeid);
1040  HeapTupleHeaderSetTypMod(dtuple, wrvstate->wrv_tupdesc->tdtypmod);
1041 
1042  return PointerGetDatum(dtuple);
1043 }
Oid tdtypeid
Definition: tupdesc.h:77
#define HeapTupleHeaderSetTypeId(tup, typeid)
Definition: htup_details.h:450
ExprState xprstate
Definition: execnodes.h:620
#define PointerGetDatum(X)
Definition: postgres.h:564
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int errcode(int sqlerrcode)
Definition: elog.c:575
Definition: primnodes.h:141
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:254
int32 tdtypmod
Definition: tupdesc.h:78
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:597
Oid vartype
Definition: primnodes.h:148
bool heap_attisnull(HeapTuple tup, int attnum)
Definition: heaptuple.c:297
int errdetail(const char *fmt,...)
Definition: elog.c:873
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:129
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
#define RECORDOID
Definition: pg_type.h:668
#define ereport(elevel, rest)
Definition: elog.h:122
Index varno
Definition: primnodes.h:144
TupleTableSlot * ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
Definition: execJunk.c:262
#define HeapTupleHeaderSetTypMod(tup, typmod)
Definition: htup_details.h:460
#define INNER_VAR
Definition: primnodes.h:131
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:130
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
HeapTuple ExecFetchSlotTuple(TupleTableSlot *slot)
Definition: execTuples.c:618
JunkFilter * wrv_junkFilter
Definition: execnodes.h:623
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
Datum ExecFetchSlotTupleDatum(TupleTableSlot *slot)
Definition: execTuples.c:698
#define OUTER_VAR
Definition: primnodes.h:132
TupleDesc wrv_tupdesc
Definition: execnodes.h:622
static Datum ExecEvalWholeRowVar ( WholeRowVarExprState wrvstate,
ExprContext econtext,
bool isNull 
)
static

Definition at line 691 of file execQual.c.

References Assert, tupleDesc::attrs, 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, ExprState::evalfunc, ExecEvalWholeRowFast(), ExecEvalWholeRowSlow(), ExecFilterJunk(), ExecGetResultType(), ExecInitExtraTupleSlot(), ExecInitJunkFilter(), ExecTypeSetColNames(), ExprState::expr, format_type_be(), i, INNER_VAR, InvalidAttrNumber, lfirst, list_length(), lookup_rowtype_tupdesc(), MemoryContextSwitchTo(), tupleDesc::natts, nodeTag, NULL, OUTER_VAR, WholeRowVarExprState::parent, PlanState::plan, RECORDOID, ReleaseTupleDesc, TargetEntry::resjunk, rt_fetch, PlanState::state, T_CteScanState, T_SubqueryScanState, Plan::targetlist, Var::varattno, Var::varno, Var::vartype, WholeRowVarExprState::wrv_junkFilter, WholeRowVarExprState::wrv_tupdesc, and WholeRowVarExprState::xprstate.

Referenced by ExecInitExpr().

693 {
694  Var *variable = (Var *) wrvstate->xprstate.expr;
695  TupleTableSlot *slot;
696  TupleDesc output_tupdesc;
697  MemoryContext oldcontext;
698  bool needslow = false;
699 
700  /* This was checked by ExecInitExpr */
701  Assert(variable->varattno == InvalidAttrNumber);
702 
703  /* Get the input slot we want */
704  switch (variable->varno)
705  {
706  case INNER_VAR: /* get the tuple from the inner node */
707  slot = econtext->ecxt_innertuple;
708  break;
709 
710  case OUTER_VAR: /* get the tuple from the outer node */
711  slot = econtext->ecxt_outertuple;
712  break;
713 
714  /* INDEX_VAR is handled by default case */
715 
716  default: /* get the tuple from the relation being
717  * scanned */
718  slot = econtext->ecxt_scantuple;
719  break;
720  }
721 
722  /*
723  * If the input tuple came from a subquery, it might contain "resjunk"
724  * columns (such as GROUP BY or ORDER BY columns), which we don't want to
725  * keep in the whole-row result. We can get rid of such columns by
726  * passing the tuple through a JunkFilter --- but to make one, we have to
727  * lay our hands on the subquery's targetlist. Fortunately, there are not
728  * very many cases where this can happen, and we can identify all of them
729  * by examining our parent PlanState. We assume this is not an issue in
730  * standalone expressions that don't have parent plans. (Whole-row Vars
731  * can occur in such expressions, but they will always be referencing
732  * table rows.)
733  */
734  if (wrvstate->parent)
735  {
736  PlanState *subplan = NULL;
737 
738  switch (nodeTag(wrvstate->parent))
739  {
740  case T_SubqueryScanState:
741  subplan = ((SubqueryScanState *) wrvstate->parent)->subplan;
742  break;
743  case T_CteScanState:
744  subplan = ((CteScanState *) wrvstate->parent)->cteplanstate;
745  break;
746  default:
747  break;
748  }
749 
750  if (subplan)
751  {
752  bool junk_filter_needed = false;
753  ListCell *tlist;
754 
755  /* Detect whether subplan tlist actually has any junk columns */
756  foreach(tlist, subplan->plan->targetlist)
757  {
758  TargetEntry *tle = (TargetEntry *) lfirst(tlist);
759 
760  if (tle->resjunk)
761  {
762  junk_filter_needed = true;
763  break;
764  }
765  }
766 
767  /* If so, build the junkfilter in the query memory context */
768  if (junk_filter_needed)
769  {
770  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
771  wrvstate->wrv_junkFilter =
773  ExecGetResultType(subplan)->tdhasoid,
774  ExecInitExtraTupleSlot(wrvstate->parent->state));
775  MemoryContextSwitchTo(oldcontext);
776  }
777  }
778  }
779 
780  /* Apply the junkfilter if any */
781  if (wrvstate->wrv_junkFilter != NULL)
782  slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
783 
784  /*
785  * If the Var identifies a named composite type, we must check that the
786  * actual tuple type is compatible with it.
787  */
788  if (variable->vartype != RECORDOID)
789  {
790  TupleDesc var_tupdesc;
791  TupleDesc slot_tupdesc;
792  int i;
793 
794  /*
795  * We really only care about numbers of attributes and data types.
796  * Also, we can ignore type mismatch on columns that are dropped in
797  * the destination type, so long as (1) the physical storage matches
798  * or (2) the actual column value is NULL. Case (1) is helpful in
799  * some cases involving out-of-date cached plans, while case (2) is
800  * expected behavior in situations such as an INSERT into a table with
801  * dropped columns (the planner typically generates an INT4 NULL
802  * regardless of the dropped column type). If we find a dropped
803  * column and cannot verify that case (1) holds, we have to use
804  * ExecEvalWholeRowSlow to check (2) for each row.
805  */
806  var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
807 
808  slot_tupdesc = slot->tts_tupleDescriptor;
809 
810  if (var_tupdesc->natts != slot_tupdesc->natts)
811  ereport(ERROR,
812  (errcode(ERRCODE_DATATYPE_MISMATCH),
813  errmsg("table row type and query-specified row type do not match"),
814  errdetail_plural("Table row contains %d attribute, but query expects %d.",
815  "Table row contains %d attributes, but query expects %d.",
816  slot_tupdesc->natts,
817  slot_tupdesc->natts,
818  var_tupdesc->natts)));
819 
820  for (i = 0; i < var_tupdesc->natts; i++)
821  {
822  Form_pg_attribute vattr = var_tupdesc->attrs[i];
823  Form_pg_attribute sattr = slot_tupdesc->attrs[i];
824 
825  if (vattr->atttypid == sattr->atttypid)
826  continue; /* no worries */
827  if (!vattr->attisdropped)
828  ereport(ERROR,
829  (errcode(ERRCODE_DATATYPE_MISMATCH),
830  errmsg("table row type and query-specified row type do not match"),
831  errdetail("Table has type %s at ordinal position %d, but query expects %s.",
832  format_type_be(sattr->atttypid),
833  i + 1,
834  format_type_be(vattr->atttypid))));
835 
836  if (vattr->attlen != sattr->attlen ||
837  vattr->attalign != sattr->attalign)
838  needslow = true; /* need runtime check for null */
839  }
840 
841  /*
842  * Use the variable's declared rowtype as the descriptor for the
843  * output values, modulo possibly assigning new column names below. In
844  * particular, we *must* absorb any attisdropped markings.
845  */
846  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
847  output_tupdesc = CreateTupleDescCopy(var_tupdesc);
848  MemoryContextSwitchTo(oldcontext);
849 
850  ReleaseTupleDesc(var_tupdesc);
851  }
852  else
853  {
854  /*
855  * In the RECORD case, we use the input slot's rowtype as the
856  * descriptor for the output values, modulo possibly assigning new
857  * column names below.
858  */
859  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
860  output_tupdesc = CreateTupleDescCopy(slot->tts_tupleDescriptor);
861  MemoryContextSwitchTo(oldcontext);
862  }
863 
864  /*
865  * Construct a tuple descriptor for the composite values we'll produce,
866  * and make sure its record type is "blessed". The main reason to do this
867  * is to be sure that operations such as row_to_json() will see the
868  * desired column names when they look up the descriptor from the type
869  * information embedded in the composite values.
870  *
871  * We already got the correct physical datatype info above, but now we
872  * should try to find the source RTE and adopt its column aliases, in case
873  * they are different from the original rowtype's names. For example, in
874  * "SELECT foo(t) FROM tab t(x,y)", the first two columns in the composite
875  * output should be named "x" and "y" regardless of tab's column names.
876  *
877  * If we can't locate the RTE, assume the column names we've got are OK.
878  * (As of this writing, the only cases where we can't locate the RTE are
879  * in execution of trigger WHEN clauses, and then the Var will have the
880  * trigger's relation's rowtype, so its names are fine.) Also, if the
881  * creator of the RTE didn't bother to fill in an eref field, assume our
882  * column names are OK. (This happens in COPY, and perhaps other places.)
883  */
884  if (econtext->ecxt_estate &&
885  variable->varno <= list_length(econtext->ecxt_estate->es_range_table))
886  {
887  RangeTblEntry *rte = rt_fetch(variable->varno,
888  econtext->ecxt_estate->es_range_table);
889 
890  if (rte->eref)
891  ExecTypeSetColNames(output_tupdesc, rte->eref->colnames);
892  }
893 
894  /* Bless the tupdesc if needed, and save it in the execution state */
895  wrvstate->wrv_tupdesc = BlessTupleDesc(output_tupdesc);
896 
897  /* Skip all the above on future executions of node */
898  if (needslow)
900  else
902 
903  /* Fetch the value */
904  return (*wrvstate->xprstate.evalfunc) ((ExprState *) wrvstate, econtext,
905  isNull);
906 }
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:141
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate)
Definition: execTuples.c:852
static Datum ExecEvalWholeRowSlow(WholeRowVarExprState *wrvstate, ExprContext *econtext, bool *isNull)
Definition: execQual.c:969
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1245
ExprState xprstate
Definition: execnodes.h:620
List * colnames
Definition: primnodes.h:42
Form_pg_attribute * attrs
Definition: tupdesc.h:74
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:575
struct PlanState * parent
Definition: execnodes.h:621
AttrNumber varattno
Definition: primnodes.h:146
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
EState * state
Definition: execnodes.h:1048
List * es_range_table
Definition: execnodes.h:372
Definition: primnodes.h:141
int natts
Definition: tupdesc.h:73
Datum(* ExprStateEvalFunc)(ExprState *expression, ExprContext *econtext, bool *isNull)
Definition: execnodes.h:590
bool resjunk
Definition: primnodes.h:1337
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:597
Oid vartype
Definition: primnodes.h:148
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1031
ExprStateEvalFunc evalfunc
Definition: execnodes.h:598
JunkFilter * ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot)
Definition: execJunk.c:61
int errdetail(const char *fmt,...)
Definition: elog.c:873
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:129
struct EState * ecxt_estate
Definition: execnodes.h:156
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
#define RECORDOID
Definition: pg_type.h:668
#define ereport(elevel, rest)
Definition: elog.h:122
#define rt_fetch(rangetable_index, rangetable)
Definition: parsetree.h:31
Index varno
Definition: primnodes.h:144
TupleTableSlot * ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
Definition: execJunk.c:262
Plan * plan
Definition: execnodes.h:1046
#define INNER_VAR
Definition: primnodes.h:131
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:130
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
#define lfirst(lc)
Definition: pg_list.h:106
static int list_length(const List *l)
Definition: pg_list.h:89
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:965
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:458
#define InvalidAttrNumber
Definition: attnum.h:23
#define nodeTag(nodeptr)
Definition: nodes.h:513
List * targetlist
Definition: plannodes.h:129
JunkFilter * wrv_junkFilter
Definition: execnodes.h:623
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
Alias * eref
Definition: parsenodes.h:961
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:107
static Datum ExecEvalWholeRowFast(WholeRowVarExprState *wrvstate, ExprContext *econtext, bool *isNull)
Definition: execQual.c:915
#define OUTER_VAR
Definition: primnodes.h:132
void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList)
Definition: execTuples.c:986
TupleDesc wrv_tupdesc
Definition: execnodes.h:622
static Datum ExecEvalWindowFunc ( WindowFuncExprState wfunc,
ExprContext econtext,
bool isNull 
)
static

Definition at line 538 of file execQual.c.

References ExprContext::ecxt_aggnulls, ExprContext::ecxt_aggvalues, elog, ERROR, NULL, and WindowFuncExprState::wfuncno.

Referenced by ExecInitExpr().

540 {
541  if (econtext->ecxt_aggvalues == NULL) /* safety check */
542  elog(ERROR, "no window functions in this expression context");
543 
544  *isNull = econtext->ecxt_aggnulls[wfunc->wfuncno];
545  return econtext->ecxt_aggvalues[wfunc->wfuncno];
546 }
Datum * ecxt_aggvalues
Definition: execnodes.h:144
#define ERROR
Definition: elog.h:43
bool * ecxt_aggnulls
Definition: execnodes.h:145
#define NULL
Definition: c.h:226
#define elog
Definition: elog.h:219
static Datum ExecEvalXml ( XmlExprState xmlExpr,
ExprContext econtext,
bool isNull 
)
static

Definition at line 3350 of file execQual.c.

References appendStringInfo(), arg, XmlExpr::arg_names, XmlExprState::args, Assert, BoolGetDatum, buf, cstring_to_text_with_len(), StringInfoData::data, DatumGetBool, DatumGetInt32, DatumGetPointer, DatumGetTextP, DatumGetXmlP, elog, ERROR, ExecEvalExpr, ExprState::expr, exprType(), forboth, initStringInfo(), IS_DOCUMENT, IS_XMLCONCAT, IS_XMLELEMENT, IS_XMLFOREST, IS_XMLPARSE, IS_XMLPI, IS_XMLROOT, IS_XMLSERIALIZE, lappend(), StringInfoData::len, lfirst, linitial, list_length(), lsecond, lthird, map_sql_value_to_xml_value(), XmlExpr::name, XmlExprState::named_args, NIL, NULL, XmlExpr::op, pfree(), PointerGetDatum, strVal, value, values, xml_is_document(), xmlconcat(), xmlelement(), XmlExpr::xmloption, xmlparse(), xmlpi(), xmlroot(), xmltotext_with_xmloption(), and XmlExprState::xprstate.

Referenced by ExecInitExpr().

3352 {
3353  XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
3354  Datum value;
3355  bool isnull;
3356  ListCell *arg;
3357  ListCell *narg;
3358 
3359  *isNull = true; /* until we get a result */
3360 
3361  switch (xexpr->op)
3362  {
3363  case IS_XMLCONCAT:
3364  {
3365  List *values = NIL;
3366 
3367  foreach(arg, xmlExpr->args)
3368  {
3369  ExprState *e = (ExprState *) lfirst(arg);
3370 
3371  value = ExecEvalExpr(e, econtext, &isnull);
3372  if (!isnull)
3373  values = lappend(values, DatumGetPointer(value));
3374  }
3375 
3376  if (list_length(values) > 0)
3377  {
3378  *isNull = false;
3379  return PointerGetDatum(xmlconcat(values));
3380  }
3381  else
3382  return (Datum) 0;
3383  }
3384  break;
3385 
3386  case IS_XMLFOREST:
3387  {
3389 
3390  initStringInfo(&buf);
3391  forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
3392  {
3393  ExprState *e = (ExprState *) lfirst(arg);
3394  char *argname = strVal(lfirst(narg));
3395 
3396  value = ExecEvalExpr(e, econtext, &isnull);
3397  if (!isnull)
3398  {
3399  appendStringInfo(&buf, "<%s>%s</%s>",
3400  argname,
3402  argname);
3403  *isNull = false;
3404  }
3405  }
3406 
3407  if (*isNull)
3408  {
3409  pfree(buf.data);
3410  return (Datum) 0;
3411  }
3412  else
3413  {
3414  text *result;
3415 
3416  result = cstring_to_text_with_len(buf.data, buf.len);
3417  pfree(buf.data);
3418 
3419  return PointerGetDatum(result);
3420  }
3421  }
3422  break;
3423 
3424  case IS_XMLELEMENT:
3425  *isNull = false;
3426  return PointerGetDatum(xmlelement(xmlExpr, econtext));
3427  break;
3428 
3429  case IS_XMLPARSE:
3430  {
3431  ExprState *e;
3432  text *data;
3433  bool preserve_whitespace;
3434 
3435  /* arguments are known to be text, bool */
3436  Assert(list_length(xmlExpr->args) == 2);
3437 
3438  e = (ExprState *) linitial(xmlExpr->args);
3439  value = ExecEvalExpr(e, econtext, &isnull);
3440  if (isnull)
3441  return (Datum) 0;
3442  data = DatumGetTextP(value);
3443 
3444  e = (ExprState *) lsecond(xmlExpr->args);
3445  value = ExecEvalExpr(e, econtext, &isnull);
3446  if (isnull) /* probably can't happen */
3447  return (Datum) 0;
3448  preserve_whitespace = DatumGetBool(value);
3449 
3450  *isNull = false;
3451 
3452  return PointerGetDatum(xmlparse(data,
3453  xexpr->xmloption,
3454  preserve_whitespace));
3455  }
3456  break;
3457 
3458  case IS_XMLPI:
3459  {
3460  ExprState *e;
3461  text *arg;
3462 
3463  /* optional argument is known to be text */
3464  Assert(list_length(xmlExpr->args) <= 1);
3465 
3466  if (xmlExpr->args)
3467  {
3468  e = (ExprState *) linitial(xmlExpr->args);
3469  value = ExecEvalExpr(e, econtext, &isnull);
3470  if (isnull)
3471  arg = NULL;
3472  else
3473  arg = DatumGetTextP(value);
3474  }
3475  else
3476  {
3477  arg = NULL;
3478  isnull = false;
3479  }
3480 
3481  return PointerGetDatum(xmlpi(xexpr->name, arg, isnull, isNull));
3482  }
3483  break;
3484 
3485  case IS_XMLROOT:
3486  {
3487  ExprState *e;
3488  xmltype *data;
3489  text *version;
3490  int standalone;
3491 
3492  /* arguments are known to be xml, text, int */
3493  Assert(list_length(xmlExpr->args) == 3);
3494 
3495  e = (ExprState *) linitial(xmlExpr->args);
3496  value = ExecEvalExpr(e, econtext, &isnull);
3497  if (isnull)
3498  return (Datum) 0;
3499  data = DatumGetXmlP(value);
3500 
3501  e = (ExprState *) lsecond(xmlExpr->args);
3502  value = ExecEvalExpr(e, econtext, &isnull);
3503  if (isnull)
3504  version = NULL;
3505  else
3506  version = DatumGetTextP(value);
3507 
3508  e = (ExprState *) lthird(xmlExpr->args);
3509  value = ExecEvalExpr(e, econtext, &isnull);
3510  standalone = DatumGetInt32(value);
3511 
3512  *isNull = false;
3513 
3514  return PointerGetDatum(xmlroot(data,
3515  version,
3516  standalone));
3517  }
3518  break;
3519 
3520  case IS_XMLSERIALIZE:
3521  {
3522  ExprState *e;
3523 
3524  /* argument type is known to be xml */
3525  Assert(list_length(xmlExpr->args) == 1);
3526 
3527  e = (ExprState *) linitial(xmlExpr->args);
3528  value = ExecEvalExpr(e, econtext, &isnull);
3529  if (isnull)
3530  return (Datum) 0;
3531 
3532  *isNull = false;
3533 
3535  }
3536  break;
3537 
3538  case IS_DOCUMENT:
3539  {
3540  ExprState *e;
3541 
3542  /* optional argument is known to be xml */
3543  Assert(list_length(xmlExpr->args) == 1);
3544 
3545  e = (ExprState *) linitial(xmlExpr->args);
3546  value = ExecEvalExpr(e, econtext, &isnull);
3547  if (isnull)
3548  return (Datum) 0;
3549  else
3550  {
3551  *isNull = false;
3553  }
3554  }
3555  break;
3556  }
3557 
3558  elog(ERROR, "unrecognized XML operation");
3559  return (Datum) 0;
3560 }
ExprState xprstate
Definition: execnodes.h:975
#define NIL
Definition: pg_list.h:69
static struct @76 value
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:174
char * name
Definition: primnodes.h:1119
List * args
Definition: execnodes.h:977
#define DatumGetInt32(X)
Definition: postgres.h:480
#define PointerGetDatum(X)
Definition: postgres.h:564
xmltype * xmlconcat(List *args)
Definition: xml.c:461
Definition: nodes.h:508
#define strVal(v)
Definition: value.h:54
List * arg_names
Definition: primnodes.h:1121
#define DatumGetXmlP(X)
Definition: xml.h:49
#define lsecond(l)
Definition: pg_list.h:114
void pfree(void *pointer)
Definition: mcxt.c:992
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define linitial(l)
Definition: pg_list.h:110
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
#define ERROR
Definition: elog.h:43
Expr * expr
Definition: execnodes.h:597
text * xmltotext_with_xmloption(xmltype *data, XmlOptionType xmloption_arg)
Definition: xml.c:564
static char * buf
Definition: pg_test_fsync.c:65
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:163
xmltype * xmlroot(xmltype *data, text *version, int standalone)
Definition: xml.c:771
#define DatumGetBool(X)
Definition: postgres.h:401
List * lappend(List *list, void *datum)
Definition: list.c:128
bool xml_is_document(xmltype *arg)
Definition: xml.c:837
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
XmlExprOp op
Definition: primnodes.h:1118
uintptr_t Datum
Definition: postgres.h:374
#define BoolGetDatum(X)
Definition: postgres.h:410
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
#define lfirst(lc)
Definition: pg_list.h:106
XmlOptionType xmloption
Definition: primnodes.h:1123
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
List * named_args
Definition: execnodes.h:976
static int list_length(const List *l)
Definition: pg_list.h:89
#define DatumGetTextP(X)
Definition: fmgr.h:248
#define DatumGetPointer(X)
Definition: postgres.h:557
static Datum values[MAXATTR]
Definition: bootstrap.c:162
e
Definition: preproc-init.c:82
xmltype * xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
Definition: xml.c:577
xmltype * xmlpi(char *target, text *arg, bool arg_is_null, bool *result_is_null)
Definition: xml.c:719
void * arg
#define lthird(l)
Definition: pg_list.h:118
Definition: c.h:434
#define elog
Definition: elog.h:219
char * map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
Definition: xml.c:1951
Definition: pg_list.h:45
xmltype * xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
Definition: xml.c:701
ExprState* ExecInitExpr ( Expr node,
PlanState parent 
)

Definition at line 4266 of file execQual.c.

References WindowFunc::aggfilter, WindowFuncExprState::aggfilter, AggState::aggs, GroupingFuncExprState::aggstate, ArrayCoerceExprState::amstate, AND_EXPR, arg, GenericExprState::arg, FieldSelect::arg, FieldStore::arg, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, FieldSelectState::arg, ConvertRowtypeExpr::arg, FieldStoreState::arg, CoerceViaIOState::arg, ArrayCoerceExprState::arg, ConvertRowtypeExprState::arg, CaseExpr::arg, CaseExprState::arg, NullTestState::arg, CoerceToDomainState::arg, NullTest::arg, BooleanTest::arg, CoerceToDomain::arg, FieldSelectState::argdesc, FieldStoreState::argdesc, NullTestState::argdesc, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, WindowFuncExprState::args, FuncExprState::args, BoolExprState::args, CaseExpr::args, CaseExprState::args, RowExprState::args, CoalesceExprState::args, RowExpr::args, MinMaxExprState::args, XmlExprState::args, CoalesceExpr::args, MinMaxExpr::args, XmlExpr::args, CaseExprState::argtyplen, Assert, tupleDesc::attrs, BlessTupleDesc(), BoolExpr::boolop, BTORDER_PROC, castNode, MinMaxExprState::cfunc, check_stack_depth(), GroupingFuncExprState::clauses, TypeCacheEntry::cmp_proc, RowCompareExprState::collations, RowExpr::colnames, GroupingFunc::cols, CoerceToDomainState::constraint_ref, convert(), CurrentMemoryContext, CaseExpr::defresult, CaseExprState::defresult, ArrayExprState::elemalign, ArrayExprState::elembyval, ScalarArrayOpExprState::element_type, ArrayExpr::element_typeid, ArrayExprState::elements, ArrayExpr::elements, ArrayCoerceExprState::elemfunc, ArrayExprState::elemlength, elog, ereport, errcode(), errmsg(), ERROR, ExprState::evalfunc, ExecEvalAggref(), ExecEvalAnd(), ExecEvalArray(), ExecEvalArrayCoerceExpr(), ExecEvalArrayRef(), ExecEvalBooleanTest(), ExecEvalCase(), ExecEvalCaseTestExpr(), ExecEvalCoalesce(), ExecEvalCoerceToDomain(), ExecEvalCoerceToDomainValue(), ExecEvalCoerceViaIO(), ExecEvalConst(), ExecEvalConvertRowtype(), ExecEvalCurrentOfExpr(), ExecEvalDistinct(), ExecEvalFieldSelect(), ExecEvalFieldStore(), ExecEvalFunc(), ExecEvalGroupingFuncExpr(), ExecEvalMinMax(), ExecEvalNot(), ExecEvalNullIf(), ExecEvalNullTest(), ExecEvalOper(), ExecEvalOr(), ExecEvalParamExec(), ExecEvalParamExtern(), ExecEvalRelabelType(), ExecEvalRow(), ExecEvalRowCompare(), ExecEvalScalarArrayOp(), ExecEvalScalarVar(), ExecEvalSQLValueFunction(), ExecEvalWholeRowVar(), ExecEvalWindowFunc(), ExecEvalXml(), ExecInitAlternativeSubPlan(), ExecInitExpr(), ExecInitSubPlan(), ExecTypeFromExprList(), ExecTypeSetColNames(), ExprState::expr, CaseWhen::expr, CaseWhenState::expr, TargetEntry::expr, exprType(), fmgr_info(), FmgrInfo::fn_oid, format_type_be(), forthree, FuncExprState::func, FuncExpr::funcretset, FuncExprState::funcReturnsSet, RowCompareExprState::funcs, WindowAggState::funcs, ScalarArrayOpExprState::fxprstate, get_element_type(), get_op_opfamily_properties(), get_opfamily_proc(), get_typlen(), get_typlenbyvalalign(), getBaseType(), getTypeInputInfo(), getTypeOutputInfo(), Agg::groupingSets, i, CoerceViaIOState::infunc, InitDomainConstraintRef(), RowCompareExpr::inputcollids, INT4OID, CoerceViaIOState::intypioparam, InvalidAttrNumber, InvalidOid, IsA, lappend(), RowCompareExprState::largs, RowCompareExpr::largs, lcons(), lfirst, lfirst_oid, list_length(), lookup_rowtype_tupdesc_copy(), lookup_type_cache(), makeNode, makeNullConst(), MinMaxExpr::minmaxtype, XmlExprState::named_args, XmlExpr::named_args, tupleDesc::natts, FieldStore::newvals, FieldStoreState::newvals, NIL, nodeTag, NOT_EXPR, NULL, AggState::numaggs, WindowAggState::numaggs, WindowAggState::numfuncs, OidIsValid, RowCompareExpr::opfamilies, RowCompareExpr::opnos, OpExpr::opretset, OR_EXPR, CoerceViaIOState::outfunc, palloc(), palloc0(), PARAM_EXEC, PARAM_EXTERN, WholeRowVarExprState::parent, PlanState::plan, RowCompareExprState::rargs, RowCompareExpr::rargs, RECORDOID, ArrayRef::refarraytype, ArrayRef::refassgnexpr, ArrayRefExprState::refassgnexpr, ArrayRefExprState::refattrlength, ArrayRefExprState::refelemalign, ArrayRefExprState::refelembyval, ArrayRefExprState::refelemlength, ArrayRef::refelemtype, ArrayRef::refexpr, ArrayRefExprState::refexpr, ArrayRef::reflowerindexpr, ArrayRefExprState::reflowerindexpr, ArrayRef::refupperindexpr, ArrayRefExprState::refupperindexpr, CaseWhen::result, CaseWhenState::result, ArrayCoerceExprState::resultelemtype, CoerceViaIO::resulttype, ArrayCoerceExpr::resulttype, CoerceToDomain::resulttype, RowExpr::row_typeid, PlanState::subPlan, T_Aggref, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncExpr, T_GroupingFunc, T_List, T_MinMaxExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SQLValueFunction, T_SubPlan, T_TargetEntry, T_Var, T_WindowFunc, T_XmlExpr, RowExprState::tupdesc, TYPECACHE_CMP_PROC, WindowFunc::winagg, WholeRowVarExprState::wrv_junkFilter, WholeRowVarExprState::wrv_tupdesc, GenericExprState::xprstate, AggrefExprState::xprstate, WindowFuncExprState::xprstate, ArrayRefExprState::xprstate, FuncExprState::xprstate, BoolExprState::xprstate, FieldSelectState::xprstate, FieldStoreState::xprstate, CoerceViaIOState::xprstate, ArrayCoerceExprState::xprstate, ConvertRowtypeExprState::xprstate, CaseExprState::xprstate, CaseWhenState::xprstate, ArrayExprState::xprstate, RowExprState::xprstate, RowCompareExprState::xprstate, CoalesceExprState::xprstate, MinMaxExprState::xprstate, XmlExprState::xprstate, NullTestState::xprstate, and CoerceToDomainState::xprstate.

Referenced by ATRewriteTable(), BeginCopyFrom(), build_pertrans_for_aggref(), evaluate_expr(), exec_eval_simple_expr(), ExecIndexBuildScanKeys(), ExecInitAgg(), ExecInitAlternativeSubPlan(), ExecInitBitmapHeapScan(), ExecInitCteScan(), ExecInitCustomScan(), ExecInitExpr(), ExecInitForeignScan(), ExecInitFunctionScan(), ExecInitGather(), ExecInitGroup(), ExecInitHash(), ExecInitHashJoin(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecInitLimit(), ExecInitMergeJoin(), ExecInitModifyTable(), ExecInitNestLoop(), ExecInitProjectSet(), ExecInitResult(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitSubPlan(), ExecInitSubqueryScan(), ExecInitTidScan(), ExecInitValuesScan(), ExecInitWindowAgg(), ExecInitWorkTableScan(), ExecPrepareExpr(), get_cast_hashentry(), get_qual_for_range(), MJExamineQuals(), operator_predicate_proof(), prep_domain_constraints(), prepare_query_params(), slot_fill_defaults(), and ValuesNext().

4267 {
4268  ExprState *state;
4269 
4270  if (node == NULL)
4271  return NULL;
4272 
4273  /* Guard against stack overflow due to overly complex expressions */
4275 
4276  switch (nodeTag(node))
4277  {
4278  case T_Var:
4279  /* varattno == InvalidAttrNumber means it's a whole-row Var */
4280  if (((Var *) node)->varattno == InvalidAttrNumber)
4281  {
4283 
4284  wstate->parent = parent;
4285  wstate->wrv_tupdesc = NULL;
4286  wstate->wrv_junkFilter = NULL;
4287  state = (ExprState *) wstate;
4289  }
4290  else
4291  {
4292  state = makeNode(ExprState);
4293  state->evalfunc = ExecEvalScalarVar;
4294  }
4295  break;
4296  case T_Const:
4297  state = makeNode(ExprState);
4298  state->evalfunc = ExecEvalConst;
4299  break;
4300  case T_Param:
4301  state = makeNode(ExprState);
4302  switch (((Param *) node)->paramkind)
4303  {
4304  case PARAM_EXEC:
4305  state->evalfunc = ExecEvalParamExec;
4306  break;
4307  case PARAM_EXTERN:
4308  state->evalfunc = ExecEvalParamExtern;
4309  break;
4310  default:
4311  elog(ERROR, "unrecognized paramkind: %d",
4312  (int) ((Param *) node)->paramkind);
4313  break;
4314  }
4315  break;
4316  case T_CoerceToDomainValue:
4317  state = makeNode(ExprState);
4319  break;
4320  case T_CaseTestExpr:
4321  state = makeNode(ExprState);
4322  state->evalfunc = ExecEvalCaseTestExpr;
4323  break;
4324  case T_Aggref:
4325  {
4327 
4329  if (parent && IsA(parent, AggState))
4330  {
4331  AggState *aggstate = (AggState *) parent;
4332 
4333  aggstate->aggs = lcons(astate, aggstate->aggs);
4334  aggstate->numaggs++;
4335  }
4336  else
4337  {
4338  /* planner messed up */
4339  elog(ERROR, "Aggref found in non-Agg plan node");
4340  }
4341  state = (ExprState *) astate;
4342  }
4343  break;
4344  case T_GroupingFunc:
4345  {
4346  GroupingFunc *grp_node = (GroupingFunc *) node;
4348  Agg *agg = NULL;
4349 
4350  if (!parent || !IsA(parent, AggState) ||!IsA(parent->plan, Agg))
4351  elog(ERROR, "parent of GROUPING is not Agg node");
4352 
4353  grp_state->aggstate = (AggState *) parent;
4354 
4355  agg = (Agg *) (parent->plan);
4356 
4357  if (agg->groupingSets)
4358  grp_state->clauses = grp_node->cols;
4359  else
4360  grp_state->clauses = NIL;
4361 
4362  state = (ExprState *) grp_state;
4364  }
4365  break;
4366  case T_WindowFunc:
4367  {
4368  WindowFunc *wfunc = (WindowFunc *) node;
4370 
4372  if (parent && IsA(parent, WindowAggState))
4373  {
4374  WindowAggState *winstate = (WindowAggState *) parent;
4375  int nfuncs;
4376 
4377  winstate->funcs = lcons(wfstate, winstate->funcs);
4378  nfuncs = ++winstate->numfuncs;
4379  if (wfunc->winagg)
4380  winstate->numaggs++;
4381 
4382  wfstate->args = (List *) ExecInitExpr((Expr *) wfunc->args,
4383  parent);
4384  wfstate->aggfilter = ExecInitExpr(wfunc->aggfilter,
4385  parent);
4386 
4387  /*
4388  * Complain if the windowfunc's arguments contain any
4389  * windowfuncs; nested window functions are semantically
4390  * nonsensical. (This should have been caught earlier,
4391  * but we defend against it here anyway.)
4392  */
4393  if (nfuncs != winstate->numfuncs)
4394  ereport(ERROR,
4395  (errcode(ERRCODE_WINDOWING_ERROR),
4396  errmsg("window function calls cannot be nested")));
4397  }
4398  else
4399  {
4400  /* planner messed up */
4401  elog(ERROR, "WindowFunc found in non-WindowAgg plan node");
4402  }
4403  state = (ExprState *) wfstate;
4404  }
4405  break;
4406  case T_ArrayRef:
4407  {
4408  ArrayRef *aref = (ArrayRef *) node;
4410 
4412  astate->refupperindexpr = (List *)
4413  ExecInitExpr((Expr *) aref->refupperindexpr, parent);
4414  astate->reflowerindexpr = (List *)
4415  ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
4416  astate->refexpr = ExecInitExpr(aref->refexpr, parent);
4417  astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
4418  parent);
4419  /* do one-time catalog lookups for type info */
4420  astate->refattrlength = get_typlen(aref->refarraytype);
4422  &astate->refelemlength,
4423  &astate->refelembyval,
4424  &astate->refelemalign);
4425  state = (ExprState *) astate;
4426  }
4427  break;
4428  case T_FuncExpr:
4429  {
4430  FuncExpr *funcexpr = (FuncExpr *) node;
4432 
4434  fstate->args = (List *)
4435  ExecInitExpr((Expr *) funcexpr->args, parent);
4436  fstate->func.fn_oid = InvalidOid; /* not initialized */
4437  fstate->funcReturnsSet = funcexpr->funcretset;
4438  state = (ExprState *) fstate;
4439  }
4440  break;
4441  case T_OpExpr:
4442  {
4443  OpExpr *opexpr = (OpExpr *) node;
4445 
4447  fstate->args = (List *)
4448  ExecInitExpr((Expr *) opexpr->args, parent);
4449  fstate->func.fn_oid = InvalidOid; /* not initialized */
4450  fstate->funcReturnsSet = opexpr->opretset;
4451  state = (ExprState *) fstate;
4452  }
4453  break;
4454  case T_DistinctExpr:
4455  {
4456  DistinctExpr *distinctexpr = (DistinctExpr *) node;
4458 
4460  fstate->args = (List *)
4461  ExecInitExpr((Expr *) distinctexpr->args, parent);
4462  fstate->func.fn_oid = InvalidOid; /* not initialized */
4463  fstate->funcReturnsSet = false; /* not supported */
4464  state = (ExprState *) fstate;
4465  }
4466  break;
4467  case T_NullIfExpr:
4468  {
4469  NullIfExpr *nullifexpr = (NullIfExpr *) node;
4471 
4473  fstate->args = (List *)
4474  ExecInitExpr((Expr *) nullifexpr->args, parent);
4475  fstate->func.fn_oid = InvalidOid; /* not initialized */
4476  fstate->funcReturnsSet = false; /* not supported */
4477  state = (ExprState *) fstate;
4478  }
4479  break;
4480  case T_ScalarArrayOpExpr:
4481  {
4482  ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
4484 
4486  sstate->fxprstate.args = (List *)
4487  ExecInitExpr((Expr *) opexpr->args, parent);
4488  sstate->fxprstate.func.fn_oid = InvalidOid; /* not initialized */
4489  sstate->fxprstate.funcReturnsSet = false; /* not supported */
4490  sstate->element_type = InvalidOid; /* ditto */
4491  state = (ExprState *) sstate;
4492  }
4493  break;
4494  case T_BoolExpr:
4495  {
4496  BoolExpr *boolexpr = (BoolExpr *) node;
4498 
4499  switch (boolexpr->boolop)
4500  {
4501  case AND_EXPR:
4503  break;
4504  case OR_EXPR:
4506  break;
4507  case NOT_EXPR:
4509  break;
4510  default:
4511  elog(ERROR, "unrecognized boolop: %d",
4512  (int) boolexpr->boolop);
4513  break;
4514  }
4515  bstate->args = (List *)
4516  ExecInitExpr((Expr *) boolexpr->args, parent);
4517  state = (ExprState *) bstate;
4518  }
4519  break;
4520  case T_SubPlan:
4521  {
4522  SubPlan *subplan = (SubPlan *) node;
4523  SubPlanState *sstate;
4524 
4525  if (!parent)
4526  elog(ERROR, "SubPlan found with no parent plan");
4527 
4528  sstate = ExecInitSubPlan(subplan, parent);
4529 
4530  /* Add SubPlanState nodes to parent->subPlan */
4531  parent->subPlan = lappend(parent->subPlan, sstate);
4532 
4533  state = (ExprState *) sstate;
4534  }
4535  break;
4536  case T_AlternativeSubPlan:
4537  {
4538  AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
4539  AlternativeSubPlanState *asstate;
4540 
4541  if (!parent)
4542  elog(ERROR, "AlternativeSubPlan found with no parent plan");
4543 
4544  asstate = ExecInitAlternativeSubPlan(asplan, parent);
4545 
4546  state = (ExprState *) asstate;
4547  }
4548  break;
4549  case T_FieldSelect:
4550  {
4551  FieldSelect *fselect = (FieldSelect *) node;
4553 
4555  fstate->arg = ExecInitExpr(fselect->arg, parent);
4556  fstate->argdesc = NULL;
4557  state = (ExprState *) fstate;
4558  }
4559  break;
4560  case T_FieldStore:
4561  {
4562  FieldStore *fstore = (FieldStore *) node;
4564 
4566  fstate->arg = ExecInitExpr(fstore->arg, parent);
4567  fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
4568  fstate->argdesc = NULL;
4569  state = (ExprState *) fstate;
4570  }
4571  break;
4572  case T_RelabelType:
4573  {
4574  RelabelType *relabel = (RelabelType *) node;
4576 
4578  gstate->arg = ExecInitExpr(relabel->arg, parent);
4579  state = (ExprState *) gstate;
4580  }
4581  break;
4582  case T_CoerceViaIO:
4583  {
4584  CoerceViaIO *iocoerce = (CoerceViaIO *) node;
4586  Oid iofunc;
4587  bool typisvarlena;
4588 
4590  iostate->arg = ExecInitExpr(iocoerce->arg, parent);
4591  /* lookup the result type's input function */
4592  getTypeInputInfo(iocoerce->resulttype, &iofunc,
4593  &iostate->intypioparam);
4594  fmgr_info(iofunc, &iostate->infunc);
4595  /* lookup the input type's output function */
4596  getTypeOutputInfo(exprType((Node *) iocoerce->arg),
4597  &iofunc, &typisvarlena);
4598  fmgr_info(iofunc, &iostate->outfunc);
4599  state = (ExprState *) iostate;
4600  }
4601  break;
4602  case T_ArrayCoerceExpr:
4603  {
4604  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
4606 
4608  astate->arg = ExecInitExpr(acoerce->arg, parent);
4609  astate->resultelemtype = get_element_type(acoerce->resulttype);
4610  if (astate->resultelemtype == InvalidOid)
4611  ereport(ERROR,
4612  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4613  errmsg("target type is not an array")));
4614  /* Arrays over domains aren't supported yet */
4615  Assert(getBaseType(astate->resultelemtype) ==
4616  astate->resultelemtype);
4617  astate->elemfunc.fn_oid = InvalidOid; /* not initialized */
4618  astate->amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState));
4619  state = (ExprState *) astate;
4620  }
4621  break;
4622  case T_ConvertRowtypeExpr:
4623  {
4626 
4628  cstate->arg = ExecInitExpr(convert->arg, parent);
4629  state = (ExprState *) cstate;
4630  }
4631  break;
4632  case T_CaseExpr:
4633  {
4634  CaseExpr *caseexpr = (CaseExpr *) node;
4636  List *outlist = NIL;
4637  ListCell *l;
4638 
4640  cstate->arg = ExecInitExpr(caseexpr->arg, parent);
4641  foreach(l, caseexpr->args)
4642  {
4645 
4646  wstate->xprstate.evalfunc = NULL; /* not used */
4647  wstate->xprstate.expr = (Expr *) when;
4648  wstate->expr = ExecInitExpr(when->expr, parent);
4649  wstate->result = ExecInitExpr(when->result, parent);
4650  outlist = lappend(outlist, wstate);
4651  }
4652  cstate-><