From: Craig Ringer Date: Fri, 6 Feb 2015 11:31:19 +0000 (+1300) Subject: bdr: add bdr_test_replication_connection(...) X-Git-Tag: bdr-plugin/0.9.0~81 X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=eb5cb8bd15e77a138d37e4e77717077ce8504be7;p=2ndquadrant_bdr.git bdr: add bdr_test_replication_connection(...) --- diff --git a/bdr_remotecalls.c b/bdr_remotecalls.c index 108cd0a739..d0557f65a8 100644 --- a/bdr_remotecalls.c +++ b/bdr_remotecalls.c @@ -45,8 +45,10 @@ #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. @@ -288,3 +290,50 @@ bdr_get_remote_nodeinfo(PG_FUNCTION_ARGS) 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)); +} diff --git a/expected/identifier.out b/expected/identifier.out index 1564cddd82..c0322129cd 100644 --- a/expected/identifier.out +++ b/expected/identifier.out @@ -39,3 +39,25 @@ FROM bdr.bdr_get_remote_nodeinfo('dbname='||current_database()) r; 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) + diff --git a/extsql/bdr--0.8.0.7--0.9.0.0.sql b/extsql/bdr--0.8.0.7--0.9.0.0.sql index 4feaf86e97..6843d0db48 100644 --- a/extsql/bdr--0.8.0.7--0.9.0.0.sql +++ b/extsql/bdr--0.8.0.7--0.9.0.0.sql @@ -13,6 +13,14 @@ REVOKE ALL ON FUNCTION bdr_get_remote_nodeinfo(text) FROM public; 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; diff --git a/sql/identifier.sql b/sql/identifier.sql index 3627694745..58a3a8f206 100644 --- a/sql/identifier.sql +++ b/sql/identifier.sql @@ -22,3 +22,17 @@ FROM bdr.bdr_get_remote_nodeinfo('dbname=postgres') r, 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;