Commit c06f6a6b authored by Tom Lane's avatar Tom Lane

Support toasting of shared system relations, and provide toast tables for

pg_database, pg_shadow, pg_group, all of which now have potentially-long
fields.  Along the way, get rid of SharedSystemRelationNames list: shared
rels are now identified in their include/pg_catalog/*.h files by a
BKI_SHARED_RELATION macro, while indexes and toast rels inherit sharedness
automatically from their parent table.  Fix some bugs with failure to detoast
pg_group.grolist during ALTER GROUP.
parent 108871f4
%{
/*-------------------------------------------------------------------------
*
* backendparse.y
* yacc parser grammer for the "backend" initialization program.
* bootparse.y
* yacc parser grammar for the "backend" initialization program.
*
* 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/bootstrap/bootparse.y,v 1.45 2002/04/17 20:57:56 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.46 2002/04/27 21:24:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -88,8 +88,9 @@ int num_columns_read = 0;
%type <list> boot_index_params
%type <ielem> boot_index_param
%type <ival> boot_const boot_ident
%type <ival> optbootstrap optwithoutoids boot_tuple boot_tuplelist
%type <ival> boot_const boot_ident
%type <ival> optbootstrap optsharedrelation optwithoutoids
%type <ival> boot_tuple boot_tuplelist
%type <oidval> optoideq
%token <ival> CONST ID
......@@ -97,7 +98,7 @@ int num_columns_read = 0;
%token STRING XDEFINE
%token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE
%token COMMA EQUALS LPAREN RPAREN
%token OBJ_ID XBOOTSTRAP XWITHOUT_OIDS NULLVAL
%token OBJ_ID XBOOTSTRAP XSHARED_RELATION XWITHOUT_OIDS NULLVAL
%start TopLevel
%nonassoc low
......@@ -150,16 +151,14 @@ Boot_CloseStmt:
;
Boot_CreateStmt:
XCREATE optbootstrap optwithoutoids boot_ident LPAREN
XCREATE optbootstrap optsharedrelation optwithoutoids boot_ident LPAREN
{
do_start();
numattr = 0;
if ($2)
elog(DEBUG3, "creating bootstrap relation %s...",
LexIDStr($4));
else
elog(DEBUG3, "creating relation %s...",
LexIDStr($4));
elog(DEBUG3, "creating%s%s relation %s...",
$2 ? " bootstrap" : "",
$3 ? " shared" : "",
LexIDStr($5));
}
boot_typelist
{
......@@ -171,21 +170,22 @@ Boot_CreateStmt:
if ($2)
{
extern Relation reldesc;
TupleDesc tupdesc;
if (reldesc)
if (boot_reldesc)
{
elog(DEBUG3, "create bootstrap: warning, open relation exists, closing first");
closerel(NULL);
}
tupdesc = CreateTupleDesc(numattr, attrtypes);
reldesc = heap_create(LexIDStr($4),
PG_CATALOG_NAMESPACE,
tupdesc,
true, true);
reldesc->rd_rel->relhasoids = ! ($3);
boot_reldesc = heap_create(LexIDStr($5),
PG_CATALOG_NAMESPACE,
tupdesc,
$3,
true,
true);
boot_reldesc->rd_rel->relhasoids = ! ($4);
elog(DEBUG3, "bootstrap relation created");
}
else
......@@ -194,11 +194,12 @@ Boot_CreateStmt:
TupleDesc tupdesc;
tupdesc = CreateTupleDesc(numattr,attrtypes);
id = heap_create_with_catalog(LexIDStr($4),
id = heap_create_with_catalog(LexIDStr($5),
PG_CATALOG_NAMESPACE,
tupdesc,
RELKIND_RELATION,
! ($3),
$3,
! ($4),
true);
elog(DEBUG3, "relation created with oid %u", id);
}
......@@ -221,7 +222,7 @@ Boot_InsertStmt:
if (num_columns_read != numattr)
elog(ERROR, "incorrect number of columns in row (expected %d, got %d)",
numattr, num_columns_read);
if (reldesc == (Relation)NULL)
if (boot_reldesc == (Relation) NULL)
{
elog(ERROR, "relation not open");
err_out();
......@@ -283,6 +284,11 @@ optbootstrap:
| { $$ = 0; }
;
optsharedrelation:
XSHARED_RELATION { $$ = 1; }
| { $$ = 0; }
;
optwithoutoids:
XWITHOUT_OIDS { $$ = 1; }
| { $$ = 0; }
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.21 2001/08/10 18:57:33 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.22 2002/04/27 21:24:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -71,6 +71,8 @@ create { return(XCREATE); }
OID { return(OBJ_ID); }
bootstrap { return(XBOOTSTRAP); }
"shared_relation" { return(XSHARED_RELATION); }
"without_oids" { return(XWITHOUT_OIDS); }
_null_ { return(NULLVAL); }
insert { return(INSERT_TUPLE); }
......@@ -94,7 +96,6 @@ insert { return(INSERT_TUPLE); }
"index" { return(INDEX); }
"on" { return(ON); }
"using" { return(USING); }
"without_oids" { return(XWITHOUT_OIDS); }
{arrayid} {
yylval.ival = EnterString(MapArrayTypeName((char*)yytext));
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.126 2002/04/25 02:56:55 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.127 2002/04/27 21:24:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -59,6 +59,9 @@ static void cleanup(void);
* global variables
* ----------------
*/
Relation boot_reldesc; /* current relation descriptor */
/*
* In the lexical analyzer, we need to get the reference number quickly from
* the string, and the string from the reference number. Thus we have
......@@ -500,20 +503,20 @@ boot_openrel(char *relname)
heap_close(rel, NoLock);
}
if (reldesc != NULL)
if (boot_reldesc != NULL)
closerel(NULL);
elog(DEBUG3, "open relation %s, attrsize %d", relname ? relname : "(null)",
(int) ATTRIBUTE_TUPLE_SIZE);
reldesc = heap_openr(relname, NoLock);
numattr = reldesc->rd_rel->relnatts;
boot_reldesc = heap_openr(relname, NoLock);
numattr = boot_reldesc->rd_rel->relnatts;
for (i = 0; i < numattr; i++)
{
if (attrtypes[i] == NULL)
attrtypes[i] = AllocateAttribute();
memmove((char *) attrtypes[i],
(char *) reldesc->rd_att->attrs[i],
(char *) boot_reldesc->rd_att->attrs[i],
ATTRIBUTE_TUPLE_SIZE);
/* Some old pg_attribute tuples might not have attisset. */
......@@ -523,8 +526,9 @@ boot_openrel(char *relname)
* defined yet.
*/
if (namestrcmp(&attrtypes[i]->attname, "attisset") == 0)
attrtypes[i]->attisset = get_attisset(RelationGetRelid(reldesc),
NameStr(attrtypes[i]->attname));
attrtypes[i]->attisset =
get_attisset(RelationGetRelid(boot_reldesc),
NameStr(attrtypes[i]->attname));
else
attrtypes[i]->attisset = false;
......@@ -547,9 +551,9 @@ closerel(char *name)
{
if (name)
{
if (reldesc)
if (boot_reldesc)
{
if (strcmp(RelationGetRelationName(reldesc), name) != 0)
if (strcmp(RelationGetRelationName(boot_reldesc), name) != 0)
elog(ERROR, "closerel: close of '%s' when '%s' was expected",
name, relname ? relname : "(null)");
}
......@@ -559,13 +563,13 @@ closerel(char *name)
}
if (reldesc == NULL)
if (boot_reldesc == NULL)
elog(ERROR, "no open relation to close");
else
{
elog(DEBUG3, "close relation %s", relname ? relname : "(null)");
heap_close(reldesc, NoLock);
reldesc = (Relation) NULL;
heap_close(boot_reldesc, NoLock);
boot_reldesc = (Relation) NULL;
}
}
......@@ -585,7 +589,7 @@ DefineAttr(char *name, char *type, int attnum)
int attlen;
Oid typeoid;
if (reldesc != NULL)
if (boot_reldesc != NULL)
{
elog(LOG, "warning: no open relations allowed with 'create' command");
closerel(relname);
......@@ -674,7 +678,7 @@ InsertOneTuple(Oid objectid)
if (objectid != (Oid) 0)
tuple->t_data->t_oid = objectid;
heap_insert(reldesc, tuple);
heap_insert(boot_reldesc, tuple);
heap_freetuple(tuple);
elog(DEBUG3, "row inserted");
......@@ -706,13 +710,13 @@ InsertOneValue(char *value, int i)
elog(DEBUG3, "Typ != NULL");
app = Typ;
while (*app && (*app)->am_oid != reldesc->rd_att->attrs[i]->atttypid)
while (*app && (*app)->am_oid != boot_reldesc->rd_att->attrs[i]->atttypid)
++app;
ap = *app;
if (ap == NULL)
{
elog(FATAL, "unable to find atttypid %u in Typ list",
reldesc->rd_att->attrs[i]->atttypid);
boot_reldesc->rd_att->attrs[i]->atttypid);
}
values[i] = OidFunctionCall3(ap->am_typ.typinput,
CStringGetDatum(value),
......@@ -806,8 +810,8 @@ cleanup()
elog(FATAL, "Memory manager fault: cleanup called twice.\n");
proc_exit(1);
}
if (reldesc != (Relation) NULL)
heap_close(reldesc, NoLock);
if (boot_reldesc != (Relation) NULL)
heap_close(boot_reldesc, NoLock);
CommitTransactionCommand();
proc_exit(Warnings);
}
......
$Header: /cvsroot/pgsql/src/backend/catalog/README,v 1.6 2002/04/15 23:46:13 momjian Exp $
$Header: /cvsroot/pgsql/src/backend/catalog/README,v 1.7 2002/04/27 21:24:33 tgl Exp $
This directory contains .c files that manipulate the system catalogs;
src/include/catalog contains the .h files that define the structure
......@@ -69,15 +69,14 @@ manually create appropriate entries for them in the pre-loaded contents of
pg_class, pg_attribute, and pg_type. You'll also need to add code to function
heap_create() in heap.c to force the correct OID to be assigned when the table
is first referenced. (It's near the top of the function with the comment
beginning in 'Real ugly stuff'.) Avoid making new catalogs be bootstrap
beginning in "Real ugly stuff".) Avoid making new catalogs be bootstrap
catalogs if at all possible; generally, only tables that must be written to
in order to create a table should be bootstrapped.
- Certain BOOTSTRAP tables must be at the start of the Makefile
POSTGRES_BKI_SRCS variable, as these will not be created through standard
function means, but will be written directly to disk. That's how pg_class is
created without depending on functions which depend on the existence of
pg_class. The list of files this currently includes is:
POSTGRES_BKI_SRCS variable, as these will not be created through the standard
heap_create_with_catalog process, because it needs these tables to exist
already. The list of files this currently includes is:
pg_proc.h pg_type.h pg_attribute.h pg_class.h
Also, indexing.h must be last, since the indexes can't be created until all
the tables are in place. There are reputedly some other order dependencies
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.45 2002/04/12 20:38:18 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.46 2002/04/27 21:24:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -177,29 +177,6 @@ IsReservedName(const char *name)
name[2] == '_');
}
/*
* IsSharedSystemRelationName
* True iff name is the name of a shared system catalog relation.
*
* Note: This function assumes that this is a system relation
* in the first place. If that is not known, check the namespace
* (with IsSystemNamespace) before calling this function.
*/
bool
IsSharedSystemRelationName(const char *relname)
{
int i;
i = 0;
while (SharedSystemRelationNames[i] != NULL)
{
if (strcmp(SharedSystemRelationNames[i], relname) == 0)
return TRUE;
i++;
}
return FALSE;
}
/*
* newoid - returns a unique identifier across all catalogs.
......
......@@ -10,7 +10,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.26 2002/03/26 19:15:24 tgl Exp $
# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.27 2002/04/27 21:24:33 tgl Exp $
#
# NOTES
# non-essential whitespace is removed from the generated file.
......@@ -217,6 +217,7 @@ BEGIN {
inside = 0;
raw = 0;
bootstrap = "";
shared_relation = "";
without_oids = "";
nc = 0;
reln_open = 0;
......@@ -331,6 +332,9 @@ raw == 1 { print; next; }
if ($0 ~ /BOOTSTRAP/) {
bootstrap = "bootstrap ";
}
if ($0 ~ /BKI_SHARED_RELATION/) {
shared_relation = "shared_relation ";
}
if ($0 ~ /BKI_WITHOUT_OIDS/) {
without_oids = "without_oids ";
}
......@@ -358,7 +362,7 @@ inside == 1 {
# if this is the last line, then output the bki catalog stuff.
# ----
if ($1 ~ /}/) {
print "create " bootstrap without_oids catalog;
print "create " bootstrap shared_relation without_oids catalog;
print "\t(";
for (j=1; j<i-1; j++) {
......@@ -375,6 +379,7 @@ inside == 1 {
reln_open = 1;
inside = 0;
bootstrap = "";
shared_relation = "";
without_oids = "";
next;
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.196 2002/04/12 20:38:18 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.197 2002/04/27 21:24:33 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -210,11 +210,12 @@ Relation
heap_create(const char *relname,
Oid relnamespace,
TupleDesc tupDesc,
bool shared_relation,
bool storage_create,
bool allow_system_table_mods)
{
Oid relid;
Oid dbid = MyDatabaseId;
Oid dbid = shared_relation ? InvalidOid : MyDatabaseId;
bool nailme = false;
RelFileNode rnode;
Relation rel;
......@@ -225,16 +226,15 @@ heap_create(const char *relname,
if (!allow_system_table_mods &&
(IsSystemNamespace(relnamespace) || IsToastNamespace(relnamespace)) &&
IsNormalProcessingMode())
elog(ERROR, "invalid relation \"%s\"; "
elog(ERROR, "cannot create %s.%s: "
"system catalog modifications are currently disallowed",
relname);
get_namespace_name(relnamespace), relname);
/*
* Real ugly stuff to assign the proper relid in the relation
* descriptor follows. Note that only "bootstrapped" relations whose
* OIDs are hard-coded in pg_class.h need be listed here. We also
* have to take special care for those rels that should be nailed
* in cache and/or are shared across databases.
* OIDs are hard-coded in pg_class.h should be listed here. We also
* have to recognize those rels that must be nailed in cache.
*/
if (IsSystemNamespace(relnamespace))
{
......@@ -260,24 +260,19 @@ heap_create(const char *relname,
}
else if (strcmp(ShadowRelationName, relname) == 0)
{
dbid = InvalidOid;
relid = RelOid_pg_shadow;
}
else if (strcmp(GroupRelationName, relname) == 0)
{
dbid = InvalidOid;
relid = RelOid_pg_group;
}
else if (strcmp(DatabaseRelationName, relname) == 0)
{
dbid = InvalidOid;
relid = RelOid_pg_database;
}
else
{
relid = newoid();
if (IsSharedSystemRelationName(relname))
dbid = InvalidOid;
}
}
else
......@@ -651,6 +646,7 @@ heap_create_with_catalog(const char *relname,
Oid relnamespace,
TupleDesc tupdesc,
char relkind,
bool shared_relation,
bool relhasoids,
bool allow_system_table_mods)
{
......@@ -678,8 +674,12 @@ heap_create_with_catalog(const char *relname,
* necessary anymore, but we may as well avoid the cycles of creating
* and deleting the file in case we fail.)
*/
new_rel_desc = heap_create(relname, relnamespace, tupdesc,
false, allow_system_table_mods);
new_rel_desc = heap_create(relname,
relnamespace,
tupdesc,
shared_relation,
false,
allow_system_table_mods);
/* Fetch the relation OID assigned by heap_create */
new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.176 2002/04/12 20:38:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.177 2002/04/27 21:24:34 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -67,7 +67,6 @@ static TupleDesc BuildFuncTupleDesc(Oid funcOid,
static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
int numatts, AttrNumber *attNums,
Oid *classObjectId);
static void ConstructIndexReldesc(Relation indexRelation, Oid amoid);
static void UpdateRelationRelation(Relation indexRelation);
static void InitializeAttributeOids(Relation indexRelation,
int numatts, Oid indexoid);
......@@ -305,26 +304,6 @@ ConstructTupleDescriptor(Relation heapRelation,
return indexTupDesc;
}
/* ----------------------------------------------------------------
* ConstructIndexReldesc
* ----------------------------------------------------------------
*/
static void
ConstructIndexReldesc(Relation indexRelation, Oid amoid)
{
/*
* Set up some additional fields of the index' pg_class entry. In
* particular, initialize knowledge of whether the index is shared.
*/
indexRelation->rd_rel->relowner = GetUserId();
indexRelation->rd_rel->relam = amoid;
indexRelation->rd_rel->relisshared =
IsSystemNamespace(RelationGetNamespace(indexRelation)) &&
IsSharedSystemRelationName(RelationGetRelationName(indexRelation));
indexRelation->rd_rel->relkind = RELKIND_INDEX;
indexRelation->rd_rel->relhasoids = false;
}
/* ----------------------------------------------------------------
* UpdateRelationRelation
* ----------------------------------------------------------------
......@@ -561,6 +540,7 @@ index_create(Oid heapRelationId,
Relation heapRelation;
Relation indexRelation;
TupleDesc indexTupDesc;
bool shared_relation;
Oid namespaceId;
Oid indexoid;
......@@ -571,7 +551,12 @@ index_create(Oid heapRelationId,
*/
heapRelation = heap_open(heapRelationId, ShareLock);
/*
* The index will be in the same namespace as its parent table,
* and is shared across databases if and only if the parent is.
*/
namespaceId = RelationGetNamespace(heapRelation);
shared_relation = heapRelation->rd_rel->relisshared;
/*
* check parameters
......@@ -585,6 +570,16 @@ index_create(Oid heapRelationId,
IsNormalProcessingMode())
elog(ERROR, "User-defined indexes on system catalogs are not supported");
/*
* We cannot allow indexing a shared relation after initdb (because
* there's no way to make the entry in other databases' pg_class).
* Unfortunately we can't distinguish initdb from a manually started
* standalone backend. However, we can at least prevent this mistake
* under normal multi-user operation.
*/
if (shared_relation && IsUnderPostmaster)
elog(ERROR, "Shared indexes cannot be created after initdb");
if (get_relname_relid(indexRelationName, namespaceId))
elog(ERROR, "index named \"%s\" already exists",
indexRelationName);
......@@ -607,6 +602,7 @@ index_create(Oid heapRelationId,
indexRelation = heap_create(indexRelationName,
namespaceId,
indexTupDesc,
shared_relation,
false,
allow_system_table_mods);
indexoid = RelationGetRelid(indexRelation);
......@@ -619,16 +615,18 @@ index_create(Oid heapRelationId,
LockRelation(indexRelation, AccessExclusiveLock);
/*
* construct the index relation descriptor
* Fill in fields of the index's pg_class entry that are not set
* correctly by heap_create.
*
* XXX should have a proper way to create cataloged relations
* XXX should have a cleaner way to create cataloged indexes
*/
ConstructIndexReldesc(indexRelation, accessMethodObjectId);
indexRelation->rd_rel->relowner = GetUserId();
indexRelation->rd_rel->relam = accessMethodObjectId;
indexRelation->rd_rel->relkind = RELKIND_INDEX;
indexRelation->rd_rel->relhasoids = false;
/* ----------------
* add index to catalogs
* (append RELATION tuple)
* ----------------
/*
* store index's pg_class entry
*/
UpdateRelationRelation(indexRelation);
......
......@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.78 2002/04/15 05:22:03 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.79 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -152,6 +152,7 @@ copy_heap(Oid OIDOldHeap, const char *NewName)
RelationGetNamespace(OldHeap),
tupdesc,
OldHeap->rd_rel->relkind,
OldHeap->rd_rel->relisshared,
OldHeap->rd_rel->relhasoids,
allowSystemTableMods);
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.87 2002/04/21 00:26:42 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.88 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -475,11 +475,14 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
elog(ERROR, "permission denied");
MemSet(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_database_datconfig-1] = 'r';
if (strcmp(stmt->variable, "all")==0 && stmt->value == NULL)
{
/* RESET ALL */
repl_null[Anum_pg_database_datconfig-1] = 'n';
repl_val[Anum_pg_database_datconfig-1] = (Datum) 0;
}
else
{
Datum datum;
......@@ -491,16 +494,12 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_database_datconfig,
RelationGetDescr(rel), &isnull);
a = isnull ? ((ArrayType *) NULL) : DatumGetArrayTypeP(datum);
if (valuestr)
a = GUCArrayAdd(isnull
? NULL
: (ArrayType *) pg_detoast_datum((struct varlena *)datum),
stmt->variable, valuestr);
a = GUCArrayAdd(a, stmt->variable, valuestr);
else
a = GUCArrayDelete(isnull
? NULL
: (ArrayType *) pg_detoast_datum((struct varlena *)datum),
stmt->variable);
a = GUCArrayDelete(a, stmt->variable);
repl_val[Anum_pg_database_datconfig-1] = PointerGetDatum(a);
}
......@@ -546,8 +545,6 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
if (gottuple)
{
Form_pg_database dbform = (Form_pg_database) GETSTRUCT(tuple);
text *tmptext;
bool isnull;
/* oid of the database */
if (dbIdP)
......@@ -573,16 +570,21 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
/* database path (as registered in pg_database) */
if (dbpath)
{
tmptext = DatumGetTextP(heap_getattr(tuple,
Anum_pg_database_datpath,
RelationGetDescr(relation),
&isnull));
Datum datum;
bool isnull;
datum = heap_getattr(tuple,
Anum_pg_database_datpath,
RelationGetDescr(relation),
&isnull);
if (!isnull)
{
Assert(VARSIZE(tmptext) - VARHDRSZ < MAXPGPATH);
text *pathtext = DatumGetTextP(datum);
int pathlen = VARSIZE(pathtext) - VARHDRSZ;
strncpy(dbpath, VARDATA(tmptext), VARSIZE(tmptext) - VARHDRSZ);
*(dbpath + VARSIZE(tmptext) - VARHDRSZ) = '\0';
Assert(pathlen >= 0 && pathlen < MAXPGPATH);
strncpy(dbpath, VARDATA(pathtext), pathlen);
*(dbpath + pathlen) = '\0';
}
else
strcpy(dbpath, "");
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.11 2002/04/27 03:45:01 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.12 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -200,6 +200,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
namespaceId,
descriptor,
relkind,
false,
stmt->hasoids || parentHasOids,
allowSystemTableMods);
......@@ -2840,6 +2841,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
HeapTuple reltup;
HeapTupleData classtuple;
TupleDesc tupdesc;
bool shared_relation;
Relation class_rel;
Buffer buffer;
Relation ridescs[Num_pg_class_indices];
......@@ -2856,6 +2858,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
*/
rel = heap_open(relOid, AccessExclusiveLock);
/* Check permissions */
if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
RelationGetRelationName(rel));
......@@ -2863,6 +2866,19 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
if (!pg_class_ownercheck(relOid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
/*
* Toast table is shared if and only if its parent is.
*
* We cannot allow toasting a shared relation after initdb (because
* there's no way to mark it toasted in other databases' pg_class).
* Unfortunately we can't distinguish initdb from a manually started
* standalone backend. However, we can at least prevent this mistake
* under normal multi-user operation.
*/
shared_relation = rel->rd_rel->relisshared;
if (shared_relation && IsUnderPostmaster)
elog(ERROR, "Shared relations cannot be toasted after initdb");
/*
* lock the pg_class tuple for update (is that really needed?)
*/
......@@ -2962,6 +2978,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
PG_TOAST_NAMESPACE,
tupdesc,
RELKIND_TOASTVALUE,
shared_relation,
false,
true);
......
This diff is collapsed.
......@@ -27,7 +27,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.159 2002/04/27 03:45:02 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.160 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -733,6 +733,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
namespaceId,
tupdesc,
RELKIND_RELATION,
false,
true,
allowSystemTableMods);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.162 2002/04/19 16:36:08 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.163 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1319,7 +1319,10 @@ LookupOpclassInfo(Oid operatorClassOid,
* The relation descriptor is built just from the supplied parameters,
* without actually looking at any system table entries. We cheat
* quite a lot since we only need to work for a few basic system
* catalogs...
* catalogs.
*
* formrdesc is currently used for: pg_class, pg_attribute, pg_proc,
* and pg_type (see RelationCacheInitialize).
*
* Note that these catalogs can't have constraints, default values,
* rules, or triggers, since we don't cope with any of that.
......@@ -1374,9 +1377,10 @@ formrdesc(const char *relationName,
/*
* It's important to distinguish between shared and non-shared
* relations, even at bootstrap time, to make sure we know where they
* are stored.
* are stored. At present, all relations that formrdesc is used for
* are not shared.
*/
relation->rd_rel->relisshared = IsSharedSystemRelationName(relationName);
relation->rd_rel->relisshared = false;
relation->rd_rel->relpages = 1;
relation->rd_rel->reltuples = 1;
......@@ -1434,15 +1438,8 @@ formrdesc(const char *relationName,
/* In bootstrap mode, we have no indexes */
if (!IsBootstrapProcessingMode())
{
/*
* This list is incomplete, but it only has to work for the set of
* rels that formrdesc is used for ...
*/
if (strcmp(relationName, RelationRelationName) == 0 ||
strcmp(relationName, AttributeRelationName) == 0 ||
strcmp(relationName, ProcedureRelationName) == 0 ||
strcmp(relationName, TypeRelationName) == 0)
relation->rd_rel->relhasindex = true;
/* Otherwise, all the rels formrdesc is used for have indexes */
relation->rd_rel->relhasindex = true;
}
/*
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.63 2002/03/02 21:39:33 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.64 2002/04/27 21:24:34 tgl Exp $
*
* NOTES
* Globals used all over the place should be declared here and not
......@@ -18,14 +18,6 @@
*/
#include "postgres.h"
#include <fcntl.h>
#include <sys/file.h>
#include <sys/types.h>
#include <math.h>
#include <unistd.h>
#include "catalog/catname.h"
#include "catalog/indexing.h"
#include "libpq/pqcomm.h"
#include "miscadmin.h"
#include "storage/backendid.h"
......@@ -47,14 +39,11 @@ struct Port *MyProcPort;
long MyCancelKey;
char *DataDir = NULL;
/*
* The PGDATA directory user says to use, or defaults to via environment
* variable. NULL if no option given and no environment variable set
*/
Relation reldesc; /* current relation descriptor */
char OutputFileName[MAXPGPATH];
char pg_pathname[MAXPGPATH]; /* full path to postgres
......@@ -85,27 +74,3 @@ bool allowSystemTableMods = false;
int SortMem = 512;
int VacuumMem = 8192;
int NBuffers = DEF_NBUFFERS;
/* ----------------
* List of relations that are shared across all databases in an installation.
*
* This used to be binary-searched, requiring that it be kept in sorted order.
* We just do a linear search now so there's no requirement that the list
* be ordered. The list is so small it shouldn't make much difference.
* make sure the list is null-terminated
* - jolly 8/19/95
* ----------------
*/
char *SharedSystemRelationNames[] = {
DatabaseRelationName,
DatabaseNameIndex,
DatabaseOidIndex,
GroupRelationName,
GroupNameIndex,
GroupSysidIndex,
ShadowRelationName,
ShadowNameIndex,
ShadowSysidIndex,
NULL
};
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.86 2002/04/04 04:25:49 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.87 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -612,9 +612,8 @@ InitializeSessionUserId(const char *username)
Anum_pg_shadow_useconfig, &isnull);
if (!isnull)
{
ArrayType *a;
ArrayType *a = DatumGetArrayTypeP(datum);
a = (ArrayType *) pg_detoast_datum((struct varlena *)datum);
ProcessGUCArray(a, PGC_S_USER);
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.102 2002/04/01 03:34:26 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.103 2002/04/27 21:24:34 tgl Exp $
*
*
*-------------------------------------------------------------------------
......@@ -138,7 +138,7 @@ ReverifyMyDatabase(const char *name)
#endif
/*
* Set up datbase-specific configuration variables.
* Set up database-specific configuration variables.
*/
if (IsUnderPostmaster)
{
......@@ -149,9 +149,8 @@ ReverifyMyDatabase(const char *name)
RelationGetDescr(pgdbrel), &isnull);
if (!isnull)
{
ArrayType *a;
ArrayType *a = DatumGetArrayTypeP(datum);
a = (ArrayType *) pg_detoast_datum((struct varlena *)datum);
ProcessGUCArray(a, PGC_S_DATABASE);
}
}
......
......@@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.151 2002/04/21 00:26:43 tgl Exp $
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.152 2002/04/27 21:24:34 tgl Exp $
#
#-------------------------------------------------------------------------
......@@ -658,10 +658,13 @@ $ECHO_N "enabling unlimited row size for system tables... "$ECHO_C
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
ALTER TABLE pg_attrdef CREATE TOAST TABLE;
ALTER TABLE pg_database CREATE TOAST TABLE;
ALTER TABLE pg_description CREATE TOAST TABLE;
ALTER TABLE pg_group CREATE TOAST TABLE;
ALTER TABLE pg_proc CREATE TOAST TABLE;
ALTER TABLE pg_relcheck CREATE TOAST TABLE;
ALTER TABLE pg_rewrite CREATE TOAST TABLE;
ALTER TABLE pg_shadow CREATE TOAST TABLE;
ALTER TABLE pg_statistic CREATE TOAST TABLE;
EOF
if [ "$?" -ne 0 ]; then
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: bootstrap.h,v 1.28 2002/03/26 19:16:20 tgl Exp $
* $Id: bootstrap.h,v 1.29 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -31,7 +31,7 @@ typedef struct hashnode
} hashnode;
extern Relation reldesc;
extern Relation boot_reldesc;
extern Form_pg_attribute attrtypes[MAXATTR];
extern int numattr;
extern int BootstrapMain(int ac, char *av[]);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catalog.h,v 1.23 2002/04/12 20:38:30 tgl Exp $
* $Id: catalog.h,v 1.24 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -30,7 +30,6 @@ extern bool IsSystemNamespace(Oid namespaceId);
extern bool IsToastNamespace(Oid namespaceId);
extern bool IsReservedName(const char *name);
extern bool IsSharedSystemRelationName(const char *relname);
extern Oid newoid(void);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catname.h,v 1.24 2002/03/22 21:34:44 tgl Exp $
* $Id: catname.h,v 1.25 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -42,6 +42,4 @@
#define RelCheckRelationName "pg_relcheck"
#define TriggerRelationName "pg_trigger"
extern char *SharedSystemRelationNames[];
#endif /* CATNAME_H */
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.127 2002/04/26 01:24:08 tgl Exp $
* $Id: catversion.h,v 1.128 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200204251
#define CATALOG_VERSION_NO 200204271
#endif
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: heap.h,v 1.49 2002/03/31 06:26:32 tgl Exp $
* $Id: heap.h,v 1.50 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -30,6 +30,7 @@ typedef struct RawColumnDefault
extern Relation heap_create(const char *relname,
Oid relnamespace,
TupleDesc tupDesc,
bool shared_relation,
bool storage_create,
bool allow_system_table_mods);
......@@ -39,6 +40,7 @@ extern Oid heap_create_with_catalog(const char *relname,
Oid relnamespace,
TupleDesc tupdesc,
char relkind,
bool shared_relation,
bool relhasoids,
bool allow_system_table_mods);
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_database.h,v 1.23 2002/04/21 00:26:43 tgl Exp $
* $Id: pg_database.h,v 1.24 2002/04/27 21:24:34 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -31,7 +31,7 @@
* typedef struct FormData_pg_database
* ----------------
*/
CATALOG(pg_database) BOOTSTRAP
CATALOG(pg_database) BOOTSTRAP BKI_SHARED_RELATION
{
NameData datname; /* database name */
int4 datdba; /* sysid of owner */
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_group.h,v 1.13 2001/11/05 17:46:32 momjian Exp $
* $Id: pg_group.h,v 1.14 2002/04/27 21:24:34 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -25,7 +25,7 @@
* ----------------
*/
CATALOG(pg_group) BOOTSTRAP BKI_WITHOUT_OIDS
CATALOG(pg_group) BOOTSTRAP BKI_SHARED_RELATION BKI_WITHOUT_OIDS
{
NameData groname;
int4 grosysid;
......
......@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_shadow.h,v 1.19 2002/04/11 05:32:03 petere Exp $
* $Id: pg_shadow.h,v 1.20 2002/04/27 21:24:34 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -29,7 +29,7 @@
* typedef struct FormData_pg_shadow
* ----------------
*/
CATALOG(pg_shadow) BOOTSTRAP BKI_WITHOUT_OIDS
CATALOG(pg_shadow) BOOTSTRAP BKI_SHARED_RELATION BKI_WITHOUT_OIDS
{
NameData usename;
int4 usesysid;
......@@ -37,8 +37,9 @@ CATALOG(pg_shadow) BOOTSTRAP BKI_WITHOUT_OIDS
bool usetrace;
bool usesuper; /* read this field via superuser() only */
bool usecatupd;
/* remaining fields may be null; use heap_getattr to read them! */
text passwd;
int4 valuntil;
int4 valuntil; /* actually abstime */
text useconfig[1];
} FormData_pg_shadow;
......
......@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1995, Regents of the University of California
*
* $Id: postgres.h,v 1.56 2001/11/05 17:46:31 momjian Exp $
* $Id: postgres.h,v 1.57 2002/04/27 21:24:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -597,7 +597,7 @@ extern int assertTest(int val);
#define CATALOG(x) typedef struct CppConcat(FormData_,x)
#define BOOTSTRAP
#define BKI_SHARED_RELATION
#define BKI_WITHOUT_OIDS
/* these need to expand into some harmless, repeatable declaration */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment