@@ -97,55 +97,50 @@ SELECT * FROM pred_tab t WHERE t.b IS NULL OR t.c IS NULL;
97
97
-- and b) its Var is not nullable by any outer joins
98
98
EXPLAIN (COSTS OFF)
99
99
SELECT * FROM pred_tab t1
100
- LEFT JOIN pred_tab t2 ON TRUE
101
- LEFT JOIN pred_tab t3 ON t2.a IS NOT NULL;
102
- QUERY PLAN
103
- -------------------------------------------------
100
+ LEFT JOIN pred_tab t2 ON t1.a IS NOT NULL;
101
+ QUERY PLAN
102
+ -------------------------------------
104
103
Nested Loop Left Join
105
104
-> Seq Scan on pred_tab t1
106
105
-> Materialize
107
- -> Nested Loop Left Join
108
- -> Seq Scan on pred_tab t2
109
- -> Materialize
110
- -> Seq Scan on pred_tab t3
111
- (7 rows)
106
+ -> Seq Scan on pred_tab t2
107
+ (4 rows)
112
108
113
109
-- Ensure the IS_NOT_NULL qual is not ignored when columns are made nullable
114
110
-- by an outer join
115
111
EXPLAIN (COSTS OFF)
116
112
SELECT * FROM pred_tab t1
117
- LEFT JOIN pred_tab t2 ON t1.a = 1
113
+ FULL JOIN pred_tab t2 ON t1.a = t2.a
118
114
LEFT JOIN pred_tab t3 ON t2.a IS NOT NULL;
119
115
QUERY PLAN
120
116
-------------------------------------------
121
117
Nested Loop Left Join
122
118
Join Filter: (t2.a IS NOT NULL)
123
- -> Nested Loop Left Join
124
- Join Filter: (t1.a = 1)
125
- -> Seq Scan on pred_tab t1
126
- -> Materialize
119
+ -> Merge Full Join
120
+ Merge Cond: (t1.a = t2.a)
121
+ -> Sort
122
+ Sort Key: t1.a
123
+ -> Seq Scan on pred_tab t1
124
+ -> Sort
125
+ Sort Key: t2.a
127
126
-> Seq Scan on pred_tab t2
128
127
-> Materialize
129
128
-> Seq Scan on pred_tab t3
130
- (9 rows)
129
+ (12 rows)
131
130
132
131
-- Ensure the IS_NULL qual is reduced to constant-FALSE, since a) it's on a NOT
133
132
-- NULL column, and b) its Var is not nullable by any outer joins
134
133
EXPLAIN (COSTS OFF)
135
134
SELECT * FROM pred_tab t1
136
- LEFT JOIN pred_tab t2 ON TRUE
137
- LEFT JOIN pred_tab t3 ON t2.a IS NULL AND t2.b = 1;
138
- QUERY PLAN
139
- ---------------------------------------------------
135
+ LEFT JOIN pred_tab t2 ON t1.a IS NULL;
136
+ QUERY PLAN
137
+ --------------------------------
140
138
Nested Loop Left Join
139
+ Join Filter: false
141
140
-> Seq Scan on pred_tab t1
142
- -> Materialize
143
- -> Nested Loop Left Join
144
- Join Filter: (false AND (t2.b = 1))
145
- -> Seq Scan on pred_tab t2
146
- -> Result
147
- One-Time Filter: false
148
- (8 rows)
141
+ -> Result
142
+ One-Time Filter: false
143
+ (5 rows)
149
144
150
145
-- Ensure the IS_NULL qual is not reduced to constant-FALSE when the column is
151
146
-- nullable by an outer join
@@ -172,55 +167,50 @@ SELECT * FROM pred_tab t1
172
167
-- Ensure the OR clause is ignored when an OR branch is provably always true
173
168
EXPLAIN (COSTS OFF)
174
169
SELECT * FROM pred_tab t1
175
- LEFT JOIN pred_tab t2 ON TRUE
176
- LEFT JOIN pred_tab t3 ON t2.a IS NOT NULL OR t2.b = 1;
177
- QUERY PLAN
178
- -------------------------------------------------
170
+ LEFT JOIN pred_tab t2 ON t1.a IS NOT NULL OR t2.b = 1;
171
+ QUERY PLAN
172
+ -------------------------------------
179
173
Nested Loop Left Join
180
174
-> Seq Scan on pred_tab t1
181
175
-> Materialize
182
- -> Nested Loop Left Join
183
- -> Seq Scan on pred_tab t2
184
- -> Materialize
185
- -> Seq Scan on pred_tab t3
186
- (7 rows)
176
+ -> Seq Scan on pred_tab t2
177
+ (4 rows)
187
178
188
179
-- Ensure the NullTest is not ignored when the column is nullable by an outer
189
180
-- join
190
181
EXPLAIN (COSTS OFF)
191
182
SELECT * FROM pred_tab t1
192
- LEFT JOIN pred_tab t2 ON t1.a = 1
183
+ FULL JOIN pred_tab t2 ON t1.a = t2.a
193
184
LEFT JOIN pred_tab t3 ON t2.a IS NOT NULL OR t2.b = 1;
194
185
QUERY PLAN
195
186
---------------------------------------------------
196
187
Nested Loop Left Join
197
188
Join Filter: ((t2.a IS NOT NULL) OR (t2.b = 1))
198
- -> Nested Loop Left Join
199
- Join Filter: (t1.a = 1)
200
- -> Seq Scan on pred_tab t1
201
- -> Materialize
189
+ -> Merge Full Join
190
+ Merge Cond: (t1.a = t2.a)
191
+ -> Sort
192
+ Sort Key: t1.a
193
+ -> Seq Scan on pred_tab t1
194
+ -> Sort
195
+ Sort Key: t2.a
202
196
-> Seq Scan on pred_tab t2
203
197
-> Materialize
204
198
-> Seq Scan on pred_tab t3
205
- (9 rows)
199
+ (12 rows)
206
200
207
201
-- Ensure the OR clause is reduced to constant-FALSE when all OR branches are
208
202
-- provably false
209
203
EXPLAIN (COSTS OFF)
210
204
SELECT * FROM pred_tab t1
211
- LEFT JOIN pred_tab t2 ON TRUE
212
- LEFT JOIN pred_tab t3 ON (t2.a IS NULL OR t2.c IS NULL) AND t2.b = 1;
213
- QUERY PLAN
214
- ---------------------------------------------------
205
+ LEFT JOIN pred_tab t2 ON (t1.a IS NULL OR t1.c IS NULL);
206
+ QUERY PLAN
207
+ --------------------------------
215
208
Nested Loop Left Join
209
+ Join Filter: false
216
210
-> Seq Scan on pred_tab t1
217
- -> Materialize
218
- -> Nested Loop Left Join
219
- Join Filter: (false AND (t2.b = 1))
220
- -> Seq Scan on pred_tab t2
221
- -> Result
222
- One-Time Filter: false
223
- (8 rows)
211
+ -> Result
212
+ One-Time Filter: false
213
+ (5 rows)
224
214
225
215
-- Ensure the OR clause is not reduced to constant-FALSE when a column is
226
216
-- made nullable from an outer join
@@ -290,3 +280,84 @@ SELECT * FROM pred_parent WHERE a IS NULL;
290
280
(2 rows)
291
281
292
282
DROP TABLE pred_parent, pred_child;
283
+ -- Validate we do not reduce a clone clause to a constant true or false
284
+ CREATE TABLE pred_tab (a int, b int);
285
+ CREATE TABLE pred_tab_notnull (a int, b int NOT NULL);
286
+ INSERT INTO pred_tab VALUES (1, 1);
287
+ INSERT INTO pred_tab VALUES (2, 2);
288
+ INSERT INTO pred_tab_notnull VALUES (2, 2);
289
+ INSERT INTO pred_tab_notnull VALUES (3, 3);
290
+ ANALYZE pred_tab;
291
+ ANALYZE pred_tab_notnull;
292
+ -- Ensure the IS_NOT_NULL qual is not reduced to constant true and removed
293
+ EXPLAIN (COSTS OFF)
294
+ SELECT * FROM pred_tab t1
295
+ LEFT JOIN pred_tab t2 ON TRUE
296
+ LEFT JOIN pred_tab_notnull t3 ON t2.a = t3.a
297
+ LEFT JOIN pred_tab t4 ON t3.b IS NOT NULL;
298
+ QUERY PLAN
299
+ ---------------------------------------------------------------
300
+ Nested Loop Left Join
301
+ -> Seq Scan on pred_tab t1
302
+ -> Materialize
303
+ -> Nested Loop Left Join
304
+ Join Filter: (t3.b IS NOT NULL)
305
+ -> Nested Loop Left Join
306
+ Join Filter: (t2.a = t3.a)
307
+ -> Seq Scan on pred_tab t2
308
+ -> Materialize
309
+ -> Seq Scan on pred_tab_notnull t3
310
+ -> Materialize
311
+ -> Seq Scan on pred_tab t4
312
+ (12 rows)
313
+
314
+ SELECT * FROM pred_tab t1
315
+ LEFT JOIN pred_tab t2 ON TRUE
316
+ LEFT JOIN pred_tab_notnull t3 ON t2.a = t3.a
317
+ LEFT JOIN pred_tab t4 ON t3.b IS NOT NULL;
318
+ a | b | a | b | a | b | a | b
319
+ ---+---+---+---+---+---+---+---
320
+ 1 | 1 | 1 | 1 | | | |
321
+ 1 | 1 | 2 | 2 | 2 | 2 | 1 | 1
322
+ 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2
323
+ 2 | 2 | 1 | 1 | | | |
324
+ 2 | 2 | 2 | 2 | 2 | 2 | 1 | 1
325
+ 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2
326
+ (6 rows)
327
+
328
+ -- Ensure the IS_NULL qual is not reduced to constant false
329
+ EXPLAIN (COSTS OFF)
330
+ SELECT * FROM pred_tab t1
331
+ LEFT JOIN pred_tab t2 ON TRUE
332
+ LEFT JOIN pred_tab_notnull t3 ON t2.a = t3.a
333
+ LEFT JOIN pred_tab t4 ON t3.b IS NULL AND t3.a IS NOT NULL;
334
+ QUERY PLAN
335
+ --------------------------------------------------------------------
336
+ Nested Loop Left Join
337
+ -> Seq Scan on pred_tab t1
338
+ -> Materialize
339
+ -> Nested Loop Left Join
340
+ Join Filter: ((t3.b IS NULL) AND (t3.a IS NOT NULL))
341
+ -> Nested Loop Left Join
342
+ Join Filter: (t2.a = t3.a)
343
+ -> Seq Scan on pred_tab t2
344
+ -> Materialize
345
+ -> Seq Scan on pred_tab_notnull t3
346
+ -> Materialize
347
+ -> Seq Scan on pred_tab t4
348
+ (12 rows)
349
+
350
+ SELECT * FROM pred_tab t1
351
+ LEFT JOIN pred_tab t2 ON TRUE
352
+ LEFT JOIN pred_tab_notnull t3 ON t2.a = t3.a
353
+ LEFT JOIN pred_tab t4 ON t3.b IS NULL AND t3.a IS NOT NULL;
354
+ a | b | a | b | a | b | a | b
355
+ ---+---+---+---+---+---+---+---
356
+ 1 | 1 | 1 | 1 | | | |
357
+ 1 | 1 | 2 | 2 | 2 | 2 | |
358
+ 2 | 2 | 1 | 1 | | | |
359
+ 2 | 2 | 2 | 2 | 2 | 2 | |
360
+ (4 rows)
361
+
362
+ DROP TABLE pred_tab;
363
+ DROP TABLE pred_tab_notnull;
0 commit comments