Skip to content

Commit 4295eb2

Browse files
authored
Support CTE/JOIN usage for PIVOT operator (#299)
This commit fixed an issue that CTE and JOIN cannot be used with pivot operator. We added 1 field (Node *context) in FuncExpr Struct to store pivot additional information. FuncExpr will carry the pivot information to ExecMakeTableFunctionResult. In this function, we pass the pivot information into two newly added FunctionCallInfo that we can retrieve at bbf_pivot function. Task: BABEL-4713, BABEL-4714, BABEL-4795 Signed-off-by: Yanjie Xu <[email protected]>
1 parent fcc7c28 commit 4295eb2

File tree

8 files changed

+24
-2
lines changed

8 files changed

+24
-2
lines changed

src/backend/executor/execSRF.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "funcapi.h"
2626
#include "miscadmin.h"
2727
#include "nodes/nodeFuncs.h"
28+
#include "parser/parser.h"
2829
#include "parser/parse_coerce.h"
2930
#include "pgstat.h"
3031
#include "utils/acl.h"
@@ -33,6 +34,8 @@
3334
#include "utils/memutils.h"
3435
#include "utils/typcache.h"
3536

37+
/* Hook to set TSQL pivot data to fcinfo */
38+
pass_pivot_data_to_fcinfo_hook_type pass_pivot_data_to_fcinfo_hook = NULL;
3639

3740
/* static function decls */
3841
static void init_sexpr(Oid foid, Oid input_collation, Expr *node,
@@ -202,7 +205,12 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
202205
/* Treat setexpr as a generic expression */
203206
InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
204207
}
205-
208+
209+
if (sql_dialect == SQL_DIALECT_TSQL && pass_pivot_data_to_fcinfo_hook)
210+
{
211+
(pass_pivot_data_to_fcinfo_hook)(fcinfo, setexpr->expr);
212+
}
213+
206214
/*
207215
* Switch to short-lived context for calling the function or expression.
208216
*/

src/backend/nodes/makefuncs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ makeFuncExpr(Oid funcid, Oid rettype, List *args,
534534
funcexpr->inputcollid = inputcollid;
535535
funcexpr->args = args;
536536
funcexpr->location = -1;
537+
funcexpr->context = NULL;
537538

538539
return funcexpr;
539540
}
@@ -600,6 +601,7 @@ makeFuncCall(List *name, List *args, CoercionForm funcformat, int location)
600601
n->func_variadic = false;
601602
n->funcformat = funcformat;
602603
n->location = location;
604+
n->context = NULL;
603605
return n;
604606
}
605607

src/backend/optimizer/util/clauses.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,7 @@ eval_const_expressions_mutator(Node *node,
26012601
newexpr->inputcollid = expr->inputcollid;
26022602
newexpr->args = args;
26032603
newexpr->location = expr->location;
2604+
newexpr->context = expr->context;
26042605
return (Node *) newexpr;
26052606
}
26062607
case T_OpExpr:
@@ -4562,6 +4563,7 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
45624563
newexpr->inputcollid = input_collid;
45634564
newexpr->args = args;
45644565
newexpr->location = -1;
4566+
newexpr->context = NULL;
45654567

45664568
return evaluate_expr((Expr *) newexpr, result_type, result_typmod,
45674569
result_collid);
@@ -4674,6 +4676,7 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
46744676
fexpr->inputcollid = input_collid;
46754677
fexpr->args = args;
46764678
fexpr->location = -1;
4679+
fexpr->context = NULL;
46774680

46784681
/* Fetch the function body */
46794682
tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc);

src/backend/parser/analyze.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pre_transform_setop_tree_hook_type pre_transform_setop_tree_hook = NULL;
8989
/* Hook to reset a query's targetlist after modification in pre_transfrom_sort_clause */
9090
pre_transform_setop_sort_clause_hook_type pre_transform_setop_sort_clause_hook = NULL;
9191

92-
/* Hooks for transform TSQL pivot clause in select stmt */
92+
/* Hook to transform TSQL pivot clause in select stmt */
9393
transform_pivot_clause_hook_type transform_pivot_clause_hook = NULL;
9494

9595
static Query *transformOptionalSelectInto(ParseState *pstate, Node *parseTree);

src/backend/parser/parse_func.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,10 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
765765
/* funccollid and inputcollid will be set by parse_collate.c */
766766
funcexpr->args = fargs;
767767
funcexpr->location = location;
768+
funcexpr->context = NULL;
769+
770+
if (fn != NULL)
771+
funcexpr->context = copyObject(fn->context);
768772

769773
retval = (Node *) funcexpr;
770774
}

src/include/executor/executor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@ extern Datum ExecMakeFunctionResultSet(SetExprState *fcache,
473473
MemoryContext argContext,
474474
bool *isNull,
475475
ExprDoneCond *isDone);
476+
typedef void (*pass_pivot_data_to_fcinfo_hook_type)(FunctionCallInfo fcinfo, Expr *expr);
477+
extern PGDLLEXPORT pass_pivot_data_to_fcinfo_hook_type pass_pivot_data_to_fcinfo_hook;
476478

477479
/*
478480
* prototypes from functions in execScan.c

src/include/nodes/parsenodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ typedef struct FuncCall
432432
bool func_variadic; /* last argument was labeled VARIADIC */
433433
CoercionForm funcformat; /* how to display this node */
434434
int location; /* token location, or -1 if unknown */
435+
Node *context; /* pass necessary info through planner and executor */
435436
} FuncCall;
436437

437438
/*

src/include/nodes/primnodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ typedef struct FuncExpr
695695
List *args;
696696
/* token location, or -1 if unknown */
697697
int location;
698+
/* pass necessary info through planner and executor */
699+
Node *context pg_node_attr(query_jumble_ignore, read_write_ignore, read_as(NULL));
698700
} FuncExpr;
699701

700702
/*

0 commit comments

Comments
 (0)