1 /*-------------------------------------------------------------------------
2  *
3  * multi_logical_planner.h
4  *	  Type declarations for multi-relational algebra operators, and function
5  *	  declarations for building logical plans over distributed relations.
6  *
7  * Copyright (c) Citus Data, Inc.
8  *
9  * $Id$
10  *
11  *-------------------------------------------------------------------------
12  */
13 
14 #ifndef MULTI_LOGICAL_PLANNER_H
15 #define MULTI_LOGICAL_PLANNER_H
16 
17 #include "distributed/citus_nodes.h"
18 #include "distributed/errormessage.h"
19 #include "distributed/log_utils.h"
20 #include "distributed/multi_join_order.h"
21 #include "distributed/relation_restriction_equivalence.h"
22 #include "nodes/nodes.h"
23 #include "nodes/primnodes.h"
24 #include "nodes/parsenodes.h"
25 #include "nodes/pg_list.h"
26 
27 
28 #define SUBQUERY_RANGE_TABLE_ID -1
29 #define SUBQUERY_RELATION_ID 10000
30 #define SUBQUERY_PUSHDOWN_RELATION_ID 10001
31 
32 
33 /*
34  * MultiNode represents the base node type for all multi-relational algebra
35  * nodes. By creating this base node, we can simulate inheritance and represent
36  * derived operator nodes as a MultiNode type. A similar structure to simulate
37  * inheritance is also used in PostgreSQL's plan nodes.
38  */
39 typedef struct MultiNode
40 {
41 	CitusNode type;
42 
43 	struct MultiNode *parentNode;
44 
45 	/* child node(s) are defined in unary and binary nodes */
46 } MultiNode;
47 
48 
49 /* Represents unary nodes that have only one child */
50 typedef struct MultiUnaryNode
51 {
52 	MultiNode node;
53 
54 	struct MultiNode *childNode;
55 } MultiUnaryNode;
56 
57 
58 /* Represents binary nodes that have two children */
59 typedef struct MultiBinaryNode
60 {
61 	MultiNode node;
62 
63 	struct MultiNode *leftChildNode;
64 	struct MultiNode *rightChildNode;
65 } MultiBinaryNode;
66 
67 
68 /*
69  * MultiTreeRoot keeps a pointer to the root node in the multi-relational
70  * operator tree. This node is always on the top of every logical plan.
71  */
72 typedef struct MultiTreeRoot
73 {
74 	MultiUnaryNode unaryNode;
75 } MultiTreeRoot;
76 
77 
78 /*
79  * MultiTable represents a distributed table in a logical query plan. Note that
80  * this node does not represent a query operator, and differs from the nodes
81  * that follow in that sense.
82  */
83 typedef struct MultiTable
84 {
85 	MultiUnaryNode unaryNode;
86 	Oid relationId;
87 	int rangeTableId;
88 	Var *partitionColumn;
89 	Alias *alias;
90 	Alias *referenceNames;
91 	Query *subquery; /* this field is only valid for non-relation subquery types */
92 	bool includePartitions;
93 } MultiTable;
94 
95 
96 /* Defines the columns to project in multi-relational algebra */
97 typedef struct MultiProject
98 {
99 	MultiUnaryNode unaryNode;
100 	List *columnList;
101 } MultiProject;
102 
103 
104 /*
105  * MultiCollect defines the Collect operator in multi-relational algebra. This
106  * operator collects data from remote nodes; the collected data are output from
107  * the query operator that is beneath this Collect in the logical query tree.
108  */
109 typedef struct MultiCollect
110 {
111 	MultiUnaryNode unaryNode;
112 } MultiCollect;
113 
114 
115 /*
116  * MultiSelect defines the MultiSelect operator in multi-relational algebra.
117  * This operator contains select predicates which apply to a selected logical
118  * relation.
119  */
120 typedef struct MultiSelect
121 {
122 	MultiUnaryNode unaryNode;
123 	List *selectClauseList;
124 } MultiSelect;
125 
126 
127 /*
128  * MultiJoin joins the output of two query operators that are beneath it in the
129  * query tree. The operator also keeps the join rule that applies between the
130  * two operators, and the partition key to use if the join is distributed.
131  */
132 typedef struct MultiJoin
133 {
134 	MultiBinaryNode binaryNode;
135 	List *joinClauseList;
136 	JoinRuleType joinRuleType;
137 	JoinType joinType;
138 } MultiJoin;
139 
140 
141 /* Defines the (re-)Partition operator in multi-relational algebra */
142 typedef struct MultiPartition
143 {
144 	MultiUnaryNode unaryNode;
145 	Var *partitionColumn;
146 	uint32 splitPointTableId;
147 } MultiPartition;
148 
149 
150 /* Defines the CartesianProduct operator in multi-relational algebra */
151 typedef struct MultiCartesianProduct
152 {
153 	MultiBinaryNode binaryNode;
154 } MultiCartesianProduct;
155 
156 
157 /*
158  * MultiExtendedOp defines a set of extended operators that operate on columns
159  * in relational algebra. This node allows us to distinguish between operations
160  * in the coordinator and worker nodes, and also captures the following:
161  *
162  * (1) Aggregate functions such as sums or averages;
163  * (2) Grouping of attributes; these groupings may also be tied to aggregates;
164  * (3) Extended projection expressions including columns, arithmetic and string
165  * functions;
166  * (4) User's intented display information, such as column display order;
167  * (5) Sort clauses on columns, expressions, or aggregates; and
168  * (6) Limit count and offset clause.
169  */
170 typedef struct MultiExtendedOp
171 {
172 	MultiUnaryNode unaryNode;
173 	List *targetList;
174 	List *groupClauseList;
175 	List *sortClauseList;
176 	Node *limitCount;
177 	Node *limitOffset;
178 #if PG_VERSION_NUM >= PG_VERSION_13
179 	LimitOption limitOption;
180 #endif
181 	Node *havingQual;
182 	List *distinctClause;
183 	List *windowClause;
184 	bool hasDistinctOn;
185 	bool hasWindowFuncs;
186 	bool onlyPushableWindowFunctions;
187 } MultiExtendedOp;
188 
189 
190 /* Function declarations for building logical plans */
191 extern MultiTreeRoot * MultiLogicalPlanCreate(Query *originalQuery, Query *queryTree,
192 											  PlannerRestrictionContext *
193 											  plannerRestrictionContext);
194 extern bool FindNodeMatchingCheckFunction(Node *node, bool (*check)(Node *));
195 extern bool TargetListOnPartitionColumn(Query *query, List *targetEntryList);
196 extern bool FindNodeMatchingCheckFunctionInRangeTableList(List *rtable, bool (*check)(
197 															  Node *));
198 extern bool IsCitusTableRTE(Node *node);
199 extern bool IsDistributedOrReferenceTableRTE(Node *node);
200 extern bool IsDistributedTableRTE(Node *node);
201 extern bool IsReferenceTableRTE(Node *node);
202 extern bool QueryContainsDistributedTableRTE(Query *query);
203 extern bool IsCitusExtraDataContainerRelation(RangeTblEntry *rte);
204 extern bool ContainsReadIntermediateResultFunction(Node *node);
205 extern bool ContainsReadIntermediateResultArrayFunction(Node *node);
206 extern char * FindIntermediateResultIdIfExists(RangeTblEntry *rte);
207 extern MultiNode * ParentNode(MultiNode *multiNode);
208 extern MultiNode * ChildNode(MultiUnaryNode *multiNode);
209 extern MultiNode * GrandChildNode(MultiUnaryNode *multiNode);
210 extern void SetChild(MultiUnaryNode *parent, MultiNode *child);
211 extern void SetLeftChild(MultiBinaryNode *parent, MultiNode *leftChild);
212 extern void SetRightChild(MultiBinaryNode *parent, MultiNode *rightChild);
213 extern bool UnaryOperator(MultiNode *node);
214 extern bool BinaryOperator(MultiNode *node);
215 extern List * OutputTableIdList(MultiNode *multiNode);
216 extern List * FindNodesOfType(MultiNode *node, int type);
217 extern List * JoinClauseList(List *whereClauseList);
218 extern bool IsJoinClause(Node *clause);
219 extern List * SubqueryEntryList(Query *queryTree);
220 extern DeferredErrorMessage * DeferErrorIfQueryNotSupported(Query *queryTree);
221 extern List * WhereClauseList(FromExpr *fromExpr);
222 extern List * QualifierList(FromExpr *fromExpr);
223 extern List * TableEntryList(List *rangeTableList);
224 extern List * UsedTableEntryList(Query *query);
225 extern List * pull_var_clause_default(Node *node);
226 extern bool OperatorImplementsEquality(Oid opno);
227 extern DeferredErrorMessage * DeferErrorIfUnsupportedClause(List *clauseList);
228 extern MultiProject * MultiProjectNode(List *targetEntryList);
229 extern MultiExtendedOp * MultiExtendedOpNode(Query *queryTree, Query *originalQuery);
230 extern DeferredErrorMessage * DeferErrorIfUnsupportedSubqueryRepartition(Query *
231 																		 subqueryTree);
232 extern MultiNode * MultiNodeTree(Query *queryTree);
233 
234 
235 #endif   /* MULTI_LOGICAL_PLANNER_H */
236