提交 cc38f526 编写于 作者: H Heikki Linnakangas

Remove unnecessary use of PQExpBuffer.

StringInfo is more appropriate in backend code. (Unless the buffer needs to
be used in a thread.)

In the passing, rename the 'conn' static variable in cdbfilerepconnclient.c.
It seemed overly generic.
上级 840a451b
......@@ -15,8 +15,6 @@
#include "regex/regex.h"
#include "libpq/libpq-be.h"
#include "gp-libpq-fe.h"
#include "gp-libpq-int.h"
#include "fmgr.h"
#include "funcapi.h"
#include "utils/builtins.h"
......@@ -60,7 +58,7 @@ static char* parse_prefix_from_params(char *params);
static char* parse_status_from_params(char *params);
static char* parse_option_from_params(char *params, char *option);
static char *queryNBUBackupFilePathName(char *netbackupServiceHost, char *netbackupRestoreFileName);
static char *shellEscape(const char *shellArg, PQExpBuffer escapeBuf, bool addQuote);
static char *shellEscape(const char *shellArg, bool addQuote);
#ifdef USE_DDBOOST
......@@ -316,8 +314,6 @@ gp_backup_launch__(PG_FUNCTION_ARGS)
}
}
PQExpBuffer escapeBuf = NULL;
pszDBName = NULL;
pszUserName = (char *) NULL;
if (MyProcPort != NULL)
......@@ -330,13 +326,7 @@ gp_backup_launch__(PG_FUNCTION_ARGS)
pszDBName = "";
else
{
/*
* pszDBName will be pointing to the data portion of the PQExpBuffer
* once escpaped (escapeBuf->data), so we can't safely destroy the
* escapeBuf buffer until the end of the function.
*/
escapeBuf = createPQExpBuffer();
pszDBName = shellEscape(pszDBName, escapeBuf, true);
pszDBName = shellEscape(pszDBName, true);
}
if (pszUserName == NULL)
......@@ -996,8 +986,6 @@ gp_backup_launch__(PG_FUNCTION_ARGS)
assert(pszSaveBackupfileName != NULL && pszSaveBackupfileName[0] != '\0');
destroyPQExpBuffer(escapeBuf);
return DirectFunctionCall1(textin, CStringGetDatum(pszSaveBackupfileName));
}
......@@ -1223,7 +1211,6 @@ gp_restore_launch__(PG_FUNCTION_ARGS)
len_name = strlen(pszBackupFileName);
PQExpBuffer escapeBuf = NULL;
pszDBName = NULL;
pszUserName = NULL;
if (MyProcPort != NULL)
......@@ -1235,15 +1222,7 @@ gp_restore_launch__(PG_FUNCTION_ARGS)
if (pszDBName == NULL)
pszDBName = "";
else
{
/*
* pszDBName will be pointing to the data portion of the PQExpBuffer
* once escpaped (escapeBuf->data), so we can't safely destroy the
* escapeBuf buffer until the end of the function.
*/
escapeBuf = createPQExpBuffer();
pszDBName = shellEscape(pszDBName, escapeBuf, true);
}
pszDBName = shellEscape(pszDBName, true);
if (pszUserName == NULL)
pszUserName = "";
......@@ -1465,8 +1444,6 @@ gp_restore_launch__(PG_FUNCTION_ARGS)
assert(pszBackupFileName != NULL && pszBackupFileName[0] != '\0');
destroyPQExpBuffer(escapeBuf);
return DirectFunctionCall1(textin, CStringGetDatum(pszBackupFileName));
}
......@@ -2473,40 +2450,39 @@ static char *formDDBoostFileName(char *pszBackupKey, bool isPostData, bool isCom
* escaped.
*
* This function escapes the following characters: '"', '$', '`', '\', '!', '''.
*
* The StringInfo escapeBuf is used for assembling the escaped string and is reset at the
* start of this function.
*/
char *
shellEscape(const char *shellArg, PQExpBuffer escapeBuf, bool addQuote)
shellEscape(const char *shellArg, bool addQuote)
{
const char *s = shellArg;
const char escape = '\\';
const char *s = shellArg;
const char escape = '\\';
StringInfoData escapeBuf;
resetPQExpBuffer(escapeBuf);
initStringInfo(&escapeBuf);
if (addQuote)
appendPQExpBufferChar(escapeBuf, '\"');
/*
* Copy the shellArg into the escapeBuf prepending any characters
* requiring an escape with the escape character.
*/
while (*s != '\0')
{
switch (*s)
{
case '"':
case '$':
case '\\':
case '`':
case '!':
appendPQExpBufferChar(escapeBuf, escape);
}
appendPQExpBufferChar(escapeBuf, *s);
s++;
}
appendStringInfoChar(&escapeBuf, '\"');
if(addQuote)
appendPQExpBufferChar(escapeBuf, '\"');
return escapeBuf->data;
/*
* Copy the shellArg into the escapeBuf prepending any characters
* requiring an escape with the escape character.
*/
while (*s != '\0')
{
switch (*s)
{
case '"':
case '$':
case '\\':
case '`':
case '!':
appendStringInfoChar(&escapeBuf, escape);
}
appendStringInfoChar(&escapeBuf, *s);
s++;
}
if (addQuote)
appendStringInfoChar(&escapeBuf, '\"');
return escapeBuf.data;
}
......@@ -12,7 +12,6 @@
#include "postgres.h"
#include "gp-libpq-fe.h"
#include "gp-libpq-int.h"
#include "miscadmin.h"
#include "cdb/cdbconn.h"
#include "cdb/cdbcopy.h"
......
......@@ -13,6 +13,7 @@
*
*/
#include "postgres.h"
#include <signal.h>
#include "cdb/cdbvars.h"
......@@ -20,10 +21,10 @@
#include "cdb/cdbfilerepconnclient.h"
#include "gp-libpq-fe.h"
#include "gp-libpq-int.h"
#include "pqexpbuffer.h"
#include "cdb/cdbfilerepservice.h"
static PGconn *conn = NULL;
static PGconn *filerep_conn = NULL;
/*
*
*/
......@@ -34,51 +35,52 @@ FileRepConnClient_EstablishConnection(
bool reportError)
{
int status = STATUS_OK;
PQExpBuffer buffer = NULL;
char portbuf[11];
char timeoutbuf[11];
const char *keys[5];
const char *vals[5];
/* FileRepConnClient_CloseConnection();*/
buffer = createPQExpBuffer();
if (PQExpBufferBroken(buffer))
{
destroyPQExpBuffer(buffer);
/* XXX: allocation failed. Is this the right thing to do ? */
return STATUS_ERROR;
}
snprintf(portbuf, sizeof(portbuf), "%d", port);
snprintf(timeoutbuf, sizeof(timeoutbuf), "%d", gp_segment_connect_timeout);
keys[0] = "host";
vals[0] = hostAddress;
keys[1] = "port";
vals[1] = portbuf;
keys[2] = "dbname";
vals[2] = "postgres";
keys[3] = "connect_timeout";
vals[3] = timeoutbuf;
keys[4] = NULL;
vals[4] = NULL;
appendPQExpBuffer(buffer, "host=%s ", hostAddress);
appendPQExpBuffer(buffer, "port=%d ", port);
appendPQExpBuffer(buffer, "dbname=postgres ");
appendPQExpBuffer(buffer, "connect_timeout=%d", gp_segment_connect_timeout);
conn = PQconnectdb(buffer->data);
filerep_conn = PQconnectdbParams(keys, vals, false);
if (PQstatus(conn) != CONNECTION_OK) {
if (PQstatus(filerep_conn) != CONNECTION_OK)
{
if (reportError || Debug_filerep_print)
ereport(WARNING,
(errcode_for_socket_access(),
errmsg("could not establish connection with server, host:'%s' port:'%d' err:'%s' : %m",
hostAddress,
port,
PQerrorMessage(conn)),
PQerrorMessage(filerep_conn)),
errSendAlert(true),
FileRep_errcontext()));
status = STATUS_ERROR;
if (conn) {
PQfinish(conn);
conn = NULL;
if (filerep_conn)
{
PQfinish(filerep_conn);
filerep_conn = NULL;
}
}
/* NOTE Handle error message see ftsprobe.c */
if (buffer) {
destroyPQExpBuffer(buffer);
buffer = NULL;
}
return status;
}
......@@ -88,11 +90,12 @@ FileRepConnClient_EstablishConnection(
void
FileRepConnClient_CloseConnection(void)
{
if (conn) {
if (filerep_conn)
{
/* use non-blocking mode to avoid the long timeout in pqSendSome */
conn->nonblocking = TRUE;
PQfinish(conn);
conn = NULL;
filerep_conn->nonblocking = TRUE;
PQfinish(filerep_conn);
filerep_conn = NULL;
}
return;
}
......@@ -118,7 +121,7 @@ FileRepConnClient_SendMessage(
int status = STATUS_OK;
#ifdef USE_ASSERT_CHECKING
int prevOutCount = conn->outCount;
int prevOutCount = filerep_conn->outCount;
#endif // USE_ASSERT_CHECKING
switch(messageType)
......@@ -143,12 +146,12 @@ FileRepConnClient_SendMessage(
* Note that pqPutMsgStart and pqPutnchar both may grow the connection's internal buffer, and do not
* flush data
*/
if (pqPutMsgStart(msgType, true, conn) < 0 )
if (pqPutMsgStart(msgType, true, filerep_conn) < 0 )
{
return false;
}
if ( pqPutnchar(message, messageLength, conn) < 0 )
if ( pqPutnchar(message, messageLength, filerep_conn) < 0 )
{
return false;
}
......@@ -156,23 +159,23 @@ FileRepConnClient_SendMessage(
/* Server side needs complete messages for mode-transitions so disable auto-flush since it flushes
* partial messages
*/
pqPutMsgEndNoAutoFlush(conn);
pqPutMsgEndNoAutoFlush(filerep_conn);
/* assert that a flush did not occur */
Assert( prevOutCount + messageLength + 5 == conn->outCount ); /* the +5 is the amount added by pgPutMsgStart */
Assert( prevOutCount + messageLength + 5 == filerep_conn->outCount ); /* the +5 is the amount added by pgPutMsgStart */
/*
* note also that we could do a flush beforehand to avoid
* having pqPutMsgStart and pqPutnchar growing the buffer
*/
if (messageSynchronous || conn->outCount >= file_rep_min_data_before_flush )
if (messageSynchronous || filerep_conn->outCount >= file_rep_min_data_before_flush )
{
int result = 0;
/* wait and timeout will be handled by pqWaitTimeout */
while ((status = pqFlushNonBlocking(conn)) > 0)
while ((status = pqFlushNonBlocking(filerep_conn)) > 0)
{
/* retry on timeout */
while (!(result = pqWaitTimeout(FALSE, TRUE, conn, time(NULL) + file_rep_socket_timeout)))
while (!(result = pqWaitTimeout(FALSE, TRUE, filerep_conn, time(NULL) + file_rep_socket_timeout)))
{
if (FileRepSubProcess_IsStateTransitionRequested())
{
......
......@@ -386,7 +386,6 @@ cdbdisp_makeDispatcherState(CdbDispatcherState *ds,
/*
* Free memory in CdbDispatcherState
*
* Free the PQExpBufferData allocated in libpq.
* Free dispatcher memory context.
*/
void
......
......@@ -314,19 +314,15 @@ isPrimaryWriterGangAlive(void)
/*
* Check the segment failure reason by comparing connection error message.
*/
bool segment_failure_due_to_recovery(struct PQExpBufferData* error_message)
bool
segment_failure_due_to_recovery(const char *error_message)
{
char *fatal = NULL, *message = NULL, *ptr = NULL;
char *fatal = NULL, *ptr = NULL;
int fatal_len = 0;
if (error_message == NULL)
return false;
message = error_message->data;
if (message == NULL)
return false;
fatal = _("FATAL");
fatal_len = strlen(fatal);
......@@ -338,14 +334,14 @@ bool segment_failure_due_to_recovery(struct PQExpBufferData* error_message)
* the strings a lot we have to take extreme care with looking at
* the string.
*/
ptr = strstr(message, fatal);
ptr = strstr(error_message, fatal);
if ((ptr != NULL) && ptr[fatal_len] == ':')
{
if (strstr(message, _(POSTMASTER_IN_STARTUP_MSG)))
if (strstr(error_message, _(POSTMASTER_IN_STARTUP_MSG)))
{
return true;
}
if (strstr(message, _(POSTMASTER_IN_RECOVERY_MSG)))
if (strstr(error_message, _(POSTMASTER_IN_RECOVERY_MSG)))
{
return true;
}
......
......@@ -179,7 +179,7 @@ create_gang_retry:
break;
case PGRES_POLLING_FAILED:
if (segment_failure_due_to_recovery(&segdbDesc->conn->errorMessage))
if (segment_failure_due_to_recovery(PQerrorMessage(segdbDesc->conn)))
{
in_recovery_mode_count++;
connStatusDone[i] = true;
......
......@@ -403,7 +403,7 @@ checkConnectionStatus(Gang* gp, int* countInRecovery, int* countSuccessful, stru
ereport(LOG, (errcode(segdbDesc->errcode), errmsg("%s",segdbDesc->error_message.data)));
/* this connect failed -- but why ? */
if (segment_failure_due_to_recovery(&segdbDesc->error_message))
if (segment_failure_due_to_recovery(segdbDesc->error_message.data))
{
elog(LOG, "segment is in recovery mode (%s)", segdbDesc->whoami);
(*countInRecovery)++;
......
......@@ -55,7 +55,6 @@
#include "utils/typcache.h"
#include "utils/xml.h"
#include "gp-libpq-fe.h"
#include "pqexpbuffer.h"
/* ----------
......
......@@ -92,7 +92,7 @@ bool isPrimaryWriterGangAlive(void);
Gang *buildGangDefinition(GangType type, int gang_id, int size, int content);
void build_gpqeid_param(char *buf, int bufsz, int segIndex, bool is_writer, int gangId, int hostSegs);
char *makeOptions(void);
bool segment_failure_due_to_recovery(struct PQExpBufferData *segdbDesc);
extern bool segment_failure_due_to_recovery(const char *error_message);
/*
* disconnectAndDestroyIdleReaderGangs()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册