mirror of https://github.com/postgres/postgres
Fix volatile-safety issue in dblink's materializeQueryResult().
Some fields of the sinfo struct are modified within PG_TRY and then referenced within PG_CATCH, so as with recent patch to async.c, "volatile" is necessary for strict POSIX compliance; and that propagates to a couple of subroutines as well as materializeQueryResult() itself. I think the risk of actual issues here is probably higher than in async.c, because storeQueryResult() is likely to get inlined into materializeQueryResult(), leaving the compiler free to conclude that its stores into sinfo fields are dead code.
This commit is contained in:
parent
168a809d4b
commit
dabda64152
|
@ -94,8 +94,8 @@ static void materializeQueryResult(FunctionCallInfo fcinfo,
|
||||||
const char *conname,
|
const char *conname,
|
||||||
const char *sql,
|
const char *sql,
|
||||||
bool fail);
|
bool fail);
|
||||||
static PGresult *storeQueryResult(storeInfo *sinfo, PGconn *conn, const char *sql);
|
static PGresult *storeQueryResult(volatile storeInfo *sinfo, PGconn *conn, const char *sql);
|
||||||
static void storeRow(storeInfo *sinfo, PGresult *res, bool first);
|
static void storeRow(volatile storeInfo *sinfo, PGresult *res, bool first);
|
||||||
static remoteConn *getConnectionByName(const char *name);
|
static remoteConn *getConnectionByName(const char *name);
|
||||||
static HTAB *createConnHash(void);
|
static HTAB *createConnHash(void);
|
||||||
static void createNewConnection(const char *name, remoteConn *rconn);
|
static void createNewConnection(const char *name, remoteConn *rconn);
|
||||||
|
@ -966,13 +966,13 @@ materializeQueryResult(FunctionCallInfo fcinfo,
|
||||||
{
|
{
|
||||||
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
|
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
|
||||||
PGresult *volatile res = NULL;
|
PGresult *volatile res = NULL;
|
||||||
storeInfo sinfo;
|
volatile storeInfo sinfo;
|
||||||
|
|
||||||
/* prepTuplestoreResult must have been called previously */
|
/* prepTuplestoreResult must have been called previously */
|
||||||
Assert(rsinfo->returnMode == SFRM_Materialize);
|
Assert(rsinfo->returnMode == SFRM_Materialize);
|
||||||
|
|
||||||
/* initialize storeInfo to empty */
|
/* initialize storeInfo to empty */
|
||||||
memset(&sinfo, 0, sizeof(sinfo));
|
memset((void *) &sinfo, 0, sizeof(sinfo));
|
||||||
sinfo.fcinfo = fcinfo;
|
sinfo.fcinfo = fcinfo;
|
||||||
|
|
||||||
PG_TRY();
|
PG_TRY();
|
||||||
|
@ -1077,7 +1077,7 @@ materializeQueryResult(FunctionCallInfo fcinfo,
|
||||||
* Execute query, and send any result rows to sinfo->tuplestore.
|
* Execute query, and send any result rows to sinfo->tuplestore.
|
||||||
*/
|
*/
|
||||||
static PGresult *
|
static PGresult *
|
||||||
storeQueryResult(storeInfo *sinfo, PGconn *conn, const char *sql)
|
storeQueryResult(volatile storeInfo *sinfo, PGconn *conn, const char *sql)
|
||||||
{
|
{
|
||||||
bool first = true;
|
bool first = true;
|
||||||
int nestlevel = -1;
|
int nestlevel = -1;
|
||||||
|
@ -1145,7 +1145,7 @@ storeQueryResult(storeInfo *sinfo, PGconn *conn, const char *sql)
|
||||||
* (in this case the PGresult might contain either zero or one row).
|
* (in this case the PGresult might contain either zero or one row).
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
storeRow(storeInfo *sinfo, PGresult *res, bool first)
|
storeRow(volatile storeInfo *sinfo, PGresult *res, bool first)
|
||||||
{
|
{
|
||||||
int nfields = PQnfields(res);
|
int nfields = PQnfields(res);
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
Loading…
Reference in New Issue