mirror of
https://github.com/postgres/postgres.git
synced 2025-11-03 09:13:20 +03:00
Allow usage of match_orclause_to_indexcol() for joins
This commit allows transformation of OR-clauses into SAOP's for index scans
within nested loop joins. That required the following changes.
1. Make match_orclause_to_indexcol() and group_similar_or_args() understand
const-ness in the same way as match_opclause_to_indexcol(). This
generally makes our approach more uniform.
2. Make match_join_clauses_to_index() pass OR-clauses to
match_clause_to_index().
3. Also switch match_join_clauses_to_index() to use list_append_unique_ptr()
for adding clauses to *joinorclauses. That avoids possible duplicates
when processing the same clauses with different indexes. Previously such
duplicates were elimited in match_clause_to_index(), but now
group_similar_or_args() each time generates distinct copies of grouped
OR clauses.
Discussion: https://postgr.es/m/CAPpHfdv%2BjtNwofg-p5z86jLYZUTt6tR17Wy00ta0dL%3DwHQN3ZA%40mail.gmail.com
Reviewed-by: Andrei Lepikhov <lepihov@gmail.com>
Reviewed-by: Alena Rybakina <a.rybakina@postgrespro.ru>
Reviewed-by: Pavel Borisov <pashkin.elfe@gmail.com>
This commit is contained in:
@@ -781,6 +781,12 @@ EXPLAIN (COSTS OFF)
|
||||
SELECT * FROM tenk1
|
||||
WHERE tenthous = 1::numeric OR tenthous = 3::int4 OR tenthous = 42::numeric;
|
||||
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT count(*) FROM tenk1 t1
|
||||
WHERE t1.thousand = 42 OR t1.thousand = (SELECT t2.tenthous FROM tenk1 t2 WHERE t2.thousand = t1.tenthous + 1 LIMIT 1);
|
||||
SELECT count(*) FROM tenk1 t1
|
||||
WHERE t1.thousand = 42 OR t1.thousand = (SELECT t2.tenthous FROM tenk1 t2 WHERE t2.thousand = t1.tenthous + 1 LIMIT 1);
|
||||
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT count(*) FROM tenk1
|
||||
WHERE hundred = 42 AND (thousand = 42 OR thousand = 99);
|
||||
@@ -1367,6 +1373,9 @@ CREATE STATISTICS t_a_b_stat (mcv) ON a, b FROM bitmap_split_or;
|
||||
CREATE STATISTICS t_b_c_stat (mcv) ON b, c FROM bitmap_split_or;
|
||||
ANALYZE bitmap_split_or;
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT * FROM bitmap_split_or t1, bitmap_split_or t2
|
||||
WHERE t1.a = t2.b OR t1.a = 2;
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT * FROM bitmap_split_or WHERE a = 1 AND (b = 1 OR b = 2) AND c = 2;
|
||||
DROP TABLE bitmap_split_or;
|
||||
|
||||
|
||||
@@ -3016,7 +3016,6 @@ SELECT t1.a FROM skip_fetch t1 LEFT JOIN skip_fetch t2 ON t2.a = 1 WHERE t2.a IS
|
||||
|
||||
RESET enable_indexonlyscan;
|
||||
RESET enable_seqscan;
|
||||
|
||||
-- Test BitmapHeapScan with a rescan releases resources correctly
|
||||
SET enable_seqscan = off;
|
||||
SET enable_indexscan = off;
|
||||
@@ -3046,3 +3045,20 @@ SELECT 1 FROM group_tbl t1
|
||||
GROUP BY s.c1, s.c2;
|
||||
|
||||
DROP TABLE group_tbl;
|
||||
|
||||
--
|
||||
-- Test for a nested loop join involving index scan, transforming OR-clauses
|
||||
-- to SAOP.
|
||||
--
|
||||
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT COUNT(*) FROM tenk1 t1, tenk1 t2
|
||||
WHERE t2.thousand = t1.tenthous OR t2.thousand = t1.unique1 OR t2.thousand = t1.unique2;
|
||||
SELECT COUNT(*) FROM tenk1 t1, tenk1 t2
|
||||
WHERE t2.thousand = t1.tenthous OR t2.thousand = t1.unique1 OR t2.thousand = t1.unique2;
|
||||
|
||||
EXPLAIN (COSTS OFF)
|
||||
SELECT COUNT(*) FROM onek t1 LEFT JOIN tenk1 t2
|
||||
ON (t2.thousand = t1.tenthous OR t2.thousand = t1.thousand);
|
||||
SELECT COUNT(*) FROM onek t1 LEFT JOIN tenk1 t2
|
||||
ON (t2.thousand = t1.tenthous OR t2.thousand = t1.thousand);
|
||||
|
||||
Reference in New Issue
Block a user