-- Make sure changes citus.node_conninfo shutdown connections with old settings
CREATE SCHEMA node_conninfo_reload;
SET search_path TO node_conninfo_reload;
SET citus.shard_count TO 4;
SET citus.shard_replication_factor TO 1;
SET citus.force_max_query_parallelization TO ON;
SET citus.next_shard_id TO 278000;
create table test(a int);
select create_distributed_table('test', 'a');
 create_distributed_table
---------------------------------------------------------------------

(1 row)

-- Make sure a connection is opened and cached
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     0
(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=require
(1 row)

-- Set sslmode to something that does not work when connecting
ALTER SYSTEM SET citus.node_conninfo = 'sslmode=doesnotexist';
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=doesnotexist
(1 row)

-- Should give a connection error because of bad sslmode
select count(*) from test where a = 0;
ERROR:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
SELECT (citus_stat_counters(oid)).connection_establishment_failed AS old_connection_establishment_failed
FROM pg_database WHERE datname = current_database() \gset
SET citus.enable_stat_counters TO true;
select count(*) from test;
WARNING:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
ERROR:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
RESET citus.enable_stat_counters;
-- make sure that we properly updated the connection_establishment_failed counter
SELECT (citus_stat_counters(oid)).connection_establishment_failed - :old_connection_establishment_failed > 0
FROM pg_database WHERE datname = current_database();
 ?column?
---------------------------------------------------------------------
 t
(1 row)

SELECT (citus_stat_counters(oid)).connection_establishment_failed AS old_connection_establishment_failed
FROM pg_database WHERE datname = current_database() \gset
-- Test a function that tries to establish parallel node connections.
SET citus.enable_stat_counters TO true;
-- we don't care about the result, hence make it always return true
SELECT COUNT(*) > -1 FROM get_global_active_transactions();
WARNING:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
WARNING:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
 ?column?
---------------------------------------------------------------------
 t
(1 row)

RESET citus.enable_stat_counters;
-- make sure that we properly updated the connection_establishment_failed counter
SELECT (citus_stat_counters(oid)).connection_establishment_failed - :old_connection_establishment_failed = 2
FROM pg_database WHERE datname = current_database();
 ?column?
---------------------------------------------------------------------
 t
(1 row)

-- Reset it again
ALTER SYSTEM RESET citus.node_conninfo;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=require
(1 row)

-- Should work again
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     0
(1 row)

ALTER SYSTEM SET citus.node_conninfo = 'sslmode=doesnotexist';
-- we cannot set application name
ALTER SYSTEM SET citus.node_conninfo = 'application_name=XXX';
ERROR:  invalid value for parameter "citus.node_conninfo": "application_name=XXX"
DETAIL:  Prohibited conninfo keyword detected: application_name
BEGIN;
-- Should still work (no SIGHUP yet);
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     0
(1 row)

select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=doesnotexist
(1 row)

-- Should work since a connection was already taken from pool for this shard,
-- since the same placement is accessed it will reuse that connection for this
-- query
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     0
(1 row)

COMMIT;
-- Should fail now with connection error, when transaction is finished
select count(*) from test where a = 0;
ERROR:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
-- Reset it again
ALTER SYSTEM RESET citus.node_conninfo;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=require
(1 row)

-- Should work again
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     0
(1 row)

ALTER SYSTEM SET citus.node_conninfo = 'sslmode=doesnotexist';
BEGIN;
-- Should still work (no SIGHUP yet);
INSERT INTO test VALUES(0);
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=doesnotexist
(1 row)

-- Should work since a connection was already taken from pool for this shard,
-- since the same placement is accessed it will reuse that connection for this
-- query
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     1
(1 row)

COMMIT;
-- Should fail now, when transaction is finished
SET client_min_messages TO ERROR;
select count(*) from test where a = 0;
ERROR:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
RESET client_min_messages;
-- Reset it again
ALTER SYSTEM RESET citus.node_conninfo;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=require
(1 row)

-- Should work again
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     1
(1 row)

ALTER SYSTEM SET citus.node_conninfo = 'sslmode=doesnotexist';
BEGIN;
-- Should still work (no SIGHUP yet);
INSERT INTO test VALUES(1);
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=doesnotexist
(1 row)

-- Should fail since a different shard is accessed and thus a new connection
-- will to be created.
select count(*) from test where a = 0;
ERROR:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
COMMIT;
-- Should still fail now, when transaction is finished
select count(*) from test where a = 0;
ERROR:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
-- Reset it again
ALTER SYSTEM RESET citus.node_conninfo;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=require
(1 row)

-- Should work again
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     1
(1 row)

ALTER SYSTEM SET citus.node_conninfo = 'sslmode=doesnotexist';
BEGIN;
-- Should still work (no SIGHUP yet);
TRUNCATE test;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=doesnotexist
(1 row)

-- Should work since truncate grabbed connections for all shards and these are
-- reused
select count(*) from test;
 count
---------------------------------------------------------------------
     0
(1 row)

COMMIT;
-- Should fail now, when transaction is finished
SET client_min_messages TO ERROR;
select count(*) from test;
ERROR:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
RESET client_min_messages;
-- Reset it again
ALTER SYSTEM RESET citus.node_conninfo;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=require
(1 row)

-- Should work again
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     0
(1 row)

ALTER SYSTEM SET citus.node_conninfo = 'sslmode=doesnotexist';
BEGIN;
-- Should still work (no SIGHUP yet);
TRUNCATE test;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=doesnotexist
(1 row)

-- Should fail because of divede by 0 on the coordinator.
select count(*)/0 from test;
ERROR:  division by zero
ROLLBACK;
-- Should fail now, when transaction is finished
SET client_min_messages TO ERROR;
select count(*) from test;
ERROR:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
RESET client_min_messages;
-- Reset it again
ALTER SYSTEM RESET citus.node_conninfo;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=require
(1 row)

-- Should work again
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     0
(1 row)

-- Set sslmode to something that does work when connecting
ALTER SYSTEM SET citus.node_conninfo = 'sslmode=allow';
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=allow
(1 row)

-- Should still work, since sslmode=allow is valid
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     0
(1 row)

-- Set sslmode to the same again (to get more coverage)
ALTER SYSTEM SET citus.node_conninfo = 'sslmode=allow';
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=allow
(1 row)

-- Should still work
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     0
(1 row)

-- Reset it again
ALTER SYSTEM RESET citus.node_conninfo;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=require
(1 row)

-- Should work
select count(*) from test where a = 0;
 count
---------------------------------------------------------------------
     0
(1 row)

-- Test connecting all the shards
ALTER SYSTEM SET citus.node_conninfo = 'sslmode=doesnotexist';
BEGIN;
ALTER TABLE test ADD COLUMN b INT;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=doesnotexist
(1 row)

-- Should work since connections to the same shards that BEGIN is sent
-- are reused.
ALTER TABLE test ADD COLUMN c INT;
COMMIT;
-- Should fail now, when transaction is finished
ALTER TABLE test ADD COLUMN d INT;
ERROR:  connection to the remote node postgres@localhost:xxxxx failed with the following error: invalid sslmode value: "doesnotexist"
-- Reset it again
ALTER SYSTEM RESET citus.node_conninfo;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

show citus.node_conninfo;
 citus.node_conninfo
---------------------------------------------------------------------
 sslmode=require
(1 row)

-- Should work again
ALTER TABLE test ADD COLUMN e INT;
-- show that we allow providing "host" param via citus.node_conninfo
ALTER SYSTEM SET citus.node_conninfo = 'sslmode=require host=nosuchhost';
SELECT pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

SELECT pg_sleep(0.1);
 pg_sleep
---------------------------------------------------------------------

(1 row)

-- fails due to invalid host
SELECT COUNT(*)>=0 FROM test;
WARNING:  connection to the remote node postgres@localhost:xxxxx failed with the following error: could not parse network address "localhost": Name or service not known
ERROR:  connection to the remote node postgres@localhost:xxxxx failed with the following error: could not parse network address "localhost": Name or service not known
SELECT array_agg(nodeid) as updated_nodeids from pg_dist_node WHERE nodename = 'localhost' \gset
UPDATE pg_dist_node SET nodename = '127.0.0.1' WHERE nodeid = ANY(:'updated_nodeids'::int[]);
ALTER SYSTEM SET citus.node_conninfo = 'sslmode=require host=localhost';
SELECT pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

SELECT pg_sleep(0.1);
 pg_sleep
---------------------------------------------------------------------

(1 row)

-- works when hostaddr is specified in pg_dist_node after providing host in citus.node_conninfo
SELECT COUNT(*)>=0 FROM test;
 ?column?
---------------------------------------------------------------------
 t
(1 row)

-- restore original nodenames into pg_dist_node
UPDATE pg_dist_node SET nodename = 'localhost' WHERE nodeid = ANY(:'updated_nodeids'::int[]);
-- reset it
ALTER SYSTEM RESET citus.node_conninfo;
select pg_reload_conf();
 pg_reload_conf
---------------------------------------------------------------------
 t
(1 row)

select pg_sleep(0.1); -- wait for config reload to apply
 pg_sleep
---------------------------------------------------------------------

(1 row)

DROP SCHEMA node_conninfo_reload CASCADE;
NOTICE:  drop cascades to table test
