*** ./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;