Skip to content

Commit 14cae9f

Browse files
committed
Add CTE/VIEW/JOIN support for PIVOT
Modified internal PIVOT information analyzer -> executor passing design. Supported CTE/VIEW/JOIN as well as function/procedure for PIVOT operator. Task: BABEL-4713, BABEL-4714, BABEL-4673 Signed-off-by: Yanjie Xu <[email protected]>
1 parent 4497316 commit 14cae9f

File tree

15 files changed

+42
-55
lines changed

15 files changed

+42
-55
lines changed

src/backend/executor/execSRF.c

Lines changed: 7 additions & 0 deletions
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"
@@ -203,6 +204,12 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
203204
InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
204205
}
205206

207+
if (sql_dialect == SQL_DIALECT_TSQL && IsA(setexpr->expr, FuncExpr))
208+
{
209+
fcinfo->pivot_parsetree = ((FuncExpr*) setexpr->expr)->pivot_parsetree;
210+
fcinfo->pivot_extrainfo = ((FuncExpr*) setexpr->expr)->pivot_extrainfo;
211+
}
212+
206213
/*
207214
* Switch to short-lived context for calling the function or expression.
208215
*/

src/backend/executor/functions.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,8 +1936,6 @@ check_sql_fn_retval(List *queryTreeLists,
19361936
newquery->querySource = parse->querySource;
19371937
newquery->canSetTag = true;
19381938
newquery->targetList = upper_tlist;
1939-
newquery->isPivot = false;
1940-
newquery->pivotInfoList = NIL;
19411939

19421940
/* We need a moderately realistic colnames list for the subquery RTE */
19431941
colnames = NIL;

src/backend/nodes/makefuncs.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,8 @@ makeFuncExpr(Oid funcid, Oid rettype, List *args,
534534
funcexpr->inputcollid = inputcollid;
535535
funcexpr->args = args;
536536
funcexpr->location = -1;
537+
funcexpr->pivot_parsetree = NIL;
538+
funcexpr->pivot_extrainfo = NIL;
537539

538540
return funcexpr;
539541
}
@@ -600,6 +602,8 @@ makeFuncCall(List *name, List *args, CoercionForm funcformat, int location)
600602
n->func_variadic = false;
601603
n->funcformat = funcformat;
602604
n->location = location;
605+
n->pivot_parsetree = NIL;
606+
n->pivot_extrainfo = NIL;
603607
return n;
604608
}
605609

src/backend/optimizer/plan/planner.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6553,8 +6553,6 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid)
65536553
/* Set up mostly-dummy planner state */
65546554
query = makeNode(Query);
65556555
query->commandType = CMD_SELECT;
6556-
query->isPivot = false;
6557-
query->pivotInfoList = NIL;
65586556

65596557
glob = makeNode(PlannerGlobal);
65606558

@@ -6677,9 +6675,7 @@ plan_create_index_workers(Oid tableOid, Oid indexOid)
66776675
/* Set up largely-dummy planner state */
66786676
query = makeNode(Query);
66796677
query->commandType = CMD_SELECT;
6680-
query->isPivot = false;
6681-
query->pivotInfoList = NIL;
6682-
6678+
66836679
glob = makeNode(PlannerGlobal);
66846680

66856681
root = makeNode(PlannerInfo);

src/backend/optimizer/util/clauses.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,8 @@ eval_const_expressions_mutator(Node *node,
26012601
newexpr->inputcollid = expr->inputcollid;
26022602
newexpr->args = args;
26032603
newexpr->location = expr->location;
2604+
newexpr->pivot_parsetree = expr->pivot_parsetree;
2605+
newexpr->pivot_extrainfo = expr->pivot_extrainfo;
26042606
return (Node *) newexpr;
26052607
}
26062608
case T_OpExpr:
@@ -4562,6 +4564,8 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
45624564
newexpr->inputcollid = input_collid;
45634565
newexpr->args = args;
45644566
newexpr->location = -1;
4567+
newexpr->pivot_parsetree = NIL;
4568+
newexpr->pivot_extrainfo = NIL;
45654569

45664570
return evaluate_expr((Expr *) newexpr, result_type, result_typmod,
45674571
result_collid);
@@ -4674,6 +4678,8 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
46744678
fexpr->inputcollid = input_collid;
46754679
fexpr->args = args;
46764680
fexpr->location = -1;
4681+
fexpr->pivot_parsetree = NIL;
4682+
fexpr->pivot_extrainfo = NIL;
46774683

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

