32 #define ERRCODE_DUPLICATE_OBJECT "42710" 39 #define MINIMUM_VERSION_FOR_SHOW_CMD 100000 44 #define MINIMUM_VERSION_FOR_GROUP_ACCESS 110000 68 const char **keywords;
90 if (conn_opts == NULL)
96 for (conn_opt = conn_opts; conn_opt->
keyword != NULL; conn_opt++)
98 if (conn_opt->
val != NULL && conn_opt->
val[0] !=
'\0' &&
99 strcmp(conn_opt->
keyword,
"dbname") != 0)
103 keywords =
pg_malloc0((argcount + 1) *
sizeof(*keywords));
104 values =
pg_malloc0((argcount + 1) *
sizeof(*values));
106 for (conn_opt = conn_opts; conn_opt->
keyword != NULL; conn_opt++)
108 if (conn_opt->
val != NULL && conn_opt->
val[0] !=
'\0' &&
109 strcmp(conn_opt->
keyword,
"dbname") != 0)
112 values[
i] = conn_opt->
val;
119 keywords =
pg_malloc0((argcount + 1) *
sizeof(*keywords));
120 values =
pg_malloc0((argcount + 1) *
sizeof(*values));
123 keywords[
i] =
"dbname";
126 keywords[
i] =
"replication";
127 values[
i] =
dbname == NULL ?
"true" :
"database";
129 keywords[
i] =
"fallback_application_name";
135 keywords[
i] =
"host";
141 keywords[
i] =
"user";
147 keywords[
i] =
"port";
163 need_password =
false;
169 keywords[
i] =
"password";
196 need_password =
true;
199 while (need_password);
247 pg_log_error(
"could not determine server setting for integer_datetimes");
252 if (strcmp(tmpparam,
"on") != 0)
254 pg_log_error(
"integer_datetimes compile flag does not match server");
294 res =
PQexec(conn,
"SHOW wal_segment_size");
297 pg_log_error(
"could not send replication command \"%s\": %s",
305 pg_log_error(
"could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields",
313 if (sscanf(
PQgetvalue(res, 0, 0),
"%d%s", &xlog_val, xlog_unit) != 2)
323 if (strcmp(xlog_unit,
"MB") == 0)
324 multiplier = 1024 * 1024;
325 else if (strcmp(xlog_unit,
"GB") == 0)
326 multiplier = 1024 * 1024 * 1024;
333 pg_log_error(
ngettext(
"WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte",
334 "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes",
367 res =
PQexec(conn,
"SHOW data_directory_mode");
370 pg_log_error(
"could not send replication command \"%s\": %s",
378 pg_log_error(
"could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields",
385 if (sscanf(
PQgetvalue(res, 0, 0),
"%o", &data_directory_mode) != 1)
387 pg_log_error(
"group access flag could not be parsed: %s",
419 res =
PQexec(conn,
"IDENTIFY_SYSTEM");
422 pg_log_error(
"could not send replication command \"%s\": %s",
430 pg_log_error(
"could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields",
442 if (starttli != NULL)
446 if (startpos != NULL)
448 if (sscanf(
PQgetvalue(res, 0, 2),
"%X/%X", &hi, &lo) != 2)
450 pg_log_error(
"could not parse write-ahead log location \"%s\"",
456 *startpos = ((uint64) hi) << 32 | lo;
467 pg_log_error(
"could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields",
488 bool is_temporary,
bool is_physical,
bool reserve_wal,
496 Assert((is_physical && plugin == NULL) ||
497 (!is_physical && plugin != NULL));
498 Assert(slot_name != NULL);
523 if (slot_exists_ok &&
533 pg_log_error(
"could not send replication command \"%s\": %s",
544 pg_log_error(
"could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields",
568 Assert(slot_name != NULL);
578 pg_log_error(
"could not send replication command \"%s\": %s",
588 pg_log_error(
"could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields",
628 long *secs,
int *microsecs)
655 return (diff >= msec * INT64CONST(1000));
666 memcpy(buf, &n64,
sizeof(n64));
677 memcpy(&n64, buf,
sizeof(n64));
#define IsValidWalSegSize(size)
static const char * plugin
int PQnfields(const PGresult *res)
char * PQerrorMessage(const PGconn *conn)
int gettimeofday(struct timeval *tp, struct timezone *tzp)
TimestampTz feGetCurrentTimestamp(void)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
#define pg_log_error(...)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
#define DEFAULT_XLOG_SEG_SIZE
bool RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli, XLogRecPtr *startpos, char **db_name)
void PQfinish(PGconn *conn)
char * simple_prompt(const char *prompt, bool echo)
int PQserverVersion(const PGconn *conn)
int PQntuples(const PGresult *res)
bool feTimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
ExecStatusType PQresultStatus(const PGresult *res)
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
#define MINIMUM_VERSION_FOR_SHOW_CMD
static bool slot_exists_ok
void destroyPQExpBuffer(PQExpBuffer str)
PQconninfoOption * PQconninfoParse(const char *conninfo, char **errmsg)
bool RetrieveWalSegSize(PGconn *conn)
void * pg_malloc0(size_t size)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void feTimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
void PQconninfoFree(PQconninfoOption *connOptions)
char * pg_strdup(const char *in)
#define ngettext(s, p, n)
PQExpBuffer createPQExpBuffer(void)
void PQclear(PGresult *res)
char * PQresultErrorField(const PGresult *res, int fieldcode)
#define Assert(condition)
static XLogRecPtr startpos
#define ALWAYS_SECURE_SEARCH_PATH_SQL
bool CreateReplicationSlot(PGconn *conn, const char *slot_name, const char *plugin, bool is_temporary, bool is_physical, bool reserve_wal, bool slot_exists_ok)
static Datum values[MAXATTR]
#define MINIMUM_VERSION_FOR_GROUP_ACCESS
int PQconnectionNeedsPassword(const PGconn *conn)
int64 fe_recvint64(char *buf)
void SetDataDirectoryCreatePerm(int dataDirMode)
PGresult * PQexec(PGconn *conn, const char *query)
bool DropReplicationSlot(PGconn *conn, const char *slot_name)
#define POSTGRES_EPOCH_JDATE
static bool RetrieveDataDirCreatePerm(PGconn *conn)
void fe_sendint64(int64 i, char *buf)
PGconn * GetConnection(void)
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
ConnStatusType PQstatus(const PGconn *conn)
#define ERRCODE_DUPLICATE_OBJECT