diff options
Diffstat (limited to 'src/backend/executor/execExprInterp.c')
-rw-r--r-- | src/backend/executor/execExprInterp.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index 80c5e04dd5f..9fcb6be414d 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -217,6 +217,8 @@ typedef struct ScalarArrayOpExprHashTable { saophash_hash *hashtab; /* underlying hash table */ struct ExprEvalStep *op; + FmgrInfo hash_finfo; /* function's lookup data */ + FunctionCallInfoBaseData hash_fcinfo_data; /* arguments etc */ } ScalarArrayOpExprHashTable; /* Define parameters for ScalarArrayOpExpr hash table code generation. */ @@ -3474,13 +3476,13 @@ static uint32 saop_element_hash(struct saophash_hash *tb, Datum key) { ScalarArrayOpExprHashTable *elements_tab = (ScalarArrayOpExprHashTable *) tb->private_data; - FunctionCallInfo fcinfo = elements_tab->op->d.hashedscalararrayop.hash_fcinfo_data; + FunctionCallInfo fcinfo = &elements_tab->hash_fcinfo_data; Datum hash; fcinfo->args[0].value = key; fcinfo->args[0].isnull = false; - hash = elements_tab->op->d.hashedscalararrayop.hash_fn_addr(fcinfo); + hash = elements_tab->hash_finfo.fn_addr(fcinfo); return DatumGetUInt32(hash); } @@ -3502,7 +3504,7 @@ saop_hash_element_match(struct saophash_hash *tb, Datum key1, Datum key2) fcinfo->args[1].value = key2; fcinfo->args[1].isnull = false; - result = elements_tab->op->d.hashedscalararrayop.fn_addr(fcinfo); + result = elements_tab->op->d.hashedscalararrayop.finfo->fn_addr(fcinfo); return DatumGetBool(result); } @@ -3549,6 +3551,7 @@ ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *eco /* Build the hash table on first evaluation */ if (elements_tab == NULL) { + ScalarArrayOpExpr *saop; int16 typlen; bool typbyval; char typalign; @@ -3560,6 +3563,8 @@ ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *eco MemoryContext oldcontext; ArrayType *arr; + saop = op->d.hashedscalararrayop.saop; + arr = DatumGetArrayTypeP(*op->resvalue); nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr)); @@ -3571,10 +3576,21 @@ ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *eco oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory); elements_tab = (ScalarArrayOpExprHashTable *) - palloc(sizeof(ScalarArrayOpExprHashTable)); + palloc0(offsetof(ScalarArrayOpExprHashTable, hash_fcinfo_data) + + SizeForFunctionCallInfo(1)); op->d.hashedscalararrayop.elements_tab = elements_tab; elements_tab->op = op; + fmgr_info(saop->hashfuncid, &elements_tab->hash_finfo); + fmgr_info_set_expr((Node *) saop, &elements_tab->hash_finfo); + + InitFunctionCallInfoData(elements_tab->hash_fcinfo_data, + &elements_tab->hash_finfo, + 1, + saop->inputcollid, + NULL, + NULL); + /* * Create the hash table sizing it according to the number of elements * in the array. This does assume that the array has no duplicates. @@ -3669,7 +3685,7 @@ ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *eco fcinfo->args[1].value = (Datum) 0; fcinfo->args[1].isnull = true; - result = op->d.hashedscalararrayop.fn_addr(fcinfo); + result = op->d.hashedscalararrayop.finfo->fn_addr(fcinfo); resultnull = fcinfo->isnull; /* |