citus/src/test/regress/output/multi_alter_table_statement...

1262 lines
51 KiB
Plaintext

--
-- MULTI_ALTER_TABLE_STATEMENTS
--
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 220000;
-- Check that we can run ALTER TABLE statements on distributed tables.
-- We set the shardid sequence here so that the shardids in this test
-- aren't affected by changes to the previous tests.
CREATE TABLE lineitem_alter (
l_orderkey bigint not null,
l_partkey integer not null,
l_suppkey integer not null,
l_linenumber integer not null,
l_quantity decimal(15, 2) not null,
l_extendedprice decimal(15, 2) not null,
l_discount decimal(15, 2) not null,
l_tax decimal(15, 2) not null,
l_returnflag char(1) not null,
l_linestatus char(1) not null,
l_shipdate date not null,
l_commitdate date not null,
l_receiptdate date not null,
l_shipinstruct char(25) not null,
l_shipmode char(10) not null,
l_comment varchar(44) not null
)
WITH ( fillfactor = 80 );
SELECT create_distributed_table('lineitem_alter', 'l_orderkey', 'append');
create_distributed_table
--------------------------
(1 row)
SELECT master_create_empty_shard('lineitem_alter') AS shardid \gset
copy lineitem_alter FROM '@abs_srcdir@/data/lineitem.1.data' with (delimiter '|', append_to_shard :shardid);
-- verify that the storage options made it to the table definitions
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
relname | reloptions
----------------+-----------------
lineitem_alter | {fillfactor=80}
(1 row)
\c - - - :worker_1_port
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' ORDER BY relname;
relname | reloptions
-----------------------+-----------------
lineitem_alter_220000 | {fillfactor=80}
(1 row)
\c - - - :master_port
-- Verify that we can add columns
ALTER TABLE lineitem_alter ADD COLUMN float_column FLOAT;
ALTER TABLE lineitem_alter ADD COLUMN date_column DATE;
ALTER TABLE lineitem_alter ADD COLUMN int_column1 INTEGER DEFAULT 1;
ALTER TABLE lineitem_alter ADD COLUMN int_column2 INTEGER DEFAULT 2;
ALTER TABLE lineitem_alter ADD COLUMN null_column INTEGER;
-- show changed schema on one worker
\c - - - :worker_1_port
SELECT attname, atttypid::regtype
FROM
(SELECT oid FROM pg_class WHERE relname LIKE 'lineitem_alter_%' ORDER BY relname LIMIT 1) pc
JOIN pg_attribute ON (pc.oid = pg_attribute.attrelid)
ORDER BY attnum;
attname | atttypid
-----------------+-------------------
tableoid | oid
cmax | cid
xmax | xid
cmin | cid
xmin | xid
ctid | tid
l_orderkey | bigint
l_partkey | integer
l_suppkey | integer
l_linenumber | integer
l_quantity | numeric
l_extendedprice | numeric
l_discount | numeric
l_tax | numeric
l_returnflag | character
l_linestatus | character
l_shipdate | date
l_commitdate | date
l_receiptdate | date
l_shipinstruct | character
l_shipmode | character
l_comment | character varying
float_column | double precision
date_column | date
int_column1 | integer
int_column2 | integer
null_column | integer
(27 rows)
\c - - - :master_port
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
Column | Type | Modifiers
-----------------+-----------------------+-----------
l_orderkey | bigint | not null
l_partkey | integer | not null
l_suppkey | integer | not null
l_linenumber | integer | not null
l_quantity | numeric(15,2) | not null
l_extendedprice | numeric(15,2) | not null
l_discount | numeric(15,2) | not null
l_tax | numeric(15,2) | not null
l_returnflag | character(1) | not null
l_linestatus | character(1) | not null
l_shipdate | date | not null
l_commitdate | date | not null
l_receiptdate | date | not null
l_shipinstruct | character(25) | not null
l_shipmode | character(10) | not null
l_comment | character varying(44) | not null
float_column | double precision |
date_column | date |
int_column1 | integer | default 1
int_column2 | integer | default 2
null_column | integer |
(21 rows)
SELECT float_column, count(*) FROM lineitem_alter GROUP BY float_column;
float_column | count
--------------+-------
| 6000
(1 row)
SELECT int_column1, count(*) FROM lineitem_alter GROUP BY int_column1;
int_column1 | count
-------------+-------
1 | 6000
(1 row)
-- Verify that SET|DROP DEFAULT works
ALTER TABLE lineitem_alter ALTER COLUMN float_column SET DEFAULT 1;
ALTER TABLE lineitem_alter ALTER COLUMN int_column1 DROP DEFAULT;
-- \copy to verify that default values take effect
SELECT master_create_empty_shard('lineitem_alter') as shardid \gset
copy lineitem_alter (l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment) FROM '@abs_srcdir@/data/lineitem.1.data' with (delimiter '|', append_to_shard :shardid);
SELECT float_column, count(*) FROM lineitem_alter GROUP BY float_column;
float_column | count
--------------+-------
| 6000
1 | 6000
(2 rows)
SELECT int_column1, count(*) FROM lineitem_alter GROUP BY int_column1;
int_column1 | count
-------------+-------
| 6000
1 | 6000
(2 rows)
-- Verify that SET NOT NULL works
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 SET NOT NULL;
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
Column | Type | Modifiers
-----------------+-----------------------+--------------------
l_orderkey | bigint | not null
l_partkey | integer | not null
l_suppkey | integer | not null
l_linenumber | integer | not null
l_quantity | numeric(15,2) | not null
l_extendedprice | numeric(15,2) | not null
l_discount | numeric(15,2) | not null
l_tax | numeric(15,2) | not null
l_returnflag | character(1) | not null
l_linestatus | character(1) | not null
l_shipdate | date | not null
l_commitdate | date | not null
l_receiptdate | date | not null
l_shipinstruct | character(25) | not null
l_shipmode | character(10) | not null
l_comment | character varying(44) | not null
float_column | double precision | default 1
date_column | date |
int_column1 | integer |
int_column2 | integer | not null default 2
null_column | integer |
(21 rows)
-- Drop default so that NULLs will be inserted for this column
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 DROP DEFAULT;
-- \copy should fail because it will try to insert NULLs for a NOT NULL column
-- Note, this operation will create a table on the workers but it won't be in the metadata
BEGIN;
SELECT master_create_empty_shard('lineitem_alter') as shardid \gset
copy lineitem_alter (l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment) FROM '@abs_srcdir@/data/lineitem.1.data' with (delimiter '|', append_to_shard :shardid);
ERROR: null value in column "int_column2" of relation "lineitem_alter_220002" violates not-null constraint
DETAIL: Failing row contains (1, 155190, 7706, 1, 17.00, 21168.23, 0.04, 0.02, N, O, 1996-03-13, 1996-02-12, 1996-03-22, DELIVER IN PERSON , TRUCK , egular courts above the, 1, null, null, null, null).
END;
-- Verify that DROP NOT NULL works
ALTER TABLE lineitem_alter ALTER COLUMN int_column2 DROP NOT NULL;
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
Column | Type | Modifiers
-----------------+-----------------------+-----------
l_orderkey | bigint | not null
l_partkey | integer | not null
l_suppkey | integer | not null
l_linenumber | integer | not null
l_quantity | numeric(15,2) | not null
l_extendedprice | numeric(15,2) | not null
l_discount | numeric(15,2) | not null
l_tax | numeric(15,2) | not null
l_returnflag | character(1) | not null
l_linestatus | character(1) | not null
l_shipdate | date | not null
l_commitdate | date | not null
l_receiptdate | date | not null
l_shipinstruct | character(25) | not null
l_shipmode | character(10) | not null
l_comment | character varying(44) | not null
float_column | double precision | default 1
date_column | date |
int_column1 | integer |
int_column2 | integer |
null_column | integer |
(21 rows)
-- \copy should succeed now
SELECT master_create_empty_shard('lineitem_alter') as shardid \gset
copy lineitem_alter (l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment) FROM '@abs_srcdir@/data/lineitem.1.data' with (delimiter '|', append_to_shard :shardid);
SELECT count(*) from lineitem_alter;
count
-------
18000
(1 row)
-- Verify that SET DATA TYPE works
SELECT int_column2, pg_typeof(int_column2), count(*) from lineitem_alter GROUP BY int_column2;
int_column2 | pg_typeof | count
-------------+-----------+-------
| integer | 6000
2 | integer | 12000
(2 rows)
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;
Column | Type | Modifiers
-----------------+-----------------------+-----------
l_orderkey | bigint | not null
l_partkey | integer | not null
l_suppkey | integer | not null
l_linenumber | integer | not null
l_quantity | numeric(15,2) | not null
l_extendedprice | numeric(15,2) | not null
l_discount | numeric(15,2) | not null
l_tax | numeric(15,2) | not null
l_returnflag | character(1) | not null
l_linestatus | character(1) | not null
l_shipdate | date | not null
l_commitdate | date | not null
l_receiptdate | date | not null
l_shipinstruct | character(25) | not null
l_shipmode | character(10) | not null
l_comment | character varying(44) | not null
float_column | double precision | default 1
date_column | date |
int_column1 | integer |
int_column2 | double precision |
null_column | integer |
(21 rows)
SELECT int_column2, pg_typeof(int_column2), count(*) from lineitem_alter GROUP BY int_column2;
int_column2 | pg_typeof | count
-------------+------------------+-------
| double precision | 6000
2 | double precision | 12000
(2 rows)
-- Verify that DROP COLUMN works
ALTER TABLE lineitem_alter DROP COLUMN int_column1;
ALTER TABLE lineitem_alter DROP COLUMN float_column;
ALTER TABLE lineitem_alter DROP COLUMN date_column;
-- Verify that RENAME COLUMN works
ALTER TABLE lineitem_alter RENAME COLUMN l_orderkey TO l_orderkey_renamed;
SELECT SUM(l_orderkey_renamed) FROM lineitem_alter;
sum
----------
53620791
(1 row)
-- Verify that IF EXISTS works as expected
ALTER TABLE non_existent_table ADD COLUMN new_column INTEGER;
ERROR: relation "non_existent_table" does not exist
ALTER TABLE IF EXISTS non_existent_table ADD COLUMN new_column INTEGER;
NOTICE: relation "non_existent_table" does not exist, skipping
ALTER TABLE IF EXISTS lineitem_alter ALTER COLUMN int_column2 SET DATA TYPE INTEGER;
ALTER TABLE lineitem_alter DROP COLUMN non_existent_column;
ERROR: column "non_existent_column" of relation "lineitem_alter" does not exist
ALTER TABLE lineitem_alter DROP COLUMN IF EXISTS non_existent_column;
NOTICE: column "non_existent_column" of relation "lineitem_alter" does not exist, skipping
ALTER TABLE lineitem_alter DROP COLUMN IF EXISTS int_column2;
-- Verify with IF EXISTS for extant table
ALTER TABLE IF EXISTS lineitem_alter RENAME COLUMN l_orderkey_renamed TO l_orderkey;
SELECT SUM(l_orderkey) FROM lineitem_alter;
sum
----------
53620791
(1 row)
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
Column | Type | Modifiers
-----------------+-----------------------+-----------
l_orderkey | bigint | not null
l_partkey | integer | not null
l_suppkey | integer | not null
l_linenumber | integer | not null
l_quantity | numeric(15,2) | not null
l_extendedprice | numeric(15,2) | not null
l_discount | numeric(15,2) | not null
l_tax | numeric(15,2) | not null
l_returnflag | character(1) | not null
l_linestatus | character(1) | not null
l_shipdate | date | not null
l_commitdate | date | not null
l_receiptdate | date | not null
l_shipinstruct | character(25) | not null
l_shipmode | character(10) | not null
l_comment | character varying(44) | not null
null_column | integer |
(17 rows)
-- Verify that we can execute commands with multiple subcommands
ALTER TABLE lineitem_alter ADD COLUMN int_column1 INTEGER,
ADD COLUMN int_column2 INTEGER;
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
Column | Type | Modifiers
-----------------+-----------------------+-----------
l_orderkey | bigint | not null
l_partkey | integer | not null
l_suppkey | integer | not null
l_linenumber | integer | not null
l_quantity | numeric(15,2) | not null
l_extendedprice | numeric(15,2) | not null
l_discount | numeric(15,2) | not null
l_tax | numeric(15,2) | not null
l_returnflag | character(1) | not null
l_linestatus | character(1) | not null
l_shipdate | date | not null
l_commitdate | date | not null
l_receiptdate | date | not null
l_shipinstruct | character(25) | not null
l_shipmode | character(10) | not null
l_comment | character varying(44) | not null
null_column | integer |
int_column1 | integer |
int_column2 | integer |
(19 rows)
ALTER TABLE lineitem_alter ADD COLUMN int_column3 INTEGER,
ALTER COLUMN int_column1 SET STATISTICS 10;
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 (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
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;
Column | Type | Modifiers
-----------------+-----------------------+-----------
l_orderkey | bigint | not null
l_partkey | integer | not null
l_suppkey | integer | not null
l_linenumber | integer | not null
l_quantity | numeric(15,2) | not null
l_extendedprice | numeric(15,2) | not null
l_discount | numeric(15,2) | not null
l_tax | numeric(15,2) | not null
l_returnflag | character(1) | not null
l_linestatus | character(1) | not null
l_shipdate | date | not null
l_commitdate | date | not null
l_receiptdate | date | not null
l_shipinstruct | character(25) | not null
l_shipmode | character(10) | not null
l_comment | character varying(44) | not null
null_column | integer |
(17 rows)
-- Verify that we cannot execute alter commands on the distribution column
ALTER TABLE lineitem_alter ALTER COLUMN l_orderkey DROP NOT NULL;
ERROR: cannot execute ALTER TABLE command involving partition column
ALTER TABLE lineitem_alter DROP COLUMN l_orderkey;
ERROR: cannot execute ALTER TABLE command involving partition column
-- Verify that we error out on unsupported statement types
ALTER TABLE lineitem_alter ALTER COLUMN l_orderkey SET STATISTICS 100;
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 (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
ALTER TABLE lineitem_alter DROP CONSTRAINT IF EXISTS non_existent_contraint;
NOTICE: constraint "non_existent_contraint" of relation "lineitem_alter" does not exist, skipping
ALTER TABLE lineitem_alter SET WITHOUT OIDS;
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 (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
-- Verify that we error out in case of postgres errors on supported statement
-- types
ALTER TABLE lineitem_alter ADD COLUMN new_column non_existent_type;
ERROR: type "non_existent_type" does not exist
LINE 1: ALTER TABLE lineitem_alter ADD COLUMN new_column non_existen...
^
ALTER TABLE lineitem_alter ALTER COLUMN null_column SET NOT NULL;
ERROR: column "null_column" of relation "lineitem_alter_220000" contains null values
CONTEXT: while executing command on localhost:57637
ALTER TABLE lineitem_alter ALTER COLUMN l_partkey SET DEFAULT 'a';
ERROR: invalid input syntax for type integer: "a"
-- Verify that we error out on RENAME CONSTRAINT statement
ALTER TABLE lineitem_alter RENAME CONSTRAINT constraint_a TO constraint_b;
ERROR: renaming constraints belonging to distributed tables is currently unsupported
-- Verify that IF EXISTS works as expected with RENAME statements
ALTER TABLE non_existent_table RENAME TO non_existent_table_renamed;
ERROR: relation "non_existent_table" does not exist
ALTER TABLE IF EXISTS non_existent_table RENAME TO non_existent_table_renamed;
NOTICE: relation "non_existent_table" does not exist, skipping
ALTER TABLE IF EXISTS non_existent_table RENAME COLUMN column1 TO column2;
NOTICE: relation "non_existent_table" does not exist, skipping
-- Verify that none of the failed alter table commands took effect on the master
-- node
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
Column | Type | Modifiers
-----------------+-----------------------+-----------
l_orderkey | bigint | not null
l_partkey | integer | not null
l_suppkey | integer | not null
l_linenumber | integer | not null
l_quantity | numeric(15,2) | not null
l_extendedprice | numeric(15,2) | not null
l_discount | numeric(15,2) | not null
l_tax | numeric(15,2) | not null
l_returnflag | character(1) | not null
l_linestatus | character(1) | not null
l_shipdate | date | not null
l_commitdate | date | not null
l_receiptdate | date | not null
l_shipinstruct | character(25) | not null
l_shipmode | character(10) | not null
l_comment | character varying(44) | not null
null_column | integer |
(17 rows)
-- verify that non-propagated ddl commands are allowed inside a transaction block
SET citus.enable_ddl_propagation to false;
BEGIN;
CREATE INDEX temp_index_1 ON lineitem_alter(l_linenumber);
COMMIT;
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
indexname | tablename
--------------+----------------
temp_index_1 | lineitem_alter
(1 row)
DROP INDEX temp_index_1;
-- verify that single distributed ddl commands are allowed inside a transaction block
SET citus.enable_ddl_propagation to true;
BEGIN;
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
COMMIT;
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
indexname | tablename
--------------+----------------
temp_index_2 | lineitem_alter
(1 row)
DROP INDEX temp_index_2;
-- and so are multiple ddl statements
BEGIN;
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
ALTER TABLE lineitem_alter ADD COLUMN first integer;
COMMIT;
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
Column | Type | Modifiers
-----------------+-----------------------+-----------
l_orderkey | bigint | not null
l_partkey | integer | not null
l_suppkey | integer | not null
l_linenumber | integer | not null
l_quantity | numeric(15,2) | not null
l_extendedprice | numeric(15,2) | not null
l_discount | numeric(15,2) | not null
l_tax | numeric(15,2) | not null
l_returnflag | character(1) | not null
l_linestatus | character(1) | not null
l_shipdate | date | not null
l_commitdate | date | not null
l_receiptdate | date | not null
l_shipinstruct | character(25) | not null
l_shipmode | character(10) | not null
l_comment | character varying(44) | not null
null_column | integer |
first | integer |
(18 rows)
SELECT "Column", "Type", "Definition" FROM index_attrs WHERE
relid = 'temp_index_2'::regclass;
Column | Type | Definition
------------+--------+------------
l_orderkey | bigint | l_orderkey
(1 row)
ALTER TABLE lineitem_alter DROP COLUMN first;
DROP INDEX temp_index_2;
-- ensure that user-specified rollback causes full rollback
BEGIN;
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
CREATE INDEX temp_index_3 ON lineitem_alter(l_partkey);
ROLLBACK;
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
indexname | tablename
-----------+-----------
(0 rows)
-- ensure that errors cause full rollback
BEGIN;
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
ERROR: relation "temp_index_2" already exists
ROLLBACK;
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
indexname | tablename
-----------+-----------
(0 rows)
-- verify that SAVEPOINT is allowed...
BEGIN;
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
SAVEPOINT my_savepoint;
CREATE INDEX temp_index_3 ON lineitem_alter(l_partkey);
ROLLBACK;
-- and also rolling back to it is also allowed
BEGIN;
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
SAVEPOINT my_savepoint;
CREATE INDEX temp_index_3 ON lineitem_alter(l_partkey);
ROLLBACK TO my_savepoint;
COMMIT;
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
indexname | tablename
--------------+----------------
temp_index_2 | lineitem_alter
(1 row)
DROP INDEX temp_index_2;
-- Add column on only one worker...
\c - - - :worker_2_port
ALTER TABLE lineitem_alter_220000 ADD COLUMN first integer;
\c - - - :master_port
-- and try to add it in a multi-statement block, which fails
BEGIN;
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
ALTER TABLE lineitem_alter ADD COLUMN first integer;
ERROR: column "first" of relation "lineitem_alter_220000" already exists
CONTEXT: while executing command on localhost:57638
COMMIT;
-- Nothing from the block should have committed
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
indexname | tablename
-----------+-----------
(0 rows)
-- Create single-shard table (to avoid deadlocks in the upcoming test hackery)
CREATE TABLE single_shard_items (id integer NOT NULL, name text);
SET citus.shard_count TO 1;
SET citus.shard_replication_factor TO 2;
SELECT create_distributed_table('single_shard_items', 'id', 'hash');
create_distributed_table
--------------------------
(1 row)
-- Verify that ALTER TABLE .. REPLICATION IDENTITY [USING INDEX]* .. works
CREATE UNIQUE INDEX replica_idx on single_shard_items(id);
SELECT relreplident FROM pg_class WHERE relname = 'single_shard_items';
relreplident
--------------
d
(1 row)
SELECT run_command_on_workers('SELECT relreplident FROM pg_class WHERE relname LIKE ''single_shard_items_%'' LIMIT 1;');
run_command_on_workers
------------------------
(localhost,57637,t,d)
(localhost,57638,t,d)
(2 rows)
ALTER TABLE single_shard_items REPLICA IDENTITY nothing;
SELECT relreplident FROM pg_class WHERE relname = 'single_shard_items';
relreplident
--------------
n
(1 row)
SELECT run_command_on_workers('SELECT relreplident FROM pg_class WHERE relname LIKE ''single_shard_items_%'' LIMIT 1;');
run_command_on_workers
------------------------
(localhost,57637,t,n)
(localhost,57638,t,n)
(2 rows)
ALTER TABLE single_shard_items REPLICA IDENTITY full;
SELECT relreplident FROM pg_class WHERE relname = 'single_shard_items';
relreplident
--------------
f
(1 row)
SELECT run_command_on_workers('SELECT relreplident FROM pg_class WHERE relname LIKE ''single_shard_items_%'' LIMIT 1;');
run_command_on_workers
------------------------
(localhost,57637,t,f)
(localhost,57638,t,f)
(2 rows)
ALTER TABLE single_shard_items REPLICA IDENTITY USING INDEX replica_idx;
SELECT relreplident FROM pg_class WHERE relname = 'single_shard_items';
relreplident
--------------
i
(1 row)
SELECT run_command_on_workers('SELECT relreplident FROM pg_class WHERE relname LIKE ''single_shard_items_%'' LIMIT 1;');
run_command_on_workers
------------------------
(localhost,57637,t,i)
(localhost,57638,t,i)
(2 rows)
ALTER TABLE single_shard_items REPLICA IDENTITY default, REPLICA IDENTITY USING INDEX replica_idx, REPLICA IDENTITY nothing;
SELECT relreplident FROM pg_class WHERE relname = 'single_shard_items';
relreplident
--------------
n
(1 row)
SELECT run_command_on_workers('SELECT relreplident FROM pg_class WHERE relname LIKE ''single_shard_items_%'' LIMIT 1;');
run_command_on_workers
------------------------
(localhost,57637,t,n)
(localhost,57638,t,n)
(2 rows)
ALTER TABLE single_shard_items ADD COLUMN test_col int, REPLICA IDENTITY full;
DROP INDEX replica_idx;
ALTER TABLE single_shard_items REPLICA IDENTITY default;
-- Drop the column from the worker...
\c - - - :worker_2_port
ALTER TABLE lineitem_alter_220000 DROP COLUMN first;
-- Create table to trigger at-xact-end (deferred) failure
CREATE TABLE ddl_commands (command text UNIQUE DEFERRABLE INITIALLY DEFERRED);
-- Use an event trigger to log all DDL event tags in it
CREATE FUNCTION log_ddl_tag() RETURNS event_trigger AS $ldt$
BEGIN
INSERT INTO ddl_commands VALUES (tg_tag);
END;
$ldt$ LANGUAGE plpgsql;
CREATE EVENT TRIGGER log_ddl_tag ON ddl_command_end EXECUTE PROCEDURE log_ddl_tag();
\c - - - :master_port
-- The above trigger will cause failure at transaction end on one placement.
-- We'll test 2PC first, as it should handle this "best" (no divergence)
SET citus.multi_shard_commit_protocol TO '2pc';
BEGIN;
CREATE INDEX single_index_2 ON single_shard_items(id);
CREATE INDEX single_index_3 ON single_shard_items(name);
COMMIT;
ERROR: duplicate key value violates unique constraint "ddl_commands_command_key"
DETAIL: Key (command)=(CREATE INDEX) already exists.
CONTEXT: while executing command on localhost:57638
-- Nothing from the block should have committed
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'single_shard_items' ORDER BY 1;
indexname | tablename
-----------+-----------
(0 rows)
-- Even if 1PC is picked for multi-shard commands
-- Citus always uses 2PC for replication > 1
SET citus.multi_shard_commit_protocol TO '1pc';
BEGIN;
CREATE INDEX single_index_2 ON single_shard_items(id);
CREATE INDEX single_index_3 ON single_shard_items(name);
COMMIT;
ERROR: duplicate key value violates unique constraint "ddl_commands_command_key"
DETAIL: Key (command)=(CREATE INDEX) already exists.
CONTEXT: while executing command on localhost:57638
-- Nothing from the block should have committed
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'single_shard_items' ORDER BY 1;
indexname | tablename
-----------+-----------
(0 rows)
\c - - - :worker_2_port
DROP EVENT TRIGGER log_ddl_tag;
DROP FUNCTION log_ddl_tag();
DROP TABLE ddl_commands;
\c - - - :master_port
-- Distributed SELECTs may appear after ALTER
BEGIN;
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
SELECT count(*) FROM lineitem_alter;
count
-------
18000
(1 row)
ROLLBACK;
-- and before
BEGIN;
SELECT count(*) FROM lineitem_alter;
count
-------
18000
(1 row)
CREATE INDEX temp_index_2 ON lineitem_alter(l_orderkey);
COMMIT;
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
indexname | tablename
--------------+----------------
temp_index_2 | lineitem_alter
(1 row)
DROP INDEX temp_index_2;
--- verify that distributed ddl commands can be used with 2pc
SET citus.multi_shard_commit_protocol TO '2pc';
CREATE INDEX temp_index_3 ON lineitem_alter(l_orderkey);
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
indexname | tablename
--------------+----------------
temp_index_3 | lineitem_alter
(1 row)
DROP INDEX temp_index_3;
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
indexname | tablename
-----------+-----------
(0 rows)
RESET citus.multi_shard_commit_protocol;
-- verify that not any of shard placements are marked as failed when a query failure occurs
CREATE TABLE test_ab (a int, b int);
SET citus.shard_count TO 8;
SELECT create_distributed_table('test_ab', 'a', 'hash');
create_distributed_table
--------------------------
(1 row)
INSERT INTO test_ab VALUES (2, 10);
INSERT INTO test_ab VALUES (2, 11);
CREATE UNIQUE INDEX temp_unique_index_1 ON test_ab(a);
ERROR: could not create unique index "temp_unique_index_1_220011"
DETAIL: Key (a)=(2) is duplicated.
CONTEXT: while executing command on localhost:57638
SELECT shardid FROM pg_dist_shard_placement NATURAL JOIN pg_dist_shard
WHERE logicalrelid='test_ab'::regclass AND shardstate=3;
shardid
---------
(0 rows)
-- Check that the schema on the worker still looks reasonable
\c - - - :worker_1_port
SELECT attname, atttypid::regtype
FROM
(SELECT oid FROM pg_class WHERE relname LIKE 'lineitem_alter_%' ORDER BY relname LIMIT 1) pc
JOIN pg_attribute ON (pc.oid = pg_attribute.attrelid)
ORDER BY attnum;
attname | atttypid
-------------------------------+-------------------
tableoid | oid
cmax | cid
xmax | xid
cmin | cid
xmin | xid
ctid | tid
l_orderkey | bigint
l_partkey | integer
l_suppkey | integer
l_linenumber | integer
l_quantity | numeric
l_extendedprice | numeric
l_discount | numeric
l_tax | numeric
l_returnflag | character
l_linestatus | character
l_shipdate | date
l_commitdate | date
l_receiptdate | date
l_shipinstruct | character
l_shipmode | character
l_comment | character varying
........pg.dropped.17........ | -
........pg.dropped.18........ | -
........pg.dropped.19........ | -
........pg.dropped.20........ | -
null_column | integer
........pg.dropped.22........ | -
........pg.dropped.23........ | -
........pg.dropped.24........ | -
(30 rows)
\c - - - :master_port
-- verify that we can rename distributed tables
SHOW citus.enable_ddl_propagation;
citus.enable_ddl_propagation
------------------------------
on
(1 row)
ALTER TABLE lineitem_alter RENAME TO lineitem_renamed;
-- verify rename is performed
SELECT relname FROM pg_class WHERE relname = 'lineitem_renamed';
relname
------------------
lineitem_renamed
(1 row)
-- show rename worked on one worker, too
\c - - - :worker_1_port
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_renamed%' ORDER BY relname;
relname
-------------------------
lineitem_renamed_220000
lineitem_renamed_220001
lineitem_renamed_220003
(3 rows)
\c - - - :master_port
-- revert it to original name
ALTER TABLE lineitem_renamed RENAME TO lineitem_alter;
-- show rename worked on one worker, too
\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;
relname
-----------------------
lineitem_alter_220000
lineitem_alter_220001
lineitem_alter_220003
(3 rows)
\c - - - :master_port
-- verify that we can set and reset storage parameters
ALTER TABLE lineitem_alter SET(fillfactor=40);
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
relname | reloptions
----------------+-----------------
lineitem_alter | {fillfactor=40}
(1 row)
\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;
relname | reloptions
-----------------------+-----------------
lineitem_alter_220000 | {fillfactor=40}
lineitem_alter_220001 | {fillfactor=40}
lineitem_alter_220003 | {fillfactor=40}
(3 rows)
\c - - - :master_port
ALTER TABLE lineitem_alter RESET(fillfactor);
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
relname | reloptions
----------------+------------
lineitem_alter |
(1 row)
\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;
relname | reloptions
-----------------------+------------
lineitem_alter_220000 |
lineitem_alter_220001 |
lineitem_alter_220003 |
(3 rows)
\c - - - :master_port
-- verify that we can rename indexes on distributed tables
CREATE INDEX temp_index_1 ON lineitem_alter(l_linenumber);
ALTER INDEX temp_index_1 RENAME TO idx_lineitem_linenumber;
-- verify rename is performed
SELECT relname FROM pg_class WHERE relname = 'idx_lineitem_linenumber';
relname
-------------------------
idx_lineitem_linenumber
(1 row)
-- show rename worked on one worker, too
\c - - - :worker_1_port
SELECT relname FROM pg_class WHERE relname LIKE 'idx_lineitem_linenumber%' ORDER BY relname;
relname
--------------------------------
idx_lineitem_linenumber_220000
idx_lineitem_linenumber_220001
idx_lineitem_linenumber_220003
(3 rows)
\c - - - :master_port
-- now get rid of the index
DROP INDEX idx_lineitem_linenumber;
-- verify that we don't intercept DDL commands if propagation is turned off
SET citus.enable_ddl_propagation to false;
-- table rename statement can be performed on the coordinator only now
ALTER TABLE lineitem_alter RENAME TO lineitem_renamed;
-- verify rename is performed
SELECT relname FROM pg_class WHERE relname = 'lineitem_alter' or relname = 'lineitem_renamed';
relname
------------------
lineitem_renamed
(1 row)
-- revert it to original name
ALTER TABLE lineitem_renamed RENAME TO lineitem_alter;
-- this column is added to master table and not workers
ALTER TABLE lineitem_alter ADD COLUMN column_only_added_to_master int;
-- verify newly added column is not present in a worker shard
\c - - - :worker_1_port
SELECT column_only_added_to_master FROM lineitem_alter_220000 LIMIT 0;
ERROR: column "column_only_added_to_master" does not exist
LINE 1: SELECT column_only_added_to_master FROM lineitem_alter_22000...
^
\c - - - :master_port
-- ddl propagation flag is reset to default, disable it again
SET citus.enable_ddl_propagation to false;
-- following query succeeds since it accesses an previously existing column
SELECT l_orderkey FROM lineitem_alter LIMIT 0;
l_orderkey
------------
(0 rows)
-- make master and workers have the same schema again
ALTER TABLE lineitem_alter DROP COLUMN column_only_added_to_master;
-- now this should succeed
SELECT * FROM lineitem_alter LIMIT 0;
l_orderkey | l_partkey | l_suppkey | l_linenumber | l_quantity | l_extendedprice | l_discount | l_tax | l_returnflag | l_linestatus | l_shipdate | l_commitdate | l_receiptdate | l_shipinstruct | l_shipmode | l_comment | null_column
------------+-----------+-----------+--------------+------------+-----------------+------------+-------+--------------+--------------+------------+--------------+---------------+----------------+------------+-----------+-------------
(0 rows)
-- previously unsupported statements are accepted by postgresql now
ALTER TABLE lineitem_alter ALTER COLUMN l_orderkey SET STATISTICS 100;
ALTER TABLE lineitem_alter DROP CONSTRAINT IF EXISTS non_existent_contraint;
NOTICE: constraint "non_existent_contraint" of relation "lineitem_alter" does not exist, skipping
ALTER TABLE lineitem_alter SET WITHOUT OIDS;
-- distribution column still cannot be dropped.
ALTER TABLE lineitem_alter DROP COLUMN l_orderkey;
ERROR: cannot execute ALTER TABLE command dropping partition column
-- Even unique indexes on l_partkey (non-partition column) are allowed.
-- Citus would have prevented that.
CREATE UNIQUE INDEX unique_lineitem_partkey on lineitem_alter(l_partkey);
SELECT indexname, tablename FROM pg_indexes WHERE tablename = 'lineitem_alter';
indexname | tablename
-------------------------+----------------
unique_lineitem_partkey | lineitem_alter
(1 row)
-- verify index is not created on worker
\c - - - :worker_1_port
SELECT indexname, tablename FROM pg_indexes WHERE tablename like 'lineitem_alter_%';
indexname | tablename
-----------+-----------
(0 rows)
\c - - - :master_port
-- verify alter table and drop sequence in the same transaction does not cause deadlock
SET citus.shard_count TO 4;
SET citus.shard_replication_factor TO 2;
CREATE TABLE sequence_deadlock_test (a serial, b serial);
SELECT create_distributed_table('sequence_deadlock_test', 'a');
create_distributed_table
--------------------------
(1 row)
BEGIN;
ALTER TABLE sequence_deadlock_test ADD COLUMN c int;
-- suppress notice message caused by DROP ... CASCADE to prevent pg version difference
SET client_min_messages TO 'WARNING';
DROP SEQUENCE sequence_deadlock_test_b_seq CASCADE;
RESET client_min_messages;
END;
DROP TABLE sequence_deadlock_test;
-- verify enable/disable trigger all works
SET citus.shard_replication_factor TO 1;
SET citus.shard_count TO 1;
CREATE TABLE trigger_table (
id int,
value text
);
SELECT create_distributed_table('trigger_table', 'id');
create_distributed_table
--------------------------
(1 row)
-- first set a trigger on a shard
\c - - - :worker_1_port
CREATE FUNCTION update_value() RETURNS trigger AS $up$
BEGIN
NEW.value := 'trigger enabled';
RETURN NEW;
END;
$up$ LANGUAGE plpgsql;
CREATE TRIGGER update_value
BEFORE INSERT ON trigger_table_220017
FOR EACH ROW EXECUTE PROCEDURE update_value();
\c - - - :master_port
INSERT INTO trigger_table VALUES (1, 'trigger disabled');
SELECT value, count(*) FROM trigger_table GROUP BY value ORDER BY value;
value | count
-----------------+-------
trigger enabled | 1
(1 row)
ALTER TABLE trigger_table DISABLE TRIGGER ALL;
ERROR: triggers are only supported for local tables added to metadata
INSERT INTO trigger_table VALUES (1, 'trigger disabled');
SELECT value, count(*) FROM trigger_table GROUP BY value ORDER BY value;
value | count
-----------------+-------
trigger enabled | 2
(1 row)
ALTER TABLE trigger_table ENABLE TRIGGER ALL;
ERROR: triggers are only supported for local tables added to metadata
INSERT INTO trigger_table VALUES (1, 'trigger disabled');
SELECT value, count(*) FROM trigger_table GROUP BY value ORDER BY value;
value | count
-----------------+-------
trigger enabled | 3
(1 row)
DROP TABLE trigger_table;
-- test ALTER TABLE ALL IN TABLESPACE
-- we expect that it will warn out
CREATE TABLESPACE super_fast_ssd LOCATION '@abs_srcdir@/data';
ALTER TABLE ALL IN TABLESPACE pg_default SET TABLESPACE super_fast_ssd;
WARNING: not propagating ALTER TABLE ALL IN TABLESPACE commands to worker nodes
HINT: Connect to worker nodes directly to manually move all tables.
ALTER TABLE ALL IN TABLESPACE super_fast_ssd SET TABLESPACE pg_default;
WARNING: not propagating ALTER TABLE ALL IN TABLESPACE commands to worker nodes
HINT: Connect to worker nodes directly to manually move all tables.
DROP TABLESPACE super_fast_ssd;
-- Cleanup the table and its shards
SET citus.enable_ddl_propagation to true;
DROP TABLE lineitem_alter;
-- check that nothing's left over on workers, other than the leftover shard created
-- during the unsuccessful COPY
\c - - - :worker_1_port
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%';
relname
-----------------------
lineitem_alter_220002
(1 row)
\c - - - :master_port
-- Test alter table with drop table in the same transaction
BEGIN;
CREATE TABLE test_table_1(id int);
SELECT create_distributed_table('test_table_1','id');
create_distributed_table
--------------------------
(1 row)
ALTER TABLE test_table_1 ADD CONSTRAINT u_key UNIQUE(id);
DROP TABLE test_table_1;
END;
-- There should be no test_table_1 shard on workers
\c - - - :worker_1_port
SELECT relname FROM pg_class WHERE relname LIKE 'test_table_1%';
relname
---------
(0 rows)
\c - - - :master_port
-- verify logged info is propagated to workers when distributing the table
CREATE TABLE logged_test(id int);
ALTER TABLE logged_test SET UNLOGGED;
SELECT create_distributed_table('logged_test', 'id');
create_distributed_table
--------------------------
(1 row)
\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;
relname | logged_info
--------------------+-------------
logged_test_220022 | unlogged
logged_test_220023 | unlogged
logged_test_220024 | unlogged
logged_test_220025 | unlogged
(4 rows)
\c - - - :master_port
-- verify SET LOGGED/UNLOGGED works after distributing the table
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;
relname | logged_info
-------------+-------------
logged_test | logged
(1 row)
\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;
relname | logged_info
--------------------+-------------
logged_test_220022 | logged
logged_test_220023 | logged
logged_test_220024 | logged
logged_test_220025 | logged
(4 rows)
\c - - - :master_port
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;
relname | logged_info
-------------+-------------
logged_test | unlogged
(1 row)
\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;
relname | logged_info
--------------------+-------------
logged_test_220022 | unlogged
logged_test_220023 | unlogged
logged_test_220024 | unlogged
logged_test_220025 | unlogged
(4 rows)
\c - - - :master_port
DROP TABLE logged_test;
-- Test WITH options on a normal simple hash-distributed table
CREATE TABLE hash_dist(id bigint primary key, f1 text) WITH (fillfactor=40);
SELECT create_distributed_table('hash_dist','id');
create_distributed_table
--------------------------
(1 row)
-- verify that the storage options made it to the table definitions
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist';
relname | reloptions
-----------+-----------------
hash_dist | {fillfactor=40}
(1 row)
\c - - - :worker_1_port
SELECT relname, reloptions FROM pg_class WHERE relkind = 'r' AND relname LIKE 'hash_dist%' ORDER BY relname;
relname | reloptions
------------------+-----------------
hash_dist_220026 | {fillfactor=40}
hash_dist_220027 | {fillfactor=40}
hash_dist_220028 | {fillfactor=40}
hash_dist_220029 | {fillfactor=40}
(4 rows)
\c - - - :master_port
-- verify that we can set and reset index storage parameters
ALTER INDEX hash_dist_pkey SET(fillfactor=40);
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
relname | reloptions
----------------+-----------------
hash_dist_pkey | {fillfactor=40}
(1 row)
\c - - - :worker_1_port
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey%' ORDER BY relname;
relname | reloptions
-----------------------+-----------------
hash_dist_pkey_220026 | {fillfactor=40}
hash_dist_pkey_220027 | {fillfactor=40}
hash_dist_pkey_220028 | {fillfactor=40}
hash_dist_pkey_220029 | {fillfactor=40}
(4 rows)
\c - - - :master_port
ALTER INDEX hash_dist_pkey RESET(fillfactor);
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
relname | reloptions
----------------+------------
hash_dist_pkey |
(1 row)
\c - - - :worker_1_port
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey%' ORDER BY relname;
relname | reloptions
-----------------------+------------
hash_dist_pkey_220026 |
hash_dist_pkey_220027 |
hash_dist_pkey_220028 |
hash_dist_pkey_220029 |
(4 rows)
\c - - - :master_port
-- verify error message on ALTER INDEX, SET TABLESPACE is unsupported
ALTER INDEX hash_dist_pkey SET TABLESPACE foo;
ERROR: alter index ... set tablespace ... is currently unsupported
DETAIL: Only RENAME TO, SET (), RESET (), ATTACH PARTITION and SET STATISTICS are supported.
-- verify that we can add indexes with new storage options
CREATE UNIQUE INDEX another_index ON hash_dist(id) WITH (fillfactor=50);
-- show the index and its storage options on coordinator, then workers
SELECT relname, reloptions FROM pg_class WHERE relname = 'another_index';
relname | reloptions
---------------+-----------------
another_index | {fillfactor=50}
(1 row)
\c - - - :worker_1_port
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'another_index%' ORDER BY relname;
relname | reloptions
----------------------+-----------------
another_index_220026 | {fillfactor=50}
another_index_220027 | {fillfactor=50}
another_index_220028 | {fillfactor=50}
another_index_220029 | {fillfactor=50}
(4 rows)
\c - - - :master_port
-- get rid of the index
DROP INDEX another_index;
-- check if we fail properly when a column with un-supported constraint is added
-- UNIQUE, PRIMARY KEY on non-distribution column is not supported
-- CHECK, FOREIGN KEY, UNIQE, PRIMARY KEY cannot be added together with ADD COLUMN
SET citus.shard_replication_factor TO 1;
CREATE TABLE test_table_1(id int);
SELECT create_distributed_table('test_table_1', 'id');
create_distributed_table
--------------------------
(1 row)
ALTER TABLE test_table_1 ADD COLUMN test_col int UNIQUE;
ERROR: cannot create constraint on "test_table_1"
DETAIL: Distributed relations cannot have UNIQUE, EXCLUDE, or PRIMARY KEY constraints that do not include the partition column (with an equality operator if EXCLUDE).
ALTER TABLE test_table_1 ADD COLUMN test_col int PRIMARY KEY;
ERROR: cannot create constraint on "test_table_1"
DETAIL: Distributed relations cannot have UNIQUE, EXCLUDE, or PRIMARY KEY constraints that do not include the partition column (with an equality operator if EXCLUDE).
ALTER TABLE test_table_1 ADD COLUMN test_col int CHECK (test_col > 3);
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 test_table_1 ADD COLUMN test_col data_type; ALTER TABLE test_table_1 ADD CONSTRAINT constraint_name CHECK (check_expression);
CREATE TABLE reference_table(i int UNIQUE);
SELECT create_reference_table('reference_table');
create_reference_table
------------------------
(1 row)
ALTER TABLE test_table_1 ADD COLUMN test_col int REFERENCES reference_table(i) ON DELETE 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 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;
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
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 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;
DROP TABLE reference_table;
CREATE TABLE referenced_table(i int UNIQUE);
SELECT create_distributed_table('referenced_table', 'i');
create_distributed_table
--------------------------
(1 row)
ALTER TABLE test_table_1 ADD COLUMN test_col int REFERENCES referenced_table(i);
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
DROP TABLE referenced_table, test_table_1;