|
15 | 15 | #include "postgres.h"
|
16 | 16 |
|
17 | 17 | #include "optimizer/clauses.h"
|
18 |
| -#include "optimizer/predtest.h" |
19 | 18 | #include "optimizer/restrictinfo.h"
|
20 | 19 | #include "optimizer/var.h"
|
21 | 20 |
|
@@ -87,192 +86,6 @@ make_restrictinfo(Expr *clause,
|
87 | 86 | nullable_relids);
|
88 | 87 | }
|
89 | 88 |
|
90 |
| -/* |
91 |
| - * make_restrictinfo_from_bitmapqual |
92 |
| - * |
93 |
| - * Given the bitmapqual Path structure for a bitmap indexscan, generate |
94 |
| - * RestrictInfo node(s) equivalent to the condition represented by the |
95 |
| - * indexclauses of the Path structure. |
96 |
| - * |
97 |
| - * The result is a List (effectively, implicit-AND representation) of |
98 |
| - * RestrictInfos. |
99 |
| - * |
100 |
| - * The caller must pass is_pushed_down, but we assume outerjoin_delayed |
101 |
| - * and pseudoconstant are false while outer_relids and nullable_relids |
102 |
| - * are NULL (no other kind of qual should ever get into a bitmapqual). |
103 |
| - * |
104 |
| - * If include_predicates is true, we add any partial index predicates to |
105 |
| - * the explicit index quals. When this is not true, we return a condition |
106 |
| - * that might be weaker than the actual scan represents. |
107 |
| - * |
108 |
| - * To do this through the normal make_restrictinfo() API, callers would have |
109 |
| - * to strip off the RestrictInfo nodes present in the indexclauses lists, and |
110 |
| - * then make_restrictinfo() would have to build new ones. It's better to have |
111 |
| - * a specialized routine to allow sharing of RestrictInfos. |
112 |
| - * |
113 |
| - * The qual manipulations here are much the same as in create_bitmap_subplan; |
114 |
| - * keep the two routines in sync! |
115 |
| - */ |
116 |
| -List * |
117 |
| -make_restrictinfo_from_bitmapqual(Path *bitmapqual, |
118 |
| - bool is_pushed_down, |
119 |
| - bool include_predicates) |
120 |
| -{ |
121 |
| - List *result; |
122 |
| - ListCell *l; |
123 |
| - |
124 |
| - if (IsA(bitmapqual, BitmapAndPath)) |
125 |
| - { |
126 |
| - BitmapAndPath *apath = (BitmapAndPath *) bitmapqual; |
127 |
| - |
128 |
| - /* |
129 |
| - * There may well be redundant quals among the subplans, since a |
130 |
| - * top-level WHERE qual might have gotten used to form several |
131 |
| - * different index quals. We don't try exceedingly hard to eliminate |
132 |
| - * redundancies, but we do eliminate obvious duplicates by using |
133 |
| - * list_concat_unique. |
134 |
| - */ |
135 |
| - result = NIL; |
136 |
| - foreach(l, apath->bitmapquals) |
137 |
| - { |
138 |
| - List *sublist; |
139 |
| - |
140 |
| - sublist = make_restrictinfo_from_bitmapqual((Path *) lfirst(l), |
141 |
| - is_pushed_down, |
142 |
| - include_predicates); |
143 |
| - result = list_concat_unique(result, sublist); |
144 |
| - } |
145 |
| - } |
146 |
| - else if (IsA(bitmapqual, BitmapOrPath)) |
147 |
| - { |
148 |
| - BitmapOrPath *opath = (BitmapOrPath *) bitmapqual; |
149 |
| - List *withris = NIL; |
150 |
| - List *withoutris = NIL; |
151 |
| - |
152 |
| - /* |
153 |
| - * Here, we only detect qual-free subplans. A qual-free subplan would |
154 |
| - * cause us to generate "... OR true ..." which we may as well reduce |
155 |
| - * to just "true". We do not try to eliminate redundant subclauses |
156 |
| - * because (a) it's not as likely as in the AND case, and (b) we might |
157 |
| - * well be working with hundreds or even thousands of OR conditions, |
158 |
| - * perhaps from a long IN list. The performance of list_append_unique |
159 |
| - * would be unacceptable. |
160 |
| - */ |
161 |
| - foreach(l, opath->bitmapquals) |
162 |
| - { |
163 |
| - List *sublist; |
164 |
| - |
165 |
| - sublist = make_restrictinfo_from_bitmapqual((Path *) lfirst(l), |
166 |
| - is_pushed_down, |
167 |
| - include_predicates); |
168 |
| - if (sublist == NIL) |
169 |
| - { |
170 |
| - /* |
171 |
| - * If we find a qual-less subscan, it represents a constant |
172 |
| - * TRUE, and hence the OR result is also constant TRUE, so we |
173 |
| - * can stop here. |
174 |
| - */ |
175 |
| - return NIL; |
176 |
| - } |
177 |
| - |
178 |
| - /* |
179 |
| - * If the sublist contains multiple RestrictInfos, we create an |
180 |
| - * AND subclause. If there's just one, we have to check if it's |
181 |
| - * an OR clause, and if so flatten it to preserve AND/OR flatness |
182 |
| - * of our output. |
183 |
| - * |
184 |
| - * We construct lists with and without sub-RestrictInfos, so as |
185 |
| - * not to have to regenerate duplicate RestrictInfos below. |
186 |
| - */ |
187 |
| - if (list_length(sublist) > 1) |
188 |
| - { |
189 |
| - withris = lappend(withris, make_andclause(sublist)); |
190 |
| - sublist = get_actual_clauses(sublist); |
191 |
| - withoutris = lappend(withoutris, make_andclause(sublist)); |
192 |
| - } |
193 |
| - else |
194 |
| - { |
195 |
| - RestrictInfo *subri = (RestrictInfo *) linitial(sublist); |
196 |
| - |
197 |
| - Assert(IsA(subri, RestrictInfo)); |
198 |
| - if (restriction_is_or_clause(subri)) |
199 |
| - { |
200 |
| - BoolExpr *subor = (BoolExpr *) subri->orclause; |
201 |
| - |
202 |
| - Assert(or_clause((Node *) subor)); |
203 |
| - withris = list_concat(withris, |
204 |
| - list_copy(subor->args)); |
205 |
| - subor = (BoolExpr *) subri->clause; |
206 |
| - Assert(or_clause((Node *) subor)); |
207 |
| - withoutris = list_concat(withoutris, |
208 |
| - list_copy(subor->args)); |
209 |
| - } |
210 |
| - else |
211 |
| - { |
212 |
| - withris = lappend(withris, subri); |
213 |
| - withoutris = lappend(withoutris, subri->clause); |
214 |
| - } |
215 |
| - } |
216 |
| - } |
217 |
| - |
218 |
| - /* |
219 |
| - * Avoid generating one-element ORs, which could happen due to |
220 |
| - * redundancy elimination or ScalarArrayOpExpr quals. |
221 |
| - */ |
222 |
| - if (list_length(withris) <= 1) |
223 |
| - result = withris; |
224 |
| - else |
225 |
| - { |
226 |
| - /* Here's the magic part not available to outside callers */ |
227 |
| - result = |
228 |
| - list_make1(make_restrictinfo_internal(make_orclause(withoutris), |
229 |
| - make_orclause(withris), |
230 |
| - is_pushed_down, |
231 |
| - false, |
232 |
| - false, |
233 |
| - NULL, |
234 |
| - NULL, |
235 |
| - NULL)); |
236 |
| - } |
237 |
| - } |
238 |
| - else if (IsA(bitmapqual, IndexPath)) |
239 |
| - { |
240 |
| - IndexPath *ipath = (IndexPath *) bitmapqual; |
241 |
| - |
242 |
| - result = list_copy(ipath->indexclauses); |
243 |
| - if (include_predicates && ipath->indexinfo->indpred != NIL) |
244 |
| - { |
245 |
| - foreach(l, ipath->indexinfo->indpred) |
246 |
| - { |
247 |
| - Expr *pred = (Expr *) lfirst(l); |
248 |
| - |
249 |
| - /* |
250 |
| - * We know that the index predicate must have been implied by |
251 |
| - * the query condition as a whole, but it may or may not be |
252 |
| - * implied by the conditions that got pushed into the |
253 |
| - * bitmapqual. Avoid generating redundant conditions. |
254 |
| - */ |
255 |
| - if (!predicate_implied_by(list_make1(pred), result)) |
256 |
| - result = lappend(result, |
257 |
| - make_restrictinfo(pred, |
258 |
| - is_pushed_down, |
259 |
| - false, |
260 |
| - false, |
261 |
| - NULL, |
262 |
| - NULL, |
263 |
| - NULL)); |
264 |
| - } |
265 |
| - } |
266 |
| - } |
267 |
| - else |
268 |
| - { |
269 |
| - elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual)); |
270 |
| - result = NIL; /* keep compiler quiet */ |
271 |
| - } |
272 |
| - |
273 |
| - return result; |
274 |
| -} |
275 |
| - |
276 | 89 | /*
|
277 | 90 | * make_restrictinfos_from_actual_clauses
|
278 | 91 | *
|
|
0 commit comments