Skip to content

Commit cdeca5f

Browse files
committed
Make toast-table creation and deletion work somewhat reliably.
Don't go through pg_exec_query_dest(), but directly to the execution routines. Also, extend parameter lists so that there's no need to change the global setting of allowSystemTableMods, a hack that was certain to cause trouble in the event of any error.
1 parent 9cf3277 commit cdeca5f

File tree

18 files changed

+148
-102
lines changed

18 files changed

+148
-102
lines changed

src/backend/bootstrap/bootparse.y

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.30 2000/06/18 22:43:51 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.31 2000/07/04 06:11:22 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -166,7 +166,7 @@ Boot_CreateStmt:
166166
puts("creating bootstrap relation");
167167
tupdesc = CreateTupleDesc(numattr,attrtypes);
168168
reldesc = heap_create(LexIDStr($3), tupdesc,
169-
false, true);
169+
false, true, true);
170170
if (DebugMode)
171171
puts("bootstrap relation created ok");
172172
}
@@ -177,7 +177,10 @@ Boot_CreateStmt:
177177

178178
tupdesc = CreateTupleDesc(numattr,attrtypes);
179179
id = heap_create_with_catalog(LexIDStr($3),
180-
tupdesc, RELKIND_RELATION, false);
180+
tupdesc,
181+
RELKIND_RELATION,
182+
false,
183+
true);
181184
if (!Quiet)
182185
printf("CREATED relation %s with OID %u\n",
183186
LexIDStr($3), id);

