mirror of https://github.com/citusdata/citus.git
Fix crash caused by some form of ALTER TABLE ADD COLUMN statements. (#7522)
DESCRIPTION: Fixes a crash caused by some form of ALTER TABLE ADD COLUMN statements. When adding multiple columns, if one of the ADD COLUMN statements contains a FOREIGN constraint ommitting the referenced columns in the statement, a SEGFAULT occurs. For instance, the following statement results in a crash: ``` ALTER TABLE lt ADD COLUMN new_col1 bool, ADD COLUMN new_col2 int references rt; ``` Fixes #7520.pull/7534/head^2
parent
0acb5f6e86
commit
fdd658acec
|
@ -3053,11 +3053,15 @@ ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *command,
|
||||||
else if (constraint->contype == CONSTR_FOREIGN)
|
else if (constraint->contype == CONSTR_FOREIGN)
|
||||||
{
|
{
|
||||||
RangeVar *referencedTable = constraint->pktable;
|
RangeVar *referencedTable = constraint->pktable;
|
||||||
char *referencedColumn = strVal(lfirst(list_head(constraint->pk_attrs)));
|
|
||||||
Oid referencedRelationId = RangeVarGetRelid(referencedTable, NoLock, false);
|
Oid referencedRelationId = RangeVarGetRelid(referencedTable, NoLock, false);
|
||||||
|
|
||||||
appendStringInfo(errHint, "FOREIGN KEY (%s) REFERENCES %s(%s)", colName,
|
appendStringInfo(errHint, "FOREIGN KEY (%s) REFERENCES %s", colName,
|
||||||
get_rel_name(referencedRelationId), referencedColumn);
|
get_rel_name(referencedRelationId));
|
||||||
|
|
||||||
|
if (list_length(constraint->pk_attrs) > 0)
|
||||||
|
{
|
||||||
|
AppendColumnNameList(errHint, constraint->pk_attrs);
|
||||||
|
}
|
||||||
|
|
||||||
if (constraint->fk_del_action == FKCONSTR_ACTION_SETNULL)
|
if (constraint->fk_del_action == FKCONSTR_ACTION_SETNULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -121,7 +121,7 @@ AppendAlterTableStmt(StringInfo buf, AlterTableStmt *stmt)
|
||||||
* AppendColumnNameList converts a list of columns into comma separated string format
|
* AppendColumnNameList converts a list of columns into comma separated string format
|
||||||
* (colname_1, colname_2, .., colname_n).
|
* (colname_1, colname_2, .., colname_n).
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
AppendColumnNameList(StringInfo buf, List *columns)
|
AppendColumnNameList(StringInfo buf, List *columns)
|
||||||
{
|
{
|
||||||
appendStringInfoString(buf, " (");
|
appendStringInfoString(buf, " (");
|
||||||
|
|
|
@ -121,6 +121,8 @@ extern void AppendGrantedByInGrant(StringInfo buf, GrantStmt *stmt);
|
||||||
extern void AppendGrantSharedPrefix(StringInfo buf, GrantStmt *stmt);
|
extern void AppendGrantSharedPrefix(StringInfo buf, GrantStmt *stmt);
|
||||||
extern void AppendGrantSharedSuffix(StringInfo buf, GrantStmt *stmt);
|
extern void AppendGrantSharedSuffix(StringInfo buf, GrantStmt *stmt);
|
||||||
|
|
||||||
|
extern void AppendColumnNameList(StringInfo buf, List *columns);
|
||||||
|
|
||||||
/* Common deparser utils */
|
/* Common deparser utils */
|
||||||
|
|
||||||
typedef struct DefElemOptionFormat
|
typedef struct DefElemOptionFormat
|
||||||
|
|
|
@ -44,6 +44,15 @@ ERROR: cannot execute ADD COLUMN command with PRIMARY KEY, UNIQUE, FOREIGN and
|
||||||
DETAIL: Adding a column with a constraint in one command is not supported because all constraints in Citus must have explicit names
|
DETAIL: Adding a column with a constraint in one command is not supported because all constraints in Citus must have explicit names
|
||||||
HINT: You can issue each command separately such as ALTER TABLE referencing ADD COLUMN test_8 data_type; ALTER TABLE referencing ADD CONSTRAINT constraint_name CHECK (check_expression);
|
HINT: You can issue each command separately such as ALTER TABLE referencing ADD COLUMN test_8 data_type; ALTER TABLE referencing ADD CONSTRAINT constraint_name CHECK (check_expression);
|
||||||
ALTER TABLE referencing ADD COLUMN test_8 integer CONSTRAINT check_test_8 CHECK (test_8 > 0);
|
ALTER TABLE referencing ADD COLUMN test_8 integer CONSTRAINT check_test_8 CHECK (test_8 > 0);
|
||||||
|
-- error out properly even if the REFERENCES does not include the column list of the referenced table
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_9 bool, ADD COLUMN test_10 int REFERENCES referenced;
|
||||||
|
ERROR: cannot execute ADD COLUMN command with PRIMARY KEY, UNIQUE, FOREIGN and CHECK constraints
|
||||||
|
DETAIL: Adding a column with a constraint in one command is not supported because all constraints in Citus must have explicit names
|
||||||
|
HINT: You can issue each command separately such as ALTER TABLE referencing ADD COLUMN test_10 data_type; ALTER TABLE referencing ADD CONSTRAINT constraint_name FOREIGN KEY (test_10) REFERENCES referenced;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_9 bool, ADD COLUMN test_10 int REFERENCES referenced(int_col);
|
||||||
|
ERROR: cannot execute ADD COLUMN command with PRIMARY KEY, UNIQUE, FOREIGN and CHECK constraints
|
||||||
|
DETAIL: Adding a column with a constraint in one command is not supported because all constraints in Citus must have explicit names
|
||||||
|
HINT: You can issue each command separately such as ALTER TABLE referencing ADD COLUMN test_10 data_type; ALTER TABLE referencing ADD CONSTRAINT constraint_name FOREIGN KEY (test_10) REFERENCES referenced (int_col );
|
||||||
-- try to add test_6 again, but with IF NOT EXISTS
|
-- try to add test_6 again, but with IF NOT EXISTS
|
||||||
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 text;
|
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 text;
|
||||||
NOTICE: column "test_6" of relation "referencing" already exists, skipping
|
NOTICE: column "test_6" of relation "referencing" already exists, skipping
|
||||||
|
|
|
@ -41,6 +41,10 @@ ALTER TABLE referencing ADD COLUMN "test_\'!7" "simple_!\'custom_type";
|
||||||
ALTER TABLE referencing ADD COLUMN test_8 integer CHECK (test_8 > 0);
|
ALTER TABLE referencing ADD COLUMN test_8 integer CHECK (test_8 > 0);
|
||||||
ALTER TABLE referencing ADD COLUMN test_8 integer CONSTRAINT check_test_8 CHECK (test_8 > 0);
|
ALTER TABLE referencing ADD COLUMN test_8 integer CONSTRAINT check_test_8 CHECK (test_8 > 0);
|
||||||
|
|
||||||
|
-- error out properly even if the REFERENCES does not include the column list of the referenced table
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_9 bool, ADD COLUMN test_10 int REFERENCES referenced;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_9 bool, ADD COLUMN test_10 int REFERENCES referenced(int_col);
|
||||||
|
|
||||||
-- try to add test_6 again, but with IF NOT EXISTS
|
-- try to add test_6 again, but with IF NOT EXISTS
|
||||||
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 text;
|
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 text;
|
||||||
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 integer;
|
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 integer;
|
||||||
|
|
Loading…
Reference in New Issue