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);