|
30 | 30 | if cross_query_blocks is false), calling func() for each one with pre-
|
31 | 31 | or post-order traversal. If func() returns true, traversal is stopped early.
|
32 | 32 |
|
| 33 | + The `join` parameter, signifying what query block `path` is part of, is only |
| 34 | + used if you set cross_query_blocks = false. It is used to know whether a |
| 35 | + MATERIALIZE or STREAM access path is part of the same query block or not. |
| 36 | + If you give join == nullptr and cross_query_blocks == false, the walk will |
| 37 | + always stop at such access paths. |
| 38 | +
|
33 | 39 | Nothing currently uses post-order traversal, but it has been requested for
|
34 | 40 | future use.
|
35 | 41 | */
|
36 | 42 | template <class Func>
|
37 |
| -void WalkAccessPaths(AccessPath *path, bool cross_query_blocks, Func &&func, |
| 43 | +void WalkAccessPaths(AccessPath *path, const JOIN *join, |
| 44 | + bool cross_query_blocks, Func &&func, |
38 | 45 | bool post_order_traversal = false) {
|
39 | 46 | if (!post_order_traversal) {
|
40 | 47 | if (func(path)) {
|
@@ -64,103 +71,103 @@ void WalkAccessPaths(AccessPath *path, bool cross_query_blocks, Func &&func,
|
64 | 71 | // No children.
|
65 | 72 | return;
|
66 | 73 | case AccessPath::NESTED_LOOP_JOIN:
|
67 |
| - WalkAccessPaths(path->nested_loop_join().outer, cross_query_blocks, |
| 74 | + WalkAccessPaths(path->nested_loop_join().outer, join, cross_query_blocks, |
68 | 75 | std::forward<Func &&>(func), post_order_traversal);
|
69 |
| - WalkAccessPaths(path->nested_loop_join().inner, cross_query_blocks, |
| 76 | + WalkAccessPaths(path->nested_loop_join().inner, join, cross_query_blocks, |
70 | 77 | std::forward<Func &&>(func), post_order_traversal);
|
71 | 78 | break;
|
72 | 79 | case AccessPath::NESTED_LOOP_SEMIJOIN_WITH_DUPLICATE_REMOVAL:
|
73 | 80 | WalkAccessPaths(path->nested_loop_semijoin_with_duplicate_removal().outer,
|
74 |
| - cross_query_blocks, std::forward<Func &&>(func), |
| 81 | + join, cross_query_blocks, std::forward<Func &&>(func), |
75 | 82 | post_order_traversal);
|
76 | 83 | WalkAccessPaths(path->nested_loop_semijoin_with_duplicate_removal().inner,
|
77 |
| - cross_query_blocks, std::forward<Func &&>(func), |
| 84 | + join, cross_query_blocks, std::forward<Func &&>(func), |
78 | 85 | post_order_traversal);
|
79 | 86 | break;
|
80 | 87 | case AccessPath::BKA_JOIN:
|
81 |
| - WalkAccessPaths(path->bka_join().outer, cross_query_blocks, |
| 88 | + WalkAccessPaths(path->bka_join().outer, join, cross_query_blocks, |
82 | 89 | std::forward<Func &&>(func), post_order_traversal);
|
83 |
| - WalkAccessPaths(path->bka_join().inner, cross_query_blocks, |
| 90 | + WalkAccessPaths(path->bka_join().inner, join, cross_query_blocks, |
84 | 91 | std::forward<Func &&>(func), post_order_traversal);
|
85 | 92 | break;
|
86 | 93 | case AccessPath::HASH_JOIN:
|
87 |
| - WalkAccessPaths(path->hash_join().outer, cross_query_blocks, |
| 94 | + WalkAccessPaths(path->hash_join().outer, join, cross_query_blocks, |
88 | 95 | std::forward<Func &&>(func), post_order_traversal);
|
89 |
| - WalkAccessPaths(path->hash_join().inner, cross_query_blocks, |
| 96 | + WalkAccessPaths(path->hash_join().inner, join, cross_query_blocks, |
90 | 97 | std::forward<Func &&>(func), post_order_traversal);
|
91 | 98 | break;
|
92 | 99 | case AccessPath::FILTER:
|
93 |
| - WalkAccessPaths(path->filter().child, cross_query_blocks, |
| 100 | + WalkAccessPaths(path->filter().child, join, cross_query_blocks, |
94 | 101 | std::forward<Func &&>(func), post_order_traversal);
|
95 | 102 | break;
|
96 | 103 | case AccessPath::SORT:
|
97 |
| - WalkAccessPaths(path->sort().child, cross_query_blocks, |
| 104 | + WalkAccessPaths(path->sort().child, join, cross_query_blocks, |
98 | 105 | std::forward<Func &&>(func), post_order_traversal);
|
99 | 106 | break;
|
100 | 107 | case AccessPath::AGGREGATE:
|
101 |
| - WalkAccessPaths(path->aggregate().child, cross_query_blocks, |
| 108 | + WalkAccessPaths(path->aggregate().child, join, cross_query_blocks, |
102 | 109 | std::forward<Func &&>(func), post_order_traversal);
|
103 | 110 | break;
|
104 | 111 | case AccessPath::TEMPTABLE_AGGREGATE:
|
105 |
| - WalkAccessPaths(path->temptable_aggregate().subquery_path, |
| 112 | + WalkAccessPaths(path->temptable_aggregate().subquery_path, join, |
106 | 113 | cross_query_blocks, std::forward<Func &&>(func),
|
107 | 114 | post_order_traversal);
|
108 |
| - WalkAccessPaths(path->temptable_aggregate().table_path, |
| 115 | + WalkAccessPaths(path->temptable_aggregate().table_path, join, |
109 | 116 | cross_query_blocks, std::forward<Func &&>(func),
|
110 | 117 | post_order_traversal);
|
111 | 118 | break;
|
112 | 119 | case AccessPath::LIMIT_OFFSET:
|
113 |
| - WalkAccessPaths(path->limit_offset().child, cross_query_blocks, |
| 120 | + WalkAccessPaths(path->limit_offset().child, join, cross_query_blocks, |
114 | 121 | std::forward<Func &&>(func), post_order_traversal);
|
115 | 122 | break;
|
116 | 123 | case AccessPath::STREAM:
|
117 |
| - if (cross_query_blocks) { |
118 |
| - WalkAccessPaths(path->stream().child, cross_query_blocks, |
| 124 | + if (cross_query_blocks || path->stream().join == join) { |
| 125 | + WalkAccessPaths(path->stream().child, join, cross_query_blocks, |
119 | 126 | std::forward<Func &&>(func), post_order_traversal);
|
120 | 127 | }
|
121 | 128 | break;
|
122 | 129 | case AccessPath::MATERIALIZE:
|
123 |
| - WalkAccessPaths(path->materialize().table_path, cross_query_blocks, |
| 130 | + WalkAccessPaths(path->materialize().table_path, join, cross_query_blocks, |
124 | 131 | std::forward<Func &&>(func), post_order_traversal);
|
125 |
| - if (cross_query_blocks) { |
126 |
| - for (const MaterializePathParameters::QueryBlock &query_block : |
127 |
| - path->materialize().param->query_blocks) { |
128 |
| - WalkAccessPaths(query_block.subquery_path, cross_query_blocks, |
| 132 | + for (const MaterializePathParameters::QueryBlock &query_block : |
| 133 | + path->materialize().param->query_blocks) { |
| 134 | + if (cross_query_blocks || query_block.join == join) { |
| 135 | + WalkAccessPaths(query_block.subquery_path, join, cross_query_blocks, |
129 | 136 | std::forward<Func &&>(func), post_order_traversal);
|
130 | 137 | }
|
131 | 138 | }
|
132 | 139 | break;
|
133 | 140 | case AccessPath::MATERIALIZE_INFORMATION_SCHEMA_TABLE:
|
134 | 141 | WalkAccessPaths(path->materialize_information_schema_table().table_path,
|
135 |
| - cross_query_blocks, std::forward<Func &&>(func), |
| 142 | + join, cross_query_blocks, std::forward<Func &&>(func), |
136 | 143 | post_order_traversal);
|
137 | 144 | break;
|
138 | 145 | case AccessPath::APPEND:
|
139 | 146 | if (cross_query_blocks) {
|
140 | 147 | for (const AppendPathParameters &child : *path->append().children) {
|
141 |
| - WalkAccessPaths(child.path, cross_query_blocks, |
| 148 | + WalkAccessPaths(child.path, join, cross_query_blocks, |
142 | 149 | std::forward<Func &&>(func), post_order_traversal);
|
143 | 150 | }
|
144 | 151 | }
|
145 | 152 | break;
|
146 | 153 | case AccessPath::WINDOWING:
|
147 |
| - WalkAccessPaths(path->windowing().child, cross_query_blocks, |
| 154 | + WalkAccessPaths(path->windowing().child, join, cross_query_blocks, |
148 | 155 | std::forward<Func &&>(func), post_order_traversal);
|
149 | 156 | break;
|
150 | 157 | case AccessPath::WEEDOUT:
|
151 |
| - WalkAccessPaths(path->weedout().child, cross_query_blocks, |
| 158 | + WalkAccessPaths(path->weedout().child, join, cross_query_blocks, |
152 | 159 | std::forward<Func &&>(func), post_order_traversal);
|
153 | 160 | break;
|
154 | 161 | case AccessPath::REMOVE_DUPLICATES:
|
155 |
| - WalkAccessPaths(path->remove_duplicates().child, cross_query_blocks, |
| 162 | + WalkAccessPaths(path->remove_duplicates().child, join, cross_query_blocks, |
156 | 163 | std::forward<Func &&>(func), post_order_traversal);
|
157 | 164 | break;
|
158 | 165 | case AccessPath::ALTERNATIVE:
|
159 |
| - WalkAccessPaths(path->alternative().child, cross_query_blocks, |
| 166 | + WalkAccessPaths(path->alternative().child, join, cross_query_blocks, |
160 | 167 | std::forward<Func &&>(func), post_order_traversal);
|
161 | 168 | break;
|
162 | 169 | case AccessPath::CACHE_INVALIDATOR:
|
163 |
| - WalkAccessPaths(path->cache_invalidator().child, cross_query_blocks, |
| 170 | + WalkAccessPaths(path->cache_invalidator().child, join, cross_query_blocks, |
164 | 171 | std::forward<Func &&>(func), post_order_traversal);
|
165 | 172 | break;
|
166 | 173 | }
|
|
0 commit comments