@@ -596,7 +596,6 @@ sighup_handler(int signum)
596596int
597597main (int argc , char * * argv )
598598{
599- PGresult * res ;
600599 static struct option long_options [] = {
601600/* general options */
602601 {"file" , required_argument , NULL , 'f' },
@@ -628,6 +627,7 @@ main(int argc, char **argv)
628627 int option_index ;
629628 uint32 hi ,
630629 lo ;
630+ char * db_name ;
631631
632632 progname = get_progname (argv [0 ]);
633633 set_pglocale_pgservice (argv [0 ], PG_TEXTDOMAIN ("pg_recvlogical" ));
@@ -834,124 +834,62 @@ main(int argc, char **argv)
834834#endif
835835
836836 /*
837- * don't really need this but it actually helps to get more precise error
838- * messages about authentication, required GUCs and such without starting
839- * to loop around connection attempts lateron .
837+ * Obtain a connection to server. This is not really necessary but it
838+ * helps to get more precise error messages about authentification,
839+ * required GUC parameters and such .
840840 */
841- {
842- conn = GetConnection ();
843- if (!conn )
844- /* Error message already written in GetConnection() */
845- exit (1 );
841+ conn = GetConnection ();
842+ if (!conn )
843+ /* Error message already written in GetConnection() */
844+ exit (1 );
846845
847- /*
848- * Run IDENTIFY_SYSTEM so we can get the timeline and current xlog
849- * position.
850- */
851- res = PQexec (conn , "IDENTIFY_SYSTEM" );
852- if (PQresultStatus (res ) != PGRES_TUPLES_OK )
853- {
854- fprintf (stderr , _ ("%s: could not send replication command \"%s\": %s" ),
855- progname , "IDENTIFY_SYSTEM" , PQerrorMessage (conn ));
856- disconnect_and_exit (1 );
857- }
846+ /*
847+ * Run IDENTIFY_SYSTEM to make sure we connected using a database specific
848+ * replication connection.
849+ */
850+ if (!RunIdentifySystem (conn , NULL , NULL , NULL , & db_name ))
851+ disconnect_and_exit (1 );
858852
859- if (PQntuples (res ) != 1 || PQnfields (res ) < 4 )
860- {
861- fprintf (stderr ,
862- _ ("%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n" ),
863- progname , PQntuples (res ), PQnfields (res ), 1 , 4 );
864- disconnect_and_exit (1 );
865- }
866- PQclear (res );
853+ if (db_name == NULL )
854+ {
855+ fprintf (stderr ,
856+ _ ("%s: failed to establish database specific replication connection\n" ),
857+ progname );
858+ disconnect_and_exit (1 );
867859 }
868860
869-
870- /*
871- * drop a replication slot
872- */
861+ /* Drop a replication slot. */
873862 if (do_drop_slot )
874863 {
875- char query [256 ];
876-
877864 if (verbose )
878865 fprintf (stderr ,
879866 _ ("%s: dropping replication slot \"%s\"\n" ),
880867 progname , replication_slot );
881868
882- snprintf (query , sizeof (query ), "DROP_REPLICATION_SLOT \"%s\"" ,
883- replication_slot );
884- res = PQexec (conn , query );
885- if (PQresultStatus (res ) != PGRES_COMMAND_OK )
886- {
887- fprintf (stderr , _ ("%s: could not send replication command \"%s\": %s" ),
888- progname , query , PQerrorMessage (conn ));
869+ if (!DropReplicationSlot (conn , replication_slot ))
889870 disconnect_and_exit (1 );
890- }
891-
892- if (PQntuples (res ) != 0 || PQnfields (res ) != 0 )
893- {
894- fprintf (stderr ,
895- _ ("%s: could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n" ),
896- progname , replication_slot , PQntuples (res ), PQnfields (res ), 0 , 0 );
897- disconnect_and_exit (1 );
898- }
899-
900- PQclear (res );
901- disconnect_and_exit (0 );
902871 }
903872
904- /*
905- * create a replication slot
906- */
873+ /* Create a replication slot. */
907874 if (do_create_slot )
908875 {
909- char query [256 ];
910-
911876 if (verbose )
912877 fprintf (stderr ,
913878 _ ("%s: creating replication slot \"%s\"\n" ),
914879 progname , replication_slot );
915880
916- snprintf (query , sizeof (query ), "CREATE_REPLICATION_SLOT \"%s\" LOGICAL \"%s\"" ,
917- replication_slot , plugin );
918-
919- res = PQexec (conn , query );
920- if (PQresultStatus (res ) != PGRES_TUPLES_OK )
921- {
922- fprintf (stderr , _ ("%s: could not send replication command \"%s\": %s" ),
923- progname , query , PQerrorMessage (conn ));
881+ if (!CreateReplicationSlot (conn , replication_slot , plugin ,
882+ & startpos , false))
924883 disconnect_and_exit (1 );
925- }
926-
927- if (PQntuples (res ) != 1 || PQnfields (res ) != 4 )
928- {
929- fprintf (stderr ,
930- _ ("%s: could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n" ),
931- progname , replication_slot , PQntuples (res ), PQnfields (res ), 1 , 4 );
932- disconnect_and_exit (1 );
933- }
934-
935- if (sscanf (PQgetvalue (res , 0 , 1 ), "%X/%X" , & hi , & lo ) != 2 )
936- {
937- fprintf (stderr ,
938- _ ("%s: could not parse transaction log location \"%s\"\n" ),
939- progname , PQgetvalue (res , 0 , 1 ));
940- disconnect_and_exit (1 );
941- }
942- startpos = ((uint64 ) hi ) << 32 | lo ;
943-
944- replication_slot = strdup (PQgetvalue (res , 0 , 0 ));
945- PQclear (res );
946884 }
947885
948-
949886 if (!do_start_slot )
950887 disconnect_and_exit (0 );
951888
889+ /* Stream loop */
952890 while (true)
953891 {
954- StreamLog ();
892+ StreamLogicalLog ();
955893 if (time_to_abort )
956894 {
957895 /*
0 commit comments