diff.diff.no-cfbot

text/plain

Filename: diff.diff.no-cfbot
Type: text/plain
Part: 0
Message: Re: POC, WIP: OR-clause support for indexes
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 641b1d7bf8c..cde635d9cb6 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -1366,7 +1366,7 @@ group_similar_or_args(PlannerInfo *root, RelOptInfo *rel, RestrictInfo *rinfo)
 	}
 
 	/* Sort clauses to make similar clauses go together */
-	pg_qsort(matches, n, sizeof(OrArgIndexMatch), or_arg_index_match_cmp);
+	qsort(matches, n, sizeof(OrArgIndexMatch), or_arg_index_match_cmp);
 
 	/* Group similar clauses into */
 	group_start = 0;
@@ -3346,7 +3346,13 @@ match_orclause_to_indexcol(PlannerInfo *root,
 
 		elems = (Datum *) palloc(sizeof(Datum) * list_length(consts));
 		foreach(lc, consts)
-			elems[i++] = ((Const *) lfirst(lc))->constvalue;
+		{
+			Const *value = (Const *) lfirst(lc);
+
+			Assert(!value->constisnull && value->constvalue);
+
+			elems[i++] = value->constvalue;
+		}
 
 		arrayConst = construct_array(elems, i, consttype,
 									 typlen, typbyval, typalign);
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 5ccca4d83ca..5623f4b3123 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -1875,6 +1875,67 @@ SELECT * FROM tenk1
       42 |    5530 |   0 |    2 |   2 |      2 |      42 |       42 |          42 |        42 |       42 |  84 |   85 | QBAAAA   | SEIAAA   | OOOOxx
 (1 row)
 
+EXPLAIN (COSTS OFF)
+SELECT * FROM tenk1
+  WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42 or tenthous is null);
+                                                                QUERY PLAN                                                                 
+-------------------------------------------------------------------------------------------------------------------------------------------
+ Bitmap Heap Scan on tenk1
+   Recheck Cond: (((thousand = 42) AND (tenthous IS NULL)) OR ((thousand = 42) AND ((tenthous = 1) OR (tenthous = 3) OR (tenthous = 42))))
+   Filter: ((tenthous = 1) OR (tenthous = 3) OR (tenthous = 42) OR (tenthous IS NULL))
+   ->  BitmapOr
+         ->  Bitmap Index Scan on tenk1_thous_tenthous
+               Index Cond: ((thousand = 42) AND (tenthous IS NULL))
+         ->  Bitmap Index Scan on tenk1_thous_tenthous
+               Index Cond: ((thousand = 42) AND (tenthous = ANY ('{1,3,42}'::integer[])))
+(8 rows)
+
+create index stringu1_idx on tenk1 (stringu1);
+EXPLAIN (COSTS OFF)
+SELECT * FROM tenk1
+  WHERE thousand = 42 AND (stringu1::text = 'MAAAAA' OR stringu1::text = 'TUAAAA'::name OR stringu1 = 'OBAAAA'::name);
+                                                      QUERY PLAN                                                       
+-----------------------------------------------------------------------------------------------------------------------
+ Bitmap Heap Scan on tenk1
+   Recheck Cond: (thousand = 42)
+   Filter: (((stringu1)::text = 'MAAAAA'::text) OR ((stringu1)::text = 'TUAAAA'::name) OR (stringu1 = 'OBAAAA'::name))
+   ->  Bitmap Index Scan on tenk1_thous_tenthous
+         Index Cond: (thousand = 42)
+(5 rows)
+
+EXPLAIN (COSTS OFF)
+SELECT * FROM tenk1
+  WHERE thousand = 42 AND (stringu1 = 'MAAAAA' OR stringu1 = 'TUAAAA' OR stringu1 = 'OBAAAA');
+                                                            QUERY PLAN                                                             
+-----------------------------------------------------------------------------------------------------------------------------------
+ Bitmap Heap Scan on tenk1
+   Recheck Cond: ((thousand = 42) AND ((stringu1 = 'MAAAAA'::name) OR (stringu1 = 'TUAAAA'::name) OR (stringu1 = 'OBAAAA'::name)))
+   ->  BitmapAnd
+         ->  Bitmap Index Scan on tenk1_thous_tenthous
+               Index Cond: (thousand = 42)
+         ->  Bitmap Index Scan on stringu1_idx
+               Index Cond: (stringu1 = ANY ('{MAAAAA,TUAAAA,OBAAAA}'::name[]))
+(7 rows)
+
+EXPLAIN (COSTS OFF)
+SELECT * FROM tenk1
+  WHERE thousand = 42 AND (stringu1 = 'MAAAAA' OR stringu1 = 'TUAAAA'::text OR stringu1 = 'OBAAAA'::text);
+                                                             QUERY PLAN                                                              
+-------------------------------------------------------------------------------------------------------------------------------------
+ Bitmap Heap Scan on tenk1
+   Recheck Cond: ((thousand = 42) AND ((stringu1 = 'MAAAAA'::name) OR ((stringu1 = 'TUAAAA'::text) OR (stringu1 = 'OBAAAA'::text))))
+   Filter: ((stringu1 = 'MAAAAA'::name) OR (stringu1 = 'TUAAAA'::text) OR (stringu1 = 'OBAAAA'::text))
+   ->  BitmapAnd
+         ->  Bitmap Index Scan on tenk1_thous_tenthous
+               Index Cond: (thousand = 42)
+         ->  BitmapOr
+               ->  Bitmap Index Scan on stringu1_idx
+                     Index Cond: (stringu1 = 'MAAAAA'::name)
+               ->  Bitmap Index Scan on stringu1_idx
+                     Index Cond: (stringu1 = ANY ('{TUAAAA,OBAAAA}'::text[] COLLATE "C"))
+(11 rows)
+
+Drop index stringu1_idx;
 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM tenk1
   WHERE hundred = 42 AND (thousand = 42 OR thousand = 99);
diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql
index 7e108f9b283..37538ab6bba 100644
--- a/src/test/regress/sql/create_index.sql
+++ b/src/test/regress/sql/create_index.sql
@@ -738,6 +738,23 @@ SELECT * FROM tenk1
 SELECT * FROM tenk1
   WHERE thousand = 42 AND (tenthous = 1 OR tenthous = (SELECT 1 + 2) OR tenthous = 42);
 
+EXPLAIN (COSTS OFF)
+SELECT * FROM tenk1
+  WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42 or tenthous is null);
+
+create index stringu1_idx on tenk1 (stringu1);
+EXPLAIN (COSTS OFF)
+SELECT * FROM tenk1
+  WHERE thousand = 42 AND (stringu1::text = 'MAAAAA' OR stringu1::text = 'TUAAAA'::name OR stringu1 = 'OBAAAA'::name);
+
+EXPLAIN (COSTS OFF)
+SELECT * FROM tenk1
+  WHERE thousand = 42 AND (stringu1 = 'MAAAAA' OR stringu1 = 'TUAAAA' OR stringu1 = 'OBAAAA');
+EXPLAIN (COSTS OFF)
+SELECT * FROM tenk1
+  WHERE thousand = 42 AND (stringu1 = 'MAAAAA' OR stringu1 = 'TUAAAA'::text OR stringu1 = 'OBAAAA'::text);
+Drop index stringu1_idx;
+
 EXPLAIN (COSTS OFF)
 SELECT count(*) FROM tenk1
   WHERE hundred = 42 AND (thousand = 42 OR thousand = 99);