]> granicus.if.org Git - postgresql/commitdiff
Fix improper NULL handling in list partitioning code.
authorRobert Haas <rhaas@postgresql.org>
Mon, 27 Mar 2017 14:51:46 +0000 (10:51 -0400)
committerRobert Haas <rhaas@postgresql.org>
Mon, 27 Mar 2017 14:51:46 +0000 (10:51 -0400)
The previous logic was wrong when the value was NULL but there was
no partition for NULL.

Amit Langote, reviewed by Jeevan Ladhe

Discussion: http://postgr.es/m/d64f8498-70eb-3c88-b56d-c54fd3b0500f@lab.ntt.co.jp

src/backend/catalog/partition.c
src/test/regress/expected/insert.out
src/test/regress/sql/insert.sql

index b434c384c97aa33fd32ac97b44db3b9a49f2975c..f9fd1366e26adefe8d8bcb6b169b4c74619da838 100644 (file)
@@ -1729,10 +1729,14 @@ get_partition_for_tuple(PartitionDispatch *pd,
                                                errmsg("range partition key of row contains null")));
                }
 
-               if (partdesc->boundinfo->has_null && isnull[0])
-                       /* Tuple maps to the null-accepting list partition */
+               /*
+                * A null partition key is only acceptable if null-accepting list
+                * partition exists.
+                */
+               cur_index = -1;
+               if (isnull[0] && partdesc->boundinfo->has_null)
                        cur_index = partdesc->boundinfo->null_index;
-               else
+               else if (!isnull[0])
                {
                        /* Else bsearch in partdesc->boundinfo */
                        bool            equal = false;
index 116854e1420838b30c2e2489a1560a4aed951a7d..7fafa982126dda29a1c51aa7144200c0462182fa 100644 (file)
@@ -365,6 +365,13 @@ DETAIL:  Failing row contains (1, 2).
 insert into mlparted1 (a, b) values (2, 3);
 ERROR:  new row for relation "mlparted11" violates partition constraint
 DETAIL:  Failing row contains (3, 2).
+-- check routing error through a list partitioned table when the key is null
+create table lparted_nonullpart (a int, b char) partition by list (b);
+create table lparted_nonullpart_a partition of lparted_nonullpart for values in ('a');
+insert into lparted_nonullpart values (1);
+ERROR:  no partition of relation "lparted_nonullpart" found for row
+DETAIL:  Partition key of the failing row contains (b) = (null).
+drop table lparted_nonullpart;
 -- check that RETURNING works correctly with tuple-routing
 alter table mlparted drop constraint check_b;
 create table mlparted12 partition of mlparted1 for values from (5) to (10);
index c56c3c22f8e5a34fa5c99bac2b262d43820fe4b8..f9c00705a2204086cd4f83e5b09e1f50b9d46f48 100644 (file)
@@ -226,6 +226,12 @@ insert into mlparted values (1, 2);
 -- selected by tuple-routing
 insert into mlparted1 (a, b) values (2, 3);
 
+-- check routing error through a list partitioned table when the key is null
+create table lparted_nonullpart (a int, b char) partition by list (b);
+create table lparted_nonullpart_a partition of lparted_nonullpart for values in ('a');
+insert into lparted_nonullpart values (1);
+drop table lparted_nonullpart;
+
 -- check that RETURNING works correctly with tuple-routing
 alter table mlparted drop constraint check_b;
 create table mlparted12 partition of mlparted1 for values from (5) to (10);