1 /*-------------------------------------------------------------------------
4 * code to create and destroy POSTGRES heap relations
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.78 1999/05/10 00:44:54 momjian Exp $
14 * heap_create() - Create an uncataloged heap relation
15 * heap_create_with_catalog() - Create a cataloged relation
16 * heap_destroy_with_catalog() - Removes named relation from catalogs
19 * this code taken from access/heap/create.c, which contains
20 * the old heap_create_with_catalog, amcreate, and amdestroy.
21 * those routines will soon call these routines using the function
23 * just like the poorly named "NewXXX" routines do. The
24 * "New" routines are all going to die soon, once and for all!
27 *-------------------------------------------------------------------------
30 #include "miscadmin.h"
32 #include "access/heapam.h"
33 #include "catalog/catalog.h"
34 #include "catalog/catname.h"
35 #include "catalog/heap.h"
36 #include "catalog/index.h"
37 #include "catalog/indexing.h"
38 #include "catalog/pg_attrdef.h"
39 #include "catalog/pg_index.h"
40 #include "catalog/pg_inherits.h"
41 #include "catalog/pg_ipl.h"
42 #include "catalog/pg_relcheck.h"
43 #include "catalog/pg_type.h"
44 #include "commands/trigger.h"
46 #include "nodes/plannodes.h"
47 #include "optimizer/tlist.h"
48 #include "parser/parse_expr.h"
49 #include "parser/parse_node.h"
50 #include "parser/parse_type.h"
51 #include "parser/parse_coerce.h"
52 #include "rewrite/rewriteRemove.h"
53 #include "storage/bufmgr.h"
54 #include "storage/lmgr.h"
55 #include "storage/smgr.h"
56 #include "tcop/tcopprot.h"
57 #include "utils/catcache.h"
58 #include "utils/builtins.h"
59 #include "utils/mcxt.h"
60 #include "utils/relcache.h"
61 #include "utils/syscache.h"
62 #include "utils/tqual.h"
63 #include "utils/temprel.h"
66 #include <regex/utils.h>
71 static void AddNewRelationTuple(Relation pg_class_desc,
72 Relation new_rel_desc, Oid new_rel_oid, unsigned natts,
73 char relkind, char *temp_relname);
74 static void AddToNoNameRelList(Relation r);
75 static void DeleteAttributeTuples(Relation rel);
76 static void DeleteRelationTuple(Relation rel);
77 static void DeleteTypeTuple(Relation rel);
78 static void RelationRemoveIndexes(Relation relation);
79 static void RelationRemoveInheritance(Relation relation);
80 static void RemoveFromNoNameRelList(Relation r);
81 static void AddNewRelationType(char *typeName, Oid new_rel_oid);
82 static void StoreConstraints(Relation rel);
83 static void RemoveConstraints(Relation rel);
86 /* ----------------------------------------------------------------
87 * XXX UGLY HARD CODED BADNESS FOLLOWS XXX
89 * these should all be moved to someplace in the lib/catalog
90 * module, if not obliterated first.
91 * ----------------------------------------------------------------
97 * Should the executor special case these attributes in the future?
98 * Advantage: consume 1/2 the space in the ATTRIBUTE relation.
99 * Disadvantage: having rules to compute values in these tuples may
100 * be more difficult if not impossible.
103 static FormData_pg_attribute a1 = {
104 0xffffffff, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
105 SelfItemPointerAttributeNumber, 0, -1, -1, '\0', '\0', 'i', '\0', '\0'
108 static FormData_pg_attribute a2 = {
109 0xffffffff, {"oid"}, OIDOID, 0, sizeof(Oid),
110 ObjectIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
113 static FormData_pg_attribute a3 = {
114 0xffffffff, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
115 MinTransactionIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
118 static FormData_pg_attribute a4 = {
119 0xffffffff, {"cmin"}, CIDOID, 0, sizeof(CommandId),
120 MinCommandIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
123 static FormData_pg_attribute a5 = {
124 0xffffffff, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
125 MaxTransactionIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
128 static FormData_pg_attribute a6 = {
129 0xffffffff, {"cmax"}, CIDOID, 0, sizeof(CommandId),
130 MaxCommandIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
133 static Form_pg_attribute HeapAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6};
135 /* ----------------------------------------------------------------
136 * XXX END OF UGLY HARD CODED BADNESS XXX
137 * ----------------------------------------------------------------
140 /* the tempRelList holds
141 the list of temporary uncatalogued relations that are created.
142 these relations should be destroyed at the end of transactions
144 typedef struct tempRelList
146 Relation *rels; /* array of relation descriptors */
147 int num; /* number of temporary relations */
148 int size; /* size of space allocated for the rels
152 #define NONAME_REL_LIST_SIZE 32
154 static TempRelList *tempRels = NULL;
157 /* ----------------------------------------------------------------
158 * heap_create - Create an uncataloged heap relation
160 * Fields relpages, reltuples, reltuples, relkeys, relhistory,
161 * relisindexed, and relkind of rel->rd_rel are initialized
162 * to all zeros, as are rd_last and rd_hook. Rd_refcnt is set to 1.
164 * Remove the system relation specific code to elsewhere eventually.
166 * Eventually, must place information about this temporary relation
167 * into the transaction context block.
170 * if heap_create is called with "" as the name, then heap_create will create
171 * a temporary name "pg_noname.$PID.$SEQUENCE" for the relation
172 * ----------------------------------------------------------------
175 heap_create(char *relname,
185 int natts = tupDesc->natts;
186 static unsigned int uniqueId = 0;
188 extern GlobalMemory CacheCxt;
189 MemoryContext oldcxt;
196 AssertArg(natts > 0);
198 if (relname && !allowSystemTableMods && IsSystemRelationName(relname) && IsNormalProcessingMode())
200 elog(ERROR, "Illegal class name '%s'"
201 "\n\tThe 'pg_' name prefix is reserved for system catalogs",
206 * switch to the cache context so that we don't lose
207 * allocations at the end of this transaction, I guess.
212 CacheCxt = CreateGlobalMemory("Cache");
214 oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
217 * real ugly stuff to assign the proper relid in the relation
218 * descriptor follows.
221 if (relname && !strcmp(RelationRelationName, relname))
223 relid = RelOid_pg_class;
226 else if (relname && !strcmp(AttributeRelationName, relname))
228 relid = RelOid_pg_attribute;
231 else if (relname && !strcmp(ProcedureRelationName, relname))
233 relid = RelOid_pg_proc;
236 else if (relname && !strcmp(TypeRelationName, relname))
238 relid = RelOid_pg_type;
249 relname = palloc(NAMEDATALEN);
250 snprintf(relname, NAMEDATALEN, "pg_noname.%d.%u",
251 (int) MyProcPid, uniqueId++);
256 /* replace relname of caller */
257 snprintf(relname, NAMEDATALEN, "pg_temp.%d.%u",
258 (int) MyProcPid, uniqueId++);
262 * allocate a new relation descriptor.
264 * XXX the length computation may be incorrect, handle elsewhere
267 len = sizeof(RelationData);
269 rel = (Relation) palloc(len);
270 MemSet((char *) rel, 0, len);
273 * create a new tuple descriptor from the one passed in
275 rel->rd_att = CreateTupleDescCopyConstr(tupDesc);
278 * nail the reldesc if this is a bootstrap create reln and
279 * we may need it in the cache later on in the bootstrap
280 * process so we don't ever want it kicked out. e.g. pg_attribute!!!
284 rel->rd_isnailed = true;
286 RelationSetReferenceCount(rel, 1);
288 rel->rd_rel = (Form_pg_class) palloc(sizeof *rel->rd_rel);
291 * initialize the fields of our new relation descriptor
294 MemSet((char *) rel->rd_rel, 0, sizeof *rel->rd_rel);
295 namestrcpy(&(rel->rd_rel->relname), relname);
296 rel->rd_rel->relkind = RELKIND_UNCATALOGED;
297 rel->rd_rel->relnatts = natts;
299 rel->rd_rel->relchecks = tupDesc->constr->num_check;
301 for (i = 0; i < natts; i++)
302 rel->rd_att->attrs[i]->attrelid = relid;
304 RelationGetRelid(rel) = relid;
308 /* for system relations, set the reltype field here */
309 rel->rd_rel->reltype = relid;
313 * remember if this is a noname relation
316 rel->rd_isnoname = isnoname;
319 * have the storage manager create the relation.
323 rel->rd_nonameunlinked = TRUE; /* change once table is created */
324 rel->rd_fd = (File) smgrcreate(DEFAULT_SMGR, rel);
325 rel->rd_nonameunlinked = FALSE;
327 RelationRegisterRelation(rel);
329 MemoryContextSwitchTo(oldcxt);
332 * add all noname relations to the tempRels list so they can be
333 * properly disposed of at the end of transaction
336 AddToNoNameRelList(rel);
342 /* ----------------------------------------------------------------
343 * heap_create_with_catalog - Create a cataloged relation
345 * this is done in 6 steps:
347 * 1) CheckAttributeNames() is used to make certain the tuple
348 * descriptor contains a valid set of attribute names
350 * 2) pg_class is opened and RelationFindRelid()
351 * preforms a scan to ensure that no relation with the
352 * same name already exists.
354 * 3) heap_create_with_catalog() is called to create the new relation
357 * 4) TypeDefine() is called to define a new type corresponding
358 * to the new relation.
360 * 5) AddNewAttributeTuples() is called to register the
361 * new relation's schema in pg_attribute.
363 * 6) AddNewRelationTuple() is called to register the
364 * relation itself in the catalogs.
366 * 7) StoreConstraints is called () - vadim 08/22/97
368 * 8) the relations are closed and the new relation's oid
372 * A new relation is inserted into the RELATION relation
373 * with the specified attribute(s) (newly inserted into
374 * the ATTRIBUTE relation). How does concurrency control
375 * work? Is it automatic now? Expects the caller to have
376 * attname, atttypid, atttyparg, attproc, and attlen domains filled.
377 * Create fills the attnum domains sequentually from zero,
378 * fills the attdisbursion domains with zeros, and fills the
379 * attrelid fields with the relid.
381 * scan relation catalog for name conflict
382 * scan type catalog for typids (if not arg)
383 * create and insert attribute(s) into attribute catalog
384 * create new relation
385 * insert new relation into attribute catalog
387 * Should coordinate with heap_create_with_catalog(). Either
388 * it should not be called or there should be a way to prevent
389 * the relation from being removed at the end of the
390 * transaction if it is successful ('u'/'r' may be enough).
391 * Also, if the transaction does not commit, then the
392 * relation should be removed.
394 * XXX amcreate ignores "off" when inserting (for now).
395 * XXX amcreate (like the other utilities) needs to understand indexes.
397 * ----------------------------------------------------------------
400 /* --------------------------------
401 * CheckAttributeNames
403 * this is used to make certain the tuple descriptor contains a
404 * valid set of attribute names. a problem simply generates
405 * elog(ERROR) which aborts the current transaction.
406 * --------------------------------
409 CheckAttributeNames(TupleDesc tupdesc)
413 int natts = tupdesc->natts;
416 * first check for collision with system attribute names
419 * also, warn user if attribute to be created has
420 * an unknown typid (usually as a result of a 'retrieve into'
423 for (i = 0; i < natts; i += 1)
425 for (j = 0; j < sizeof HeapAtt / sizeof HeapAtt[0]; j += 1)
427 if (nameeq(&(HeapAtt[j]->attname),
428 &(tupdesc->attrs[i]->attname)))
430 elog(ERROR, "Attribute '%s' has a name conflict"
431 "\n\tName matches an existing system attribute",
432 HeapAtt[j]->attname.data);
435 if (tupdesc->attrs[i]->atttypid == UNKNOWNOID)
437 elog(NOTICE, "Attribute '%s' has an unknown type"
438 "\n\tRelation created; continue",
439 tupdesc->attrs[i]->attname.data);
444 * next check for repeated attribute names
447 for (i = 1; i < natts; i += 1)
449 for (j = 0; j < i; j += 1)
451 if (nameeq(&(tupdesc->attrs[j]->attname),
452 &(tupdesc->attrs[i]->attname)))
454 elog(ERROR, "Attribute '%s' is repeated",
455 tupdesc->attrs[j]->attname.data);
461 /* --------------------------------
464 * this preforms a scan of pg_class to ensure that
465 * no relation with the same name already exists.
466 * --------------------------------
469 RelnameFindRelid(char *relname)
475 * If this is not bootstrap (initdb) time, use the catalog index on
478 if (!IsBootstrapProcessingMode())
480 tuple = SearchSysCacheTuple(RELNAME,
481 PointerGetDatum(relname),
483 if (HeapTupleIsValid(tuple))
484 relid = tuple->t_data->t_oid;
490 Relation pg_class_desc;
492 HeapScanDesc pg_class_scan;
494 pg_class_desc = heap_openr(RelationRelationName);
497 * At bootstrap time, we have to do this the hard way. Form the
501 ScanKeyEntryInitialize(&key,
503 (AttrNumber) Anum_pg_class_relname,
504 (RegProcedure) F_NAMEEQ,
511 pg_class_scan = heap_beginscan(pg_class_desc,
518 * get a tuple. if the tuple is NULL then it means we
519 * didn't find an existing relation.
522 tuple = heap_getnext(pg_class_scan, 0);
524 if (HeapTupleIsValid(tuple))
525 relid = tuple->t_data->t_oid;
529 heap_endscan(pg_class_scan);
531 heap_close(pg_class_desc);
536 /* --------------------------------
537 * AddNewAttributeTuples
539 * this registers the new relation's schema by adding
540 * tuples to pg_attribute.
541 * --------------------------------
544 AddNewAttributeTuples(Oid new_rel_oid,
547 Form_pg_attribute *dpp;
552 Relation idescs[Num_pg_attr_indices];
553 int natts = tupdesc->natts;
559 rel = heap_openr(AttributeRelationName);
562 * Check if we have any indices defined on pg_attribute.
567 hasindex = RelationGetForm(rel)->relhasindex;
569 CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
572 * initialize tuple descriptor. Note we use setheapoverride()
573 * so that we can see the effects of our TypeDefine() done
577 setheapoverride(true);
579 setheapoverride(false);
582 * first we add the user attributes..
585 dpp = tupdesc->attrs;
586 for (i = 0; i < natts; i++)
588 (*dpp)->attrelid = new_rel_oid;
589 (*dpp)->attdisbursion = 0;
591 tup = heap_addheader(Natts_pg_attribute,
592 ATTRIBUTE_TUPLE_SIZE,
595 heap_insert(rel, tup);
598 CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
605 * next we add the system attributes..
609 for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)
611 (*dpp)->attrelid = new_rel_oid;
612 /* (*dpp)->attdisbursion = 0; unneeded */
614 tup = heap_addheader(Natts_pg_attribute,
615 ATTRIBUTE_TUPLE_SIZE,
618 heap_insert(rel, tup);
621 CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
630 * close pg_attribute indices
633 CatalogCloseIndices(Num_pg_attr_indices, idescs);
636 /* --------------------------------
637 * AddNewRelationTuple
639 * this registers the new relation in the catalogs by
640 * adding a tuple to pg_class.
641 * --------------------------------
644 AddNewRelationTuple(Relation pg_class_desc,
645 Relation new_rel_desc,
651 Form_pg_class new_rel_reltup;
653 Relation idescs[Num_pg_class_indices];
657 * first we munge some of the information in our
658 * uncataloged relation's relation descriptor.
661 new_rel_reltup = new_rel_desc->rd_rel;
663 /* CHECK should get new_rel_oid first via an insert then use XXX */
666 * Here we insert bogus estimates of the size of the new relation.
667 * In reality, of course, the new relation has 0 tuples and pages,
668 * and if we were tracking these statistics accurately then we'd
669 * set the fields that way. But at present the stats will be updated
670 * only by VACUUM or CREATE INDEX, and the user might insert a lot of
671 * tuples before he gets around to doing either of those. So, instead
672 * of saying the relation is empty, we insert guesstimates. The point
673 * is to keep the optimizer from making really stupid choices on
674 * never-yet-vacuumed tables; so the estimates need only be large
675 * enough to discourage the optimizer from using nested-loop plans.
676 * With this hack, nested-loop plans will be preferred only after
677 * the table has been proven to be small by VACUUM or CREATE INDEX.
678 * (NOTE: if user does CREATE TABLE, then CREATE INDEX, then loads
679 * the table, he still loses until he vacuums, because CREATE INDEX
680 * will set reltuples to zero. Can't win 'em all. Maintaining the
681 * stats on-the-fly would solve the problem, but the overhead of that
682 * would likely cost more than it'd save.)
685 new_rel_reltup->relpages = 10; /* bogus estimates */
686 new_rel_reltup->reltuples = 1000;
688 new_rel_reltup->relowner = GetUserId();
689 new_rel_reltup->relkind = relkind;
690 new_rel_reltup->relnatts = natts;
693 * now form a tuple to add to pg_class
694 * XXX Natts_pg_class_fixed is a hack - see pg_class.h
697 tup = heap_addheader(Natts_pg_class_fixed,
699 (char *) new_rel_reltup);
700 tup->t_data->t_oid = new_rel_oid;
703 * finally insert the new tuple and free it.
705 * Note: I have no idea why we do a
706 * SetProcessingMode(BootstrapProcessing);
710 isBootstrap = IsBootstrapProcessingMode() ? true : false;
712 SetProcessingMode(BootstrapProcessing);
714 heap_insert(pg_class_desc, tup);
717 create_temp_relation(temp_relname, tup);
722 * First, open the catalog indices and insert index tuples for the
726 CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
727 CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class_desc, tup);
728 CatalogCloseIndices(Num_pg_class_indices, idescs);
729 /* now restore processing mode */
730 SetProcessingMode(NormalProcessing);
737 /* --------------------------------
738 * AddNewRelationType -
740 * define a complex type corresponding to the new relation
741 * --------------------------------
744 AddNewRelationType(char *typeName, Oid new_rel_oid)
749 * The sizes are set to oid size because it makes implementing sets
750 * MUCH easier, and no one (we hope) uses these fields to figure out
751 * how much space to allocate for the type. An oid is the type used
752 * for a set definition. When a user requests a set, what they
753 * actually get is the oid of a tuple in the pg_proc catalog, so the
754 * size of the "set" is the size of an oid. Similarly, byval being
755 * true makes sets much easier, and it isn't used by anything else.
756 * Note the assumption that OIDs are the same size as int4s.
758 new_type_oid = TypeCreate(typeName, /* type name */
759 new_rel_oid, /* relation oid */
760 typeLen(typeidType(OIDOID)), /* internal size */
761 typeLen(typeidType(OIDOID)), /* external size */
762 'c', /* type-type (catalog) */
763 ',', /* default array delimiter */
764 "oidin", /* input procedure */
765 "oidout", /* output procedure */
766 "oidin", /* receive procedure */
767 "oidout", /* send procedure */
768 NULL, /* array element type - irrelevent */
769 "-", /* default type value */
770 (bool) 1, /* passed by value */
771 'i'); /* default alignment */
774 /* --------------------------------
775 * heap_create_with_catalog
777 * creates a new cataloged relation. see comments above.
778 * --------------------------------
781 heap_create_with_catalog(char *relname,
786 Relation pg_class_desc;
787 Relation new_rel_desc;
789 int natts = tupdesc->natts;
790 char *temp_relname = NULL;
796 Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode());
797 if (natts == 0 || natts > MaxHeapAttributeNumber)
798 elog(ERROR, "Number of attributes is out of range"
799 "\n\tFrom 1 to %d attributes may be specified",
800 MaxHeapAttributeNumber);
802 CheckAttributeNames(tupdesc);
804 /* temp tables can mask non-temp tables */
805 if ((!istemp && RelnameFindRelid(relname)) ||
806 (istemp && get_temp_rel_by_name(relname) != NULL))
807 elog(ERROR, "Relation '%s' already exists", relname);
809 /* invalidate cache so non-temp table is masked by temp */
812 Oid relid = RelnameFindRelid(relname);
814 if (relid != InvalidOid)
817 * This is heavy-handed, but appears necessary bjm 1999/02/01
818 * SystemCacheRelationFlushed(relid) is not enough either.
820 RelationForgetRelation(relid);
825 /* save user relation name because heap_create changes it */
828 temp_relname = pstrdup(relname); /* save original value */
829 relname = palloc(NAMEDATALEN);
830 strcpy(relname, temp_relname); /* heap_create will change this */
834 * ok, relation does not already exist so now we
835 * create an uncataloged relation and pull its relation oid
836 * from the newly formed relation descriptor.
838 * Note: The call to heap_create() does all the "real" work
839 * of creating the disk file for the relation.
840 * This changes relname for noname and temp tables.
843 new_rel_desc = heap_create(relname, tupdesc, false, istemp);
845 new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
848 * since defining a relation also defines a complex type,
849 * we add a new system type corresponding to the new relation.
852 AddNewRelationType(relname, new_rel_oid);
855 * now add tuples to pg_attribute for the attributes in
859 AddNewAttributeTuples(new_rel_oid, tupdesc);
862 * now update the information in pg_class.
865 pg_class_desc = heap_openr(RelationRelationName);
867 AddNewRelationTuple(pg_class_desc,
874 StoreConstraints(new_rel_desc);
883 * ok, the relation has been cataloged, so close our relations
884 * and return the oid of the newly created relation.
886 * SOMEDAY: fill the STATISTIC relation properly.
889 heap_close(new_rel_desc);
890 heap_close(pg_class_desc);
896 /* ----------------------------------------------------------------
897 * heap_destroy_with_catalog - removes all record of named relation from catalogs
899 * 1) open relation, check for existence, etc.
900 * 2) remove inheritance information
902 * 4) remove pg_class tuple
903 * 5) remove pg_attribute tuples
904 * 6) remove pg_type tuples
905 * 7) RemoveConstraints ()
909 * Except for vital relations, removes relation from
910 * relation catalog, and related attributes from
911 * attribute catalog (needed?). (Anything else?)
913 * get proper relation from relation catalog (if not arg)
914 * check if relation is vital (strcmp()/reltype?)
915 * scan attribute catalog deleting attributes of reldesc
917 * delete relation from relation catalog
918 * (How are the tuples of the relation discarded?)
920 * XXX Must fix to work with indexes.
921 * There may be a better order for doing things.
922 * Problems with destroying a deleted database--cannot create
923 * a struct reldesc without having an open file descriptor.
924 * ----------------------------------------------------------------
927 /* --------------------------------
928 * RelationRemoveInheritance
930 * Note: for now, we cause an exception if relation is a
931 * superclass. Someday, we may want to allow this and merge
932 * the type info into subclass procedures.... this seems like
934 * --------------------------------
937 RelationRemoveInheritance(Relation relation)
939 Relation catalogRelation;
949 catalogRelation = heap_openr(InheritsRelationName);
952 * form a scan key for the subclasses of this class
956 ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_inherits_inhparent,
958 ObjectIdGetDatum(RelationGetRelid(relation)));
960 scan = heap_beginscan(catalogRelation,
967 * if any subclasses exist, then we disallow the deletion.
970 tuple = heap_getnext(scan, 0);
971 if (HeapTupleIsValid(tuple))
974 heap_close(catalogRelation);
976 elog(ERROR, "Relation '%u' inherits '%s'",
977 ((Form_pg_inherits) GETSTRUCT(tuple))->inhrel,
978 RelationGetRelationName(relation));
982 * If we get here, it means the relation has no subclasses
983 * so we can trash it. First we remove dead INHERITS tuples.
986 entry.sk_attno = Anum_pg_inherits_inhrel;
988 scan = heap_beginscan(catalogRelation,
994 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
996 heap_delete(catalogRelation, &tuple->t_self, NULL);
1001 heap_close(catalogRelation);
1004 * now remove dead IPL tuples
1007 catalogRelation = heap_openr(InheritancePrecidenceListRelationName);
1009 entry.sk_attno = Anum_pg_ipl_iplrel;
1011 scan = heap_beginscan(catalogRelation,
1017 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
1018 heap_delete(catalogRelation, &tuple->t_self, NULL);
1021 heap_close(catalogRelation);
1024 /* --------------------------------
1025 * RelationRemoveIndexes
1027 * --------------------------------
1030 RelationRemoveIndexes(Relation relation)
1032 Relation indexRelation;
1037 indexRelation = heap_openr(IndexRelationName);
1039 ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_index_indrelid,
1041 ObjectIdGetDatum(RelationGetRelid(relation)));
1043 scan = heap_beginscan(indexRelation,
1049 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
1050 index_destroy(((Form_pg_index) GETSTRUCT(tuple))->indexrelid);
1053 heap_close(indexRelation);
1056 /* --------------------------------
1057 * DeleteRelationTuple
1059 * --------------------------------
1062 DeleteRelationTuple(Relation rel)
1064 Relation pg_class_desc;
1071 pg_class_desc = heap_openr(RelationRelationName);
1073 tup = SearchSysCacheTupleCopy(RELOID,
1074 ObjectIdGetDatum(rel->rd_att->attrs[0]->attrelid),
1076 if (!HeapTupleIsValid(tup))
1078 heap_close(pg_class_desc);
1079 elog(ERROR, "Relation '%s' does not exist",
1080 &rel->rd_rel->relname);
1084 * delete the relation tuple from pg_class, and finish up.
1087 heap_delete(pg_class_desc, &tup->t_self, NULL);
1090 heap_close(pg_class_desc);
1093 /* --------------------------------
1094 * DeleteAttributeTuples
1096 * --------------------------------
1099 DeleteAttributeTuples(Relation rel)
1101 Relation pg_attribute_desc;
1109 pg_attribute_desc = heap_openr(AttributeRelationName);
1111 /* -----------------
1112 * Get a write lock _before_ getting the read lock in the scan
1115 LockRelation(pg_attribute_desc, AccessExclusiveLock);
1117 for (attnum = FirstLowInvalidHeapAttributeNumber + 1;
1118 attnum <= rel->rd_att->natts;
1121 if (HeapTupleIsValid(tup = SearchSysCacheTupleCopy(ATTNUM,
1122 ObjectIdGetDatum(RelationGetRelid(rel)),
1123 Int16GetDatum(attnum),
1126 heap_delete(pg_attribute_desc, &tup->t_self, NULL);
1132 * Release the write lock
1135 UnlockRelation(pg_attribute_desc, AccessExclusiveLock);
1136 heap_close(pg_attribute_desc);
1139 /* --------------------------------
1142 * If the user attempts to destroy a relation and there
1143 * exists attributes in other relations of type
1144 * "relation we are deleting", then we have to do something
1145 * special. presently we disallow the destroy.
1146 * --------------------------------
1149 DeleteTypeTuple(Relation rel)
1151 Relation pg_type_desc;
1152 HeapScanDesc pg_type_scan;
1153 Relation pg_attribute_desc;
1154 HeapScanDesc pg_attribute_scan;
1165 pg_type_desc = heap_openr(TypeRelationName);
1168 * create a scan key to locate the type tuple corresponding
1172 ScanKeyEntryInitialize(&key, 0,
1173 Anum_pg_type_typrelid,
1175 ObjectIdGetDatum(RelationGetRelid(rel)));
1177 pg_type_scan = heap_beginscan(pg_type_desc,
1184 * use heap_getnext() to fetch the pg_type tuple. If this
1185 * tuple is not valid then something's wrong.
1188 tup = heap_getnext(pg_type_scan, 0);
1190 if (!HeapTupleIsValid(tup))
1192 heap_endscan(pg_type_scan);
1193 heap_close(pg_type_desc);
1194 elog(ERROR, "DeleteTypeTuple: %s type nonexistent",
1195 &rel->rd_rel->relname);
1199 * now scan pg_attribute. if any other relations have
1200 * attributes of the type of the relation we are deleteing
1201 * then we have to disallow the deletion. should talk to
1202 * stonebraker about this. -cim 6/19/90
1205 typoid = tup->t_data->t_oid;
1207 pg_attribute_desc = heap_openr(AttributeRelationName);
1209 ScanKeyEntryInitialize(&attkey,
1211 Anum_pg_attribute_atttypid,
1215 pg_attribute_scan = heap_beginscan(pg_attribute_desc,
1222 * try and get a pg_attribute tuple. if we succeed it means
1223 * we can't delete the relation because something depends on
1227 atttup = heap_getnext(pg_attribute_scan, 0);
1229 if (HeapTupleIsValid(atttup))
1231 Oid relid = ((Form_pg_attribute) GETSTRUCT(atttup))->attrelid;
1233 heap_endscan(pg_type_scan);
1234 heap_close(pg_type_desc);
1235 heap_endscan(pg_attribute_scan);
1236 heap_close(pg_attribute_desc);
1238 elog(ERROR, "DeleteTypeTuple: att of type %s exists in relation %u",
1239 &rel->rd_rel->relname, relid);
1241 heap_endscan(pg_attribute_scan);
1242 heap_close(pg_attribute_desc);
1245 * Ok, it's safe so we delete the relation tuple
1246 * from pg_type and finish up. But first end the scan so that
1247 * we release the read lock on pg_type. -mer 13 Aug 1991
1250 heap_delete(pg_type_desc, &tup->t_self, NULL);
1252 heap_endscan(pg_type_scan);
1253 heap_close(pg_type_desc);
1256 /* --------------------------------
1257 * heap_destroy_with_catalog
1259 * --------------------------------
1262 heap_destroy_with_catalog(char *relname)
1266 bool istemp = (get_temp_rel_by_name(relname) != NULL);
1269 * first open the relation. if the relation does exist,
1270 * heap_openr() returns NULL.
1273 rel = heap_openr(relname);
1275 elog(ERROR, "Relation '%s' does not exist", relname);
1277 LockRelation(rel, AccessExclusiveLock);
1281 * prevent deletion of system relations
1284 /* allow temp of pg_class? Guess so. */
1286 !allowSystemTableMods && IsSystemRelationName(RelationGetRelationName(rel)->data))
1287 elog(ERROR, "System relation '%s' cannot be destroyed",
1288 &rel->rd_rel->relname);
1291 * remove inheritance information
1294 RelationRemoveInheritance(rel);
1297 * remove indexes if necessary
1300 if (rel->rd_rel->relhasindex)
1301 RelationRemoveIndexes(rel);
1304 * remove rules if necessary
1307 if (rel->rd_rules != NULL)
1308 RelationRemoveRules(rid);
1311 if (rel->rd_rel->reltriggers > 0)
1312 RelationRemoveTriggers(rel);
1315 * delete attribute tuples
1318 DeleteAttributeTuples(rel);
1321 remove_temp_relation(rid);
1324 * delete type tuple. here we want to see the effects
1325 * of the deletions we just did, so we use setheapoverride().
1328 setheapoverride(true);
1329 DeleteTypeTuple(rel);
1330 setheapoverride(false);
1333 * delete relation tuple
1336 /* must delete fake tuple in cache */
1337 DeleteRelationTuple(rel);
1340 * release dirty buffers of this relation
1342 ReleaseRelationBuffers(rel);
1345 * flush the relation from the relcache
1347 * Does nothing!!! Flushing moved below. - vadim 06/04/97
1348 RelationIdInvalidateRelationCacheByRelationId(rel->rd_id);
1351 RemoveConstraints(rel);
1354 * unlink the relation and finish up.
1357 if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked))
1358 smgrunlink(DEFAULT_SMGR, rel);
1360 rel->rd_nonameunlinked = TRUE;
1362 UnlockRelation(rel, AccessExclusiveLock);
1366 RelationForgetRelation(rid);
1371 * destroy and close temporary relations
1376 heap_destroy(Relation rel)
1378 ReleaseRelationBuffers(rel);
1379 if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked))
1380 smgrunlink(DEFAULT_SMGR, rel);
1381 rel->rd_nonameunlinked = TRUE;
1383 RemoveFromNoNameRelList(rel);
1387 /**************************************************************
1388 functions to deal with the list of temporary relations
1389 **************************************************************/
1394 initialize temporary relations list
1395 the tempRelList is a list of temporary relations that
1396 are created in the course of the transactions
1397 they need to be destroyed properly at the end of the transactions
1399 MODIFIES the global variable tempRels
1403 malloc is used instead of palloc because we KNOW when we are
1404 going to free these things. Keeps us away from the memory context
1409 InitNoNameRelList(void)
1413 free(tempRels->rels);
1417 tempRels = (TempRelList *) malloc(sizeof(TempRelList));
1418 tempRels->size = NONAME_REL_LIST_SIZE;
1419 tempRels->rels = (Relation *) malloc(sizeof(Relation) * tempRels->size);
1420 MemSet(tempRels->rels, 0, sizeof(Relation) * tempRels->size);
1425 removes a relation from the TempRelList
1427 MODIFIES the global variable tempRels
1428 we don't really remove it, just mark it as NULL
1429 and DestroyNoNameRels will look for NULLs
1432 RemoveFromNoNameRelList(Relation r)
1439 for (i = 0; i < tempRels->num; i++)
1441 if (tempRels->rels[i] == r)
1443 tempRels->rels[i] = NULL;
1450 add a temporary relation to the TempRelList
1452 MODIFIES the global variable tempRels
1455 AddToNoNameRelList(Relation r)
1460 if (tempRels->num == tempRels->size)
1462 tempRels->size += NONAME_REL_LIST_SIZE;
1463 tempRels->rels = realloc(tempRels->rels,
1464 sizeof(Relation) * tempRels->size);
1466 tempRels->rels[tempRels->num] = r;
1471 go through the tempRels list and destroy each of the relations
1474 DestroyNoNameRels(void)
1482 for (i = 0; i < tempRels->num; i++)
1484 rel = tempRels->rels[i];
1485 /* rel may be NULL if it has been removed from the list already */
1489 free(tempRels->rels);
1496 StoreAttrDefault(Relation rel, AttrDefault *attrdef)
1498 char str[MAX_PARSE_BUFFER];
1499 char cast[2 * NAMEDATALEN] = {0};
1500 Form_pg_attribute atp = rel->rd_att->attrs[attrdef->adnum - 1];
1501 QueryTreeList *queryTree_list;
1503 List *planTree_list;
1509 MemoryContext oldcxt;
1511 Relation idescs[Num_pg_attrdef_indices];
1514 char nulls[4] = {' ', ' ', ' ', ' '};
1515 extern GlobalMemory CacheCxt;
1518 /* Surround table name with double quotes to allow mixed-case and
1519 * whitespaces in names. - BGA 1998-11-14
1521 snprintf(str, MAX_PARSE_BUFFER,
1522 "select %s%s from \"%.*s\"", attrdef->adsrc, cast,
1523 NAMEDATALEN, rel->rd_rel->relname.data);
1524 setheapoverride(true);
1525 planTree_list = (List *) pg_parse_and_plan(str, NULL, 0, &queryTree_list, None, FALSE);
1526 setheapoverride(false);
1527 query = (Query *) (queryTree_list->qtrees[0]);
1529 if (length(query->rtable) > 1 ||
1530 flatten_tlist(query->targetList) != NIL)
1531 elog(ERROR, "Cannot use attribute(s) in DEFAULT clause");
1532 te = (TargetEntry *) lfirst(query->targetList);
1533 resdom = te->resdom;
1535 type = exprType(expr);
1537 if (type != atp->atttypid)
1539 if (IS_BINARY_COMPATIBLE(type, atp->atttypid))
1540 ; /* use without change */
1541 else if (can_coerce_type(1, &(type), &(atp->atttypid)))
1542 expr = coerce_type(NULL, (Node *)expr, type, atp->atttypid);
1543 else if (IsA(expr, Const))
1546 elog(ERROR, "DEFAULT clause const type '%s' mismatched with column type '%s'",
1547 typeidTypeName(type), typeidTypeName(atp->atttypid));
1548 snprintf(cast, 2*NAMEDATALEN, ":: %s", typeidTypeName(atp->atttypid));
1552 elog(ERROR, "DEFAULT clause type '%s' mismatched with column type '%s'",
1553 typeidTypeName(type), typeidTypeName(atp->atttypid));
1556 adbin = nodeToString(expr);
1557 oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
1558 attrdef->adbin = (char *) palloc(strlen(adbin) + 1);
1559 strcpy(attrdef->adbin, adbin);
1560 (void) MemoryContextSwitchTo(oldcxt);
1563 values[Anum_pg_attrdef_adrelid - 1] = rel->rd_id;
1564 values[Anum_pg_attrdef_adnum - 1] = attrdef->adnum;
1565 values[Anum_pg_attrdef_adbin - 1] = PointerGetDatum(textin(attrdef->adbin));
1566 values[Anum_pg_attrdef_adsrc - 1] = PointerGetDatum(textin(attrdef->adsrc));
1567 adrel = heap_openr(AttrDefaultRelationName);
1568 tuple = heap_formtuple(adrel->rd_att, values, nulls);
1569 CatalogOpenIndices(Num_pg_attrdef_indices, Name_pg_attrdef_indices, idescs);
1570 heap_insert(adrel, tuple);
1571 CatalogIndexInsert(idescs, Num_pg_attrdef_indices, adrel, tuple);
1572 CatalogCloseIndices(Num_pg_attrdef_indices, idescs);
1575 pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
1576 pfree(DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
1582 StoreRelCheck(Relation rel, ConstrCheck *check)
1584 char str[MAX_PARSE_BUFFER];
1585 QueryTreeList *queryTree_list;
1587 List *planTree_list;
1591 MemoryContext oldcxt;
1593 Relation idescs[Num_pg_relcheck_indices];
1596 char nulls[4] = {' ', ' ', ' ', ' '};
1597 extern GlobalMemory CacheCxt;
1599 /* Check for table's existance. Surround table name with double-quotes
1600 * to allow mixed-case and whitespace names. - thomas 1998-11-12
1602 snprintf(str, MAX_PARSE_BUFFER,
1603 "select 1 from \"%.*s\" where %s",
1604 NAMEDATALEN, rel->rd_rel->relname.data, check->ccsrc);
1605 setheapoverride(true);
1606 planTree_list = (List *) pg_parse_and_plan(str, NULL, 0, &queryTree_list, None, FALSE);
1607 setheapoverride(false);
1608 query = (Query *) (queryTree_list->qtrees[0]);
1610 if (length(query->rtable) > 1)
1611 elog(ERROR, "Only relation '%.*s' can be referenced",
1612 NAMEDATALEN, rel->rd_rel->relname.data);
1614 plan = (Plan *) lfirst(planTree_list);
1617 ccbin = nodeToString(qual);
1618 oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
1619 check->ccbin = (char *) palloc(strlen(ccbin) + 1);
1620 strcpy(check->ccbin, ccbin);
1621 (void) MemoryContextSwitchTo(oldcxt);
1624 values[Anum_pg_relcheck_rcrelid - 1] = rel->rd_id;
1625 values[Anum_pg_relcheck_rcname - 1] = PointerGetDatum(namein(check->ccname));
1626 values[Anum_pg_relcheck_rcbin - 1] = PointerGetDatum(textin(check->ccbin));
1627 values[Anum_pg_relcheck_rcsrc - 1] = PointerGetDatum(textin(check->ccsrc));
1628 rcrel = heap_openr(RelCheckRelationName);
1629 tuple = heap_formtuple(rcrel->rd_att, values, nulls);
1630 CatalogOpenIndices(Num_pg_relcheck_indices, Name_pg_relcheck_indices, idescs);
1631 heap_insert(rcrel, tuple);
1632 CatalogIndexInsert(idescs, Num_pg_relcheck_indices, rcrel, tuple);
1633 CatalogCloseIndices(Num_pg_relcheck_indices, idescs);
1636 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
1637 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
1638 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
1645 StoreConstraints(Relation rel)
1647 TupleConstr *constr = rel->rd_att->constr;
1653 if (constr->num_defval > 0)
1655 for (i = 0; i < constr->num_defval; i++)
1656 StoreAttrDefault(rel, &(constr->defval[i]));
1659 if (constr->num_check > 0)
1661 for (i = 0; i < constr->num_check; i++)
1662 StoreRelCheck(rel, &(constr->check[i]));
1669 RemoveAttrDefault(Relation rel)
1672 HeapScanDesc adscan;
1676 adrel = heap_openr(AttrDefaultRelationName);
1678 ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid,
1679 F_OIDEQ, rel->rd_id);
1681 LockRelation(adrel, AccessExclusiveLock);
1683 adscan = heap_beginscan(adrel, 0, SnapshotNow, 1, &key);
1685 while (HeapTupleIsValid(tup = heap_getnext(adscan, 0)))
1686 heap_delete(adrel, &tup->t_self, NULL);
1688 heap_endscan(adscan);
1690 UnlockRelation(adrel, AccessExclusiveLock);
1696 RemoveRelCheck(Relation rel)
1699 HeapScanDesc rcscan;
1703 rcrel = heap_openr(RelCheckRelationName);
1705 ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
1706 F_OIDEQ, rel->rd_id);
1708 LockRelation(rcrel, AccessExclusiveLock);
1710 rcscan = heap_beginscan(rcrel, 0, SnapshotNow, 1, &key);
1712 while (HeapTupleIsValid(tup = heap_getnext(rcscan, 0)))
1713 heap_delete(rcrel, &tup->t_self, NULL);
1715 heap_endscan(rcscan);
1717 UnlockRelation(rcrel, AccessExclusiveLock);
1723 RemoveConstraints(Relation rel)
1725 TupleConstr *constr = rel->rd_att->constr;
1730 if (constr->num_defval > 0)
1731 RemoveAttrDefault(rel);
1733 if (constr->num_check > 0)
1734 RemoveRelCheck(rel);