head 1.27; access; symbols release_4_2:1.27 aix_ok:1.24 Version_2_1:1.1; locks; strict; comment @ * @; 1.27 date 94.02.15.05.27.11; author aoki; state Exp; branches; next 1.26; 1.26 date 94.01.11.17.36.16; author jiangwu; state Exp; branches; next 1.25; 1.25 date 93.11.03.08.24.31; author aoki; state Exp; branches; next 1.24; 1.24 date 93.09.26.00.17.46; author paxson; state Exp; branches; next 1.23; 1.23 date 93.07.16.19.00.22; author avi; state Exp; branches; next 1.22; 1.22 date 93.06.24.04.06.57; author aoki; state Exp; branches; next 1.21; 1.21 date 93.01.16.03.14.59; author aoki; state Exp; branches; next 1.20; 1.20 date 92.12.19.01.38.45; author aoki; state Exp; branches; next 1.19; 1.19 date 92.12.18.20.56.18; author mao; state Exp; branches; next 1.18; 1.18 date 92.12.10.03.08.36; author marc; state Exp; branches; next 1.17; 1.17 date 92.10.14.05.55.35; author mao; state Exp; branches 1.17.1.1; next 1.16; 1.16 date 92.03.02.21.04.25; author mer; state Exp; branches; next 1.15; 1.15 date 92.02.27.05.23.53; author mer; state Exp; branches; next 1.14; 1.14 date 92.02.25.21.43.49; author mer; state Exp; branches; next 1.13; 1.13 date 91.11.14.15.01.25; author jolly; state Exp; branches; next 1.12; 1.12 date 91.09.18.18.20.00; author mer; state Exp; branches; next 1.11; 1.11 date 91.09.06.15.49.04; author mer; state Exp; branches; next 1.10; 1.10 date 91.08.14.22.08.13; author mer; state Exp; branches; next 1.9; 1.9 date 91.08.14.12.42.46; author mer; state Exp; branches; next 1.8; 1.8 date 91.07.22.22.20.50; author mao; state Exp; branches; next 1.7; 1.7 date 91.07.09.12.53.40; author mer; state Exp; branches; next 1.6; 1.6 date 91.07.03.00.44.57; author mao; state Exp; branches; next 1.5; 1.5 date 91.05.01.02.50.33; author cimarron; state Exp; branches; next 1.4; 1.4 date 91.04.20.03.49.22; author kemnitz; state Exp; branches; next 1.3; 1.3 date 91.04.19.05.37.58; author kemnitz; state Exp; branches; next 1.2; 1.2 date 91.03.26.17.22.19; author kemnitz; state Exp; branches; next 1.1; 1.1 date 91.02.06.19.01.32; author cimarron; state Exp; branches; next ; 1.17.1.1 date 92.12.20.22.30.33; author mao; state Exp; branches; next ; desc @heap relation creation/destruction routines @ 1.27 log @uninit variable @ text @/* ---------------------------------------------------------------- * FILE * heap.c * * DESCRIPTION * code to create and destroy POSTGRES heap relations * * INTERFACE ROUTINES * heap_creatr() - Create an uncataloged heap relation * heap_create() - Create a cataloged relation * heap_destroy() - Removes named relation from catalogs * * NOTES * this code taken from access/heap/create.c, which contains * the old amcreatr, amcreate, and amdestroy. those routines * will soon call these routines using the function manager, * just like the poorly named "NewXXX" routines do. The * "New" routines are all going to die soon, once and for all! * -cim 1/13/91 * * IDENTIFICATION * $Header: /import/faerie/faerie/aoki/postgres/src/backend/catalog/RCS/heap.c,v 1.26 1994/01/11 17:36:16 jiangwu Exp aoki $ * ---------------------------------------------------------------- */ #include #include #include "tmp/postgres.h" RcsId("$Header: /import/faerie/faerie/aoki/postgres/src/backend/catalog/RCS/heap.c,v 1.26 1994/01/11 17:36:16 jiangwu Exp aoki $"); #include "access/btree.h" /* XXX */ #include "access/heapam.h" #include "access/hrnd.h" #include "access/htup.h" #include "access/istrat.h" #include "access/relscan.h" #include "access/skey.h" #include "access/tqual.h" /* for NowTimeQual */ #include "rules/prs2locks.h" #include "storage/buf.h" #include "storage/itemptr.h" #include "tmp/hasht.h" #include "tmp/miscadmin.h" #include "fmgr.h" #include "utils/log.h" /* XXX */ #include "utils/mcxt.h" #include "utils/rel.h" #include "utils/relcache.h" #include "catalog/catname.h" #include "catalog/pg_relation.h" #include "catalog/pg_attribute.h" #include "catalog/pg_index.h" #include "catalog/pg_inherits.h" #include "catalog/pg_ipl.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "catalog/indexing.h" #include "lib/catalog.h" #ifndef private #define private /* public */ #endif /* ---------------------------------------------------------------- * XXX UGLY HARD CODED BADNESS FOLLOWS XXX * * these should all be moved to someplace in the lib/catalog * module, if not obliterated first. * ---------------------------------------------------------------- */ /* * Note: * Should the executor special case these attributes in the future? * Advantage: consume 1/2 the space in the ATTRIBUTE relation. * Disadvantage: having rules to compute values in these tuples may * be more difficult if not impossible. */ static struct attribute a1 = { -1l, "ctid", 27l, 0l, 0l, 0l, sizeof (ItemPointerData), SelfItemPointerAttributeNumber, 0, '\0', '\001', 0l }; static struct attribute a2 = { -1l, "lock", 31l, 0l, 0l, 0l, -1, RuleLockAttributeNumber, 0, '\0', '\001', 0l }; static struct attribute a3 = { -1l, "oid", 26l, 0l, 0l, 0l, sizeof (OID), ObjectIdAttributeNumber, 0, '\001', '\001', 0l }; static struct attribute a4 = { -1l, "xmin", 28l, 0l, 0l, 0l, sizeof (PG_XID), MinTransactionIdAttributeNumber, 0, '\0', '\001', 0l }; static struct attribute a5 = { -1l, "cmin", 29l, 0l, 0l, 0l, sizeof (CID), MinCommandIdAttributeNumber, 0, '\001', '\001', 0l }; static struct attribute a6 = { -1l, "xmax", 28l, 0l, 0l, 0l, sizeof (PG_XID), MaxTransactionIdAttributeNumber, 0, '\0', '\001', 0l }; static struct attribute a7 = { -1l, "cmax", 29l, 0l, 0l, 0l, sizeof (CID), MaxCommandIdAttributeNumber, 0, '\001', '\001', 0l }; static struct attribute a8 = { -1l, "chain", 27l, 0l, 0l, 0l, sizeof (ItemPointerData), ChainItemPointerAttributeNumber, 0, '\0', '\001', 0l }; static struct attribute a9 = { -1l, "anchor", 27l, 0l, 0l, 0l, sizeof (ItemPointerData), AnchorItemPointerAttributeNumber, 0, '\0', '\001', 0l }; static struct attribute a10 = { -1l, "tmin", 20l, 0l, 0l, 0l, sizeof (AbsoluteTime), MinAbsoluteTimeAttributeNumber, 0, '\001', '\001', 0l }; static struct attribute a11 = { -1l, "tmax", 20l, 0l, 0l, 0l, sizeof (AbsoluteTime), MaxAbsoluteTimeAttributeNumber, 0, '\001', '\001', 0l }; static struct attribute a12 = { -1l, "vtype", 18l, 0l, 0l, 0l, sizeof (char), VersionTypeAttributeNumber, 0, '\001', '\001', 0l }; static struct attribute *HeapAtt[] = { &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11, &a12 }; /* ---------------------------------------------------------------- * XXX END OF UGLY HARD CODED BADNESS XXX * ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- * heap_creatr - Create an uncataloged heap relation * * Fields relpages, reltuples, reltuples, relkeys, relhistory, * relisindexed, and relkind of rdesc->rd_rel are initialized * to all zeros, as are rd_last and rd_hook. Rd_refcnt is set to 1. * * Remove the system relation specific code to elsewhere eventually. * * Eventually, must place information about this temporary relation * into the transaction context block. * ---------------------------------------------------------------- */ Relation heap_creatr(relname, natts, smgr, att) char relname[]; unsigned natts; unsigned smgr; struct attribute *att[]; /* XXX */ { register int i; ObjectId relid; Relation rdesc; int len; bool nailme = false; File fd; extern GlobalMemory CacheCxt; MemoryContext oldcxt; File smgrcreate(); /* XXX */ /* ---------------- * sanity checks * ---------------- */ if (!natts) elog(WARN, "heap_creatr(%s): called with 0 natts", relname); if (issystem(relname) && IsNormalProcessingMode()) { elog(WARN, "Illegal class name: %s -- pg_ is reserved for system catalogs", relname); } /* ---------------- * switch to the cache context so that we don't lose * allocations at the end of this transaction, I guess. * -cim 6/14/90 * ---------------- */ if (!CacheCxt) CacheCxt = CreateGlobalMemory("Cache"); oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt); /* ---------------- * real ugly stuff to assign the proper relid in the relation * descriptor follows. * ---------------- */ if (! strncmp(relname, RelationRelationName, 16)) { relid = RelOid_pg_relation; nailme = true; } else if (! strncmp(relname, AttributeRelationName, 16)) { relid = RelOid_pg_attribute; nailme = true; } else if (! strncmp(relname, ProcedureRelationName, 16)) { relid = RelOid_pg_proc; nailme = true; } else if (! strncmp(relname, TypeRelationName, 16)) { relid = RelOid_pg_type; nailme = true; } else { relid = newoid(); if (! strncmp(relname, "temp_", 5)) sprintf(relname, "temp_%d", relid); }; /* ---------------- * allocate a new relation descriptor. * * XXX the length computation may be incorrect, handle elsewhere * ---------------- */ len = sizeof *rdesc + (int)(natts - 1) * sizeof rdesc->rd_att; len += sizeof (IndexStrategy) + sizeof(RegProcedure *); rdesc = (Relation) palloc(len); bzero((char *)rdesc, len); /* ---------------- * initialize the fields of our new relation descriptor * ---------------- */ /* ---------------- * nail the reldesc if this is a bootstrap create reln and * we may need it in the cache later on in the bootstrap * process so we don't ever want it kicked out. e.g. pg_attribute!!! * ---------------- */ if (nailme) rdesc->rd_isnailed = true; RelationSetReferenceCount(rdesc, 1); rdesc->rd_rel = (RelationTupleForm) palloc(sizeof (RuleLock) + sizeof *rdesc->rd_rel); bzero((char *)rdesc->rd_rel, sizeof *rdesc->rd_rel + sizeof (RuleLock)); strncpy((char *)&rdesc->rd_rel->relname, relname, sizeof(NameData)); rdesc->rd_rel->relkind = 'u'; rdesc->rd_rel->relnatts = natts; rdesc->rd_rel->relsmgr = smgr; for (i = 0; i < natts; i++) { rdesc->rd_att.data[i] = (AttributeTupleForm) palloc(sizeof *att[0] + sizeof (RuleLock)); bcopy((char *)att[i], (char *)rdesc->rd_att.data[i], sizeof *att[0]); bzero((char *)(rdesc->rd_att.data[i] + 1), sizeof (RuleLock)); rdesc->rd_att.data[i]->attrelid = relid; } rdesc->rd_id = relid; /* ---------------- * have the storage manager create the relation. * ---------------- */ rdesc->rd_fd = smgrcreate(smgr, rdesc); RelationRegisterRelation(rdesc); MemoryContextSwitchTo(oldcxt); return (rdesc); } /* ---------------------------------------------------------------- * heap_create - Create a cataloged relation * * this is done in 6 steps: * * 1) CheckAttributeNames() is used to make certain the tuple * descriptor contains a valid set of attribute names * * 2) pg_relation is opened and RelationAlreadyExists() * preforms a scan to ensure that no relation with the * same name already exists. * * 3) amcreatr() is called to create the new relation on * disk. * * 4) TypeDefine() is called to define a new type corresponding * to the new relation. * * 5) AddNewAttributeTuples() is called to register the * new relation's schema in pg_attribute. * * 6) AddPgRelationTuple() is called to register the * relation itself in the catalogs. * * 7) the relations are closed and the new relation's oid * is returned. * * old comments: * A new relation is inserted into the RELATION relation * with the specified attribute(s) (newly inserted into * the ATTRIBUTE relation). How does concurrency control * work? Is it automatic now? Expects the caller to have * attname, atttypid, atttyparg, attproc, and attlen domains filled. * Create fills the attnum domains sequentually from zero, * fills the attnvals domains with zeros, and fills the * attrelid fields with the relid. * * scan relation catalog for name conflict * scan type catalog for typids (if not arg) * create and insert attribute(s) into attribute catalog * create new relation * insert new relation into attribute catalog * * Should coordinate with amcreatr(). Either it should * not be called or there should be a way to prevent * the relation from being removed at the end of the * transaction if it is successful ('u'/'r' may be enough). * Also, if the transaction does not commit, then the * relation should be removed. * * XXX amcreate ignores "off" when inserting (for now). * XXX amcreate (like the other utilities) needs to understand indexes. * * ---------------------------------------------------------------- */ /* -------------------------------- * CheckAttributeNames * * this is used to make certain the tuple descriptor contains a * valid set of attribute names. a problem simply generates * elog(WARN) which aborts the current transaction. * -------------------------------- */ void CheckAttributeNames(natts, tupdesc) unsigned natts; struct attribute *tupdesc[]; { int i; int j; /* ---------------- * first check for collision with system attribute names * ---------------- */ for (i = 0; i < natts; i += 1) { for (j = 0; j < sizeof HeapAtt / sizeof HeapAtt[0]; j += 1) { if (NameIsEqual((Name)(HeapAtt[j]->attname), (Name)(tupdesc[i]->attname))) { elog(WARN, "create: system attribute named \"%s\"", HeapAtt[j]->attname); } } } /* ---------------- * next check for repeated attribute names * ---------------- */ for (i = 1; i < natts; i += 1) { for (j = 0; j < i; j += 1) { if (NameIsEqual((Name)(tupdesc[j]->attname), (Name)(tupdesc[i]->attname))) { elog(WARN, "create: repeated attribute \"%s\"", tupdesc[j]->attname); } } } } /* -------------------------------- * RelationAlreadyExists * * this preforms a scan of pg_relation to ensure that * no relation with the same name already exists. The caller * has to open pg_relation and pass an open descriptor. * -------------------------------- */ int RelationAlreadyExists(pg_relation_desc, relname) Relation pg_relation_desc; char relname[]; { ScanKeyEntryData key; HeapScanDesc pg_relation_scan; HeapTuple tup; /* * If this is not bootstrap (initdb) time, use the catalog index * on pg_class. */ if (!IsBootstrapProcessingMode()) { tup = ClassNameIndexScan(pg_relation_desc, relname); if (HeapTupleIsValid(tup)) { pfree (tup); return ((int) true); } else return ((int) false); } /* ---------------- * At bootstrap time, we have to do this the hard way. Form the * scan key. * ---------------- */ ScanKeyEntryInitialize(&key, 0, (AttributeNumber)Anum_pg_relation_relname, (RegProcedure)F_CHAR16EQ, (Datum) relname); /* ---------------- * begin the scan * ---------------- */ pg_relation_scan = ambeginscan(pg_relation_desc, 0, NowTimeQual, 1, &key); /* ---------------- * get a tuple. if the tuple is NULL then it means we * didn't find an existing relation. * ---------------- */ tup = amgetnext(pg_relation_scan, 0, (Buffer *)NULL); /* ---------------- * end the scan and return existance of relation. * ---------------- */ amendscan(pg_relation_scan); return (PointerIsValid(tup) == true); } /* -------------------------------- * AddNewAttributeTuples * * this registers the new relation's schema by adding * tuples to pg_attribute. * -------------------------------- */ void AddNewAttributeTuples(new_rel_oid, new_type_oid, natts, tupdesc) ObjectId new_rel_oid; ObjectId new_type_oid; /* might not be needed. */ unsigned natts; struct attribute *tupdesc[]; { register struct attribute **dpp; /* XXX */ HeapTuple tup; Relation rdesc; int i; bool hasindex; Relation idescs[Num_pg_attr_indices]; /* ---------------- * open pg_attribute * ---------------- */ rdesc = amopenr(AttributeRelationName); /* ----------------- * Check if we have any indices defined on pg_attribute. * ----------------- */ Assert(rdesc); Assert(rdesc->rd_rel); if (hasindex = RelationGetRelationTupleForm(rdesc)->relhasindex) CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs); /* ---------------- * initialize tuple descriptor. Note we use setheapoverride() * so that we can see the effects of our TypeDefine() done * previously. * ---------------- */ setheapoverride(true); fillatt(natts, (AttributeTupleForm*)tupdesc); setheapoverride(false); /* ---------------- * make sure all the tuples are added together. * ---------------- */ setclusteredappend(true); /* ---------------- * first we add the user attributes.. * ---------------- */ dpp = tupdesc; for (i = 0; i < natts; i++) { (*dpp)->attrelid = new_rel_oid; (*dpp)->attnvals = 0l; tup = addtupleheader(Natts_pg_attribute, sizeof (struct attribute), (char *) *dpp); aminsert(rdesc, tup, (double *)NULL); if (hasindex) CatalogIndexInsert(idescs, Num_pg_attr_indices, rdesc, tup); pfree((char *)tup); dpp++; } /* ---------------- * next we add the system attributes.. * ---------------- */ dpp = HeapAtt; for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++) { (*dpp)->attrelid = new_rel_oid; /* (*dpp)->attnvals = 0l; unneeded */ tup = addtupleheader(Natts_pg_attribute, sizeof (struct attribute), (char *)*dpp); aminsert(rdesc, tup, (double *)NULL); if (hasindex) CatalogIndexInsert(idescs, Num_pg_attr_indices, rdesc, tup); pfree((char *)tup); dpp++; } /* ---------------- * all done with pg_attribute now, so turn off * "clusterd append mode" and close our relation. * ---------------- */ setclusteredappend(false); amclose(rdesc); /* * close pg_attribute indices */ if (hasindex) CatalogCloseIndices(Num_pg_attr_indices, idescs); } /* -------------------------------- * AddPgRelationTuple * * this registers the new relation in the catalogs by * adding a tuple to pg_relation. * -------------------------------- */ void AddPgRelationTuple(pg_relation_desc, new_rel_desc, new_rel_oid, arch, natts) Relation pg_relation_desc; Relation new_rel_desc; ObjectId new_rel_oid; int arch; unsigned natts; { RelationTupleForm new_rel_reltup; HeapTuple tup; Relation idescs[Num_pg_class_indices]; bool isBootstrap; /* ---------------- * first we munge some of the information in our * uncataloged relation's relation descriptor. * ---------------- */ new_rel_reltup = new_rel_desc->rd_rel; /* CHECK should get new_rel_oid first via an insert then use XXX */ /* new_rel_reltup->reltuples = 1; */ /* XXX */ new_rel_reltup->relowner = GetUserId(); new_rel_reltup->relkind = 'r'; new_rel_reltup->relarch = arch; new_rel_reltup->relnatts = natts; /* ---------------- * now form a tuple to add to pg_relation * XXX Natts_pg_relation_fixed is a hack - see pg_relation.h * ---------------- */ tup = addtupleheader(Natts_pg_relation_fixed, sizeof (struct relation), (char *) new_rel_reltup); tup->t_oid = new_rel_oid; /* ---------------- * finally insert the new tuple and free it. * * Note: I have no idea why we do a * SetProcessingMode(BootstrapProcessing); * here -cim 6/14/90 * ---------------- */ isBootstrap = IsBootstrapProcessingMode() ? true : false; SetProcessingMode(BootstrapProcessing); aminsert(pg_relation_desc, tup, (double *)NULL); if (! isBootstrap) { /* * First, open the catalog indices and insert index tuples for * the new relation. */ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs); CatalogIndexInsert(idescs, Num_pg_class_indices, pg_relation_desc, tup); CatalogCloseIndices(Num_pg_class_indices, idescs); /* now restore processing mode */ SetProcessingMode(NormalProcessing); } pfree((char *)tup); } /* -------------------------------- * heap_create * * creates a new cataloged relation. see comments above. * -------------------------------- */ ObjectId heap_create(relname, arch, natts, smgr, tupdesc) char relname[]; int arch; unsigned natts; unsigned smgr; struct attribute *tupdesc[]; { Relation pg_relation_desc; Relation new_rel_desc; ObjectId new_rel_oid; ObjectId new_type_oid; int i; /* ---------------- * sanity checks * ---------------- */ AssertState(IsNormalProcessingMode() || IsBootstrapProcessingMode()); if (natts == 0 || natts > MaxHeapAttributeNumber) elog(WARN, "amcreate: from 1 to %d attributes must be specified", MaxHeapAttributeNumber); CheckAttributeNames(natts, tupdesc); /* ---------------- * open pg_relation and see that the relation doesn't * already exist. * ---------------- */ pg_relation_desc = amopenr(RelationRelationName); if (RelationAlreadyExists(pg_relation_desc, relname)) { amclose(pg_relation_desc); elog(WARN, "amcreate: %s relation already exists", relname); } /* ---------------- * ok, relation does not already exist so now we * create an uncataloged relation and pull its relation oid * from the newly formed relation descriptor. * * Note: The call to amcreatr() does all the "real" work * of creating the disk file for the relation. * ---------------- */ new_rel_desc = amcreatr(relname, natts, smgr, tupdesc); new_rel_oid = new_rel_desc->rd_att.data[0]->attrelid; /* ---------------- * since defining a relation also defines a complex type, * we add a new system type corresponding to the new relation. * ---------------- */ /* The sizes are set to oid size because it makes implementing sets MUCH * easier, and no one (we hope) uses these fields to figure out * how much space to allocate for the type. * An oid is the type used for a set definition. When a user * requests a set, what they actually get is the oid of a tuple in * the pg_proc catalog, so the size of the "set" is the size * of an oid. * Similarly, byval being true makes sets much easier, and * it isn't used by anything else. * Note the assumption that OIDs are the same size as int4s. */ new_type_oid = TypeDefine(relname, /* type name */ new_rel_oid, /* relation oid */ tlen(type("oid")), /* internal size */ tlen(type("oid")), /* external size */ 'c', /* type-type (catalog) */ ',', /* default array delimiter */ "int4in", /* input procedure */ "int4out", /* output procedure */ "int4in", /* send procedure */ "int4out", /* receive procedure */ NULL, /* array element type - irrelevent */ "-", /* default type value */ (Boolean) 1); /* passed by value */ /* ---------------- * now add tuples to pg_attribute for the attributes in * our new relation. * ---------------- */ AddNewAttributeTuples(new_rel_oid, new_type_oid, natts, tupdesc); /* ---------------- * now update the information in pg_relation. * ---------------- */ AddPgRelationTuple(pg_relation_desc, new_rel_desc, new_rel_oid, arch, natts); /* ---------------- * ok, the relation has been cataloged, so close our relations * and return the oid of the newly created relation. * * SOMEDAY: fill the STATISTIC relation properly. * ---------------- */ amclose(new_rel_desc); amclose(pg_relation_desc); return new_rel_oid; } /* ---------------------------------------------------------------- * heap_destroy - removes all record of named relation from catalogs * * 1) open relation, check for existence, etc. * 2) remove inheritance information * 3) remove indexes * 4) remove pg_relation tuple * 5) remove pg_attribute tuples * 6) remove pg_type tuples * 7) unlink relation * * old comments * Except for vital relations, removes relation from * relation catalog, and related attributes from * attribute catalog (needed?). (Anything else???) * * get proper relation from relation catalog (if not arg) * check if relation is vital (strcmp()/reltype???) * scan attribute catalog deleting attributes of reldesc * (necessary?) * delete relation from relation catalog * (How are the tuples of the relation discarded???) * * XXX Must fix to work with indexes. * There may be a better order for doing things. * Problems with destroying a deleted database--cannot create * a struct reldesc without having an open file descriptor. * ---------------------------------------------------------------- */ /* -------------------------------- * RelationRemoveInheritance * * Note: for now, we cause an exception if relation is a * superclass. Someday, we may want to allow this and merge * the type info into subclass procedures.... this seems like * lots of work. * -------------------------------- */ void RelationRemoveInheritance(relation) Relation relation; { Relation catalogRelation; Relation iplRelation; HeapTuple tuple; HeapScanDesc scan; ScanKeyEntryData entry[1]; /* ---------------- * open pg_inherits * ---------------- */ catalogRelation = RelationNameOpenHeapRelation(InheritsRelationName); /* ---------------- * form a scan key for the subclasses of this class * and begin scanning * ---------------- */ ScanKeyEntryInitialize(&entry[0], 0x0, InheritsParentAttributeNumber, ObjectIdEqualRegProcedure, ObjectIdGetDatum(RelationGetRelationId(relation))); scan = RelationBeginHeapScan(catalogRelation, false, NowTimeQual, 1, entry); /* ---------------- * if any subclasses exist, then we disallow the deletion. * ---------------- */ tuple = HeapScanGetNextTuple(scan, false, (Buffer *)NULL); if (HeapTupleIsValid(tuple)) { HeapScanEnd(scan); RelationCloseHeapRelation(catalogRelation); elog(WARN, "relation <%d> inherits \"%s\"", ((InheritsTupleForm) GETSTRUCT(tuple))->inhrel, RelationGetRelationName(relation)); } /* ---------------- * If we get here, it means the relation has no subclasses * so we can trash it. First we remove dead INHERITS tuples. * ---------------- */ entry[0].attributeNumber = InheritsRelationIdAttributeNumber; scan = RelationBeginHeapScan(catalogRelation, false, NowTimeQual, 1, entry); for (;;) { tuple = HeapScanGetNextTuple(scan, false, (Buffer *)NULL); if (!HeapTupleIsValid(tuple)) { break; } RelationDeleteHeapTuple(catalogRelation, &tuple->t_ctid); } HeapScanEnd(scan); RelationCloseHeapRelation(catalogRelation); /* ---------------- * now remove dead IPL tuples * ---------------- */ catalogRelation = RelationNameOpenHeapRelation(InheritancePrecidenceListRelationName); entry[0].attributeNumber = InheritancePrecidenceListRelationIdAttributeNumber; scan = RelationBeginHeapScan(catalogRelation, false, NowTimeQual, 1, entry); for (;;) { tuple = HeapScanGetNextTuple(scan, false, (Buffer *)NULL); if (!HeapTupleIsValid(tuple)) { break; } RelationDeleteHeapTuple(catalogRelation, &tuple->t_ctid); } HeapScanEnd(scan); RelationCloseHeapRelation(catalogRelation); } /* -------------------------------- * RelationRemoveIndexes * * -------------------------------- */ void RelationRemoveIndexes(relation) Relation relation; { ObjectId indexId; Relation indexRelation; HeapTuple tuple; HeapScanDesc scan; ScanKeyEntryData entry[1]; indexRelation = RelationNameOpenHeapRelation(IndexRelationName); ScanKeyEntryInitialize(&entry[0], 0x0, IndexHeapRelationIdAttributeNumber, ObjectIdEqualRegProcedure, ObjectIdGetDatum(RelationGetRelationId(relation))); scan = RelationBeginHeapScan(indexRelation, false, NowTimeQual, 1, entry); for (;;) { tuple = HeapScanGetNextTuple(scan, false, (Buffer *)NULL); if (!HeapTupleIsValid(tuple)) { break; } DestroyIndexRelationById( ((IndexTupleForm)GETSTRUCT(tuple))->indexrelid); } HeapScanEnd(scan); RelationCloseHeapRelation(indexRelation); } /* -------------------------------- * DeletePgRelationTuple * * -------------------------------- */ void DeletePgRelationTuple(rdesc) Relation rdesc; { Relation pg_relation_desc; HeapScanDesc pg_relation_scan; ScanKeyEntryData key; HeapTuple tup; /* ---------------- * open pg_relation * ---------------- */ pg_relation_desc = amopenr(RelationRelationName); /* ---------------- * create a scan key to locate the relation oid of the * relation to delete * ---------------- */ ScanKeyEntryInitialize(&key, NULL, ObjectIdAttributeNumber, F_INT4EQ, rdesc->rd_att.data[0]->attrelid); pg_relation_scan = ambeginscan(pg_relation_desc, 0, NowTimeQual, 1, &key); /* ---------------- * use amgetnext() to fetch the pg_relation tuple. If this * tuple is not valid then something's wrong. * ---------------- */ tup = amgetnext(pg_relation_scan, 0, (Buffer *) NULL); if (! PointerIsValid(tup)) { amendscan(pg_relation_scan); amclose(pg_relation_desc); elog(WARN, "DeletePgRelationTuple: %s relation nonexistent", &rdesc->rd_rel->relname); } /* ---------------- * delete the relation tuple from pg_relation, and finish up. * ---------------- */ amendscan(pg_relation_scan); amdelete(pg_relation_desc, &tup->t_ctid); amclose(pg_relation_desc); } /* -------------------------------- * DeletePgAttributeTuples * * -------------------------------- */ void DeletePgAttributeTuples(rdesc) Relation rdesc; { Relation pg_attribute_desc; HeapScanDesc pg_attribute_scan; ScanKeyEntryData key; HeapTuple tup; /* ---------------- * open pg_attribute * ---------------- */ pg_attribute_desc = amopenr(AttributeRelationName); /* ---------------- * create a scan key to locate the attribute tuples to delete * and begin the scan. * ---------------- */ ScanKeyEntryInitialize(&key, NULL, Anum_pg_attribute_attrelid, F_INT4EQ, rdesc->rd_att.data[0]->attrelid); /* ----------------- * Get a write lock _before_ getting the read lock in the scan * ---------------- */ RelationSetLockForWrite(pg_attribute_desc); pg_attribute_scan = ambeginscan(pg_attribute_desc, 0, NowTimeQual, 1, &key); /* ---------------- * use amgetnext() / amdelete() until all attribute tuples * have been deleted. * ---------------- */ while (tup = amgetnext(pg_attribute_scan, 0, (Buffer *)NULL), PointerIsValid(tup)) { amdelete(pg_attribute_desc, &tup->t_ctid); } /* ---------------- * finish up. * ---------------- */ amendscan(pg_attribute_scan); /* ---------------- * Release the write lock * ---------------- */ RelationUnsetLockForWrite(pg_attribute_desc); amclose(pg_attribute_desc); } /* -------------------------------- * DeletePgTypeTuple * * If the user attempts to destroy a relation and there * exists attributes in other relations of type * "relation we are deleting", then we have to do something * special. presently we disallow the destroy. * -------------------------------- */ void DeletePgTypeTuple(rdesc) Relation rdesc; { Relation pg_type_desc; HeapScanDesc pg_type_scan; Relation pg_attribute_desc; HeapScanDesc pg_attribute_scan; ScanKeyEntryData key; ScanKeyEntryData attkey; HeapTuple tup; HeapTuple atttup; ObjectId typoid; /* ---------------- * open pg_type * ---------------- */ pg_type_desc = amopenr(TypeRelationName); /* ---------------- * create a scan key to locate the type tuple corresponding * to this relation. * ---------------- */ ScanKeyEntryInitialize(&key, NULL, Anum_pg_type_typrelid, F_INT4EQ, rdesc->rd_att.data[0]->attrelid); pg_type_scan = ambeginscan(pg_type_desc, 0, NowTimeQual, 1, &key); /* ---------------- * use amgetnext() to fetch the pg_type tuple. If this * tuple is not valid then something's wrong. * ---------------- */ tup = amgetnext(pg_type_scan, 0, (Buffer *)NULL); if (! PointerIsValid(tup)) { amendscan(pg_type_scan); amclose(pg_type_desc); elog(WARN, "DeletePgTypeTuple: %s type nonexistent", &rdesc->rd_rel->relname); } /* ---------------- * now scan pg_attribute. if any other relations have * attributes of the type of the relation we are deleteing * then we have to disallow the deletion. should talk to * stonebraker about this. -cim 6/19/90 * ---------------- */ typoid = tup->t_oid; pg_attribute_desc = amopenr(AttributeRelationName); ScanKeyEntryInitialize(&attkey, NULL, Anum_pg_attribute_atttypid, F_INT4EQ, typoid); pg_attribute_scan = ambeginscan(pg_attribute_desc, 0, NowTimeQual, 1, &attkey); /* ---------------- * try and get a pg_attribute tuple. if we succeed it means * we cant delete the relation because something depends on * the schema. * ---------------- */ atttup = amgetnext(pg_attribute_scan, 0, (Buffer *)NULL); if (PointerIsValid(atttup)) { ObjectId relid = ((AttributeTupleForm) GETSTRUCT(atttup))->attrelid; amendscan(pg_type_scan); amclose(pg_type_desc); amendscan(pg_attribute_scan); amclose(pg_attribute_desc); elog(WARN, "DeletePgTypeTuple: att of type %s exists in relation %d", &rdesc->rd_rel->relname, relid); } amendscan(pg_attribute_scan); amclose(pg_attribute_desc); /* ---------------- * Ok, it's safe so we delete the relation tuple * from pg_type and finish up. But first end the scan so that * we release the read lock on pg_type. -mer 13 Aug 1991 * ---------------- */ amendscan(pg_type_scan); amdelete(pg_type_desc, &tup->t_ctid); amclose(pg_type_desc); } /* -------------------------------- * heap_destroy * * -------------------------------- */ void heap_destroy(relname) char relname[]; { Relation rdesc; /* int issystem(); */ /* ---------------- * first open the relation. if the relation does exist, * amopenr() returns NULL. * ---------------- */ rdesc = amopenr(relname); if (rdesc == NULL) elog(WARN,"Relation %s Does Not Exist!", relname); /* ---------------- * prevent deletion of system relations * ---------------- */ if (issystem((char*)(RelationGetRelationName(rdesc))) || 0 /* is not owned etc. */) elog(WARN, "amdestroy: cannot destroy %s relation", &rdesc->rd_rel->relname); /* ---------------- * remove inheritance information * ---------------- */ RelationRemoveInheritance(rdesc); /* ---------------- * remove indexes if necessary * ---------------- */ if (rdesc->rd_rel->relhasindex) { RelationRemoveIndexes(rdesc); } /* ---------------- * delete attribute tuples * ---------------- */ DeletePgAttributeTuples(rdesc); /* ---------------- * delete type tuple. here we want to see the effects * of the deletions we just did, so we use setheapoverride(). * ---------------- */ setheapoverride(true); DeletePgTypeTuple(rdesc); setheapoverride(false); /* ---------------- * delete relation tuple * ---------------- */ DeletePgRelationTuple(rdesc); /* ---------------- * unlink the relation and finish up. * ---------------- */ (void) smgrunlink(rdesc->rd_rel->relsmgr, rdesc); amclose(rdesc); } @ 1.26 log @Changed XID to PG_XID to avoid conflict with Xlib -- jw, 1/11/94 @ text @d22 1 a22 1 * $Header: /private/src/postgres/src/backend/catalog/RCS/heap.c,v 1.25 1993/11/03 08:24:31 aoki Exp jiangwu $ d31 1 a31 1 RcsId("$Header: /private/src/postgres/src/backend/catalog/RCS/heap.c,v 1.25 1993/11/03 08:24:31 aoki Exp jiangwu $"); a258 1 rdesc->rd_fd = fd; @ 1.25 log @fix broken prs2 protos remove rules/rlock.h, access/xcxt.h, access/newam.h (dead headers with residual dependencies) @ text @d22 1 a22 1 * $Header: /faerie/aoki/postgres/src/backend/catalog/RCS/heap.c,v 1.24 1993/09/26 00:17:46 paxson Exp aoki $ d31 1 a31 1 RcsId("$Header: /faerie/aoki/postgres/src/backend/catalog/RCS/heap.c,v 1.24 1993/09/26 00:17:46 paxson Exp aoki $"); d101 1 a101 1 -1l, "xmin", 28l, 0l, 0l, 0l, sizeof (XID), d111 1 a111 1 -1l, "xmax", 28l, 0l, 0l, 0l, sizeof (XID), @ 1.24 log @changed TypeDefine call in heap_create, which defines a type corresponding to the new relation being defined, to make that type have size 4 (the size of an OID) and byval = true. Reasoning: no one else looks in the class type to figure out how big the class is or its byval, so can make these values what I need to make sets easier to implement. changed input and output procs for relation type to be int4in and int4out (the same as for OIDs), since relations as attrs are really sets, so they are oid-sized added big comment in heap_create about the size of the type corresponding to a new relation @ text @d22 1 a22 1 * $Header: /local/src/postgres/src/backend/catalog/RCS/heap.c,v 1.23 1993/07/16 19:00:22 avi Exp paxson $ d31 1 a31 1 RcsId("$Header: /local/src/postgres/src/backend/catalog/RCS/heap.c,v 1.23 1993/07/16 19:00:22 avi Exp paxson $"); d41 1 a41 1 #include "rules/rlock.h" a62 4 #ifdef sprite #include "sprite_file.h" #endif /* sprite */ @ 1.23 log @time cleanup @ text @d22 1 a22 1 * $Header: /private/src/postgres/src/backend/catalog/RCS/heap.c,v 1.22 1993/06/24 04:06:57 aoki Exp avi $ d31 1 a31 1 RcsId("$Header: /private/src/postgres/src/backend/catalog/RCS/heap.c,v 1.22 1993/06/24 04:06:57 aoki Exp avi $"); d731 11 d744 2 a745 2 -1, /* internal size (varlena) */ -1, /* external size (varlena) */ d748 4 a751 4 "textin", /* input procedure */ "textout", /* output procedure */ "textin", /* send procedure */ "textout", /* recieve procedure */ d754 1 a754 1 (Boolean) 0); /* passed by value */ @ 1.22 log @removed some broken extern decl's @ text @d22 1 a22 1 * $Header: /usr/local/devel/postgres/src/backend/catalog/RCS/heap.c,v 1.21 1993/01/16 03:14:59 aoki Exp $ d31 1 a31 1 RcsId("$Header: /usr/local/devel/postgres/src/backend/catalog/RCS/heap.c,v 1.21 1993/01/16 03:14:59 aoki Exp $"); d135 1 a135 1 -1l, "tmin", 20l, 0l, 0l, 0l, sizeof (ABSTIME), d140 1 a140 1 -1l, "tmax", 20l, 0l, 0l, 0l, sizeof (ABSTIME), @ 1.21 log @removed references to utils/fmgr.h and parser/parse.h @ text @d22 1 a22 1 * $Header: /home2/aoki/postgres/src/backend/catalog/RCS/heap.c,v 1.20 1992/12/19 01:38:45 aoki Exp aoki $ d31 1 a31 1 RcsId("$Header: /home2/aoki/postgres/src/backend/catalog/RCS/heap.c,v 1.20 1992/12/19 01:38:45 aoki Exp aoki $"); a188 1 /* int issystem(); */ a189 2 /* OID newoid(); */ extern bcopy(), bzero(); @ 1.20 log @second checkin for acls and other stuff @ text @d22 1 a22 1 * $Header: /home2/aoki/postgres/catalog/RCS/heap.c,v 1.19 1992/12/18 20:56:18 mao Exp aoki $ d31 1 a31 1 RcsId("$Header: /home2/aoki/postgres/catalog/RCS/heap.c,v 1.19 1992/12/18 20:56:18 mao Exp aoki $"); d46 1 a46 1 #include "utils/fmgr.h" @ 1.19 log @use and maintain catalog indices wherever possible @ text @d22 1 a22 1 * $Header: /private/mao/postgres/src/lib/catalog/RCS/heap.c,v 1.17 1992/10/14 05:55:35 mao Exp $ d31 1 a31 1 RcsId("$Header: /private/mao/postgres/src/lib/catalog/RCS/heap.c,v 1.17 1992/10/14 05:55:35 mao Exp $"); d634 1 d637 1 a637 1 tup = addtupleheader(Natts_pg_relation, @ 1.18 log @don't extern bzero - let it come from headers if necessary @ text @d22 1 a22 1 * $Header: /usr/local/devel/postgres/src/backend/catalog/RCS/heap.c,v 1.17 1992/10/14 05:55:35 mao Exp marc $ d31 1 a31 1 RcsId("$Header: /usr/local/devel/postgres/src/backend/catalog/RCS/heap.c,v 1.17 1992/10/14 05:55:35 mao Exp marc $"); d192 1 d434 14 d449 2 a450 1 * form the scan key d614 1 d655 11 a665 1 if (! isBootstrap) d667 1 @ 1.17 log @when destroying a relation, call the storage manager routine to handle the unlink. @ text @d22 1 a22 1 * $Header: /private/mao/postgres/src/lib/catalog/RCS/heap.c,v 1.16 1992/03/02 21:04:25 mer Exp mao $ d31 1 a31 1 RcsId("$Header: /private/mao/postgres/src/lib/catalog/RCS/heap.c,v 1.16 1992/03/02 21:04:25 mer Exp mao $"); a191 1 extern bcopy(), bzero(); @ 1.17.1.1 log @turn off sanity checking if we're creating inversion classes -- code elsewhere guarantees unique names, and 4.0.1 on toe and heel is way too slow if we do this every time we import a file. @ text @d22 1 a22 1 * $Header: /private/src/postgres/src/backend/catalog/RCS/heap.c,v 1.17 1992/10/14 05:55:35 mao Exp mao $ d31 1 a31 1 RcsId("$Header: /private/src/postgres/src/backend/catalog/RCS/heap.c,v 1.17 1992/10/14 05:55:35 mao Exp mao $"); d675 1 a675 8 /* * XXX mao 12/92 -- performance is so bad with very large catalogs and * no useful catalog indices under 4.0.1 that i'm short-circuiting * some checking for inversion classes. */ if (strncmp(relname, "Xin", 3) != 0) CheckAttributeNames(natts, tupdesc); d684 4 a687 5 if (strncmp(relname, "Xin", 3) != 0) if (RelationAlreadyExists(pg_relation_desc, relname)) { amclose(pg_relation_desc); elog(WARN, "amcreate: %s relation already exists", relname); } @ 1.16 log @keep indices on pg_attribute up to date when pg_attribute changes. @ text @d22 1 a22 1 * $Header: /users/mer/pg/src/lib/catalog/RCS/heap.c,v 1.13 1991/11/14 15:01:25 jolly Exp mer $ d31 1 a31 1 RcsId("$Header: /users/mer/pg/src/lib/catalog/RCS/heap.c,v 1.13 1991/11/14 15:01:25 jolly Exp mer $"); a1166 22 * UnlinkRelationFile * * unlink unix file and close relation * -------------------------------- */ void UnlinkRelationFile(rdesc) Relation rdesc; { /* char *relpath();*/ int i; /* ---------------- * unlink the unix file * ---------------- */ if (FileNameUnlink((FileName)(relpath((char*)(&rdesc->rd_rel->relname)))) < 0) elog(WARN, "amdestroyr: unlink: %m"); } /* -------------------------------- d1234 1 a1234 2 UnlinkRelationFile(rdesc); @ 1.15 log @ail the reldesc if this is a bootstrap created relation n @ text @d22 1 a22 1 * $Header: /users/mer/pg/src/lib/catalog/RCS/heap.c,v 1.14 1992/02/25 21:43:49 mer Exp mer $ d31 1 a31 1 RcsId("$Header: /users/mer/pg/src/lib/catalog/RCS/heap.c,v 1.14 1992/02/25 21:43:49 mer Exp mer $"); d60 1 d267 1 d490 2 d499 9 d538 3 d561 3 d575 5 @ 1.14 log @weren't allocating enough space for the reldesc, this one is a beaut! @ text @d22 1 a22 1 * $Header: /users/mer/pg/src/lib/catalog/RCS/heap.c,v 1.13 1991/11/14 15:01:25 jolly Exp mer $ d31 1 a31 1 RcsId("$Header: /users/mer/pg/src/lib/catalog/RCS/heap.c,v 1.13 1991/11/14 15:01:25 jolly Exp mer $"); d181 1 d224 1 d226 2 d229 1 d231 2 d234 1 d236 2 d239 1 d241 2 d266 8 @ 1.13 log @cleaned up for function prototyping @ text @d22 1 a22 1 * $Header: lib/catalog/RCS/heap.c,v 1.12 91/09/18 18:20:00 mer Exp Locker: jolly $ d31 1 a31 1 RcsId("$Header: lib/catalog/RCS/heap.c,v 1.12 91/09/18 18:20:00 mer Exp Locker: jolly $"); d243 1 a243 1 len += sizeof (IndexStrategy); @ 1.12 log @purge IsSystemRelation() from the system @ text @d22 1 a22 1 * $Header: /users/mer/postgres/src/lib/catalog/RCS/heap.c,v 1.11 1991/09/06 15:49:04 mer Exp mer $ d31 1 a31 1 RcsId("$Header: /users/mer/postgres/src/lib/catalog/RCS/heap.c,v 1.11 1991/09/06 15:49:04 mer Exp mer $"); d61 2 d187 1 a187 1 int issystem(); d189 1 a189 1 OID newoid(); d215 1 a215 1 oldcxt = MemoryContextSwitchTo(CacheCxt); d369 2 a370 1 if (NameIsEqual(HeapAtt[j]->attname, tupdesc[i]->attname)) { d384 2 a385 1 if (NameIsEqual(tupdesc[j]->attname, tupdesc[i]->attname)) { d407 1 a407 1 struct skey key; d415 5 a419 2 ScanKeyEntryInitialize(&key, 0, Anum_pg_relation_relname, F_CHAR16EQ, (DATUM) relname); a467 2 extern fillatt(); d481 1 a481 1 fillatt(natts, tupdesc); a555 2 extern fillatt(); d897 1 a897 1 struct skey key; d955 1 a955 1 struct skey key; d1027 2 a1028 2 struct skey key; struct skey attkey; d1131 1 a1131 1 char *relpath(); d1138 1 a1138 1 if (FileNameUnlink(relpath(&rdesc->rd_rel->relname)) < 0) d1153 1 a1153 1 int issystem(); d1168 1 a1168 1 if (issystem(RelationGetRelationName(rdesc)) || 0 /* is not owned etc. */) @ 1.11 log @disallow user classes beginning with pg_ @ text @d22 1 a22 1 * $Header: /users/mer/postgres/src/lib/catalog/RCS/heap.c,v 1.10 1991/08/14 22:08:13 mer Exp mer $ d31 1 a31 1 RcsId("$Header: /users/mer/postgres/src/lib/catalog/RCS/heap.c,v 1.10 1991/08/14 22:08:13 mer Exp mer $"); d1165 1 a1165 1 if (IsSystemRelation(rdesc) || 0 /* is not owned etc. */) @ 1.10 log @fix deadlock problems... set write locks and end scans sooner @ text @d22 1 a22 1 * $Header: /users/mer/postgres/src/lib/catalog/RCS/heap.c,v 1.9 91/08/14 12:42:46 mer Exp Locker: mer $ d31 1 a31 1 RcsId("$Header: /users/mer/postgres/src/lib/catalog/RCS/heap.c,v 1.9 91/08/14 12:42:46 mer Exp Locker: mer $"); d191 1 a191 1 * sanity check d196 7 @ 1.9 log @nix the write lock on pg_class since its locking is non2phase anyway also reorder the endscan on pg_type so as not to cause r->w upgrade of lock @ text @d22 1 a22 1 * $Header: RCS/heap.c,v 1.8 91/07/22 22:20:50 mao Exp Locker: kemnitz $ d31 1 a31 1 RcsId("$Header: RCS/heap.c,v 1.8 91/07/22 22:20:50 mao Exp Locker: kemnitz $"); d928 1 a930 1 amendscan(pg_relation_scan); d962 6 d990 6 d1158 1 a1158 1 if (issystem(&rdesc->rd_rel->relname) || 0 /* is not owned etc. */) @ 1.8 log @jukebox storage manager installation @ text @d22 1 a22 1 * $Header: /users/mao/postgres/src/lib/catalog/RCS/heap.c,v 1.7 1991/07/09 12:53:40 mer Exp mao $ d31 1 a31 1 RcsId("$Header: /users/mao/postgres/src/lib/catalog/RCS/heap.c,v 1.7 1991/07/09 12:53:40 mer Exp mao $"); a628 7 /* ---------------- * Set a write lock right at the start. This prevents upgrading * the lock from read to write and deadlock when running multi-user * ---------------- */ RelationSetLockForWrite(pg_relation_desc); d1089 2 a1090 1 * from pg_type and finish up. d1093 1 a1095 1 amendscan(pg_type_scan); @ 1.7 log @multi-user fix, set write lock just before create processing @ text @d22 1 a22 1 * $Header: lib/catalog/RCS/heap.c,v 1.6 91/07/03 00:44:57 mao Exp Locker: mer $ d31 1 a31 1 RcsId("$Header: lib/catalog/RCS/heap.c,v 1.6 91/07/03 00:44:57 mao Exp Locker: mer $"); d169 1 a169 1 heap_creatr(relname, natts, att) d172 1 d186 1 a186 1 File relopen(); /* XXX */ d195 1 a195 1 elog(WARN, "amcreatr(%s): called with 0 natts", relname); a227 41 * try and create the relation. * ---------------- */ fd = relopen(relname, O_RDWR|O_CREAT|O_EXCL, 0666); /* ---------------- * I don't understand this. -cim 6/14/90 * What's happening here is that if the file exists, but is empty, * then we assume that life is okay. If it's not empty, we abort. * The reason for this is that during bootstrap processing, it is * possible for the pg_log and pg_time files to get created before * we come across their create entries in the bki files. --mao 2 july 91 * ---------------- */ if (fd < 0) { char buf[4]; int n; fd = relopen(relname, O_RDWR, 0666); /* ---------------- * if we failed to create the relation, generate * an error. * ---------------- */ if (fd < 0) elog(WARN, "amcreatr(%s): %m", relname); /* ---------------- * check that the newly created file is empty. * ---------------- */ n = FileRead(fd, buf, 4); if (n != 0) { FileClose(fd); elog(WARN, "amcreatr: %s not zero size",relname); } } /* ---------------- d251 1 a251 1 strncpy((char *)&rdesc->rd_rel->relname, relname, 16); d254 1 a254 6 /* * relid should be 0 it is an unknown relation--assigned in amcreate() * Eventually, this will really be an unnamed file, and this should * be integrated with amcreate(). XXX */ d267 7 d598 1 a598 1 heap_create(relname, arch, natts, tupdesc) d602 1 d650 1 a650 1 new_rel_desc = amcreatr(relname, natts, tupdesc); @ 1.6 log @keep track of storage manager to be used @ text @d22 1 a22 1 * $Header: /users/mao/postgres/src/lib/catalog/RCS/heap.c,v 1.5 1991/05/01 02:50:33 cimarron Exp mao $ d31 1 a31 1 RcsId("$Header: /users/mao/postgres/src/lib/catalog/RCS/heap.c,v 1.5 1991/05/01 02:50:33 cimarron Exp mao $"); d665 7 @ 1.5 log @round II of converting simple functions to macros + code cleaning in general @ text @d22 1 a22 1 * $Header: RCS/heap.c,v 1.4 91/04/20 03:49:22 kemnitz Exp Locker: cimarron $ d31 1 a31 1 RcsId("$Header: RCS/heap.c,v 1.4 91/04/20 03:49:22 kemnitz Exp Locker: cimarron $"); d178 1 a178 1 d180 1 a180 1 d183 1 a183 1 d188 1 a188 1 d195 1 a195 1 d225 1 a225 1 d234 5 d262 1 a262 1 d266 1 a266 1 d289 1 a289 1 d313 1 a313 1 d467 1 a467 1 d487 1 a487 1 d509 1 a509 1 d515 1 a515 1 d581 1 a581 1 d583 1 a583 1 d588 1 a588 1 */ d590 1 a590 1 d617 1 a617 1 d619 1 a619 1 d621 1 a621 1 d624 1 a624 1 d647 1 a647 1 d670 1 a670 1 d682 1 a682 1 d725 1 a725 1 * d799 1 a799 1 d892 1 a892 1 d908 1 a908 1 d926 1 a926 1 d932 1 a932 1 d940 1 a940 1 d946 1 a946 1 d966 1 a966 1 d998 1 a998 1 d1004 1 a1004 1 d1047 1 a1047 1 d1053 1 a1053 1 d1061 1 a1061 1 d1067 1 a1067 1 d1092 1 a1092 1 d1095 1 a1095 1 d1101 1 a1101 1 d1123 1 a1123 1 d1130 1 a1130 1 d1154 1 a1154 1 @ 1.4 log @relations don't need typelem's. @ text @d22 1 a22 1 * $Header: RCS/heap.c,v 1.3 91/04/19 05:37:58 kemnitz Exp Locker: kemnitz $ d31 1 a31 1 RcsId("$Header: RCS/heap.c,v 1.3 91/04/19 05:37:58 kemnitz Exp Locker: kemnitz $"); a486 1 HeapTuple addtupleheader(); a576 1 HeapTuple addtupleheader(); @ 1.3 log @uses new scankey stuff @ text @d22 1 a22 1 * $Header: RCS/heap.c,v 1.2 91/03/26 17:22:19 kemnitz Exp Locker: kemnitz $ d31 1 a31 1 RcsId("$Header: RCS/heap.c,v 1.2 91/03/26 17:22:19 kemnitz Exp Locker: kemnitz $"); d695 1 a695 1 "char", /* array element type */ @ 1.2 log @calls TypeDefine with the new argument typdelim. @ text @d22 1 a22 1 * $Header: RCS/heap.c,v 1.1 91/02/06 19:01:32 cimarron Exp Locker: kemnitz $ d31 1 a31 1 RcsId("$Header: RCS/heap.c,v 1.1 91/02/06 19:01:32 cimarron Exp Locker: kemnitz $"); d437 2 a438 4 key.sk_flags = 0; key.sk_attnum = Anum_pg_relation_relname; key.sk_opr = F_CHAR16EQ; key.sk_data = (DATUM) relname; d793 3 a795 4 entry[0].flags = 0x0; entry[0].attributeNumber = InheritsParentAttributeNumber; entry[0].procedure = ObjectIdEqualRegProcedure; entry[0].argument = ObjectIdGetDatum(RelationGetRelationId(relation)); d886 3 a888 4 entry[0].flags = 0x0; entry[0].attributeNumber = IndexHeapRelationIdAttributeNumber; entry[0].procedure = ObjectIdEqualRegProcedure; entry[0].argument = ObjectIdGetDatum(RelationGetRelationId(relation)); d935 2 a936 4 key.sk_flags = NULL; key.sk_attnum = ObjectIdAttributeNumber; key.sk_opr = F_INT4EQ; key.sk_data = (DATUM) rdesc->rd_att.data[0]->attrelid; d993 2 a994 4 key.sk_flags = NULL; key.sk_attnum = Anum_pg_attribute_attrelid; key.sk_opr = F_INT4EQ; key.sk_data = (DATUM) rdesc->rd_att.data[0]->attrelid; d1056 2 a1057 4 key.sk_flags = NULL; key.sk_attnum = Anum_pg_type_typrelid; key.sk_opr = F_INT4EQ; key.sk_data = (DATUM) rdesc->rd_att.data[0]->attrelid; d1090 2 a1091 4 attkey.sk_flags = NULL; attkey.sk_attnum = Anum_pg_attribute_atttypid; attkey.sk_opr = F_INT4EQ; attkey.sk_data = (DATUM) typoid; @ 1.1 log @Initial revision @ text @d22 1 a22 1 * $Header$ d31 1 a31 1 RcsId("$Header: RCS/create.c,v 1.33 90/11/20 15:50:09 sp Exp $"); d692 1 @