\c - - - :master_port
SET client_min_messages TO WARNING;
CREATE EXTENSION IF NOT EXISTS citus_columnar;
RESET client_min_messages;
CREATE SCHEMA single_node;
SET search_path TO single_node;
SET citus.shard_count TO 4;
SET citus.shard_replication_factor TO 1;
SET citus.next_shard_id TO 93630500;
SELECT 1 FROM master_add_node('localhost', :master_port, groupid => 0);
NOTICE:  localhost:xxxxx is the coordinator and already contains metadata, skipping syncing the metadata
 ?column?
---------------------------------------------------------------------
        1
(1 row)

SELECT 1 FROM master_set_node_property('localhost', :master_port, 'shouldhaveshards', true);
 ?column?
---------------------------------------------------------------------
        1
(1 row)

CREATE TABLE test(x int, y int);
SELECT create_distributed_table('test','x');
 create_distributed_table
---------------------------------------------------------------------

(1 row)

CREATE TABLE ref(a int, b int);
SELECT create_reference_table('ref');
 create_reference_table
---------------------------------------------------------------------

(1 row)

CREATE TABLE local(c int, d int);
INSERT INTO test VALUES (1, 2), (3, 4), (5, 6), (2, 7), (4, 5);
INSERT INTO ref VALUES (1, 2), (5, 6), (7, 8);
INSERT INTO local VALUES (1, 2), (3, 4), (7, 8);
-- Check repartition joins are supported
SET citus.enable_repartition_joins TO ON;
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

SET citus.enable_single_hash_repartition_joins TO ON;
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

RESET citus.enable_single_hash_repartition_joins;
SET citus.task_assignment_policy TO 'round-robin';
SET citus.enable_single_hash_repartition_joins TO ON;
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

SET citus.task_assignment_policy TO 'greedy';
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

SET citus.task_assignment_policy TO 'first-replica';
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

RESET citus.enable_repartition_joins;
-- connect to the follower and check that a simple select query works, the follower
-- is still in the default cluster and will send queries to the primary nodes
\c - - - :follower_master_port
SET search_path TO single_node;
SELECT * FROM test WHERE x = 1;
 x | y
---------------------------------------------------------------------
 1 | 2
(1 row)

SELECT count(*) FROM test;
 count
---------------------------------------------------------------------
     5
(1 row)

SELECT * FROM test ORDER BY x;
 x | y
---------------------------------------------------------------------
 1 | 2
 2 | 7
 3 | 4
 4 | 5
 5 | 6
(5 rows)

SELECT count(*) FROM ref;
 count
---------------------------------------------------------------------
     3
(1 row)

SELECT * FROM ref ORDER BY a;
 a | b
---------------------------------------------------------------------
 1 | 2
 5 | 6
 7 | 8
(3 rows)

SELECT * FROM test, ref WHERE x = a ORDER BY x;
 x | y | a | b
---------------------------------------------------------------------
 1 | 2 | 1 | 2
 5 | 6 | 5 | 6
(2 rows)

SELECT count(*) FROM local;
 count
---------------------------------------------------------------------
     3
(1 row)

SELECT * FROM local ORDER BY c;
 c | d
---------------------------------------------------------------------
 1 | 2
 3 | 4
 7 | 8
(3 rows)

SELECT * FROM ref, local WHERE a = c ORDER BY a;
 a | b | c | d
---------------------------------------------------------------------
 1 | 2 | 1 | 2
 7 | 8 | 7 | 8
(2 rows)

SET citus.enable_repartition_joins TO ON;
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

SET citus.enable_single_hash_repartition_joins TO ON;
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

SET citus.task_assignment_policy TO 'round-robin';
SET citus.enable_single_hash_repartition_joins TO ON;
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

SET citus.task_assignment_policy TO 'greedy';
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

SET citus.task_assignment_policy TO 'first-replica';
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

RESET citus.enable_repartition_joins;
RESET citus.enable_single_hash_repartition_joins;
-- Confirm that dummy placements work
SELECT count(*) FROM test WHERE false;
 count
---------------------------------------------------------------------
     0
(1 row)

SELECT count(*) FROM test WHERE false GROUP BY GROUPING SETS (x,y);
 count