src/backend/catalog/heap.c

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.137 2000/07/03 23:09:27 wieck Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.138 2000/07/04 06:11:23 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -172,7 +172,8 @@ Relation
172172
heap_create(char *relname,
173173
TupleDesc tupDesc,
174174
bool istemp,
175-
bool storage_create)
175+
bool storage_create,
176+
bool allow_system_table_mods)
176177
{
177178
static unsigned int uniqueId = 0;
178179

@@ -189,7 +190,7 @@ heap_create(char *relname,
189190
*/
190191
AssertArg(natts > 0);
191192

192-
if (relname && !allowSystemTableMods &&
193+
if (relname && !allow_system_table_mods &&
193194
IsSystemRelationName(relname) && IsNormalProcessingMode())
194195
{
195196
elog(ERROR, "Illegal class name '%s'"
@@ -744,7 +745,8 @@ Oid
744745
heap_create_with_catalog(char *relname,
745746
TupleDesc tupdesc,
746747
char relkind,
747-
bool istemp)
748+
bool istemp,
749+
bool allow_system_table_mods)
748750
{
749751
Relation pg_class_desc;
750752
Relation new_rel_desc;
@@ -769,9 +771,9 @@ heap_create_with_catalog(char *relname,
769771
(istemp && get_temp_rel_by_username(relname) != NULL))
770772
elog(ERROR, "Relation '%s' already exists", relname);
771773

772-
/* save user relation name because heap_create changes it */
773774
if (istemp)
774775
{
776+
/* save user relation name because heap_create changes it */
775777
temp_relname = pstrdup(relname); /* save original value */
776778
relname = palloc(NAMEDATALEN);
777779
strcpy(relname, temp_relname); /* heap_create will change this */
@@ -797,7 +799,8 @@ heap_create_with_catalog(char *relname,
797799
* work of creating the disk file for the relation.
798800
* ----------------
799801
*/
800-
new_rel_desc = heap_create(relname, tupdesc, istemp, false);
802+
new_rel_desc = heap_create(relname, tupdesc, istemp, false,
803+
allow_system_table_mods);
801804

802805
new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
803806

@@ -1419,7 +1422,8 @@ DeleteTypeTuple(Relation rel)
14191422
* --------------------------------
14201423
*/
14211424
void
1422-
heap_drop_with_catalog(const char *relname)
1425+
heap_drop_with_catalog(const char *relname,
1426+
bool allow_system_table_mods)
14231427
{
14241428
Relation rel;
14251429
Oid rid;
@@ -1438,7 +1442,7 @@ heap_drop_with_catalog(const char *relname)
14381442
* ----------------
14391443
*/
14401444
/* allow temp of pg_class? Guess so. */
1441-
if (!istemp && !allowSystemTableMods &&
1445+
if (!istemp && !allow_system_table_mods &&
14421446
IsSystemRelationName(RelationGetRelationName(rel)))
14431447
elog(ERROR, "System relation '%s' cannot be destroyed",
14441448
RelationGetRelationName(rel));
@@ -1546,15 +1550,9 @@ heap_drop_with_catalog(const char *relname)
15461550
if (has_toasttable)
15471551
{
15481552
char toast_relname[NAMEDATALEN];
1549-
bool old_allow;
15501553

1551-
old_allow = allowSystemTableMods;
1552-
allowSystemTableMods = true;
1553-
1554-
sprintf(toast_relname, "pg_toast_%d", rid);
1555-
heap_drop_with_catalog(toast_relname);
1556-
1557-
allowSystemTableMods = old_allow;
1554+
sprintf(toast_relname, "pg_toast_%u", rid);
1555+
heap_drop_with_catalog(toast_relname, true);
15581556
}
15591557
}
15601558

src/backend/catalog/index.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.121 2000/06/30 07:04:17 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.122 2000/07/04 06:11:23 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -946,7 +946,8 @@ index_create(char *heapRelationName,
946946
Node *predicate,
947947
bool islossy,
948948
bool unique,
949-
bool primary)
949+
bool primary,
950+
bool allow_system_table_mods)
950951
{
951952
Relation heapRelation;
952953
Relation indexRelation;
@@ -989,21 +990,21 @@ index_create(char *heapRelationName,
989990
numatts,
990991
attNums);
991992

992-
/* save user relation name because heap_create changes it */
993993
if (istemp)
994994
{
995-
temp_relname = pstrdup(indexRelationName); /* save original value */
995+
/* save user relation name because heap_create changes it */
996+
temp_relname = pstrdup(indexRelationName); /* save original value */
996997
indexRelationName = palloc(NAMEDATALEN);
997-
strcpy(indexRelationName, temp_relname); /* heap_create will
998-
* change this */
998+
strcpy(indexRelationName, temp_relname); /* heap_create will
999+
* change this */
9991000
}
10001001

10011002
/* ----------------
10021003
* create the index relation
10031004
* ----------------
10041005
*/
10051006
indexRelation = heap_create(indexRelationName, indexTupDesc,
1006-
istemp, false);
1007+
istemp, false, allow_system_table_mods);
10071008

10081009
/* ----------------
10091010
* construct the index relation descriptor

src/backend/commands/cluster.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.56 2000/06/17 23:41:36 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.57 2000/07/04 06:11:27 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -30,6 +30,7 @@
3030
#include "catalog/pg_proc.h"
3131
#include "commands/cluster.h"
3232
#include "commands/rename.h"
33+
#include "miscadmin.h"
3334
#include "utils/builtins.h"
3435
#include "utils/syscache.h"
3536

@@ -140,7 +141,7 @@ cluster(char *oldrelname, char *oldindexname)
140141
StartTransactionCommand();
141142

142143
/* Destroy old heap (along with its index) and rename new. */
143-
heap_drop_with_catalog(saveoldrelname);
144+
heap_drop_with_catalog(saveoldrelname, allowSystemTableMods);
144145

145146
CommitTransactionCommand();
146147
StartTransactionCommand();
@@ -176,7 +177,8 @@ copy_heap(Oid OIDOldHeap)
176177
tupdesc = CreateTupleDescCopy(OldHeapDesc);
177178

178179
OIDNewHeap = heap_create_with_catalog(NewName, tupdesc,
179-
RELKIND_RELATION, false);
180+
RELKIND_RELATION, false,
181+
allowSystemTableMods);
180182

181183
if (!OidIsValid(OIDNewHeap))
182184
elog(ERROR, "clusterheap: cannot create temporary heap relation\n");
@@ -276,7 +278,8 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
276278
(Node *) NULL, /* XXX where's the predicate? */
277279
Old_pg_index_Form->indislossy,
278280
Old_pg_index_Form->indisunique,
279-
Old_pg_index_Form->indisprimary);
281+
Old_pg_index_Form->indisprimary,
282+
allowSystemTableMods);
280283

281284
setRelhasindexInplace(OIDNewHeap, true, false);
282285

src/backend/commands/command.c

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.82 2000/07/03 23:09:33 wieck Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.83 2000/07/04 06:11:27 tgl Exp $
1212
*
1313
* NOTES
1414
* The PerformAddAttribute() code, like most of the relation
@@ -21,8 +21,10 @@
2121

2222
#include "catalog/catalog.h"
2323
#include "catalog/catname.h"
24+
#include "catalog/index.h"
2425
#include "catalog/indexing.h"
2526
#include "catalog/pg_attrdef.h"
27+
#include "catalog/pg_opclass.h"
2628
#include "commands/command.h"
2729
#include "executor/spi.h"
2830
#include "catalog/heap.h"
@@ -1184,22 +1186,18 @@ AlterTableCreateToastTable(const char *relationName)
11841186
Form_pg_attribute *att;
11851187
Relation class_rel;
11861188
Relation ridescs[Num_pg_class_indices];
1187-
Oid toast_relid = 2;
1188-
Oid toast_idxid = 2;
1189+
Oid toast_relid;
1190+
Oid toast_idxid;
11891191
bool has_toastable_attrs = false;
1190-
bool old_allow;
11911192
int i;
1192-
11931193
char toast_relname[NAMEDATALEN];
11941194
char toast_idxname[NAMEDATALEN];
1195-
char tmp_query[1024];
11961195
Relation toast_rel;
1196+
AttrNumber attNums[1];
1197+
Oid classObjectId[1];
11971198

11981199
/*
1199-
* permissions checking. this would normally be done in utility.c,
1200-
* but this particular routine is recursive.
1201-
*
1202-
* normally, only the owner of a class can change its schema.
1200+
* permissions checking. XXX exactly what is appropriate here?
12031201
*/
12041202
/*
12051203
if (!allowSystemTableMods && IsSystemRelationName(relationName))
@@ -1215,7 +1213,7 @@ AlterTableCreateToastTable(const char *relationName)
12151213
* Grab an exclusive lock on the target table, which we will NOT
12161214
* release until end of transaction.
12171215
*/
1218-
rel = heap_openr(relationName, RowExclusiveLock);
1216+
rel = heap_openr(relationName, AccessExclusiveLock);
12191217
myrelid = RelationGetRelid(rel);
12201218

12211219
/*
@@ -1240,8 +1238,8 @@ AlterTableCreateToastTable(const char *relationName)
12401238
* Get the pg_class tuple for the relation
12411239
*/
12421240
reltup = SearchSysCacheTuple(RELNAME,
1243-
PointerGetDatum(relationName),
1244-
0, 0, 0);
1241+
PointerGetDatum(relationName),
1242+
0, 0, 0);
12451243

12461244
if (!HeapTupleIsValid(reltup))
12471245
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
@@ -1261,26 +1259,43 @@ AlterTableCreateToastTable(const char *relationName)
12611259
relationName);
12621260

12631261
/*
1264-
* Create the toast table and it's index
1265-
* This is bad and ugly, because we need to override
1266-
* allowSystemTableMods in order to keep the toast
1267-
* table- and index-name out of the users namespace.
1262+
* Create the toast table and its index
12681263
*/
1269-
sprintf(toast_relname, "pg_toast_%d", myrelid);
1270-
sprintf(toast_idxname, "pg_toast_%d_idx", myrelid);
1271-
1272-
old_allow = allowSystemTableMods;
1273-
allowSystemTableMods = true;
1274-
1275-
sprintf(tmp_query, "create table \"%s\" (chunk_id oid, chunk_seq int4, chunk_data text)",
1276-
toast_relname);
1277-
pg_exec_query_dest(tmp_query, None, CurrentMemoryContext);
1278-
1279-
sprintf(tmp_query, "create index \"%s\" on \"%s\" (chunk_id)",
1280-
toast_idxname, toast_relname);
1281-
pg_exec_query_dest(tmp_query, None, CurrentMemoryContext);
1282-
1283-
allowSystemTableMods = old_allow;
1264+
sprintf(toast_relname, "pg_toast_%u", myrelid);
1265+
sprintf(toast_idxname, "pg_toast_%u_idx", myrelid);
1266+
1267+
/* this is pretty painful... need a tuple descriptor */
1268+
tupdesc = CreateTemplateTupleDesc(3);
1269+
TupleDescInitEntry(tupdesc, (AttrNumber) 1,
1270+
"chunk_id",
1271+
OIDOID,
1272+
-1, 0, false);
1273+
TupleDescInitEntry(tupdesc, (AttrNumber) 2,
1274+
"chunk_seq",
1275+
INT4OID,
1276+
-1, 0, false);
1277+
TupleDescInitEntry(tupdesc, (AttrNumber) 3,
1278+
"chunk_data",
1279+
TEXTOID, /* XXX wouldn't BYTEAOID be better? */
1280+
-1, 0, false);
1281+
1282+
/* XXX use RELKIND_TOASTVALUE here? */
1283+
/* XXX what if owning relation is temp? need we mark toasttable too? */
1284+
heap_create_with_catalog(toast_relname, tupdesc, RELKIND_RELATION,
1285+
false, true);
1286+
1287+
/* make the toast relation visible, else index creation will fail */
1288+
CommandCounterIncrement();
1289+
1290+
/* create index on chunk_id */
1291+
attNums[0] = 1;
1292+
classObjectId[0] = OID_OPS_OID;
1293+
index_create(toast_relname, toast_idxname, NULL, NULL, BTREE_AM_OID,
1294+
1, attNums, classObjectId,
1295+
(Node *) NULL, false, false, false, true);
1296+
1297+
/* make the index visible in this transaction */
1298+
CommandCounterIncrement();
12841299

12851300
/*
12861301
* Get the OIDs of the newly created objects
@@ -1318,8 +1333,8 @@ AlterTableCreateToastTable(const char *relationName)
13181333

13191334
heap_freetuple(reltup);
13201335

1336+
heap_close(class_rel, RowExclusiveLock);
13211337
heap_close(rel, NoLock);
1322-
heap_close(class_rel, NoLock);
13231338
}
13241339

13251340

src/backend/commands/creatinh.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
*
1010
* IDENTIFICATION
1111
<<<<<<< creatinh.c
12-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.61 2000/06/12 03:40:29 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.62 2000/07/04 06:11:27 tgl Exp $
1313
=======
14-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.61 2000/06/12 03:40:29 momjian Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.62 2000/07/04 06:11:27 tgl Exp $
1515
>>>>>>> 1.58
1616
*
1717
*-------------------------------------------------------------------------
@@ -27,6 +27,7 @@
2727
#include "catalog/pg_ipl.h"
2828
#include "catalog/pg_type.h"
2929
#include "commands/creatinh.h"
30+
#include "miscadmin.h"
3031
#include "utils/syscache.h"
3132

3233
/* ----------------
@@ -146,7 +147,8 @@ DefineRelation(CreateStmt *stmt, char relkind)
146147
}
147148

148149
relationId = heap_create_with_catalog(relname, descriptor,
149-
relkind, stmt->istemp);
150+
relkind, stmt->istemp,
151+
allowSystemTableMods);
150152

151153
StoreCatalogInheritance(relationId, inheritList);
152154

@@ -224,7 +226,7 @@ void
224226
RemoveRelation(char *name)
225227
{
226228
AssertArg(name);
227-
heap_drop_with_catalog(name);
229+
heap_drop_with_catalog(name, allowSystemTableMods);
228230
}
229231

230232
/*

0 commit comments

Comments
 (0)