@@ -147,7 +147,7 @@ libpqProcessFileList(void)
147147{
148148PGresult *res;
149149const 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/*----