diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 9144eec..5f8961e 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -2636,6 +2636,16 @@
for details
+
+
+ datcreated
+ timestamptz
+
+
+ Timestamp of database creation
+
+
+
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index d40fd68..6499aeb 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -113,7 +113,7 @@ static int num_columns_read = 0;
%token OPEN XCLOSE XCREATE INSERT_TUPLE
%token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST
%token COMMA EQUALS LPAREN RPAREN
-%token OBJ_ID XBOOTSTRAP XSHARED_RELATION XWITHOUT_OIDS XROWTYPE_OID NULLVAL
+%token OBJ_ID XBOOTSTRAP XSHARED_RELATION XWITHOUT_OIDS XROWTYPE_OID NULLVAL NOWVAL
%start TopLevel
@@ -443,6 +443,8 @@ boot_column_val:
{ InsertOneValue($1, num_columns_read++); }
| NULLVAL
{ InsertOneNull(num_columns_read++); }
+ | NOWVAL
+ { InsertOneNow(num_columns_read++); }
;
boot_const :
diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l
index bdd7dcb..d92b3ea 100644
--- a/src/backend/bootstrap/bootscanner.l
+++ b/src/backend/bootstrap/bootscanner.l
@@ -80,6 +80,7 @@ bootstrap { return(XBOOTSTRAP); }
"without_oids" { return(XWITHOUT_OIDS); }
"rowtype_oid" { return(XROWTYPE_OID); }
_null_ { return(NULLVAL); }
+_now_ { return(NOWVAL); }
insert { return(INSERT_TUPLE); }
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 82ef726..cd5d98d 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -43,6 +43,7 @@
#include "utils/ps_status.h"
#include "utils/rel.h"
#include "utils/relmapper.h"
+#include "utils/timestamp.h"
#include "utils/tqual.h"
extern int optind;
@@ -862,6 +863,18 @@ InsertOneNull(int i)
}
/* ----------------
+ * InsertOneNow
+ * ----------------
+ */
+void
+InsertOneNow(int i)
+{
+ elog(DEBUG4, "inserting column %d NULL", i);
+ Assert(i >= 0 && i < MAXATTR);
+ values[i] = TimestampTzGetDatum(GetCurrentTimestamp());
+}
+
+/* ----------------
* cleanup
* ----------------
*/
diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm
index 59a5016..9f337f5 100644
--- a/src/backend/catalog/Catalog.pm
+++ b/src/backend/catalog/Catalog.pm
@@ -35,7 +35,8 @@ sub Catalogs
'int32' => 'int4',
'Oid' => 'oid',
'NameData' => 'name',
- 'TransactionId' => 'xid');
+ 'TransactionId' => 'xid',
+ 'TimestampTz' => 'timestamptz');
foreach my $input_file (@_)
{
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 1f6e02d..eeb033b 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -57,6 +57,7 @@
#include "utils/pg_locale.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
+#include "utils/timestamp.h"
#include "utils/tqual.h"
@@ -491,6 +492,7 @@ createdb(const CreatedbStmt *stmt)
new_record[Anum_pg_database_datlastsysoid - 1] = ObjectIdGetDatum(src_lastsysoid);
new_record[Anum_pg_database_datfrozenxid - 1] = TransactionIdGetDatum(src_frozenxid);
new_record[Anum_pg_database_dattablespace - 1] = ObjectIdGetDatum(dst_deftablespace);
+ new_record[Anum_pg_database_datcreated - 1] = TimestampTzGetDatum(GetCurrentTimestamp());
/*
* We deliberately set datacl to default (NULL), rather than copying it
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index b165a0a..4d82a7c 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -39,6 +39,7 @@ extern void DefineAttr(char *name, char *type, int attnum);
extern void InsertOneTuple(Oid objectid);
extern void InsertOneValue(char *value, int i);
extern void InsertOneNull(int i);
+extern void InsertOneNow(int i);
extern char *MapArrayTypeName(char *s);
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index 4010959..a5aa4b3 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -20,6 +20,7 @@
#define PG_DATABASE_H
#include "catalog/genbki.h"
+#include "datatype/timestamp.h"
/* ----------------
* pg_database definition. cpp turns this into
@@ -42,6 +43,7 @@ CATALOG(pg_database,1262) BKI_SHARED_RELATION BKI_ROWTYPE_OID(1248) BKI_SCHEMA_M
Oid datlastsysoid; /* highest OID to consider a system OID */
TransactionId datfrozenxid; /* all Xids < this are frozen in this DB */
Oid dattablespace; /* default table space for this DB */
+ TimestampTz datcreated; /* creation timestamp */
#ifdef CATALOG_VARLEN /* variable-length fields start here */
aclitem datacl[1]; /* access permissions */
@@ -59,7 +61,7 @@ typedef FormData_pg_database *Form_pg_database;
* compiler constants for pg_database
* ----------------
*/
-#define Natts_pg_database 12
+#define Natts_pg_database 13
#define Anum_pg_database_datname 1
#define Anum_pg_database_datdba 2
#define Anum_pg_database_encoding 3
@@ -71,9 +73,10 @@ typedef FormData_pg_database *Form_pg_database;
#define Anum_pg_database_datlastsysoid 9
#define Anum_pg_database_datfrozenxid 10
#define Anum_pg_database_dattablespace 11
-#define Anum_pg_database_datacl 12
+#define Anum_pg_database_datcreated 12
+#define Anum_pg_database_datacl 13
-DATA(insert OID = 1 ( template1 PGUID ENCODING "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1663 _null_));
+DATA(insert OID = 1 ( template1 PGUID ENCODING "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1663 _now_ _null_));
SHDESCR("default template for new databases");
#define TemplateDbOid 1