Skip to content

Commit 42050d7

Browse files
committed
[BABEL-4673] Support View usage for PIVOT operator
This commit fixed an issue that view cannot be created or used by stmt with pivot operator. Task: BABEL-4673 Signed-off-by: Yanjie Xu <[email protected]>
1 parent 92aeff5 commit 42050d7

File tree

9 files changed

+55
-3
lines changed

9 files changed

+55
-3
lines changed

src/backend/executor/functions.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,6 +1936,8 @@ 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;
19391941

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

src/backend/optimizer/plan/planner.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6553,6 +6553,8 @@ 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;
65566558

65576559
glob = makeNode(PlannerGlobal);
65586560

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

66816685
root = makeNode(PlannerInfo);

src/backend/parser/analyze.c

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

409409
if (n->valuesLists)
410+
{
410411
result = transformValuesClause(pstate, n);
412+
result->isPivot = false;
413+
result->pivotInfoList = NIL;
414+
}
415+
411416
else if (n->op == SETOP_NONE)
417+
{
412418
result = transformSelectStmt(pstate, n);
419+
}
413420
else
421+
{
414422
result = transformSetOperationStmt(pstate, n);
423+
result->isPivot = false;
424+
result->pivotInfoList = NIL;
425+
}
426+
415427
}
416428
break;
417429

@@ -459,6 +471,11 @@ transformStmt(ParseState *pstate, Node *parseTree)
459471
break;
460472
}
461473

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

1470+
qry->isPivot = false;
1471+
qry->pivotInfoList = NIL;
1472+
14531473
if (stmt->isPivot && transform_pivot_clause_hook)
14541474
{
1455-
(*transform_pivot_clause_hook)(pstate, stmt);
1475+
(*transform_pivot_clause_hook)(qry, pstate, stmt);
14561476
}
14571477

14581478
/* process the FROM clause */

src/backend/parser/parse_utilcmd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3096,6 +3096,8 @@ 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;
30993101

31003102
*actions = list_make1(nothing_qry);
31013103
}

src/backend/rewrite/rewriteHandler.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
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+
5154
/* We use a list of these to detect recursion in RewriteQuery */
5255
typedef struct rewrite_event
5356
{
@@ -1826,6 +1829,16 @@ ApplyRetrieveRule(Query *parsetree,
18261829
*/
18271830
rule_action = copyObject(linitial(rule->actions));
18281831

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+
18291842
AcquireRewriteLocks(rule_action, true, (rc != NULL));
18301843

18311844
/*

src/backend/rewrite/rewriteSearchCycle.c

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

283285
newrte = makeNode(RangeTblEntry);
284286
newrte->rtekind = RTE_SUBQUERY;
@@ -366,6 +368,8 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
366368
newq2 = makeNode(Query);
367369
newq2->commandType = CMD_SELECT;
368370
newq2->canSetTag = true;
371+
newq2->isPivot = false;
372+
newq2->pivotInfoList = NIL;
369373

370374
newrte = makeNode(RangeTblEntry);
371375
newrte->rtekind = RTE_SUBQUERY;

src/include/nodes/parsenodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ 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);
238241
} Query;
239242

240243

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)(ParseState *pstate, SelectStmt *stmt);
68+
typedef void (*transform_pivot_clause_hook_type)(Query *qry, 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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,8 @@ 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+
3539
#endif /* REWRITEHANDLER_H */

0 commit comments

Comments
 (0)