Skip to content

Commit 504c220

Browse files
committed
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
1 parent e3cf708 commit 504c220

File tree

11 files changed

+44
-5
lines changed

11 files changed

+44
-5
lines changed

src/backend/commands/sequence.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
167167
coldef->is_local = true;
168168
coldef->is_not_null = true;
169169
coldef->is_from_type = false;
170+
coldef->is_from_parent = false;
170171
coldef->storage = 0;
171172
coldef->raw_default = NULL;
172173
coldef->cooked_default = NULL;

src/backend/commands/tablecmds.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,6 +1919,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
19191919
def->is_local = false;
19201920
def->is_not_null = attribute->attnotnull;
19211921
def->is_from_type = false;
1922+
def->is_from_parent = true;
19221923
def->storage = attribute->attstorage;
19231924
def->raw_default = NULL;
19241925
def->cooked_default = NULL;
@@ -2206,11 +2207,20 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
22062207
* merge the column options into the column from the
22072208
* parent
22082209
*/
2209-
coldef->is_not_null = restdef->is_not_null;
2210-
coldef->raw_default = restdef->raw_default;
2211-
coldef->cooked_default = restdef->cooked_default;
2212-
coldef->constraints = restdef->constraints;
2213-
list_delete_cell(schema, rest, prev);
2210+
if (coldef->is_from_parent)
2211+
{
2212+
coldef->is_not_null = restdef->is_not_null;
2213+
coldef->raw_default = restdef->raw_default;
2214+
coldef->cooked_default = restdef->cooked_default;
2215+
coldef->constraints = restdef->constraints;
2216+
coldef->is_from_parent = false;
2217+
list_delete_cell(schema, rest, prev);
2218+
}
2219+
else
2220+
ereport(ERROR,
2221+
(errcode(ERRCODE_DUPLICATE_COLUMN),
2222+
errmsg("column \"%s\" specified more than once",
2223+
coldef->colname)));
22142224
}
22152225
prev = rest;
22162226
rest = next;

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2804,6 +2804,7 @@ _copyColumnDef(const ColumnDef *from)
28042804
COPY_SCALAR_FIELD(is_local);
28052805
COPY_SCALAR_FIELD(is_not_null);
28062806
COPY_SCALAR_FIELD(is_from_type);
2807+
COPY_SCALAR_FIELD(is_from_parent);
28072808
COPY_SCALAR_FIELD(storage);
28082809
COPY_NODE_FIELD(raw_default);
28092810
COPY_NODE_FIELD(cooked_default);

src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2540,6 +2540,7 @@ _equalColumnDef(const ColumnDef *a, const ColumnDef *b)
25402540
COMPARE_SCALAR_FIELD(is_local);
25412541
COMPARE_SCALAR_FIELD(is_not_null);
25422542
COMPARE_SCALAR_FIELD(is_from_type);
2543+
COMPARE_SCALAR_FIELD(is_from_parent);
25432544
COMPARE_SCALAR_FIELD(storage);
25442545
COMPARE_NODE_FIELD(raw_default);
25452546
COMPARE_NODE_FIELD(cooked_default);

src/backend/nodes/makefuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@ makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
494494
n->is_local = true;
495495
n->is_not_null = false;
496496
n->is_from_type = false;
497+
n->is_from_parent = false;
497498
n->storage = 0;
498499
n->raw_default = NULL;
499500
n->cooked_default = NULL;

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2766,6 +2766,7 @@ _outColumnDef(StringInfo str, const ColumnDef *node)
27662766
WRITE_BOOL_FIELD(is_local);
27672767
WRITE_BOOL_FIELD(is_not_null);
27682768
WRITE_BOOL_FIELD(is_from_type);
2769+
WRITE_BOOL_FIELD(is_from_parent);
27692770
WRITE_CHAR_FIELD(storage);
27702771
WRITE_NODE_FIELD(raw_default);
27712772
WRITE_NODE_FIELD(cooked_default);

