Commit 504c2205 authored by Robert Haas's avatar Robert Haas

Fix crash when partitioned column specified twice.

Amit Langote, reviewed by Beena Emerson

Discussion: http://postgr.es/m/6ed23d3d-c09d-4cbc-3628-0a8a32f750f4@lab.ntt.co.jp
parent e3cf7080
...@@ -167,6 +167,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) ...@@ -167,6 +167,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
coldef->is_local = true; coldef->is_local = true;
coldef->is_not_null = true; coldef->is_not_null = true;
coldef->is_from_type = false; coldef->is_from_type = false;
coldef->is_from_parent = false;
coldef->storage = 0; coldef->storage = 0;
coldef->raw_default = NULL; coldef->raw_default = NULL;
coldef->cooked_default = NULL; coldef->cooked_default = NULL;
......
...@@ -1919,6 +1919,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence, ...@@ -1919,6 +1919,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
def->is_local = false; def->is_local = false;
def->is_not_null = attribute->attnotnull; def->is_not_null = attribute->attnotnull;
def->is_from_type = false; def->is_from_type = false;
def->is_from_parent = true;
def->storage = attribute->attstorage; def->storage = attribute->attstorage;
def->raw_default = NULL; def->raw_default = NULL;
def->cooked_default = NULL; def->cooked_default = NULL;
...@@ -2206,12 +2207,21 @@ MergeAttributes(List *schema, List *supers, char relpersistence, ...@@ -2206,12 +2207,21 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
* merge the column options into the column from the * merge the column options into the column from the
* parent * parent
*/ */
if (coldef->is_from_parent)
{
coldef->is_not_null = restdef->is_not_null; coldef->is_not_null = restdef->is_not_null;
coldef->raw_default = restdef->raw_default; coldef->raw_default = restdef->raw_default;
coldef->cooked_default = restdef->cooked_default; coldef->cooked_default = restdef->cooked_default;
coldef->constraints = restdef->constraints; coldef->constraints = restdef->constraints;
coldef->is_from_parent = false;
list_delete_cell(schema, rest, prev); list_delete_cell(schema, rest, prev);
} }
else
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_COLUMN),
errmsg("column \"%s\" specified more than once",
coldef->colname)));
}
prev = rest; prev = rest;
rest = next; rest = next;
} }
......
...@@ -2804,6 +2804,7 @@ _copyColumnDef(const ColumnDef *from) ...@@ -2804,6 +2804,7 @@ _copyColumnDef(const ColumnDef *from)
COPY_SCALAR_FIELD(is_local); COPY_SCALAR_FIELD(is_local);
COPY_SCALAR_FIELD(is_not_null); COPY_SCALAR_FIELD(is_not_null);
COPY_SCALAR_FIELD(is_from_type); COPY_SCALAR_FIELD(is_from_type);
COPY_SCALAR_FIELD(is_from_parent);
COPY_SCALAR_FIELD(storage); COPY_SCALAR_FIELD(storage);
COPY_NODE_FIELD(raw_default); COPY_NODE_FIELD(raw_default);
COPY_NODE_FIELD(cooked_default); COPY_NODE_FIELD(cooked_default);
......
...@@ -2540,6 +2540,7 @@ _equalColumnDef(const ColumnDef *a, const ColumnDef *b) ...@@ -2540,6 +2540,7 @@ _equalColumnDef(const ColumnDef *a, const ColumnDef *b)
COMPARE_SCALAR_FIELD(is_local); COMPARE_SCALAR_FIELD(is_local);
COMPARE_SCALAR_FIELD(is_not_null); COMPARE_SCALAR_FIELD(is_not_null);
COMPARE_SCALAR_FIELD(is_from_type); COMPARE_SCALAR_FIELD(is_from_type);
COMPARE_SCALAR_FIELD(is_from_parent);
COMPARE_SCALAR_FIELD(storage); COMPARE_SCALAR_FIELD(storage);
COMPARE_NODE_FIELD(raw_default); COMPARE_NODE_FIELD(raw_default);
COMPARE_NODE_FIELD(cooked_default); COMPARE_NODE_FIELD(cooked_default);
......
...@@ -494,6 +494,7 @@ makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid) ...@@ -494,6 +494,7 @@ makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
n->is_local = true; n->is_local = true;
n->is_not_null = false; n->is_not_null = false;
n->is_from_type = false; n->is_from_type = false;
n->is_from_parent = false;
n->storage = 0; n->storage = 0;
n->raw_default = NULL; n->raw_default = NULL;
n->cooked_default = NULL; n->cooked_default = NULL;
......
...@@ -2766,6 +2766,7 @@ _outColumnDef(StringInfo str, const ColumnDef *node) ...@@ -2766,6 +2766,7 @@ _outColumnDef(StringInfo str, const ColumnDef *node)
WRITE_BOOL_FIELD(is_local); WRITE_BOOL_FIELD(is_local);
WRITE_BOOL_FIELD(is_not_null); WRITE_BOOL_FIELD(is_not_null);
WRITE_BOOL_FIELD(is_from_type); WRITE_BOOL_FIELD(is_from_type);
WRITE_BOOL_FIELD(is_from_parent);
WRITE_CHAR_FIELD(storage); WRITE_CHAR_FIELD(storage);
WRITE_NODE_FIELD(raw_default); WRITE_NODE_FIELD(raw_default);
WRITE_NODE_FIELD(cooked_default); WRITE_NODE_FIELD(cooked_default);
......
...@@ -3253,6 +3253,7 @@ columnDef: ColId Typename create_generic_options ColQualList ...@@ -3253,6 +3253,7 @@ columnDef: ColId Typename create_generic_options ColQualList
n->is_local = true; n->is_local = true;
n->is_not_null = false; n->is_not_null = false;
n->is_from_type = false; n->is_from_type = false;
n->is_from_parent = false;
n->storage = 0; n->storage = 0;
n->raw_default = NULL; n->raw_default = NULL;
n->cooked_default = NULL; n->cooked_default = NULL;
...@@ -3274,6 +3275,7 @@ columnOptions: ColId ColQualList ...@@ -3274,6 +3275,7 @@ columnOptions: ColId ColQualList
n->is_local = true; n->is_local = true;
n->is_not_null = false; n->is_not_null = false;
n->is_from_type = false; n->is_from_type = false;
n->is_from_parent = false;
n->storage = 0; n->storage = 0;
n->raw_default = NULL; n->raw_default = NULL;
n->cooked_default = NULL; n->cooked_default = NULL;
...@@ -3292,6 +3294,7 @@ columnOptions: ColId ColQualList ...@@ -3292,6 +3294,7 @@ columnOptions: ColId ColQualList
n->is_local = true; n->is_local = true;
n->is_not_null = false; n->is_not_null = false;
n->is_from_type = false; n->is_from_type = false;
n->is_from_parent = false;
n->storage = 0; n->storage = 0;
n->raw_default = NULL; n->raw_default = NULL;
n->cooked_default = NULL; n->cooked_default = NULL;
...@@ -11888,6 +11891,7 @@ TableFuncElement: ColId Typename opt_collate_clause ...@@ -11888,6 +11891,7 @@ TableFuncElement: ColId Typename opt_collate_clause
n->is_local = true; n->is_local = true;
n->is_not_null = false; n->is_not_null = false;
n->is_from_type = false; n->is_from_type = false;
n->is_from_parent = false;
n->storage = 0; n->storage = 0;
n->raw_default = NULL; n->raw_default = NULL;
n->cooked_default = NULL; n->cooked_default = NULL;
......
...@@ -983,6 +983,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla ...@@ -983,6 +983,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
def->is_local = true; def->is_local = true;
def->is_not_null = attribute->attnotnull; def->is_not_null = attribute->attnotnull;
def->is_from_type = false; def->is_from_type = false;
def->is_from_parent = false;
def->storage = 0; def->storage = 0;
def->raw_default = NULL; def->raw_default = NULL;
def->cooked_default = NULL; def->cooked_default = NULL;
...@@ -1221,6 +1222,7 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename) ...@@ -1221,6 +1222,7 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
n->is_local = true; n->is_local = true;
n->is_not_null = false; n->is_not_null = false;
n->is_from_type = true; n->is_from_type = true;
n->is_from_parent = false;
n->storage = 0; n->storage = 0;
n->raw_default = NULL; n->raw_default = NULL;
n->cooked_default = NULL; n->cooked_default = NULL;
......
...@@ -643,6 +643,7 @@ typedef struct ColumnDef ...@@ -643,6 +643,7 @@ typedef struct ColumnDef
bool is_local; /* column has local (non-inherited) def'n */ bool is_local; /* column has local (non-inherited) def'n */
bool is_not_null; /* NOT NULL constraint specified? */ bool is_not_null; /* NOT NULL constraint specified? */
bool is_from_type; /* column definition came from table type */ bool is_from_type; /* column definition came from table type */
bool is_from_parent; /* column def came from partition parent */
char storage; /* attstorage setting, or 0 for default */ char storage; /* attstorage setting, or 0 for default */
Node *raw_default; /* default value (untransformed parse tree) */ Node *raw_default; /* default value (untransformed parse tree) */
Node *cooked_default; /* default value (transformed expr tree) */ Node *cooked_default; /* default value (transformed expr tree) */
......
...@@ -609,6 +609,14 @@ SELECT attname, attislocal, attinhcount FROM pg_attribute ...@@ -609,6 +609,14 @@ SELECT attname, attislocal, attinhcount FROM pg_attribute
(2 rows) (2 rows)
-- able to specify column default, column constraint, and table constraint -- able to specify column default, column constraint, and table constraint
-- first check the "column specified more than once" error
CREATE TABLE part_b PARTITION OF parted (
b NOT NULL,
b DEFAULT 1,
b CHECK (b >= 0),
CONSTRAINT check_a CHECK (length(a) > 0)
) FOR VALUES IN ('b');
ERROR: column "b" specified more than once
CREATE TABLE part_b PARTITION OF parted ( CREATE TABLE part_b PARTITION OF parted (
b NOT NULL DEFAULT 1 CHECK (b >= 0), b NOT NULL DEFAULT 1 CHECK (b >= 0),
CONSTRAINT check_a CHECK (length(a) > 0) CONSTRAINT check_a CHECK (length(a) > 0)
......
...@@ -569,6 +569,15 @@ SELECT attname, attislocal, attinhcount FROM pg_attribute ...@@ -569,6 +569,15 @@ SELECT attname, attislocal, attinhcount FROM pg_attribute
ORDER BY attnum; ORDER BY attnum;
-- able to specify column default, column constraint, and table constraint -- able to specify column default, column constraint, and table constraint
-- first check the "column specified more than once" error
CREATE TABLE part_b PARTITION OF parted (
b NOT NULL,
b DEFAULT 1,
b CHECK (b >= 0),
CONSTRAINT check_a CHECK (length(a) > 0)
) FOR VALUES IN ('b');
CREATE TABLE part_b PARTITION OF parted ( CREATE TABLE part_b PARTITION OF parted (
b NOT NULL DEFAULT 1 CHECK (b >= 0), b NOT NULL DEFAULT 1 CHECK (b >= 0),
CONSTRAINT check_a CHECK (length(a) > 0) CONSTRAINT check_a CHECK (length(a) > 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment