1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-07 00:36:50 +03:00

Skip not SOAP-supported indexes while transforming an OR clause into SAOP

There is no point in transforming OR-clauses into SAOP's if the target index
doesn't support SAOP scans anyway.  This commit adds corresponding checks
to match_orclause_to_indexcol() and group_similar_or_args().  The first check
fixes the actual bug, while the second just saves some cycles.

Reported-by: Alexander Lakhin
Discussion: https://postgr.es/m/8174de69-9e1a-0827-0e81-ef97f56a5939%40gmail.com
Author: Alena Rybakina
Reviewed-by: Ranier Vilela, Alexander Korotkov, Andrei Lepikhov
This commit is contained in:
Alexander Korotkov
2024-11-29 09:48:29 +02:00
parent b6612aedc5
commit 5bba0546ee
3 changed files with 33 additions and 2 deletions

View File

@ -1354,8 +1354,11 @@ group_similar_or_args(PlannerInfo *root, RelOptInfo *rel, RestrictInfo *rinfo)
{ {
IndexOptInfo *index = (IndexOptInfo *) lfirst(lc2); IndexOptInfo *index = (IndexOptInfo *) lfirst(lc2);
/* Ignore index if it doesn't support bitmap scans */ /*
if (!index->amhasgetbitmap) * Ignore index if it doesn't support bitmap scans or SAOP
* clauses.
*/
if (!index->amhasgetbitmap || !index->amsearcharray)
continue; continue;
for (colnum = 0; colnum < index->nkeycolumns; colnum++) for (colnum = 0; colnum < index->nkeycolumns; colnum++)
@ -3248,6 +3251,10 @@ match_orclause_to_indexcol(PlannerInfo *root,
Assert(IsA(orclause, BoolExpr)); Assert(IsA(orclause, BoolExpr));
Assert(orclause->boolop == OR_EXPR); Assert(orclause->boolop == OR_EXPR);
/* Ignore index if it doesn't support SAOP clauses */
if (!index->amsearcharray)
return NULL;
/* /*
* Try to convert a list of OR-clauses to a single SAOP expression. Each * Try to convert a list of OR-clauses to a single SAOP expression. Each
* OR entry must be in the form: (indexkey operator constant) or (constant * OR entry must be in the form: (indexkey operator constant) or (constant

View File

@ -1233,6 +1233,24 @@ SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA';
14 14
(1 row) (1 row)
-- OR-clauses shouldn't be transformed into SAOP because hash indexes don't
-- support SAOP scans.
SET enable_seqscan = off;
EXPLAIN (COSTS OFF)
SELECT COUNT(*) FROM tenk1 WHERE stringu1 = 'TVAAAA' OR stringu1 = 'TVAAAB';
QUERY PLAN
------------------------------------------------------------------------------------
Aggregate
-> Bitmap Heap Scan on tenk1
Recheck Cond: ((stringu1 = 'TVAAAA'::name) OR (stringu1 = 'TVAAAB'::name))
-> BitmapOr
-> Bitmap Index Scan on hash_tuplesort_idx
Index Cond: (stringu1 = 'TVAAAA'::name)
-> Bitmap Index Scan on hash_tuplesort_idx
Index Cond: (stringu1 = 'TVAAAB'::name)
(8 rows)
RESET enable_seqscan;
DROP INDEX hash_tuplesort_idx; DROP INDEX hash_tuplesort_idx;
RESET maintenance_work_mem; RESET maintenance_work_mem;
-- --

View File

@ -372,6 +372,12 @@ CREATE INDEX hash_tuplesort_idx ON tenk1 USING hash (stringu1 name_ops) WITH (fi
EXPLAIN (COSTS OFF) EXPLAIN (COSTS OFF)
SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA'; SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA';
SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA'; SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA';
-- OR-clauses shouldn't be transformed into SAOP because hash indexes don't
-- support SAOP scans.
SET enable_seqscan = off;
EXPLAIN (COSTS OFF)
SELECT COUNT(*) FROM tenk1 WHERE stringu1 = 'TVAAAA' OR stringu1 = 'TVAAAB';
RESET enable_seqscan;
DROP INDEX hash_tuplesort_idx; DROP INDEX hash_tuplesort_idx;
RESET maintenance_work_mem; RESET maintenance_work_mem;