Forgot to run make installcheck. Here's the new version of the patch that updated the test answer file.
From 9071918648412383e41976a01106257bd6a2539e Mon Sep 17 00:00:00 2001 From: Alexandra Wang <lew...@pivotal.io> Date: Wed, 8 Apr 2020 16:07:28 -0700 Subject: [PATCH v2] Report error position in partition bound check
We have been passing a dummy ParseState to ereport(). Without the source text in the ParseState ereport does not report the error position even if a error location is supplied. This patch passes a ParseState to check_new_partition_bound() when it is available. -- Create parent table create table foo (a int, b date) partition by range (b); -- Before: create table foo_part_1 partition of foo for values from (date '2007-01-01') to (date '2006-01-01'); ERROR: empty range bound specified for partition "foo_part_1" DETAIL: Specified lower bound ('2007-01-01') is greater than or equal to upper bound ('2006-01-01'). -- After: create table foo_part_1 partition of foo for values from (date '2007-01-01') to (date '2006-01-01'); ERROR: empty range bound specified for partition "foo_part_1" LINE 1: ...eate table foo_part_1 partition of foo for values from (date... ^ DETAIL: Specified lower bound ('2007-01-01') is greater than or equal to upper bound ('2006-01-01'). Co-authored-by: Ashwin Agrawal<aagra...@pivotal.io> --- src/backend/commands/tablecmds.c | 4 +-- src/backend/partitioning/partbounds.c | 3 +-- src/include/partitioning/partbounds.h | 4 ++- src/test/regress/expected/create_table.out | 30 ++++++++++++++++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 6162fb018c..46df40bee8 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1004,7 +1004,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, * Check first that the new partition's bound is valid and does not * overlap with any of existing partitions of the parent. */ - check_new_partition_bound(relname, parent, bound); + check_new_partition_bound(relname, parent, bound, pstate); /* * If the default partition exists, its partition constraints will @@ -16268,7 +16268,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) * error. */ check_new_partition_bound(RelationGetRelationName(attachrel), rel, - cmd->bound); + cmd->bound, NULL); /* OK to create inheritance. Rest of the checks performed there */ CreateInheritance(attachrel, rel); diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index 7607501fe7..dd56832efc 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -2803,12 +2803,11 @@ partitions_are_ordered(PartitionBoundInfo boundinfo, int nparts) */ void check_new_partition_bound(char *relname, Relation parent, - PartitionBoundSpec *spec) + PartitionBoundSpec *spec, ParseState *pstate) { PartitionKey key = RelationGetPartitionKey(parent); PartitionDesc partdesc = RelationGetPartitionDesc(parent); PartitionBoundInfo boundinfo = partdesc->boundinfo; - ParseState *pstate = make_parsestate(NULL); int with = -1; bool overlap = false; diff --git a/src/include/partitioning/partbounds.h b/src/include/partitioning/partbounds.h index dfc720720b..c82f77d02f 100644 --- a/src/include/partitioning/partbounds.h +++ b/src/include/partitioning/partbounds.h @@ -14,6 +14,7 @@ #include "fmgr.h" #include "nodes/parsenodes.h" #include "nodes/pg_list.h" +#include "parser/parse_node.h" #include "partitioning/partdefs.h" #include "utils/relcache.h" struct RelOptInfo; /* avoid including pathnodes.h here */ @@ -98,7 +99,8 @@ extern PartitionBoundInfo partition_bounds_merge(int partnatts, List **inner_parts); extern bool partitions_are_ordered(PartitionBoundInfo boundinfo, int nparts); extern void check_new_partition_bound(char *relname, Relation parent, - PartitionBoundSpec *spec); + PartitionBoundSpec *spec, + ParseState *pstate); extern void check_default_partition_contents(Relation parent, Relation defaultRel, PartitionBoundSpec *new_spec); diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out index 1c72f23bc9..b8de012536 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -677,6 +677,8 @@ LINE 1: ...BLE fail_part PARTITION OF list_parted FOR VALUES WITH (MODU... CREATE TABLE part_default PARTITION OF list_parted DEFAULT; CREATE TABLE fail_default_part PARTITION OF list_parted DEFAULT; ERROR: partition "fail_default_part" conflicts with existing default partition "part_default" +LINE 1: ...TE TABLE fail_default_part PARTITION OF list_parted DEFAULT; + ^ -- specified literal can't be cast to the partition column data type CREATE TABLE bools ( a bool @@ -702,6 +704,8 @@ CREATE TABLE bigintp_10 PARTITION OF bigintp FOR VALUES IN (10); -- fails due to overlap: CREATE TABLE bigintp_10_2 PARTITION OF bigintp FOR VALUES IN ('10'); ERROR: partition "bigintp_10_2" would overlap partition "bigintp_10" +LINE 1: ...ABLE bigintp_10_2 PARTITION OF bigintp FOR VALUES IN ('10'); + ^ DROP TABLE bigintp; CREATE TABLE range_parted ( a date @@ -823,8 +827,12 @@ CREATE TABLE part_ab PARTITION OF list_parted2 FOR VALUES IN ('a', 'b'); CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT; CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN (null); ERROR: partition "fail_part" would overlap partition "part_null_z" +LINE 1: ...LE fail_part PARTITION OF list_parted2 FOR VALUES IN (null); + ^ CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('b', 'c'); ERROR: partition "fail_part" would overlap partition "part_ab" +LINE 1: ...LE fail_part PARTITION OF list_parted2 FOR VALUES IN ('b', '... + ^ -- check default partition overlap INSERT INTO list_parted2 VALUES('X'); CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('W', 'X', 'Y'); @@ -835,28 +843,42 @@ CREATE TABLE range_parted2 ( -- trying to create range partition with empty range CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (0); ERROR: empty range bound specified for partition "fail_part" +LINE 1: ...E fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) T... + ^ DETAIL: Specified lower bound (1) is greater than or equal to upper bound (0). -- note that the range '[1, 1)' has no elements CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (1); ERROR: empty range bound specified for partition "fail_part" +LINE 1: ...E fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) T... + ^ DETAIL: Specified lower bound (1) is greater than or equal to upper bound (1). CREATE TABLE part0 PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (1); CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (2); ERROR: partition "fail_part" would overlap partition "part0" +LINE 1: ...E fail_part PARTITION OF range_parted2 FOR VALUES FROM (minv... + ^ CREATE TABLE part1 PARTITION OF range_parted2 FOR VALUES FROM (1) TO (10); CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (maxvalue); ERROR: partition "fail_part" would overlap partition "part1" +LINE 1: ...E fail_part PARTITION OF range_parted2 FOR VALUES FROM (9) T... + ^ CREATE TABLE part2 PARTITION OF range_parted2 FOR VALUES FROM (20) TO (30); CREATE TABLE part3 PARTITION OF range_parted2 FOR VALUES FROM (30) TO (40); CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (30); ERROR: partition "fail_part" would overlap partition "part2" +LINE 1: ...E fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) ... + ^ CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (50); ERROR: partition "fail_part" would overlap partition "part2" +LINE 1: ...E fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) ... + ^ -- Create a default partition for range partitioned table CREATE TABLE range2_default PARTITION OF range_parted2 DEFAULT; -- More than one default partition is not allowed, so this should give error CREATE TABLE fail_default_part PARTITION OF range_parted2 DEFAULT; ERROR: partition "fail_default_part" conflicts with existing default partition "range2_default" +LINE 1: ... TABLE fail_default_part PARTITION OF range_parted2 DEFAULT; + ^ -- Check if the range for default partitions overlap INSERT INTO range_parted2 VALUES (85); CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (80) TO (90); @@ -870,17 +892,23 @@ CREATE TABLE range_parted3 ( CREATE TABLE part00 PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, maxvalue); CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, 1); ERROR: partition "fail_part" would overlap partition "part00" +LINE 1: ...E fail_part PARTITION OF range_parted3 FOR VALUES FROM (0, m... + ^ CREATE TABLE part10 PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, 1); CREATE TABLE part11 PARTITION OF range_parted3 FOR VALUES FROM (1, 1) TO (1, 10); CREATE TABLE part12 PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, maxvalue); CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, 20); ERROR: partition "fail_part" would overlap partition "part12" +LINE 1: ...E fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, 1... + ^ CREATE TABLE range3_default PARTITION OF range_parted3 DEFAULT; -- cannot create a partition that says column b is allowed to range -- from -infinity to +infinity, while there exist partitions that have -- more specific ranges CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, maxvalue); ERROR: partition "fail_part" would overlap partition "part10" +LINE 1: ...E fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, m... + ^ -- check for partition bound overlap and other invalid specifications for the hash partition CREATE TABLE hash_parted2 ( a varchar @@ -892,6 +920,8 @@ CREATE TABLE h2part_4 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMA -- overlap with part_4 CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 1); ERROR: partition "fail_part" would overlap partition "h2part_4" +LINE 1: ...LE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODU... + ^ -- modulus must be greater than zero CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 0, REMAINDER 1); ERROR: modulus for hash partition must be a positive integer -- 2.26.0