diff --git a/src/backend/executor/execSRF.c b/src/backend/executor/execSRF.c index 73bf9152a4b..b26b4ab7153 100644 --- a/src/backend/executor/execSRF.c +++ b/src/backend/executor/execSRF.c @@ -25,6 +25,7 @@ #include "funcapi.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" +#include "parser/parser.h" #include "parser/parse_coerce.h" #include "pgstat.h" #include "utils/acl.h" @@ -33,6 +34,8 @@ #include "utils/memutils.h" #include "utils/typcache.h" +/* Hook to set TSQL pivot data to fcinfo */ +pass_pivot_data_to_fcinfo_hook_type pass_pivot_data_to_fcinfo_hook = NULL; /* static function decls */ static void init_sexpr(Oid foid, Oid input_collation, Expr *node, @@ -202,7 +205,12 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, /* Treat setexpr as a generic expression */ InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL); } - + + if (sql_dialect == SQL_DIALECT_TSQL && pass_pivot_data_to_fcinfo_hook) + { + (pass_pivot_data_to_fcinfo_hook)(fcinfo, setexpr->expr); + } + /* * Switch to short-lived context for calling the function or expression. */ diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index 0e7e6e46d94..07af2177879 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -534,6 +534,7 @@ makeFuncExpr(Oid funcid, Oid rettype, List *args, funcexpr->inputcollid = inputcollid; funcexpr->args = args; funcexpr->location = -1; + funcexpr->context = NULL; return funcexpr; } @@ -600,6 +601,7 @@ makeFuncCall(List *name, List *args, CoercionForm funcformat, int location) n->func_variadic = false; n->funcformat = funcformat; n->location = location; + n->context = NULL; return n; } diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 840cafa27e8..22ad68ab8f6 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -2601,6 +2601,7 @@ eval_const_expressions_mutator(Node *node, newexpr->inputcollid = expr->inputcollid; newexpr->args = args; newexpr->location = expr->location; + newexpr->context = expr->context; return (Node *) newexpr; } case T_OpExpr: @@ -4562,6 +4563,7 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, newexpr->inputcollid = input_collid; newexpr->args = args; newexpr->location = -1; + newexpr->context = NULL; return evaluate_expr((Expr *) newexpr, result_type, result_typmod, result_collid); @@ -4674,6 +4676,7 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid, fexpr->inputcollid = input_collid; fexpr->args = args; fexpr->location = -1; + fexpr->context = NULL; /* Fetch the function body */ tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc); diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 39a62e0b75b..766b36deabc 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -89,7 +89,7 @@ pre_transform_setop_tree_hook_type pre_transform_setop_tree_hook = NULL; /* Hook to reset a query's targetlist after modification in pre_transfrom_sort_clause */ pre_transform_setop_sort_clause_hook_type pre_transform_setop_sort_clause_hook = NULL; -/* Hooks for transform TSQL pivot clause in select stmt */ +/* Hook to transform TSQL pivot clause in select stmt */ transform_pivot_clause_hook_type transform_pivot_clause_hook = NULL; static Query *transformOptionalSelectInto(ParseState *pstate, Node *parseTree); diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 35c3eba0182..aa568514683 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -765,6 +765,10 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, /* funccollid and inputcollid will be set by parse_collate.c */ funcexpr->args = fargs; funcexpr->location = location; + funcexpr->context = NULL; + + if (fn != NULL) + funcexpr->context = copyObject(fn->context); retval = (Node *) funcexpr; } diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 35ab4852cbd..0b3bdca7258 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -473,6 +473,8 @@ extern Datum ExecMakeFunctionResultSet(SetExprState *fcache, MemoryContext argContext, bool *isNull, ExprDoneCond *isDone); +typedef void (*pass_pivot_data_to_fcinfo_hook_type)(FunctionCallInfo fcinfo, Expr *expr); +extern PGDLLEXPORT pass_pivot_data_to_fcinfo_hook_type pass_pivot_data_to_fcinfo_hook; /* * prototypes from functions in execScan.c diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 8733e69be55..6e6d13cf2ec 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -432,6 +432,7 @@ typedef struct FuncCall bool func_variadic; /* last argument was labeled VARIADIC */ CoercionForm funcformat; /* how to display this node */ int location; /* token location, or -1 if unknown */ + Node *context; /* pass necessary info through planner and executor */ } FuncCall; /* diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 55201447015..b29f0c291ed 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -695,6 +695,8 @@ typedef struct FuncExpr List *args; /* token location, or -1 if unknown */ int location; + /* pass necessary info through planner and executor */ + Node *context pg_node_attr(query_jumble_ignore, read_write_ignore, read_as(NULL)); } FuncExpr; /*