---------------------------------------------------------------------
(0 rows)

-- Confirm that they work with round-robin task assignment policy
SET citus.task_assignment_policy TO 'round-robin';
SELECT count(*) FROM test WHERE false;
 count
---------------------------------------------------------------------
     0
(1 row)

SELECT count(*) FROM test WHERE false GROUP BY GROUPING SETS (x,y);
 count
---------------------------------------------------------------------
(0 rows)

SET citus.task_assignment_policy TO 'greedy';
SELECT count(*) FROM test WHERE false;
 count
---------------------------------------------------------------------
     0
(1 row)

SELECT count(*) FROM test WHERE false GROUP BY GROUPING SETS (x,y);
 count
---------------------------------------------------------------------
(0 rows)

SET citus.task_assignment_policy TO 'first-replica';
SELECT count(*) FROM test WHERE false;
 count
---------------------------------------------------------------------
     0
(1 row)

SELECT count(*) FROM test WHERE false GROUP BY GROUPING SETS (x,y);
 count
---------------------------------------------------------------------
(0 rows)

RESET citus.task_assignment_policy;
-- now, connect to the follower but tell it to use secondary nodes. There are no
-- secondary nodes so this should fail.
-- (this is :follower_master_port but substitution doesn't work here)
\c "port=9070 dbname=regression options='-c\ citus.use_secondary_nodes=always'"
SET search_path TO single_node;
SELECT * FROM test WHERE x = 1;
ERROR:  node group 0 does not have a secondary node
-- add the the follower as secondary nodes and try again, the SELECT statement
-- should work this time
\c -reuse-previous=off regression - - :master_port
SET search_path TO single_node;
SELECT 1 FROM master_add_node('localhost', :follower_master_port, groupid => 0, noderole => 'secondary', nodecluster => 'second-cluster');
 ?column?
---------------------------------------------------------------------
        1
(1 row)

SELECT 1 FROM master_set_node_property('localhost', :master_port, 'shouldhaveshards', true);
 ?column?
---------------------------------------------------------------------
        1
(1 row)

\c "port=9070 dbname=regression options='-c\ citus.use_secondary_nodes=always\ -c\ citus.cluster_name=second-cluster'"
SET search_path TO single_node;
SELECT * FROM test WHERE x = 1;
 x | y
---------------------------------------------------------------------
 1 | 2
(1 row)

SELECT count(*) FROM test;
 count
---------------------------------------------------------------------
     5
(1 row)

SELECT * FROM test ORDER BY x;
 x | y
---------------------------------------------------------------------
 1 | 2
 2 | 7
 3 | 4
 4 | 5
 5 | 6
(5 rows)

SELECT count(*) FROM ref;
 count
---------------------------------------------------------------------
     3
(1 row)

SELECT * FROM ref ORDER BY a;
 a | b
---------------------------------------------------------------------
 1 | 2
 5 | 6
 7 | 8
(3 rows)

SELECT * FROM test, ref WHERE x = a ORDER BY x;
 x | y | a | b
---------------------------------------------------------------------
 1 | 2 | 1 | 2
 5 | 6 | 5 | 6
(2 rows)

SELECT count(*) FROM local;
 count
---------------------------------------------------------------------
     3
(1 row)

SELECT * FROM local ORDER BY c;
 c | d
---------------------------------------------------------------------
 1 | 2
 3 | 4
 7 | 8
(3 rows)

SELECT * FROM ref, local WHERE a = c ORDER BY a;
 a | b | c | d
---------------------------------------------------------------------
 1 | 2 | 1 | 2
 7 | 8 | 7 | 8
(2 rows)

SET citus.enable_repartition_joins TO ON;
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

SET citus.enable_single_hash_repartition_joins TO ON;
SELECT * FROM test t1, test t2 WHERE t1.x = t2.y ORDER BY t1.x;
 x | y | x | y
---------------------------------------------------------------------
 2 | 7 | 1 | 2
 4 | 5 | 3 | 4
 5 | 6 | 4 | 5
(3 rows)

RESET citus.enable_repartition_joins;
RESET citus.enable_single_hash_repartition_joins;
-- Confirm that dummy placements work
SELECT count(*) FROM test WHERE false;
 count
---------------------------------------------------------------------
     0
(1 row)

SELECT count(*) FROM test WHERE false GROUP BY GROUPING SETS (x,y);
 count
---------------------------------------------------------------------
(0 rows)

-- Confirm that they work with round-robin task assignment policy
SET citus.task_assignment_policy TO 'round-robin';
SELECT count(*) FROM test WHERE false;
 count
---------------------------------------------------------------------
     0
(1 row)

SELECT count(*) FROM test WHERE false GROUP BY GROUPING SETS (x,y);
 count
---------------------------------------------------------------------
(0 rows)

RESET citus.task_assignment_policy;
-- Simple columnar follower test
\c -reuse-previous=off regression - - :master_port
CREATE TABLE columnar_test (a int, b int) USING columnar;
INSERT INTO columnar_test(a, b) VALUES (1, 1);
INSERT INTO columnar_test(a, b) VALUES (1, 2);
TRUNCATE columnar_test;
INSERT INTO columnar_test(a, b) VALUES (1, 3);
INSERT INTO columnar_test(a, b) VALUES (1, 4);
BEGIN;
INSERT INTO columnar_test SELECT g, g*10
  FROM generate_series(10001,20000) g;
ROLLBACK;
VACUUM columnar_test;
INSERT INTO columnar_test(a, b) VALUES (1, 5);
INSERT INTO columnar_test(a, b) VALUES (1, 6);
VACUUM FULL columnar_test;
INSERT INTO columnar_test(a, b) VALUES (1, 7);
INSERT INTO columnar_test(a, b) VALUES (1, 8);
\c - - - :follower_master_port
SELECT * FROM columnar_test ORDER BY 1,2;
 a | b
---------------------------------------------------------------------
 1 | 3
 1 | 4
 1 | 5
 1 | 6
 1 | 7
 1 | 8
(6 rows)

\c -reuse-previous=off regression - - :master_port
SET citus.shard_replication_factor TO 1;
SET search_path TO single_node;
CREATE TABLE dist_table (a INT, b INT);
SELECT create_distributed_table ('dist_table', 'a', shard_count:=4);
 create_distributed_table
---------------------------------------------------------------------

(1 row)

INSERT INTO dist_table VALUES (1, 1);
\c "port=9070 dbname=regression options='-c\ citus.use_secondary_nodes=always\ -c\ citus.cluster_name=second-cluster'"
SET search_path TO single_node;
SELECT * FROM dist_table;
 a | b
---------------------------------------------------------------------
 1 | 1
(1 row)

SELECT global_pid AS follower_coordinator_gpid FROM get_all_active_transactions() WHERE process_id = pg_backend_pid() \gset
SELECT pg_typeof(:follower_coordinator_gpid);
 pg_typeof
---------------------------------------------------------------------
 bigint
(1 row)

SELECT pg_cancel_backend(:follower_coordinator_gpid);
ERROR:  canceling statement due to user request
SET citus.log_remote_commands TO ON;
SELECT pg_cancel_backend(:follower_coordinator_gpid) FROM dist_table WHERE a = 1;
NOTICE:  executing the command locally: SELECT pg_cancel_backend('xxxxx'::bigint) AS pg_cancel_backend FROM single_node.dist_table_102008 dist_table WHERE (a OPERATOR(pg_catalog.=) 1)
NOTICE:  issuing SELECT pg_cancel_backend(xxxxx::integer)
DETAIL:  on server postgres@localhost:xxxxx connectionId: xxxxxxx
ERROR:  canceling statement due to user request
-- Cleanup
\c -reuse-previous=off regression - - :master_port
SET search_path TO single_node;
SET client_min_messages TO WARNING;
DROP SCHEMA single_node CASCADE;
-- Remove the coordinator again
SELECT 1 FROM master_remove_node('localhost', :master_port);
 ?column?
---------------------------------------------------------------------
        1
(1 row)

-- Remove the secondary coordinator again
SELECT 1 FROM master_remove_node('localhost', :follower_master_port);
 ?column?
---------------------------------------------------------------------
        1
(1 row)

