aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_utilcmd.c
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2019-03-26 10:09:14 +0900
committerMichael Paquier <michael@paquier.xyz>2019-03-26 10:09:14 +0900
commitcdde886d36b5a4d7ad9e1d02596f7fa1c8c129e3 (patch)
tree96bc052486e8f4a6ebd4ef76607445540a26ece4 /src/backend/parser/parse_utilcmd.c
parent2e3da03e9ee4d6ee5cf0d1ffe0227fe6275397e1 (diff)
downloadpostgresql-cdde886d36b5a4d7ad9e1d02596f7fa1c8c129e3.tar.gz
postgresql-cdde886d36b5a4d7ad9e1d02596f7fa1c8c129e3.zip
Fix crash when using partition bound expressions
Since 7c079d7, partition bounds are able to use generalized expression syntax when processed, treating "minvalue" and "maxvalue" as specific cases as they get passed down for transformation as a column references. The checks for infinite bounds in range expressions have been lax though, causing crashes when trying to use column reference names with more than one field. Here is an example causing a crash: CREATE TABLE list_parted (a int) PARTITION BY LIST (a); CREATE TABLE part_list_crash PARTITION OF list_parted FOR VALUES IN (somename.somename); Note that the creation of the second relation should fail as partition bounds cannot have column references in their expressions, so when finding an expression which does not match the expected infinite bounds, then this commit lets the generic transformation machinery check after it. The error message generated in this case references as well a missing RTE, which is confusing. This problem will be treated separately as it impacts as well default expressions for some time, and for now only the cases where a crash can happen are fixed. While on it, extend the set of regression tests in place for list partition bounds and add an extra set for range partition bounds. Reported-by: Alexander Lakhin Author: Michael Paquier Reviewed-by: Amit Langote Discussion: https://postgr.es/m/15668-0377b1981aa1a393@postgresql.org
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r--src/backend/parser/parse_utilcmd.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index a37d1f18bea..b4ec96d6d6d 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -3746,12 +3746,24 @@ transformPartitionRangeBounds(ParseState *pstate, List *blist,
ColumnRef *cref = (ColumnRef *) expr;
char *cname = NULL;
+ /*
+ * There should be a single field named either "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 between all partition strategies, let the
+ * expression transformation report any errors rather than
+ * doing it ourselves.
+ */
+ }
+ else if (strcmp("minvalue", cname) == 0)
{
prd = makeNode(PartitionRangeDatum);
prd->kind = PARTITION_RANGE_DATUM_MINVALUE;