@@ -149,14 +149,14 @@ libpqProcessFileList(void)
149
149
sql =
150
150
"WITH RECURSIVE files (path, filename, size, isdir) AS (\n"
151
151
" SELECT '' AS path, filename, size, isdir FROM\n"
152
- " (SELECT pg_ls_dir('.') AS filename) AS fn,\n"
153
- " pg_stat_file(fn.filename) AS this\n"
152
+ " (SELECT pg_ls_dir('.', true, false ) AS filename) AS fn,\n"
153
+ " pg_stat_file(fn.filename, true ) AS this\n"
154
154
" UNION ALL\n"
155
155
" SELECT parent.path || parent.filename || '/' AS path,\n"
156
156
" fn, this.size, this.isdir\n"
157
157
" FROM files AS parent,\n"
158
- " pg_ls_dir(parent.path || parent.filename) AS fn,\n"
159
- " pg_stat_file(parent.path || parent.filename || '/' || fn) AS this\n"
158
+ " pg_ls_dir(parent.path || parent.filename, true, false ) AS fn,\n"
159
+ " pg_stat_file(parent.path || parent.filename || '/' || fn, true ) AS this\n"
160
160
" WHERE parent.isdir = 't'\n"
161
161
")\n"
162
162
"SELECT path || filename, size, isdir,\n"
@@ -183,6 +183,15 @@ libpqProcessFileList(void)
183
183
char * link_target = PQgetvalue (res , i , 3 );
184
184
file_type_t type ;
185
185
186
+ if (PQgetisnull (res , 0 , 1 ))
187
+ {
188
+ /*
189
+ * The file was removed from the server while the query was
190
+ * running. Ignore it.
191
+ */
192
+ continue ;
193
+ }
194
+
186
195
if (link_target [0 ])
187
196
type = FILE_TYPE_SYMLINK ;
188
197
else if (isdir )
@@ -259,8 +268,7 @@ receiveFileChunks(const char *sql)
259
268
}
260
269
261
270
if (PQgetisnull (res , 0 , 0 ) ||
262
- PQgetisnull (res , 0 , 1 ) ||
263
- PQgetisnull (res , 0 , 2 ))
271
+ PQgetisnull (res , 0 , 1 ))
264
272
{
265
273
pg_fatal ("unexpected null values in result while fetching remote files\n" );
266
274
}
@@ -280,6 +288,21 @@ receiveFileChunks(const char *sql)
280
288
281
289
chunk = PQgetvalue (res , 0 , 2 );
282
290
291
+ /*
292
+ * It's possible that the file was deleted on remote side after we
293
+ * created the file map. In this case simply ignore it, as if it was
294
+ * not there in the first place, and move on.
295
+ */
296
+ if (PQgetisnull (res , 0 , 2 ))
297
+ {
298
+ pg_log (PG_DEBUG ,
299
+ "received NULL chunk for file \"%s\", file has been deleted\n" ,
300
+ filename );
301
+ pg_free (filename );
302
+ PQclear (res );
303
+ continue ;
304
+ }
305
+
283
306
pg_log (PG_DEBUG , "received chunk for file \"%s\", offset %d, size %d\n" ,
284
307
filename , chunkoff , chunksize );
285
308
@@ -445,7 +468,7 @@ libpq_executeFileMap(filemap_t *map)
445
468
*/
446
469
sql =
447
470
"SELECT path, begin, \n"
448
- " pg_read_binary_file(path, begin, len) AS chunk\n"
471
+ " pg_read_binary_file(path, begin, len, true ) AS chunk\n"
449
472
"FROM fetchchunks\n" ;
450
473
451
474
receiveFileChunks (sql );
0 commit comments