77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.5 1996/11/0606:47:03 scrappy Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.6 1996/11/0607:31:19 scrappy Exp $
1111 *
1212 * INTERFACE ROUTINES
1313 *heap_creatr()- Create an uncataloged heap relation
2626 */
2727#include <postgres.h>
2828
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>
2937#include <utils/mcxt.h>
3038#include <parser/catalog_utils.h>
3139#include <catalog/index.h>
3947#include <rewrite/rewriteRemove.h>
4048#include <storage/lmgr.h>
4149#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
7355
7456/* ----------------------------------------------------------------
7557 *XXX UGLY HARD CODED BADNESS FOLLOWS XXX
@@ -1179,4 +1161,263 @@ DeletePgTypeTuple(Relation rdesc)
11791161
11801162/* ----------------
11811163 *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+