partition-bound-crash-v2.patch
text/plain
Filename: partition-bound-crash-v2.patch
Type: text/plain
Part: 0
Patch
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| src/backend/parser/parse_utilcmd.c | 13 | 3 |
| src/test/regress/expected/create_table.out | 60 | 0 |
| src/test/regress/sql/create_table.sql | 22 | 0 |
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index a37d1f18be..67b05b8039 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -3746,18 +3746,28 @@ transformPartitionRangeBounds(ParseState *pstate, List *blist,
ColumnRef *cref = (ColumnRef *) expr;
char *cname = NULL;
+ /*
+ * There should be a single field named "minvalue" or "maxvalue".
+ */
if (list_length(cref->fields) == 1 &&
IsA(linitial(cref->fields), String))
cname = strVal(linitial(cref->fields));
- Assert(cname != NULL);
- if (strcmp("minvalue", cname) == 0)
+ if (cname == NULL)
+ {
+ /*
+ * ColumnRef is not in the desired single-field-name form; for
+ * consistency, let transformExpr() report the error rather
+ * than doing it ourselves.
+ */
+ }
+ else if (pg_strncasecmp(cname, "minvalue", 6) == 0)
{
prd = makeNode(PartitionRangeDatum);
prd->kind = PARTITION_RANGE_DATUM_MINVALUE;
prd->value = NULL;
}
- else if (strcmp("maxvalue", cname) == 0)
+ else if (pg_strncasecmp(cname, "maxvalue", 6) == 0)
{
prd = makeNode(PartitionRangeDatum);
prd->kind = PARTITION_RANGE_DATUM_MAXVALUE;
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index d51e547278..503dca5866 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -709,6 +709,66 @@ ERROR: modulus for hash partition must be a positive integer
-- remainder must be greater than or equal to zero and less than modulus
CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 8);
ERROR: remainder for hash partition must be less than modulus
+-- more tests for generalized expression syntax for list/range partition bounds
+CREATE TABLE list_parted_bound_exprs(a int) PARTITION BY LIST (a);
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN ("UNKNOWN");
+ERROR: column "UNKNOWN" does not exist
+LINE 1: ...RTITION OF list_parted_bound_exprs FOR VALUES IN ("UNKNOWN")...
+ ^
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (a);
+ERROR: cannot use column references in partition bound expression
+LINE 1: ...prs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (a);
+ ^
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (foo.a);
+ERROR: missing FROM-clause entry for table "foo"
+LINE 1: ... PARTITION OF list_parted_bound_exprs FOR VALUES IN (foo.a);
+ ^
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (list_parted_bound_exprs.a);
+ERROR: missing FROM-clause entry for table "list_parted_bound_exprs"
+LINE 1: ...RTITION OF list_parted_bound_exprs FOR VALUES IN (list_parte...
+ ^
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (list_parted_bound_exprs1.a.a.a.a);
+ERROR: improper qualified name (too many dotted names): list_parted_bound_exprs1.a.a.a.a
+LINE 1: ...RTITION OF list_parted_bound_exprs FOR VALUES IN (list_parte...
+ ^
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (list_parted_bound_exprs1.a);
+ERROR: cannot use column references in partition bound expression
+LINE 1: ...RTITION OF list_parted_bound_exprs FOR VALUES IN (list_parte...
+ ^
+CREATE TABLE range_parted_bound_exprs(a int) PARTITION BY RANGE (a);
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO (unknown);
+ERROR: column "unknown" does not exist
+LINE 1: ...F range_parted_bound_exprs FOR VALUES FROM (1) TO (unknown);
+ ^
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO ("a".unknown);
+ERROR: missing FROM-clause entry for table "a"
+LINE 1: ... range_parted_bound_exprs FOR VALUES FROM (1) TO ("a".unknow...
+ ^
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO ("a"."a");
+ERROR: missing FROM-clause entry for table "a"
+LINE 1: ...F range_parted_bound_exprs FOR VALUES FROM (1) TO ("a"."a");
+ ^
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO ("range_parted_bound_exprs1"."a");
+ERROR: cannot use column references in partition bound expression
+LINE 1: ... range_parted_bound_exprs FOR VALUES FROM (1) TO ("range_par...
+ ^
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO ("range_parted_bound_exprs1"."a".a.a);
+ERROR: cross-database references are not implemented: range_parted_bound_exprs1.a.a.a
+LINE 1: ... range_parted_bound_exprs FOR VALUES FROM (1) TO ("range_par...
+ ^
+-- the following two should work
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM ("minValue") TO (1);
+CREATE TABLE range_parted_bound_exprs2 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO (MAXVALUE);
+\d+ range_parted_bound_exprs
+ Partitioned table "public.range_parted_bound_exprs"
+ Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
+--------+---------+-----------+----------+---------+---------+--------------+-------------
+ a | integer | | | | plain | |
+Partition key: RANGE (a)
+Partitions: range_parted_bound_exprs1 FOR VALUES FROM (MINVALUE) TO (1),
+ range_parted_bound_exprs2 FOR VALUES FROM (1) TO (MAXVALUE)
+
+drop table list_parted_bound_exprs, range_parted_bound_exprs;
-- check schema propagation from parent
CREATE TABLE parted (
a text,
diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql
index 4091c19cf0..399a882430 100644
--- a/src/test/regress/sql/create_table.sql
+++ b/src/test/regress/sql/create_table.sql
@@ -627,6 +627,28 @@ CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 0, REM
-- remainder must be greater than or equal to zero and less than modulus
CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 8);
+-- more tests for generalized expression syntax for list/range partition bounds
+CREATE TABLE list_parted_bound_exprs(a int) PARTITION BY LIST (a);
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN ("UNKNOWN");
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (a);
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (foo.a);
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (list_parted_bound_exprs.a);
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (list_parted_bound_exprs1.a.a.a.a);
+CREATE TABLE list_parted_bound_exprs1 PARTITION OF list_parted_bound_exprs FOR VALUES IN (list_parted_bound_exprs1.a);
+
+CREATE TABLE range_parted_bound_exprs(a int) PARTITION BY RANGE (a);
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO (unknown);
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO ("a".unknown);
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO ("a"."a");
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO ("range_parted_bound_exprs1"."a");
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO ("range_parted_bound_exprs1"."a".a.a);
+-- the following two should work
+CREATE TABLE range_parted_bound_exprs1 PARTITION OF range_parted_bound_exprs FOR VALUES FROM ("minValue") TO (1);
+CREATE TABLE range_parted_bound_exprs2 PARTITION OF range_parted_bound_exprs FOR VALUES FROM (1) TO (MAXVALUE);
+\d+ range_parted_bound_exprs
+
+drop table list_parted_bound_exprs, range_parted_bound_exprs;
+
-- check schema propagation from parent
CREATE TABLE parted (