unique_any_elements_change.no-cfbot

text/plain

Filename: unique_any_elements_change.no-cfbot
Type: text/plain
Part: 0
Message: Re: POC, WIP: OR-clause support for indexes
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;
 
 --