GitHub

@@ -147,7 +147,7 @@ libpqProcessFileList(void)

147147

{

148148

PGresult *res;

149149

const char *sql;

150-

int i;

150+

int i, p;

151151152152

/*

153153

* Create a recursive directory listing of the whole data directory.

@@ -163,7 +163,8 @@ libpqProcessFileList(void)

163163

"WITH RECURSIVE files (path, filename, size, isdir) AS (\n"

164164

" SELECT '' AS path, filename, size, isdir FROM\n"

165165

" (SELECT pg_ls_dir('.', true, false) AS filename) AS fn,\n"

166-

" pg_stat_file(fn.filename, true) AS this\n"

166+

" LATERAL pg_stat_file(fn.filename, true) AS this\n"

167+

" WHERE filename = $1\n"

167168

" UNION ALL\n"

168169

" SELECT parent.path || parent.filename || '/' AS path,\n"

169170

" fn, this.size, this.isdir\n"

@@ -177,44 +178,56 @@ libpqProcessFileList(void)

177178

"FROM files\n"

178179

"LEFT OUTER JOIN pg_tablespace ON files.path = 'pg_tblspc/'\n"

179180

" AND oid::text = files.filename\n";

180-

res = PQexec(conn, sql);

181181182-

if (PQresultStatus(res) != PGRES_TUPLES_OK)

183-

pg_fatal("could not fetch file list: %s",

184-

PQresultErrorMessage(res));

182+

/* Going through the directories in a loop. Doing it this way

183+

* makes it easier to add more inclusions later.

184+

*

185+

* Note that the query filters out on top-level directories before

186+

* recursion so this will not give us problems in terms of listing

187+

* lots of files many times.

188+

*/

189+

for (p = 0; rewind_dirs[p] != NULL; ++p)

190+

{

191+

const char *paths[1];

192+

paths[0] = rewind_dirs[p];

193+

res = PQexecParams(conn, sql, 1, NULL, paths, NULL, NULL, 0);

185194186-

/* sanity check the result set */

187-

if (PQnfields(res) != 4)

188-

pg_fatal("unexpected result set while fetching file list\n");

195+

if (PQresultStatus(res) != PGRES_TUPLES_OK)

196+

pg_fatal("could not fetch file list: %s",

197+

PQresultErrorMessage(res));

189198190-

/* Read result to local variables */

191-

for (i = 0; i < PQntuples(res); i++)

192-

{

193-

char *path = PQgetvalue(res, i, 0);

194-

int64 filesize = atol(PQgetvalue(res, i, 1));

195-

bool isdir = (strcmp(PQgetvalue(res, i, 2), "t") == 0);

196-

char *link_target = PQgetvalue(res, i, 3);

197-

file_type_t type;

199+

/* sanity check the result set */

200+

if (PQnfields(res) != 4)

201+

pg_fatal("unexpected result set while fetching file list\n");

198202199-

if (PQgetisnull(res, 0, 1))

203+

/* Read result to local variables */

204+

for (i = 0; i < PQntuples(res); i++)

200205

{

201-

/*

202-

* The file was removed from the server while the query was

203-

* running. Ignore it.

204-

*/

205-

continue;

206+

char *path = PQgetvalue(res, i, 0);

207+

int64 filesize = atol(PQgetvalue(res, i, 1));

208+

bool isdir = (strcmp(PQgetvalue(res, i, 2), "t") == 0);

209+

char *link_target = PQgetvalue(res, i, 3);

210+

file_type_t type;

211+212+

if (PQgetisnull(res, 0, 1))

213+

{

214+

/*

215+

* The file was removed from the server while the query was

216+

* running. Ignore it.

217+

*/

218+

continue;

219+

}

220+221+

if (link_target[0])

222+

type = FILE_TYPE_SYMLINK;

223+

else if (isdir)

224+

type = FILE_TYPE_DIRECTORY;

225+

else

226+

type = FILE_TYPE_REGULAR;

227+

process_source_file(path, type, filesize, link_target);

206228

}

207-208-

if (link_target[0])

209-

type = FILE_TYPE_SYMLINK;

210-

else if (isdir)

211-

type = FILE_TYPE_DIRECTORY;

212-

else

213-

type = FILE_TYPE_REGULAR;

214-215-

process_source_file(path, type, filesize, link_target);

229+

PQclear(res);

216230

}

217-

PQclear(res);

218231

}

219232220233

/*----

Read the original on github.com ↗