Skip to content

Commit 5b47c54

Browse files
committed
Add connection sanity checks to create_subscription
1 parent 366290b commit 5b47c54

File tree

8 files changed

+152
-11
lines changed

8 files changed

+152
-11
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ SCRIPTS_built = pglogical_create_subscriber
1818
PG_CPPFLAGS = -I$(libpq_srcdir)
1919
SHLIB_LINK = $(libpq)
2020

21-
REGRESS = init basic extended toasted replication_set add_table matview bidirectional foreign_key functions drop
21+
REGRESS = init_fail init basic extended toasted replication_set add_table matview bidirectional foreign_key functions drop
2222

2323
ifdef USE_PGXS
2424

expected/init.out

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,17 @@ END;$FUNC$ LANGUAGE plpgsql;
2020
\c postgres
2121
GRANT ALL ON SCHEMA public TO nonsuper;
2222
\c regression
23-
CREATE EXTENSION pglogical;
23+
SET client_min_messages = 'warning';
24+
CREATE EXTENSION IF NOT EXISTS pglogical;
2425
SELECT * FROM pglogical.create_node(node_name := 'test_provider', dsn := 'dbname=regression user=super');
2526
create_node
2627
-------------
2728
2689511696
2829
(1 row)
2930

3031
\c postgres
31-
CREATE EXTENSION pglogical;
32+
SET client_min_messages = 'warning';
33+
CREATE EXTENSION IF NOT EXISTS pglogical;
3234
SELECT * FROM pglogical.create_node(node_name := 'test_subscriber', dsn := 'dbname=postgres user=super');
3335
create_node
3436
-------------

