7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.5 1996/11/06 06:47:03 scrappy Exp $
10
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.6 1996/11/06 07:31:19 scrappy Exp $
11
11
*
12
12
* INTERFACE ROUTINES
13
13
* heap_creatr() - Create an uncataloged heap relation
26
26
*/
27
27
#include <postgres.h>
28
28
29
+ #include <catalog/pg_ipl.h>
30
+ #include <catalog/pg_inherits.h>
31
+ #include <catalog/pg_proc.h>
32
+ #include <miscadmin.h>
33
+ #include <catalog/indexing.h>
34
+ #include <catalog/catalog.h>
35
+ #include <utils/builtins.h>
36
+ #include <access/heapam.h>
29
37
#include <utils/mcxt.h>
30
38
#include <parser/catalog_utils.h>
31
39
#include <catalog/index.h>
39
47
#include <rewrite/rewriteRemove.h>
40
48
#include <storage/lmgr.h>
41
49
#include <storage/smgr.h>
42
- #include <access/relscan.h>
43
- #include <utils/tqual.h>
44
-
45
- /*
46
- #include <catalog/heap.h>
47
- #include <catalog/pg_proc.h>
48
- #include <parser/catalog_utils.h>
49
- #include <access/heapam.h>
50
- #include <access/genam.h>
51
- #include <access/istrat.h>
52
- #include <storage/bufmgr.h>
53
- #include <lib/hasht.h>
54
- #include <miscadmin.h>
55
- #include <fmgr.h>
56
- #include <utils/builtins.h>
57
- #include <utils/mcxt.h>
58
- #include <utils/relcache.h>
59
- #include <catalog/catname.h>
60
- #include <catalog/pg_index.h>
61
- #include <catalog/pg_inherits.h>
62
- #include <catalog/pg_ipl.h>
63
- #include <catalog/index.h>
64
- #include <catalog/indexing.h>
65
- #include <catalog/catalog.h>
66
- #include <storage/lmgr.h>
67
- #include <rewrite/rewriteRemove.h>
68
- #include <storage/smgr.h>
69
- */
70
-
71
- static void AddNewAttributeTuples (Oid new_rel_oid , TupleDesc tupdesc );
72
- static void CheckAttributeNames (TupleDesc tupdesc );
50
+ #ifndef HAVE_MEMMOVE
51
+ # include <regex/utils.h>
52
+ #else
53
+ # include <string.h>
54
+ #endif
73
55
74
56
/* ----------------------------------------------------------------
75
57
* XXX UGLY HARD CODED BADNESS FOLLOWS XXX
@@ -1179,4 +1161,263 @@ DeletePgTypeTuple(Relation rdesc)
1179
1161
1180
1162
/* ----------------
1181
1163
* now scan pg_attribute. if any other relations have
1182
- * attributes of the type of the relation we are de
1164
+ * attributes of the type of the relation we are deleteing
1165
+ * then we have to disallow the deletion. should talk to
1166
+ * stonebraker about this. -cim 6/19/90
1167
+ * ----------------
1168
+ */
1169
+ typoid = tup -> t_oid ;
1170
+
1171
+ pg_attribute_desc = heap_openr (AttributeRelationName );
1172
+
1173
+ ScanKeyEntryInitialize (& attkey ,
1174
+ 0 , Anum_pg_attribute_atttypid , F_INT4EQ ,
1175
+ typoid );
1176
+
1177
+ pg_attribute_scan = heap_beginscan (pg_attribute_desc ,
1178
+ 0 ,
1179
+ NowTimeQual ,
1180
+ 1 ,
1181
+ & attkey );
1182
+
1183
+ /* ----------------
1184
+ * try and get a pg_attribute tuple. if we succeed it means
1185
+ * we cant delete the relation because something depends on
1186
+ * the schema.
1187
+ * ----------------
1188
+ */
1189
+ atttup = heap_getnext (pg_attribute_scan , 0 , (Buffer * )NULL );
1190
+
1191
+ if (PointerIsValid (atttup )) {
1192
+ Oid relid = ((AttributeTupleForm ) GETSTRUCT (atttup ))-> attrelid ;
1193
+
1194
+ heap_endscan (pg_type_scan );
1195
+ heap_close (pg_type_desc );
1196
+ heap_endscan (pg_attribute_scan );
1197
+ heap_close (pg_attribute_desc );
1198
+
1199
+ elog (WARN , "DeletePgTypeTuple: att of type %s exists in relation %d" ,
1200
+ & rdesc -> rd_rel -> relname , relid );
1201
+ }
1202
+ heap_endscan (pg_attribute_scan );
1203
+ heap_close (pg_attribute_desc );
1204
+
1205
+ /* ----------------
1206
+ * Ok, it's safe so we delete the relation tuple
1207
+ * from pg_type and finish up. But first end the scan so that
1208
+ * we release the read lock on pg_type. -mer 13 Aug 1991
1209
+ * ----------------
1210
+ */
1211
+ heap_endscan (pg_type_scan );
1212
+ heap_delete (pg_type_desc , & tup -> t_ctid );
1213
+
1214
+ heap_close (pg_type_desc );
1215
+ }
1216
+
1217
+ /* --------------------------------
1218
+ * heap_destroy
1219
+ *
1220
+ * --------------------------------
1221
+ */
1222
+ void
1223
+ heap_destroy (char * relname )
1224
+ {
1225
+ Relation rdesc ;
1226
+
1227
+ /* ----------------
1228
+ * first open the relation. if the relation does exist,
1229
+ * heap_openr() returns NULL.
1230
+ * ----------------
1231
+ */
1232
+ rdesc = heap_openr (relname );
1233
+ if (rdesc == NULL )
1234
+ elog (WARN ,"Relation %s Does Not Exist!" , relname );
1235
+
1236
+ /* ----------------
1237
+ * prevent deletion of system relations
1238
+ * ----------------
1239
+ */
1240
+ if (IsSystemRelationName (RelationGetRelationName (rdesc )-> data ))
1241
+ elog (WARN , "amdestroy: cannot destroy %s relation" ,
1242
+ & rdesc -> rd_rel -> relname );
1243
+
1244
+ /* ----------------
1245
+ * remove inheritance information
1246
+ * ----------------
1247
+ */
1248
+ RelationRemoveInheritance (rdesc );
1249
+
1250
+ /* ----------------
1251
+ * remove indexes if necessary
1252
+ * ----------------
1253
+ */
1254
+ if (rdesc -> rd_rel -> relhasindex ) {
1255
+ RelationRemoveIndexes (rdesc );
1256
+ }
1257
+
1258
+ /* ----------------
1259
+ * remove rules if necessary
1260
+ * ----------------
1261
+ */
1262
+ if (rdesc -> rd_rules != NULL ) {
1263
+ RelationRemoveRules (rdesc -> rd_id );
1264
+ }
1265
+
1266
+ /* ----------------
1267
+ * delete attribute tuples
1268
+ * ----------------
1269
+ */
1270
+ DeletePgAttributeTuples (rdesc );
1271
+
1272
+ /* ----------------
1273
+ * delete type tuple. here we want to see the effects
1274
+ * of the deletions we just did, so we use setheapoverride().
1275
+ * ----------------
1276
+ */
1277
+ setheapoverride (true);
1278
+ DeletePgTypeTuple (rdesc );
1279
+ setheapoverride (false);
1280
+
1281
+ /* ----------------
1282
+ * delete relation tuple
1283
+ * ----------------
1284
+ */
1285
+ DeletePgRelationTuple (rdesc );
1286
+
1287
+ /* ----------------
1288
+ * flush the relation from the relcache
1289
+ * ----------------
1290
+ */
1291
+ RelationIdInvalidateRelationCacheByRelationId (rdesc -> rd_id );
1292
+
1293
+ /* ----------------
1294
+ * unlink the relation and finish up.
1295
+ * ----------------
1296
+ */
1297
+ (void ) smgrunlink (rdesc -> rd_rel -> relsmgr , rdesc );
1298
+ if (rdesc -> rd_istemp ) {
1299
+ rdesc -> rd_tmpunlinked = TRUE;
1300
+ }
1301
+ heap_close (rdesc );
1302
+ }
1303
+
1304
+ /*
1305
+ * heap_destroyr
1306
+ * destroy and close temporary relations
1307
+ *
1308
+ */
1309
+
1310
+ void
1311
+ heap_destroyr (Relation rdesc )
1312
+ {
1313
+ ReleaseTmpRelBuffers (rdesc );
1314
+ (void ) smgrunlink (rdesc -> rd_rel -> relsmgr , rdesc );
1315
+ if (rdesc -> rd_istemp ) {
1316
+ rdesc -> rd_tmpunlinked = TRUE;
1317
+ }
1318
+ heap_close (rdesc );
1319
+ RemoveFromTempRelList (rdesc );
1320
+ }
1321
+
1322
+
1323
+ /**************************************************************
1324
+ functions to deal with the list of temporary relations
1325
+ **************************************************************/
1326
+
1327
+ /* --------------
1328
+ InitTempRellist():
1329
+
1330
+ initialize temporary relations list
1331
+ the tempRelList is a list of temporary relations that
1332
+ are created in the course of the transactions
1333
+ they need to be destroyed properly at the end of the transactions
1334
+
1335
+ MODIFIES the global variable tempRels
1336
+
1337
+ >> NOTE <<
1338
+
1339
+ malloc is used instead of palloc because we KNOW when we are
1340
+ going to free these things. Keeps us away from the memory context
1341
+ hairyness
1342
+
1343
+ */
1344
+ void
1345
+ InitTempRelList ()
1346
+ {
1347
+ if (tempRels ) {
1348
+ free (tempRels -> rels );
1349
+ free (tempRels );
1350
+ };
1351
+
1352
+ tempRels = (TempRelList * )malloc (sizeof (TempRelList ));
1353
+ tempRels -> size = TEMP_REL_LIST_SIZE ;
1354
+ tempRels -> rels = (Relation * )malloc (sizeof (Relation ) * tempRels -> size );
1355
+ memset (tempRels -> rels , 0 , sizeof (Relation ) * tempRels -> size );
1356
+ tempRels -> num = 0 ;
1357
+ }
1358
+
1359
+ /*
1360
+ removes a relation from the TempRelList
1361
+
1362
+ MODIFIES the global variable tempRels
1363
+ we don't really remove it, just mark it as NULL
1364
+ and DestroyTempRels will look for NULLs
1365
+ */
1366
+ void
1367
+ RemoveFromTempRelList (Relation r )
1368
+ {
1369
+ int i ;
1370
+
1371
+ if (!tempRels )
1372
+ return ;
1373
+
1374
+ for (i = 0 ; i < tempRels -> num ; i ++ ) {
1375
+ if (tempRels -> rels [i ] == r ) {
1376
+ tempRels -> rels [i ] = NULL ;
1377
+ break ;
1378
+ }
1379
+ }
1380
+ }
1381
+
1382
+ /*
1383
+ add a temporary relation to the TempRelList
1384
+
1385
+ MODIFIES the global variable tempRels
1386
+ */
1387
+ void
1388
+ AddToTempRelList (Relation r )
1389
+ {
1390
+ if (!tempRels )
1391
+ return ;
1392
+
1393
+ if (tempRels -> num == tempRels -> size ) {
1394
+ tempRels -> size += TEMP_REL_LIST_SIZE ;
1395
+ tempRels -> rels = realloc (tempRels -> rels , tempRels -> size );
1396
+ }
1397
+ tempRels -> rels [tempRels -> num ] = r ;
1398
+ tempRels -> num ++ ;
1399
+ }
1400
+
1401
+ /*
1402
+ go through the tempRels list and destroy each of the relations
1403
+ */
1404
+ void
1405
+ DestroyTempRels ()
1406
+ {
1407
+ int i ;
1408
+ Relation rdesc ;
1409
+
1410
+ if (!tempRels )
1411
+ return ;
1412
+
1413
+ for (i = 0 ;i < tempRels -> num ;i ++ ) {
1414
+ rdesc = tempRels -> rels [i ];
1415
+ /* rdesc may be NULL if it has been removed from the list already */
1416
+ if (rdesc )
1417
+ heap_destroyr (rdesc );
1418
+ }
1419
+ free (tempRels -> rels );
1420
+ free (tempRels );
1421
+ tempRels = NULL ;
1422
+ }
1423
+
0 commit comments