#include "utils/syscache.h"
PGDLLEXPORT Datum bdr_get_remote_nodeinfo(PG_FUNCTION_ARGS);
+PGDLLEXPORT Datum bdr_test_replication_connection(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(bdr_get_remote_nodeinfo);
+PG_FUNCTION_INFO_V1(bdr_test_replication_connection);
/*
* Make standard postgres connection, ERROR on failure.
PG_RETURN_DATUM(HeapTupleGetDatum(returnTuple));
}
+
+/*
+ * Test a given dsn as a replication connection, appending the replication
+ * parameter.
+ *
+ * If non-null, the node identity information arguments will be checked
+ * against the identity reported by the connection.
+ *
+ * This can be used safely against the local_dsn, as it does not enforce
+ * that the local node ID differ from the identity on the other end.
+ */
+Datum
+bdr_test_replication_connection(PG_FUNCTION_ARGS)
+{
+ const char *conninfo = text_to_cstring(PG_GETARG_TEXT_P(0));
+ TupleDesc tupleDesc;
+ HeapTuple returnTuple;
+ PGconn *conn;
+ NameData appname;
+ uint64 remote_sysid;
+ TimeLineID remote_tlid;
+ Oid remote_dboid;
+ Datum values[3];
+ bool isnull[3] = {false, false, false};
+ char sysid_str[33];
+
+ if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+
+ strncpy(NameStr(appname), "BDR test connection", NAMEDATALEN);
+
+ conn = bdr_connect(conninfo, &appname, &remote_sysid, &remote_tlid,
+ &remote_dboid);
+
+ snprintf(sysid_str, sizeof(sysid_str), UINT64_FORMAT, remote_sysid);
+ sysid_str[sizeof(sysid_str)-1] = '\0';
+
+ values[0] = CStringGetTextDatum(sysid_str);
+ values[1] = ObjectIdGetDatum(remote_tlid);
+ values[2] = ObjectIdGetDatum(remote_dboid);
+
+ returnTuple = heap_form_tuple(tupleDesc, values, isnull);
+
+ PQfinish(conn);
+
+ PG_RETURN_DATUM(HeapTupleGetDatum(returnTuple));
+}
t
(1 row)
+-- Test probing for replication connection
+SELECT
+ r.sysid = l.sysid,
+ r.timeline = l.timeline,
+ r.dboid = (SELECT oid FROM pg_database WHERE datname = 'postgres')
+FROM bdr.bdr_test_replication_connection('dbname=postgres') r,
+ bdr.bdr_get_local_nodeid() l;
+ ?column? | ?column? | ?column?
+----------+----------+----------
+ t | t | t
+(1 row)
+
+-- Probing replication connection for the local dsn will work too
+-- even though the identifier is the same.
+SELECT
+ r.dboid = (SELECT oid FROM pg_database WHERE datname = current_database())
+FROM bdr.bdr_test_replication_connection('dbname='||current_database()) r;
+ ?column?
+----------
+ t
+(1 row)
+
COMMENT ON FUNCTION bdr_get_remote_nodeinfo(text) IS 'Get node identity and BDR info from a remote server by dsn';
+CREATE FUNCTION bdr_test_replication_connection(dsn text, sysid OUT text, timeline OUT oid, dboid OUT oid)
+RETURNS record LANGUAGE c AS 'MODULE_PATHNAME';
+
+REVOKE ALL ON FUNCTION bdr_test_replication_connection(text) FROM public;
+
+COMMENT ON FUNCTION bdr_test_replication_connection(text)
+IS 'Make a replication-mode connection to the specified DSN and get its node identity.';
+
RESET bdr.permit_unsafe_ddl_commands;
RESET bdr.skip_ddl_replication;
RESET search_path;
SELECT
r.dboid = (SELECT oid FROM pg_database WHERE datname = current_database())
FROM bdr.bdr_get_remote_nodeinfo('dbname='||current_database()) r;
+
+-- Test probing for replication connection
+SELECT
+ r.sysid = l.sysid,
+ r.timeline = l.timeline,
+ r.dboid = (SELECT oid FROM pg_database WHERE datname = 'postgres')
+FROM bdr.bdr_test_replication_connection('dbname=postgres') r,
+ bdr.bdr_get_local_nodeid() l;
+
+-- Probing replication connection for the local dsn will work too
+-- even though the identifier is the same.
+SELECT
+ r.dboid = (SELECT oid FROM pg_database WHERE datname = current_database())
+FROM bdr.bdr_test_replication_connection('dbname='||current_database()) r;