expected/init_fail.out

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
\c regression
2+
SET client_min_messages = 'warning';
3+
DROP ROLE IF EXISTS nonreplica;
4+
CREATE USER nonreplica;
5+
CREATE EXTENSION IF NOT EXISTS pglogical;
6+
GRANT ALL ON SCHEMA pglogical TO nonreplica;
7+
GRANT ALL ON ALL TABLES IN SCHEMA pglogical TO nonreplica;
8+
\c postgres
9+
SET client_min_messages = 'warning';
10+
CREATE EXTENSION IF NOT EXISTS pglogical;
11+
-- fail (local node not existing)
12+
SELECT * FROM pglogical.create_subscription(
13+
subscription_name := 'test_subscription',
14+
provider_dsn := 'dbname=regression user=nonreplica',
15+
forward_origins := '{}');
16+
ERROR: local node not found
17+
-- succeed
18+
SELECT * FROM pglogical.create_node(node_name := 'test_subscriber', dsn := 'dbname=postgres user=nonreplica');
19+
create_node
20+
-------------
21+
1755434425
22+
(1 row)
23+
24+
-- fail (can't connect to remote)
25+
SELECT * FROM pglogical.create_subscription(
26+
subscription_name := 'test_subscription',
27+
provider_dsn := 'dbname=regression user=nonexisting',
28+
forward_origins := '{}');
29+
ERROR: could not connect to the postgresql server: FATAL: role "nonexisting" does not exist
30+
31+
DETAIL: dsn was: dbname=regression user=nonexisting fallback_application_name='create_subscription'
32+
-- fail (remote node not existing)
33+
SELECT * FROM pglogical.create_subscription(
34+
subscription_name := 'test_subscription',
35+
provider_dsn := 'dbname=regression user=nonreplica',
36+
forward_origins := '{}');
37+
ERROR: could fetch remote node info: ERROR: local node not found
38+
39+
40+
\c regression
41+
-- succeed
42+
SELECT * FROM pglogical.create_node(node_name := 'test_provider', dsn := 'dbname=postgres user=nonreplica');
43+
create_node
44+
-------------
45+
2689511696
46+
(1 row)
47+
48+
\c postgres
49+
-- fail (can't connect with replication connection to remote)
50+
SELECT * FROM pglogical.create_subscription(
51+
subscription_name := 'test_subscription',
52+
provider_dsn := 'dbname=regression user=nonreplica',
53+
forward_origins := '{}');
54+
ERROR: could not connect to the postgresql server in replication mode: FATAL: no pg_hba.conf entry for replication connection from host "[local]", user "nonreplica"
55+
56+
DETAIL: dsn was: dbname=regression user=nonreplica replication=database fallback_application_name='create_subscription'
57+
-- cleanup
58+
SELECT * FROM pglogical.drop_node('test_subscriber');
59+
drop_node
60+
-----------
61+
t
62+
(1 row)
63+
64+
\c regression
65+
SELECT * FROM pglogical.drop_node('test_provider');
66+
drop_node
67+
-----------
68+
t
69+
(1 row)
70+
71+
SET client_min_messages = 'warning';
72+
DROP OWNED BY nonreplica;
73+
DROP ROLE IF EXISTS nonreplica;

pglogical.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ pglogical_connect(const char *connstring, const char *connname)
141141
conn = PQconnectdb(dsn.data);
142142
if (PQstatus(conn) != CONNECTION_OK)
143143
{
144-
ereport(FATAL,
144+
ereport(ERROR,
145145
(errmsg("could not connect to the postgresql server: %s",
146146
PQerrorMessage(conn)),
147147
errdetail("dsn was: %s", dsn.data)));
@@ -167,7 +167,7 @@ pglogical_connect_replica(const char *connstring, const char *connname)
167167
conn = PQconnectdb(dsn.data);
168168
if (PQstatus(conn) != CONNECTION_OK)
169169
{
170-
ereport(FATAL,
170+
ereport(ERROR,
171171
(errmsg("could not connect to the postgresql server in replication mode: %s",
172172
PQerrorMessage(conn)),
173173
errdetail("dsn was: %s", dsn.data)));

pglogical_functions.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,20 @@ static void gen_slot_name(Name slot_name, char *dbname,
112112
Datum
113113
pglogical_create_node(PG_FUNCTION_ARGS)
114114
{
115-
PGLogicalNode node;
115+
char *node_name = NameStr(*PG_GETARG_NAME(0));
116+
char *node_dsn = text_to_cstring(PG_GETARG_TEXT_PP(1));
117+
PGLogicalNode node;
116118
PGlogicalInterface nodeif;
117119
PGLogicalRepSet repset;
118120

119121
node.id = InvalidOid;
120-
node.name = NameStr(*PG_GETARG_NAME(0));
122+
node.name = node_name;
121123
create_node(&node);
122124

123125
nodeif.id = InvalidOid;
124126
nodeif.name = node.name;
125127
nodeif.nodeid = node.id;
126-
nodeif.dsn = text_to_cstring(PG_GETARG_TEXT_PP(1));
128+
nodeif.dsn = node_dsn;
127129
create_node_interface(&nodeif);
128130

129131
/* Create predefined repsets. */
@@ -268,6 +270,14 @@ pglogical_create_subscription(PG_FUNCTION_ARGS)
268270
pglogical_remote_node_info(conn, &origin.id, &origin.name, NULL, NULL, NULL);
269271
PQfinish(conn);
270272

273+
/* Check that we can connect remotely also in replication mode. */
274+
conn = pglogical_connect_replica(provider_dsn, "create_subscription");
275+
PQfinish(conn);
276+
277+
/* Check that local connection works. */
278+
conn = pglogical_connect(localnode->interface->dsn, "create_subscription");
279+
PQfinish(conn);
280+
271281
/* Next, create local representation of remote node and interface. */
272282
create_node(&origin);
273283

pglogical_output

Submodule pglogical_output deleted from 5ceb199

sql/init.sql

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ END;$FUNC$ LANGUAGE plpgsql;
2626
GRANT ALL ON SCHEMA public TO nonsuper;
2727

2828
\c regression
29-
CREATE EXTENSION pglogical;
29+
SET client_min_messages = 'warning';
30+
CREATE EXTENSION IF NOT EXISTS pglogical;
3031

3132
SELECT * FROM pglogical.create_node(node_name := 'test_provider', dsn := 'dbname=regression user=super');
3233

3334
\c postgres
34-
CREATE EXTENSION pglogical;
35+
SET client_min_messages = 'warning';
36+
CREATE EXTENSION IF NOT EXISTS pglogical;
3537

3638
SELECT * FROM pglogical.create_node(node_name := 'test_subscriber', dsn := 'dbname=postgres user=super');
3739

sql/init_fail.sql

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
\c regression
2+
SET client_min_messages = 'warning';
3+
DROP ROLE IF EXISTS nonreplica;
4+
CREATE USER nonreplica;
5+
CREATE EXTENSION IF NOT EXISTS pglogical;
6+
GRANT ALL ON SCHEMA pglogical TO nonreplica;
7+
GRANT ALL ON ALL TABLES IN SCHEMA pglogical TO nonreplica;
8+
9+
\c postgres
10+
SET client_min_messages = 'warning';
11+
CREATE EXTENSION IF NOT EXISTS pglogical;
12+
13+
-- fail (local node not existing)
14+
SELECT * FROM pglogical.create_subscription(
15+
subscription_name := 'test_subscription',
16+
provider_dsn := 'dbname=regression user=nonreplica',
17+
forward_origins := '{}');
18+
19+
-- succeed
20+
SELECT * FROM pglogical.create_node(node_name := 'test_subscriber', dsn := 'dbname=postgres user=nonreplica');
21+
22+
-- fail (can't connect to remote)
23+
SELECT * FROM pglogical.create_subscription(
24+
subscription_name := 'test_subscription',
25+
provider_dsn := 'dbname=regression user=nonexisting',
26+
forward_origins := '{}');
27+
28+
-- fail (remote node not existing)
29+
SELECT * FROM pglogical.create_subscription(
30+
subscription_name := 'test_subscription',
31+
provider_dsn := 'dbname=regression user=nonreplica',
32+
forward_origins := '{}');
33+
34+
\c regression
35+
-- succeed
36+
SELECT * FROM pglogical.create_node(node_name := 'test_provider', dsn := 'dbname=postgres user=nonreplica');
37+
38+
\c postgres
39+
40+
-- fail (can't connect with replication connection to remote)
41+
SELECT * FROM pglogical.create_subscription(
42+
subscription_name := 'test_subscription',
43+
provider_dsn := 'dbname=regression user=nonreplica',
44+
forward_origins := '{}');
45+
46+
-- cleanup
47+
48+
SELECT * FROM pglogical.drop_node('test_subscriber');
49+
50+
\c regression
51+
SELECT * FROM pglogical.drop_node('test_provider');
52+
53+
SET client_min_messages = 'warning';
54+
DROP OWNED BY nonreplica;
55+
DROP ROLE IF EXISTS nonreplica;

0 commit comments

Comments
 (0)