Commit 030962da authored by Jan Wieck's avatar Jan Wieck

Bugfix in ALTER TABLE CREATE TOAST TABLE

Automatically create toast table at CREATE TABLE if new table
has toastable attributes.

Jan
parent f2dfd561
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.83 2000/07/04 06:11:27 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.84 2000/07/05 12:45:25 wieck Exp $
*
* NOTES
* The PerformAddAttribute() code, like most of the relation
......@@ -1177,21 +1177,23 @@ AlterTableDropConstraint(const char *relationName,
* ALTER TABLE CREATE TOAST TABLE
*/
void
AlterTableCreateToastTable(const char *relationName)
AlterTableCreateToastTable(const char *relationName, bool silent)
{
Relation rel;
Oid myrelid;
HeapTuple reltup;
HeapTupleData classtuple;
TupleDesc tupdesc;
Form_pg_attribute *att;
Relation class_rel;
Buffer buffer;
Relation ridescs[Num_pg_class_indices];
Oid toast_relid;
Oid toast_idxid;
bool has_toastable_attrs = false;
int i;
char toast_relname[NAMEDATALEN];
char toast_idxname[NAMEDATALEN];
char toast_relname[NAMEDATALEN + 1];
char toast_idxname[NAMEDATALEN + 1];
Relation toast_rel;
AttrNumber attNums[1];
Oid classObjectId[1];
......@@ -1199,16 +1201,33 @@ AlterTableCreateToastTable(const char *relationName)
/*
* permissions checking. XXX exactly what is appropriate here?
*/
/*
if (!allowSystemTableMods && IsSystemRelationName(relationName))
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
relationName);
*/
#ifndef NO_SECURITY
if (!pg_ownercheck(UserName, relationName, RELNAME))
elog(ERROR, "ALTER TABLE: permission denied");
#endif
/*
* lock the pg_class tuple for update
*/
reltup = SearchSysCacheTuple(RELNAME, PointerGetDatum(relationName),
0, 0, 0);
if (!HeapTupleIsValid(reltup))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName);
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
classtuple.t_self = reltup->t_self;
switch (heap_mark4update(class_rel, &classtuple, &buffer))
{
case HeapTupleSelfUpdated:
case HeapTupleMayBeUpdated:
break;
default:
elog(ERROR, "couldn't lock pg_class tuple");
}
reltup = heap_copytuple(&classtuple);
ReleaseBuffer(buffer);
/*
* Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction.
......@@ -1231,22 +1250,24 @@ AlterTableCreateToastTable(const char *relationName)
}
if (!has_toastable_attrs)
{
if (silent)
{
heap_close(rel, NoLock);
heap_close(class_rel, NoLock);
return;
}
elog(ERROR, "ALTER TABLE: relation \"%s\" has no toastable attributes",
relationName);
}
/*
* Get the pg_class tuple for the relation
*/
reltup = SearchSysCacheTuple(RELNAME,
PointerGetDatum(relationName),
0, 0, 0);
if (!HeapTupleIsValid(reltup))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName);
/*
* XXX is the following check sufficient?
* XXX is the following check sufficient? At least it would
* allow to create TOAST tables for views. But why not - someone
* can insert into a view, so it shouldn't be impossible to hide
* huge data there :-)
*/
if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION)
{
......@@ -1281,6 +1302,8 @@ AlterTableCreateToastTable(const char *relationName)
/* XXX use RELKIND_TOASTVALUE here? */
/* XXX what if owning relation is temp? need we mark toasttable too? */
/* !!! No need to worry about temp. It'll go away when it's master */
/* table is deleted. Jan */
heap_create_with_catalog(toast_relname, tupdesc, RELKIND_RELATION,
false, true);
......@@ -1307,18 +1330,6 @@ AlterTableCreateToastTable(const char *relationName)
toast_idxid = RelationGetRelid(toast_rel);
index_close(toast_rel);
/*
* Get the pg_class tuple for the relation
*/
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
reltup = SearchSysCacheTupleCopy(RELNAME,
PointerGetDatum(relationName),
0, 0, 0);
if (!HeapTupleIsValid(reltup))
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
relationName);
/*
* Store the toast table- and index-Oid's in the relation tuple
*/
......@@ -1326,14 +1337,16 @@ AlterTableCreateToastTable(const char *relationName)
((Form_pg_class) GETSTRUCT(reltup))->reltoastidxid = toast_idxid;
heap_update(class_rel, &reltup->t_self, reltup, NULL);
/* keep catalog indices current */
/*
* Keep catalog indices current
*/
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
CatalogIndexInsert(ridescs, Num_pg_class_indices, rel, reltup);
CatalogIndexInsert(ridescs, Num_pg_class_indices, class_rel, reltup);
CatalogCloseIndices(Num_pg_class_indices, ridescs);
heap_freetuple(reltup);
heap_close(class_rel, RowExclusiveLock);
heap_close(class_rel, NoLock);
heap_close(rel, NoLock);
}
......
......@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.90 2000/07/03 23:09:46 wieck Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.91 2000/07/05 12:45:26 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -159,6 +159,15 @@ ProcessUtility(Node *parsetree,
CHECK_IF_ABORTED();
DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION);
/*
* Let AlterTableCreateToastTable decide if this
* one needs a secondary relation too.
*
*/
CommandCounterIncrement();
AlterTableCreateToastTable(((CreateStmt *)parsetree)->relname,
true);
break;
case T_DropStmt:
......@@ -361,7 +370,7 @@ ProcessUtility(Node *parsetree,
AlterTableDropConstraint(stmt->relname, stmt->inh, stmt->name, stmt->behavior);
break;
case 'E': /* CREATE TOAST TABLE */
AlterTableCreateToastTable(stmt->relname);
AlterTableCreateToastTable(stmt->relname, false);
break;
default: /* oops */
elog(ERROR, "T_AlterTableStmt: unknown subtype");
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: command.h,v 1.20 2000/07/03 23:10:10 wieck Exp $
* $Id: command.h,v 1.21 2000/07/05 12:45:31 wieck Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -58,7 +58,8 @@ extern void AlterTableDropConstraint(const char *relationName,
bool inh, const char *constrName,
int behavior);
extern void AlterTableCreateToastTable(const char *relationName);
extern void AlterTableCreateToastTable(const char *relationName,
bool silent);
/*
* LOCK
......
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