src/backend/parser/gram.y

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3253,6 +3253,7 @@ columnDef: ColId Typename create_generic_options ColQualList
32533253
n->is_local = true;
32543254
n->is_not_null = false;
32553255
n->is_from_type = false;
3256+
n->is_from_parent = false;
32563257
n->storage = 0;
32573258
n->raw_default = NULL;
32583259
n->cooked_default = NULL;
@@ -3274,6 +3275,7 @@ columnOptions: ColId ColQualList
32743275
n->is_local = true;
32753276
n->is_not_null = false;
32763277
n->is_from_type = false;
3278+
n->is_from_parent = false;
32773279
n->storage = 0;
32783280
n->raw_default = NULL;
32793281
n->cooked_default = NULL;
@@ -3292,6 +3294,7 @@ columnOptions: ColId ColQualList
32923294
n->is_local = true;
32933295
n->is_not_null = false;
32943296
n->is_from_type = false;
3297+
n->is_from_parent = false;
32953298
n->storage = 0;
32963299
n->raw_default = NULL;
32973300
n->cooked_default = NULL;
@@ -11888,6 +11891,7 @@ TableFuncElement: ColId Typename opt_collate_clause
1188811891
n->is_local = true;
1188911892
n->is_not_null = false;
1189011893
n->is_from_type = false;
11894+
n->is_from_parent = false;
1189111895
n->storage = 0;
1189211896
n->raw_default = NULL;
1189311897
n->cooked_default = NULL;

src/backend/parser/parse_utilcmd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
983983
def->is_local = true;
984984
def->is_not_null = attribute->attnotnull;
985985
def->is_from_type = false;
986+
def->is_from_parent = false;
986987
def->storage = 0;
987988
def->raw_default = NULL;
988989
def->cooked_default = NULL;
@@ -1221,6 +1222,7 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
12211222
n->is_local = true;
12221223
n->is_not_null = false;
12231224
n->is_from_type = true;
1225+
n->is_from_parent = false;
12241226
n->storage = 0;
12251227
n->raw_default = NULL;
12261228
n->cooked_default = NULL;

src/include/nodes/parsenodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,7 @@ typedef struct ColumnDef
643643
bool is_local; /* column has local (non-inherited) def'n */
644644
bool is_not_null; /* NOT NULL constraint specified? */
645645
bool is_from_type; /* column definition came from table type */
646+
bool is_from_parent; /* column def came from partition parent */
646647
char storage; /* attstorage setting, or 0 for default */
647648
Node *raw_default; /* default value (untransformed parse tree) */
648649
Node *cooked_default; /* default value (transformed expr tree) */

src/test/regress/expected/create_table.out

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,14 @@ SELECT attname, attislocal, attinhcount FROM pg_attribute
609609
(2 rows)
610610

611611
-- able to specify column default, column constraint, and table constraint
612+
-- first check the "column specified more than once" error
613+
CREATE TABLE part_b PARTITION OF parted (
614+
b NOT NULL,
615+
b DEFAULT 1,
616+
b CHECK (b >= 0),
617+
CONSTRAINT check_a CHECK (length(a) > 0)
618+
) FOR VALUES IN ('b');
619+
ERROR: column "b" specified more than once
612620
CREATE TABLE part_b PARTITION OF parted (
613621
b NOT NULL DEFAULT 1 CHECK (b >= 0),
614622
CONSTRAINT check_a CHECK (length(a) > 0)

src/test/regress/sql/create_table.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,15 @@ SELECT attname, attislocal, attinhcount FROM pg_attribute
569569
ORDER BY attnum;
570570

571571
-- able to specify column default, column constraint, and table constraint
572+
573+
-- first check the "column specified more than once" error
574+
CREATE TABLE part_b PARTITION OF parted (
575+
b NOT NULL,
576+
b DEFAULT 1,
577+
b CHECK (b >= 0),
578+
CONSTRAINT check_a CHECK (length(a) > 0)
579+
) FOR VALUES IN ('b');
580+
572581
CREATE TABLE part_b PARTITION OF parted (
573582
b NOT NULL DEFAULT 1 CHECK (b >= 0),
574583
CONSTRAINT check_a CHECK (length(a) > 0)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy