for (i = 0; i < PQntuples(res); i++)
{
char *path = PQgetvalue(res, i, 0);
- int filesize = atoi(PQgetvalue(res, i, 1));
+ int64 filesize = atol(PQgetvalue(res, i, 1));
bool isdir = (strcmp(PQgetvalue(res, i, 2), "t") == 0);
char *link_target = PQgetvalue(res, i, 3);
file_type_t type;
PQclear(res);
}
+/*
+ * Converts an int64 from network byte order to native format.
+ */
+static int64
+pg_recvint64(int64 value)
+{
+ union
+ {
+ int64 i64;
+ uint32 i32[2];
+ } swap;
+ int64 result;
+
+ swap.i64 = value;
+
+ result = (uint32) ntohl(swap.i32[0]);
+ result <<= 32;
+ result |= (uint32) ntohl(swap.i32[1]);
+
+ return result;
+}
+
/*----
* Runs a query, which returns pieces of files from the remote source data
* directory, and overwrites the corresponding parts of target files with
* the received parts. The result set is expected to be of format:
*
* path text -- path in the data directory, e.g "base/1/123"
- * begin int4 -- offset within the file
+ * begin int8 -- offset within the file
* chunk bytea -- file content
*----
*/
{
char *filename;
int filenamelen;
- int chunkoff;
+ int64 chunkoff;
int chunksize;
char *chunk;
pg_fatal("unexpected result set size while fetching remote files\n");
if (PQftype(res, 0) != TEXTOID ||
- PQftype(res, 1) != INT4OID ||
+ PQftype(res, 1) != INT8OID ||
PQftype(res, 2) != BYTEAOID)
{
pg_fatal("unexpected data types in result set while fetching remote files: %u %u %u\n",
pg_fatal("unexpected null values in result while fetching remote files\n");
}
- if (PQgetlength(res, 0, 1) != sizeof(int32))
+ if (PQgetlength(res, 0, 1) != sizeof(int64))
pg_fatal("unexpected result length while fetching remote files\n");
/* Read result set to local variables */
- memcpy(&chunkoff, PQgetvalue(res, 0, 1), sizeof(int32));
- chunkoff = ntohl(chunkoff);
+ memcpy(&chunkoff, PQgetvalue(res, 0, 1), sizeof(int64));
+ chunkoff = pg_recvint64(chunkoff);
chunksize = PQgetlength(res, 0, 2);
filenamelen = PQgetlength(res, 0, 0);
continue;
}
- pg_log(PG_DEBUG, "received chunk for file \"%s\", offset %d, size %d\n",
+ pg_log(PG_DEBUG, "received chunk for file \"%s\", offset " INT64_FORMAT ", size %d\n",
filename, chunkoff, chunksize);
open_target_file(filename, false);
* function to actually fetch the data.
*/
static void
-fetch_file_range(const char *path, unsigned int begin, unsigned int end)
+fetch_file_range(const char *path, uint64 begin, uint64 end)
{
char linebuf[MAXPGPATH + 23];
{
unsigned int len;
+ /* Fine as long as CHUNKSIZE is not bigger than UINT32_MAX */
if (end - begin > CHUNKSIZE)
len = CHUNKSIZE;
else
- len = end - begin;
+ len = (unsigned int) (end - begin);
- snprintf(linebuf, sizeof(linebuf), "%s\t%u\t%u\n", path, begin, len);
+ snprintf(linebuf, sizeof(linebuf), "%s\t" UINT64_FORMAT "\t%u\n", path, begin, len);
if (PQputCopyData(conn, linebuf, strlen(linebuf)) != 1)
pg_fatal("could not send COPY data: %s",
* First create a temporary table, and load it with the blocks that we
* need to fetch.
*/
- sql = "CREATE TEMPORARY TABLE fetchchunks(path text, begin int4, len int4);";
+ sql = "CREATE TEMPORARY TABLE fetchchunks(path text, begin int8, len int4);";
res = PQexec(conn, sql);
if (PQresultStatus(res) != PGRES_COMMAND_OK)