src/backend/parser/analyze.c

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -407,23 +407,11 @@ transformStmt(ParseState *pstate, Node *parseTree)
407407
SelectStmt *n = (SelectStmt *) parseTree;
408408

409409
if (n->valuesLists)
410-
{
411410
result = transformValuesClause(pstate, n);
412-
result->isPivot = false;
413-
result->pivotInfoList = NIL;
414-
}
415-
416411
else if (n->op == SETOP_NONE)
417-
{
418412
result = transformSelectStmt(pstate, n);
419-
}
420413
else
421-
{
422414
result = transformSetOperationStmt(pstate, n);
423-
result->isPivot = false;
424-
result->pivotInfoList = NIL;
425-
}
426-
427415
}
428416
break;
429417

@@ -471,11 +459,6 @@ transformStmt(ParseState *pstate, Node *parseTree)
471459
break;
472460
}
473461

474-
if (nodeTag(parseTree) != T_SelectStmt)
475-
{
476-
result->isPivot = false;
477-
result->pivotInfoList = NIL;
478-
}
479462
/* Mark as original query until we learn differently */
480463
result->querySource = QSRC_ORIGINAL;
481464
result->canSetTag = true;
@@ -1467,12 +1450,9 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
14671450
/* make WINDOW info available for window functions, too */
14681451
pstate->p_windowdefs = stmt->windowClause;
14691452

1470-
qry->isPivot = false;
1471-
qry->pivotInfoList = NIL;
1472-
14731453
if (stmt->isPivot && transform_pivot_clause_hook)
14741454
{
1475-
(*transform_pivot_clause_hook)(qry, pstate, stmt);
1455+
(*transform_pivot_clause_hook)(pstate, stmt);
14761456
}
14771457

14781458
/* process the FROM clause */

src/backend/parser/parse_func.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,17 @@ 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+
if (fn != NULL)
769+
{
770+
funcexpr->pivot_parsetree = copyObject(fn->pivot_parsetree);
771+
funcexpr->pivot_extrainfo = copyObject(fn->pivot_extrainfo);
772+
}
773+
else
774+
{
775+
funcexpr->pivot_parsetree = NIL;
776+
funcexpr->pivot_extrainfo = NIL;
777+
}
778+
768779

769780
retval = (Node *) funcexpr;
770781
}

src/backend/parser/parse_utilcmd.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3096,8 +3096,6 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString,
30963096
nothing_qry->rtable = pstate->p_rtable;
30973097
nothing_qry->rteperminfos = pstate->p_rteperminfos;
30983098
nothing_qry->jointree = makeFromExpr(NIL, NULL); /* no join wanted */
3099-
nothing_qry->isPivot = false;
3100-
nothing_qry->pivotInfoList = NIL;
31013099

31023100
*actions = list_make1(nothing_qry);
31033101
}

src/backend/rewrite/rewriteHandler.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@
4848

4949
bbfViewHasInsteadofTrigger_hook_type bbfViewHasInsteadofTrigger_hook = NULL; /** BBF Hook to check Instead Of trigger on View */
5050

