*** ./doc/src/sgml/catalogs.sgml.orig Mon Apr 5 12:06:40 2004 --- ./doc/src/sgml/catalogs.sgml Fri May 7 08:46:38 2004 *************** *** 1536,1541 **** --- 1536,1552 ---- + datisinit + bool + + + False when a database is just created but housekeeping initialization + tasks are not performed yet. On the first connection, the initialization + is performed and the boolean is turned to true. + + + + datlastsysoid oid *** ./src/backend/commands/dbcommands.c.orig Tue Apr 20 09:35:43 2004 --- ./src/backend/commands/dbcommands.c Fri May 7 21:52:38 2004 *************** *** 424,429 **** --- 424,430 ---- new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding); new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(false); new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true); + new_record[Anum_pg_database_datisinit - 1] = BoolGetDatum(false); new_record[Anum_pg_database_datlastsysoid - 1] = ObjectIdGetDatum(src_lastsysoid); new_record[Anum_pg_database_datvacuumxid - 1] = TransactionIdGetDatum(src_vacuumxid); new_record[Anum_pg_database_datfrozenxid - 1] = TransactionIdGetDatum(src_frozenxid); *** ./src/backend/utils/init/postinit.c.orig Fri Dec 12 19:45:09 2003 --- ./src/backend/utils/init/postinit.c Sat May 8 11:05:36 2004 *************** *** 49,54 **** --- 49,108 ---- /*** InitPostgres support ***/ + #include "executor/spi.h" + + /* Do housekeeping initializations if required, on first connection. + */ + static void InitializeDatabase(const char * dbname) + { + /* su */ + AclId saved_user = GetUserId(); + SetUserId(1); + + /* Querying in C is nice, but SQL is nicer. + * This is only done once in a lifetime of the database, + * so paying for the parser/optimiser cost is not that bad? + * What if that fails? + */ + SetQuerySnapshot(); + + if (SPI_connect() != SPI_OK_CONNECT) + ereport(ERROR, (errmsg("SPI_connect failed"))); + + if (SPI_exec("UPDATE " SystemCatalogName "." DatabaseRelationName + " SET datisinit=TRUE" + " WHERE datname=CURRENT_DATABASE()" + " AND datisinit=FALSE" , 0) != SPI_OK_UPDATE) + ereport(ERROR, (errmsg("database initialization %s update failed", + DatabaseRelationName))); + + if (SPI_processed==1) + { + /* ok, we have it! otherwise, some concurrent connection did it. */ + + if (SPI_exec("UPDATE " SystemCatalogName "." NamespaceRelationName + " SET nspowner=datdba," + " nspacl=NULL " + // nspacl = aclitems_switch_grantor(nspacl, datdba) -- ??? + " FROM " SystemCatalogName "." DatabaseRelationName " " + " WHERE nspname NOT LIKE" + " ALL(ARRAY['pg_%','information_schema'])" + " AND datname=CURRENT_DATABASE()" + " AND nspowner!=datdba;", 0) != SPI_OK_UPDATE) + ereport(ERROR, (errmsg("database initialization %s update failed", + NamespaceRelationName))); + + if (SPI_processed>0) + ereport(LOG, /* don't bother the user about these details... */ + (errmsg("database initialization schema owner updates: %d", + SPI_processed))); + } + + if (SPI_finish() != SPI_OK_FINISH) + ereport(ERROR, (errmsg("SPI_finish failed"))); + + SetUserId(saved_user); + } /* -------------------------------- * ReverifyMyDatabase *************** *** 129,134 **** --- 183,194 ---- errmsg("database \"%s\" is not currently accepting connections", name))); + /* Do we need the housekeeping initialization of the database? + * could be skipped on standalone "panic" mode? + */ + if (!dbform->datisinit) + InitializeDatabase(name); + /* * OK, we're golden. Only other to-do item is to save the encoding * info out of the pg_database tuple. *** ./src/include/catalog/catname.h.orig Sat Nov 29 23:40:58 2003 --- ./src/include/catalog/catname.h Sat May 8 09:09:11 2004 *************** *** 14,19 **** --- 14,20 ---- #ifndef CATNAME_H #define CATNAME_H + #define SystemCatalogName "pg_catalog" #define AggregateRelationName "pg_aggregate" #define AccessMethodRelationName "pg_am" *** ./src/include/catalog/catversion.h.orig Mon May 3 10:45:38 2004 --- ./src/include/catalog/catversion.h Sat May 8 10:43:47 2004 *************** *** 53,58 **** */ /* yyyymmddN */ ! #define CATALOG_VERSION_NO 200405020 #endif --- 53,58 ---- */ /* yyyymmddN */ ! #define CATALOG_VERSION_NO 200405080 #endif *** ./src/include/catalog/pg_attribute.h.orig Mon Apr 5 12:06:43 2004 --- ./src/include/catalog/pg_attribute.h Fri May 7 21:46:24 2004 *************** *** 287,299 **** DATA(insert ( 1262 encoding 23 -1 4 3 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1262 datistemplate 16 -1 1 4 0 -1 -1 t p c t f f t 0)); DATA(insert ( 1262 datallowconn 16 -1 1 5 0 -1 -1 t p c t f f t 0)); ! DATA(insert ( 1262 datlastsysoid 26 -1 4 6 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1262 datvacuumxid 28 -1 4 7 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1262 datfrozenxid 28 -1 4 8 0 -1 -1 t p i t f f t 0)); /* do not mark datpath as toastable; GetRawDatabaseInfo won't cope */ ! DATA(insert ( 1262 datpath 25 -1 -1 9 0 -1 -1 f p i t f f t 0)); ! DATA(insert ( 1262 datconfig 1009 -1 -1 10 1 -1 -1 f x i f f f t 0)); ! DATA(insert ( 1262 datacl 1034 -1 -1 11 1 -1 -1 f x i f f f t 0)); DATA(insert ( 1262 ctid 27 0 6 -1 0 -1 -1 f p s t f f t 0)); DATA(insert ( 1262 oid 26 0 4 -2 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1262 xmin 28 0 4 -3 0 -1 -1 t p i t f f t 0)); --- 287,300 ---- DATA(insert ( 1262 encoding 23 -1 4 3 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1262 datistemplate 16 -1 1 4 0 -1 -1 t p c t f f t 0)); DATA(insert ( 1262 datallowconn 16 -1 1 5 0 -1 -1 t p c t f f t 0)); ! DATA(insert ( 1262 datisinit 16 -1 1 6 0 -1 -1 t p c t f f t 0)); ! DATA(insert ( 1262 datlastsysoid 26 -1 4 7 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1262 datvacuumxid 28 -1 4 8 0 -1 -1 t p i t f f t 0)); ! DATA(insert ( 1262 datfrozenxid 28 -1 4 9 0 -1 -1 t p i t f f t 0)); /* do not mark datpath as toastable; GetRawDatabaseInfo won't cope */ ! DATA(insert ( 1262 datpath 25 -1 -1 10 0 -1 -1 f p i t f f t 0)); ! DATA(insert ( 1262 datconfig 1009 -1 -1 11 1 -1 -1 f x i f f f t 0)); ! DATA(insert ( 1262 datacl 1034 -1 -1 12 1 -1 -1 f x i f f f t 0)); DATA(insert ( 1262 ctid 27 0 6 -1 0 -1 -1 f p s t f f t 0)); DATA(insert ( 1262 oid 26 0 4 -2 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1262 xmin 28 0 4 -3 0 -1 -1 t p i t f f t 0)); *** ./src/include/catalog/pg_class.h.orig Mon Apr 5 12:06:43 2004 --- ./src/include/catalog/pg_class.h Fri May 7 21:39:32 2004 *************** *** 146,152 **** DESCR(""); DATA(insert OID = 1261 ( pg_group PGNSP 87 PGUID 0 1261 0 0 0 0 f t r 3 0 0 0 0 0 f f f f _null_ )); DESCR(""); ! DATA(insert OID = 1262 ( pg_database PGNSP 88 PGUID 0 1262 0 0 0 0 f t r 11 0 0 0 0 0 t f f f _null_ )); DESCR(""); DATA(insert OID = 376 ( pg_xactlock PGNSP 0 PGUID 0 0 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ )); DESCR(""); --- 146,152 ---- DESCR(""); DATA(insert OID = 1261 ( pg_group PGNSP 87 PGUID 0 1261 0 0 0 0 f t r 3 0 0 0 0 0 f f f f _null_ )); DESCR(""); ! DATA(insert OID = 1262 ( pg_database PGNSP 88 PGUID 0 1262 0 0 0 0 f t r 12 0 0 0 0 0 t f f f _null_ )); DESCR(""); DATA(insert OID = 376 ( pg_xactlock PGNSP 0 PGUID 0 0 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ )); DESCR(""); *** ./src/include/catalog/pg_database.h.orig Tue Feb 10 02:55:26 2004 --- ./src/include/catalog/pg_database.h Fri May 7 08:57:38 2004 *************** *** 38,43 **** --- 38,44 ---- int4 encoding; /* character encoding */ bool datistemplate; /* allowed as CREATE DATABASE template? */ bool datallowconn; /* new connections allowed? */ + bool datisinit; /* was it already initialized? */ Oid datlastsysoid; /* highest OID to consider a system OID */ TransactionId datvacuumxid; /* all XIDs before this are vacuumed */ TransactionId datfrozenxid; /* all XIDs before this are frozen */ *************** *** 57,76 **** * compiler constants for pg_database * ---------------- */ ! #define Natts_pg_database 11 #define Anum_pg_database_datname 1 #define Anum_pg_database_datdba 2 #define Anum_pg_database_encoding 3 #define Anum_pg_database_datistemplate 4 #define Anum_pg_database_datallowconn 5 ! #define Anum_pg_database_datlastsysoid 6 ! #define Anum_pg_database_datvacuumxid 7 ! #define Anum_pg_database_datfrozenxid 8 ! #define Anum_pg_database_datpath 9 ! #define Anum_pg_database_datconfig 10 ! #define Anum_pg_database_datacl 11 ! DATA(insert OID = 1 ( template1 PGUID ENCODING t t 0 0 0 "" _null_ _null_ )); DESCR("Default template database"); #define TemplateDbOid 1 --- 58,78 ---- * compiler constants for pg_database * ---------------- */ ! #define Natts_pg_database 12 #define Anum_pg_database_datname 1 #define Anum_pg_database_datdba 2 #define Anum_pg_database_encoding 3 #define Anum_pg_database_datistemplate 4 #define Anum_pg_database_datallowconn 5 ! #define Anum_pg_database_datisinit 6 ! #define Anum_pg_database_datlastsysoid 7 ! #define Anum_pg_database_datvacuumxid 8 ! #define Anum_pg_database_datfrozenxid 9 ! #define Anum_pg_database_datpath 10 ! #define Anum_pg_database_datconfig 11 ! #define Anum_pg_database_datacl 12 ! DATA(insert OID = 1 ( template1 PGUID ENCODING t t t 0 0 0 "" _null_ _null_ )); DESCR("Default template database"); #define TemplateDbOid 1 *** ./src/test/regress/expected/create_database.out.orig Sat May 8 11:07:33 2004 --- ./src/test/regress/expected/create_database.out Sat May 8 11:08:57 2004 *************** *** 0 **** --- 1,66 ---- + CREATE USER calvin; + CREATE DATABASE calvin WITH OWNER calvin; + CREATE USER hobbes; + CREATE DATABASE hobbes WITH OWNER hobbes; + SELECT datname, datdba, datisinit + FROM pg_database + WHERE datname = ANY(ARRAY['calvin', 'hobbes']) + ORDER BY datname; + datname | datdba | datisinit + ---------+--------+----------- + calvin | 100 | f + hobbes | 101 | f + (2 rows) + + \c calvin calvin + SELECT CURRENT_USER; + current_user + -------------- + calvin + (1 row) + + SELECT datname, datdba, datisinit + FROM pg_database + WHERE datname = ANY(ARRAY['calvin', 'hobbes']) + ORDER BY datname; + datname | datdba | datisinit + ---------+--------+----------- + calvin | 100 | t + hobbes | 101 | f + (2 rows) + + SELECT * + FROM pg_namespace + WHERE nspname NOT LIKE ALL(ARRAY['pg_%', 'information_schema']) + ORDER BY nspname; + nspname | nspowner | nspacl + ---------+----------+-------- + public | 100 | + (1 row) + + \c hobbes calvin + SELECT CURRENT_USER; + current_user + -------------- + calvin + (1 row) + + SELECT datname, datdba, datisinit + FROM pg_database + WHERE datname = ANY(ARRAY['calvin', 'hobbes']) + ORDER BY datname; + datname | datdba | datisinit + ---------+--------+----------- + calvin | 100 | t + hobbes | 101 | t + (2 rows) + + SELECT * + FROM pg_namespace + WHERE nspname NOT LIKE ALL(ARRAY['pg_%', 'information_schema']) + ORDER BY nspname; + nspname | nspowner | nspacl + ---------+----------+-------- + public | 101 | + (1 row) + *** ./src/test/regress/serial_schedule.orig Sun Jan 11 05:58:17 2004 --- ./src/test/regress/serial_schedule Sat May 8 11:02:52 2004 *************** *** 49,54 **** --- 49,55 ---- test: create_aggregate test: create_operator test: create_index + test: create_database test: inherit test: vacuum test: create_view *** ./src/test/regress/sql/create_database.sql.orig Fri May 7 21:58:06 2004 --- ./src/test/regress/sql/create_database.sql Sat May 8 10:01:47 2004 *************** *** 0 **** --- 1,36 ---- + CREATE USER calvin; + CREATE DATABASE calvin WITH OWNER calvin; + + CREATE USER hobbes; + CREATE DATABASE hobbes WITH OWNER hobbes; + + SELECT datname, datdba, datisinit + FROM pg_database + WHERE datname = ANY(ARRAY['calvin', 'hobbes']) + ORDER BY datname; + + \c calvin calvin + SELECT CURRENT_USER; + + SELECT datname, datdba, datisinit + FROM pg_database + WHERE datname = ANY(ARRAY['calvin', 'hobbes']) + ORDER BY datname; + + SELECT * + FROM pg_namespace + WHERE nspname NOT LIKE ALL(ARRAY['pg_%', 'information_schema']) + ORDER BY nspname; + + \c hobbes calvin + SELECT CURRENT_USER; + + SELECT datname, datdba, datisinit + FROM pg_database + WHERE datname = ANY(ARRAY['calvin', 'hobbes']) + ORDER BY datname; + + SELECT * + FROM pg_namespace + WHERE nspname NOT LIKE ALL(ARRAY['pg_%', 'information_schema']) + ORDER BY nspname;