1 /*-------------------------------------------------------------------------
2  *
3  * multi_join_order.h
4  *
5  * Type and function declarations for determining a left-only join order for a
6  * distributed query plan.
7  *
8  * Copyright (c) Citus Data, Inc.
9  *
10  * $Id$
11  *
12  *-------------------------------------------------------------------------
13  */
14 
15 #ifndef MULTI_JOIN_ORDER_H
16 #define MULTI_JOIN_ORDER_H
17 
18 #include "postgres.h"
19 
20 #include "nodes/pg_list.h"
21 #include "nodes/primnodes.h"
22 
23 
24 /*
25  * JoinRuleType determines the type of the join rule that applies between two
26  * tables or row sources. The rule types are ordered below according to their
27  * costs, with the cheapes rule appearing at the top. Note that changing the
28  * order of these enums *will* change the order in which the rules are applied.
29  */
30 typedef enum JoinRuleType
31 {
32 	JOIN_RULE_INVALID_FIRST = 0,
33 	REFERENCE_JOIN = 1,
34 	LOCAL_PARTITION_JOIN = 2,
35 	SINGLE_HASH_PARTITION_JOIN = 3,
36 	SINGLE_RANGE_PARTITION_JOIN = 4,
37 	DUAL_PARTITION_JOIN = 5,
38 	CARTESIAN_PRODUCT_REFERENCE_JOIN = 6,
39 	CARTESIAN_PRODUCT = 7,
40 
41 	/*
42 	 * Add new join rule types above this comment. After adding, you must also
43 	 * update these arrays: RuleEvalFunctionArray, RuleApplyFunctionArray, and
44 	 * RuleNameArray.
45 	 */
46 	JOIN_RULE_LAST
47 } JoinRuleType;
48 
49 
50 /*
51  * TableEntry represents a table used when determining the join order. A table
52  * entry corresponds to an ordinary relation reference (RTE_RELATION) in the
53  * query range table list.
54  */
55 typedef struct TableEntry
56 {
57 	Oid relationId;
58 	uint32 rangeTableId;
59 } TableEntry;
60 
61 
62 /*
63  * JoinOrderNode represents an element in the join order list; and this list
64  * keeps the total join order for a distributed query. The first node in this
65  * list later becomes the leftmost table in the join tree, and the successive
66  * elements in the list are the joining tables in the left-deep tree.
67  */
68 typedef struct JoinOrderNode
69 {
70 	TableEntry *tableEntry;     /* this node's relation and range table id */
71 	JoinRuleType joinRuleType;  /* not relevant for the first table */
72 	JoinType joinType;          /* not relevant for the first table */
73 
74 	/*
75 	 * We keep track of all unique partition columns in the relation to correctly find
76 	 * join clauses that can be applied locally.
77 	 */
78 	List *partitionColumnList;
79 
80 	char partitionMethod;
81 	List *joinClauseList;       /* not relevant for the first table */
82 	TableEntry *anchorTable;
83 } JoinOrderNode;
84 
85 
86 /* Config variables managed via guc.c */
87 extern bool LogMultiJoinOrder;
88 extern bool EnableSingleHashRepartitioning;
89 
90 
91 /* Function declaration for determining table join orders */
92 extern List * JoinExprList(FromExpr *fromExpr);
93 extern List * JoinOrderList(List *rangeTableEntryList, List *joinClauseList);
94 extern bool IsApplicableJoinClause(List *leftTableIdList, uint32 rightTableId,
95 								   Node *joinClause);
96 extern List * ApplicableJoinClauses(List *leftTableIdList, uint32 rightTableId,
97 									List *joinClauseList);
98 extern bool NodeIsEqualsOpExpr(Node *node);
99 extern bool IsSupportedReferenceJoin(JoinType joinType, bool leftIsReferenceTable,
100 									 bool rightIsReferenceTable);
101 extern OpExpr * SinglePartitionJoinClause(List *partitionColumnList,
102 										  List *applicableJoinClauses);
103 extern OpExpr * DualPartitionJoinClause(List *applicableJoinClauses);
104 extern Var * LeftColumnOrNULL(OpExpr *joinClause);
105 extern Var * RightColumnOrNULL(OpExpr *joinClause);
106 extern Var * PartitionColumn(Oid relationId, uint32 rangeTableId);
107 extern Var * DistPartitionKey(Oid relationId);
108 extern Var * DistPartitionKeyOrError(Oid relationId);
109 extern char PartitionMethod(Oid relationId);
110 extern char TableReplicationModel(Oid relationId);
111 
112 
113 #endif   /* MULTI_JOIN_ORDER_H */
114