1515 *
1616 *
1717 * IDENTIFICATION
18- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.153 2005/03/12 21:11:50 tgl Exp $
18+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.154 2005/03/12 21:33:55 tgl Exp $
1919 *
2020 *-------------------------------------------------------------------------
2121 */
5454
5555/* non-export function prototypes */
5656static bool get_db_info (const char * name , Oid * dbIdP , int4 * ownerIdP ,
57- int * encodingP , bool * dbIsTemplateP , Oid * dbLastSysOidP ,
57+ int * encodingP , bool * dbIsTemplateP , bool * dbAllowConnP ,
58+ Oid * dbLastSysOidP ,
5859 TransactionId * dbVacuumXidP , TransactionId * dbFrozenXidP ,
5960 Oid * dbTablespace );
6061static bool have_createdb_privilege (void );
@@ -73,6 +74,7 @@ createdb(const CreatedbStmt *stmt)
7374 AclId src_owner ;
7475 int src_encoding ;
7576 bool src_istemplate ;
77+ bool src_allowconn ;
7678 Oid src_lastsysoid ;
7779 TransactionId src_vacuumxid ;
7880 TransactionId src_frozenxid ;
@@ -217,7 +219,8 @@ createdb(const CreatedbStmt *stmt)
217219 * idea, so accept possibility of race to create. We will check again
218220 * after we grab the exclusive lock.
219221 */
220- if (get_db_info (dbname , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL ))
222+ if (get_db_info (dbname , NULL , NULL , NULL ,
223+ NULL , NULL , NULL , NULL , NULL , NULL ))
221224 ereport (ERROR ,
222225 (errcode (ERRCODE_DUPLICATE_DATABASE ),
223226 errmsg ("database \"%s\" already exists" , dbname )));
@@ -229,7 +232,7 @@ createdb(const CreatedbStmt *stmt)
229232 dbtemplate = "template1" ; /* Default template database name */
230233
231234 if (!get_db_info (dbtemplate , & src_dboid , & src_owner , & src_encoding ,
232- & src_istemplate , & src_lastsysoid ,
235+ & src_istemplate , & src_allowconn , & src_lastsysoid ,
233236 & src_vacuumxid , & src_frozenxid , & src_deftablespace ))
234237 ereport (ERROR ,
235238 (errcode (ERRCODE_UNDEFINED_DATABASE ),
@@ -328,6 +331,16 @@ createdb(const CreatedbStmt *stmt)
328331 /* Note there is no additional permission check in this path */
329332 }
330333
334+ /*
335+ * Normally we mark the new database with the same datvacuumxid and
336+ * datfrozenxid as the source. However, if the source is not allowing
337+ * connections then we assume it is fully frozen, and we can set the
338+ * current transaction ID as the xid limits. This avoids immediately
339+ * starting to generate warnings after cloning template0.
340+ */
341+ if (!src_allowconn )
342+ src_vacuumxid = src_frozenxid = GetCurrentTransactionId ();
343+
331344 /*
332345 * Preassign OID for pg_database tuple, so that we can compute db
333346 * path.
@@ -455,7 +468,8 @@ createdb(const CreatedbStmt *stmt)
455468 pg_database_rel = heap_openr (DatabaseRelationName , ExclusiveLock );
456469
457470 /* Check to see if someone else created same DB name meanwhile. */
458- if (get_db_info (dbname , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL ))
471+ if (get_db_info (dbname , NULL , NULL , NULL ,
472+ NULL , NULL , NULL , NULL , NULL , NULL ))
459473 {
460474 /* Don't hold lock while doing recursive remove */
461475 heap_close (pg_database_rel , ExclusiveLock );
@@ -552,7 +566,7 @@ dropdb(const char *dbname)
552566 pgdbrel = heap_openr (DatabaseRelationName , ExclusiveLock );
553567
554568 if (!get_db_info (dbname , & db_id , & db_owner , NULL ,
555- & db_istemplate , NULL , NULL , NULL , NULL ))
569+ & db_istemplate , NULL , NULL , NULL , NULL , NULL ))
556570 ereport (ERROR ,
557571 (errcode (ERRCODE_UNDEFINED_DATABASE ),
558572 errmsg ("database \"%s\" does not exist" , dbname )));
@@ -936,7 +950,8 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
936950
937951static bool
938952get_db_info (const char * name , Oid * dbIdP , int4 * ownerIdP ,
939- int * encodingP , bool * dbIsTemplateP , Oid * dbLastSysOidP ,
953+ int * encodingP , bool * dbIsTemplateP , bool * dbAllowConnP ,
954+ Oid * dbLastSysOidP ,
940955 TransactionId * dbVacuumXidP , TransactionId * dbFrozenXidP ,
941956 Oid * dbTablespace )
942957{
@@ -978,6 +993,9 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
978993 /* allowed as template? */
979994 if (dbIsTemplateP )
980995 * dbIsTemplateP = dbform -> datistemplate ;
996+ /* allowing connections? */
997+ if (dbAllowConnP )
998+ * dbAllowConnP = dbform -> datallowconn ;
981999 /* last system OID used in database */
9821000 if (dbLastSysOidP )
9831001 * dbLastSysOidP = dbform -> datlastsysoid ;
0 commit comments