Enable ALTER TABLE ... ADD UNIQUE and ADD EXCLUDE. (#6582)

DESCRIPTION: Adds support for creating table constraints UNIQUE and
EXCLUDE via ALTER TABLE command without client having to specify a name.

ALTER TABLE ... ADD CONSTRAINT <conname> UNIQUE ...
ALTER TABLE ... ADD CONSTRAINT <conname> EXCLUDE ...

commands require the client to provide an explicit constraint name.
However, in postgres it is possible for clients not to provide a name
and let the postgres generate it using the following commands

ALTER TABLE ... ADD UNIQUE ...
ALTER TABLE ... ADD EXCLUDE ...

This PR enables the same functionality for citus tables.
git_credential_change
Emel Şimşek 2023-01-05 18:12:32 +03:00 committed by GitHub
parent 135c519c62
commit db7a70ef3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1097 additions and 95 deletions

View File

@ -702,12 +702,87 @@ PostprocessAlterTableSchemaStmt(Node *node, const char *queryString)
/* /*
* SwitchToSequentialAndLocalExecutionIfPrimaryKeyNameTooLong generates the longest primary key name * GenerateConstraintName creates and returns a default name for the constraints Citus supports
* for default naming. See ConstTypeCitusCanDefaultName function for the supported constraint types.
*/
static char *
GenerateConstraintName(const char *tabname, Oid namespaceId, Constraint *constraint)
{
char *conname = NULL;
switch (constraint->contype)
{
case CONSTR_PRIMARY:
{
conname = ChooseIndexName(tabname, namespaceId,
NULL, NULL, true, true);
break;
}
case CONSTR_UNIQUE:
{
ListCell *lc;
List *indexParams = NIL;
foreach(lc, constraint->keys)
{
IndexElem *iparam = makeNode(IndexElem);
iparam->name = pstrdup(strVal(lfirst(lc)));
indexParams = lappend(indexParams, iparam);
}
conname = ChooseIndexName(tabname, namespaceId,
ChooseIndexColumnNames(indexParams),
NULL, false, true);
break;
}
case CONSTR_EXCLUSION:
{
ListCell *lc;
List *indexParams = NIL;
List *excludeOpNames = NIL;
foreach(lc, constraint->exclusions)
{
List *pair = (List *) lfirst(lc);
Assert(list_length(pair) == 2);
IndexElem *elem = linitial_node(IndexElem, pair);
List *opname = lsecond_node(List, pair);
indexParams = lappend(indexParams, elem);
excludeOpNames = lappend(excludeOpNames, opname);
}
conname = ChooseIndexName(tabname, namespaceId,
ChooseIndexColumnNames(indexParams),
excludeOpNames,
false, true);
break;
}
default:
{
ereport(ERROR, (errmsg(
"unsupported constraint type for generating a constraint name: %d",
constraint->contype)));
break;
}
}
return conname;
}
/*
* SwitchToSequentialAndLocalExecutionIfConstraintNameTooLong generates the longest index constraint name
* among the shards of the partitions, and if exceeds the limit switches to sequential and * among the shards of the partitions, and if exceeds the limit switches to sequential and
* local execution to prevent self-deadlocks. * local execution to prevent self-deadlocks.
*/ */
static void static void
SwitchToSequentialAndLocalExecutionIfPrimaryKeyNameTooLong(Oid relationId) SwitchToSequentialAndLocalExecutionIfConstraintNameTooLong(Oid relationId,
Constraint *constraint)
{ {
if (!PartitionedTable(relationId)) if (!PartitionedTable(relationId))
{ {
@ -743,12 +818,10 @@ SwitchToSequentialAndLocalExecutionIfPrimaryKeyNameTooLong(Oid relationId)
Oid namespaceOid = RelationGetNamespace(rel); Oid namespaceOid = RelationGetNamespace(rel);
RelationClose(rel); RelationClose(rel);
char *primaryKeyName = ChooseIndexName(longestPartitionShardName, char *longestConname = GenerateConstraintName(longestPartitionShardName,
namespaceOid, namespaceOid, constraint);
NULL, NULL, true, true);
if (longestConname && strnlen(longestConname, NAMEDATALEN) >= NAMEDATALEN - 1)
if (primaryKeyName && strnlen(primaryKeyName, NAMEDATALEN) >= NAMEDATALEN - 1)
{ {
if (ParallelQueryExecutedInTransaction()) if (ParallelQueryExecutedInTransaction())
{ {
@ -758,18 +831,18 @@ SwitchToSequentialAndLocalExecutionIfPrimaryKeyNameTooLong(Oid relationId)
* thus contradicting our purpose of using sequential mode. * thus contradicting our purpose of using sequential mode.
*/ */
ereport(ERROR, (errmsg( ereport(ERROR, (errmsg(
"The primary key name (%s) on a shard is too long and could lead " "The constraint name (%s) on a shard is too long and could lead "
"to deadlocks when executed in a transaction " "to deadlocks when executed in a transaction "
"block after a parallel query", primaryKeyName), "block after a parallel query", longestConname),
errhint("Try re-running the transaction with " errhint("Try re-running the transaction with "
"\"SET LOCAL citus.multi_shard_modify_mode TO " "\"SET LOCAL citus.multi_shard_modify_mode TO "
"\'sequential\';\""))); "\'sequential\';\"")));
} }
else else
{ {
elog(DEBUG1, "the primary key name on the shards of the partition " elog(DEBUG1, "the constraint name on the shards of the partition "
"is too long, switching to sequential and local execution " "is too long, switching to sequential and local execution "
"mode to prevent self deadlocks: %s", primaryKeyName); "mode to prevent self deadlocks: %s", longestConname);
SetLocalMultiShardModifyModeToSequential(); SetLocalMultiShardModifyModeToSequential();
SetLocalExecutionStatus(LOCAL_EXECUTION_REQUIRED); SetLocalExecutionStatus(LOCAL_EXECUTION_REQUIRED);
@ -779,39 +852,39 @@ SwitchToSequentialAndLocalExecutionIfPrimaryKeyNameTooLong(Oid relationId)
/* /*
* PreprocessAlterTableAddPrimaryKey creates a new primary key constraint name changing the original alterTableCommand run by the utility hook. * PreprocessAlterTableAddIndexConstraint creates a new constraint name for the index constraints {PRIMARY KEY, UNIQUE, EXCLUDE}
* Then converts the ALTER TABLE ... ADD PRIMARY KEY ... command * and changes the original alterTableCommand run by the utility hook to use the new constraint name.
* into ALTER TABLE ... ADD CONSTRAINT <constraint name> PRIMARY KEY format and returns the DDLJob * Then converts the ALTER TABLE ... ADD {PRIMARY KEY, UNIQUE, EXCLUDE} ... command
* into ALTER TABLE ... ADD CONSTRAINT <constraint name> {PRIMARY KEY, UNIQUE, EXCLUDE} format and returns the DDLJob
* to run this command in the workers. * to run this command in the workers.
*/ */
static List * static List *
PreprocessAlterTableAddPrimaryKey(AlterTableStmt *alterTableStatement, Oid relationId, PreprocessAlterTableAddIndexConstraint(AlterTableStmt *alterTableStatement, Oid
Constraint *constraint) relationId,
Constraint *constraint)
{ {
/* We should only preprocess an ADD PRIMARY KEY command if we are changing the it. /* We should only preprocess an ADD CONSTRAINT command if we are changing the it.
* This only happens when we have to create a primary key name ourselves in the case that the client does * This only happens when we have to create a constraint name in citus since the client does
* not specify a name. * not specify a name.
*/ */
Assert(constraint->conname == NULL); Assert(constraint->conname == NULL);
bool primary = true;
bool isconstraint = true;
Relation rel = RelationIdGetRelation(relationId); Relation rel = RelationIdGetRelation(relationId);
/* /*
* Change the alterTableCommand so that the standard utility * Change the alterTableCommand so that the standard utility
* hook runs it with the name we created. * hook runs it with the name we created.
*/ */
constraint->conname = ChooseIndexName(RelationGetRelationName(rel),
RelationGetNamespace(rel), constraint->conname = GenerateConstraintName(RelationGetRelationName(rel),
NULL, NULL, primary, RelationGetNamespace(rel),
isconstraint); constraint);
RelationClose(rel); RelationClose(rel);
char *ddlCommand = DeparseTreeNode((Node *) alterTableStatement); SwitchToSequentialAndLocalExecutionIfConstraintNameTooLong(relationId, constraint);
SwitchToSequentialAndLocalExecutionIfPrimaryKeyNameTooLong(relationId); char *ddlCommand = DeparseTreeNode((Node *) alterTableStatement);
DDLJob *ddlJob = palloc0(sizeof(DDLJob)); DDLJob *ddlJob = palloc0(sizeof(DDLJob));
@ -1063,17 +1136,18 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
*/ */
constraint->skip_validation = true; constraint->skip_validation = true;
} }
else if (constraint->contype == CONSTR_PRIMARY) else if (constraint->conname == NULL)
{ {
if (constraint->conname == NULL) if (ConstrTypeCitusCanDefaultName(constraint->contype))
{ {
/* /*
* Create a constraint name. Convert ALTER TABLE ... ADD PRIMARY ... command into * Create a constraint name. Convert ALTER TABLE ... ADD PRIMARY ... command into
* ALTER TABLE ... ADD CONSTRAINT <conname> PRIMARY KEY ... form and create the ddl jobs * ALTER TABLE ... ADD CONSTRAINT <conname> PRIMARY KEY ... form and create the ddl jobs
* for running this form of the command on the workers. * for running this form of the command on the workers.
*/ */
return PreprocessAlterTableAddPrimaryKey(alterTableStatement, return PreprocessAlterTableAddIndexConstraint(alterTableStatement,
leftRelationId, constraint); leftRelationId,
constraint);
} }
} }
} }
@ -1824,6 +1898,18 @@ ConstrTypeUsesIndex(ConstrType constrType)
} }
/*
* ConstrTypeSupportsDefaultNaming returns true if we can generate a default name for the given constraint type
*/
bool
ConstrTypeCitusCanDefaultName(ConstrType constrType)
{
return constrType == CONSTR_PRIMARY ||
constrType == CONSTR_UNIQUE ||
constrType == CONSTR_EXCLUSION;
}
/* /*
* AlterTableDropsForeignKey returns true if the given AlterTableStmt drops * AlterTableDropsForeignKey returns true if the given AlterTableStmt drops
* a foreign key. False otherwise. * a foreign key. False otherwise.
@ -3025,7 +3111,7 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
* and changing the command into the following form. * and changing the command into the following form.
* ALTER TABLE ... ADD CONSTRAINT <constaint_name> PRIMARY KEY ... * ALTER TABLE ... ADD CONSTRAINT <constaint_name> PRIMARY KEY ...
*/ */
if (constraint->contype != CONSTR_PRIMARY) if (ConstrTypeCitusCanDefaultName(constraint->contype) == false)
{ {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg( errmsg(

View File

@ -11,6 +11,7 @@
*/ */
#include "postgres.h" #include "postgres.h"
#include "distributed/commands.h"
#include "distributed/deparser.h" #include "distributed/deparser.h"
#include "distributed/version_compat.h" #include "distributed/version_compat.h"
#include "nodes/nodes.h" #include "nodes/nodes.h"
@ -103,10 +104,138 @@ AppendAlterTableStmt(StringInfo buf, AlterTableStmt *stmt)
} }
/*
* AppendAlterTableCmdAddConstraint builds the add constraint command for index constraints
* in the ADD CONSTRAINT <conname> {PRIMARY KEY, UNIQUE, EXCLUSION} form and appends it to the buf.
*/
static void
AppendAlterTableCmdAddConstraint(StringInfo buf, Constraint *constraint)
{
/* Need to deparse the alter table constraint command only if we are adding a constraint name.*/
if (constraint->conname == NULL)
{
ereport(ERROR, (errmsg(
"Constraint name can not be NULL when deparsing the constraint.")));
}
appendStringInfoString(buf, " ADD CONSTRAINT ");
appendStringInfo(buf, "%s ", quote_identifier(constraint->conname));
/* postgres version >= PG15
* UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) [ INCLUDE ( column_name [, ...]) ]
* postgres version < PG15
* UNIQUE ( column_name [, ... ] ) [ INCLUDE ( column_name [, ...]) ]
* PRIMARY KEY ( column_name [, ... ] ) [ INCLUDE ( column_name [, ...]) ]
*/
if (constraint->contype == CONSTR_PRIMARY || constraint->contype == CONSTR_UNIQUE)
{
if (constraint->contype == CONSTR_PRIMARY)
{
appendStringInfoString(buf,
" PRIMARY KEY (");
}
else
{
appendStringInfoString(buf, " UNIQUE");
#if (PG_VERSION_NUM >= PG_VERSION_15)
if (constraint->nulls_not_distinct == true)
{
appendStringInfoString(buf, " NULLS NOT DISTINCT");
}
#endif
appendStringInfoString(buf, " (");
}
ListCell *lc;
bool firstkey = true;
foreach(lc, constraint->keys)
{
if (firstkey == false)
{
appendStringInfoString(buf, ", ");
}
appendStringInfo(buf, "%s", quote_identifier(strVal(lfirst(lc))));
firstkey = false;
}
appendStringInfoString(buf, ")");
if (constraint->including != NULL)
{
appendStringInfoString(buf, " INCLUDE (");
firstkey = true;
foreach(lc, constraint->including)
{
if (firstkey == false)
{
appendStringInfoString(buf, ", ");
}
appendStringInfo(buf, "%s", quote_identifier(strVal(lfirst(
lc))));
firstkey = false;
}
appendStringInfoString(buf, " )");
}
}
else if (constraint->contype == CONSTR_EXCLUSION)
{
/*
* This block constructs the EXCLUDE clause which is in the following form:
* EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] )
*/
appendStringInfoString(buf, " EXCLUDE ");
if (constraint->access_method != NULL)
{
appendStringInfoString(buf, "USING ");
appendStringInfo(buf, "%s ", quote_identifier(
constraint->access_method));
}
appendStringInfoString(buf, " (");
ListCell *lc;
bool firstOp = true;
foreach(lc, constraint->exclusions)
{
List *pair = (List *) lfirst(lc);
Assert(list_length(pair) == 2);
IndexElem *elem = linitial_node(IndexElem, pair);
List *opname = lsecond_node(List, pair);
if (firstOp == false)
{
appendStringInfoString(buf, " ,");
}
ListCell *lc2;
foreach(lc2, opname)
{
appendStringInfo(buf, "%s WITH %s", quote_identifier(elem->name),
strVal(lfirst(lc2)));
}
firstOp = false;
}
appendStringInfoString(buf, " )");
}
}
/* /*
* AppendAlterTableCmd builds and appends to the given buffer a command * AppendAlterTableCmd builds and appends to the given buffer a command
* from given AlterTableCmd object. Currently supported commands are of type * from given AlterTableCmd object. Currently supported commands are of type
* AT_AddColumn and AT_SetNotNull * AT_AddColumn, AT_SetNotNull and AT_AddConstraint {PRIMARY KEY, UNIQUE, EXCLUDE}.
*/ */
static void static void
AppendAlterTableCmd(StringInfo buf, AlterTableCmd *alterTableCmd) AppendAlterTableCmd(StringInfo buf, AlterTableCmd *alterTableCmd)
@ -123,38 +252,13 @@ AppendAlterTableCmd(StringInfo buf, AlterTableCmd *alterTableCmd)
{ {
Constraint *constraint = (Constraint *) alterTableCmd->def; Constraint *constraint = (Constraint *) alterTableCmd->def;
/* We need to deparse ALTER TABLE ... PRIMARY KEY commands into /* We need to deparse ALTER TABLE ... ADD {PRIMARY KEY, UNIQUE, EXCLUSION} commands into
* ALTER TABLE ... ADD CONSTRAINT <conname> PRIMARY KEY ... to be able * ALTER TABLE ... ADD CONSTRAINT <conname> {PRIMARY KEY, UNIQUE, EXCLUSION} ... format to be able
* add a constraint name. * add a constraint name.
*/ */
if (constraint->contype == CONSTR_PRIMARY) if (ConstrTypeCitusCanDefaultName(constraint->contype))
{ {
/* Need to deparse PRIMARY KEY constraint commands only if adding a name.*/ AppendAlterTableCmdAddConstraint(buf, constraint);
if (constraint->conname == NULL)
{
ereport(ERROR, (errmsg(
"Constraint name can not be NULL when constraint type is PRIMARY KEY")));
}
appendStringInfoString(buf, " ADD CONSTRAINT ");
appendStringInfo(buf, "%s ", quote_identifier(constraint->conname));
appendStringInfoString(buf, " PRIMARY KEY (");
ListCell *lc;
bool firstkey = true;
foreach(lc, constraint->keys)
{
if (firstkey == false)
{
appendStringInfoString(buf, ", ");
}
appendStringInfo(buf, "%s", quote_identifier(strVal(lfirst(lc))));
firstkey = false;
}
appendStringInfoString(buf, ")");
break; break;
} }
} }

View File

@ -561,6 +561,7 @@ extern List * AlterTableSchemaStmtObjectAddress(Node *stmt,
extern List * MakeNameListFromRangeVar(const RangeVar *rel); extern List * MakeNameListFromRangeVar(const RangeVar *rel);
extern Oid GetSequenceOid(Oid relationId, AttrNumber attnum); extern Oid GetSequenceOid(Oid relationId, AttrNumber attnum);
extern bool ConstrTypeUsesIndex(ConstrType constrType); extern bool ConstrTypeUsesIndex(ConstrType constrType);
extern bool ConstrTypeCitusCanDefaultName(ConstrType constrType);
/* text_search.c - forward declarations */ /* text_search.c - forward declarations */

View File

@ -434,13 +434,8 @@ ERROR: cannot execute ADD CONSTRAINT command with other subcommands
HINT: You can issue each subcommand separately HINT: You can issue each subcommand separately
-- Tests for constraints without name -- Tests for constraints without name
-- Commands below should error out since constraints do not have the name -- Commands below should error out since constraints do not have the name
ALTER TABLE products ADD UNIQUE(product_no);
ERROR: cannot create constraint without a name on a distributed table
ALTER TABLE products ADD PRIMARY KEY(product_no);
ALTER TABLE products ADD CHECK(product_no <> 0); ALTER TABLE products ADD CHECK(product_no <> 0);
ERROR: cannot create constraint without a name on a distributed table ERROR: cannot create constraint without a name on a distributed table
ALTER TABLE products ADD EXCLUDE USING btree (product_no with =);
ERROR: cannot create constraint without a name on a distributed table
-- ... with names, we can add/drop the constraints just fine -- ... with names, we can add/drop the constraints just fine
ALTER TABLE products ADD CONSTRAINT nonzero_product_no CHECK(product_no <> 0); ALTER TABLE products ADD CONSTRAINT nonzero_product_no CHECK(product_no <> 0);
ALTER TABLE products ADD CONSTRAINT uniq_product_no EXCLUDE USING btree (product_no with =); ALTER TABLE products ADD CONSTRAINT uniq_product_no EXCLUDE USING btree (product_no with =);
@ -689,6 +684,8 @@ DROP SCHEMA sc3 CASCADE;
NOTICE: drop cascades to 2 other objects NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to table sc3.alter_add_prim_key DETAIL: drop cascades to table sc3.alter_add_prim_key
drop cascades to table sc3.alter_add_unique drop cascades to table sc3.alter_add_unique
CREATE SCHEMA test_auto_explain;
SET search_path TO 'test_auto_explain';
-- Test ALTER TABLE ... ADD CONSTRAINT ... does not cause a crash when auto_explain module is loaded -- Test ALTER TABLE ... ADD CONSTRAINT ... does not cause a crash when auto_explain module is loaded
CREATE TABLE target_table(col_1 int primary key, col_2 int); CREATE TABLE target_table(col_1 int primary key, col_2 int);
SELECT create_distributed_table('target_table','col_1'); SELECT create_distributed_table('target_table','col_1');
@ -720,7 +717,7 @@ SET citus.enable_ddl_propagation TO OFF;
ALTER TABLE target_table ADD CONSTRAINT fkey_167 FOREIGN KEY (col_1) REFERENCES test_ref_table(key) ON DELETE CASCADE; ALTER TABLE target_table ADD CONSTRAINT fkey_167 FOREIGN KEY (col_1) REFERENCES test_ref_table(key) ON DELETE CASCADE;
LOG: duration: xxxx ms plan: LOG: duration: xxxx ms plan:
{ {
"Query Text": "SELECT fk.\"col_1\" FROM ONLY \"public\".\"target_table\" fk LEFT OUTER JOIN ONLY \"public\".\"test_ref_table\" pk ON ( pk.\"key\" OPERATOR(pg_catalog.=) fk.\"col_1\") WHERE pk.\"key\" IS NULL AND (fk.\"col_1\" IS NOT NULL)", "Query Text": "SELECT fk.\"col_1\" FROM ONLY \"test_auto_explain\".\"target_table\" fk LEFT OUTER JOIN ONLY \"test_auto_explain\".\"test_ref_table\" pk ON ( pk.\"key\" OPERATOR(pg_catalog.=) fk.\"col_1\") WHERE pk.\"key\" IS NULL AND (fk.\"col_1\" IS NOT NULL)",
"Plan": { "Plan": {
"Node Type": "Custom Scan", "Node Type": "Custom Scan",
"Custom Plan Provider": "Citus Adaptive", "Custom Plan Provider": "Citus Adaptive",
@ -732,5 +729,9 @@ LOG: duration: xxxx ms plan:
"Citus Explain Scan": "Explain for triggered constraint validation queries during ALTER TABLE commands are not supported by Citus" "Citus Explain Scan": "Explain for triggered constraint validation queries during ALTER TABLE commands are not supported by Citus"
} }
} }
CONTEXT: SQL statement "SELECT fk."col_1" FROM ONLY "public"."target_table" fk LEFT OUTER JOIN ONLY "public"."test_ref_table" pk ON ( pk."key" OPERATOR(pg_catalog.=) fk."col_1") WHERE pk."key" IS NULL AND (fk."col_1" IS NOT NULL)" CONTEXT: SQL statement "SELECT fk."col_1" FROM ONLY "test_auto_explain"."target_table" fk LEFT OUTER JOIN ONLY "test_auto_explain"."test_ref_table" pk ON ( pk."key" OPERATOR(pg_catalog.=) fk."col_1") WHERE pk."key" IS NULL AND (fk."col_1" IS NOT NULL)"
END; END;
RESET citus.enable_ddl_propagation;
SET client_min_messages to ERROR;
SET search_path TO 'public';
DROP SCHEMA test_auto_explain CASCADE;

View File

@ -30,7 +30,7 @@ SELECT con.conname
(1 row) (1 row)
-- Check that the primary key name created on the coordinator is sent to workers and -- Check that the primary key name created on the coordinator is sent to workers and
-- the constraints created for the shard tables conform to the <conname>_shardid scheme. -- the constraints created for the shard tables conform to the <conname>_shardid naming scheme.
\c - - :public_worker_1_host :worker_1_port \c - - :public_worker_1_host :worker_1_port
SELECT con.conname SELECT con.conname
FROM pg_catalog.pg_constraint con FROM pg_catalog.pg_constraint con
@ -44,7 +44,117 @@ SELECT con.conname
\c - - :master_host :master_port \c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_pkey; ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_pkey;
ALTER TABLE AT_AddConstNoName.products ADD PRIMARY KEY(product_no); -- Check "ADD UNIQUE"
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products';
conname
---------------------------------------------------------------------
products_product_no_key
(1 row)
-- Check that UNIQUE constraint name created on the coordinator is sent to workers and
-- the constraints created for the shard tables conform to the <conname>_shardid scheme.
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_5410000';
conname
---------------------------------------------------------------------
products_product_no_key_5410000
(1 row)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_key;
-- Check "ADD UNIQUE" with column name list
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no,name);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products';
conname
---------------------------------------------------------------------
products_product_no_name_key
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_5410000';
conname
---------------------------------------------------------------------
products_product_no_name_key_5410000
(1 row)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_name_key;
-- Check "ADD UNIQUE ... INCLUDE"
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no) INCLUDE(price);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products';
conname
---------------------------------------------------------------------
products_product_no_key
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_5410000';
conname
---------------------------------------------------------------------
products_product_no_key_5410000
(1 row)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_key;
-- Check "ADD UNIQUE NULLS NOT DISTICT"
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
\gset
\if :server_version_ge_15
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE NULLS NOT DISTINCT (product_no, price);
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_price_key;
\endif
-- Check "ADD EXCLUDE"
CREATE EXTENSION btree_gist;
ALTER TABLE AT_AddConstNoName.products ADD EXCLUDE USING gist (name WITH <> , product_no WITH =);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products';
conname
---------------------------------------------------------------------
products_name_product_no_excl
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_5410000';
conname
---------------------------------------------------------------------
products_name_product_no_excl_5410000
(1 row)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_name_product_no_excl;
DROP TABLE AT_AddConstNoName.products; DROP TABLE AT_AddConstNoName.products;
-- Check "ADD PRIMARY KEY" with reference table -- Check "ADD PRIMARY KEY" with reference table
CREATE TABLE AT_AddConstNoName.products_ref ( CREATE TABLE AT_AddConstNoName.products_ref (
@ -74,7 +184,7 @@ SELECT create_reference_table('AT_AddConstNoName.products_ref_3');
(1 row) (1 row)
-- Check for name collisions -- Check that name collisions are handled for PRIMARY KEY.
ALTER TABLE AT_AddConstNoName.products_ref_3 ADD CONSTRAINT products_ref_pkey PRIMARY KEY(name); ALTER TABLE AT_AddConstNoName.products_ref_3 ADD CONSTRAINT products_ref_pkey PRIMARY KEY(name);
ALTER TABLE AT_AddConstNoName.products_ref_2 ADD CONSTRAINT products_ref_pkey1 PRIMARY KEY(name); ALTER TABLE AT_AddConstNoName.products_ref_2 ADD CONSTRAINT products_ref_pkey1 PRIMARY KEY(name);
ALTER TABLE AT_AddConstNoName.products_ref ADD PRIMARY KEY(name); ALTER TABLE AT_AddConstNoName.products_ref ADD PRIMARY KEY(name);
@ -89,8 +199,37 @@ SELECT con.conname
(1 row) (1 row)
ALTER TABLE AT_AddConstNoName.products_ref DROP CONSTRAINT products_ref_pkey2; ALTER TABLE AT_AddConstNoName.products_ref DROP CONSTRAINT products_ref_pkey2;
-- Check that name collisions are handled for UNIQUE.
ALTER TABLE AT_AddConstNoName.products_ref_3 ADD CONSTRAINT products_ref_name_key UNIQUE(name);
ALTER TABLE AT_AddConstNoName.products_ref_2 ADD CONSTRAINT products_ref_name_key1 UNIQUE(name);
ALTER TABLE AT_AddConstNoName.products_ref ADD UNIQUE(name);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_ref';
conname
---------------------------------------------------------------------
products_ref_name_key2
(1 row)
ALTER TABLE AT_AddConstNoName.products_ref DROP CONSTRAINT products_ref_name_key2;
-- Check that name collisions are handled for EXCLUDE
ALTER TABLE AT_AddConstNoName.products_ref_3 ADD CONSTRAINT products_ref_product_no_excl EXCLUDE (product_no WITH =);
ALTER TABLE AT_AddConstNoName.products_ref_2 ADD CONSTRAINT products_ref_product_no_excl1 EXCLUDE (product_no WITH =);
ALTER TABLE AT_AddConstNoName.products_ref ADD EXCLUDE(product_no WITH =);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_ref';
conname
---------------------------------------------------------------------
products_ref_product_no_excl2
(1 row)
DROP TABLE AT_AddConstNoName.products_ref; DROP TABLE AT_AddConstNoName.products_ref;
-- Check with max table name (63 chars) -- Check "ADD PRIMARY KEY" with max table name (63 chars)
CREATE TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglonger ( CREATE TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglonger (
product_no integer, product_no integer,
name text, name text,
@ -144,6 +283,92 @@ SELECT con.conname
--------------------------------------------------------------------- ---------------------------------------------------------------------
(0 rows) (0 rows)
-- Check "ADD UNIQUE" with max table name (63 chars)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglon ADD UNIQUE(product_no);
-- Constraint should be created on the coordinator with a shortened name
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%';
conname
---------------------------------------------------------------------
verylonglonglonglonglonglonglonglonglonglonglong_product_no_key
(1 row)
-- Constraints for the main table and the shards should be created on the worker with a shortened name
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
verylonglonglonglonglonglonglonglonglonglonglo_cd61b0cf_5410006
verylonglonglonglonglonglonglonglonglonglonglo_cd61b0cf_5410007
verylonglonglonglonglonglonglonglonglonglonglo_cd61b0cf_5410008
verylonglonglonglonglonglonglonglonglonglonglo_cd61b0cf_5410009
verylonglonglonglonglonglonglonglonglonglonglong_product_no_key
(5 rows)
-- UNIQUE constraint can be deleted via the coordinator
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglon DROP CONSTRAINT verylonglonglonglonglonglonglonglonglonglonglong_product_no_key;
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%';
conname
---------------------------------------------------------------------
(0 rows)
-- Check "ADD EXCLUDE" with max table name (63 chars)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglon ADD EXCLUDE (product_no WITH =);
-- Constraint should be created on the coordinator with a shortened name
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%';
conname
---------------------------------------------------------------------
verylonglonglonglonglonglonglonglonglonglonglon_product_no_excl
(1 row)
-- Constraints for the main table and the shards should be created on the worker with a shortened name
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
verylonglonglonglonglonglonglonglonglonglonglo_057ed027_5410006
verylonglonglonglonglonglonglonglonglonglonglo_057ed027_5410007
verylonglonglonglonglonglonglonglonglonglonglo_057ed027_5410008
verylonglonglonglonglonglonglonglonglonglonglo_057ed027_5410009
verylonglonglonglonglonglonglonglonglonglonglon_product_no_excl
(5 rows)
-- EXCLUDE constraint can be deleted via the coordinator
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglon DROP CONSTRAINT verylonglonglonglonglonglonglonglonglonglonglon_product_no_excl;
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%';
conname
---------------------------------------------------------------------
(0 rows)
-- Test the scenario where a partitioned distributed table has a child with max allowed name -- Test the scenario where a partitioned distributed table has a child with max allowed name
-- Verify that we switch to sequential execution mode to avoid deadlock in this scenario -- Verify that we switch to sequential execution mode to avoid deadlock in this scenario
\c - - :master_host :master_port \c - - :master_host :master_port
@ -156,9 +381,10 @@ SELECT create_distributed_table('AT_AddConstNoName.dist_partitioned_table', 'par
(1 row) (1 row)
-- Check "ADD PRIMARY KEY"
SET client_min_messages TO DEBUG1; SET client_min_messages TO DEBUG1;
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD PRIMARY KEY(partition_col); ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD PRIMARY KEY(partition_col);
DEBUG: the primary key name on the shards of the partition is too long, switching to sequential and local execution mode to prevent self deadlocks: longlonglonglonglonglonglonglonglonglonglonglo_537570f5_54_pkey DEBUG: the constraint name on the shards of the partition is too long, switching to sequential and local execution mode to prevent self deadlocks: longlonglonglonglonglonglonglonglonglonglonglo_537570f5_54_pkey
DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "dist_partitioned_table_pkey" for table "dist_partitioned_table" DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "dist_partitioned_table_pkey" for table "dist_partitioned_table"
DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "longlonglonglonglonglonglonglonglonglonglonglonglonglonglo_pkey" for table "longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc" DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "longlonglonglonglonglonglonglonglonglonglonglonglonglonglo_pkey" for table "longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc"
DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "p1_pkey" for table "p1" DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "p1_pkey" for table "p1"
@ -202,8 +428,55 @@ SELECT con.conname
--------------------------------------------------------------------- ---------------------------------------------------------------------
(0 rows) (0 rows)
-- Test we error out when creating a primary key on a partition table with a long name if we cannot -- Check "ADD UNIQUE"
\c - - :master_host :master_port
SET client_min_messages TO DEBUG1;
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD UNIQUE(partition_col);
DEBUG: the constraint name on the shards of the partition is too long, switching to sequential and local execution mode to prevent self deadlocks: longlonglonglonglonglonglonglonglonglonglongl_partition_col_key
DEBUG: ALTER TABLE / ADD UNIQUE will create implicit index "dist_partitioned_table_partition_col_key" for table "dist_partitioned_table"
DEBUG: ALTER TABLE / ADD UNIQUE will create implicit index "longlonglonglonglonglonglonglonglonglonglongl_partition_col_key" for table "longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc"
DEBUG: ALTER TABLE / ADD UNIQUE will create implicit index "p1_partition_col_key" for table "p1"
RESET client_min_messages;
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'dist_partitioned_table';
conname
---------------------------------------------------------------------
dist_partitioned_table_partition_col_key
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'longlonglonglonglonglonglonglonglong%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
longlonglonglonglonglonglonglonglonglonglongl__d794d9f1_5410014
longlonglonglonglonglonglonglonglonglonglongl__d794d9f1_5410015
longlonglonglonglonglonglonglonglonglonglongl__d794d9f1_5410016
longlonglonglonglonglonglonglonglonglonglongl__d794d9f1_5410017
longlonglonglonglonglonglonglonglonglonglongl_partition_col_key
(5 rows)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.dist_partitioned_table DROP CONSTRAINT dist_partitioned_table_partition_col_key;
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'longlonglonglonglonglonglonglonglong%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
(0 rows)
-- Test we error out when creating a constraint on a partition table with a long name if we cannot
-- switch to sequential execution -- switch to sequential execution
-- Check "ADD PRIMARY KEY"
\c - - :master_host :master_port \c - - :master_host :master_port
BEGIN; BEGIN;
SELECT count(*) FROM AT_AddConstNoName.dist_partitioned_table; SELECT count(*) FROM AT_AddConstNoName.dist_partitioned_table;
@ -213,7 +486,7 @@ BEGIN;
(1 row) (1 row)
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD PRIMARY KEY(partition_col); ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD PRIMARY KEY(partition_col);
ERROR: The primary key name (longlonglonglonglonglonglonglonglonglonglonglo_537570f5_54_pkey) on a shard is too long and could lead to deadlocks when executed in a transaction block after a parallel query ERROR: The constraint name (longlonglonglonglonglonglonglonglonglonglonglo_537570f5_54_pkey) on a shard is too long and could lead to deadlocks when executed in a transaction block after a parallel query
HINT: Try re-running the transaction with "SET LOCAL citus.multi_shard_modify_mode TO 'sequential';" HINT: Try re-running the transaction with "SET LOCAL citus.multi_shard_modify_mode TO 'sequential';"
ROLLBACK; ROLLBACK;
-- try inside a sequential block -- try inside a sequential block
@ -227,8 +500,33 @@ BEGIN;
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD PRIMARY KEY(partition_col); ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD PRIMARY KEY(partition_col);
ROLLBACK; ROLLBACK;
-- Check "ADD UNIQUE"
\c - - :master_host :master_port
BEGIN;
SELECT count(*) FROM AT_AddConstNoName.dist_partitioned_table;
count
---------------------------------------------------------------------
0
(1 row)
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD UNIQUE(partition_col);
ERROR: The constraint name (longlonglonglonglonglonglonglonglonglonglongl_partition_col_key) on a shard is too long and could lead to deadlocks when executed in a transaction block after a parallel query
HINT: Try re-running the transaction with "SET LOCAL citus.multi_shard_modify_mode TO 'sequential';"
ROLLBACK;
-- try inside a sequential block
BEGIN;
SET LOCAL citus.multi_shard_modify_mode TO 'sequential';
SELECT count(*) FROM AT_AddConstNoName.dist_partitioned_table;
count
---------------------------------------------------------------------
0
(1 row)
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD UNIQUE(partition_col);
ROLLBACK;
DROP TABLE AT_AddConstNoName.dist_partitioned_table; DROP TABLE AT_AddConstNoName.dist_partitioned_table;
-- Test primary key name is generated by postgres for citus local table. -- Test with Citus Local Tables
-- Test "ADD PRIMARY KEY"
\c - - :master_host :master_port \c - - :master_host :master_port
SET client_min_messages to ERROR; SET client_min_messages to ERROR;
SELECT 1 FROM master_add_node('localhost', :master_port, groupId => 0); SELECT 1 FROM master_add_node('localhost', :master_port, groupId => 0);
@ -246,7 +544,7 @@ SELECT citus_add_local_table_to_metadata('AT_AddConstNoName.citus_local_table');
(1 row) (1 row)
ALTER TABLE AT_AddConstNoName.citus_local_table ADD PRIMARY KEY(id); ALTER TABLE AT_AddConstNoName.citus_local_table ADD PRIMARY KEY(id);
-- Check the primary key is created for the local table and its shard. -- Check the primary key is created for the local table and its shard
SELECT con.conname SELECT con.conname
FROM pg_catalog.pg_constraint con FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
@ -289,6 +587,78 @@ SELECT con.conname
citus_local_table_pkey_5410026 citus_local_table_pkey_5410026
(5 rows) (5 rows)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_table DROP CONSTRAINT citus_local_table_pkey;
-- Check "ADD UNIQUE"
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_table ADD UNIQUE(id);
-- Check the UNIQUE constraint is created for the local table and its shard
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'citus_local_table%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
citus_local_table_id_key
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'citus_local_table%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
citus_local_table_id_key
citus_local_table_id_key_5410023
citus_local_table_id_key_5410024
citus_local_table_id_key_5410025
citus_local_table_id_key_5410026
(5 rows)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_table DROP CONSTRAINT citus_local_table_id_key;
-- Check "ADD EXCLUDE"
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_table ADD EXCLUDE(id WITH =);
-- Check the EXCLUDE constraint is created for the local table and its shard
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'citus_local_table%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
citus_local_table_id_excl
(1 row)
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'citus_local_table%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
citus_local_table_id_excl
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'citus_local_table%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
citus_local_table_id_excl
citus_local_table_id_excl_5410023
citus_local_table_id_excl_5410024
citus_local_table_id_excl_5410025
citus_local_table_id_excl_5410026
(5 rows)
\c - - :master_host :master_port \c - - :master_host :master_port
DROP TABLE AT_AddConstNoName.citus_local_table; DROP TABLE AT_AddConstNoName.citus_local_table;
-- Test with partitioned citus local table -- Test with partitioned citus local table
@ -301,6 +671,7 @@ SELECT citus_add_local_table_to_metadata('AT_AddConstNoName.citus_local_partitio
(1 row) (1 row)
-- Check "ADD PRIMARY KEY"
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD PRIMARY KEY(partition_col); ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD PRIMARY KEY(partition_col);
SELECT create_distributed_table('AT_AddConstNoName.citus_local_partitioned_table', 'partition_col'); SELECT create_distributed_table('AT_AddConstNoName.citus_local_partitioned_table', 'partition_col');
create_distributed_table create_distributed_table
@ -311,7 +682,7 @@ SELECT create_distributed_table('AT_AddConstNoName.citus_local_partitioned_table
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_pkey; ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_pkey;
SET client_min_messages TO DEBUG1; SET client_min_messages TO DEBUG1;
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD PRIMARY KEY(partition_col); ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD PRIMARY KEY(partition_col);
DEBUG: the primary key name on the shards of the partition is too long, switching to sequential and local execution mode to prevent self deadlocks: longlonglonglonglonglonglonglonglonglonglonglo_537570f5_54_pkey DEBUG: the constraint name on the shards of the partition is too long, switching to sequential and local execution mode to prevent self deadlocks: longlonglonglonglonglonglonglonglonglonglonglo_537570f5_54_pkey
DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "citus_local_partitioned_table_pkey" for table "citus_local_partitioned_table" DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "citus_local_partitioned_table_pkey" for table "citus_local_partitioned_table"
DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "longlonglonglonglonglonglonglonglonglonglonglonglonglonglo_pkey" for table "longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc" DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "longlonglonglonglonglonglonglonglonglonglonglonglonglonglo_pkey" for table "longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc"
DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "p1_pkey" for table "p1" DEBUG: ALTER TABLE / ADD PRIMARY KEY will create implicit index "p1_pkey" for table "p1"
@ -343,6 +714,46 @@ SELECT con.conname
\c - - :master_host :master_port \c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_pkey; ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_pkey;
-- Check "ADD UNIQUE"
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD UNIQUE(partition_col);
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_partition_col_key;
SET client_min_messages TO DEBUG1;
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD UNIQUE(partition_col);
DEBUG: the constraint name on the shards of the partition is too long, switching to sequential and local execution mode to prevent self deadlocks: longlonglonglonglonglonglonglonglonglonglongl_partition_col_key
DEBUG: ALTER TABLE / ADD UNIQUE will create implicit index "citus_local_partitioned_table_partition_col_key" for table "citus_local_partitioned_table"
DEBUG: ALTER TABLE / ADD UNIQUE will create implicit index "longlonglonglonglonglonglonglonglonglonglongl_partition_col_key" for table "longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc"
DEBUG: ALTER TABLE / ADD UNIQUE will create implicit index "p1_partition_col_key" for table "p1"
RESET client_min_messages;
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'citus_local_partitioned_table';
conname
---------------------------------------------------------------------
citus_local_partitioned_table_partition_col_key
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'longlonglonglonglonglonglonglonglong%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
longlonglonglonglonglonglonglonglonglonglongl__d794d9f1_5410034
longlonglonglonglonglonglonglonglonglonglongl__d794d9f1_5410035
longlonglonglonglonglonglonglonglonglonglongl__d794d9f1_5410036
longlonglonglonglonglonglonglonglonglonglongl__d794d9f1_5410037
longlonglonglonglonglonglonglonglonglonglongl_partition_col_key
(5 rows)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_partition_col_key;
-- Check "ADD EXCLUDE" errors out for partitioned table since the postgres does not allow it
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD EXCLUDE(partition_col WITH =);
ERROR: exclusion constraints are not supported on partitioned tables
SELECT 1 FROM master_remove_node('localhost', :master_port); SELECT 1 FROM master_remove_node('localhost', :master_port);
?column? ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -357,6 +768,7 @@ SELECT create_distributed_table('AT_AddConstNoName."2nd table"','2nd id');
(1 row) (1 row)
-- Check "ADD PRIMARY KEY"
ALTER TABLE AT_AddConstNoName."2nd table" ADD PRIMARY KEY ("2nd id", "3rd id"); ALTER TABLE AT_AddConstNoName."2nd table" ADD PRIMARY KEY ("2nd id", "3rd id");
SELECT con.conname SELECT con.conname
FROM pg_catalog.pg_constraint con FROM pg_catalog.pg_constraint con
@ -386,6 +798,67 @@ SELECT con.conname
\c - - :master_host :master_port \c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName."2nd table" DROP CONSTRAINT "2nd table_pkey"; ALTER TABLE AT_AddConstNoName."2nd table" DROP CONSTRAINT "2nd table_pkey";
-- Check "ADD UNIQUE"
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName."2nd table" ADD UNIQUE ("2nd id", "3rd id");
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = '2nd table';
conname
---------------------------------------------------------------------
2nd table_2nd id_3rd id_key
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE '2nd table%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
2nd table_2nd id_3rd id_key
2nd table_2nd id_3rd id_key_5410042
2nd table_2nd id_3rd id_key_5410043
2nd table_2nd id_3rd id_key_5410044
2nd table_2nd id_3rd id_key_5410045
(5 rows)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName."2nd table" DROP CONSTRAINT "2nd table_2nd id_3rd id_key";
-- Check "ADD EXCLUDE"
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName."2nd table" ADD EXCLUDE ("2nd id" WITH =);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = '2nd table';
conname
---------------------------------------------------------------------
2nd table_2nd id_excl
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE '2nd table%' ORDER BY con.conname ASC;
conname
---------------------------------------------------------------------
2nd table_2nd id_excl
2nd table_2nd id_excl_5410042
2nd table_2nd id_excl_5410043
2nd table_2nd id_excl_5410044
2nd table_2nd id_excl_5410045
(5 rows)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName."2nd table" DROP CONSTRAINT "2nd table_2nd id_excl";
DROP EXTENSION btree_gist;
DROP SCHEMA AT_AddConstNoName CASCADE; DROP SCHEMA AT_AddConstNoName CASCADE;
NOTICE: drop cascades to 6 other objects NOTICE: drop cascades to 6 other objects
DETAIL: drop cascades to table at_addconstnoname.products_ref_2 DETAIL: drop cascades to table at_addconstnoname.products_ref_2

View File

@ -68,10 +68,6 @@ ALTER TABLE name_lengths ADD COLUMN float_col_1234567890123456789012345678901234
ALTER TABLE name_lengths ADD COLUMN date_col_12345678901234567890123456789012345678901234567890 DATE; ALTER TABLE name_lengths ADD COLUMN date_col_12345678901234567890123456789012345678901234567890 DATE;
ALTER TABLE name_lengths ADD COLUMN int_col_12345678901234567890123456789012345678901234567890 INTEGER DEFAULT 1; ALTER TABLE name_lengths ADD COLUMN int_col_12345678901234567890123456789012345678901234567890 INTEGER DEFAULT 1;
-- Placeholders for unsupported ALTER TABLE to add constraints with implicit names that are likely too long -- Placeholders for unsupported ALTER TABLE to add constraints with implicit names that are likely too long
ALTER TABLE name_lengths ADD UNIQUE (float_col_12345678901234567890123456789012345678901234567890);
ERROR: cannot create constraint without a name on a distributed table
ALTER TABLE name_lengths ADD EXCLUDE (int_col_12345678901234567890123456789012345678901234567890 WITH =);
ERROR: cannot create constraint without a name on a distributed table
ALTER TABLE name_lengths ADD CHECK (date_col_12345678901234567890123456789012345678901234567890 > '2014-01-01'::date); ALTER TABLE name_lengths ADD CHECK (date_col_12345678901234567890123456789012345678901234567890 > '2014-01-01'::date);
ERROR: cannot create constraint without a name on a distributed table ERROR: cannot create constraint without a name on a distributed table
\c - - :public_worker_1_host :worker_1_port \c - - :public_worker_1_host :worker_1_port

View File

@ -378,10 +378,7 @@ ALTER TABLE products ADD CONSTRAINT unn_1 UNIQUE(product_no, price), ADD CONSTRA
-- Tests for constraints without name -- Tests for constraints without name
-- Commands below should error out since constraints do not have the name -- Commands below should error out since constraints do not have the name
ALTER TABLE products ADD UNIQUE(product_no);
ALTER TABLE products ADD PRIMARY KEY(product_no);
ALTER TABLE products ADD CHECK(product_no <> 0); ALTER TABLE products ADD CHECK(product_no <> 0);
ALTER TABLE products ADD EXCLUDE USING btree (product_no with =);
-- ... with names, we can add/drop the constraints just fine -- ... with names, we can add/drop the constraints just fine
ALTER TABLE products ADD CONSTRAINT nonzero_product_no CHECK(product_no <> 0); ALTER TABLE products ADD CONSTRAINT nonzero_product_no CHECK(product_no <> 0);
@ -576,6 +573,9 @@ DROP SCHEMA sc1 CASCADE;
DROP SCHEMA sc2 CASCADE; DROP SCHEMA sc2 CASCADE;
DROP SCHEMA sc3 CASCADE; DROP SCHEMA sc3 CASCADE;
CREATE SCHEMA test_auto_explain;
SET search_path TO 'test_auto_explain';
-- Test ALTER TABLE ... ADD CONSTRAINT ... does not cause a crash when auto_explain module is loaded -- Test ALTER TABLE ... ADD CONSTRAINT ... does not cause a crash when auto_explain module is loaded
CREATE TABLE target_table(col_1 int primary key, col_2 int); CREATE TABLE target_table(col_1 int primary key, col_2 int);
SELECT create_distributed_table('target_table','col_1'); SELECT create_distributed_table('target_table','col_1');
@ -598,3 +598,9 @@ SET citus.enable_ddl_propagation TO OFF;
-- alter table triggers SELECT, and auto_explain catches that -- alter table triggers SELECT, and auto_explain catches that
ALTER TABLE target_table ADD CONSTRAINT fkey_167 FOREIGN KEY (col_1) REFERENCES test_ref_table(key) ON DELETE CASCADE; ALTER TABLE target_table ADD CONSTRAINT fkey_167 FOREIGN KEY (col_1) REFERENCES test_ref_table(key) ON DELETE CASCADE;
END; END;
RESET citus.enable_ddl_propagation;
SET client_min_messages to ERROR;
SET search_path TO 'public';
DROP SCHEMA test_auto_explain CASCADE;

View File

@ -26,7 +26,7 @@ SELECT con.conname
WHERE rel.relname = 'products'; WHERE rel.relname = 'products';
-- Check that the primary key name created on the coordinator is sent to workers and -- Check that the primary key name created on the coordinator is sent to workers and
-- the constraints created for the shard tables conform to the <conname>_shardid scheme. -- the constraints created for the shard tables conform to the <conname>_shardid naming scheme.
\c - - :public_worker_1_host :worker_1_port \c - - :public_worker_1_host :worker_1_port
SELECT con.conname SELECT con.conname
FROM pg_catalog.pg_constraint con FROM pg_catalog.pg_constraint con
@ -37,7 +37,94 @@ SELECT con.conname
\c - - :master_host :master_port \c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_pkey; ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_pkey;
ALTER TABLE AT_AddConstNoName.products ADD PRIMARY KEY(product_no); -- Check "ADD UNIQUE"
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products';
-- Check that UNIQUE constraint name created on the coordinator is sent to workers and
-- the constraints created for the shard tables conform to the <conname>_shardid scheme.
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_5410000';
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_key;
-- Check "ADD UNIQUE" with column name list
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no,name);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products';
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_5410000';
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_name_key;
-- Check "ADD UNIQUE ... INCLUDE"
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no) INCLUDE(price);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products';
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_5410000';
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_key;
-- Check "ADD UNIQUE NULLS NOT DISTICT"
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
\gset
\if :server_version_ge_15
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE NULLS NOT DISTINCT (product_no, price);
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_price_key;
\endif
-- Check "ADD EXCLUDE"
CREATE EXTENSION btree_gist;
ALTER TABLE AT_AddConstNoName.products ADD EXCLUDE USING gist (name WITH <> , product_no WITH =);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products';
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_5410000';
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_name_product_no_excl;
DROP TABLE AT_AddConstNoName.products; DROP TABLE AT_AddConstNoName.products;
@ -63,7 +150,7 @@ CREATE TABLE AT_AddConstNoName.products_ref_3 (
SELECT create_reference_table('AT_AddConstNoName.products_ref'); SELECT create_reference_table('AT_AddConstNoName.products_ref');
SELECT create_reference_table('AT_AddConstNoName.products_ref_3'); SELECT create_reference_table('AT_AddConstNoName.products_ref_3');
-- Check for name collisions -- Check that name collisions are handled for PRIMARY KEY.
ALTER TABLE AT_AddConstNoName.products_ref_3 ADD CONSTRAINT products_ref_pkey PRIMARY KEY(name); ALTER TABLE AT_AddConstNoName.products_ref_3 ADD CONSTRAINT products_ref_pkey PRIMARY KEY(name);
ALTER TABLE AT_AddConstNoName.products_ref_2 ADD CONSTRAINT products_ref_pkey1 PRIMARY KEY(name); ALTER TABLE AT_AddConstNoName.products_ref_2 ADD CONSTRAINT products_ref_pkey1 PRIMARY KEY(name);
ALTER TABLE AT_AddConstNoName.products_ref ADD PRIMARY KEY(name); ALTER TABLE AT_AddConstNoName.products_ref ADD PRIMARY KEY(name);
@ -76,9 +163,33 @@ SELECT con.conname
ALTER TABLE AT_AddConstNoName.products_ref DROP CONSTRAINT products_ref_pkey2; ALTER TABLE AT_AddConstNoName.products_ref DROP CONSTRAINT products_ref_pkey2;
-- Check that name collisions are handled for UNIQUE.
ALTER TABLE AT_AddConstNoName.products_ref_3 ADD CONSTRAINT products_ref_name_key UNIQUE(name);
ALTER TABLE AT_AddConstNoName.products_ref_2 ADD CONSTRAINT products_ref_name_key1 UNIQUE(name);
ALTER TABLE AT_AddConstNoName.products_ref ADD UNIQUE(name);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_ref';
ALTER TABLE AT_AddConstNoName.products_ref DROP CONSTRAINT products_ref_name_key2;
-- Check that name collisions are handled for EXCLUDE
ALTER TABLE AT_AddConstNoName.products_ref_3 ADD CONSTRAINT products_ref_product_no_excl EXCLUDE (product_no WITH =);
ALTER TABLE AT_AddConstNoName.products_ref_2 ADD CONSTRAINT products_ref_product_no_excl1 EXCLUDE (product_no WITH =);
ALTER TABLE AT_AddConstNoName.products_ref ADD EXCLUDE(product_no WITH =);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_ref';
DROP TABLE AT_AddConstNoName.products_ref; DROP TABLE AT_AddConstNoName.products_ref;
-- Check with max table name (63 chars) -- Check "ADD PRIMARY KEY" with max table name (63 chars)
CREATE TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglonger ( CREATE TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglonger (
product_no integer, product_no integer,
name text, name text,
@ -108,6 +219,66 @@ SELECT con.conname
\c - - :master_host :master_port \c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglon DROP CONSTRAINT verylonglonglonglonglonglonglonglonglonglonglonglonglonglo_pkey; ALTER TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglon DROP CONSTRAINT verylonglonglonglonglonglonglonglonglonglonglonglonglonglo_pkey;
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%';
-- Check "ADD UNIQUE" with max table name (63 chars)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglon ADD UNIQUE(product_no);
-- Constraint should be created on the coordinator with a shortened name
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%';
-- Constraints for the main table and the shards should be created on the worker with a shortened name
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%' ORDER BY con.conname ASC;
-- UNIQUE constraint can be deleted via the coordinator
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglon DROP CONSTRAINT verylonglonglonglonglonglonglonglonglonglonglong_product_no_key;
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%';
-- Check "ADD EXCLUDE" with max table name (63 chars)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglon ADD EXCLUDE (product_no WITH =);
-- Constraint should be created on the coordinator with a shortened name
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%';
-- Constraints for the main table and the shards should be created on the worker with a shortened name
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'very%' ORDER BY con.conname ASC;
-- EXCLUDE constraint can be deleted via the coordinator
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.verylonglonglonglonglonglonglonglonglonglonglonglonglonglonglon DROP CONSTRAINT verylonglonglonglonglonglonglonglonglonglonglon_product_no_excl;
\c - - :public_worker_1_host :worker_1_port \c - - :public_worker_1_host :worker_1_port
SELECT con.conname SELECT con.conname
FROM pg_catalog.pg_constraint con FROM pg_catalog.pg_constraint con
@ -123,6 +294,7 @@ CREATE TABLE AT_AddConstNoName.p1 PARTITION OF AT_AddConstNoName.dist_partitione
CREATE TABLE AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc PARTITION OF AT_AddConstNoName.dist_partitioned_table FOR VALUES FROM ('2020-01-01') TO ('2021-01-01'); CREATE TABLE AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc PARTITION OF AT_AddConstNoName.dist_partitioned_table FOR VALUES FROM ('2020-01-01') TO ('2021-01-01');
SELECT create_distributed_table('AT_AddConstNoName.dist_partitioned_table', 'partition_col'); SELECT create_distributed_table('AT_AddConstNoName.dist_partitioned_table', 'partition_col');
-- Check "ADD PRIMARY KEY"
SET client_min_messages TO DEBUG1; SET client_min_messages TO DEBUG1;
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD PRIMARY KEY(partition_col); ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD PRIMARY KEY(partition_col);
RESET client_min_messages; RESET client_min_messages;
@ -150,8 +322,39 @@ SELECT con.conname
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'longlonglonglonglonglonglonglonglong%' ORDER BY con.conname ASC; WHERE rel.relname LIKE 'longlonglonglonglonglonglonglonglong%' ORDER BY con.conname ASC;
-- Test we error out when creating a primary key on a partition table with a long name if we cannot -- Check "ADD UNIQUE"
\c - - :master_host :master_port
SET client_min_messages TO DEBUG1;
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD UNIQUE(partition_col);
RESET client_min_messages;
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'dist_partitioned_table';
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'longlonglonglonglonglonglonglonglong%' ORDER BY con.conname ASC;
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.dist_partitioned_table DROP CONSTRAINT dist_partitioned_table_partition_col_key;
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'longlonglonglonglonglonglonglonglong%' ORDER BY con.conname ASC;
-- Test we error out when creating a constraint on a partition table with a long name if we cannot
-- switch to sequential execution -- switch to sequential execution
-- Check "ADD PRIMARY KEY"
\c - - :master_host :master_port \c - - :master_host :master_port
BEGIN; BEGIN;
SELECT count(*) FROM AT_AddConstNoName.dist_partitioned_table; SELECT count(*) FROM AT_AddConstNoName.dist_partitioned_table;
@ -164,9 +367,24 @@ BEGIN;
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD PRIMARY KEY(partition_col); ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD PRIMARY KEY(partition_col);
ROLLBACK; ROLLBACK;
-- Check "ADD UNIQUE"
\c - - :master_host :master_port
BEGIN;
SELECT count(*) FROM AT_AddConstNoName.dist_partitioned_table;
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD UNIQUE(partition_col);
ROLLBACK;
-- try inside a sequential block
BEGIN;
SET LOCAL citus.multi_shard_modify_mode TO 'sequential';
SELECT count(*) FROM AT_AddConstNoName.dist_partitioned_table;
ALTER TABLE AT_AddConstNoName.dist_partitioned_table ADD UNIQUE(partition_col);
ROLLBACK;
DROP TABLE AT_AddConstNoName.dist_partitioned_table; DROP TABLE AT_AddConstNoName.dist_partitioned_table;
-- Test primary key name is generated by postgres for citus local table. -- Test with Citus Local Tables
-- Test "ADD PRIMARY KEY"
\c - - :master_host :master_port \c - - :master_host :master_port
SET client_min_messages to ERROR; SET client_min_messages to ERROR;
SELECT 1 FROM master_add_node('localhost', :master_port, groupId => 0); SELECT 1 FROM master_add_node('localhost', :master_port, groupId => 0);
@ -177,7 +395,7 @@ SELECT citus_add_local_table_to_metadata('AT_AddConstNoName.citus_local_table');
ALTER TABLE AT_AddConstNoName.citus_local_table ADD PRIMARY KEY(id); ALTER TABLE AT_AddConstNoName.citus_local_table ADD PRIMARY KEY(id);
-- Check the primary key is created for the local table and its shard. -- Check the primary key is created for the local table and its shard
SELECT con.conname SELECT con.conname
FROM pg_catalog.pg_constraint con FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
@ -186,6 +404,54 @@ SELECT con.conname
SELECT create_distributed_table('AT_AddConstNoName.citus_local_table','id'); SELECT create_distributed_table('AT_AddConstNoName.citus_local_table','id');
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'citus_local_table%' ORDER BY con.conname ASC;
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'citus_local_table%' ORDER BY con.conname ASC;
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_table DROP CONSTRAINT citus_local_table_pkey;
-- Check "ADD UNIQUE"
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_table ADD UNIQUE(id);
-- Check the UNIQUE constraint is created for the local table and its shard
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'citus_local_table%' ORDER BY con.conname ASC;
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'citus_local_table%' ORDER BY con.conname ASC;
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_table DROP CONSTRAINT citus_local_table_id_key;
-- Check "ADD EXCLUDE"
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_table ADD EXCLUDE(id WITH =);
-- Check the EXCLUDE constraint is created for the local table and its shard
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'citus_local_table%' ORDER BY con.conname ASC;
SELECT con.conname SELECT con.conname
FROM pg_catalog.pg_constraint con FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
@ -208,6 +474,7 @@ CREATE TABLE AT_AddConstNoName.p1 PARTITION OF AT_AddConstNoName.citus_local_par
CREATE TABLE AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc PARTITION OF AT_AddConstNoName.citus_local_partitioned_table FOR VALUES FROM ('2020-01-01') TO ('2021-01-01'); CREATE TABLE AT_AddConstNoName.longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc PARTITION OF AT_AddConstNoName.citus_local_partitioned_table FOR VALUES FROM ('2020-01-01') TO ('2021-01-01');
SELECT citus_add_local_table_to_metadata('AT_AddConstNoName.citus_local_partitioned_table'); SELECT citus_add_local_table_to_metadata('AT_AddConstNoName.citus_local_partitioned_table');
-- Check "ADD PRIMARY KEY"
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD PRIMARY KEY(partition_col); ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD PRIMARY KEY(partition_col);
SELECT create_distributed_table('AT_AddConstNoName.citus_local_partitioned_table', 'partition_col'); SELECT create_distributed_table('AT_AddConstNoName.citus_local_partitioned_table', 'partition_col');
@ -234,12 +501,41 @@ SELECT con.conname
\c - - :master_host :master_port \c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_pkey; ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_pkey;
-- Check "ADD UNIQUE"
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD UNIQUE(partition_col);
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_partition_col_key;
SET client_min_messages TO DEBUG1;
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD UNIQUE(partition_col);
RESET client_min_messages;
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'citus_local_partitioned_table';
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'longlonglonglonglonglonglonglonglong%' ORDER BY con.conname ASC;
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_partition_col_key;
-- Check "ADD EXCLUDE" errors out for partitioned table since the postgres does not allow it
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD EXCLUDE(partition_col WITH =);
SELECT 1 FROM master_remove_node('localhost', :master_port); SELECT 1 FROM master_remove_node('localhost', :master_port);
-- Test with unusual table and column names -- Test with unusual table and column names
CREATE TABLE AT_AddConstNoName."2nd table" ( "2nd id" INTEGER, "3rd id" INTEGER); CREATE TABLE AT_AddConstNoName."2nd table" ( "2nd id" INTEGER, "3rd id" INTEGER);
SELECT create_distributed_table('AT_AddConstNoName."2nd table"','2nd id'); SELECT create_distributed_table('AT_AddConstNoName."2nd table"','2nd id');
-- Check "ADD PRIMARY KEY"
ALTER TABLE AT_AddConstNoName."2nd table" ADD PRIMARY KEY ("2nd id", "3rd id"); ALTER TABLE AT_AddConstNoName."2nd table" ADD PRIMARY KEY ("2nd id", "3rd id");
SELECT con.conname SELECT con.conname
FROM pg_catalog.pg_constraint con FROM pg_catalog.pg_constraint con
@ -258,4 +554,45 @@ SELECT con.conname
\c - - :master_host :master_port \c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName."2nd table" DROP CONSTRAINT "2nd table_pkey"; ALTER TABLE AT_AddConstNoName."2nd table" DROP CONSTRAINT "2nd table_pkey";
-- Check "ADD UNIQUE"
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName."2nd table" ADD UNIQUE ("2nd id", "3rd id");
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = '2nd table';
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE '2nd table%' ORDER BY con.conname ASC;
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName."2nd table" DROP CONSTRAINT "2nd table_2nd id_3rd id_key";
-- Check "ADD EXCLUDE"
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName."2nd table" ADD EXCLUDE ("2nd id" WITH =);
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = '2nd table';
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE '2nd table%' ORDER BY con.conname ASC;
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName."2nd table" DROP CONSTRAINT "2nd table_2nd id_excl";
DROP EXTENSION btree_gist;
DROP SCHEMA AT_AddConstNoName CASCADE; DROP SCHEMA AT_AddConstNoName CASCADE;

View File

@ -46,8 +46,6 @@ ALTER TABLE name_lengths ADD COLUMN date_col_12345678901234567890123456789012345
ALTER TABLE name_lengths ADD COLUMN int_col_12345678901234567890123456789012345678901234567890 INTEGER DEFAULT 1; ALTER TABLE name_lengths ADD COLUMN int_col_12345678901234567890123456789012345678901234567890 INTEGER DEFAULT 1;
-- Placeholders for unsupported ALTER TABLE to add constraints with implicit names that are likely too long -- Placeholders for unsupported ALTER TABLE to add constraints with implicit names that are likely too long
ALTER TABLE name_lengths ADD UNIQUE (float_col_12345678901234567890123456789012345678901234567890);
ALTER TABLE name_lengths ADD EXCLUDE (int_col_12345678901234567890123456789012345678901234567890 WITH =);
ALTER TABLE name_lengths ADD CHECK (date_col_12345678901234567890123456789012345678901234567890 > '2014-01-01'::date); ALTER TABLE name_lengths ADD CHECK (date_col_12345678901234567890123456789012345678901234567890 > '2014-01-01'::date);
\c - - :public_worker_1_host :worker_1_port \c - - :public_worker_1_host :worker_1_port