51-
/* Hooks for restoring PIVOT info from previously created view */
52-
rewrite_pivot_view_hook_type rewrite_pivot_view_hook = NULL;
53-
5451
/* We use a list of these to detect recursion in RewriteQuery */
5552
typedef struct rewrite_event
5653
{
@@ -1829,16 +1826,6 @@ ApplyRetrieveRule(Query *parsetree,
18291826
*/
18301827
rule_action = copyObject(linitial(rule->actions));
18311828

1832-
/*
1833-
* If action query is a pivot stmt, we save the pivot related info to
1834-
* tsql_outmost_context
1835-
*/
1836-
if (sql_dialect == SQL_DIALECT_TSQL && rule_action->isPivot && rewrite_pivot_view_hook)
1837-
{
1838-
/* save information to tsql_outmost_context */
1839-
(*rewrite_pivot_view_hook)(rule_action);
1840-
}
1841-
18421829
AcquireRewriteLocks(rule_action, true, (rc != NULL));
18431830

18441831
/*

src/backend/rewrite/rewriteSearchCycle.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,6 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
279279
newq1 = makeNode(Query);
280280
newq1->commandType = CMD_SELECT;
281281
newq1->canSetTag = true;
282-
newq1->isPivot = false;
283-
newq1->pivotInfoList = NIL;
284282

285283
newrte = makeNode(RangeTblEntry);
286284
newrte->rtekind = RTE_SUBQUERY;
@@ -368,8 +366,6 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
368366
newq2 = makeNode(Query);
369367
newq2->commandType = CMD_SELECT;
370368
newq2->canSetTag = true;
371-
newq2->isPivot = false;
372-
newq2->pivotInfoList = NIL;
373369

374370
newrte = makeNode(RangeTblEntry);
375371
newrte->rtekind = RTE_SUBQUERY;

src/include/fmgr.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#ifndef FMGR_H
1919
#define FMGR_H
2020

21+
#include "nodes/pg_list.h"
2122
/* We don't want to include primnodes.h here, so make some stub references */
2223
typedef struct Node *fmNodePtr;
2324
typedef struct Aggref *fmAggrefPtr;
@@ -91,6 +92,8 @@ typedef struct FunctionCallInfoBaseData
9192
#define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4
9293
bool isnull; /* function must set true if result is NULL */
9394
short nargs; /* # arguments actually passed */
95+
List *pivot_parsetree; /* bbf_pivot function required rewritted parsetrees */
96+
List *pivot_extrainfo; /* bbf_pivot function required aggregation function and source sql string */
9497
#define FIELDNO_FUNCTIONCALLINFODATA_ARGS 6
9598
NullableDatum args[FLEXIBLE_ARRAY_MEMBER];
9699
} FunctionCallInfoBaseData;
@@ -155,6 +158,8 @@ extern void fmgr_symbol(Oid functionId, char **mod, char **fn);
155158
(Fcinfo).fncollation = (Collation); \
156159
(Fcinfo).isnull = false; \
157160
(Fcinfo).nargs = (Nargs); \
161+
(Fcinfo).pivot_parsetree = NIL; \
162+
(Fcinfo).pivot_extrainfo = NIL; \
158163
} while (0)
159164

160165
/*

src/include/nodes/parsenodes.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,6 @@ typedef struct Query
235235
int stmt_location;
236236
/* length in bytes; 0 means "rest of string" */
237237
int stmt_len pg_node_attr(query_jumble_ignore);
238-
239-
bool isPivot pg_node_attr(query_jumble_ignore);
240-
List *pivotInfoList pg_node_attr(query_jumble_ignore);
241238
} Query;
242239

243240

@@ -435,6 +432,8 @@ typedef struct FuncCall
435432
bool func_variadic; /* last argument was labeled VARIADIC */
436433
CoercionForm funcformat; /* how to display this node */
437434
int location; /* token location, or -1 if unknown */
435+
List *pivot_parsetree; /* bbf_pivot function required rewritted parsetrees */
436+
List *pivot_extrainfo; /* bbf_pivot function required aggregation function and source sql string */
438437
} FuncCall;
439438

440439
/*

src/include/nodes/primnodes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,10 @@ typedef struct FuncExpr
695695
List *args;
696696
/* token location, or -1 if unknown */
697697
int location;
698+
/* bbf_pivot function required rewritted parsetrees */
699+
List *pivot_parsetree pg_node_attr(query_jumble_ignore);
700+
/* bbf_pivot function required aggregation function name and source sql string */
701+
List *pivot_extrainfo pg_node_attr(query_jumble_ignore);
698702
} FuncExpr;
699703

700704
/*

src/include/parser/analyze.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ typedef void (*pre_transform_setop_sort_clause_hook_type) (ParseState *pstate, Q
6565
extern PGDLLEXPORT pre_transform_setop_sort_clause_hook_type pre_transform_setop_sort_clause_hook;
6666

6767
/* Hook for transform pivot clause in tsql select stmt */
68-
typedef void (*transform_pivot_clause_hook_type)(Query *qry, ParseState *pstate, SelectStmt *stmt);
68+
typedef void (*transform_pivot_clause_hook_type)(ParseState *pstate, SelectStmt *stmt);
6969
extern PGDLLEXPORT transform_pivot_clause_hook_type transform_pivot_clause_hook;
7070

7171
extern Query *parse_analyze_fixedparams(RawStmt *parseTree, const char *sourceText,

src/include/rewrite/rewriteHandler.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,4 @@ extern int relation_is_updatable(Oid reloid,
3232
bool include_triggers,
3333
Bitmapset *include_cols);
3434

35-
/* Hooks for restoring PIVOT info from previously created view */
36-
typedef void (*rewrite_pivot_view_hook_type)(Query *qry);
37-
extern PGDLLEXPORT rewrite_pivot_view_hook_type rewrite_pivot_view_hook;
38-
3935
#endif /* REWRITEHANDLER_H */

0 commit comments

Comments
 (0)