* dbcommands.c
*
*
- * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.70 2000/11/30 08:46:22 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.74 2001/03/22 03:59:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* non-export function prototypes */
static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
- int *encodingP, bool *dbIsTemplateP,
- Oid *dbLastSysOidP, char *dbpath);
+ int *encodingP, bool *dbIsTemplateP,
+ Oid *dbLastSysOidP, char *dbpath);
static bool get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb);
static char *resolve_alt_dbpath(const char *dbpath, Oid dboid);
static bool remove_dbdirs(const char *real_loc, const char *altloc);
elog(ERROR, "CREATE DATABASE: may not be called in a transaction block");
/*
- * Check for db name conflict. There is a race condition here, since
+ * Check for db name conflict. There is a race condition here, since
* another backend could create the same DB name before we commit.
- * However, holding an exclusive lock on pg_database for the whole time
- * we are copying the source database doesn't seem like a good idea,
- * so accept possibility of race to create. We will check again after
- * we grab the exclusive lock.
+ * However, holding an exclusive lock on pg_database for the whole
+ * time we are copying the source database doesn't seem like a good
+ * idea, so accept possibility of race to create. We will check again
+ * after we grab the exclusive lock.
*/
if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL))
elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname);
* Lookup database (template) to be cloned.
*/
if (!dbtemplate)
- dbtemplate = "template1"; /* Default template database name */
+ dbtemplate = "template1"; /* Default template database name */
if (!get_db_info(dbtemplate, &src_dboid, &src_owner, &src_encoding,
&src_istemplate, &src_lastsysoid, src_dbpath))
elog(ERROR, "CREATE DATABASE: template \"%s\" does not exist",
dbtemplate);
+
/*
- * Permission check: to copy a DB that's not marked datistemplate,
- * you must be superuser or the owner thereof.
+ * Permission check: to copy a DB that's not marked datistemplate, you
+ * must be superuser or the owner thereof.
*/
if (!src_istemplate)
{
elog(ERROR, "CREATE DATABASE: permission to copy \"%s\" denied",
dbtemplate);
}
+
/*
* Determine physical path of source database
*/
if (encoding < 0)
encoding = src_encoding;
- /*
- * Preassign OID for pg_database tuple, so that we can compute db path.
+ /*
+ * Preassign OID for pg_database tuple, so that we can compute db
+ * path.
*/
dboid = newoid();
/*
- * Compute nominal location (where we will try to access the database),
- * and resolve alternate physical location if one is specified.
+ * Compute nominal location (where we will try to access the
+ * database), and resolve alternate physical location if one is
+ * specified.
*/
nominal_loc = GetDatabasePath(dboid);
alt_loc = resolve_alt_dbpath(dbpath, dboid);
elog(ERROR, "database path may not contain single quotes");
/* ... otherwise we'd be open to shell exploits below */
- /* Force dirty buffers out to disk, to ensure source database is
- * up-to-date for the copy. (We really only need to flush buffers
- * for the source database...)
+ /*
+ * Force dirty buffers out to disk, to ensure source database is
+ * up-to-date for the copy. (We really only need to flush buffers for
+ * the source database...)
*/
BufferSync();
tuple = heap_formtuple(pg_database_dsc, new_record, new_record_nulls);
- tuple->t_data->t_oid = dboid; /* override heap_insert's OID selection */
+ tuple->t_data->t_oid = dboid; /* override heap_insert's OID
+ * selection */
heap_insert(pg_database_rel, tuple);
/* Close pg_database, but keep lock till commit */
heap_close(pg_database_rel, NoLock);
- /* Force dirty buffers out to disk, so that newly-connecting backends
+ /*
+ * Force dirty buffers out to disk, so that newly-connecting backends
* will see the new database in pg_database right away. (They'll see
* an uncommitted tuple, but they don't care; see GetRawDatabaseInfo.)
*/
bool db_istemplate;
bool use_super;
Oid db_id;
- char *alt_loc;
- char *nominal_loc;
- char dbpath[MAXPGPATH];
+ char *alt_loc;
+ char *nominal_loc;
+ char dbpath[MAXPGPATH];
Relation pgdbrel;
HeapScanDesc pgdbscan;
ScanKeyData key;
elog(ERROR, "DROP DATABASE: permission denied");
/*
- * Disallow dropping a DB that is marked istemplate. This is just
- * to prevent people from accidentally dropping template0 or template1;
+ * Disallow dropping a DB that is marked istemplate. This is just to
+ * prevent people from accidentally dropping template0 or template1;
* they can do so if they're really determined ...
*/
if (db_istemplate)
tup = heap_getnext(pgdbscan, 0);
if (!HeapTupleIsValid(tup))
{
+
/*
* This error should never come up since the existence of the
* database is checked earlier
}
/* Remove the database's tuple from pg_database */
- heap_delete(pgdbrel, &tup->t_self, NULL);
+ simple_heap_delete(pgdbrel, &tup->t_self);
heap_endscan(pgdbscan);
* Remove the database's subdirectory and everything in it.
*/
remove_dbdirs(nominal_loc, alt_loc);
+
+ /*
+ * Force dirty buffers out to disk, so that newly-connecting backends
+ * will see the database tuple marked dead in pg_database right away.
+ * (They'll see an uncommitted deletion, but they don't care; see
+ * GetRawDatabaseInfo.)
+ */
+ BufferSync();
}
{
tmptext = DatumGetTextP(heap_getattr(tuple,
Anum_pg_database_datpath,
- RelationGetDescr(relation),
+ RelationGetDescr(relation),
&isnull));
if (!isnull)
{
static char *
-resolve_alt_dbpath(const char * dbpath, Oid dboid)
+resolve_alt_dbpath(const char *dbpath, Oid dboid)
{
- const char * prefix;
- char * ret;
- size_t len;
+ const char *prefix;
+ char *ret;
+ size_t len;
if (dbpath == NULL || dbpath[0] == '\0')
return NULL;
else
{
/* must be environment variable */
- char * var = getenv(dbpath);
+ char *var = getenv(dbpath);
+
if (!var)
elog(ERROR, "Postmaster environment variable '%s' not set", dbpath);
if (var[0] != '/')
static bool
-remove_dbdirs(const char * nominal_loc, const char * alt_loc)
+remove_dbdirs(const char *nominal_loc, const char *alt_loc)
{
- const char *target_dir;
- char buf[MAXPGPATH + 100];
- bool success = true;
+ const char *target_dir;
+ char buf[MAXPGPATH + 100];
+ bool success = true;
target_dir = alt_loc ? alt_loc : nominal_loc;