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.100 1999/10/03 23:55:26 tgl 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 "access/genam.h"
34 #include "access/xact.h"
35 #include "catalog/catalog.h"
36 #include "catalog/catname.h"
37 #include "catalog/heap.h"
38 #include "catalog/index.h"
39 #include "catalog/indexing.h"
40 #include "catalog/pg_attrdef.h"
41 #include "catalog/pg_index.h"
42 #include "catalog/pg_inherits.h"
43 #include "catalog/pg_ipl.h"
44 #include "catalog/pg_proc.h"
45 #include "catalog/pg_relcheck.h"
46 #include "commands/trigger.h"
47 #include "optimizer/clauses.h"
48 #include "optimizer/planmain.h"
49 #include "optimizer/tlist.h"
50 #include "optimizer/var.h"
51 #include "parser/parse_clause.h"
52 #include "parser/parse_coerce.h"
53 #include "parser/parse_expr.h"
54 #include "parser/parse_relation.h"
55 #include "rewrite/rewriteRemove.h"
56 #include "storage/smgr.h"
57 #include "tcop/tcopprot.h"
58 #include "utils/builtins.h"
59 #include "utils/portal.h"
60 #include "utils/relcache.h"
61 #include "utils/syscache.h"
62 #include "utils/temprel.h"
65 static void AddNewRelationTuple(Relation pg_class_desc,
66 Relation new_rel_desc, Oid new_rel_oid, unsigned natts,
67 char relkind, char *temp_relname);
68 static void AddToNoNameRelList(Relation r);
69 static void DeleteAttributeTuples(Relation rel);
70 static void DeleteRelationTuple(Relation rel);
71 static void DeleteTypeTuple(Relation rel);
72 static void RelationRemoveIndexes(Relation relation);
73 static void RelationRemoveInheritance(Relation relation);
74 static void RemoveFromNoNameRelList(Relation r);
75 static void AddNewRelationType(char *typeName, Oid new_rel_oid);
76 static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
77 bool updatePgAttribute);
78 static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
79 static void StoreConstraints(Relation rel);
80 static void RemoveConstraints(Relation rel);
83 /* ----------------------------------------------------------------
84 * XXX UGLY HARD CODED BADNESS FOLLOWS XXX
86 * these should all be moved to someplace in the lib/catalog
87 * module, if not obliterated first.
88 * ----------------------------------------------------------------
94 * Should the executor special case these attributes in the future?
95 * Advantage: consume 1/2 the space in the ATTRIBUTE relation.
96 * Disadvantage: having rules to compute values in these tuples may
97 * be more difficult if not impossible.
100 static FormData_pg_attribute a1 = {
101 0xffffffff, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
102 SelfItemPointerAttributeNumber, 0, -1, -1, '\0', '\0', 'i', '\0', '\0'
105 static FormData_pg_attribute a2 = {
106 0xffffffff, {"oid"}, OIDOID, 0, sizeof(Oid),
107 ObjectIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
110 static FormData_pg_attribute a3 = {
111 0xffffffff, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
112 MinTransactionIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
115 static FormData_pg_attribute a4 = {
116 0xffffffff, {"cmin"}, CIDOID, 0, sizeof(CommandId),
117 MinCommandIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
120 static FormData_pg_attribute a5 = {
121 0xffffffff, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
122 MaxTransactionIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
125 static FormData_pg_attribute a6 = {
126 0xffffffff, {"cmax"}, CIDOID, 0, sizeof(CommandId),
127 MaxCommandIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
130 static Form_pg_attribute HeapAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6};
132 /* ----------------------------------------------------------------
133 * XXX END OF UGLY HARD CODED BADNESS XXX
134 * ----------------------------------------------------------------
137 /* the tempRelList holds
138 the list of temporary uncatalogued relations that are created.
139 these relations should be destroyed at the end of transactions
141 typedef struct tempRelList
143 Relation *rels; /* array of relation descriptors */
144 int num; /* number of temporary relations */
145 int size; /* size of space allocated for the rels
149 #define NONAME_REL_LIST_SIZE 32
151 static TempRelList *tempRels = NULL;
154 /* ----------------------------------------------------------------
155 * heap_create - Create an uncataloged heap relation
157 * Fields relpages, reltuples, reltuples, relkeys, relhistory,
158 * relisindexed, and relkind of rel->rd_rel are initialized
159 * to all zeros, as are rd_last and rd_hook. Rd_refcnt is set to 1.
161 * Remove the system relation specific code to elsewhere eventually.
163 * Eventually, must place information about this temporary relation
164 * into the transaction context block.
167 * if heap_create is called with "" as the name, then heap_create will create
168 * a temporary name "pg_noname.$PID.$SEQUENCE" for the relation
169 * ----------------------------------------------------------------
172 heap_create(char *relname,
182 int natts = tupDesc->natts;
183 static unsigned int uniqueId = 0;
185 extern GlobalMemory CacheCxt;
186 MemoryContext oldcxt;
193 AssertArg(natts > 0);
195 if (relname && !allowSystemTableMods && IsSystemRelationName(relname) && IsNormalProcessingMode())
197 elog(ERROR, "Illegal class name '%s'"
198 "\n\tThe 'pg_' name prefix is reserved for system catalogs",
203 * switch to the cache context so that we don't lose
204 * allocations at the end of this transaction, I guess.
209 CacheCxt = CreateGlobalMemory("Cache");
211 oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
214 * real ugly stuff to assign the proper relid in the relation
215 * descriptor follows.
218 if (relname && !strcmp(RelationRelationName, relname))
220 relid = RelOid_pg_class;
223 else if (relname && !strcmp(AttributeRelationName, relname))
225 relid = RelOid_pg_attribute;
228 else if (relname && !strcmp(ProcedureRelationName, relname))
230 relid = RelOid_pg_proc;
233 else if (relname && !strcmp(TypeRelationName, relname))
235 relid = RelOid_pg_type;
244 relname = palloc(NAMEDATALEN);
245 snprintf(relname, NAMEDATALEN, "pg_noname.%d.%u",
246 (int) MyProcPid, uniqueId++);
251 /* replace relname of caller */
252 snprintf(relname, NAMEDATALEN, "pg_temp.%d.%u", MyProcPid, uniqueId++);
256 * allocate a new relation descriptor.
259 len = sizeof(RelationData);
261 rel = (Relation) palloc(len);
262 MemSet((char *) rel, 0, len);
265 * create a new tuple descriptor from the one passed in
267 rel->rd_att = CreateTupleDescCopyConstr(tupDesc);
270 * nail the reldesc if this is a bootstrap create reln and
271 * we may need it in the cache later on in the bootstrap
272 * process so we don't ever want it kicked out. e.g. pg_attribute!!!
276 rel->rd_isnailed = true;
278 RelationSetReferenceCount(rel, 1);
280 rel->rd_rel = (Form_pg_class) palloc(sizeof *rel->rd_rel);
283 * initialize the fields of our new relation descriptor
286 MemSet((char *) rel->rd_rel, 0, sizeof *rel->rd_rel);
287 namestrcpy(&(rel->rd_rel->relname), relname);
288 rel->rd_rel->relkind = RELKIND_UNCATALOGED;
289 rel->rd_rel->relnatts = natts;
291 rel->rd_rel->relchecks = tupDesc->constr->num_check;
293 for (i = 0; i < natts; i++)
294 rel->rd_att->attrs[i]->attrelid = relid;
296 RelationGetRelid(rel) = relid;
300 /* for system relations, set the reltype field here */
301 rel->rd_rel->reltype = relid;
305 * remember if this is a noname relation
308 rel->rd_isnoname = isnoname;
311 * have the storage manager create the relation.
315 rel->rd_nonameunlinked = TRUE; /* change once table is created */
316 rel->rd_fd = (File) smgrcreate(DEFAULT_SMGR, rel);
317 rel->rd_nonameunlinked = FALSE;
319 RelationRegisterRelation(rel);
321 MemoryContextSwitchTo(oldcxt);
324 * add all noname relations to the tempRels list so they can be
325 * properly disposed of at the end of transaction
328 AddToNoNameRelList(rel);
334 /* ----------------------------------------------------------------
335 * heap_create_with_catalog - Create a cataloged relation
337 * this is done in 6 steps:
339 * 1) CheckAttributeNames() is used to make certain the tuple
340 * descriptor contains a valid set of attribute names
342 * 2) pg_class is opened and RelationFindRelid()
343 * preforms a scan to ensure that no relation with the
344 * same name already exists.
346 * 3) heap_create_with_catalog() is called to create the new relation
349 * 4) TypeDefine() is called to define a new type corresponding
350 * to the new relation.
352 * 5) AddNewAttributeTuples() is called to register the
353 * new relation's schema in pg_attribute.
355 * 6) AddNewRelationTuple() is called to register the
356 * relation itself in the catalogs.
358 * 7) StoreConstraints is called () - vadim 08/22/97
360 * 8) the relations are closed and the new relation's oid
364 * A new relation is inserted into the RELATION relation
365 * with the specified attribute(s) (newly inserted into
366 * the ATTRIBUTE relation). How does concurrency control
367 * work? Is it automatic now? Expects the caller to have
368 * attname, atttypid, atttyparg, attproc, and attlen domains filled.
369 * Create fills the attnum domains sequentually from zero,
370 * fills the attdisbursion domains with zeros, and fills the
371 * attrelid fields with the relid.
373 * scan relation catalog for name conflict
374 * scan type catalog for typids (if not arg)
375 * create and insert attribute(s) into attribute catalog
376 * create new relation
377 * insert new relation into attribute catalog
379 * Should coordinate with heap_create_with_catalog(). Either
380 * it should not be called or there should be a way to prevent
381 * the relation from being removed at the end of the
382 * transaction if it is successful ('u'/'r' may be enough).
383 * Also, if the transaction does not commit, then the
384 * relation should be removed.
386 * XXX amcreate ignores "off" when inserting (for now).
387 * XXX amcreate (like the other utilities) needs to understand indexes.
389 * ----------------------------------------------------------------
392 /* --------------------------------
393 * CheckAttributeNames
395 * this is used to make certain the tuple descriptor contains a
396 * valid set of attribute names. a problem simply generates
397 * elog(ERROR) which aborts the current transaction.
398 * --------------------------------
401 CheckAttributeNames(TupleDesc tupdesc)
405 int natts = tupdesc->natts;
408 * first check for collision with system attribute names
411 * also, warn user if attribute to be created has
412 * an unknown typid (usually as a result of a 'retrieve into'
415 for (i = 0; i < natts; i += 1)
417 for (j = 0; j < sizeof HeapAtt / sizeof HeapAtt[0]; j += 1)
419 if (nameeq(&(HeapAtt[j]->attname),
420 &(tupdesc->attrs[i]->attname)))
422 elog(ERROR, "Attribute '%s' has a name conflict"
423 "\n\tName matches an existing system attribute",
424 HeapAtt[j]->attname.data);
427 if (tupdesc->attrs[i]->atttypid == UNKNOWNOID)
429 elog(NOTICE, "Attribute '%s' has an unknown type"
430 "\n\tRelation created; continue",
431 tupdesc->attrs[i]->attname.data);
436 * next check for repeated attribute names
439 for (i = 1; i < natts; i += 1)
441 for (j = 0; j < i; j += 1)
443 if (nameeq(&(tupdesc->attrs[j]->attname),
444 &(tupdesc->attrs[i]->attname)))
446 elog(ERROR, "Attribute '%s' is repeated",
447 tupdesc->attrs[j]->attname.data);
453 /* --------------------------------
456 * this preforms a scan of pg_class to ensure that
457 * no relation with the same name already exists.
458 * --------------------------------
461 RelnameFindRelid(char *relname)
467 * If this is not bootstrap (initdb) time, use the catalog index on
470 if (!IsBootstrapProcessingMode())
472 tuple = SearchSysCacheTuple(RELNAME,
473 PointerGetDatum(relname),
475 if (HeapTupleIsValid(tuple))
476 relid = tuple->t_data->t_oid;
482 Relation pg_class_desc;
484 HeapScanDesc pg_class_scan;
486 pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
489 * At bootstrap time, we have to do this the hard way. Form the
493 ScanKeyEntryInitialize(&key,
495 (AttrNumber) Anum_pg_class_relname,
496 (RegProcedure) F_NAMEEQ,
503 pg_class_scan = heap_beginscan(pg_class_desc,
510 * get a tuple. if the tuple is NULL then it means we
511 * didn't find an existing relation.
514 tuple = heap_getnext(pg_class_scan, 0);
516 if (HeapTupleIsValid(tuple))
517 relid = tuple->t_data->t_oid;
521 heap_endscan(pg_class_scan);
523 heap_close(pg_class_desc, AccessShareLock);
528 /* --------------------------------
529 * AddNewAttributeTuples
531 * this registers the new relation's schema by adding
532 * tuples to pg_attribute.
533 * --------------------------------
536 AddNewAttributeTuples(Oid new_rel_oid,
539 Form_pg_attribute *dpp;
544 Relation idescs[Num_pg_attr_indices];
545 int natts = tupdesc->natts;
551 rel = heap_openr(AttributeRelationName, RowExclusiveLock);
554 * Check if we have any indices defined on pg_attribute.
557 hasindex = RelationGetForm(rel)->relhasindex;
559 CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
562 * initialize tuple descriptor. Note we use setheapoverride()
563 * so that we can see the effects of our TypeDefine() done
567 setheapoverride(true);
569 setheapoverride(false);
572 * first we add the user attributes..
575 dpp = tupdesc->attrs;
576 for (i = 0; i < natts; i++)
578 (*dpp)->attrelid = new_rel_oid;
579 (*dpp)->attdisbursion = 0;
581 tup = heap_addheader(Natts_pg_attribute,
582 ATTRIBUTE_TUPLE_SIZE,
585 heap_insert(rel, tup);
588 CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
595 * next we add the system attributes..
599 for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)
601 (*dpp)->attrelid = new_rel_oid;
602 /* (*dpp)->attdisbursion = 0; unneeded */
604 tup = heap_addheader(Natts_pg_attribute,
605 ATTRIBUTE_TUPLE_SIZE,
608 heap_insert(rel, tup);
611 CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
617 heap_close(rel, RowExclusiveLock);
620 * close pg_attribute indices
623 CatalogCloseIndices(Num_pg_attr_indices, idescs);
626 /* --------------------------------
627 * AddNewRelationTuple
629 * this registers the new relation in the catalogs by
630 * adding a tuple to pg_class.
631 * --------------------------------
634 AddNewRelationTuple(Relation pg_class_desc,
635 Relation new_rel_desc,
641 Form_pg_class new_rel_reltup;
643 Relation idescs[Num_pg_class_indices];
647 * first we munge some of the information in our
648 * uncataloged relation's relation descriptor.
651 new_rel_reltup = new_rel_desc->rd_rel;
653 /* CHECK should get new_rel_oid first via an insert then use XXX */
656 * Here we insert bogus estimates of the size of the new relation.
657 * In reality, of course, the new relation has 0 tuples and pages,
658 * and if we were tracking these statistics accurately then we'd
659 * set the fields that way. But at present the stats will be updated
660 * only by VACUUM or CREATE INDEX, and the user might insert a lot of
661 * tuples before he gets around to doing either of those. So, instead
662 * of saying the relation is empty, we insert guesstimates. The point
663 * is to keep the optimizer from making really stupid choices on
664 * never-yet-vacuumed tables; so the estimates need only be large
665 * enough to discourage the optimizer from using nested-loop plans.
666 * With this hack, nested-loop plans will be preferred only after
667 * the table has been proven to be small by VACUUM or CREATE INDEX.
668 * Maintaining the stats on-the-fly would solve the problem more cleanly,
669 * but the overhead of that would likely cost more than it'd save.
670 * (NOTE: CREATE INDEX inserts the same bogus estimates if it finds the
671 * relation has 0 rows and pages. See index.c.)
674 new_rel_reltup->relpages = 10; /* bogus estimates */
675 new_rel_reltup->reltuples = 1000;
677 new_rel_reltup->relowner = GetUserId();
678 new_rel_reltup->relkind = relkind;
679 new_rel_reltup->relnatts = natts;
682 * now form a tuple to add to pg_class
683 * XXX Natts_pg_class_fixed is a hack - see pg_class.h
686 tup = heap_addheader(Natts_pg_class_fixed,
688 (char *) new_rel_reltup);
689 tup->t_data->t_oid = new_rel_oid;
692 * finally insert the new tuple and free it.
694 * Note: I have no idea why we do a
695 * SetProcessingMode(BootstrapProcessing);
699 isBootstrap = IsBootstrapProcessingMode() ? true : false;
701 SetProcessingMode(BootstrapProcessing);
703 heap_insert(pg_class_desc, tup);
706 create_temp_relation(temp_relname, tup);
712 * First, open the catalog indices and insert index tuples for the
716 CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
717 CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class_desc, tup);
718 CatalogCloseIndices(Num_pg_class_indices, idescs);
719 /* now restore processing mode */
720 SetProcessingMode(NormalProcessing);
727 /* --------------------------------
728 * AddNewRelationType -
730 * define a complex type corresponding to the new relation
731 * --------------------------------
734 AddNewRelationType(char *typeName, Oid new_rel_oid)
739 * The sizes are set to oid size because it makes implementing sets
740 * MUCH easier, and no one (we hope) uses these fields to figure out
741 * how much space to allocate for the type. An oid is the type used
742 * for a set definition. When a user requests a set, what they
743 * actually get is the oid of a tuple in the pg_proc catalog, so the
744 * size of the "set" is the size of an oid. Similarly, byval being
745 * true makes sets much easier, and it isn't used by anything else.
746 * Note the assumption that OIDs are the same size as int4s.
748 new_type_oid = TypeCreate(typeName, /* type name */
749 new_rel_oid, /* relation oid */
750 typeLen(typeidType(OIDOID)), /* internal size */
751 typeLen(typeidType(OIDOID)), /* external size */
752 'c', /* type-type (catalog) */
753 ',', /* default array delimiter */
754 "int4in", /* input procedure */
755 "int4out", /* output procedure */
756 "int4in", /* receive procedure */
757 "int4out", /* send procedure */
758 NULL, /* array element type - irrelevent */
759 "-", /* default type value */
760 (bool) 1, /* passed by value */
761 'i'); /* default alignment */
764 /* --------------------------------
765 * heap_create_with_catalog
767 * creates a new cataloged relation. see comments above.
768 * --------------------------------
771 heap_create_with_catalog(char *relname,
776 Relation pg_class_desc;
777 Relation new_rel_desc;
779 int natts = tupdesc->natts;
780 char *temp_relname = NULL;
786 Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode());
787 if (natts == 0 || natts > MaxHeapAttributeNumber)
788 elog(ERROR, "Number of attributes is out of range"
789 "\n\tFrom 1 to %d attributes may be specified",
790 MaxHeapAttributeNumber);
792 CheckAttributeNames(tupdesc);
794 /* temp tables can mask non-temp tables */
795 if ((!istemp && RelnameFindRelid(relname)) ||
796 (istemp && get_temp_rel_by_name(relname) != NULL))
797 elog(ERROR, "Relation '%s' already exists", relname);
799 /* save user relation name because heap_create changes it */
802 temp_relname = pstrdup(relname); /* save original value */
803 relname = palloc(NAMEDATALEN);
804 strcpy(relname, temp_relname); /* heap_create will change this */
808 * ok, relation does not already exist so now we
809 * create an uncataloged relation and pull its relation oid
810 * from the newly formed relation descriptor.
812 * Note: The call to heap_create() does all the "real" work
813 * of creating the disk file for the relation.
814 * This changes relname for noname and temp tables.
817 new_rel_desc = heap_create(relname, tupdesc, false, istemp);
819 new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
822 * since defining a relation also defines a complex type,
823 * we add a new system type corresponding to the new relation.
826 AddNewRelationType(relname, new_rel_oid);
829 * now add tuples to pg_attribute for the attributes in
833 AddNewAttributeTuples(new_rel_oid, tupdesc);
836 * now update the information in pg_class.
839 pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
841 AddNewRelationTuple(pg_class_desc,
848 StoreConstraints(new_rel_desc);
857 * ok, the relation has been cataloged, so close our relations
858 * and return the oid of the newly created relation.
860 * SOMEDAY: fill the STATISTIC relation properly.
863 heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */
864 heap_close(pg_class_desc, RowExclusiveLock);
870 /* ----------------------------------------------------------------
871 * heap_destroy_with_catalog - removes all record of named relation from catalogs
873 * 1) open relation, check for existence, etc.
874 * 2) remove inheritance information
876 * 4) remove pg_class tuple
877 * 5) remove pg_attribute tuples
878 * 6) remove pg_type tuples
879 * 7) RemoveConstraints ()
883 * Except for vital relations, removes relation from
884 * relation catalog, and related attributes from
885 * attribute catalog (needed?). (Anything else?)
887 * get proper relation from relation catalog (if not arg)
888 * check if relation is vital (strcmp()/reltype?)
889 * scan attribute catalog deleting attributes of reldesc
891 * delete relation from relation catalog
892 * (How are the tuples of the relation discarded?)
894 * XXX Must fix to work with indexes.
895 * There may be a better order for doing things.
896 * Problems with destroying a deleted database--cannot create
897 * a struct reldesc without having an open file descriptor.
898 * ----------------------------------------------------------------
901 /* --------------------------------
902 * RelationRemoveInheritance
904 * Note: for now, we cause an exception if relation is a
905 * superclass. Someday, we may want to allow this and merge
906 * the type info into subclass procedures.... this seems like
908 * --------------------------------
911 RelationRemoveInheritance(Relation relation)
913 Relation catalogRelation;
923 catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock);
926 * form a scan key for the subclasses of this class
930 ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_inherits_inhparent,
932 ObjectIdGetDatum(RelationGetRelid(relation)));
934 scan = heap_beginscan(catalogRelation,
941 * if any subclasses exist, then we disallow the deletion.
944 tuple = heap_getnext(scan, 0);
945 if (HeapTupleIsValid(tuple))
947 Oid subclass = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrel;
950 heap_close(catalogRelation, RowExclusiveLock);
952 elog(ERROR, "Relation '%u' inherits '%s'",
953 subclass, RelationGetRelationName(relation));
958 * If we get here, it means the relation has no subclasses
959 * so we can trash it. First we remove dead INHERITS tuples.
962 entry.sk_attno = Anum_pg_inherits_inhrel;
964 scan = heap_beginscan(catalogRelation,
970 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
972 heap_delete(catalogRelation, &tuple->t_self, NULL);
977 heap_close(catalogRelation, RowExclusiveLock);
980 * now remove dead IPL tuples
983 catalogRelation = heap_openr(InheritancePrecidenceListRelationName,
986 entry.sk_attno = Anum_pg_ipl_iplrel;
988 scan = heap_beginscan(catalogRelation,
994 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
995 heap_delete(catalogRelation, &tuple->t_self, NULL);
998 heap_close(catalogRelation, RowExclusiveLock);
1001 /* --------------------------------
1002 * RelationRemoveIndexes
1004 * --------------------------------
1007 RelationRemoveIndexes(Relation relation)
1009 Relation indexRelation;
1014 indexRelation = heap_openr(IndexRelationName, RowExclusiveLock);
1016 ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_index_indrelid,
1018 ObjectIdGetDatum(RelationGetRelid(relation)));
1020 scan = heap_beginscan(indexRelation,
1026 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
1027 index_destroy(((Form_pg_index) GETSTRUCT(tuple))->indexrelid);
1030 heap_close(indexRelation, RowExclusiveLock);
1033 /* --------------------------------
1034 * DeleteRelationTuple
1036 * --------------------------------
1039 DeleteRelationTuple(Relation rel)
1041 Relation pg_class_desc;
1048 pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
1050 tup = SearchSysCacheTupleCopy(RELOID,
1051 ObjectIdGetDatum(rel->rd_att->attrs[0]->attrelid),
1053 if (!HeapTupleIsValid(tup))
1055 heap_close(pg_class_desc, RowExclusiveLock);
1056 elog(ERROR, "Relation '%s' does not exist",
1057 &rel->rd_rel->relname);
1061 * delete the relation tuple from pg_class, and finish up.
1064 heap_delete(pg_class_desc, &tup->t_self, NULL);
1067 heap_close(pg_class_desc, RowExclusiveLock);
1070 /* --------------------------------
1071 * RelationTruncateIndexes - This routine is used to truncate all
1072 * indices associated with the heap relation to zero tuples.
1073 * The routine will truncate and then reconstruct the indices on
1074 * the relation specified by the heapRelation parameter.
1075 * --------------------------------
1078 RelationTruncateIndexes(Relation heapRelation)
1080 Relation indexRelation, currentIndex;
1083 HeapTuple indexTuple, procTuple, classTuple;
1084 Form_pg_index index;
1085 Oid heapId, indexId, procId, accessMethodId;
1086 Node *oldPred = NULL;
1088 List *cnfPred = NULL;
1089 AttrNumber *attributeNumberA;
1090 FuncIndexInfo fInfo, *funcInfo = NULL;
1091 int i, numberOfAttributes;
1094 heapId = RelationGetRelid(heapRelation);
1096 /* Scan pg_index to find indexes on heapRelation */
1098 indexRelation = heap_openr(IndexRelationName, AccessShareLock);
1099 ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, F_OIDEQ,
1100 ObjectIdGetDatum(heapId));
1101 scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry);
1102 while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
1105 * For each index, fetch index attributes so we can apply index_build
1107 index = (Form_pg_index) GETSTRUCT(indexTuple);
1108 indexId = index->indexrelid;
1109 procId = index->indproc;
1111 for (i = 0; i < INDEX_MAX_KEYS; i++)
1113 if (index->indkey[i] == InvalidAttrNumber)
1116 numberOfAttributes = i;
1118 /* If a valid where predicate, compute predicate Node */
1119 if (VARSIZE(&index->indpred) != 0)
1121 predString = fmgr(F_TEXTOUT, &index->indpred);
1122 oldPred = stringToNode(predString);
1125 predInfo = (PredInfo *) palloc(sizeof(PredInfo));
1126 predInfo->pred = (Node *) cnfPred;
1127 predInfo->oldPred = oldPred;
1129 /* Assign Index keys to attributes array */
1130 attributeNumberA = (AttrNumber *) palloc(numberOfAttributes *
1131 sizeof(AttrNumber));
1132 for (i = 0; i < numberOfAttributes; i++)
1133 attributeNumberA[i] = index->indkey[i];
1135 /* If this is a procedural index, initialize our FuncIndexInfo */
1136 if (procId != InvalidOid)
1139 FIsetnArgs(funcInfo, numberOfAttributes);
1140 procTuple = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(procId),
1142 if (!HeapTupleIsValid(procTuple))
1143 elog(ERROR, "RelationTruncateIndexes: index procedure not found");
1144 namecpy(&(funcInfo->funcName),
1145 &(((Form_pg_proc) GETSTRUCT(procTuple))->proname));
1146 FIsetProcOid(funcInfo, procTuple->t_data->t_oid);
1149 /* Fetch the classTuple associated with this index */
1150 classTuple = SearchSysCacheTupleCopy(RELOID, ObjectIdGetDatum(indexId),
1152 if (!HeapTupleIsValid(classTuple))
1153 elog(ERROR, "RelationTruncateIndexes: index access method not found");
1154 accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
1156 /* Open our index relation */
1157 currentIndex = index_open(indexId);
1158 if (currentIndex == NULL)
1159 elog(ERROR, "RelationTruncateIndexes: can't open index relation");
1161 /* Obtain exclusive lock on it, just to be sure */
1162 LockRelation(currentIndex, AccessExclusiveLock);
1165 * Release any buffers associated with this index. If they're dirty,
1166 * they're just dropped without bothering to flush to disk.
1168 ReleaseRelationBuffers(currentIndex);
1169 if (FlushRelationBuffers(currentIndex, (BlockNumber) 0, false) < 0)
1170 elog(ERROR, "RelationTruncateIndexes: unable to flush index from buffer pool");
1172 /* Now truncate the actual data and set blocks to zero */
1173 smgrtruncate(DEFAULT_SMGR, currentIndex, 0);
1174 currentIndex->rd_nblocks = 0;
1176 /* Initialize the index and rebuild */
1177 InitIndexStrategy(numberOfAttributes, currentIndex, accessMethodId);
1178 index_build(heapRelation, currentIndex, numberOfAttributes,
1179 attributeNumberA, 0, NULL, funcInfo, predInfo);
1182 * index_build will close both the heap and index relations
1183 * (but not give up the locks we hold on them). That's fine
1184 * for the index, but we need to open the heap again. We need
1185 * no new lock, since this backend still has the exclusive lock
1186 * grabbed by heap_truncate.
1188 heapRelation = heap_open(heapId, NoLock);
1189 Assert(heapRelation != NULL);
1192 /* Complete the scan and close pg_index */
1194 heap_close(indexRelation, AccessShareLock);
1197 /* ----------------------------
1200 * This routine is used to truncate the data from the
1201 * storage manager of any data within the relation handed
1203 * ----------------------------
1207 heap_truncate(char *relname)
1212 /* Open relation for processing, and grab exclusive access on it. */
1214 rel = heap_openr(relname, AccessExclusiveLock);
1218 * TRUNCATE TABLE within a transaction block is dangerous, because
1219 * if the transaction is later rolled back we have no way to
1220 * undo truncation of the relation's physical file. For now, allow it
1221 * but emit a warning message.
1222 * Someday we might want to consider postponing the physical truncate
1223 * until transaction commit, but that's a lot of work...
1224 * The only case that actually works right is for relations created
1225 * in the current transaction, since the post-abort state would be that
1226 * they don't exist anyway. So, no warning in that case.
1229 if (IsTransactionBlock() && ! rel->rd_myxactonly)
1230 elog(NOTICE, "Caution: TRUNCATE TABLE cannot be rolled back, so don't abort now");
1233 * Release any buffers associated with this relation. If they're dirty,
1234 * they're just dropped without bothering to flush to disk.
1237 ReleaseRelationBuffers(rel);
1238 if (FlushRelationBuffers(rel, (BlockNumber) 0, false) < 0)
1239 elog(ERROR, "heap_truncate: unable to flush relation from buffer pool");
1241 /* Now truncate the actual data and set blocks to zero */
1243 smgrtruncate(DEFAULT_SMGR, rel, 0);
1244 rel->rd_nblocks = 0;
1246 /* If this relation has indexes, truncate the indexes too */
1247 if (rel->rd_rel->relhasindex)
1248 RelationTruncateIndexes(rel);
1251 * Close the relation, but keep exclusive lock on it until commit.
1253 heap_close(rel, NoLock);
1256 * Is this really necessary?
1258 RelationForgetRelation(rid);
1262 /* --------------------------------
1263 * DeleteAttributeTuples
1265 * --------------------------------
1268 DeleteAttributeTuples(Relation rel)
1270 Relation pg_attribute_desc;
1278 pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock);
1280 for (attnum = FirstLowInvalidHeapAttributeNumber + 1;
1281 attnum <= rel->rd_att->natts;
1284 if (HeapTupleIsValid(tup = SearchSysCacheTupleCopy(ATTNUM,
1285 ObjectIdGetDatum(RelationGetRelid(rel)),
1286 Int16GetDatum(attnum),
1289 heap_delete(pg_attribute_desc, &tup->t_self, NULL);
1294 heap_close(pg_attribute_desc, RowExclusiveLock);
1297 /* --------------------------------
1300 * If the user attempts to destroy a relation and there
1301 * exists attributes in other relations of type
1302 * "relation we are deleting", then we have to do something
1303 * special. presently we disallow the destroy.
1304 * --------------------------------
1307 DeleteTypeTuple(Relation rel)
1309 Relation pg_type_desc;
1310 HeapScanDesc pg_type_scan;
1311 Relation pg_attribute_desc;
1312 HeapScanDesc pg_attribute_scan;
1323 pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
1326 * create a scan key to locate the type tuple corresponding
1330 ScanKeyEntryInitialize(&key, 0,
1331 Anum_pg_type_typrelid,
1333 ObjectIdGetDatum(RelationGetRelid(rel)));
1335 pg_type_scan = heap_beginscan(pg_type_desc,
1342 * use heap_getnext() to fetch the pg_type tuple. If this
1343 * tuple is not valid then something's wrong.
1346 tup = heap_getnext(pg_type_scan, 0);
1348 if (!HeapTupleIsValid(tup))
1350 heap_endscan(pg_type_scan);
1351 heap_close(pg_type_desc, RowExclusiveLock);
1352 elog(ERROR, "DeleteTypeTuple: %s type nonexistent",
1353 &rel->rd_rel->relname);
1357 * now scan pg_attribute. if any other relations have
1358 * attributes of the type of the relation we are deleteing
1359 * then we have to disallow the deletion. should talk to
1360 * stonebraker about this. -cim 6/19/90
1363 typoid = tup->t_data->t_oid;
1365 pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock);
1367 ScanKeyEntryInitialize(&attkey,
1369 Anum_pg_attribute_atttypid,
1373 pg_attribute_scan = heap_beginscan(pg_attribute_desc,
1380 * try and get a pg_attribute tuple. if we succeed it means
1381 * we can't delete the relation because something depends on
1385 atttup = heap_getnext(pg_attribute_scan, 0);
1387 if (HeapTupleIsValid(atttup))
1389 Oid relid = ((Form_pg_attribute) GETSTRUCT(atttup))->attrelid;
1391 heap_endscan(pg_attribute_scan);
1392 heap_close(pg_attribute_desc, RowExclusiveLock);
1393 heap_endscan(pg_type_scan);
1394 heap_close(pg_type_desc, RowExclusiveLock);
1396 elog(ERROR, "DeleteTypeTuple: att of type %s exists in relation %u",
1397 &rel->rd_rel->relname, relid);
1399 heap_endscan(pg_attribute_scan);
1400 heap_close(pg_attribute_desc, RowExclusiveLock);
1403 * Ok, it's safe so we delete the relation tuple
1404 * from pg_type and finish up. But first end the scan so that
1405 * we release the read lock on pg_type. -mer 13 Aug 1991
1408 heap_delete(pg_type_desc, &tup->t_self, NULL);
1410 heap_endscan(pg_type_scan);
1411 heap_close(pg_type_desc, RowExclusiveLock);
1414 /* --------------------------------
1415 * heap_destroy_with_catalog
1417 * --------------------------------
1420 heap_destroy_with_catalog(char *relname)
1424 bool istemp = (get_temp_rel_by_name(relname) != NULL);
1427 * Open and lock the relation.
1430 rel = heap_openr(relname, AccessExclusiveLock);
1434 * prevent deletion of system relations
1437 /* allow temp of pg_class? Guess so. */
1438 if (!istemp && !allowSystemTableMods &&
1439 IsSystemRelationName(RelationGetRelationName(rel)->data))
1440 elog(ERROR, "System relation '%s' cannot be destroyed",
1441 &rel->rd_rel->relname);
1444 * DROP TABLE within a transaction block is dangerous, because
1445 * if the transaction is later rolled back there will be no way to
1446 * undo the unlink of the relation's physical file. For now, allow it
1447 * but emit a warning message.
1448 * Someday we might want to consider postponing the physical unlink
1449 * until transaction commit, but that's a lot of work...
1450 * The only case that actually works right is for relations created
1451 * in the current transaction, since the post-abort state would be that
1452 * they don't exist anyway. So, no warning in that case.
1455 if (IsTransactionBlock() && ! rel->rd_myxactonly)
1456 elog(NOTICE, "Caution: DROP TABLE cannot be rolled back, so don't abort now");
1459 * remove inheritance information
1462 RelationRemoveInheritance(rel);
1465 * remove indexes if necessary
1468 if (rel->rd_rel->relhasindex)
1469 RelationRemoveIndexes(rel);
1472 * remove rules if necessary
1475 if (rel->rd_rules != NULL)
1476 RelationRemoveRules(rid);
1479 RelationRemoveTriggers(rel);
1482 * delete attribute tuples
1485 DeleteAttributeTuples(rel);
1488 remove_temp_relation(rid);
1491 * delete type tuple. here we want to see the effects
1492 * of the deletions we just did, so we use setheapoverride().
1495 setheapoverride(true);
1496 DeleteTypeTuple(rel);
1497 setheapoverride(false);
1500 * delete relation tuple
1503 /* must delete fake tuple in cache */
1504 DeleteRelationTuple(rel);
1507 * release dirty buffers of this relation
1509 ReleaseRelationBuffers(rel);
1511 RemoveConstraints(rel);
1514 * unlink the relation's physical file and finish up.
1517 if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked))
1518 smgrunlink(DEFAULT_SMGR, rel);
1520 rel->rd_nonameunlinked = TRUE;
1523 * Close relcache entry, but *keep* AccessExclusiveLock on the
1524 * relation until transaction commit. This ensures no one else
1525 * will try to do something with the doomed relation.
1527 heap_close(rel, NoLock);
1530 * flush the relation from the relcache
1533 RelationForgetRelation(rid);
1538 * destroy and close temporary relations
1543 heap_destroy(Relation rel)
1545 ReleaseRelationBuffers(rel);
1546 if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked))
1547 smgrunlink(DEFAULT_SMGR, rel);
1548 rel->rd_nonameunlinked = TRUE;
1549 heap_close(rel, NoLock);
1550 RemoveFromNoNameRelList(rel);
1554 /**************************************************************
1555 functions to deal with the list of temporary relations
1556 **************************************************************/
1561 initialize temporary relations list
1562 the tempRelList is a list of temporary relations that
1563 are created in the course of the transactions
1564 they need to be destroyed properly at the end of the transactions
1566 MODIFIES the global variable tempRels
1570 malloc is used instead of palloc because we KNOW when we are
1571 going to free these things. Keeps us away from the memory context
1576 InitNoNameRelList(void)
1580 free(tempRels->rels);
1584 tempRels = (TempRelList *) malloc(sizeof(TempRelList));
1585 tempRels->size = NONAME_REL_LIST_SIZE;
1586 tempRels->rels = (Relation *) malloc(sizeof(Relation) * tempRels->size);
1587 MemSet(tempRels->rels, 0, sizeof(Relation) * tempRels->size);
1592 removes a relation from the TempRelList
1594 MODIFIES the global variable tempRels
1595 we don't really remove it, just mark it as NULL
1596 and DestroyNoNameRels will look for NULLs
1599 RemoveFromNoNameRelList(Relation r)
1606 for (i = 0; i < tempRels->num; i++)
1608 if (tempRels->rels[i] == r)
1610 tempRels->rels[i] = NULL;
1617 add a temporary relation to the TempRelList
1619 MODIFIES the global variable tempRels
1622 AddToNoNameRelList(Relation r)
1627 if (tempRels->num == tempRels->size)
1629 tempRels->size += NONAME_REL_LIST_SIZE;
1630 tempRels->rels = realloc(tempRels->rels,
1631 sizeof(Relation) * tempRels->size);
1633 tempRels->rels[tempRels->num] = r;
1638 go through the tempRels list and destroy each of the relations
1641 DestroyNoNameRels(void)
1649 for (i = 0; i < tempRels->num; i++)
1651 rel = tempRels->rels[i];
1652 /* rel may be NULL if it has been removed from the list already */
1656 free(tempRels->rels);
1662 * Store a default expression for column attnum of relation rel.
1663 * The expression must be presented as a nodeToString() string.
1664 * If updatePgAttribute is true, update the pg_attribute entry
1665 * for the column to show that a default exists.
1668 StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
1669 bool updatePgAttribute)
1671 Form_pg_attribute atp = rel->rd_att->attrs[attnum - 1];
1677 Relation idescs[Num_pg_attrdef_indices];
1680 static char nulls[4] = {' ', ' ', ' ', ' '};
1682 Relation attridescs[Num_pg_attr_indices];
1684 Form_pg_attribute attStruct;
1686 expr = stringToNode(adbin);
1687 type = exprType(expr);
1689 if (type != atp->atttypid)
1692 * Check that it will be possible to coerce the expression
1693 * to the column's type. We store the expression without
1694 * coercion, however, to avoid premature coercion in cases like
1695 * CREATE TABLE tbl (fld datetime DEFAULT 'now');
1697 coerce_type(NULL, expr, type, atp->atttypid, atp->atttypmod);
1701 * deparse_expression needs a RangeTblEntry list, so make one
1703 rte = makeNode(RangeTblEntry);
1704 rte->relname = RelationGetRelationName(rel)->data;
1705 rte->refname = RelationGetRelationName(rel)->data;
1706 rte->relid = RelationGetRelid(rel);
1708 rte->inFromCl = true;
1709 rte->skipAcl = false;
1710 adsrc = deparse_expression(expr, lcons(lcons(rte, NIL), NIL), false);
1712 values[Anum_pg_attrdef_adrelid - 1] = rel->rd_id;
1713 values[Anum_pg_attrdef_adnum - 1] = attnum;
1714 values[Anum_pg_attrdef_adbin - 1] = PointerGetDatum(textin(adbin));
1715 values[Anum_pg_attrdef_adsrc - 1] = PointerGetDatum(textin(adsrc));
1716 adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
1717 tuple = heap_formtuple(adrel->rd_att, values, nulls);
1718 heap_insert(adrel, tuple);
1719 CatalogOpenIndices(Num_pg_attrdef_indices, Name_pg_attrdef_indices,
1721 CatalogIndexInsert(idescs, Num_pg_attrdef_indices, adrel, tuple);
1722 CatalogCloseIndices(Num_pg_attrdef_indices, idescs);
1723 heap_close(adrel, RowExclusiveLock);
1725 pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
1726 pfree(DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
1730 if (! updatePgAttribute)
1731 return; /* done if pg_attribute is OK */
1733 attrrel = heap_openr(AttributeRelationName, RowExclusiveLock);
1734 atttup = SearchSysCacheTupleCopy(ATTNUM,
1735 ObjectIdGetDatum(rel->rd_id),
1736 (Datum) attnum, 0, 0);
1737 if (!HeapTupleIsValid(atttup))
1738 elog(ERROR, "cache lookup of attribute %d in relation %u failed",
1739 attnum, rel->rd_id);
1740 attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
1741 if (! attStruct->atthasdef)
1743 attStruct->atthasdef = true;
1744 heap_replace(attrrel, &atttup->t_self, atttup, NULL);
1745 /* keep catalog indices current */
1746 CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices,
1748 CatalogIndexInsert(attridescs, Num_pg_attr_indices, attrrel, atttup);
1749 CatalogCloseIndices(Num_pg_attr_indices, attridescs);
1751 heap_close(attrrel, RowExclusiveLock);
1756 * Store a constraint expression for the given relation.
1757 * The expression must be presented as a nodeToString() string.
1759 * Caller is responsible for updating the count of constraints
1760 * in the pg_class entry for the relation.
1763 StoreRelCheck(Relation rel, char *ccname, char *ccbin)
1769 Relation idescs[Num_pg_relcheck_indices];
1772 static char nulls[4] = {' ', ' ', ' ', ' '};
1775 * Convert condition to a normal boolean expression tree.
1777 expr = stringToNode(ccbin);
1778 expr = (Node *) make_ands_explicit((List *) expr);
1780 * deparse_expression needs a RangeTblEntry list, so make one
1782 rte = makeNode(RangeTblEntry);
1783 rte->relname = RelationGetRelationName(rel)->data;
1784 rte->refname = RelationGetRelationName(rel)->data;
1785 rte->relid = RelationGetRelid(rel);
1787 rte->inFromCl = true;
1788 rte->skipAcl = false;
1789 ccsrc = deparse_expression(expr, lcons(lcons(rte, NIL), NIL), false);
1791 values[Anum_pg_relcheck_rcrelid - 1] = rel->rd_id;
1792 values[Anum_pg_relcheck_rcname - 1] = PointerGetDatum(namein(ccname));
1793 values[Anum_pg_relcheck_rcbin - 1] = PointerGetDatum(textin(ccbin));
1794 values[Anum_pg_relcheck_rcsrc - 1] = PointerGetDatum(textin(ccsrc));
1795 rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
1796 tuple = heap_formtuple(rcrel->rd_att, values, nulls);
1797 heap_insert(rcrel, tuple);
1798 CatalogOpenIndices(Num_pg_relcheck_indices, Name_pg_relcheck_indices,
1800 CatalogIndexInsert(idescs, Num_pg_relcheck_indices, rcrel, tuple);
1801 CatalogCloseIndices(Num_pg_relcheck_indices, idescs);
1802 heap_close(rcrel, RowExclusiveLock);
1804 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
1805 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
1806 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
1812 * Store defaults and constraints passed in via the tuple constraint struct.
1814 * NOTE: only pre-cooked expressions will be passed this way, which is to
1815 * say expressions inherited from an existing relation. Newly parsed
1816 * expressions can be added later, by direct calls to StoreAttrDefault
1817 * and StoreRelCheck (see AddRelationRawConstraints()). We assume that
1818 * pg_attribute and pg_class entries for the relation were already set
1819 * to reflect the existence of these defaults/constraints.
1822 StoreConstraints(Relation rel)
1824 TupleConstr *constr = rel->rd_att->constr;
1830 for (i = 0; i < constr->num_defval; i++)
1831 StoreAttrDefault(rel, constr->defval[i].adnum,
1832 constr->defval[i].adbin, false);
1834 for (i = 0; i < constr->num_check; i++)
1835 StoreRelCheck(rel, constr->check[i].ccname,
1836 constr->check[i].ccbin);
1840 * AddRelationRawConstraints
1842 * Add raw (not-yet-transformed) column default expressions and/or constraint
1843 * check expressions to an existing relation. This is defined to do both
1844 * for efficiency in DefineRelation, but of course you can do just one or
1845 * the other by passing empty lists.
1847 * rel: relation to be modified
1848 * rawColDefaults: list of RawColumnDefault structures
1849 * rawConstraints: list of Constraint nodes
1851 * All entries in rawColDefaults will be processed. Entries in rawConstraints
1852 * will be processed only if they are CONSTR_CHECK type and contain a "raw"
1855 * NB: caller should have opened rel with AccessExclusiveLock, and should
1856 * hold that lock till end of transaction.
1859 AddRelationRawConstraints(Relation rel,
1860 List *rawColDefaults,
1861 List *rawConstraints)
1863 char *relname = RelationGetRelationName(rel)->data;
1864 TupleDesc tupleDesc;
1865 TupleConstr *oldconstr;
1867 ConstrCheck *oldchecks;
1872 Relation relidescs[Num_pg_class_indices];
1874 Form_pg_class relStruct;
1877 * Get info about existing constraints.
1879 tupleDesc = RelationGetDescr(rel);
1880 oldconstr = tupleDesc->constr;
1883 numoldchecks = oldconstr->num_check;
1884 oldchecks = oldconstr->check;
1893 * Create a dummy ParseState and insert the target relation as
1894 * its sole rangetable entry. We need a ParseState for transformExpr.
1896 pstate = make_parsestate(NULL);
1897 makeRangeTable(pstate, NULL, NULL);
1898 addRangeTableEntry(pstate, relname, relname, false, true);
1901 * Process column default expressions.
1903 foreach(listptr, rawColDefaults)
1905 RawColumnDefault *colDef = (RawColumnDefault *) lfirst(listptr);
1908 Assert(colDef->raw_default != NULL);
1910 * Transform raw parsetree to executable expression.
1912 expr = transformExpr(pstate, colDef->raw_default, EXPR_COLUMN_FIRST);
1914 * Make sure default expr does not refer to any vars.
1916 if (contain_var_clause(expr))
1917 elog(ERROR, "Cannot use attribute(s) in DEFAULT clause");
1919 * Might as well try to reduce any constant expressions.
1921 expr = eval_const_expressions(expr);
1923 * Must fix opids, in case any operators remain...
1929 StoreAttrDefault(rel, colDef->attnum, nodeToString(expr), true);
1933 * Process constraint expressions.
1935 numchecks = numoldchecks;
1936 foreach(listptr, rawConstraints)
1938 Constraint *cdef = (Constraint *) lfirst(listptr);
1942 if (cdef->contype != CONSTR_CHECK || cdef->raw_expr == NULL)
1944 Assert(cdef->cooked_expr == NULL);
1946 /* Check name uniqueness, or generate a new name */
1947 if (cdef->name != NULL)
1952 ccname = cdef->name;
1953 /* Check against old constraints */
1954 for (i = 0; i < numoldchecks; i++)
1956 if (strcmp(oldchecks[i].ccname, ccname) == 0)
1957 elog(ERROR, "Duplicate CHECK constraint name: '%s'",
1960 /* Check against other new constraints */
1961 foreach(listptr2, rawConstraints)
1963 Constraint *cdef2 = (Constraint *) lfirst(listptr2);
1965 if (cdef2 == cdef ||
1966 cdef2->contype != CONSTR_CHECK ||
1967 cdef2->raw_expr == NULL ||
1968 cdef2->name == NULL)
1970 if (strcmp(cdef2->name, ccname) == 0)
1971 elog(ERROR, "Duplicate CHECK constraint name: '%s'",
1977 ccname = (char *) palloc(NAMEDATALEN);
1978 snprintf(ccname, NAMEDATALEN, "$%d", numchecks + 1);
1981 * Transform raw parsetree to executable expression.
1983 expr = transformExpr(pstate, cdef->raw_expr, EXPR_COLUMN_FIRST);
1985 * Make sure no outside relations are referred to.
1987 if (length(pstate->p_rtable) != 1)
1988 elog(ERROR, "Only relation '%s' can be referenced in CHECK",
1991 * Might as well try to reduce any constant expressions.
1993 expr = eval_const_expressions(expr);
1995 * Constraints are evaluated with execQual, which expects an
1996 * implicit-AND list, so convert expression to implicit-AND form.
1997 * (We could go so far as to convert to CNF, but that's probably
2000 expr = (Node *) make_ands_implicit((Expr *) expr);
2002 * Must fix opids in operator clauses.
2008 StoreRelCheck(rel, ccname, nodeToString(expr));
2014 * Update the count of constraints in the relation's pg_class tuple.
2015 * We do this even if there was no change, in order to ensure that an
2016 * SI update message is sent out for the pg_class tuple, which will
2017 * force other backends to rebuild their relcache entries for the rel.
2018 * (Of course, for a newly created rel there is no need for an SI message,
2019 * but for ALTER TABLE ADD ATTRIBUTE this'd be important.)
2021 relrel = heap_openr(RelationRelationName, RowExclusiveLock);
2022 reltup = SearchSysCacheTupleCopy(RELOID,
2023 ObjectIdGetDatum(rel->rd_id),
2025 if (!HeapTupleIsValid(reltup))
2026 elog(ERROR, "cache lookup of relation %u failed", rel->rd_id);
2027 relStruct = (Form_pg_class) GETSTRUCT(reltup);
2029 relStruct->relchecks = numchecks;
2031 heap_replace(relrel, &reltup->t_self, reltup, NULL);
2033 /* keep catalog indices current */
2034 CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices,
2036 CatalogIndexInsert(relidescs, Num_pg_class_indices, relrel, reltup);
2037 CatalogCloseIndices(Num_pg_class_indices, relidescs);
2039 heap_close(relrel, RowExclusiveLock);
2043 * Force rebuild of our own relcache entry, otherwise subsequent commands
2044 * in this transaction won't see the new defaults/constraints.
2045 * Must bump command counter or relcache rebuild won't see 'em either.
2047 * (This might seem unnecessary, since we are sending out an SI message;
2048 * but if the relation has just been created then relcache.c will ignore
2049 * the SI message on the grounds that the rel is transaction-local...)
2051 CommandCounterIncrement();
2052 RelationRebuildRelation(rel);
2056 RemoveAttrDefault(Relation rel)
2059 HeapScanDesc adscan;
2063 adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
2065 ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid,
2066 F_OIDEQ, rel->rd_id);
2068 adscan = heap_beginscan(adrel, 0, SnapshotNow, 1, &key);
2070 while (HeapTupleIsValid(tup = heap_getnext(adscan, 0)))
2071 heap_delete(adrel, &tup->t_self, NULL);
2073 heap_endscan(adscan);
2074 heap_close(adrel, RowExclusiveLock);
2078 RemoveRelCheck(Relation rel)
2081 HeapScanDesc rcscan;
2085 rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
2087 ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
2088 F_OIDEQ, rel->rd_id);
2090 rcscan = heap_beginscan(rcrel, 0, SnapshotNow, 1, &key);
2092 while (HeapTupleIsValid(tup = heap_getnext(rcscan, 0)))
2093 heap_delete(rcrel, &tup->t_self, NULL);
2095 heap_endscan(rcscan);
2096 heap_close(rcrel, RowExclusiveLock);
2100 RemoveConstraints(Relation rel)
2102 TupleConstr *constr = rel->rd_att->constr;
2107 if (constr->num_defval > 0)
2108 RemoveAttrDefault(rel);
2110 if (constr->num_check > 0)
2111 RemoveRelCheck(rel);