static PGconn *conn = NULL;
+/*
+ * Relation files are fetched max CHUNKSIZE bytes at a time.
+ */
#define CHUNKSIZE 1000000
static void receiveFileChunks(const char *sql);
sql =
"-- Create a recursive directory listing of the whole data directory\n"
- "with recursive files (path, filename, size, isdir) as (\n"
- " select '' as path, filename, size, isdir from\n"
- " (select pg_ls_dir('.') as filename) as fn,\n"
- " pg_stat_file(fn.filename) as this\n"
- " union all\n"
- " select parent.path || parent.filename || '/' as path,\n"
+ "WITH RECURSIVE files (path, filename, size, isdir) AS (\n"
+ " SELECT '' AS path, filename, size, isdir FROM\n"
+ " (SELECT pg_ls_dir('.') AS filename) AS fn,\n"
+ " pg_stat_file(fn.filename) AS this\n"
+ " UNION ALL\n"
+ " SELECT parent.path || parent.filename || '/' AS path,\n"
" fn, this.size, this.isdir\n"
- " from files as parent,\n"
- " pg_ls_dir(parent.path || parent.filename) as fn,\n"
- " pg_stat_file(parent.path || parent.filename || '/' || fn) as this\n"
- " where parent.isdir = 't'\n"
+ " FROM files AS parent,\n"
+ " pg_ls_dir(parent.path || parent.filename) AS fn,\n"
+ " pg_stat_file(parent.path || parent.filename || '/' || fn) AS this\n"
+ " WHERE parent.isdir = 't'\n"
")\n"
"-- Using the cte, fetch a listing of the all the files.\n"
"--\n"
"-- link's target in general, so if the admin has put any custom\n"
"-- symbolic links in the data directory, they won't be copied\n"
"-- correctly)\n"
- "select path || filename, size, isdir,\n"
- " pg_tablespace_location(pg_tablespace.oid) as link_target\n"
- "from files\n"
- "left outer join pg_tablespace on files.path = 'pg_tblspc/'\n"
- " and oid::text = files.filename\n";
+ "SELECT path || filename, size, isdir,\n"
+ " pg_tablespace_location(pg_tablespace.oid) AS link_target\n"
+ "FROM files\n"
+ "LEFT OUTER JOIN pg_tablespace ON files.path = 'pg_tblspc/'\n"
+ " AND oid::text = files.filename\n";
res = PQexec(conn, sql);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
const char *paramValues[1];
paramValues[0] = filename;
- res = PQexecParams(conn, "select pg_read_binary_file($1)",
+ res = PQexecParams(conn, "SELECT pg_read_binary_file($1)",
1, NULL, paramValues, NULL, NULL, 1);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
* 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 int4, len int4);";
res = PQexec(conn, sql);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
/* Ok, we've sent the file list. Now receive the files */
sql =
"-- fetch all the blocks listed in the temp table.\n"
- "select path, begin, \n"
- " pg_read_binary_file(path, begin, len) as chunk\n"
- "from fetchchunks\n";
+ "SELECT path, begin, \n"
+ " pg_read_binary_file(path, begin, len) AS chunk\n"
+ "FROM fetchchunks\n";
receiveFileChunks(sql);
}