13
13
*
14
14
*
15
15
* IDENTIFICATION
16
- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.194 2007/04/12 15:04:35 tgl Exp $
16
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.195 2007/06/01 19:38:07 tgl Exp $
17
17
*
18
18
*-------------------------------------------------------------------------
19
19
*/
@@ -244,17 +244,6 @@ createdb(const CreatedbStmt *stmt)
244
244
dbtemplate )));
245
245
}
246
246
247
- /*
248
- * The source DB can't have any active backends, except this one
249
- * (exception is to allow CREATE DB while connected to template1).
250
- * Otherwise we might copy inconsistent data.
251
- */
252
- if (DatabaseCancelAutovacuumActivity (src_dboid , true))
253
- ereport (ERROR ,
254
- (errcode (ERRCODE_OBJECT_IN_USE ),
255
- errmsg ("source database \"%s\" is being accessed by other users" ,
256
- dbtemplate )));
257
-
258
247
/* If encoding is defaulted, use source's encoding */
259
248
if (encoding < 0 )
260
249
encoding = src_encoding ;
@@ -333,6 +322,21 @@ createdb(const CreatedbStmt *stmt)
333
322
(errcode (ERRCODE_DUPLICATE_DATABASE ),
334
323
errmsg ("database \"%s\" already exists" , dbname )));
335
324
325
+ /*
326
+ * The source DB can't have any active backends, except this one
327
+ * (exception is to allow CREATE DB while connected to template1).
328
+ * Otherwise we might copy inconsistent data.
329
+ *
330
+ * This should be last among the basic error checks, because it involves
331
+ * potential waiting; we may as well throw an error first if we're gonna
332
+ * throw one.
333
+ */
334
+ if (CheckOtherDBBackends (src_dboid ))
335
+ ereport (ERROR ,
336
+ (errcode (ERRCODE_OBJECT_IN_USE ),
337
+ errmsg ("source database \"%s\" is being accessed by other users" ,
338
+ dbtemplate )));
339
+
336
340
/*
337
341
* Select an OID for the new database, checking that it doesn't have
338
342
* a filename conflict with anything already existing in the tablespace
@@ -542,13 +546,6 @@ dropdb(const char *dbname, bool missing_ok)
542
546
Relation pgdbrel ;
543
547
HeapTuple tup ;
544
548
545
- AssertArg (dbname );
546
-
547
- if (strcmp (dbname , get_database_name (MyDatabaseId )) == 0 )
548
- ereport (ERROR ,
549
- (errcode (ERRCODE_OBJECT_IN_USE ),
550
- errmsg ("cannot drop the currently open database" )));
551
-
552
549
/*
553
550
* Look up the target database's OID, and get exclusive lock on it. We
554
551
* need this to ensure that no new backend starts up in the target
@@ -595,11 +592,19 @@ dropdb(const char *dbname, bool missing_ok)
595
592
(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
596
593
errmsg ("cannot drop a template database" )));
597
594
595
+ /* Obviously can't drop my own database */
596
+ if (db_id == MyDatabaseId )
597
+ ereport (ERROR ,
598
+ (errcode (ERRCODE_OBJECT_IN_USE ),
599
+ errmsg ("cannot drop the currently open database" )));
600
+
598
601
/*
599
- * Check for active backends in the target database. (Because we hold the
602
+ * Check for other backends in the target database. (Because we hold the
600
603
* database lock, no new ones can start after this.)
604
+ *
605
+ * As in CREATE DATABASE, check this after other error conditions.
601
606
*/
602
- if (DatabaseCancelAutovacuumActivity (db_id , false ))
607
+ if (CheckOtherDBBackends (db_id ))
603
608
ereport (ERROR ,
604
609
(errcode (ERRCODE_OBJECT_IN_USE ),
605
610
errmsg ("database \"%s\" is being accessed by other users" ,
@@ -699,6 +704,26 @@ RenameDatabase(const char *oldname, const char *newname)
699
704
(errcode (ERRCODE_UNDEFINED_DATABASE ),
700
705
errmsg ("database \"%s\" does not exist" , oldname )));
701
706
707
+ /* must be owner */
708
+ if (!pg_database_ownercheck (db_id , GetUserId ()))
709
+ aclcheck_error (ACLCHECK_NOT_OWNER , ACL_KIND_DATABASE ,
710
+ oldname );
711
+
712
+ /* must have createdb rights */
713
+ if (!have_createdb_privilege ())
714
+ ereport (ERROR ,
715
+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
716
+ errmsg ("permission denied to rename database" )));
717
+
718
+ /*
719
+ * Make sure the new name doesn't exist. See notes for same error in
720
+ * CREATE DATABASE.
721
+ */
722
+ if (OidIsValid (get_database_oid (newname )))
723
+ ereport (ERROR ,
724
+ (errcode (ERRCODE_DUPLICATE_DATABASE ),
725
+ errmsg ("database \"%s\" already exists" , newname )));
726
+
702
727
/*
703
728
* XXX Client applications probably store the current database somewhere,
704
729
* so renaming it could cause confusion. On the other hand, there may not
@@ -713,30 +738,15 @@ RenameDatabase(const char *oldname, const char *newname)
713
738
/*
714
739
* Make sure the database does not have active sessions. This is the same
715
740
* concern as above, but applied to other sessions.
741
+ *
742
+ * As in CREATE DATABASE, check this after other error conditions.
716
743
*/
717
- if (DatabaseCancelAutovacuumActivity (db_id , false ))
744
+ if (CheckOtherDBBackends (db_id ))
718
745
ereport (ERROR ,
719
746
(errcode (ERRCODE_OBJECT_IN_USE ),
720
747
errmsg ("database \"%s\" is being accessed by other users" ,
721
748
oldname )));
722
749
723
- /* make sure the new name doesn't exist */
724
- if (OidIsValid (get_database_oid (newname )))
725
- ereport (ERROR ,
726
- (errcode (ERRCODE_DUPLICATE_DATABASE ),
727
- errmsg ("database \"%s\" already exists" , newname )));
728
-
729
- /* must be owner */
730
- if (!pg_database_ownercheck (db_id , GetUserId ()))
731
- aclcheck_error (ACLCHECK_NOT_OWNER , ACL_KIND_DATABASE ,
732
- oldname );
733
-
734
- /* must have createdb rights */
735
- if (!have_createdb_privilege ())
736
- ereport (ERROR ,
737
- (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
738
- errmsg ("permission denied to rename database" )));
739
-
740
750
/* rename */
741
751
newtup = SearchSysCacheCopy (DATABASEOID ,
742
752
ObjectIdGetDatum (db_id ),
0 commit comments