-- -- MULTI_CREATE_TABLE -- -- Create new table definitions for use in testing in distributed planning and -- execution functionality. Also create indexes to boost performance. Since we -- need to cover both reference join and partitioned join, we have created -- reference and hash-distributed version of orders, customer and part tables. SET citus.next_shard_id TO 360000; CREATE TABLE lineitem ( 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, PRIMARY KEY(l_orderkey, l_linenumber) ); SELECT create_distributed_table('lineitem', 'l_orderkey', 'hash', shard_count := 2); create_distributed_table --------------------------------------------------------------------- (1 row) CREATE INDEX lineitem_time_index ON lineitem (l_shipdate); CREATE TABLE orders ( o_orderkey bigint not null, o_custkey integer not null, o_orderstatus char(1) not null, o_totalprice decimal(15,2) not null, o_orderdate date not null, o_orderpriority char(15) not null, o_clerk char(15) not null, o_shippriority integer not null, o_comment varchar(79) not null, PRIMARY KEY(o_orderkey) ); SELECT create_distributed_table('orders', 'o_orderkey', 'hash', colocate_with := 'lineitem'); create_distributed_table --------------------------------------------------------------------- (1 row) CREATE TABLE orders_reference ( o_orderkey bigint not null, o_custkey integer not null, o_orderstatus char(1) not null, o_totalprice decimal(15,2) not null, o_orderdate date not null, o_orderpriority char(15) not null, o_clerk char(15) not null, o_shippriority integer not null, o_comment varchar(79) not null, PRIMARY KEY(o_orderkey) ); SELECT create_reference_table('orders_reference'); create_reference_table --------------------------------------------------------------------- (1 row) CREATE TABLE customer ( c_custkey integer not null, c_name varchar(25) not null, c_address varchar(40) not null, c_nationkey integer not null, c_phone char(15) not null, c_acctbal decimal(15,2) not null, c_mktsegment char(10) not null, c_comment varchar(117) not null); SELECT create_reference_table('customer'); create_reference_table --------------------------------------------------------------------- (1 row) CREATE TABLE customer_append ( c_custkey integer not null, c_name varchar(25) not null, c_address varchar(40) not null, c_nationkey integer not null, c_phone char(15) not null, c_acctbal decimal(15,2) not null, c_mktsegment char(10) not null, c_comment varchar(117) not null); SELECT create_distributed_table('customer_append', 'c_custkey', 'append'); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT master_create_empty_shard('customer_append'); master_create_empty_shard --------------------------------------------------------------------- 360006 (1 row) CREATE TABLE nation ( n_nationkey integer not null, n_name char(25) not null, n_regionkey integer not null, n_comment varchar(152)); SELECT create_reference_table('nation'); create_reference_table --------------------------------------------------------------------- (1 row) CREATE TABLE part ( p_partkey integer not null, p_name varchar(55) not null, p_mfgr char(25) not null, p_brand char(10) not null, p_type varchar(25) not null, p_size integer not null, p_container char(10) not null, p_retailprice decimal(15,2) not null, p_comment varchar(23) not null); SELECT create_reference_table('part'); create_reference_table --------------------------------------------------------------------- (1 row) CREATE TABLE part_append ( p_partkey integer not null, p_name varchar(55) not null, p_mfgr char(25) not null, p_brand char(10) not null, p_type varchar(25) not null, p_size integer not null, p_container char(10) not null, p_retailprice decimal(15,2) not null, p_comment varchar(23) not null); SELECT create_distributed_table('part_append', 'p_partkey', 'append'); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT master_create_empty_shard('part_append'); master_create_empty_shard --------------------------------------------------------------------- 360009 (1 row) CREATE TABLE supplier ( s_suppkey integer not null, s_name char(25) not null, s_address varchar(40) not null, s_nationkey integer, s_phone char(15) not null, s_acctbal decimal(15,2) not null, s_comment varchar(101) not null ); SELECT create_reference_table('supplier'); create_reference_table --------------------------------------------------------------------- (1 row) -- create a single shard supplier table which is not -- a reference table CREATE TABLE supplier_single_shard ( s_suppkey integer not null, s_name char(25) not null, s_address varchar(40) not null, s_nationkey integer, s_phone char(15) not null, s_acctbal decimal(15,2) not null, s_comment varchar(101) not null ); SELECT create_distributed_table('supplier_single_shard', 's_suppkey', 'hash', shard_count := 1); create_distributed_table --------------------------------------------------------------------- (1 row) CREATE TABLE mx_table_test (col1 int, col2 text); SET citus.next_shard_id TO 360013; -- Test initial data loading CREATE TABLE data_load_test (col1 int, col2 text, col3 serial); INSERT INTO data_load_test VALUES (132, 'hello'); INSERT INTO data_load_test VALUES (243, 'world'); -- table must be empty when using append- or range-partitioning SELECT create_distributed_table('data_load_test', 'col1', 'append'); ERROR: cannot distribute relation "data_load_test" DETAIL: Relation "data_load_test" contains data. HINT: Empty your table before distributing it. SELECT create_distributed_table('data_load_test', 'col1', 'range'); ERROR: cannot distribute relation "data_load_test" DETAIL: Relation "data_load_test" contains data. HINT: Empty your table before distributing it. -- create_distributed_table creates shards and copies data into the distributed table SELECT create_distributed_table('data_load_test', 'col1'); NOTICE: Copying data from local table... NOTICE: copying the data has completed DETAIL: The local data in the table is no longer visible, but is still on disk. HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.data_load_test$$) create_distributed_table --------------------------------------------------------------------- (1 row) SELECT * FROM data_load_test ORDER BY col1; col1 | col2 | col3 --------------------------------------------------------------------- 132 | hello | 1 243 | world | 2 (2 rows) DROP TABLE data_load_test; -- test queries on distributed tables with no shards CREATE TABLE no_shard_test (col1 int, col2 text); SELECT create_distributed_table('no_shard_test', 'col1', 'append'); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT * FROM no_shard_test WHERE col1 > 1; col1 | col2 --------------------------------------------------------------------- (0 rows) DROP TABLE no_shard_test; CREATE TABLE no_shard_test (col1 int, col2 text); SELECT create_distributed_table('no_shard_test', 'col1', 'range'); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT * FROM no_shard_test WHERE col1 > 1; col1 | col2 --------------------------------------------------------------------- (0 rows) DROP TABLE no_shard_test; -- ensure writes in the same transaction as create_distributed_table are visible BEGIN; CREATE TABLE data_load_test (col1 int, col2 text, col3 serial); INSERT INTO data_load_test VALUES (132, 'hello'); SELECT create_distributed_table('data_load_test', 'col1'); NOTICE: Copying data from local table... NOTICE: copying the data has completed DETAIL: The local data in the table is no longer visible, but is still on disk. HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.data_load_test$$) create_distributed_table --------------------------------------------------------------------- (1 row) INSERT INTO data_load_test VALUES (243, 'world'); END; SELECT * FROM data_load_test ORDER BY col1; col1 | col2 | col3 --------------------------------------------------------------------- 132 | hello | 1 243 | world | 2 (2 rows) DROP TABLE data_load_test; -- creating co-located distributed tables in the same transaction works BEGIN; CREATE TABLE data_load_test1 (col1 int, col2 text, col3 serial); INSERT INTO data_load_test1 VALUES (132, 'hello'); SELECT create_distributed_table('data_load_test1', 'col1'); NOTICE: Copying data from local table... NOTICE: copying the data has completed DETAIL: The local data in the table is no longer visible, but is still on disk. HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.data_load_test1$$) create_distributed_table --------------------------------------------------------------------- (1 row) CREATE TABLE data_load_test2 (col1 int, col2 text, col3 serial); INSERT INTO data_load_test2 VALUES (132, 'world'); SELECT create_distributed_table('data_load_test2', 'col1'); NOTICE: Copying data from local table... NOTICE: copying the data has completed DETAIL: The local data in the table is no longer visible, but is still on disk. HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.data_load_test2$$) create_distributed_table --------------------------------------------------------------------- (1 row) SELECT a.col2 ||' '|| b.col2 FROM data_load_test1 a JOIN data_load_test2 b USING (col1) WHERE col1 = 132; ?column? --------------------------------------------------------------------- hello world (1 row) DROP TABLE data_load_test1, data_load_test2; END; -- distributing catalog tables is not supported SELECT create_distributed_table('pg_class', 'relname'); ERROR: cannot create a citus table from a catalog table SELECT create_reference_table('pg_class'); ERROR: cannot create a citus table from a catalog table -- test shard_count parameter -- first set citus.shard_count so we know the parameter works SET citus.shard_count TO 10; CREATE TABLE shard_count_table (a INT, b TEXT); CREATE TABLE shard_count_table_2 (a INT, b TEXT); SELECT create_distributed_table('shard_count_table', 'a', shard_count:=5); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT shard_count FROM citus_tables WHERE table_name::text = 'shard_count_table'; shard_count --------------------------------------------------------------------- 5 (1 row) SELECT create_distributed_table('shard_count_table_2', 'a', shard_count:=0); ERROR: 0 is outside the valid range for parameter "shard_count" (1 .. 64000) SELECT create_distributed_table('shard_count_table_2', 'a', shard_count:=-100); ERROR: -100 is outside the valid range for parameter "shard_count" (1 .. 64000) SELECT create_distributed_table('shard_count_table_2', 'a', shard_count:=64001); ERROR: 64001 is outside the valid range for parameter "shard_count" (1 .. 64000) -- shard count with colocate with table should error SELECT create_distributed_table('shard_count_table_2', 'a', shard_count:=12, colocate_with:='shard_count'); ERROR: Cannot use colocate_with with a table and shard_count at the same time -- none should not error SELECT create_distributed_table('shard_count_table_2', 'a', shard_count:=12, colocate_with:='none'); create_distributed_table --------------------------------------------------------------------- (1 row) DROP TABLE shard_count_table, shard_count_table_2; -- test shard splitting doesn't break shard_count parameter -- when shard count is given table needs to have exactly that -- many shards, regardless of shard splitting on other tables -- ensure there is no colocation group with 9 shards SELECT count(*) FROM pg_dist_colocation WHERE shardcount = 9; count --------------------------------------------------------------------- 0 (1 row) SET citus.shard_count TO 9; SET citus.shard_replication_factor TO 1; CREATE TABLE shard_split_table (a int, b int); SELECT create_distributed_table ('shard_split_table', 'a'); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT 1 FROM isolate_tenant_to_new_shard('shard_split_table', 5, shard_transfer_mode => 'block_writes'); ?column? --------------------------------------------------------------------- 1 (1 row) -- show the difference in pg_dist_colocation and citus_tables shard counts SELECT ( SELECT shardcount FROM pg_dist_colocation WHERE colocationid IN ( SELECT colocation_id FROM citus_tables WHERE table_name = 'shard_split_table'::regclass ) ) AS "pg_dist_colocation", (SELECT shard_count FROM citus_tables WHERE table_name = 'shard_split_table'::regclass) AS "citus_tables"; pg_dist_colocation | citus_tables --------------------------------------------------------------------- 9 | 11 (1 row) CREATE TABLE shard_split_table_2 (a int, b int); SELECT create_distributed_table ('shard_split_table_2', 'a', shard_count:=9); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT a.colocation_id = b.colocation_id FROM citus_tables a, citus_tables b WHERE a.table_name = 'shard_split_table'::regclass AND b.table_name = 'shard_split_table_2'::regclass; ?column? --------------------------------------------------------------------- f (1 row) SELECT shard_count FROM citus_tables WHERE table_name = 'shard_split_table_2'::regclass; shard_count --------------------------------------------------------------------- 9 (1 row) -- also check we don't break regular behaviour CREATE TABLE shard_split_table_3 (a int, b int); SELECT create_distributed_table ('shard_split_table_3', 'a'); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT a.colocation_id = b.colocation_id FROM citus_tables a, citus_tables b WHERE a.table_name = 'shard_split_table'::regclass AND b.table_name = 'shard_split_table_3'::regclass; ?column? --------------------------------------------------------------------- t (1 row) SELECT shard_count FROM citus_tables WHERE table_name = 'shard_split_table_3'::regclass; shard_count --------------------------------------------------------------------- 11 (1 row) DROP TABLE shard_split_table, shard_split_table_2, shard_split_table_3; -- test a shard count with an empty default colocation group -- ensure there is no colocation group with 13 shards SELECT count(*) FROM pg_dist_colocation WHERE shardcount = 13; count --------------------------------------------------------------------- 0 (1 row) SET citus.shard_count TO 13; CREATE TABLE shard_count_drop_table (a int); SELECT create_distributed_table('shard_count_drop_table', 'a'); create_distributed_table --------------------------------------------------------------------- (1 row) DROP TABLE shard_count_drop_table; CREATE TABLE shard_count_table_3 (a int); SELECT create_distributed_table('shard_count_table_3', 'a', shard_count:=13); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT shardcount FROM pg_dist_colocation WHERE colocationid IN ( SELECT colocation_id FROM citus_tables WHERE table_name = 'shard_count_table_3'::regclass ); shardcount --------------------------------------------------------------------- 13 (1 row) CREATE TEMP TABLE temp_table(a int); -- make sure temp table cannot be distributed and we give a good error select create_distributed_table('temp_table', 'a'); ERROR: cannot distribute a temporary table select create_reference_table('temp_table'); ERROR: cannot distribute a temporary table DROP TABLE temp_table; DROP TABLE shard_count_table_3;