]> granicus.if.org Git - postgresql/commitdiff
Fix volatile-safety issue in dblink's materializeQueryResult().
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 26 Jan 2015 20:17:33 +0000 (15:17 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 26 Jan 2015 20:17:33 +0000 (15:17 -0500)
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.

contrib/dblink/dblink.c

index 2d66f3fe41382f93ede124c9ae34752456fa92d2..c5892d37cb3d474ccff54f179be0d9d18b68a5c6 100644 (file)
@@ -94,8 +94,8 @@ static void materializeQueryResult(FunctionCallInfo fcinfo,
                                           const char *conname,
                                           const char *sql,
                                           bool fail);
-static PGresult *storeQueryResult(storeInfo *sinfo, PGconn *conn, const char *sql);
-static void storeRow(storeInfo *sinfo, PGresult *res, bool first);
+static PGresult *storeQueryResult(volatile storeInfo *sinfo, PGconn *conn, const char *sql);
+static void storeRow(volatile storeInfo *sinfo, PGresult *res, bool first);
 static remoteConn *getConnectionByName(const char *name);
 static HTAB *createConnHash(void);
 static void createNewConnection(const char *name, remoteConn *rconn);
@@ -966,13 +966,13 @@ materializeQueryResult(FunctionCallInfo fcinfo,
 {
        ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
        PGresult   *volatile res = NULL;
-       storeInfo       sinfo;
+       volatile storeInfo sinfo;
 
        /* prepTuplestoreResult must have been called previously */
        Assert(rsinfo->returnMode == SFRM_Materialize);
 
        /* initialize storeInfo to empty */
-       memset(&sinfo, 0, sizeof(sinfo));
+       memset((void *) &sinfo, 0, sizeof(sinfo));
        sinfo.fcinfo = fcinfo;
 
        PG_TRY();
@@ -1077,7 +1077,7 @@ materializeQueryResult(FunctionCallInfo fcinfo,
  * Execute query, and send any result rows to sinfo->tuplestore.
  */
 static PGresult *
-storeQueryResult(storeInfo *sinfo, PGconn *conn, const char *sql)
+storeQueryResult(volatile storeInfo *sinfo, PGconn *conn, const char *sql)
 {
        bool            first = true;
        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).
  */
 static void
-storeRow(storeInfo *sinfo, PGresult *res, bool first)
+storeRow(volatile storeInfo *sinfo, PGresult *res, bool first)
 {
        int                     nfields = PQnfields(res);
        HeapTuple       tuple;