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 ,
5859TransactionId * dbVacuumXidP ,TransactionId * dbFrozenXidP ,
5960Oid * dbTablespace );
6061static bool have_createdb_privilege (void );
@@ -73,6 +74,7 @@ createdb(const CreatedbStmt *stmt)
7374AclId src_owner ;
7475int src_encoding ;
7576bool src_istemplate ;
77+ bool src_allowconn ;
7678Oid src_lastsysoid ;
7779TransactionId src_vacuumxid ;
7880TransactionId 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 ))
221224ereport (ERROR ,
222225(errcode (ERRCODE_DUPLICATE_DATABASE ),
223226errmsg ("database \"%s\" already exists" ,dbname )));
@@ -229,7 +232,7 @@ createdb(const CreatedbStmt *stmt)
229232dbtemplate = "template1" ;/* Default template database name */
230233
231234if (!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 ))
234237ereport (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)
455468pg_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 */
461475heap_close (pg_database_rel ,ExclusiveLock );
@@ -552,7 +566,7 @@ dropdb(const char *dbname)
552566pgdbrel = heap_openr (DatabaseRelationName ,ExclusiveLock );
553567
554568if (!get_db_info (dbname ,& db_id ,& db_owner ,NULL ,
555- & db_istemplate ,NULL ,NULL ,NULL ,NULL ))
569+ & db_istemplate ,NULL ,NULL ,NULL ,NULL , NULL ))
556570ereport (ERROR ,
557571(errcode (ERRCODE_UNDEFINED_DATABASE ),
558572errmsg ("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 ,
940955TransactionId * dbVacuumXidP ,TransactionId * dbFrozenXidP ,
941956Oid * dbTablespace )
942957{
@@ -978,6 +993,9 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
978993/* allowed as template? */
979994if (dbIsTemplateP )
980995* dbIsTemplateP = dbform -> datistemplate ;
996+ /* allowing connections? */
997+ if (dbAllowConnP )
998+ * dbAllowConnP = dbform -> datallowconn ;
981999/* last system OID used in database */
9821000if (dbLastSysOidP )
9831001* dbLastSysOidP = dbform -> datlastsysoid ;