Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit830c168

Browse files
committed
Give a more user-friendly error message in situation where CREATE DATABASE
specifies a new default tablespace and the template database already hassome tables in that tablespace. There isn't any way to solve this fullywithout modifying the clone database's pg_class contents, so for now thebest we can do is issue a better error message.
1 parentfae7ce8 commit830c168

File tree

3 files changed

+43
-12
lines changed

3 files changed

+43
-12
lines changed

‎src/backend/commands/dbcommands.c

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* 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 $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -281,6 +281,37 @@ createdb(const CreatedbStmt *stmt)
281281
if (aclresult!=ACLCHECK_OK)
282282
aclcheck_error(aclresult,ACL_KIND_TABLESPACE,
283283
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+
structstatst;
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+
}
284315
}
285316
else
286317
{
@@ -311,11 +342,6 @@ createdb(const CreatedbStmt *stmt)
311342
/*
312343
* Iterate through all tablespaces of the template database, and copy
313344
* 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.
319345
*/
320346
rel=heap_openr(TableSpaceRelationName,AccessShareLock);
321347
scan=heap_beginscan(rel,SnapshotNow,0,NULL);
@@ -333,7 +359,8 @@ createdb(const CreatedbStmt *stmt)
333359

334360
srcpath=GetDatabasePath(src_dboid,srctablespace);
335361

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))
337364
{
338365
/* Assume we can ignore it */
339366
pfree(srcpath);
@@ -352,7 +379,8 @@ createdb(const CreatedbStmt *stmt)
352379
remove_dbtablespaces(dboid);
353380
ereport(ERROR,
354381
(errmsg("could not initialize database directory"),
355-
errdetail("Directory \"%s\" already exists.",dstpath)));
382+
errdetail("Directory \"%s\" already exists.",
383+
dstpath)));
356384
}
357385

358386
#ifndefWIN32

‎src/backend/commands/tablespace.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
*
4646
*
4747
* IDENTIFICATION
48-
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.11 2004/08/30 02:54:38 momjian Exp $
48+
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.12 2004/10/17 20:47:20 tgl Exp $
4949
*
5050
*-------------------------------------------------------------------------
5151
*/
@@ -75,7 +75,6 @@
7575

7676
staticboolremove_tablespace_directories(Oidtablespaceoid,boolredo);
7777
staticvoidset_short_version(constchar*path);
78-
staticbooldirectory_is_empty(constchar*path);
7978

8079

8180
/*
@@ -680,8 +679,10 @@ set_short_version(const char *path)
680679

681680
/*
682681
* Check if a directory is empty.
682+
*
683+
* This probably belongs somewhere else, but not sure where...
683684
*/
684-
staticbool
685+
bool
685686
directory_is_empty(constchar*path)
686687
{
687688
DIR*dirdesc;

‎src/include/commands/tablespace.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.5 2004/08/30 02:54:40 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.6 2004/10/17 20:47:21 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -42,6 +42,8 @@ extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
4242
externOidget_tablespace_oid(constchar*tablespacename);
4343
externchar*get_tablespace_name(Oidspc_oid);
4444

45+
externbooldirectory_is_empty(constchar*path);
46+
4547
externvoidtblspc_redo(XLogRecPtrlsn,XLogRecord*rptr);
4648
externvoidtblspc_undo(XLogRecPtrlsn,XLogRecord*rptr);
4749
externvoidtblspc_desc(char*buf,uint8xl_info,char*rec);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp