gpdb
gpdb copied to clipboard
Bugfix for copy null value for partition key into partition leaf table
I encounter a bug. When copy data into a partition leaf table and table value for partition key is null, data can be copied into leaf table successfully. Even if the partition check constraint does not allow null value. This bug can be easily reproduced like this:
postgres=# create table test_tbl(a int,b int) distributed by (a) partition by range(a) (start(1) end(20) every(10));
postgres=# insert into test_tbl_1_prt_1 values(1, 1), (2, 2), (3, 3), (4, 4);
postgres=# COPY test_tbl_1_prt_1(b) FROM stdin ;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself, or an EOF signal.
>> 11
>> \.
COPY 1
postgres=# select * from test_tbl_1_prt_1;
a | b
---+----
2 | 2
3 | 3
4 | 4
| 11
1 | 1
(5 rows)
This behavior is different from copy data into root partition in Greenplum 6X_STABLE or copy data into leaf partition in Greenplum 7. In these two contidtions, errors will be raised.
The reason is as follows: In Greenplum 6X_STABLE, function CopyFrom is called when copying data into table. CopyFrom called ExecConstraints in QE to check whether target data(or slot) violates partition check. However greenplum6 see partition check as a kind of constraint. However, result is null when calculating partition constraint given null value. But In constrint check, a NULL result from a constraint expression is not to be treated as a failure. So the partition check in QE is wrongly passed.
See more details in CopyFrom->ExecConstraints->ExecRelCheck
/*
* NOTE: SQL specifies that a NULL result from a constraint expression
* is not to be treated as a failure. Therefore, tell ExecQual to
* return TRUE for NULL.
*/
if (!ExecQual(qual, econtext, true))
return check[i].ccname;
To Fix this, I called selectParititon to check whether target slot is valid for corresponding leaf partition in QD before dispatching slot to QE. I also add regression case in this issue. Please hava a look at this.