9
9
*
10
10
*
11
11
* IDENTIFICATION
12
- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.144 2004/08/30 03:50:24 tgl Exp $
12
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.145 2004/10/17 20:47:20 tgl Exp $
13
13
*
14
14
*-------------------------------------------------------------------------
15
15
*/
@@ -281,6 +281,37 @@ createdb(const CreatedbStmt *stmt)
281
281
if (aclresult != ACLCHECK_OK )
282
282
aclcheck_error (aclresult , ACL_KIND_TABLESPACE ,
283
283
tablespacename );
284
+
285
+ /*
286
+ * If we are trying to change the default tablespace of the template,
287
+ * we require that the template not have any files in the new default
288
+ * tablespace. This is necessary because otherwise the copied
289
+ * database would contain pg_class rows that refer to its default
290
+ * tablespace both explicitly (by OID) and implicitly (as zero), which
291
+ * would cause problems. For example another CREATE DATABASE using
292
+ * the copied database as template, and trying to change its default
293
+ * tablespace again, would yield outright incorrect results (it would
294
+ * improperly move tables to the new default tablespace that should
295
+ * stay in the same tablespace).
296
+ */
297
+ if (dst_deftablespace != src_deftablespace )
298
+ {
299
+ char * srcpath ;
300
+ struct stat st ;
301
+
302
+ srcpath = GetDatabasePath (src_dboid , dst_deftablespace );
303
+
304
+ if (stat (srcpath , & st ) == 0 &&
305
+ S_ISDIR (st .st_mode ) &&
306
+ !directory_is_empty (srcpath ))
307
+ ereport (ERROR ,
308
+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
309
+ errmsg ("cannot assign new default tablespace \"%s\"" ,
310
+ tablespacename ),
311
+ errdetail ("There is a conflict because database \"%s\" already has some tables in this tablespace." ,
312
+ dbtemplate )));
313
+ pfree (srcpath );
314
+ }
284
315
}
285
316
else
286
317
{
@@ -311,11 +342,6 @@ createdb(const CreatedbStmt *stmt)
311
342
/*
312
343
* Iterate through all tablespaces of the template database, and copy
313
344
* each one to the new database.
314
- *
315
- * If we are trying to change the default tablespace of the template, we
316
- * require that the template not have any files in the new default
317
- * tablespace. This avoids the need to merge two subdirectories. This
318
- * could probably be improved later.
319
345
*/
320
346
rel = heap_openr (TableSpaceRelationName , AccessShareLock );
321
347
scan = heap_beginscan (rel , SnapshotNow , 0 , NULL );
@@ -333,7 +359,8 @@ createdb(const CreatedbStmt *stmt)
333
359
334
360
srcpath = GetDatabasePath (src_dboid , srctablespace );
335
361
336
- if (stat (srcpath , & st ) < 0 || !S_ISDIR (st .st_mode ))
362
+ if (stat (srcpath , & st ) < 0 || !S_ISDIR (st .st_mode ) ||
363
+ directory_is_empty (srcpath ))
337
364
{
338
365
/* Assume we can ignore it */
339
366
pfree (srcpath );
@@ -352,7 +379,8 @@ createdb(const CreatedbStmt *stmt)
352
379
remove_dbtablespaces (dboid );
353
380
ereport (ERROR ,
354
381
(errmsg ("could not initialize database directory" ),
355
- errdetail ("Directory \"%s\" already exists." , dstpath )));
382
+ errdetail ("Directory \"%s\" already exists." ,
383
+ dstpath )));
356
384
}
357
385
358
386
#ifndef WIN32
0 commit comments