mirror of https://github.com/citusdata/citus.git
Deparse ALTER TABLE commands if ADD COLUMN is the only subcommand
And stabilize multi_alter_table_statements.sql.pull/7032/head
parent
6365f47b57
commit
f3cdb6d1bf
|
@ -76,6 +76,8 @@ static void DistributePartitionUsingParent(Oid parentRelationId,
|
||||||
static void ErrorIfMultiLevelPartitioning(Oid parentRelationId, Oid partitionRelationId);
|
static void ErrorIfMultiLevelPartitioning(Oid parentRelationId, Oid partitionRelationId);
|
||||||
static void ErrorIfAttachCitusTableToPgLocalTable(Oid parentRelationId,
|
static void ErrorIfAttachCitusTableToPgLocalTable(Oid parentRelationId,
|
||||||
Oid partitionRelationId);
|
Oid partitionRelationId);
|
||||||
|
static bool DeparserSupportsAlterTableAddColumn(AlterTableStmt *alterTableStatement,
|
||||||
|
AlterTableCmd *addColumnSubCommand);
|
||||||
static bool ATDefinesFKeyBetweenPostgresAndCitusLocalOrRef(
|
static bool ATDefinesFKeyBetweenPostgresAndCitusLocalOrRef(
|
||||||
AlterTableStmt *alterTableStatement);
|
AlterTableStmt *alterTableStatement);
|
||||||
static bool ShouldMarkConnectedRelationsNotAutoConverted(Oid leftRelationId,
|
static bool ShouldMarkConnectedRelationsNotAutoConverted(Oid leftRelationId,
|
||||||
|
@ -1281,6 +1283,7 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
* we also set skip_validation to true to prevent PostgreSQL to verify validity
|
* we also set skip_validation to true to prevent PostgreSQL to verify validity
|
||||||
* of the foreign constraint in master. Validity will be checked in workers
|
* of the foreign constraint in master. Validity will be checked in workers
|
||||||
* anyway.
|
* anyway.
|
||||||
|
* - an ADD COLUMN .. that is the only subcommand in the list OR
|
||||||
* - an ADD COLUMN .. DEFAULT nextval('..') OR
|
* - an ADD COLUMN .. DEFAULT nextval('..') OR
|
||||||
* an ADD COLUMN .. SERIAL pseudo-type OR
|
* an ADD COLUMN .. SERIAL pseudo-type OR
|
||||||
* an ALTER COLUMN .. SET DEFAULT nextval('..'). If there is we set
|
* an ALTER COLUMN .. SET DEFAULT nextval('..'). If there is we set
|
||||||
|
@ -1410,13 +1413,6 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
}
|
}
|
||||||
else if (alterTableType == AT_AddColumn)
|
else if (alterTableType == AT_AddColumn)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* TODO: This code path is nothing beneficial since we do not
|
|
||||||
* support ALTER TABLE %s ADD COLUMN %s [constraint] for foreign keys.
|
|
||||||
* However, the code is kept in case we fix the constraint
|
|
||||||
* creation without a name and allow foreign key creation with the mentioned
|
|
||||||
* command.
|
|
||||||
*/
|
|
||||||
ColumnDef *columnDefinition = (ColumnDef *) command->def;
|
ColumnDef *columnDefinition = (ColumnDef *) command->def;
|
||||||
List *columnConstraints = columnDefinition->constraints;
|
List *columnConstraints = columnDefinition->constraints;
|
||||||
|
|
||||||
|
@ -1440,12 +1436,36 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DeparserSupportsAlterTableAddColumn(alterTableStatement, command))
|
||||||
|
{
|
||||||
|
deparseAT = true;
|
||||||
|
|
||||||
|
constraint = NULL;
|
||||||
|
foreach_ptr(constraint, columnConstraints)
|
||||||
|
{
|
||||||
|
if (ConstrTypeCitusCanDefaultName(constraint->contype))
|
||||||
|
{
|
||||||
|
PrepareAlterTableStmtForConstraint(alterTableStatement,
|
||||||
|
leftRelationId,
|
||||||
|
constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the constraints to the new subcommand because now we
|
||||||
|
* might have assigned names to some of them.
|
||||||
|
*/
|
||||||
|
ColumnDef *newColumnDef = (ColumnDef *) newCmd->def;
|
||||||
|
newColumnDef->constraints = copyObject(columnConstraints);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We check for ADD COLUMN .. DEFAULT expr
|
* We check for ADD COLUMN .. DEFAULT expr
|
||||||
* if expr contains nextval('user_defined_seq')
|
* if expr contains nextval('user_defined_seq')
|
||||||
* we should deparse the statement
|
* we should deparse the statement
|
||||||
*/
|
*/
|
||||||
constraint = NULL;
|
constraint = NULL;
|
||||||
|
int constraintIdx = 0;
|
||||||
foreach_ptr(constraint, columnConstraints)
|
foreach_ptr(constraint, columnConstraints)
|
||||||
{
|
{
|
||||||
if (constraint->contype == CONSTR_DEFAULT)
|
if (constraint->contype == CONSTR_DEFAULT)
|
||||||
|
@ -1461,14 +1481,19 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
deparseAT = true;
|
deparseAT = true;
|
||||||
useInitialDDLCommandString = false;
|
useInitialDDLCommandString = false;
|
||||||
|
|
||||||
/* the new column definition will have no constraint */
|
/* drop the default expression from new subcomand */
|
||||||
ColumnDef *newColDef = copyObject(columnDefinition);
|
ColumnDef *newColumnDef = (ColumnDef *) newCmd->def;
|
||||||
newColDef->constraints = NULL;
|
newColumnDef->constraints =
|
||||||
|
list_delete_nth_cell(newColumnDef->constraints,
|
||||||
newCmd->def = (Node *) newColDef;
|
constraintIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* there can only be one DEFAULT constraint that can be used per column */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constraintIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1652,6 +1677,49 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DeparserSupportsAlterTableAddColumn returns true if it's safe to deparse
|
||||||
|
* the given ALTER TABLE statement that is known to contain given ADD COLUMN
|
||||||
|
* subcommand.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
DeparserSupportsAlterTableAddColumn(AlterTableStmt *alterTableStatement,
|
||||||
|
AlterTableCmd *addColumnSubCommand)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We support deparsing for ADD COLUMN only of it's the only
|
||||||
|
* subcommand.
|
||||||
|
*/
|
||||||
|
if (list_length(alterTableStatement->cmds) == 1 &&
|
||||||
|
alterTableStatement->objtype == OBJECT_TABLE)
|
||||||
|
{
|
||||||
|
ColumnDef *columnDefinition = (ColumnDef *) addColumnSubCommand->def;
|
||||||
|
Constraint *constraint = NULL;
|
||||||
|
foreach_ptr(constraint, columnDefinition->constraints)
|
||||||
|
{
|
||||||
|
if (constraint->contype == CONSTR_CHECK)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Given that we're in the preprocess, any reference to the
|
||||||
|
* column that we're adding would break the deparser. This
|
||||||
|
* can only be the case with CHECK constraints. For this
|
||||||
|
* reason, we skip deparsing the command and fall back to
|
||||||
|
* legacy behavior that we follow for ADD COLUMN subcommands.
|
||||||
|
*
|
||||||
|
* For other constraint types, we prepare the constraint to
|
||||||
|
* make sure that we can deparse it.
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ATDefinesFKeyBetweenPostgresAndCitusLocalOrRef returns true if given
|
* ATDefinesFKeyBetweenPostgresAndCitusLocalOrRef returns true if given
|
||||||
* alter table command defines foreign key between a postgres table and a
|
* alter table command defines foreign key between a postgres table and a
|
||||||
|
@ -3693,13 +3761,6 @@ SetupExecutionModeForAlterTable(Oid relationId, AlterTableCmd *command)
|
||||||
}
|
}
|
||||||
else if (alterTableType == AT_AddColumn)
|
else if (alterTableType == AT_AddColumn)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* TODO: This code path will never be executed since we do not
|
|
||||||
* support foreign constraint creation via
|
|
||||||
* ALTER TABLE %s ADD COLUMN %s [constraint]. However, the code
|
|
||||||
* is kept in case we fix the constraint creation without a name
|
|
||||||
* and allow foreign key creation with the mentioned command.
|
|
||||||
*/
|
|
||||||
ColumnDef *columnDefinition = (ColumnDef *) command->def;
|
ColumnDef *columnDefinition = (ColumnDef *) command->def;
|
||||||
List *columnConstraints = columnDefinition->constraints;
|
List *columnConstraints = columnDefinition->constraints;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "catalog/heap.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
|
@ -31,7 +32,8 @@ static void AppendAlterTableSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *st
|
||||||
static void AppendAlterTableStmt(StringInfo buf, AlterTableStmt *stmt);
|
static void AppendAlterTableStmt(StringInfo buf, AlterTableStmt *stmt);
|
||||||
static void AppendAlterTableCmd(StringInfo buf, AlterTableCmd *alterTableCmd,
|
static void AppendAlterTableCmd(StringInfo buf, AlterTableCmd *alterTableCmd,
|
||||||
AlterTableStmt *stmt);
|
AlterTableStmt *stmt);
|
||||||
static void AppendAlterTableCmdAddColumn(StringInfo buf, AlterTableCmd *alterTableCmd);
|
static void AppendAlterTableCmdAddColumn(StringInfo buf, AlterTableCmd *alterTableCmd,
|
||||||
|
AlterTableStmt *stmt);
|
||||||
static void AppendAlterTableCmdDropConstraint(StringInfo buf,
|
static void AppendAlterTableCmdDropConstraint(StringInfo buf,
|
||||||
AlterTableCmd *alterTableCmd);
|
AlterTableCmd *alterTableCmd);
|
||||||
|
|
||||||
|
@ -144,14 +146,14 @@ AppendColumnNameList(StringInfo buf, List *columns)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AppendAlterTableCmdConstraint builds a string required to create given
|
* AppendAlterTableCmdConstraint builds a string required to create given
|
||||||
* constraint as part of an ADD CONSTRAINT subcommand and appends it to
|
* constraint as part of an ADD CONSTRAINT or an ADD COLUMN subcommand,
|
||||||
* the buf.
|
* and appends it to the buf.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
AppendAlterTableCmdConstraint(StringInfo buf, Constraint *constraint,
|
AppendAlterTableCmdConstraint(StringInfo buf, Constraint *constraint,
|
||||||
AlterTableStmt *stmt, AlterTableType subtype)
|
AlterTableStmt *stmt, AlterTableType subtype)
|
||||||
{
|
{
|
||||||
if (subtype != AT_AddConstraint)
|
if (subtype != AT_AddConstraint && subtype != AT_AddColumn)
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errmsg("Unsupported alter table subtype: %d", (int) subtype)));
|
ereport(ERROR, (errmsg("Unsupported alter table subtype: %d", (int) subtype)));
|
||||||
}
|
}
|
||||||
|
@ -167,6 +169,10 @@ AppendAlterTableCmdConstraint(StringInfo buf, Constraint *constraint,
|
||||||
{
|
{
|
||||||
appendStringInfoString(buf, " ADD CONSTRAINT ");
|
appendStringInfoString(buf, " ADD CONSTRAINT ");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
appendStringInfoString(buf, " CONSTRAINT ");
|
||||||
|
}
|
||||||
|
|
||||||
appendStringInfo(buf, "%s ", quote_identifier(constraint->conname));
|
appendStringInfo(buf, "%s ", quote_identifier(constraint->conname));
|
||||||
|
|
||||||
|
@ -218,7 +224,8 @@ AppendAlterTableCmdConstraint(StringInfo buf, Constraint *constraint,
|
||||||
|
|
||||||
bool first = (defListCell == list_head(constraint->options));
|
bool first = (defListCell == list_head(constraint->options));
|
||||||
appendStringInfo(buf, "%s%s=%s", first ? "" : ",",
|
appendStringInfo(buf, "%s%s=%s", first ? "" : ",",
|
||||||
def->defname, defGetString(def));
|
quote_identifier(def->defname),
|
||||||
|
quote_literal_cstr(defGetString(def)));
|
||||||
}
|
}
|
||||||
|
|
||||||
appendStringInfoChar(buf, ')');
|
appendStringInfoChar(buf, ')');
|
||||||
|
@ -271,6 +278,18 @@ AppendAlterTableCmdConstraint(StringInfo buf, Constraint *constraint,
|
||||||
}
|
}
|
||||||
else if (constraint->contype == CONSTR_CHECK)
|
else if (constraint->contype == CONSTR_CHECK)
|
||||||
{
|
{
|
||||||
|
if (subtype == AT_AddColumn)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Preprocess should've rejected deparsing such an ALTER TABLE
|
||||||
|
* command but be on the safe side.
|
||||||
|
*/
|
||||||
|
ereport(ERROR, (errmsg("cannot add check constraint to column by "
|
||||||
|
"using ADD COLUMN command"),
|
||||||
|
errhint("Consider using ALTER TABLE ... ADD CONSTRAINT "
|
||||||
|
"... CHECK command after adding the column")));
|
||||||
|
}
|
||||||
|
|
||||||
LOCKMODE lockmode = AlterTableGetLockLevel(stmt->cmds);
|
LOCKMODE lockmode = AlterTableGetLockLevel(stmt->cmds);
|
||||||
Oid leftRelationId = AlterTableLookupRelation(stmt, lockmode);
|
Oid leftRelationId = AlterTableLookupRelation(stmt, lockmode);
|
||||||
|
|
||||||
|
@ -416,12 +435,29 @@ AppendAlterTableCmdConstraint(StringInfo buf, Constraint *constraint,
|
||||||
/*
|
/*
|
||||||
* For ADD CONSTRAINT subcommand, FOREIGN KEY and CHECK constraints migth
|
* For ADD CONSTRAINT subcommand, FOREIGN KEY and CHECK constraints migth
|
||||||
* have NOT VALID option.
|
* have NOT VALID option.
|
||||||
|
*
|
||||||
|
* Note that skip_validation might be true for an ADD COLUMN too but this
|
||||||
|
* is not because Postgres supports this but because Citus sets this flag
|
||||||
|
* to true for foreign key constraints added via ADD COLUMN. So we don't
|
||||||
|
* check for skip_validation for ADD COLUMN subcommand.
|
||||||
*/
|
*/
|
||||||
if (subtype == AT_AddConstraint && constraint->skip_validation)
|
if (subtype == AT_AddConstraint && constraint->skip_validation)
|
||||||
{
|
{
|
||||||
appendStringInfoString(buf, " NOT VALID ");
|
appendStringInfoString(buf, " NOT VALID ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (subtype == AT_AddColumn &&
|
||||||
|
(constraint->deferrable || constraint->initdeferred))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* For ADD COLUMN subcommand, the fact that whether given constraint
|
||||||
|
* is deferrable or initially deferred is indicated by another Constraint
|
||||||
|
* object, not via deferrable / initdeferred fields.
|
||||||
|
*/
|
||||||
|
ereport(ERROR, (errmsg("unexpected value set for deferrable/initdeferred "
|
||||||
|
"field for an ADD COLUMN subcommand")));
|
||||||
|
}
|
||||||
|
|
||||||
if (constraint->deferrable)
|
if (constraint->deferrable)
|
||||||
{
|
{
|
||||||
appendStringInfoString(buf, " DEFERRABLE");
|
appendStringInfoString(buf, " DEFERRABLE");
|
||||||
|
@ -446,7 +482,7 @@ AppendAlterTableCmd(StringInfo buf, AlterTableCmd *alterTableCmd, AlterTableStmt
|
||||||
{
|
{
|
||||||
case AT_AddColumn:
|
case AT_AddColumn:
|
||||||
{
|
{
|
||||||
AppendAlterTableCmdAddColumn(buf, alterTableCmd);
|
AppendAlterTableCmdAddColumn(buf, alterTableCmd, stmt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,15 +518,72 @@ AppendAlterTableCmd(StringInfo buf, AlterTableCmd *alterTableCmd, AlterTableStmt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GeneratedWhenStr returns the char representation of given generated_when
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
GeneratedWhenStr(char generatedWhen)
|
||||||
|
{
|
||||||
|
switch (generatedWhen)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
{
|
||||||
|
return "ALWAYS";
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
{
|
||||||
|
return "BY DEFAULT";
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
ereport(ERROR, (errmsg("unrecognized generated_when: %d",
|
||||||
|
generatedWhen)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DeparseRawExprForColumnDefault returns string representation of given
|
||||||
|
* rawExpr based on given column type information.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
DeparseRawExprForColumnDefault(Oid relationId, Oid columnTypeId, int32 columnTypeMod,
|
||||||
|
char *columnName, char attgenerated, Node *rawExpr)
|
||||||
|
{
|
||||||
|
ParseState *pstate = make_parsestate(NULL);
|
||||||
|
Relation relation = RelationIdGetRelation(relationId);
|
||||||
|
AddRangeTableEntryToQueryCompat(pstate, relation);
|
||||||
|
|
||||||
|
Node *defaultExpr = cookDefault(pstate, rawExpr,
|
||||||
|
columnTypeId, columnTypeMod,
|
||||||
|
columnName, attgenerated);
|
||||||
|
|
||||||
|
List *deparseContext = deparse_context_for(get_rel_name(relationId), relationId);
|
||||||
|
|
||||||
|
PushOverrideEmptySearchPath(CurrentMemoryContext);
|
||||||
|
char *defaultExprStr = deparse_expression(defaultExpr, deparseContext, false, false);
|
||||||
|
PopOverrideSearchPath();
|
||||||
|
|
||||||
|
RelationClose(relation);
|
||||||
|
|
||||||
|
return defaultExprStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AppendAlterTableCmd builds and appends to the given buffer an AT_AddColumn command
|
* AppendAlterTableCmd builds and appends to the given buffer an AT_AddColumn command
|
||||||
* from given AlterTableCmd object in the form ADD COLUMN ...
|
* from given AlterTableCmd object in the form ADD COLUMN ...
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
AppendAlterTableCmdAddColumn(StringInfo buf, AlterTableCmd *alterTableCmd)
|
AppendAlterTableCmdAddColumn(StringInfo buf, AlterTableCmd *alterTableCmd,
|
||||||
|
AlterTableStmt *stmt)
|
||||||
{
|
{
|
||||||
Assert(alterTableCmd->subtype == AT_AddColumn);
|
Assert(alterTableCmd->subtype == AT_AddColumn);
|
||||||
|
|
||||||
|
Oid relationId = AlterTableLookupRelation(stmt, NoLock);
|
||||||
|
|
||||||
appendStringInfoString(buf, " ADD COLUMN ");
|
appendStringInfoString(buf, " ADD COLUMN ");
|
||||||
|
|
||||||
if (alterTableCmd->missing_ok)
|
if (alterTableCmd->missing_ok)
|
||||||
|
@ -500,15 +593,6 @@ AppendAlterTableCmdAddColumn(StringInfo buf, AlterTableCmd *alterTableCmd)
|
||||||
|
|
||||||
ColumnDef *columnDefinition = (ColumnDef *) alterTableCmd->def;
|
ColumnDef *columnDefinition = (ColumnDef *) alterTableCmd->def;
|
||||||
|
|
||||||
/*
|
|
||||||
* the way we use the deparser now, constraints are always NULL
|
|
||||||
* adding this check for ColumnDef consistency
|
|
||||||
*/
|
|
||||||
if (columnDefinition->constraints != NULL)
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("Constraints are not supported for AT_AddColumn")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (columnDefinition->colname)
|
if (columnDefinition->colname)
|
||||||
{
|
{
|
||||||
appendStringInfo(buf, "%s ", quote_identifier(columnDefinition->colname));
|
appendStringInfo(buf, "%s ", quote_identifier(columnDefinition->colname));
|
||||||
|
@ -520,23 +604,87 @@ AppendAlterTableCmdAddColumn(StringInfo buf, AlterTableCmd *alterTableCmd)
|
||||||
typenameTypeIdAndMod(NULL, columnDefinition->typeName, &typeOid, &typmod);
|
typenameTypeIdAndMod(NULL, columnDefinition->typeName, &typeOid, &typmod);
|
||||||
appendStringInfo(buf, "%s", format_type_extended(typeOid, typmod,
|
appendStringInfo(buf, "%s", format_type_extended(typeOid, typmod,
|
||||||
formatFlags));
|
formatFlags));
|
||||||
if (columnDefinition->is_not_null)
|
|
||||||
|
if (columnDefinition->compression)
|
||||||
{
|
{
|
||||||
appendStringInfoString(buf, " NOT NULL");
|
appendStringInfo(buf, " COMPRESSION %s",
|
||||||
|
quote_identifier(columnDefinition->compression));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* the way we use the deparser now, collation is never used
|
|
||||||
* since the data type of columns that use sequences for default
|
|
||||||
* are only int,smallint and bigint (never text, varchar, char)
|
|
||||||
* Adding this part only for ColumnDef consistency
|
|
||||||
*/
|
|
||||||
Oid collationOid = GetColumnDefCollation(NULL, columnDefinition, typeOid);
|
Oid collationOid = GetColumnDefCollation(NULL, columnDefinition, typeOid);
|
||||||
if (OidIsValid(collationOid))
|
if (OidIsValid(collationOid))
|
||||||
{
|
{
|
||||||
const char *identifier = FormatCollateBEQualified(collationOid);
|
const char *identifier = FormatCollateBEQualified(collationOid);
|
||||||
appendStringInfo(buf, " COLLATE %s", identifier);
|
appendStringInfo(buf, " COLLATE %s", identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListCell *constraintCell = NULL;
|
||||||
|
foreach(constraintCell, columnDefinition->constraints)
|
||||||
|
{
|
||||||
|
Constraint *constraint = (Constraint *) lfirst(constraintCell);
|
||||||
|
|
||||||
|
if (constraint->contype == CONSTR_NOTNULL)
|
||||||
|
{
|
||||||
|
appendStringInfoString(buf, " NOT NULL");
|
||||||
|
}
|
||||||
|
else if (constraint->contype == CONSTR_DEFAULT)
|
||||||
|
{
|
||||||
|
char attgenerated = '\0';
|
||||||
|
appendStringInfo(buf, " DEFAULT %s",
|
||||||
|
DeparseRawExprForColumnDefault(relationId, typeOid, typmod,
|
||||||
|
columnDefinition->colname,
|
||||||
|
attgenerated,
|
||||||
|
constraint->raw_expr));
|
||||||
|
}
|
||||||
|
else if (constraint->contype == CONSTR_IDENTITY)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Citus doesn't support adding identity columns via ALTER TABLE,
|
||||||
|
* so we don't bother teaching the deparser about them.
|
||||||
|
*/
|
||||||
|
ereport(ERROR, (errmsg("unexpectedly found identity column "
|
||||||
|
"definition in ALTER TABLE command")));
|
||||||
|
}
|
||||||
|
else if (constraint->contype == CONSTR_GENERATED)
|
||||||
|
{
|
||||||
|
char attgenerated = 's';
|
||||||
|
appendStringInfo(buf, " GENERATED %s AS (%s) STORED",
|
||||||
|
GeneratedWhenStr(constraint->generated_when),
|
||||||
|
DeparseRawExprForColumnDefault(relationId, typeOid, typmod,
|
||||||
|
columnDefinition->colname,
|
||||||
|
attgenerated,
|
||||||
|
constraint->raw_expr));
|
||||||
|
}
|
||||||
|
else if (constraint->contype == CONSTR_CHECK ||
|
||||||
|
constraint->contype == CONSTR_PRIMARY ||
|
||||||
|
constraint->contype == CONSTR_UNIQUE ||
|
||||||
|
constraint->contype == CONSTR_EXCLUSION ||
|
||||||
|
constraint->contype == CONSTR_FOREIGN)
|
||||||
|
{
|
||||||
|
AppendAlterTableCmdConstraint(buf, constraint, stmt, AT_AddColumn);
|
||||||
|
}
|
||||||
|
else if (constraint->contype == CONSTR_ATTR_DEFERRABLE)
|
||||||
|
{
|
||||||
|
appendStringInfoString(buf, " DEFERRABLE");
|
||||||
|
}
|
||||||
|
else if (constraint->contype == CONSTR_ATTR_NOT_DEFERRABLE)
|
||||||
|
{
|
||||||
|
appendStringInfoString(buf, " NOT DEFERRABLE");
|
||||||
|
}
|
||||||
|
else if (constraint->contype == CONSTR_ATTR_DEFERRED)
|
||||||
|
{
|
||||||
|
appendStringInfoString(buf, " INITIALLY DEFERRED");
|
||||||
|
}
|
||||||
|
else if (constraint->contype == CONSTR_ATTR_IMMEDIATE)
|
||||||
|
{
|
||||||
|
appendStringInfoString(buf, " INITIALLY IMMEDIATE");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errmsg("unsupported constraint type"),
|
||||||
|
errdetail("constraint type: %d", constraint->contype)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,16 @@ RelayEventExtendNames(Node *parseTree, char *schemaName, uint64 shardId)
|
||||||
RelayEventExtendConstraintAndIndexNames(alterTableStmt, constraint,
|
RelayEventExtendConstraintAndIndexNames(alterTableStmt, constraint,
|
||||||
shardId);
|
shardId);
|
||||||
}
|
}
|
||||||
|
else if (command->subtype == AT_AddColumn)
|
||||||
|
{
|
||||||
|
ColumnDef *columnDefinition = (ColumnDef *) command->def;
|
||||||
|
Constraint *constraint = NULL;
|
||||||
|
foreach_ptr(constraint, columnDefinition->constraints)
|
||||||
|
{
|
||||||
|
RelayEventExtendConstraintAndIndexNames(alterTableStmt,
|
||||||
|
constraint, shardId);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (command->subtype == AT_DropConstraint ||
|
else if (command->subtype == AT_DropConstraint ||
|
||||||
command->subtype == AT_ValidateConstraint)
|
command->subtype == AT_ValidateConstraint)
|
||||||
{
|
{
|
||||||
|
@ -677,13 +687,6 @@ RelayEventExtendNamesForInterShardCommands(Node *parseTree, uint64 leftShardId,
|
||||||
}
|
}
|
||||||
else if (command->subtype == AT_AddColumn)
|
else if (command->subtype == AT_AddColumn)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* TODO: This code path will never be executed since we do not
|
|
||||||
* support foreign constraint creation via
|
|
||||||
* ALTER TABLE %s ADD COLUMN %s [constraint]. However, the code
|
|
||||||
* is kept in case we fix the constraint creation without a name
|
|
||||||
* and allow foreign key creation with the mentioned command.
|
|
||||||
*/
|
|
||||||
ColumnDef *columnDefinition = (ColumnDef *) command->def;
|
ColumnDef *columnDefinition = (ColumnDef *) command->def;
|
||||||
List *columnConstraints = columnDefinition->constraints;
|
List *columnConstraints = columnDefinition->constraints;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
CREATE SCHEMA alter_table_add_column;
|
||||||
|
SET search_path TO alter_table_add_column;
|
||||||
|
SET citus.next_shard_id TO 1830000;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
SET client_min_messages TO NOTICE;
|
||||||
|
CREATE TABLE referenced (int_col integer PRIMARY KEY);
|
||||||
|
CREATE TABLE referencing (text_col text);
|
||||||
|
SELECT create_distributed_table('referenced', null);
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('referencing', null);
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE SCHEMA alter_table_add_column_other_schema;
|
||||||
|
CREATE OR REPLACE FUNCTION alter_table_add_column_other_schema.my_random(numeric)
|
||||||
|
RETURNS numeric AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
RETURN 7 * $1;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
|
CREATE COLLATION caseinsensitive (
|
||||||
|
provider = icu,
|
||||||
|
locale = 'und-u-ks-level2'
|
||||||
|
);
|
||||||
|
CREATE TYPE "simple_!\'custom_type" AS (a integer, b integer);
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_1 integer DEFAULT (alter_table_add_column_other_schema.my_random(7) + random() + 5) NOT NULL CONSTRAINT fkey REFERENCES referenced(int_col) ON UPDATE SET DEFAULT ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_2 integer UNIQUE REFERENCES referenced(int_col) ON UPDATE CASCADE ON DELETE SET DEFAULT NOT DEFERRABLE INITIALLY IMMEDIATE;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_3 integer GENERATED ALWAYS AS (test_1 * alter_table_add_column_other_schema.my_random(1)) STORED UNIQUE REFERENCES referenced(int_col) MATCH FULL;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_4 integer PRIMARY KEY WITH (fillfactor=70) NOT NULL REFERENCES referenced(int_col) MATCH SIMPLE ON UPDATE CASCADE ON DELETE SET DEFAULT;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_5 integer CONSTRAINT unique_c UNIQUE WITH (fillfactor=50);
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_6 text COMPRESSION pglz COLLATE caseinsensitive NOT NULL;
|
||||||
|
ALTER TABLE referencing ADD COLUMN "test_\'!7" "simple_!\'custom_type";
|
||||||
|
-- we give up deparsing ALTER TABLE command if it needs to create a check constraint, and we fallback to legacy behavior
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_8 integer CHECK (test_8 > 0);
|
||||||
|
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_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);
|
||||||
|
-- try to add test_6 again, but with IF NOT EXISTS
|
||||||
|
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 text;
|
||||||
|
NOTICE: column "test_6" of relation "referencing" already exists, skipping
|
||||||
|
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 integer;
|
||||||
|
NOTICE: column "test_6" of relation "referencing" already exists, skipping
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_grouped_fkey_constraints FROM get_grouped_fkey_constraints('alter_table_add_column.referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
is_coordinator | result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t | [{"deferred": true, "deferable": true, "on_delete": "c", "on_update": "d", "match_type": "s", "constraint_names": ["fkey"], "referenced_tables": ["alter_table_add_column.referenced"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing"], "referencing_columns": ["test_1"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "d", "on_update": "c", "match_type": "s", "constraint_names": ["referencing__fkey"], "referenced_tables": ["alter_table_add_column.referenced"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing"], "referencing_columns": ["test_2"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "a", "on_update": "a", "match_type": "f", "constraint_names": ["referencing__fkey1"], "referenced_tables": ["alter_table_add_column.referenced"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing"], "referencing_columns": ["test_3"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "d", "on_update": "c", "match_type": "s", "constraint_names": ["referencing__fkey2"], "referenced_tables": ["alter_table_add_column.referenced"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing"], "referencing_columns": ["test_4"], "referencing_columns_set_null_or_default": null}]
|
||||||
|
f | [{"deferred": true, "deferable": true, "on_delete": "c", "on_update": "d", "match_type": "s", "constraint_names": ["fkey", "fkey_xxxxxxx"], "referenced_tables": ["alter_table_add_column.referenced", "alter_table_add_column.referenced_1830000"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing", "alter_table_add_column.referencing_1830001"], "referencing_columns": ["test_1"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "d", "on_update": "c", "match_type": "s", "constraint_names": ["referencing__fkey", "referencing__fkey_1830001"], "referenced_tables": ["alter_table_add_column.referenced", "alter_table_add_column.referenced_1830000"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing", "alter_table_add_column.referencing_1830001"], "referencing_columns": ["test_2"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "a", "on_update": "a", "match_type": "f", "constraint_names": ["referencing__fkey1", "referencing__fkey1_1830001"], "referenced_tables": ["alter_table_add_column.referenced", "alter_table_add_column.referenced_1830000"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing", "alter_table_add_column.referencing_1830001"], "referencing_columns": ["test_3"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "d", "on_update": "c", "match_type": "s", "constraint_names": ["referencing__fkey2", "referencing__fkey2_1830001"], "referenced_tables": ["alter_table_add_column.referenced", "alter_table_add_column.referenced_1830000"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing", "alter_table_add_column.referencing_1830001"], "referencing_columns": ["test_4"], "referencing_columns_set_null_or_default": null}]
|
||||||
|
f | [{"deferred": true, "deferable": true, "on_delete": "c", "on_update": "d", "match_type": "s", "constraint_names": ["fkey"], "referenced_tables": ["alter_table_add_column.referenced"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing"], "referencing_columns": ["test_1"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "d", "on_update": "c", "match_type": "s", "constraint_names": ["referencing__fkey"], "referenced_tables": ["alter_table_add_column.referenced"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing"], "referencing_columns": ["test_2"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "a", "on_update": "a", "match_type": "f", "constraint_names": ["referencing__fkey1"], "referenced_tables": ["alter_table_add_column.referenced"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing"], "referencing_columns": ["test_3"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "d", "on_update": "c", "match_type": "s", "constraint_names": ["referencing__fkey2"], "referenced_tables": ["alter_table_add_column.referenced"], "referenced_columns": ["int_col"], "referencing_tables": ["alter_table_add_column.referencing"], "referencing_columns": ["test_4"], "referencing_columns_set_null_or_default": null}]
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_index_defs FROM get_index_defs('alter_table_add_column', 'referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
is_coordinator | result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t | [{"indexdefs": ["CREATE UNIQUE INDEX referencing__key ON alter_table_add_column.referencing USING btree (test_2)"], "indexnames": ["referencing__key"]}, {"indexdefs": ["CREATE UNIQUE INDEX referencing__key1 ON alter_table_add_column.referencing USING btree (test_3)"], "indexnames": ["referencing__key1"]}, {"indexdefs": ["CREATE UNIQUE INDEX referencing_pkey ON alter_table_add_column.referencing USING btree (test_4) WITH (fillfactor='70')"], "indexnames": ["referencing_pkey"]}, {"indexdefs": ["CREATE UNIQUE INDEX unique_c ON alter_table_add_column.referencing USING btree (test_5) WITH (fillfactor='50')"], "indexnames": ["unique_c"]}]
|
||||||
|
f | [{"indexdefs": ["CREATE UNIQUE INDEX referencing__key ON alter_table_add_column.referencing USING btree (test_2)", "CREATE UNIQUE INDEX referencing__key_1830001 ON alter_table_add_column.referencing_1830001 USING btree (test_2)"], "indexnames": ["referencing__key", "referencing__key_1830001"]}, {"indexdefs": ["CREATE UNIQUE INDEX referencing__key1 ON alter_table_add_column.referencing USING btree (test_3)", "CREATE UNIQUE INDEX referencing__key1_1830001 ON alter_table_add_column.referencing_1830001 USING btree (test_3)"], "indexnames": ["referencing__key1", "referencing__key1_1830001"]}, {"indexdefs": ["CREATE UNIQUE INDEX referencing_pkey ON alter_table_add_column.referencing USING btree (test_4) WITH (fillfactor='70')", "CREATE UNIQUE INDEX referencing_pkey_1830001 ON alter_table_add_column.referencing_1830001 USING btree (test_4) WITH (fillfactor='70')"], "indexnames": ["referencing_pkey", "referencing_pkey_1830001"]}, {"indexdefs": ["CREATE UNIQUE INDEX unique_c ON alter_table_add_column.referencing USING btree (test_5) WITH (fillfactor='50')", "CREATE UNIQUE INDEX unique_c_1830001 ON alter_table_add_column.referencing_1830001 USING btree (test_5) WITH (fillfactor='50')"], "indexnames": ["unique_c", "unique_c_1830001"]}]
|
||||||
|
f | [{"indexdefs": ["CREATE UNIQUE INDEX referencing__key ON alter_table_add_column.referencing USING btree (test_2)"], "indexnames": ["referencing__key"]}, {"indexdefs": ["CREATE UNIQUE INDEX referencing__key1 ON alter_table_add_column.referencing USING btree (test_3)"], "indexnames": ["referencing__key1"]}, {"indexdefs": ["CREATE UNIQUE INDEX referencing_pkey ON alter_table_add_column.referencing USING btree (test_4) WITH (fillfactor='70')"], "indexnames": ["referencing_pkey"]}, {"indexdefs": ["CREATE UNIQUE INDEX unique_c ON alter_table_add_column.referencing USING btree (test_5) WITH (fillfactor='50')"], "indexnames": ["unique_c"]}]
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_column_defaults FROM get_column_defaults('alter_table_add_column', 'referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
is_coordinator | result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t | [{"column_name": "test_1", "column_default": "(((alter_table_add_column_other_schema.my_random((7)::numeric))::double precision + random()) + (5)::double precision)", "generation_expression": null}, {"column_name": "test_3", "column_default": null, "generation_expression": "((test_1)::numeric * alter_table_add_column_other_schema.my_random((1)::numeric))"}]
|
||||||
|
f | [{"column_name": "test_1", "column_default": "(((alter_table_add_column_other_schema.my_random((7)::numeric))::double precision + random()) + (5)::double precision)", "generation_expression": null}, {"column_name": "test_3", "column_default": null, "generation_expression": "((test_1)::numeric * alter_table_add_column_other_schema.my_random((1)::numeric))"}, {"column_name": "test_3", "column_default": null, "generation_expression": "((test_1)::numeric * alter_table_add_column_other_schema.my_random((1)::numeric))"}]
|
||||||
|
f | [{"column_name": "test_1", "column_default": "(((alter_table_add_column_other_schema.my_random((7)::numeric))::double precision + random()) + (5)::double precision)", "generation_expression": null}, {"column_name": "test_3", "column_default": null, "generation_expression": "((test_1)::numeric * alter_table_add_column_other_schema.my_random((1)::numeric))"}]
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_column_attrs FROM get_column_attrs('alter_table_add_column.referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
is_coordinator | result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t | {"relnames": ["alter_table_add_column.referencing"], "column_attrs": [{"not_null": true, "type_name": "int4", "column_name": "test_1", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "int4", "column_name": "test_2", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "int4", "column_name": "test_3", "collation_name": null, "compression_method": ""}, {"not_null": true, "type_name": "int4", "column_name": "test_4", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "int4", "column_name": "test_5", "collation_name": null, "compression_method": ""}, {"not_null": true, "type_name": "text", "column_name": "test_6", "collation_name": "caseinsensitive", "compression_method": "p"}, {"not_null": false, "type_name": "int4", "column_name": "test_8", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "simple_!\\'custom_type", "column_name": "test_\\'!7", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "text", "column_name": "text_col", "collation_name": "default", "compression_method": ""}]}
|
||||||
|
f | {"relnames": ["alter_table_add_column.referencing"], "column_attrs": [{"not_null": true, "type_name": "int4", "column_name": "test_1", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "int4", "column_name": "test_2", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "int4", "column_name": "test_3", "collation_name": null, "compression_method": ""}, {"not_null": true, "type_name": "int4", "column_name": "test_4", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "int4", "column_name": "test_5", "collation_name": null, "compression_method": ""}, {"not_null": true, "type_name": "text", "column_name": "test_6", "collation_name": "caseinsensitive", "compression_method": "p"}, {"not_null": false, "type_name": "int4", "column_name": "test_8", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "simple_!\\'custom_type", "column_name": "test_\\'!7", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "text", "column_name": "text_col", "collation_name": "default", "compression_method": ""}]}
|
||||||
|
f | {"relnames": ["alter_table_add_column.referencing_1830001", "alter_table_add_column.referencing"], "column_attrs": [{"not_null": true, "type_name": "int4", "column_name": "test_1", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "int4", "column_name": "test_2", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "int4", "column_name": "test_3", "collation_name": null, "compression_method": ""}, {"not_null": true, "type_name": "int4", "column_name": "test_4", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "int4", "column_name": "test_5", "collation_name": null, "compression_method": ""}, {"not_null": true, "type_name": "text", "column_name": "test_6", "collation_name": "caseinsensitive", "compression_method": "p"}, {"not_null": false, "type_name": "int4", "column_name": "test_8", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "simple_!\\'custom_type", "column_name": "test_\\'!7", "collation_name": null, "compression_method": ""}, {"not_null": false, "type_name": "text", "column_name": "text_col", "collation_name": "default", "compression_method": ""}]}
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA alter_table_add_column, alter_table_add_column_other_schema CASCADE;
|
|
@ -494,7 +494,7 @@ CREATE TABLE local_table_4 (
|
||||||
b int references local_table_4(a));
|
b int references local_table_4(a));
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (xxxxx, 'citus_local_tables_test_schema', xxxxx, 'citus_local_tables_test_schema', 'ALTER TABLE citus_local_tables_test_schema.local_table_4 ADD CONSTRAINT local_table_4_a_fkey FOREIGN KEY (a) REFERENCES citus_local_tables_test_schema.citus_local_table_1(a)')
|
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (xxxxx, 'citus_local_tables_test_schema', xxxxx, 'citus_local_tables_test_schema', 'ALTER TABLE citus_local_tables_test_schema.local_table_4 ADD CONSTRAINT local_table_4_a_fkey FOREIGN KEY (a) REFERENCES citus_local_tables_test_schema.citus_local_table_1(a)')
|
||||||
ALTER TABLE citus_local_table_1 ADD COLUMN b int NOT NULL;
|
ALTER TABLE citus_local_table_1 ADD COLUMN b int NOT NULL;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1504014, 'citus_local_tables_test_schema', 'ALTER TABLE citus_local_table_1 ADD COLUMN b int NOT NULL;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1504014, 'citus_local_tables_test_schema', 'ALTER TABLE citus_local_table_1 ADD COLUMN b integer NOT NULL;')
|
||||||
-- show that we added column with NOT NULL
|
-- show that we added column with NOT NULL
|
||||||
SELECT table_name, column_name, is_nullable
|
SELECT table_name, column_name, is_nullable
|
||||||
FROM INFORMATION_SCHEMA.COLUMNS
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
|
|
@ -123,10 +123,16 @@ BEGIN;
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
-- this actually attempts to convert local tables to citus local tables but errors out
|
BEGIN;
|
||||||
-- as citus doesn't support defining foreign keys via add column commands
|
ALTER TABLE local_table_1 ADD COLUMN col_3 INT REFERENCES reference_table_1(col_1);
|
||||||
ALTER TABLE local_table_1 ADD COLUMN col_3 INT REFERENCES reference_table_1(col_1);
|
-- show that we converted all 4 local tables in this schema to citus local tables
|
||||||
ERROR: cannot execute ADD COLUMN command with PRIMARY KEY, UNIQUE, FOREIGN and CHECK constraints
|
SELECT COUNT(*)=4 FROM citus_local_tables_in_schema;
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
BEGIN;
|
BEGIN;
|
||||||
-- define a foreign key so that all 4 local tables become citus local tables
|
-- define a foreign key so that all 4 local tables become citus local tables
|
||||||
ALTER TABLE local_table_1 ADD CONSTRAINT fkey_11 FOREIGN KEY (col_1) REFERENCES reference_table_1(col_1);
|
ALTER TABLE local_table_1 ADD CONSTRAINT fkey_11 FOREIGN KEY (col_1) REFERENCES reference_table_1(col_1);
|
||||||
|
|
|
@ -250,13 +250,10 @@ SELECT create_distributed_table('referencing_table', 'ref_id');
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
ALTER TABLE referencing_table ADD COLUMN referencing int REFERENCES referenced_table(id) ON UPDATE CASCADE;
|
ALTER TABLE referencing_table ADD COLUMN referencing int REFERENCES referenced_table(id) ON UPDATE CASCADE;
|
||||||
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_table ADD COLUMN referencing data_type; ALTER TABLE referencing_table ADD CONSTRAINT constraint_name FOREIGN KEY (referencing) REFERENCES referenced_table(id) ON UPDATE CASCADE;
|
|
||||||
SELECT COUNT(*) FROM table_fkeys_in_workers WHERE relid SIMILAR TO 'fkey_reference_table.%\d{2,}' AND refd_relid SIMILAR TO 'fkey_reference_table.%\d{2,}';
|
SELECT COUNT(*) FROM table_fkeys_in_workers WHERE relid SIMILAR TO 'fkey_reference_table.%\d{2,}' AND refd_relid SIMILAR TO 'fkey_reference_table.%\d{2,}';
|
||||||
count
|
count
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
0
|
8
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
DROP TABLE referencing_table;
|
DROP TABLE referencing_table;
|
||||||
|
|
|
@ -44,20 +44,12 @@ query |citus_nodename_for_nodeid|citus_n
|
||||||
step s3-view-worker:
|
step s3-view-worker:
|
||||||
SELECT query, citus_nodename_for_nodeid(citus_nodeid_for_gpid(global_pid)), citus_nodeport_for_nodeid(citus_nodeid_for_gpid(global_pid)), state, wait_event_type, wait_event, usename, datname FROM citus_stat_activity WHERE query NOT ILIKE ALL(VALUES('%pg_prepared_xacts%'), ('%COMMIT%'), ('%csa_from_one_node%')) AND is_worker_query = true AND backend_type = 'client backend' ORDER BY query DESC;
|
SELECT query, citus_nodename_for_nodeid(citus_nodeid_for_gpid(global_pid)), citus_nodeport_for_nodeid(citus_nodeid_for_gpid(global_pid)), state, wait_event_type, wait_event, usename, datname FROM citus_stat_activity WHERE query NOT ILIKE ALL(VALUES('%pg_prepared_xacts%'), ('%COMMIT%'), ('%csa_from_one_node%')) AND is_worker_query = true AND backend_type = 'client backend' ORDER BY query DESC;
|
||||||
|
|
||||||
query |citus_nodename_for_nodeid|citus_nodeport_for_nodeid|state |wait_event_type|wait_event|usename |datname
|
query |citus_nodename_for_nodeid|citus_nodeport_for_nodeid|state |wait_event_type|wait_event|usename |datname
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
SELECT worker_apply_shard_ddl_command (1300004, 'public', '
|
SELECT worker_apply_shard_ddl_command (1300004, 'public', 'ALTER TABLE test_table ADD COLUMN x integer;')|localhost | 57636|idle in transaction|Client |ClientRead|postgres|regression
|
||||||
ALTER TABLE test_table ADD COLUMN x INT;
|
SELECT worker_apply_shard_ddl_command (1300003, 'public', 'ALTER TABLE test_table ADD COLUMN x integer;')|localhost | 57636|idle in transaction|Client |ClientRead|postgres|regression
|
||||||
')|localhost | 57636|idle in transaction|Client |ClientRead|postgres|regression
|
SELECT worker_apply_shard_ddl_command (1300002, 'public', 'ALTER TABLE test_table ADD COLUMN x integer;')|localhost | 57636|idle in transaction|Client |ClientRead|postgres|regression
|
||||||
SELECT worker_apply_shard_ddl_command (1300003, 'public', '
|
SELECT worker_apply_shard_ddl_command (1300001, 'public', 'ALTER TABLE test_table ADD COLUMN x integer;')|localhost | 57636|idle in transaction|Client |ClientRead|postgres|regression
|
||||||
ALTER TABLE test_table ADD COLUMN x INT;
|
|
||||||
')|localhost | 57636|idle in transaction|Client |ClientRead|postgres|regression
|
|
||||||
SELECT worker_apply_shard_ddl_command (1300002, 'public', '
|
|
||||||
ALTER TABLE test_table ADD COLUMN x INT;
|
|
||||||
')|localhost | 57636|idle in transaction|Client |ClientRead|postgres|regression
|
|
||||||
SELECT worker_apply_shard_ddl_command (1300001, 'public', '
|
|
||||||
ALTER TABLE test_table ADD COLUMN x INT;
|
|
||||||
')|localhost | 57636|idle in transaction|Client |ClientRead|postgres|regression
|
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
step s2-rollback:
|
step s2-rollback:
|
||||||
|
|
|
@ -509,7 +509,7 @@ NOTICE: executing the command locally: DELETE FROM local_commands_test_schema.r
|
||||||
-- add another column to dist_table
|
-- add another column to dist_table
|
||||||
-- note that we execute below DDL locally as well
|
-- note that we execute below DDL locally as well
|
||||||
ALTER TABLE ref_table ADD b int;
|
ALTER TABLE ref_table ADD b int;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500035, 'local_commands_test_schema', 'ALTER TABLE ref_table ADD b int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500035, 'local_commands_test_schema', 'ALTER TABLE ref_table ADD COLUMN b integer;')
|
||||||
-- define self reference
|
-- define self reference
|
||||||
ALTER TABLE ref_table ADD CONSTRAINT fkey2 FOREIGN KEY(b) REFERENCES ref_table(a);
|
ALTER TABLE ref_table ADD CONSTRAINT fkey2 FOREIGN KEY(b) REFERENCES ref_table(a);
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1500035, 'local_commands_test_schema', 1500035, 'local_commands_test_schema', 'ALTER TABLE ref_table ADD CONSTRAINT fkey2 FOREIGN KEY(b) REFERENCES ref_table(a);')
|
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1500035, 'local_commands_test_schema', 1500035, 'local_commands_test_schema', 'ALTER TABLE ref_table ADD CONSTRAINT fkey2 FOREIGN KEY(b) REFERENCES ref_table(a);')
|
||||||
|
@ -629,17 +629,17 @@ NOTICE: executing the command locally: SELECT count(*) AS count FROM local_comm
|
||||||
|
|
||||||
-- execute bunch of DDL & DROP commands succesfully
|
-- execute bunch of DDL & DROP commands succesfully
|
||||||
ALTER TABLE dist_table ADD column c int;
|
ALTER TABLE dist_table ADD column c int;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500100, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500100, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500103, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500103, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500106, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500106, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500109, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500109, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500112, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500112, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500115, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500115, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500118, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500118, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500121, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500121, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500124, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500124, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500127, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500127, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500130, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500130, 'local_commands_test_schema', 'ALTER TABLE dist_table ADD COLUMN c integer;')
|
||||||
ALTER TABLE dist_table ALTER COLUMN c SET NOT NULL;
|
ALTER TABLE dist_table ALTER COLUMN c SET NOT NULL;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500100, 'local_commands_test_schema', 'ALTER TABLE dist_table ALTER COLUMN c SET NOT NULL;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500100, 'local_commands_test_schema', 'ALTER TABLE dist_table ALTER COLUMN c SET NOT NULL;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500103, 'local_commands_test_schema', 'ALTER TABLE dist_table ALTER COLUMN c SET NOT NULL;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500103, 'local_commands_test_schema', 'ALTER TABLE dist_table ALTER COLUMN c SET NOT NULL;')
|
||||||
|
@ -758,17 +758,17 @@ NOTICE: executing the command locally: SELECT count(*) AS count FROM local_comm
|
||||||
|
|
||||||
-- execute bunch of DDL & DROP commands succesfully
|
-- execute bunch of DDL & DROP commands succesfully
|
||||||
ALTER TABLE partitioning_test ADD column c int;
|
ALTER TABLE partitioning_test ADD column c int;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500165, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500165, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500168, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500168, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500171, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500171, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500174, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500174, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500177, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500177, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500180, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500180, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500183, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500183, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500186, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500186, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500189, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500189, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500192, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500192, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500195, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD column c int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1500195, 'local_commands_test_schema', 'ALTER TABLE partitioning_test ADD COLUMN c integer;')
|
||||||
TRUNCATE partitioning_test;
|
TRUNCATE partitioning_test;
|
||||||
NOTICE: executing the command locally: TRUNCATE TABLE local_commands_test_schema.partitioning_test_xxxxx CASCADE
|
NOTICE: executing the command locally: TRUNCATE TABLE local_commands_test_schema.partitioning_test_xxxxx CASCADE
|
||||||
NOTICE: executing the command locally: TRUNCATE TABLE local_commands_test_schema.partitioning_test_xxxxx CASCADE
|
NOTICE: executing the command locally: TRUNCATE TABLE local_commands_test_schema.partitioning_test_xxxxx CASCADE
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
--
|
--
|
||||||
-- MULTI_ALTER_TABLE_STATEMENTS
|
-- MULTI_ALTER_TABLE_STATEMENTS
|
||||||
--
|
--
|
||||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 220000;
|
CREATE SCHEMA multi_alter_table_statements;
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 220000;
|
||||||
-- Check that we can run ALTER TABLE statements on distributed tables.
|
-- Check that we can run ALTER TABLE statements on distributed tables.
|
||||||
-- We set the shardid sequence here so that the shardids in this test
|
-- We set the shardid sequence here so that the shardids in this test
|
||||||
-- aren't affected by changes to the previous tests.
|
-- aren't affected by changes to the previous tests.
|
||||||
|
@ -48,6 +50,8 @@ SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' OR
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 221000;
|
||||||
-- Verify that we can add columns
|
-- Verify that we can add columns
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN float_column FLOAT;
|
ALTER TABLE lineitem_alter ADD COLUMN float_column FLOAT;
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN date_column DATE;
|
ALTER TABLE lineitem_alter ADD COLUMN date_column DATE;
|
||||||
|
@ -93,7 +97,9 @@ ORDER BY attnum;
|
||||||
(27 rows)
|
(27 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 222000;
|
||||||
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
Column | Type | Modifiers
|
Column | Type | Modifiers
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
l_orderkey | bigint | not null
|
l_orderkey | bigint | not null
|
||||||
|
@ -153,7 +159,7 @@ SELECT int_column1, count(*) FROM lineitem_alter GROUP BY int_column1;
|
||||||
|
|
||||||
-- Verify that SET NOT NULL works
|
-- Verify that SET NOT NULL works
|
||||||
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 SET NOT NULL;
|
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 SET NOT NULL;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
Column | Type | Modifiers
|
Column | Type | Modifiers
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
l_orderkey | bigint | not null
|
l_orderkey | bigint | not null
|
||||||
|
@ -191,7 +197,7 @@ DETAIL: Failing row contains (1, 155190, 7706, 1, 17.00, 21168.23, 0.04, 0.02,
|
||||||
END;
|
END;
|
||||||
-- Verify that DROP NOT NULL works
|
-- Verify that DROP NOT NULL works
|
||||||
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 DROP NOT NULL;
|
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 DROP NOT NULL;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
Column | Type | Modifiers
|
Column | Type | Modifiers
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
l_orderkey | bigint | not null
|
l_orderkey | bigint | not null
|
||||||
|
@ -235,7 +241,7 @@ SELECT int_column2, pg_typeof(int_column2), count(*) from lineitem_alter GROUP B
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 SET DATA TYPE FLOAT;
|
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 SET DATA TYPE FLOAT;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
Column | Type | Modifiers
|
Column | Type | Modifiers
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
l_orderkey | bigint | not null
|
l_orderkey | bigint | not null
|
||||||
|
@ -299,7 +305,7 @@ SELECT SUM(l_orderkey) FROM lineitem_alter;
|
||||||
53620791
|
53620791
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
Column | Type | Modifiers
|
Column | Type | Modifiers
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
l_orderkey | bigint | not null
|
l_orderkey | bigint | not null
|
||||||
|
@ -324,7 +330,7 @@ SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineite
|
||||||
-- Verify that we can execute commands with multiple subcommands
|
-- Verify that we can execute commands with multiple subcommands
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN int_column1 INTEGER,
|
ALTER TABLE lineitem_alter ADD COLUMN int_column1 INTEGER,
|
||||||
ADD COLUMN int_column2 INTEGER;
|
ADD COLUMN int_column2 INTEGER;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
Column | Type | Modifiers
|
Column | Type | Modifiers
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
l_orderkey | bigint | not null
|
l_orderkey | bigint | not null
|
||||||
|
@ -353,7 +359,7 @@ ALTER TABLE lineitem_alter ADD COLUMN int_column3 INTEGER,
|
||||||
ERROR: alter table command is currently unsupported
|
ERROR: alter table command is currently unsupported
|
||||||
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP|VALIDATE CONSTRAINT, SET (), RESET (), ENABLE|DISABLE|NO FORCE|FORCE ROW LEVEL SECURITY, ATTACH|DETACH PARTITION and TYPE subcommands are supported.
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP|VALIDATE CONSTRAINT, SET (), RESET (), ENABLE|DISABLE|NO FORCE|FORCE ROW LEVEL SECURITY, ATTACH|DETACH PARTITION and TYPE subcommands are supported.
|
||||||
ALTER TABLE lineitem_alter DROP COLUMN int_column1, DROP COLUMN int_column2;
|
ALTER TABLE lineitem_alter DROP COLUMN int_column1, DROP COLUMN int_column2;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
Column | Type | Modifiers
|
Column | Type | Modifiers
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
l_orderkey | bigint | not null
|
l_orderkey | bigint | not null
|
||||||
|
@ -410,7 +416,7 @@ ALTER TABLE IF EXISTS non_existent_table RENAME COLUMN column1 TO column2;
|
||||||
NOTICE: relation "non_existent_table" does not exist, skipping
|
NOTICE: relation "non_existent_table" does not exist, skipping
|
||||||
-- Verify that none of the failed alter table commands took effect on the master
|
-- Verify that none of the failed alter table commands took effect on the master
|
||||||
-- node
|
-- node
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
Column | Type | Modifiers
|
Column | Type | Modifiers
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
l_orderkey | bigint | not null
|
l_orderkey | bigint | not null
|
||||||
|
@ -461,7 +467,7 @@ BEGIN;
|
||||||
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
|
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN first integer;
|
ALTER TABLE lineitem_alter ADD COLUMN first integer;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
Column | Type | Modifiers
|
Column | Type | Modifiers
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
l_orderkey | bigint | not null
|
l_orderkey | bigint | not null
|
||||||
|
@ -536,8 +542,10 @@ SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
|
||||||
DROP INDEX temp_index_2;
|
DROP INDEX temp_index_2;
|
||||||
-- Add column on only one worker...
|
-- Add column on only one worker...
|
||||||
\c - - - :worker_2_port
|
\c - - - :worker_2_port
|
||||||
ALTER TABLE lineitem_alter_220000 ADD COLUMN first integer;
|
ALTER TABLE multi_alter_table_statements.lineitem_alter_220000 ADD COLUMN first integer;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 223000;
|
||||||
-- and try to add it in a multi-statement block, which fails
|
-- and try to add it in a multi-statement block, which fails
|
||||||
BEGIN;
|
BEGIN;
|
||||||
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
|
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
|
||||||
|
@ -637,7 +645,7 @@ DROP INDEX replica_idx;
|
||||||
ALTER TABLE single_shard_items REPLICA IDENTITY default;
|
ALTER TABLE single_shard_items REPLICA IDENTITY default;
|
||||||
-- Drop the column from the worker...
|
-- Drop the column from the worker...
|
||||||
\c - - - :worker_2_port
|
\c - - - :worker_2_port
|
||||||
ALTER TABLE lineitem_alter_220000 DROP COLUMN first;
|
ALTER TABLE multi_alter_table_statements.lineitem_alter_220000 DROP COLUMN first;
|
||||||
-- Create table to trigger at-xact-end (deferred) failure
|
-- Create table to trigger at-xact-end (deferred) failure
|
||||||
CREATE TABLE ddl_commands (command text UNIQUE DEFERRABLE INITIALLY DEFERRED);
|
CREATE TABLE ddl_commands (command text UNIQUE DEFERRABLE INITIALLY DEFERRED);
|
||||||
-- Use an event trigger to log all DDL event tags in it
|
-- Use an event trigger to log all DDL event tags in it
|
||||||
|
@ -650,6 +658,8 @@ $ldt$ LANGUAGE plpgsql;
|
||||||
RESET citus.enable_metadata_sync;
|
RESET citus.enable_metadata_sync;
|
||||||
CREATE EVENT TRIGGER log_ddl_tag ON ddl_command_end EXECUTE PROCEDURE log_ddl_tag();
|
CREATE EVENT TRIGGER log_ddl_tag ON ddl_command_end EXECUTE PROCEDURE log_ddl_tag();
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 224000;
|
||||||
-- The above trigger will cause failure at transaction end on one placement.
|
-- The above trigger will cause failure at transaction end on one placement.
|
||||||
-- Citus always uses 2PC. 2PC should handle this "best" (no divergence)
|
-- Citus always uses 2PC. 2PC should handle this "best" (no divergence)
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
@ -670,6 +680,8 @@ DROP EVENT TRIGGER log_ddl_tag;
|
||||||
DROP FUNCTION log_ddl_tag();
|
DROP FUNCTION log_ddl_tag();
|
||||||
DROP TABLE ddl_commands;
|
DROP TABLE ddl_commands;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 225000;
|
||||||
-- Distributed SELECTs may appear after ALTER
|
-- Distributed SELECTs may appear after ALTER
|
||||||
BEGIN;
|
BEGIN;
|
||||||
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
|
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
|
||||||
|
@ -724,7 +736,7 @@ SELECT create_distributed_table('test_ab', 'a', 'hash');
|
||||||
INSERT INTO test_ab VALUES (2, 10);
|
INSERT INTO test_ab VALUES (2, 10);
|
||||||
INSERT INTO test_ab VALUES (2, 11);
|
INSERT INTO test_ab VALUES (2, 11);
|
||||||
CREATE UNIQUE INDEX temp_unique_index_1 ON test_ab(a);
|
CREATE UNIQUE INDEX temp_unique_index_1 ON test_ab(a);
|
||||||
ERROR: could not create unique index "temp_unique_index_1_220011"
|
ERROR: could not create unique index "temp_unique_index_1_225006"
|
||||||
DETAIL: Key (a)=(2) is duplicated.
|
DETAIL: Key (a)=(2) is duplicated.
|
||||||
CONTEXT: while executing command on localhost:xxxxx
|
CONTEXT: while executing command on localhost:xxxxx
|
||||||
SELECT shardid FROM pg_dist_shard_placement NATURAL JOIN pg_dist_shard
|
SELECT shardid FROM pg_dist_shard_placement NATURAL JOIN pg_dist_shard
|
||||||
|
@ -775,6 +787,8 @@ ORDER BY attnum;
|
||||||
(30 rows)
|
(30 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 226000;
|
||||||
-- verify that we can rename distributed tables
|
-- verify that we can rename distributed tables
|
||||||
SHOW citus.enable_ddl_propagation;
|
SHOW citus.enable_ddl_propagation;
|
||||||
citus.enable_ddl_propagation
|
citus.enable_ddl_propagation
|
||||||
|
@ -796,24 +810,28 @@ SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_renamed%' ORDER BY re
|
||||||
relname
|
relname
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
lineitem_renamed_220000
|
lineitem_renamed_220000
|
||||||
lineitem_renamed_220001
|
lineitem_renamed_222000
|
||||||
lineitem_renamed_220003
|
lineitem_renamed_222002
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 227000;
|
||||||
-- revert it to original name
|
-- revert it to original name
|
||||||
ALTER TABLE lineitem_renamed RENAME TO lineitem_alter;
|
ALTER TABLE lineitem_renamed RENAME TO lineitem_alter;
|
||||||
-- show rename worked on one worker, too
|
-- show rename worked on one worker, too
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220002' /* failed copy trails */ ORDER BY relname;
|
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_222001' /* failed copy trails */ ORDER BY relname;
|
||||||
relname
|
relname
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
lineitem_alter_220000
|
lineitem_alter_220000
|
||||||
lineitem_alter_220001
|
lineitem_alter_222000
|
||||||
lineitem_alter_220003
|
lineitem_alter_222002
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 228000;
|
||||||
-- verify that we can set and reset storage parameters
|
-- verify that we can set and reset storage parameters
|
||||||
ALTER TABLE lineitem_alter SET(fillfactor=40);
|
ALTER TABLE lineitem_alter SET(fillfactor=40);
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
|
@ -823,15 +841,17 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220002' /* failed copy trails */ ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_222001' /* failed copy trails */ ORDER BY relname;
|
||||||
relname | reloptions
|
relname | reloptions
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
lineitem_alter_220000 | {fillfactor=40}
|
lineitem_alter_220000 | {fillfactor=40}
|
||||||
lineitem_alter_220001 | {fillfactor=40}
|
lineitem_alter_222000 | {fillfactor=40}
|
||||||
lineitem_alter_220003 | {fillfactor=40}
|
lineitem_alter_222002 | {fillfactor=40}
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 229000;
|
||||||
ALTER TABLE lineitem_alter RESET(fillfactor);
|
ALTER TABLE lineitem_alter RESET(fillfactor);
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
relname | reloptions
|
relname | reloptions
|
||||||
|
@ -840,15 +860,17 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220002' /* failed copy trails */ ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_222001' /* failed copy trails */ ORDER BY relname;
|
||||||
relname | reloptions
|
relname | reloptions
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
lineitem_alter_220000 |
|
lineitem_alter_220000 |
|
||||||
lineitem_alter_220001 |
|
lineitem_alter_222000 |
|
||||||
lineitem_alter_220003 |
|
lineitem_alter_222002 |
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 230000;
|
||||||
-- verify that we can rename indexes on distributed tables
|
-- verify that we can rename indexes on distributed tables
|
||||||
CREATE INDEX temp_index_1 ON lineitem_alter(l_linenumber);
|
CREATE INDEX temp_index_1 ON lineitem_alter(l_linenumber);
|
||||||
ALTER INDEX temp_index_1 RENAME TO idx_lineitem_linenumber;
|
ALTER INDEX temp_index_1 RENAME TO idx_lineitem_linenumber;
|
||||||
|
@ -865,11 +887,13 @@ SELECT relname FROM pg_class WHERE relname LIKE 'idx_lineitem_linenumber%' ORDER
|
||||||
relname
|
relname
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
idx_lineitem_linenumber_220000
|
idx_lineitem_linenumber_220000
|
||||||
idx_lineitem_linenumber_220001
|
idx_lineitem_linenumber_222000
|
||||||
idx_lineitem_linenumber_220003
|
idx_lineitem_linenumber_222002
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 231000;
|
||||||
-- now get rid of the index
|
-- now get rid of the index
|
||||||
DROP INDEX idx_lineitem_linenumber;
|
DROP INDEX idx_lineitem_linenumber;
|
||||||
-- verify that we don't intercept DDL commands if propagation is turned off
|
-- verify that we don't intercept DDL commands if propagation is turned off
|
||||||
|
@ -889,9 +913,11 @@ ALTER TABLE lineitem_renamed RENAME TO lineitem_alter;
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN column_only_added_to_master int;
|
ALTER TABLE lineitem_alter ADD COLUMN column_only_added_to_master int;
|
||||||
-- verify newly added column is not present in a worker shard
|
-- verify newly added column is not present in a worker shard
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT column_only_added_to_master FROM lineitem_alter_220000 LIMIT 0;
|
SELECT column_only_added_to_master FROM multi_alter_table_statements.lineitem_alter_220000 LIMIT 0;
|
||||||
ERROR: column "column_only_added_to_master" does not exist
|
ERROR: column "column_only_added_to_master" does not exist
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 232000;
|
||||||
-- ddl propagation flag is reset to default, disable it again
|
-- ddl propagation flag is reset to default, disable it again
|
||||||
SET citus.enable_ddl_propagation to false;
|
SET citus.enable_ddl_propagation to false;
|
||||||
-- following query succeeds since it accesses an previously existing column
|
-- following query succeeds since it accesses an previously existing column
|
||||||
|
@ -933,6 +959,8 @@ SELECT indexname, tablename FROM pg_indexes WHERE tablename like 'lineitem_alte
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 233000;
|
||||||
-- verify alter table and drop sequence in the same transaction does not cause deadlock
|
-- verify alter table and drop sequence in the same transaction does not cause deadlock
|
||||||
SET citus.shard_count TO 4;
|
SET citus.shard_count TO 4;
|
||||||
SET citus.shard_replication_factor TO 2;
|
SET citus.shard_replication_factor TO 2;
|
||||||
|
@ -967,7 +995,7 @@ SELECT create_distributed_table('trigger_table', 'id');
|
||||||
-- first set a trigger on a shard
|
-- first set a trigger on a shard
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SET citus.enable_metadata_sync TO OFF;
|
SET citus.enable_metadata_sync TO OFF;
|
||||||
CREATE FUNCTION update_value() RETURNS trigger AS $up$
|
CREATE OR REPLACE FUNCTION update_value() RETURNS trigger AS $up$
|
||||||
BEGIN
|
BEGIN
|
||||||
NEW.value := 'trigger enabled';
|
NEW.value := 'trigger enabled';
|
||||||
RETURN NEW;
|
RETURN NEW;
|
||||||
|
@ -975,9 +1003,11 @@ CREATE FUNCTION update_value() RETURNS trigger AS $up$
|
||||||
$up$ LANGUAGE plpgsql;
|
$up$ LANGUAGE plpgsql;
|
||||||
RESET citus.enable_metadata_sync;
|
RESET citus.enable_metadata_sync;
|
||||||
CREATE TRIGGER update_value
|
CREATE TRIGGER update_value
|
||||||
BEFORE INSERT ON trigger_table_220017
|
BEFORE INSERT ON multi_alter_table_statements.trigger_table_233004
|
||||||
FOR EACH ROW EXECUTE PROCEDURE update_value();
|
FOR EACH ROW EXECUTE PROCEDURE update_value();
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 234000;
|
||||||
INSERT INTO trigger_table VALUES (1, 'trigger disabled');
|
INSERT INTO trigger_table VALUES (1, 'trigger disabled');
|
||||||
SELECT value, count(*) FROM trigger_table GROUP BY value ORDER BY value;
|
SELECT value, count(*) FROM trigger_table GROUP BY value ORDER BY value;
|
||||||
value | count
|
value | count
|
||||||
|
@ -1019,37 +1049,41 @@ DROP TABLESPACE super_fast_ssd;
|
||||||
SET citus.enable_ddl_propagation to true;
|
SET citus.enable_ddl_propagation to true;
|
||||||
CREATE USER alter_table_owner WITH LOGIN;
|
CREATE USER alter_table_owner WITH LOGIN;
|
||||||
GRANT USAGE ON SCHEMA public TO alter_table_owner;
|
GRANT USAGE ON SCHEMA public TO alter_table_owner;
|
||||||
|
GRANT USAGE ON SCHEMA multi_alter_table_statements TO alter_table_owner;
|
||||||
\c - alter_table_owner - :master_port
|
\c - alter_table_owner - :master_port
|
||||||
-- should not be able to access table without permission
|
-- should not be able to access table without permission
|
||||||
SELECT count(*) FROM lineitem_alter;
|
SELECT count(*) FROM multi_alter_table_statements.lineitem_alter;
|
||||||
ERROR: permission denied for table lineitem_alter
|
ERROR: permission denied for table lineitem_alter
|
||||||
-- should not be able to drop the table as non table owner
|
-- should not be able to drop the table as non table owner
|
||||||
DROP TABLE lineitem_alter;
|
DROP TABLE multi_alter_table_statements.lineitem_alter;
|
||||||
ERROR: must be owner of table lineitem_alter
|
ERROR: must be owner of table lineitem_alter
|
||||||
\c - postgres - :master_port
|
\c - postgres - :master_port
|
||||||
ALTER TABLE lineitem_alter OWNER TO alter_table_owner;
|
ALTER TABLE multi_alter_table_statements.lineitem_alter OWNER TO alter_table_owner;
|
||||||
\c - alter_table_owner - :master_port
|
\c - alter_table_owner - :master_port
|
||||||
-- should be able to query the table as table owner
|
-- should be able to query the table as table owner
|
||||||
SELECT count(*) FROM lineitem_alter;
|
SELECT count(*) FROM multi_alter_table_statements.lineitem_alter;
|
||||||
count
|
count
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
18000
|
18000
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- should be able to drop the table as table owner
|
-- should be able to drop the table as table owner
|
||||||
DROP TABLE lineitem_alter;
|
DROP TABLE multi_alter_table_statements.lineitem_alter;
|
||||||
-- check that nothing's left over on workers, other than the leftover shard created
|
-- check that nothing's left over on workers, other than the leftover shard created
|
||||||
-- during the unsuccessful COPY
|
-- during the unsuccessful COPY
|
||||||
\c - postgres - :worker_1_port
|
\c - postgres - :worker_1_port
|
||||||
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%';
|
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%';
|
||||||
relname
|
relname
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
lineitem_alter_220002
|
lineitem_alter_222001
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 235000;
|
||||||
-- drop the roles created
|
-- drop the roles created
|
||||||
REVOKE ALL ON SCHEMA PUBLIC FROM alter_table_owner;
|
REVOKE ALL ON SCHEMA PUBLIC FROM alter_table_owner;
|
||||||
|
REVOKE ALL ON SCHEMA multi_alter_table_statements FROM alter_table_owner;
|
||||||
DROP ROLE alter_table_owner;
|
DROP ROLE alter_table_owner;
|
||||||
-- Test alter table with drop table in the same transaction
|
-- Test alter table with drop table in the same transaction
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
@ -1071,6 +1105,8 @@ SELECT relname FROM pg_class WHERE relname LIKE 'test_table_1%';
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 236000;
|
||||||
-- verify logged info is propagated to workers when distributing the table
|
-- verify logged info is propagated to workers when distributing the table
|
||||||
CREATE TABLE logged_test(id int);
|
CREATE TABLE logged_test(id int);
|
||||||
ALTER TABLE logged_test SET UNLOGGED;
|
ALTER TABLE logged_test SET UNLOGGED;
|
||||||
|
@ -1084,13 +1120,15 @@ SELECT create_distributed_table('logged_test', 'id');
|
||||||
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
||||||
relname | logged_info
|
relname | logged_info
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
logged_test_220022 | unlogged
|
logged_test_236000 | unlogged
|
||||||
logged_test_220023 | unlogged
|
logged_test_236001 | unlogged
|
||||||
logged_test_220024 | unlogged
|
logged_test_236002 | unlogged
|
||||||
logged_test_220025 | unlogged
|
logged_test_236003 | unlogged
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 237000;
|
||||||
-- verify SET LOGGED/UNLOGGED works after distributing the table
|
-- verify SET LOGGED/UNLOGGED works after distributing the table
|
||||||
ALTER TABLE logged_test SET LOGGED;
|
ALTER TABLE logged_test SET LOGGED;
|
||||||
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test*' ORDER BY relname;
|
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test*' ORDER BY relname;
|
||||||
|
@ -1103,13 +1141,15 @@ SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logg
|
||||||
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
||||||
relname | logged_info
|
relname | logged_info
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
logged_test_220022 | logged
|
logged_test_236000 | logged
|
||||||
logged_test_220023 | logged
|
logged_test_236001 | logged
|
||||||
logged_test_220024 | logged
|
logged_test_236002 | logged
|
||||||
logged_test_220025 | logged
|
logged_test_236003 | logged
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 238000;
|
||||||
ALTER TABLE logged_test SET UNLOGGED;
|
ALTER TABLE logged_test SET UNLOGGED;
|
||||||
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test*' ORDER BY relname;
|
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test*' ORDER BY relname;
|
||||||
relname | logged_info
|
relname | logged_info
|
||||||
|
@ -1121,13 +1161,15 @@ SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logg
|
||||||
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
||||||
relname | logged_info
|
relname | logged_info
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
logged_test_220022 | unlogged
|
logged_test_236000 | unlogged
|
||||||
logged_test_220023 | unlogged
|
logged_test_236001 | unlogged
|
||||||
logged_test_220024 | unlogged
|
logged_test_236002 | unlogged
|
||||||
logged_test_220025 | unlogged
|
logged_test_236003 | unlogged
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 239000;
|
||||||
DROP TABLE logged_test;
|
DROP TABLE logged_test;
|
||||||
-- Test WITH options on a normal simple hash-distributed table
|
-- Test WITH options on a normal simple hash-distributed table
|
||||||
CREATE TABLE hash_dist(id bigint primary key, f1 text) WITH (fillfactor=40);
|
CREATE TABLE hash_dist(id bigint primary key, f1 text) WITH (fillfactor=40);
|
||||||
|
@ -1148,13 +1190,15 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist';
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relkind = 'r' AND relname LIKE 'hash_dist_%' ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relkind = 'r' AND relname LIKE 'hash_dist_%' ORDER BY relname;
|
||||||
relname | reloptions
|
relname | reloptions
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
hash_dist_220026 | {fillfactor=40}
|
hash_dist_239000 | {fillfactor=40}
|
||||||
hash_dist_220027 | {fillfactor=40}
|
hash_dist_239001 | {fillfactor=40}
|
||||||
hash_dist_220028 | {fillfactor=40}
|
hash_dist_239002 | {fillfactor=40}
|
||||||
hash_dist_220029 | {fillfactor=40}
|
hash_dist_239003 | {fillfactor=40}
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 240000;
|
||||||
-- verify that we can set and reset index storage parameters
|
-- verify that we can set and reset index storage parameters
|
||||||
ALTER INDEX hash_dist_pkey SET(fillfactor=40);
|
ALTER INDEX hash_dist_pkey SET(fillfactor=40);
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
|
@ -1167,13 +1211,15 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey_%' ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey_%' ORDER BY relname;
|
||||||
relname | reloptions
|
relname | reloptions
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
hash_dist_pkey_220026 | {fillfactor=40}
|
hash_dist_pkey_239000 | {fillfactor=40}
|
||||||
hash_dist_pkey_220027 | {fillfactor=40}
|
hash_dist_pkey_239001 | {fillfactor=40}
|
||||||
hash_dist_pkey_220028 | {fillfactor=40}
|
hash_dist_pkey_239002 | {fillfactor=40}
|
||||||
hash_dist_pkey_220029 | {fillfactor=40}
|
hash_dist_pkey_239003 | {fillfactor=40}
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 241000;
|
||||||
ALTER INDEX hash_dist_pkey RESET(fillfactor);
|
ALTER INDEX hash_dist_pkey RESET(fillfactor);
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
relname | reloptions
|
relname | reloptions
|
||||||
|
@ -1185,13 +1231,15 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey_%' ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey_%' ORDER BY relname;
|
||||||
relname | reloptions
|
relname | reloptions
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
hash_dist_pkey_220026 |
|
hash_dist_pkey_239000 |
|
||||||
hash_dist_pkey_220027 |
|
hash_dist_pkey_239001 |
|
||||||
hash_dist_pkey_220028 |
|
hash_dist_pkey_239002 |
|
||||||
hash_dist_pkey_220029 |
|
hash_dist_pkey_239003 |
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 242000;
|
||||||
-- verify error message on ALTER INDEX, SET TABLESPACE is unsupported
|
-- verify error message on ALTER INDEX, SET TABLESPACE is unsupported
|
||||||
ALTER INDEX hash_dist_pkey SET TABLESPACE foo;
|
ALTER INDEX hash_dist_pkey SET TABLESPACE foo;
|
||||||
ERROR: alter index ... set tablespace ... is currently unsupported
|
ERROR: alter index ... set tablespace ... is currently unsupported
|
||||||
|
@ -1209,13 +1257,15 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'another_index';
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'another_index_%' ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'another_index_%' ORDER BY relname;
|
||||||
relname | reloptions
|
relname | reloptions
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
another_index_220026 | {fillfactor=50}
|
another_index_239000 | {fillfactor=50}
|
||||||
another_index_220027 | {fillfactor=50}
|
another_index_239001 | {fillfactor=50}
|
||||||
another_index_220028 | {fillfactor=50}
|
another_index_239002 | {fillfactor=50}
|
||||||
another_index_220029 | {fillfactor=50}
|
another_index_239003 | {fillfactor=50}
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 243000;
|
||||||
-- get rid of the index
|
-- get rid of the index
|
||||||
DROP INDEX another_index;
|
DROP INDEX another_index;
|
||||||
-- check if we fail properly when a column with un-supported constraint is added
|
-- check if we fail properly when a column with un-supported constraint is added
|
||||||
|
@ -1246,15 +1296,24 @@ SELECT create_reference_table('reference_table');
|
||||||
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
ALTER TABLE test_table_1 ADD COLUMN test_col int REFERENCES reference_table(i) ON DELETE CASCADE;
|
ALTER TABLE test_table_1 ADD COLUMN test_col_1 int REFERENCES reference_table(i) ON DELETE CASCADE;
|
||||||
ERROR: cannot execute ADD COLUMN command with PRIMARY KEY, UNIQUE, FOREIGN and CHECK constraints
|
ALTER TABLE test_table_1 ADD COLUMN test_col_2 int REFERENCES reference_table(i) ON DELETE CASCADE ON UPDATE SET NULL;
|
||||||
DETAIL: Adding a column with a constraint in one command is not supported because all constraints in Citus must have explicit names
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
HINT: You can issue each command separately such as ALTER TABLE test_table_1 ADD COLUMN test_col data_type; ALTER TABLE test_table_1 ADD CONSTRAINT constraint_name FOREIGN KEY (test_col) REFERENCES reference_table(i) ON DELETE CASCADE;
|
$$SELECT get_grouped_fkey_constraints FROM get_grouped_fkey_constraints('multi_alter_table_statements.test_table_1')$$
|
||||||
ALTER TABLE test_table_1 ADD COLUMN test_col int REFERENCES reference_table(i) ON DELETE CASCADE ON UPDATE SET NULL;
|
)
|
||||||
ERROR: cannot execute ADD COLUMN command with PRIMARY KEY, UNIQUE, FOREIGN and CHECK constraints
|
JOIN pg_dist_node USING (nodeid)
|
||||||
DETAIL: Adding a column with a constraint in one command is not supported because all constraints in Citus must have explicit names
|
ORDER BY is_coordinator DESC, result;
|
||||||
HINT: You can issue each command separately such as ALTER TABLE test_table_1 ADD COLUMN test_col data_type; ALTER TABLE test_table_1 ADD CONSTRAINT constraint_name FOREIGN KEY (test_col) REFERENCES reference_table(i) ON DELETE CASCADE ON UPDATE SET NULL;
|
is_coordinator | result
|
||||||
DROP TABLE reference_table;
|
---------------------------------------------------------------------
|
||||||
|
t | [{"deferred": false, "deferable": false, "on_delete": "c", "on_update": "a", "match_type": "s", "constraint_names": ["test_table_1__fkey"], "referenced_tables": ["multi_alter_table_statements.reference_table"], "referenced_columns": ["i"], "referencing_tables": ["multi_alter_table_statements.test_table_1"], "referencing_columns": ["test_col_1"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "c", "on_update": "n", "match_type": "s", "constraint_names": ["test_table_1__fkey1"], "referenced_tables": ["multi_alter_table_statements.reference_table"], "referenced_columns": ["i"], "referencing_tables": ["multi_alter_table_statements.test_table_1"], "referencing_columns": ["test_col_2"], "referencing_columns_set_null_or_default": null}]
|
||||||
|
f | [{"deferred": false, "deferable": false, "on_delete": "c", "on_update": "a", "match_type": "s", "constraint_names": ["test_table_1__fkey", "test_table_1__fkey_243000", "test_table_1__fkey_243002"], "referenced_tables": ["multi_alter_table_statements.reference_table", "multi_alter_table_statements.reference_table_243004", "multi_alter_table_statements.reference_table_243004"], "referenced_columns": ["i"], "referencing_tables": ["multi_alter_table_statements.test_table_1", "multi_alter_table_statements.test_table_1_243000", "multi_alter_table_statements.test_table_1_243002"], "referencing_columns": ["test_col_1"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "c", "on_update": "n", "match_type": "s", "constraint_names": ["test_table_1__fkey1", "test_table_1__fkey1_243000", "test_table_1__fkey1_243002"], "referenced_tables": ["multi_alter_table_statements.reference_table", "multi_alter_table_statements.reference_table_243004", "multi_alter_table_statements.reference_table_243004"], "referenced_columns": ["i"], "referencing_tables": ["multi_alter_table_statements.test_table_1", "multi_alter_table_statements.test_table_1_243000", "multi_alter_table_statements.test_table_1_243002"], "referencing_columns": ["test_col_2"], "referencing_columns_set_null_or_default": null}]
|
||||||
|
f | [{"deferred": false, "deferable": false, "on_delete": "c", "on_update": "a", "match_type": "s", "constraint_names": ["test_table_1__fkey", "test_table_1__fkey_243001", "test_table_1__fkey_243003"], "referenced_tables": ["multi_alter_table_statements.reference_table", "multi_alter_table_statements.reference_table_243004", "multi_alter_table_statements.reference_table_243004"], "referenced_columns": ["i"], "referencing_tables": ["multi_alter_table_statements.test_table_1", "multi_alter_table_statements.test_table_1_243001", "multi_alter_table_statements.test_table_1_243003"], "referencing_columns": ["test_col_1"], "referencing_columns_set_null_or_default": null}, {"deferred": false, "deferable": false, "on_delete": "c", "on_update": "n", "match_type": "s", "constraint_names": ["test_table_1__fkey1", "test_table_1__fkey1_243001", "test_table_1__fkey1_243003"], "referenced_tables": ["multi_alter_table_statements.reference_table", "multi_alter_table_statements.reference_table_243004", "multi_alter_table_statements.reference_table_243004"], "referenced_columns": ["i"], "referencing_tables": ["multi_alter_table_statements.test_table_1", "multi_alter_table_statements.test_table_1_243001", "multi_alter_table_statements.test_table_1_243003"], "referencing_columns": ["test_col_2"], "referencing_columns_set_null_or_default": null}]
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
SET LOCAL client_min_messages TO WARNING;
|
||||||
|
DROP TABLE reference_table CASCADE;
|
||||||
|
COMMIT;
|
||||||
CREATE TABLE referenced_table(i int UNIQUE);
|
CREATE TABLE referenced_table(i int UNIQUE);
|
||||||
SELECT create_distributed_table('referenced_table', 'i');
|
SELECT create_distributed_table('referenced_table', 'i');
|
||||||
create_distributed_table
|
create_distributed_table
|
||||||
|
@ -1262,7 +1321,7 @@ SELECT create_distributed_table('referenced_table', 'i');
|
||||||
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
ALTER TABLE test_table_1 ADD COLUMN test_col int REFERENCES referenced_table(i);
|
ALTER TABLE test_table_1 ADD COLUMN test_col_3 int REFERENCES referenced_table(i);
|
||||||
ERROR: cannot create foreign key constraint
|
ERROR: cannot create foreign key constraint
|
||||||
DETAIL: Foreign keys are supported in two cases, either in between two colocated tables including partition column in the same ordinal in the both tables or from distributed to reference tables
|
DETAIL: Foreign keys are supported in two cases, either in between two colocated tables including partition column in the same ordinal in the both tables or from distributed to reference tables
|
||||||
DROP TABLE referenced_table, test_table_1;
|
DROP TABLE referenced_table, test_table_1;
|
||||||
|
@ -1290,8 +1349,7 @@ SELECT pg_identify_object_as_address(classid, objid, objsubid) from pg_catalog.p
|
||||||
(schema,{test_schema_for_sequence_propagation},{})
|
(schema,{test_schema_for_sequence_propagation},{})
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
DROP SCHEMA test_schema_for_sequence_propagation CASCADE;
|
DROP SCHEMA test_schema_for_sequence_propagation CASCADE;
|
||||||
NOTICE: drop cascades to 2 other objects
|
|
||||||
DETAIL: drop cascades to sequence test_schema_for_sequence_propagation.seq_10
|
|
||||||
drop cascades to default value for column x of table table_without_sequence
|
|
||||||
DROP TABLE table_without_sequence;
|
DROP TABLE table_without_sequence;
|
||||||
|
DROP SCHEMA multi_alter_table_statements CASCADE;
|
||||||
|
|
|
@ -89,9 +89,9 @@ NOTICE: executing the command locally: INSERT INTO multi_row_router_insert.citu
|
||||||
INSERT INTO citus_local_table (a) VALUES (12), (13);
|
INSERT INTO citus_local_table (a) VALUES (12), (13);
|
||||||
NOTICE: executing the command locally: INSERT INTO multi_row_router_insert.citus_local_table_1511001 AS citus_table_alias (a, b) VALUES (12,100), (13,100)
|
NOTICE: executing the command locally: INSERT INTO multi_row_router_insert.citus_local_table_1511001 AS citus_table_alias (a, b) VALUES (12,100), (13,100)
|
||||||
ALTER TABLE citus_local_table ADD COLUMN c INT DEFAULT to_number('5', '91');
|
ALTER TABLE citus_local_table ADD COLUMN c INT DEFAULT to_number('5', '91');
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1511001, 'multi_row_router_insert', 'ALTER TABLE citus_local_table ADD COLUMN c INT DEFAULT to_number(''5'', ''91'');')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1511001, 'multi_row_router_insert', 'ALTER TABLE citus_local_table ADD COLUMN c integer DEFAULT to_number(''5''::text, ''91''::text);')
|
||||||
ALTER TABLE citus_local_table ADD COLUMN d INT;
|
ALTER TABLE citus_local_table ADD COLUMN d INT;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1511001, 'multi_row_router_insert', 'ALTER TABLE citus_local_table ADD COLUMN d INT;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1511001, 'multi_row_router_insert', 'ALTER TABLE citus_local_table ADD COLUMN d integer;')
|
||||||
INSERT INTO citus_local_table (d, a, b) VALUES (13, 14, 15), (16, 17, 18), (19, 20, 21);
|
INSERT INTO citus_local_table (d, a, b) VALUES (13, 14, 15), (16, 17, 18), (19, 20, 21);
|
||||||
NOTICE: executing the command locally: INSERT INTO multi_row_router_insert.citus_local_table_1511001 AS citus_table_alias (a, b, c, d) VALUES (14,15,5,13), (17,18,5,16), (20,21,5,19)
|
NOTICE: executing the command locally: INSERT INTO multi_row_router_insert.citus_local_table_1511001 AS citus_table_alias (a, b, c, d) VALUES (14,15,5,13), (17,18,5,16), (20,21,5,19)
|
||||||
SELECT * FROM citus_local_table ORDER BY 1,2,3,4;
|
SELECT * FROM citus_local_table ORDER BY 1,2,3,4;
|
||||||
|
|
|
@ -167,3 +167,135 @@ BEGIN
|
||||||
EXECUTE 'SELECT COUNT(*) FROM pg_catalog.pg_dist_cleanup' INTO record_count;
|
EXECUTE 'SELECT COUNT(*) FROM pg_catalog.pg_dist_cleanup' INTO record_count;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END$$ LANGUAGE plpgsql;
|
END$$ LANGUAGE plpgsql;
|
||||||
|
-- Returns the foreign keys where the referencing relation's name starts with
|
||||||
|
-- given prefix.
|
||||||
|
--
|
||||||
|
-- Foreign keys are groupped by their configurations and then the constraint name,
|
||||||
|
-- referencing table, and referenced table for each distinct configuration are
|
||||||
|
-- aggregated into arrays.
|
||||||
|
CREATE OR REPLACE FUNCTION get_grouped_fkey_constraints(referencing_relname_prefix text)
|
||||||
|
RETURNS jsonb AS $func$
|
||||||
|
DECLARE
|
||||||
|
confdelsetcols_column_ref text;
|
||||||
|
get_grouped_fkey_constraints_query text;
|
||||||
|
result jsonb;
|
||||||
|
BEGIN
|
||||||
|
-- Read confdelsetcols as null if no such column exists.
|
||||||
|
-- This can only be the case for PG versions < 15.
|
||||||
|
IF EXISTS (SELECT 1 FROM pg_attribute WHERE attrelid = 'pg_constraint'::regclass AND attname='confdelsetcols')
|
||||||
|
THEN
|
||||||
|
confdelsetcols_column_ref := '(SELECT array_agg(attname ORDER BY attnum) FROM pg_attribute WHERE attrelid = conrelid AND attnum = ANY(confdelsetcols))';
|
||||||
|
ELSE
|
||||||
|
confdelsetcols_column_ref := '(SELECT null::smallint[])';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXECUTE format(
|
||||||
|
$$
|
||||||
|
SELECT jsonb_agg(to_jsonb(q1.*) ORDER BY q1.constraint_names) AS fkeys_with_different_config FROM (
|
||||||
|
SELECT array_agg(constraint_name ORDER BY constraint_oid) AS constraint_names,
|
||||||
|
array_agg(referencing_table::regclass::text ORDER BY constraint_oid) AS referencing_tables,
|
||||||
|
array_agg(referenced_table::regclass::text ORDER BY constraint_oid) AS referenced_tables,
|
||||||
|
referencing_columns, referenced_columns, deferable, deferred, on_update, on_delete, match_type, referencing_columns_set_null_or_default
|
||||||
|
FROM (
|
||||||
|
SELECT
|
||||||
|
oid AS constraint_oid,
|
||||||
|
conname AS constraint_name,
|
||||||
|
conrelid AS referencing_table,
|
||||||
|
(SELECT array_agg(attname ORDER BY attnum) FROM pg_attribute WHERE attrelid = conrelid AND attnum = ANY(conkey)) AS referencing_columns,
|
||||||
|
confrelid AS referenced_table,
|
||||||
|
(SELECT array_agg(attname ORDER BY attnum) FROM pg_attribute WHERE attrelid = confrelid AND attnum = ANY(confkey)) AS referenced_columns,
|
||||||
|
condeferrable AS deferable,
|
||||||
|
condeferred AS deferred,
|
||||||
|
confupdtype AS on_update,
|
||||||
|
confdeltype AS on_delete,
|
||||||
|
confmatchtype AS match_type,
|
||||||
|
%2$s AS referencing_columns_set_null_or_default
|
||||||
|
FROM pg_constraint WHERE starts_with(conrelid::regclass::text, '%1$s') AND contype = 'f'
|
||||||
|
) q2
|
||||||
|
GROUP BY referencing_columns, referenced_columns, deferable, deferred, on_update, on_delete, match_type, referencing_columns_set_null_or_default
|
||||||
|
) q1
|
||||||
|
$$,
|
||||||
|
referencing_relname_prefix,
|
||||||
|
confdelsetcols_column_ref
|
||||||
|
) INTO result;
|
||||||
|
RETURN result;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
|
CREATE OR REPLACE FUNCTION get_index_defs(schemaname text, tablename text)
|
||||||
|
RETURNS jsonb AS $func$
|
||||||
|
DECLARE
|
||||||
|
result jsonb;
|
||||||
|
indnullsnotdistinct_column_ref text;
|
||||||
|
BEGIN
|
||||||
|
-- Not use indnullsnotdistinct in group by clause if no such column exists.
|
||||||
|
-- This can only be the case for PG versions < 15.
|
||||||
|
IF EXISTS (SELECT 1 FROM pg_attribute WHERE attrelid = 'pg_index'::regclass AND attname='indnullsnotdistinct')
|
||||||
|
THEN
|
||||||
|
indnullsnotdistinct_column_ref := ',indnullsnotdistinct';
|
||||||
|
ELSE
|
||||||
|
indnullsnotdistinct_column_ref := '';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXECUTE format(
|
||||||
|
$$
|
||||||
|
SELECT jsonb_agg(to_jsonb(q1.*) ORDER BY q1.indexnames) AS index_defs FROM (
|
||||||
|
SELECT array_agg(indexname ORDER BY indexrelid) AS indexnames,
|
||||||
|
array_agg(indexdef ORDER BY indexrelid) AS indexdefs
|
||||||
|
FROM pg_indexes
|
||||||
|
JOIN pg_index
|
||||||
|
ON (indexrelid = (schemaname || '.' || indexname)::regclass)
|
||||||
|
WHERE schemaname = '%1$s' AND starts_with(tablename, '%2$s')
|
||||||
|
GROUP BY indnatts, indnkeyatts, indisunique, indisprimary, indisexclusion,
|
||||||
|
indimmediate, indisclustered, indisvalid, indisready, indislive,
|
||||||
|
indisreplident, indkey, indcollation, indclass, indoption, indexprs,
|
||||||
|
indpred %3$s
|
||||||
|
) q1
|
||||||
|
$$,
|
||||||
|
schemaname, tablename, indnullsnotdistinct_column_ref) INTO result;
|
||||||
|
RETURN result;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
|
CREATE OR REPLACE FUNCTION get_column_defaults(schemaname text, tablename text)
|
||||||
|
RETURNS jsonb AS $func$
|
||||||
|
DECLARE
|
||||||
|
result jsonb;
|
||||||
|
BEGIN
|
||||||
|
EXECUTE format(
|
||||||
|
$$
|
||||||
|
SELECT jsonb_agg(to_jsonb(q1.*) ORDER BY q1.column_name) AS column_defs FROM (
|
||||||
|
SELECT column_name, column_default::text, generation_expression::text
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = '%1$s' AND table_name = '%2$s' AND
|
||||||
|
column_default IS NOT NULL OR generation_expression IS NOT NULL
|
||||||
|
) q1
|
||||||
|
$$,
|
||||||
|
schemaname, tablename) INTO result;
|
||||||
|
RETURN result;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
|
CREATE OR REPLACE FUNCTION get_column_attrs(relname_prefix text)
|
||||||
|
RETURNS jsonb AS $func$
|
||||||
|
DECLARE
|
||||||
|
result jsonb;
|
||||||
|
BEGIN
|
||||||
|
EXECUTE format(
|
||||||
|
$$
|
||||||
|
SELECT to_jsonb(q2.*) FROM (
|
||||||
|
SELECT relnames, jsonb_agg(to_jsonb(q1.*) - 'relnames' ORDER BY q1.column_name) AS column_attrs FROM (
|
||||||
|
SELECT array_agg(attrelid::regclass::text ORDER BY attrelid) AS relnames,
|
||||||
|
attname AS column_name, typname AS type_name, collname AS collation_name, attcompression AS compression_method, attnotnull AS not_null
|
||||||
|
FROM pg_attribute pa
|
||||||
|
LEFT JOIN pg_type pt ON (pa.atttypid = pt.oid)
|
||||||
|
LEFT JOIN pg_collation pc1 ON (pa.attcollation = pc1.oid)
|
||||||
|
JOIN pg_class pc2 ON (pa.attrelid = pc2.oid)
|
||||||
|
WHERE starts_with(attrelid::regclass::text, '%1$s') AND
|
||||||
|
attnum > 0 AND NOT attisdropped AND relkind = 'r'
|
||||||
|
GROUP BY column_name, type_name, collation_name, compression_method, not_null
|
||||||
|
) q1
|
||||||
|
GROUP BY relnames
|
||||||
|
) q2
|
||||||
|
$$,
|
||||||
|
relname_prefix) INTO result;
|
||||||
|
RETURN result;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
|
|
|
@ -1473,6 +1473,56 @@ SELECT run_command_on_workers($$DROP ACCESS METHOD heap2$$);
|
||||||
(localhost,57638,t,"DROP ACCESS METHOD")
|
(localhost,57638,t,"DROP ACCESS METHOD")
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
|
CREATE TABLE referenced (int_col integer PRIMARY KEY);
|
||||||
|
CREATE TABLE referencing (text_col text);
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
SELECT create_distributed_table('referenced', null);
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('referencing', null);
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
RESET citus.shard_replication_factor;
|
||||||
|
CREATE OR REPLACE FUNCTION my_random(numeric)
|
||||||
|
RETURNS numeric AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
RETURN 7 * $1;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_2 integer UNIQUE NULLS DISTINCT REFERENCES referenced(int_col);
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_3 integer GENERATED ALWAYS AS (text_col::int * my_random(1)) STORED UNIQUE NULLS NOT DISTINCT;
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_grouped_fkey_constraints FROM get_grouped_fkey_constraints('pg15.referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
is_coordinator | result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t | [{"deferred": false, "deferable": false, "on_delete": "a", "on_update": "a", "match_type": "s", "constraint_names": ["referencing__fkey"], "referenced_tables": ["pg15.referenced"], "referenced_columns": ["int_col"], "referencing_tables": ["pg15.referencing"], "referencing_columns": ["test_2"], "referencing_columns_set_null_or_default": null}]
|
||||||
|
f | [{"deferred": false, "deferable": false, "on_delete": "a", "on_update": "a", "match_type": "s", "constraint_names": ["referencing__fkey", "referencing__fkey_960207"], "referenced_tables": ["pg15.referenced", "pg15.referenced_960206"], "referenced_columns": ["int_col"], "referencing_tables": ["pg15.referencing", "pg15.referencing_960207"], "referencing_columns": ["test_2"], "referencing_columns_set_null_or_default": null}]
|
||||||
|
f | [{"deferred": false, "deferable": false, "on_delete": "a", "on_update": "a", "match_type": "s", "constraint_names": ["referencing__fkey"], "referenced_tables": ["pg15.referenced"], "referenced_columns": ["int_col"], "referencing_tables": ["pg15.referencing"], "referencing_columns": ["test_2"], "referencing_columns_set_null_or_default": null}]
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_index_defs FROM get_index_defs('pg15', 'referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
is_coordinator | result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t | [{"indexdefs": ["CREATE UNIQUE INDEX referencing__key ON pg15.referencing USING btree (test_2)"], "indexnames": ["referencing__key"]}, {"indexdefs": ["CREATE UNIQUE INDEX referencing__key1 ON pg15.referencing USING btree (test_3) NULLS NOT DISTINCT"], "indexnames": ["referencing__key1"]}]
|
||||||
|
f | [{"indexdefs": ["CREATE UNIQUE INDEX referencing__key ON pg15.referencing USING btree (test_2)", "CREATE UNIQUE INDEX referencing__key_960207 ON pg15.referencing_960207 USING btree (test_2)"], "indexnames": ["referencing__key", "referencing__key_960207"]}, {"indexdefs": ["CREATE UNIQUE INDEX referencing__key1 ON pg15.referencing USING btree (test_3) NULLS NOT DISTINCT", "CREATE UNIQUE INDEX referencing__key1_960207 ON pg15.referencing_960207 USING btree (test_3) NULLS NOT DISTINCT"], "indexnames": ["referencing__key1", "referencing__key1_960207"]}]
|
||||||
|
f | [{"indexdefs": ["CREATE UNIQUE INDEX referencing__key ON pg15.referencing USING btree (test_2)"], "indexnames": ["referencing__key"]}, {"indexdefs": ["CREATE UNIQUE INDEX referencing__key1 ON pg15.referencing USING btree (test_3) NULLS NOT DISTINCT"], "indexnames": ["referencing__key1"]}]
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
-- Clean up
|
-- Clean up
|
||||||
\set VERBOSITY terse
|
\set VERBOSITY terse
|
||||||
SET client_min_messages TO ERROR;
|
SET client_min_messages TO ERROR;
|
||||||
|
|
|
@ -446,7 +446,7 @@ INSERT INTO local_table VALUES (1), (2), (3), (4);
|
||||||
INSERT INTO numbers VALUES (1), (2), (3), (4);
|
INSERT INTO numbers VALUES (1), (2), (3), (4);
|
||||||
NOTICE: executing the command locally: INSERT INTO replicate_ref_to_coordinator.numbers_8000001 AS citus_table_alias (a) VALUES (1), (2), (3), (4)
|
NOTICE: executing the command locally: INSERT INTO replicate_ref_to_coordinator.numbers_8000001 AS citus_table_alias (a) VALUES (1), (2), (3), (4)
|
||||||
ALTER TABLE numbers ADD COLUMN d int;
|
ALTER TABLE numbers ADD COLUMN d int;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (8000001, 'replicate_ref_to_coordinator', 'ALTER TABLE numbers ADD COLUMN d int;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (8000001, 'replicate_ref_to_coordinator', 'ALTER TABLE numbers ADD COLUMN d integer;')
|
||||||
SELECT * FROM local_table JOIN numbers USING(a) ORDER BY a;
|
SELECT * FROM local_table JOIN numbers USING(a) ORDER BY a;
|
||||||
NOTICE: executing the command locally: SELECT local_table.a, numbers.d FROM (replicate_ref_to_coordinator.local_table JOIN replicate_ref_to_coordinator.numbers_8000001 numbers(a, d) USING (a)) ORDER BY local_table.a
|
NOTICE: executing the command locally: SELECT local_table.a, numbers.d FROM (replicate_ref_to_coordinator.local_table JOIN replicate_ref_to_coordinator.numbers_8000001 numbers(a, d) USING (a)) ORDER BY local_table.a
|
||||||
a | d
|
a | d
|
||||||
|
|
|
@ -2134,10 +2134,10 @@ NOTICE: executing the command locally: SELECT count(*) AS count FROM (SELECT in
|
||||||
|
|
||||||
-- test with NULL columns
|
-- test with NULL columns
|
||||||
ALTER TABLE non_binary_copy_test ADD COLUMN z INT;
|
ALTER TABLE non_binary_copy_test ADD COLUMN z INT;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630519, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z INT;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630519, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630520, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z INT;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630520, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630521, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z INT;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630521, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630522, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z INT;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630522, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z integer;')
|
||||||
WITH cte_1 AS
|
WITH cte_1 AS
|
||||||
(INSERT INTO non_binary_copy_test SELECT * FROM non_binary_copy_test LIMIT 10000 ON CONFLICT (key) DO UPDATE SET value = (0, 'citus0')::new_type RETURNING z)
|
(INSERT INTO non_binary_copy_test SELECT * FROM non_binary_copy_test LIMIT 10000 ON CONFLICT (key) DO UPDATE SET value = (0, 'citus0')::new_type RETURNING z)
|
||||||
SELECT bool_and(z is null) FROM cte_1;
|
SELECT bool_and(z is null) FROM cte_1;
|
||||||
|
|
|
@ -2134,10 +2134,10 @@ NOTICE: executing the command locally: SELECT count(*) AS count FROM (SELECT in
|
||||||
|
|
||||||
-- test with NULL columns
|
-- test with NULL columns
|
||||||
ALTER TABLE non_binary_copy_test ADD COLUMN z INT;
|
ALTER TABLE non_binary_copy_test ADD COLUMN z INT;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630519, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z INT;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630519, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630520, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z INT;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630520, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630521, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z INT;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630521, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z integer;')
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630522, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z INT;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (90630522, 'single_node', 'ALTER TABLE non_binary_copy_test ADD COLUMN z integer;')
|
||||||
WITH cte_1 AS
|
WITH cte_1 AS
|
||||||
(INSERT INTO non_binary_copy_test SELECT * FROM non_binary_copy_test LIMIT 10000 ON CONFLICT (key) DO UPDATE SET value = (0, 'citus0')::new_type RETURNING z)
|
(INSERT INTO non_binary_copy_test SELECT * FROM non_binary_copy_test LIMIT 10000 ON CONFLICT (key) DO UPDATE SET value = (0, 'citus0')::new_type RETURNING z)
|
||||||
SELECT bool_and(z is null) FROM cte_1;
|
SELECT bool_and(z is null) FROM cte_1;
|
||||||
|
|
|
@ -157,7 +157,7 @@ test: with_executors with_join with_partitioning with_transactions with_dml
|
||||||
# Tests around DDL statements run on distributed tables
|
# Tests around DDL statements run on distributed tables
|
||||||
# ----------
|
# ----------
|
||||||
test: multi_index_statements
|
test: multi_index_statements
|
||||||
test: multi_alter_table_statements
|
test: multi_alter_table_statements alter_table_add_column
|
||||||
test: multi_alter_table_add_constraints
|
test: multi_alter_table_add_constraints
|
||||||
test: multi_alter_table_add_constraints_without_name
|
test: multi_alter_table_add_constraints_without_name
|
||||||
test: multi_alter_table_add_foreign_key_without_name
|
test: multi_alter_table_add_foreign_key_without_name
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
CREATE SCHEMA alter_table_add_column;
|
||||||
|
SET search_path TO alter_table_add_column;
|
||||||
|
|
||||||
|
SET citus.next_shard_id TO 1830000;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
|
||||||
|
SET client_min_messages TO NOTICE;
|
||||||
|
|
||||||
|
CREATE TABLE referenced (int_col integer PRIMARY KEY);
|
||||||
|
CREATE TABLE referencing (text_col text);
|
||||||
|
SELECT create_distributed_table('referenced', null);
|
||||||
|
SELECT create_distributed_table('referencing', null);
|
||||||
|
|
||||||
|
CREATE SCHEMA alter_table_add_column_other_schema;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION alter_table_add_column_other_schema.my_random(numeric)
|
||||||
|
RETURNS numeric AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
RETURN 7 * $1;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
|
|
||||||
|
CREATE COLLATION caseinsensitive (
|
||||||
|
provider = icu,
|
||||||
|
locale = 'und-u-ks-level2'
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TYPE "simple_!\'custom_type" AS (a integer, b integer);
|
||||||
|
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_1 integer DEFAULT (alter_table_add_column_other_schema.my_random(7) + random() + 5) NOT NULL CONSTRAINT fkey REFERENCES referenced(int_col) ON UPDATE SET DEFAULT ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_2 integer UNIQUE REFERENCES referenced(int_col) ON UPDATE CASCADE ON DELETE SET DEFAULT NOT DEFERRABLE INITIALLY IMMEDIATE;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_3 integer GENERATED ALWAYS AS (test_1 * alter_table_add_column_other_schema.my_random(1)) STORED UNIQUE REFERENCES referenced(int_col) MATCH FULL;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_4 integer PRIMARY KEY WITH (fillfactor=70) NOT NULL REFERENCES referenced(int_col) MATCH SIMPLE ON UPDATE CASCADE ON DELETE SET DEFAULT;
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_5 integer CONSTRAINT unique_c UNIQUE WITH (fillfactor=50);
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_6 text COMPRESSION pglz COLLATE caseinsensitive NOT NULL;
|
||||||
|
ALTER TABLE referencing ADD COLUMN "test_\'!7" "simple_!\'custom_type";
|
||||||
|
|
||||||
|
-- we give up deparsing ALTER TABLE command if it needs to create a check constraint, and we fallback to legacy behavior
|
||||||
|
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);
|
||||||
|
|
||||||
|
-- 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 integer;
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_grouped_fkey_constraints FROM get_grouped_fkey_constraints('alter_table_add_column.referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_index_defs FROM get_index_defs('alter_table_add_column', 'referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_column_defaults FROM get_column_defaults('alter_table_add_column', 'referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_column_attrs FROM get_column_attrs('alter_table_add_column.referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA alter_table_add_column, alter_table_add_column_other_schema CASCADE;
|
|
@ -100,9 +100,12 @@ BEGIN;
|
||||||
SELECT COUNT(*)=0 FROM citus_local_tables_in_schema;
|
SELECT COUNT(*)=0 FROM citus_local_tables_in_schema;
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
|
|
||||||
-- this actually attempts to convert local tables to citus local tables but errors out
|
BEGIN;
|
||||||
-- as citus doesn't support defining foreign keys via add column commands
|
ALTER TABLE local_table_1 ADD COLUMN col_3 INT REFERENCES reference_table_1(col_1);
|
||||||
ALTER TABLE local_table_1 ADD COLUMN col_3 INT REFERENCES reference_table_1(col_1);
|
|
||||||
|
-- show that we converted all 4 local tables in this schema to citus local tables
|
||||||
|
SELECT COUNT(*)=4 FROM citus_local_tables_in_schema;
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
-- define a foreign key so that all 4 local tables become citus local tables
|
-- define a foreign key so that all 4 local tables become citus local tables
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
-- MULTI_ALTER_TABLE_STATEMENTS
|
-- MULTI_ALTER_TABLE_STATEMENTS
|
||||||
--
|
--
|
||||||
|
|
||||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 220000;
|
CREATE SCHEMA multi_alter_table_statements;
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 220000;
|
||||||
|
|
||||||
-- Check that we can run ALTER TABLE statements on distributed tables.
|
-- Check that we can run ALTER TABLE statements on distributed tables.
|
||||||
-- We set the shardid sequence here so that the shardids in this test
|
-- We set the shardid sequence here so that the shardids in this test
|
||||||
|
@ -38,6 +39,8 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 221000;
|
||||||
|
|
||||||
-- Verify that we can add columns
|
-- Verify that we can add columns
|
||||||
|
|
||||||
|
@ -55,8 +58,10 @@ FROM
|
||||||
JOIN pg_attribute ON (pc.oid = pg_attribute.attrelid)
|
JOIN pg_attribute ON (pc.oid = pg_attribute.attrelid)
|
||||||
ORDER BY attnum;
|
ORDER BY attnum;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 222000;
|
||||||
|
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
SELECT float_column, count(*) FROM lineitem_alter GROUP BY float_column;
|
SELECT float_column, count(*) FROM lineitem_alter GROUP BY float_column;
|
||||||
SELECT int_column1, count(*) FROM lineitem_alter GROUP BY int_column1;
|
SELECT int_column1, count(*) FROM lineitem_alter GROUP BY int_column1;
|
||||||
|
|
||||||
|
@ -75,7 +80,7 @@ SELECT int_column1, count(*) FROM lineitem_alter GROUP BY int_column1;
|
||||||
-- Verify that SET NOT NULL works
|
-- Verify that SET NOT NULL works
|
||||||
|
|
||||||
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 SET NOT NULL;
|
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 SET NOT NULL;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
|
|
||||||
-- Drop default so that NULLs will be inserted for this column
|
-- Drop default so that NULLs will be inserted for this column
|
||||||
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 DROP DEFAULT;
|
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 DROP DEFAULT;
|
||||||
|
@ -90,7 +95,7 @@ END;
|
||||||
-- Verify that DROP NOT NULL works
|
-- Verify that DROP NOT NULL works
|
||||||
|
|
||||||
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 DROP NOT NULL;
|
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 DROP NOT NULL;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
|
|
||||||
-- COPY should succeed now
|
-- COPY should succeed now
|
||||||
SELECT master_create_empty_shard('lineitem_alter') as shardid \gset
|
SELECT master_create_empty_shard('lineitem_alter') as shardid \gset
|
||||||
|
@ -102,7 +107,7 @@ SELECT count(*) from lineitem_alter;
|
||||||
SELECT int_column2, pg_typeof(int_column2), count(*) from lineitem_alter GROUP BY int_column2;
|
SELECT int_column2, pg_typeof(int_column2), count(*) from lineitem_alter GROUP BY int_column2;
|
||||||
|
|
||||||
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 SET DATA TYPE FLOAT;
|
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 SET DATA TYPE FLOAT;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
|
|
||||||
SELECT int_column2, pg_typeof(int_column2), count(*) from lineitem_alter GROUP BY int_column2;
|
SELECT int_column2, pg_typeof(int_column2), count(*) from lineitem_alter GROUP BY int_column2;
|
||||||
|
|
||||||
|
@ -130,19 +135,19 @@ ALTER TABLE lineitem_alter DROP COLUMN IF EXISTS int_column2;
|
||||||
ALTER TABLE IF EXISTS lineitem_alter RENAME COLUMN l_orderkey_renamed TO l_orderkey;
|
ALTER TABLE IF EXISTS lineitem_alter RENAME COLUMN l_orderkey_renamed TO l_orderkey;
|
||||||
SELECT SUM(l_orderkey) FROM lineitem_alter;
|
SELECT SUM(l_orderkey) FROM lineitem_alter;
|
||||||
|
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
|
|
||||||
-- Verify that we can execute commands with multiple subcommands
|
-- Verify that we can execute commands with multiple subcommands
|
||||||
|
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN int_column1 INTEGER,
|
ALTER TABLE lineitem_alter ADD COLUMN int_column1 INTEGER,
|
||||||
ADD COLUMN int_column2 INTEGER;
|
ADD COLUMN int_column2 INTEGER;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
|
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN int_column3 INTEGER,
|
ALTER TABLE lineitem_alter ADD COLUMN int_column3 INTEGER,
|
||||||
ALTER COLUMN int_column1 SET STATISTICS 10;
|
ALTER COLUMN int_column1 SET STATISTICS 10;
|
||||||
|
|
||||||
ALTER TABLE lineitem_alter DROP COLUMN int_column1, DROP COLUMN int_column2;
|
ALTER TABLE lineitem_alter DROP COLUMN int_column1, DROP COLUMN int_column2;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
|
|
||||||
-- Verify that we cannot execute alter commands on the distribution column
|
-- Verify that we cannot execute alter commands on the distribution column
|
||||||
|
|
||||||
|
@ -174,7 +179,7 @@ ALTER TABLE IF EXISTS non_existent_table RENAME COLUMN column1 TO column2;
|
||||||
|
|
||||||
-- Verify that none of the failed alter table commands took effect on the master
|
-- Verify that none of the failed alter table commands took effect on the master
|
||||||
-- node
|
-- node
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
|
|
||||||
-- verify that non-propagated ddl commands are allowed inside a transaction block
|
-- verify that non-propagated ddl commands are allowed inside a transaction block
|
||||||
SET citus.enable_ddl_propagation to false;
|
SET citus.enable_ddl_propagation to false;
|
||||||
|
@ -198,7 +203,7 @@ CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN first integer;
|
ALTER TABLE lineitem_alter ADD COLUMN first integer;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='lineitem_alter'::regclass;
|
||||||
SELECT "Column", "Type", "Definition" FROM index_attrs WHERE
|
SELECT "Column", "Type", "Definition" FROM index_attrs WHERE
|
||||||
relid = 'temp_index_2'::regclass;
|
relid = 'temp_index_2'::regclass;
|
||||||
|
|
||||||
|
@ -241,8 +246,10 @@ DROP INDEX temp_index_2;
|
||||||
|
|
||||||
-- Add column on only one worker...
|
-- Add column on only one worker...
|
||||||
\c - - - :worker_2_port
|
\c - - - :worker_2_port
|
||||||
ALTER TABLE lineitem_alter_220000 ADD COLUMN first integer;
|
ALTER TABLE multi_alter_table_statements.lineitem_alter_220000 ADD COLUMN first integer;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 223000;
|
||||||
|
|
||||||
-- and try to add it in a multi-statement block, which fails
|
-- and try to add it in a multi-statement block, which fails
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
@ -288,7 +295,7 @@ ALTER TABLE single_shard_items REPLICA IDENTITY default;
|
||||||
|
|
||||||
-- Drop the column from the worker...
|
-- Drop the column from the worker...
|
||||||
\c - - - :worker_2_port
|
\c - - - :worker_2_port
|
||||||
ALTER TABLE lineitem_alter_220000 DROP COLUMN first;
|
ALTER TABLE multi_alter_table_statements.lineitem_alter_220000 DROP COLUMN first;
|
||||||
|
|
||||||
-- Create table to trigger at-xact-end (deferred) failure
|
-- Create table to trigger at-xact-end (deferred) failure
|
||||||
CREATE TABLE ddl_commands (command text UNIQUE DEFERRABLE INITIALLY DEFERRED);
|
CREATE TABLE ddl_commands (command text UNIQUE DEFERRABLE INITIALLY DEFERRED);
|
||||||
|
@ -305,6 +312,8 @@ RESET citus.enable_metadata_sync;
|
||||||
CREATE EVENT TRIGGER log_ddl_tag ON ddl_command_end EXECUTE PROCEDURE log_ddl_tag();
|
CREATE EVENT TRIGGER log_ddl_tag ON ddl_command_end EXECUTE PROCEDURE log_ddl_tag();
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 224000;
|
||||||
-- The above trigger will cause failure at transaction end on one placement.
|
-- The above trigger will cause failure at transaction end on one placement.
|
||||||
-- Citus always uses 2PC. 2PC should handle this "best" (no divergence)
|
-- Citus always uses 2PC. 2PC should handle this "best" (no divergence)
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
@ -321,6 +330,8 @@ DROP FUNCTION log_ddl_tag();
|
||||||
DROP TABLE ddl_commands;
|
DROP TABLE ddl_commands;
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 225000;
|
||||||
-- Distributed SELECTs may appear after ALTER
|
-- Distributed SELECTs may appear after ALTER
|
||||||
BEGIN;
|
BEGIN;
|
||||||
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
|
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
|
||||||
|
@ -360,6 +371,8 @@ FROM
|
||||||
JOIN pg_attribute ON (pc.oid = pg_attribute.attrelid)
|
JOIN pg_attribute ON (pc.oid = pg_attribute.attrelid)
|
||||||
ORDER BY attnum;
|
ORDER BY attnum;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 226000;
|
||||||
|
|
||||||
-- verify that we can rename distributed tables
|
-- verify that we can rename distributed tables
|
||||||
SHOW citus.enable_ddl_propagation;
|
SHOW citus.enable_ddl_propagation;
|
||||||
|
@ -372,29 +385,37 @@ SELECT relname FROM pg_class WHERE relname = 'lineitem_renamed';
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_renamed%' ORDER BY relname;
|
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_renamed%' ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 227000;
|
||||||
|
|
||||||
-- revert it to original name
|
-- revert it to original name
|
||||||
ALTER TABLE lineitem_renamed RENAME TO lineitem_alter;
|
ALTER TABLE lineitem_renamed RENAME TO lineitem_alter;
|
||||||
|
|
||||||
-- show rename worked on one worker, too
|
-- show rename worked on one worker, too
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220002' /* failed copy trails */ ORDER BY relname;
|
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_222001' /* failed copy trails */ ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 228000;
|
||||||
|
|
||||||
-- verify that we can set and reset storage parameters
|
-- verify that we can set and reset storage parameters
|
||||||
ALTER TABLE lineitem_alter SET(fillfactor=40);
|
ALTER TABLE lineitem_alter SET(fillfactor=40);
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220002' /* failed copy trails */ ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_222001' /* failed copy trails */ ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 229000;
|
||||||
|
|
||||||
ALTER TABLE lineitem_alter RESET(fillfactor);
|
ALTER TABLE lineitem_alter RESET(fillfactor);
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220002' /* failed copy trails */ ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_222001' /* failed copy trails */ ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 230000;
|
||||||
|
|
||||||
-- verify that we can rename indexes on distributed tables
|
-- verify that we can rename indexes on distributed tables
|
||||||
CREATE INDEX temp_index_1 ON lineitem_alter(l_linenumber);
|
CREATE INDEX temp_index_1 ON lineitem_alter(l_linenumber);
|
||||||
|
@ -407,6 +428,8 @@ SELECT relname FROM pg_class WHERE relname = 'idx_lineitem_linenumber';
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname FROM pg_class WHERE relname LIKE 'idx_lineitem_linenumber%' ORDER BY relname;
|
SELECT relname FROM pg_class WHERE relname LIKE 'idx_lineitem_linenumber%' ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 231000;
|
||||||
|
|
||||||
-- now get rid of the index
|
-- now get rid of the index
|
||||||
DROP INDEX idx_lineitem_linenumber;
|
DROP INDEX idx_lineitem_linenumber;
|
||||||
|
@ -427,8 +450,10 @@ ALTER TABLE lineitem_alter ADD COLUMN column_only_added_to_master int;
|
||||||
|
|
||||||
-- verify newly added column is not present in a worker shard
|
-- verify newly added column is not present in a worker shard
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT column_only_added_to_master FROM lineitem_alter_220000 LIMIT 0;
|
SELECT column_only_added_to_master FROM multi_alter_table_statements.lineitem_alter_220000 LIMIT 0;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 232000;
|
||||||
|
|
||||||
-- ddl propagation flag is reset to default, disable it again
|
-- ddl propagation flag is reset to default, disable it again
|
||||||
SET citus.enable_ddl_propagation to false;
|
SET citus.enable_ddl_propagation to false;
|
||||||
|
@ -458,6 +483,8 @@ SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT indexname, tablename FROM pg_indexes WHERE tablename like 'lineitem_alter_%';
|
SELECT indexname, tablename FROM pg_indexes WHERE tablename like 'lineitem_alter_%';
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 233000;
|
||||||
|
|
||||||
-- verify alter table and drop sequence in the same transaction does not cause deadlock
|
-- verify alter table and drop sequence in the same transaction does not cause deadlock
|
||||||
SET citus.shard_count TO 4;
|
SET citus.shard_count TO 4;
|
||||||
|
@ -489,7 +516,7 @@ SELECT create_distributed_table('trigger_table', 'id');
|
||||||
-- first set a trigger on a shard
|
-- first set a trigger on a shard
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SET citus.enable_metadata_sync TO OFF;
|
SET citus.enable_metadata_sync TO OFF;
|
||||||
CREATE FUNCTION update_value() RETURNS trigger AS $up$
|
CREATE OR REPLACE FUNCTION update_value() RETURNS trigger AS $up$
|
||||||
BEGIN
|
BEGIN
|
||||||
NEW.value := 'trigger enabled';
|
NEW.value := 'trigger enabled';
|
||||||
RETURN NEW;
|
RETURN NEW;
|
||||||
|
@ -498,10 +525,12 @@ $up$ LANGUAGE plpgsql;
|
||||||
RESET citus.enable_metadata_sync;
|
RESET citus.enable_metadata_sync;
|
||||||
|
|
||||||
CREATE TRIGGER update_value
|
CREATE TRIGGER update_value
|
||||||
BEFORE INSERT ON trigger_table_220017
|
BEFORE INSERT ON multi_alter_table_statements.trigger_table_233004
|
||||||
FOR EACH ROW EXECUTE PROCEDURE update_value();
|
FOR EACH ROW EXECUTE PROCEDURE update_value();
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 234000;
|
||||||
INSERT INTO trigger_table VALUES (1, 'trigger disabled');
|
INSERT INTO trigger_table VALUES (1, 'trigger disabled');
|
||||||
SELECT value, count(*) FROM trigger_table GROUP BY value ORDER BY value;
|
SELECT value, count(*) FROM trigger_table GROUP BY value ORDER BY value;
|
||||||
|
|
||||||
|
@ -529,32 +558,36 @@ SET citus.enable_ddl_propagation to true;
|
||||||
CREATE USER alter_table_owner WITH LOGIN;
|
CREATE USER alter_table_owner WITH LOGIN;
|
||||||
|
|
||||||
GRANT USAGE ON SCHEMA public TO alter_table_owner;
|
GRANT USAGE ON SCHEMA public TO alter_table_owner;
|
||||||
|
GRANT USAGE ON SCHEMA multi_alter_table_statements TO alter_table_owner;
|
||||||
|
|
||||||
\c - alter_table_owner - :master_port
|
\c - alter_table_owner - :master_port
|
||||||
-- should not be able to access table without permission
|
-- should not be able to access table without permission
|
||||||
SELECT count(*) FROM lineitem_alter;
|
SELECT count(*) FROM multi_alter_table_statements.lineitem_alter;
|
||||||
|
|
||||||
-- should not be able to drop the table as non table owner
|
-- should not be able to drop the table as non table owner
|
||||||
DROP TABLE lineitem_alter;
|
DROP TABLE multi_alter_table_statements.lineitem_alter;
|
||||||
|
|
||||||
\c - postgres - :master_port
|
\c - postgres - :master_port
|
||||||
ALTER TABLE lineitem_alter OWNER TO alter_table_owner;
|
ALTER TABLE multi_alter_table_statements.lineitem_alter OWNER TO alter_table_owner;
|
||||||
|
|
||||||
\c - alter_table_owner - :master_port
|
\c - alter_table_owner - :master_port
|
||||||
-- should be able to query the table as table owner
|
-- should be able to query the table as table owner
|
||||||
SELECT count(*) FROM lineitem_alter;
|
SELECT count(*) FROM multi_alter_table_statements.lineitem_alter;
|
||||||
|
|
||||||
-- should be able to drop the table as table owner
|
-- should be able to drop the table as table owner
|
||||||
DROP TABLE lineitem_alter;
|
DROP TABLE multi_alter_table_statements.lineitem_alter;
|
||||||
|
|
||||||
-- check that nothing's left over on workers, other than the leftover shard created
|
-- check that nothing's left over on workers, other than the leftover shard created
|
||||||
-- during the unsuccessful COPY
|
-- during the unsuccessful COPY
|
||||||
\c - postgres - :worker_1_port
|
\c - postgres - :worker_1_port
|
||||||
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%';
|
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%';
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 235000;
|
||||||
|
|
||||||
-- drop the roles created
|
-- drop the roles created
|
||||||
REVOKE ALL ON SCHEMA PUBLIC FROM alter_table_owner;
|
REVOKE ALL ON SCHEMA PUBLIC FROM alter_table_owner;
|
||||||
|
REVOKE ALL ON SCHEMA multi_alter_table_statements FROM alter_table_owner;
|
||||||
DROP ROLE alter_table_owner;
|
DROP ROLE alter_table_owner;
|
||||||
|
|
||||||
-- Test alter table with drop table in the same transaction
|
-- Test alter table with drop table in the same transaction
|
||||||
|
@ -569,6 +602,8 @@ END;
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname FROM pg_class WHERE relname LIKE 'test_table_1%';
|
SELECT relname FROM pg_class WHERE relname LIKE 'test_table_1%';
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 236000;
|
||||||
|
|
||||||
-- verify logged info is propagated to workers when distributing the table
|
-- verify logged info is propagated to workers when distributing the table
|
||||||
CREATE TABLE logged_test(id int);
|
CREATE TABLE logged_test(id int);
|
||||||
|
@ -577,6 +612,8 @@ SELECT create_distributed_table('logged_test', 'id');
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 237000;
|
||||||
|
|
||||||
-- verify SET LOGGED/UNLOGGED works after distributing the table
|
-- verify SET LOGGED/UNLOGGED works after distributing the table
|
||||||
ALTER TABLE logged_test SET LOGGED;
|
ALTER TABLE logged_test SET LOGGED;
|
||||||
|
@ -584,11 +621,15 @@ SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logg
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 238000;
|
||||||
ALTER TABLE logged_test SET UNLOGGED;
|
ALTER TABLE logged_test SET UNLOGGED;
|
||||||
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test*' ORDER BY relname;
|
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test*' ORDER BY relname;
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
SELECT relname, CASE relpersistence WHEN 'u' THEN 'unlogged' WHEN 'p' then 'logged' ELSE 'unknown' END AS logged_info FROM pg_class WHERE relname ~ 'logged_test_' ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 239000;
|
||||||
DROP TABLE logged_test;
|
DROP TABLE logged_test;
|
||||||
|
|
||||||
-- Test WITH options on a normal simple hash-distributed table
|
-- Test WITH options on a normal simple hash-distributed table
|
||||||
|
@ -601,6 +642,8 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist';
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relkind = 'r' AND relname LIKE 'hash_dist_%' ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relkind = 'r' AND relname LIKE 'hash_dist_%' ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 240000;
|
||||||
|
|
||||||
-- verify that we can set and reset index storage parameters
|
-- verify that we can set and reset index storage parameters
|
||||||
ALTER INDEX hash_dist_pkey SET(fillfactor=40);
|
ALTER INDEX hash_dist_pkey SET(fillfactor=40);
|
||||||
|
@ -609,6 +652,8 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey_%' ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey_%' ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 241000;
|
||||||
|
|
||||||
ALTER INDEX hash_dist_pkey RESET(fillfactor);
|
ALTER INDEX hash_dist_pkey RESET(fillfactor);
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
|
@ -616,6 +661,8 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey_%' ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey_%' ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 242000;
|
||||||
|
|
||||||
-- verify error message on ALTER INDEX, SET TABLESPACE is unsupported
|
-- verify error message on ALTER INDEX, SET TABLESPACE is unsupported
|
||||||
ALTER INDEX hash_dist_pkey SET TABLESPACE foo;
|
ALTER INDEX hash_dist_pkey SET TABLESPACE foo;
|
||||||
|
@ -629,6 +676,8 @@ SELECT relname, reloptions FROM pg_class WHERE relname = 'another_index';
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'another_index_%' ORDER BY relname;
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'another_index_%' ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
SET search_path TO multi_alter_table_statements, public;
|
||||||
|
SET citus.next_shard_id TO 243000;
|
||||||
|
|
||||||
-- get rid of the index
|
-- get rid of the index
|
||||||
DROP INDEX another_index;
|
DROP INDEX another_index;
|
||||||
|
@ -645,13 +694,24 @@ ALTER TABLE test_table_1 ADD COLUMN test_col int CHECK (test_col > 3);
|
||||||
|
|
||||||
CREATE TABLE reference_table(i int UNIQUE);
|
CREATE TABLE reference_table(i int UNIQUE);
|
||||||
SELECT create_reference_table('reference_table');
|
SELECT create_reference_table('reference_table');
|
||||||
ALTER TABLE test_table_1 ADD COLUMN test_col int REFERENCES reference_table(i) ON DELETE CASCADE;
|
|
||||||
ALTER TABLE test_table_1 ADD COLUMN test_col int REFERENCES reference_table(i) ON DELETE CASCADE ON UPDATE SET NULL;
|
ALTER TABLE test_table_1 ADD COLUMN test_col_1 int REFERENCES reference_table(i) ON DELETE CASCADE;
|
||||||
DROP TABLE reference_table;
|
ALTER TABLE test_table_1 ADD COLUMN test_col_2 int REFERENCES reference_table(i) ON DELETE CASCADE ON UPDATE SET NULL;
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_grouped_fkey_constraints FROM get_grouped_fkey_constraints('multi_alter_table_statements.test_table_1')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
SET LOCAL client_min_messages TO WARNING;
|
||||||
|
DROP TABLE reference_table CASCADE;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
CREATE TABLE referenced_table(i int UNIQUE);
|
CREATE TABLE referenced_table(i int UNIQUE);
|
||||||
SELECT create_distributed_table('referenced_table', 'i');
|
SELECT create_distributed_table('referenced_table', 'i');
|
||||||
ALTER TABLE test_table_1 ADD COLUMN test_col int REFERENCES referenced_table(i);
|
ALTER TABLE test_table_1 ADD COLUMN test_col_3 int REFERENCES referenced_table(i);
|
||||||
DROP TABLE referenced_table, test_table_1;
|
DROP TABLE referenced_table, test_table_1;
|
||||||
|
|
||||||
-- Check sequence propagate its own dependencies while adding a column
|
-- Check sequence propagate its own dependencies while adding a column
|
||||||
|
@ -667,5 +727,7 @@ ALTER TABLE table_without_sequence ADD COLUMN x BIGINT DEFAULT nextval('test_sch
|
||||||
SELECT pg_identify_object_as_address(classid, objid, objsubid) from pg_catalog.pg_dist_object WHERE objid IN ('test_schema_for_sequence_propagation.seq_10'::regclass);
|
SELECT pg_identify_object_as_address(classid, objid, objsubid) from pg_catalog.pg_dist_object WHERE objid IN ('test_schema_for_sequence_propagation.seq_10'::regclass);
|
||||||
SELECT pg_identify_object_as_address(classid, objid, objsubid) from pg_catalog.pg_dist_object WHERE objid IN ('test_schema_for_sequence_propagation'::regnamespace);
|
SELECT pg_identify_object_as_address(classid, objid, objsubid) from pg_catalog.pg_dist_object WHERE objid IN ('test_schema_for_sequence_propagation'::regnamespace);
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
DROP SCHEMA test_schema_for_sequence_propagation CASCADE;
|
DROP SCHEMA test_schema_for_sequence_propagation CASCADE;
|
||||||
DROP TABLE table_without_sequence;
|
DROP TABLE table_without_sequence;
|
||||||
|
DROP SCHEMA multi_alter_table_statements CASCADE;
|
||||||
|
|
|
@ -180,3 +180,139 @@ BEGIN
|
||||||
EXECUTE 'SELECT COUNT(*) FROM pg_catalog.pg_dist_cleanup' INTO record_count;
|
EXECUTE 'SELECT COUNT(*) FROM pg_catalog.pg_dist_cleanup' INTO record_count;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END$$ LANGUAGE plpgsql;
|
END$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
-- Returns the foreign keys where the referencing relation's name starts with
|
||||||
|
-- given prefix.
|
||||||
|
--
|
||||||
|
-- Foreign keys are groupped by their configurations and then the constraint name,
|
||||||
|
-- referencing table, and referenced table for each distinct configuration are
|
||||||
|
-- aggregated into arrays.
|
||||||
|
CREATE OR REPLACE FUNCTION get_grouped_fkey_constraints(referencing_relname_prefix text)
|
||||||
|
RETURNS jsonb AS $func$
|
||||||
|
DECLARE
|
||||||
|
confdelsetcols_column_ref text;
|
||||||
|
get_grouped_fkey_constraints_query text;
|
||||||
|
result jsonb;
|
||||||
|
BEGIN
|
||||||
|
-- Read confdelsetcols as null if no such column exists.
|
||||||
|
-- This can only be the case for PG versions < 15.
|
||||||
|
IF EXISTS (SELECT 1 FROM pg_attribute WHERE attrelid = 'pg_constraint'::regclass AND attname='confdelsetcols')
|
||||||
|
THEN
|
||||||
|
confdelsetcols_column_ref := '(SELECT array_agg(attname ORDER BY attnum) FROM pg_attribute WHERE attrelid = conrelid AND attnum = ANY(confdelsetcols))';
|
||||||
|
ELSE
|
||||||
|
confdelsetcols_column_ref := '(SELECT null::smallint[])';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXECUTE format(
|
||||||
|
$$
|
||||||
|
SELECT jsonb_agg(to_jsonb(q1.*) ORDER BY q1.constraint_names) AS fkeys_with_different_config FROM (
|
||||||
|
SELECT array_agg(constraint_name ORDER BY constraint_oid) AS constraint_names,
|
||||||
|
array_agg(referencing_table::regclass::text ORDER BY constraint_oid) AS referencing_tables,
|
||||||
|
array_agg(referenced_table::regclass::text ORDER BY constraint_oid) AS referenced_tables,
|
||||||
|
referencing_columns, referenced_columns, deferable, deferred, on_update, on_delete, match_type, referencing_columns_set_null_or_default
|
||||||
|
FROM (
|
||||||
|
SELECT
|
||||||
|
oid AS constraint_oid,
|
||||||
|
conname AS constraint_name,
|
||||||
|
conrelid AS referencing_table,
|
||||||
|
(SELECT array_agg(attname ORDER BY attnum) FROM pg_attribute WHERE attrelid = conrelid AND attnum = ANY(conkey)) AS referencing_columns,
|
||||||
|
confrelid AS referenced_table,
|
||||||
|
(SELECT array_agg(attname ORDER BY attnum) FROM pg_attribute WHERE attrelid = confrelid AND attnum = ANY(confkey)) AS referenced_columns,
|
||||||
|
condeferrable AS deferable,
|
||||||
|
condeferred AS deferred,
|
||||||
|
confupdtype AS on_update,
|
||||||
|
confdeltype AS on_delete,
|
||||||
|
confmatchtype AS match_type,
|
||||||
|
%2$s AS referencing_columns_set_null_or_default
|
||||||
|
FROM pg_constraint WHERE starts_with(conrelid::regclass::text, '%1$s') AND contype = 'f'
|
||||||
|
) q2
|
||||||
|
GROUP BY referencing_columns, referenced_columns, deferable, deferred, on_update, on_delete, match_type, referencing_columns_set_null_or_default
|
||||||
|
) q1
|
||||||
|
$$,
|
||||||
|
referencing_relname_prefix,
|
||||||
|
confdelsetcols_column_ref
|
||||||
|
) INTO result;
|
||||||
|
RETURN result;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION get_index_defs(schemaname text, tablename text)
|
||||||
|
RETURNS jsonb AS $func$
|
||||||
|
DECLARE
|
||||||
|
result jsonb;
|
||||||
|
indnullsnotdistinct_column_ref text;
|
||||||
|
BEGIN
|
||||||
|
-- Not use indnullsnotdistinct in group by clause if no such column exists.
|
||||||
|
-- This can only be the case for PG versions < 15.
|
||||||
|
IF EXISTS (SELECT 1 FROM pg_attribute WHERE attrelid = 'pg_index'::regclass AND attname='indnullsnotdistinct')
|
||||||
|
THEN
|
||||||
|
indnullsnotdistinct_column_ref := ',indnullsnotdistinct';
|
||||||
|
ELSE
|
||||||
|
indnullsnotdistinct_column_ref := '';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXECUTE format(
|
||||||
|
$$
|
||||||
|
SELECT jsonb_agg(to_jsonb(q1.*) ORDER BY q1.indexnames) AS index_defs FROM (
|
||||||
|
SELECT array_agg(indexname ORDER BY indexrelid) AS indexnames,
|
||||||
|
array_agg(indexdef ORDER BY indexrelid) AS indexdefs
|
||||||
|
FROM pg_indexes
|
||||||
|
JOIN pg_index
|
||||||
|
ON (indexrelid = (schemaname || '.' || indexname)::regclass)
|
||||||
|
WHERE schemaname = '%1$s' AND starts_with(tablename, '%2$s')
|
||||||
|
GROUP BY indnatts, indnkeyatts, indisunique, indisprimary, indisexclusion,
|
||||||
|
indimmediate, indisclustered, indisvalid, indisready, indislive,
|
||||||
|
indisreplident, indkey, indcollation, indclass, indoption, indexprs,
|
||||||
|
indpred %3$s
|
||||||
|
) q1
|
||||||
|
$$,
|
||||||
|
schemaname, tablename, indnullsnotdistinct_column_ref) INTO result;
|
||||||
|
RETURN result;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION get_column_defaults(schemaname text, tablename text)
|
||||||
|
RETURNS jsonb AS $func$
|
||||||
|
DECLARE
|
||||||
|
result jsonb;
|
||||||
|
BEGIN
|
||||||
|
EXECUTE format(
|
||||||
|
$$
|
||||||
|
SELECT jsonb_agg(to_jsonb(q1.*) ORDER BY q1.column_name) AS column_defs FROM (
|
||||||
|
SELECT column_name, column_default::text, generation_expression::text
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = '%1$s' AND table_name = '%2$s' AND
|
||||||
|
column_default IS NOT NULL OR generation_expression IS NOT NULL
|
||||||
|
) q1
|
||||||
|
$$,
|
||||||
|
schemaname, tablename) INTO result;
|
||||||
|
RETURN result;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION get_column_attrs(relname_prefix text)
|
||||||
|
RETURNS jsonb AS $func$
|
||||||
|
DECLARE
|
||||||
|
result jsonb;
|
||||||
|
BEGIN
|
||||||
|
EXECUTE format(
|
||||||
|
$$
|
||||||
|
SELECT to_jsonb(q2.*) FROM (
|
||||||
|
SELECT relnames, jsonb_agg(to_jsonb(q1.*) - 'relnames' ORDER BY q1.column_name) AS column_attrs FROM (
|
||||||
|
SELECT array_agg(attrelid::regclass::text ORDER BY attrelid) AS relnames,
|
||||||
|
attname AS column_name, typname AS type_name, collname AS collation_name, attcompression AS compression_method, attnotnull AS not_null
|
||||||
|
FROM pg_attribute pa
|
||||||
|
LEFT JOIN pg_type pt ON (pa.atttypid = pt.oid)
|
||||||
|
LEFT JOIN pg_collation pc1 ON (pa.attcollation = pc1.oid)
|
||||||
|
JOIN pg_class pc2 ON (pa.attrelid = pc2.oid)
|
||||||
|
WHERE starts_with(attrelid::regclass::text, '%1$s') AND
|
||||||
|
attnum > 0 AND NOT attisdropped AND relkind = 'r'
|
||||||
|
GROUP BY column_name, type_name, collation_name, compression_method, not_null
|
||||||
|
) q1
|
||||||
|
GROUP BY relnames
|
||||||
|
) q2
|
||||||
|
$$,
|
||||||
|
relname_prefix) INTO result;
|
||||||
|
RETURN result;
|
||||||
|
END;
|
||||||
|
$func$ LANGUAGE plpgsql;
|
||||||
|
|
|
@ -933,6 +933,38 @@ DROP TABLE mx_ddl_table2;
|
||||||
DROP ACCESS METHOD heap2;
|
DROP ACCESS METHOD heap2;
|
||||||
SELECT run_command_on_workers($$DROP ACCESS METHOD heap2$$);
|
SELECT run_command_on_workers($$DROP ACCESS METHOD heap2$$);
|
||||||
|
|
||||||
|
CREATE TABLE referenced (int_col integer PRIMARY KEY);
|
||||||
|
CREATE TABLE referencing (text_col text);
|
||||||
|
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
SELECT create_distributed_table('referenced', null);
|
||||||
|
SELECT create_distributed_table('referencing', null);
|
||||||
|
RESET citus.shard_replication_factor;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION my_random(numeric)
|
||||||
|
RETURNS numeric AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
RETURN 7 * $1;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
|
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_2 integer UNIQUE NULLS DISTINCT REFERENCES referenced(int_col);
|
||||||
|
ALTER TABLE referencing ADD COLUMN test_3 integer GENERATED ALWAYS AS (text_col::int * my_random(1)) STORED UNIQUE NULLS NOT DISTINCT;
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_grouped_fkey_constraints FROM get_grouped_fkey_constraints('pg15.referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
|
||||||
|
SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
||||||
|
$$SELECT get_index_defs FROM get_index_defs('pg15', 'referencing')$$
|
||||||
|
)
|
||||||
|
JOIN pg_dist_node USING (nodeid)
|
||||||
|
ORDER BY is_coordinator DESC, result;
|
||||||
|
|
||||||
-- Clean up
|
-- Clean up
|
||||||
\set VERBOSITY terse
|
\set VERBOSITY terse
|
||||||
SET client_min_messages TO ERROR;
|
SET client_min_messages TO ERROR;
|
||||||
|
|
Loading…
Reference in New Issue