diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index baeb83e58b..e9813ef6ab 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -312,8 +312,8 @@ TransformOrExprToANY(ParseState *pstate, List *args, int location) if (unlikely(found)) { - entry->consts = lappend(entry->consts, const_expr); - entry->exprs = lappend(entry->exprs, orqual); + entry->consts = list_append_unique(entry->consts, const_expr); + entry->exprs = list_append_unique(entry->exprs, orqual); } else { @@ -352,7 +352,6 @@ TransformOrExprToANY(ParseState *pstate, List *args, int location) entry = (OrClauseGroupEntry *) lfirst(lc); Assert(list_length(entry->consts) > 0); - Assert(list_length(entry->exprs) == list_length(entry->consts)); if (list_length(entry->consts) == 1 || list_length(entry->consts) > MAX_SAOP_ARRAY_SIZE) diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out index 7b721bac71..606a4399f9 100644 --- a/src/test/regress/expected/create_index.out +++ b/src/test/regress/expected/create_index.out @@ -1915,16 +1915,16 @@ SELECT count(*) FROM tenk1 EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 WHERE hundred = 42 AND (thousand < 42 OR thousand < 99 OR 43 > thousand OR 42 > thousand); - QUERY PLAN ------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------- Aggregate -> Bitmap Heap Scan on tenk1 - Recheck Cond: ((hundred = 42) AND (thousand < ANY ('{42,99,43,42}'::integer[]))) + Recheck Cond: ((hundred = 42) AND (thousand < ANY ('{42,99,43}'::integer[]))) -> BitmapAnd -> Bitmap Index Scan on tenk1_hundred Index Cond: (hundred = 42) -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: (thousand < ANY ('{42,99,43,42}'::integer[])) + Index Cond: (thousand < ANY ('{42,99,43}'::integer[])) (8 rows) EXPLAIN (COSTS OFF) diff --git a/src/test/regress/expected/select.out b/src/test/regress/expected/select.out index 0ebaf002e8..f4f5493c43 100644 --- a/src/test/regress/expected/select.out +++ b/src/test/regress/expected/select.out @@ -1047,11 +1047,11 @@ SELECT count(*) FROM onek2 WHERE stringu1 IN ('A', 'J', 'C'); EXPLAIN (COSTS OFF) SELECT unique2 FROM onek2 WHERE stringu1 IN ('A', 'A') AND (stringu1 = 'A' OR stringu1 = 'A'); - QUERY PLAN ---------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------- Bitmap Heap Scan on onek2 Recheck Cond: (stringu1 < 'B'::name) - Filter: ((stringu1 = ANY ('{A,A}'::name[])) AND (stringu1 = ANY ('{A,A}'::name[]))) + Filter: ((stringu1 = ANY ('{A,A}'::name[])) AND (stringu1 = 'A'::name)) -> Bitmap Index Scan on onek2_u2_prtl (4 rows) @@ -1114,7 +1114,7 @@ WHERE unique1 IN ((random()*2)::integer, (random()*3)::integer); Filter: (unique1 = ANY (ARRAY[((random() * '2'::double precision))::integer, ((random() * '3'::double precision))::integer])) (2 rows) --- Combine different saops. Soe of them doesnt' fit a set of partial indexes, +-- Combine different saops. Some of them doesnt' fit a set of partial indexes, -- but other fits. -- Unfortunately, we don't combine saop and OR clauses so far. EXPLAIN (COSTS OFF) @@ -1170,7 +1170,7 @@ WHERE (unique1 < 1 OR stringu1 IN ('A','J')); -> Bitmap Index Scan on onek2_u2_prtl (9 rows) --- Although SAOP doesn't fit partial indexes fully, we can use anded OR clause +-- Although SAOP doesn't fit partial indexes fully, we can use added OR clause -- to scan another couple of partial indexes. EXPLAIN (COSTS OFF) SELECT count(*) FROM onek2 @@ -1188,6 +1188,17 @@ WHERE stringu1 IN ('B','J') AND (stringu1 = 'A' OR unique1 = 1); (8 rows) RESET enable_indexscan; +--Check the case when we construct ANY list with unique elements +EXPLAIN (COSTS OFF) +SELECT count(*) FROM onek2 +WHERE unique1 = 1 OR unique1 = 1; + QUERY PLAN +---------------------------------------------------- + Aggregate + -> Index Only Scan using onek2_u1_prtl on onek2 + Index Cond: (unique1 = 1) +(3 rows) + RESET enable_seqscan; -- -- Test some corner cases that have been known to confuse the planner diff --git a/src/test/regress/sql/select.sql b/src/test/regress/sql/select.sql index 223f55af4e..b8cee41658 100644 --- a/src/test/regress/sql/select.sql +++ b/src/test/regress/sql/select.sql @@ -291,7 +291,7 @@ EXPLAIN (COSTS OFF) SELECT unique2,stringu1 FROM onek2 WHERE unique1 IN ((random()*2)::integer, (random()*3)::integer); --- Combine different saops. Soe of them doesnt' fit a set of partial indexes, +-- Combine different saops. Some of them doesnt' fit a set of partial indexes, -- but other fits. -- Unfortunately, we don't combine saop and OR clauses so far. EXPLAIN (COSTS OFF) @@ -307,13 +307,18 @@ WHERE unique1 < 1 OR (stringu1 = 'A' OR stringu1 = 'J'); EXPLAIN (COSTS OFF) SELECT unique2, stringu1 FROM onek2 WHERE (unique1 < 1 OR stringu1 IN ('A','J')); --- Although SAOP doesn't fit partial indexes fully, we can use anded OR clause +-- Although SAOP doesn't fit partial indexes fully, we can use added OR clause -- to scan another couple of partial indexes. EXPLAIN (COSTS OFF) SELECT count(*) FROM onek2 WHERE stringu1 IN ('B','J') AND (stringu1 = 'A' OR unique1 = 1); RESET enable_indexscan; +--Check the case when we construct ANY list with unique elements +EXPLAIN (COSTS OFF) +SELECT count(*) FROM onek2 +WHERE unique1 = 1 OR unique1 = 1; + RESET enable_seqscan; --