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.109 1999/11/22 17:55:57 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 "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_description.h"
42 #include "catalog/pg_index.h"
43 #include "catalog/pg_inherits.h"
44 #include "catalog/pg_ipl.h"
45 #include "catalog/pg_proc.h"
46 #include "catalog/pg_relcheck.h"
47 #include "catalog/pg_type.h"
48 #include "commands/comment.h"
49 #include "commands/trigger.h"
50 #include "optimizer/clauses.h"
51 #include "optimizer/planmain.h"
52 #include "optimizer/tlist.h"
53 #include "optimizer/var.h"
54 #include "parser/parse_clause.h"
55 #include "parser/parse_expr.h"
56 #include "parser/parse_relation.h"
57 #include "parser/parse_target.h"
58 #include "rewrite/rewriteRemove.h"
59 #include "storage/smgr.h"
60 #include "tcop/tcopprot.h"
61 #include "utils/builtins.h"
62 #include "utils/portal.h"
63 #include "utils/relcache.h"
64 #include "utils/syscache.h"
65 #include "utils/temprel.h"
68 static void AddNewRelationTuple(Relation pg_class_desc,
69 Relation new_rel_desc, Oid new_rel_oid, unsigned natts,
70 char relkind, char *temp_relname);
71 static void AddToNoNameRelList(Relation r);
73 static void DeleteAttributeTuples(Relation rel);
74 static void DeleteRelationTuple(Relation rel);
75 static void DeleteTypeTuple(Relation rel);
76 static void RelationRemoveIndexes(Relation relation);
77 static void RelationRemoveInheritance(Relation relation);
78 static void RemoveFromNoNameRelList(Relation r);
79 static void AddNewRelationType(char *typeName, Oid new_rel_oid);
80 static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
81 bool updatePgAttribute);
82 static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
83 static void StoreConstraints(Relation rel);
84 static void RemoveConstraints(Relation rel);
87 /* ----------------------------------------------------------------
88 * XXX UGLY HARD CODED BADNESS FOLLOWS XXX
90 * these should all be moved to someplace in the lib/catalog
91 * module, if not obliterated first.
92 * ----------------------------------------------------------------
98 * Should the executor special case these attributes in the future?
99 * Advantage: consume 1/2 the space in the ATTRIBUTE relation.
100 * Disadvantage: having rules to compute values in these tuples may
101 * be more difficult if not impossible.
104 static FormData_pg_attribute a1 = {
105 0xffffffff, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
106 SelfItemPointerAttributeNumber, 0, -1, -1, '\0', '\0', 'i', '\0', '\0'
109 static FormData_pg_attribute a2 = {
110 0xffffffff, {"oid"}, OIDOID, 0, sizeof(Oid),
111 ObjectIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
114 static FormData_pg_attribute a3 = {
115 0xffffffff, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
116 MinTransactionIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
119 static FormData_pg_attribute a4 = {
120 0xffffffff, {"cmin"}, CIDOID, 0, sizeof(CommandId),
121 MinCommandIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
124 static FormData_pg_attribute a5 = {
125 0xffffffff, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
126 MaxTransactionIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
129 static FormData_pg_attribute a6 = {
130 0xffffffff, {"cmax"}, CIDOID, 0, sizeof(CommandId),
131 MaxCommandIdAttributeNumber, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'
134 static Form_pg_attribute HeapAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6};
136 /* ----------------------------------------------------------------
137 * XXX END OF UGLY HARD CODED BADNESS XXX
138 * ----------------------------------------------------------------
141 /* the tempRelList holds
142 the list of temporary uncatalogued relations that are created.
143 these relations should be destroyed at the end of transactions
145 typedef struct tempRelList
147 Relation *rels; /* array of relation descriptors */
148 int num; /* number of temporary relations */
149 int size; /* size of space allocated for the rels
153 #define NONAME_REL_LIST_SIZE 32
155 static TempRelList *tempRels = NULL;
158 /* ----------------------------------------------------------------
159 * heap_create - Create an uncataloged heap relation
161 * Fields relpages, reltuples, reltuples, relkeys, relhistory,
162 * relisindexed, and relkind of rel->rd_rel are initialized
163 * to all zeros, as are rd_last and rd_hook. Rd_refcnt is set to 1.
165 * Remove the system relation specific code to elsewhere eventually.
167 * Eventually, must place information about this temporary relation
168 * into the transaction context block.
171 * if heap_create is called with "" as the name, then heap_create will create
172 * a temporary name "pg_noname.$PID.$SEQUENCE" for the relation
173 * ----------------------------------------------------------------
176 heap_create(char *relname,
187 int natts = tupDesc->natts;
188 static unsigned int uniqueId = 0;
190 extern GlobalMemory CacheCxt;
191 MemoryContext oldcxt;
198 AssertArg(natts > 0);
200 if (relname && !allowSystemTableMods && IsSystemRelationName(relname) && IsNormalProcessingMode())
202 elog(ERROR, "Illegal class name '%s'"
203 "\n\tThe 'pg_' name prefix is reserved for system catalogs",
208 * switch to the cache context so that we don't lose
209 * allocations at the end of this transaction, I guess.
214 CacheCxt = CreateGlobalMemory("Cache");
216 oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
219 * real ugly stuff to assign the proper relid in the relation
220 * descriptor follows.
223 if (relname && !strcmp(RelationRelationName, relname))
225 relid = RelOid_pg_class;
228 else if (relname && !strcmp(AttributeRelationName, relname))
230 relid = RelOid_pg_attribute;
233 else if (relname && !strcmp(ProcedureRelationName, relname))
235 relid = RelOid_pg_proc;
238 else if (relname && !strcmp(TypeRelationName, relname))
240 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", MyProcPid, uniqueId++);
261 * allocate a new relation descriptor.
264 len = sizeof(RelationData);
266 rel = (Relation) palloc(len);
267 MemSet((char *) rel, 0, len);
268 rel->rd_fd = -1; /* table is not open */
269 rel->rd_unlinked = TRUE; /* table is not created yet */
271 * create a new tuple descriptor from the one passed in
273 rel->rd_att = CreateTupleDescCopyConstr(tupDesc);
276 * nail the reldesc if this is a bootstrap create reln and
277 * we may need it in the cache later on in the bootstrap
278 * process so we don't ever want it kicked out. e.g. pg_attribute!!!
282 rel->rd_isnailed = true;
284 RelationSetReferenceCount(rel, 1);
286 rel->rd_rel = (Form_pg_class) palloc(sizeof *rel->rd_rel);
289 * initialize the fields of our new relation descriptor
292 MemSet((char *) rel->rd_rel, 0, sizeof *rel->rd_rel);
293 strcpy(RelationGetPhysicalRelationName(rel), relname);
294 rel->rd_rel->relkind = RELKIND_UNCATALOGED;
295 rel->rd_rel->relnatts = natts;
297 rel->rd_rel->relchecks = tupDesc->constr->num_check;
299 for (i = 0; i < natts; i++)
300 rel->rd_att->attrs[i]->attrelid = relid;
302 RelationGetRelid(rel) = relid;
306 /* for system relations, set the reltype field here */
307 rel->rd_rel->reltype = relid;
311 * remember if this is a noname relation
314 rel->rd_isnoname = isnoname;
317 * have the storage manager create the relation.
321 /* smgrcreate() is moved to heap_storage_create() */
323 heap_storage_create(rel);
325 RelationRegisterRelation(rel);
327 MemoryContextSwitchTo(oldcxt);
330 * add all noname relations to the tempRels list so they can be
331 * properly disposed of at the end of transaction
334 AddToNoNameRelList(rel);
340 heap_storage_create(Relation rel)
342 bool smgrcall = false;
344 if (rel->rd_unlinked)
346 rel->rd_fd = (File) smgrcreate(DEFAULT_SMGR, rel);
347 rel->rd_unlinked = FALSE;
353 /* ----------------------------------------------------------------
354 * heap_create_with_catalog - Create a cataloged relation
356 * this is done in 6 steps:
358 * 1) CheckAttributeNames() is used to make certain the tuple
359 * descriptor contains a valid set of attribute names
361 * 2) pg_class is opened and RelationFindRelid()
362 * preforms a scan to ensure that no relation with the
363 * same name already exists.
365 * 3) heap_create_with_catalog() is called to create the new relation
368 * 4) TypeDefine() is called to define a new type corresponding
369 * to the new relation.
371 * 5) AddNewAttributeTuples() is called to register the
372 * new relation's schema in pg_attribute.
374 * 6) AddNewRelationTuple() is called to register the
375 * relation itself in the catalogs.
377 * 7) StoreConstraints is called () - vadim 08/22/97
379 * 8) the relations are closed and the new relation's oid
383 * A new relation is inserted into the RELATION relation
384 * with the specified attribute(s) (newly inserted into
385 * the ATTRIBUTE relation). How does concurrency control
386 * work? Is it automatic now? Expects the caller to have
387 * attname, atttypid, atttyparg, attproc, and attlen domains filled.
388 * Create fills the attnum domains sequentually from zero,
389 * fills the attdisbursion domains with zeros, and fills the
390 * attrelid fields with the relid.
392 * scan relation catalog for name conflict
393 * scan type catalog for typids (if not arg)
394 * create and insert attribute(s) into attribute catalog
395 * create new relation
396 * insert new relation into attribute catalog
398 * Should coordinate with heap_create_with_catalog(). Either
399 * it should not be called or there should be a way to prevent
400 * the relation from being removed at the end of the
401 * transaction if it is successful ('u'/'r' may be enough).
402 * Also, if the transaction does not commit, then the
403 * relation should be removed.
405 * XXX amcreate ignores "off" when inserting (for now).
406 * XXX amcreate (like the other utilities) needs to understand indexes.
408 * ----------------------------------------------------------------
411 /* --------------------------------
412 * CheckAttributeNames
414 * this is used to make certain the tuple descriptor contains a
415 * valid set of attribute names. a problem simply generates
416 * elog(ERROR) which aborts the current transaction.
417 * --------------------------------
420 CheckAttributeNames(TupleDesc tupdesc)
424 int natts = tupdesc->natts;
427 * first check for collision with system attribute names
430 * also, warn user if attribute to be created has
431 * an unknown typid (usually as a result of a 'retrieve into'
434 for (i = 0; i < natts; i += 1)
436 for (j = 0; j < sizeof HeapAtt / sizeof HeapAtt[0]; j += 1)
438 if (nameeq(&(HeapAtt[j]->attname),
439 &(tupdesc->attrs[i]->attname)))
441 elog(ERROR, "Attribute '%s' has a name conflict"
442 "\n\tName matches an existing system attribute",
443 NameStr(HeapAtt[j]->attname));
446 if (tupdesc->attrs[i]->atttypid == UNKNOWNOID)
448 elog(NOTICE, "Attribute '%s' has an unknown type"
449 "\n\tRelation created; continue",
450 NameStr(tupdesc->attrs[i]->attname));
455 * next check for repeated attribute names
458 for (i = 1; i < natts; i += 1)
460 for (j = 0; j < i; j += 1)
462 if (nameeq(&(tupdesc->attrs[j]->attname),
463 &(tupdesc->attrs[i]->attname)))
465 elog(ERROR, "Attribute '%s' is repeated",
466 NameStr(tupdesc->attrs[j]->attname));
472 /* --------------------------------
475 * this preforms a scan of pg_class to ensure that
476 * no relation with the same name already exists.
477 * --------------------------------
480 RelnameFindRelid(char *relname)
486 * If this is not bootstrap (initdb) time, use the catalog index on
489 if (!IsBootstrapProcessingMode())
491 tuple = SearchSysCacheTuple(RELNAME,
492 PointerGetDatum(relname),
494 if (HeapTupleIsValid(tuple))
495 relid = tuple->t_data->t_oid;
501 Relation pg_class_desc;
503 HeapScanDesc pg_class_scan;
505 pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
508 * At bootstrap time, we have to do this the hard way. Form the
512 ScanKeyEntryInitialize(&key,
514 (AttrNumber) Anum_pg_class_relname,
515 (RegProcedure) F_NAMEEQ,
522 pg_class_scan = heap_beginscan(pg_class_desc,
529 * get a tuple. if the tuple is NULL then it means we
530 * didn't find an existing relation.
533 tuple = heap_getnext(pg_class_scan, 0);
535 if (HeapTupleIsValid(tuple))
536 relid = tuple->t_data->t_oid;
540 heap_endscan(pg_class_scan);
542 heap_close(pg_class_desc, AccessShareLock);
547 /* --------------------------------
548 * AddNewAttributeTuples
550 * this registers the new relation's schema by adding
551 * tuples to pg_attribute.
552 * --------------------------------
555 AddNewAttributeTuples(Oid new_rel_oid,
558 Form_pg_attribute *dpp;
563 Relation idescs[Num_pg_attr_indices];
564 int natts = tupdesc->natts;
570 rel = heap_openr(AttributeRelationName, RowExclusiveLock);
573 * Check if we have any indices defined on pg_attribute.
576 hasindex = RelationGetForm(rel)->relhasindex;
578 CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
581 * initialize tuple descriptor. Note we use setheapoverride()
582 * so that we can see the effects of our TypeDefine() done
586 setheapoverride(true);
588 setheapoverride(false);
591 * first we add the user attributes..
594 dpp = tupdesc->attrs;
595 for (i = 0; i < natts; i++)
597 (*dpp)->attrelid = new_rel_oid;
598 (*dpp)->attdisbursion = 0;
600 tup = heap_addheader(Natts_pg_attribute,
601 ATTRIBUTE_TUPLE_SIZE,
604 heap_insert(rel, tup);
607 CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
614 * next we add the system attributes..
618 for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)
620 (*dpp)->attrelid = new_rel_oid;
621 /* (*dpp)->attdisbursion = 0; unneeded */
623 tup = heap_addheader(Natts_pg_attribute,
624 ATTRIBUTE_TUPLE_SIZE,
627 heap_insert(rel, tup);
630 CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
636 heap_close(rel, RowExclusiveLock);
639 * close pg_attribute indices
642 CatalogCloseIndices(Num_pg_attr_indices, idescs);
645 /* --------------------------------
646 * AddNewRelationTuple
648 * this registers the new relation in the catalogs by
649 * adding a tuple to pg_class.
650 * --------------------------------
653 AddNewRelationTuple(Relation pg_class_desc,
654 Relation new_rel_desc,
660 Form_pg_class new_rel_reltup;
662 Relation idescs[Num_pg_class_indices];
665 * first we munge some of the information in our
666 * uncataloged relation's relation descriptor.
669 new_rel_reltup = new_rel_desc->rd_rel;
671 /* CHECK should get new_rel_oid first via an insert then use XXX */
674 * Here we insert bogus estimates of the size of the new relation.
675 * In reality, of course, the new relation has 0 tuples and pages,
676 * and if we were tracking these statistics accurately then we'd
677 * set the fields that way. But at present the stats will be updated
678 * only by VACUUM or CREATE INDEX, and the user might insert a lot of
679 * tuples before he gets around to doing either of those. So, instead
680 * of saying the relation is empty, we insert guesstimates. The point
681 * is to keep the optimizer from making really stupid choices on
682 * never-yet-vacuumed tables; so the estimates need only be large
683 * enough to discourage the optimizer from using nested-loop plans.
684 * With this hack, nested-loop plans will be preferred only after
685 * the table has been proven to be small by VACUUM or CREATE INDEX.
686 * Maintaining the stats on-the-fly would solve the problem more cleanly,
687 * but the overhead of that would likely cost more than it'd save.
688 * (NOTE: CREATE INDEX inserts the same bogus estimates if it finds the
689 * relation has 0 rows and pages. See index.c.)
692 new_rel_reltup->relpages = 10; /* bogus estimates */
693 new_rel_reltup->reltuples = 1000;
695 new_rel_reltup->relowner = GetUserId();
696 new_rel_reltup->relkind = relkind;
697 new_rel_reltup->relnatts = natts;
700 * now form a tuple to add to pg_class
701 * XXX Natts_pg_class_fixed is a hack - see pg_class.h
704 tup = heap_addheader(Natts_pg_class_fixed,
706 (char *) new_rel_reltup);
707 tup->t_data->t_oid = new_rel_oid;
710 * finally insert the new tuple and free it.
712 heap_insert(pg_class_desc, tup);
715 create_temp_relation(temp_relname, tup);
717 if (!IsBootstrapProcessingMode())
720 * First, open the catalog indices and insert index tuples for the
723 CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
724 CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class_desc, tup);
725 CatalogCloseIndices(Num_pg_class_indices, idescs);
732 /* --------------------------------
733 * AddNewRelationType -
735 * define a complex type corresponding to the new relation
736 * --------------------------------
739 AddNewRelationType(char *typeName, Oid new_rel_oid)
744 * The sizes are set to oid size because it makes implementing sets
745 * MUCH easier, and no one (we hope) uses these fields to figure out
746 * how much space to allocate for the type. An oid is the type used
747 * for a set definition. When a user requests a set, what they
748 * actually get is the oid of a tuple in the pg_proc catalog, so the
749 * size of the "set" is the size of an oid. Similarly, byval being
750 * true makes sets much easier, and it isn't used by anything else.
751 * Note the assumption that OIDs are the same size as int4s.
753 new_type_oid = TypeCreate(typeName, /* type name */
754 new_rel_oid, /* relation oid */
755 typeLen(typeidType(OIDOID)), /* internal size */
756 typeLen(typeidType(OIDOID)), /* external size */
757 'c', /* type-type (catalog) */
758 ',', /* default array delimiter */
759 "int4in", /* input procedure */
760 "int4out", /* output procedure */
761 "int4in", /* receive procedure */
762 "int4out", /* send procedure */
763 NULL, /* array element type - irrelevent */
764 "-", /* default type value */
765 (bool) 1, /* passed by value */
766 'i'); /* default alignment */
769 /* --------------------------------
770 * heap_create_with_catalog
772 * creates a new cataloged relation. see comments above.
773 * --------------------------------
776 heap_create_with_catalog(char *relname,
781 Relation pg_class_desc;
782 Relation new_rel_desc;
784 int natts = tupdesc->natts;
785 char *temp_relname = NULL;
791 Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode());
792 if (natts == 0 || natts > MaxHeapAttributeNumber)
793 elog(ERROR, "Number of attributes is out of range"
794 "\n\tFrom 1 to %d attributes may be specified",
795 MaxHeapAttributeNumber);
797 CheckAttributeNames(tupdesc);
799 /* temp tables can mask non-temp tables */
800 if ((!istemp && RelnameFindRelid(relname)) ||
801 (istemp && get_temp_rel_by_username(relname) != NULL))
802 elog(ERROR, "Relation '%s' already exists", relname);
804 /* save user relation name because heap_create changes it */
807 temp_relname = pstrdup(relname); /* save original value */
808 relname = palloc(NAMEDATALEN);
809 strcpy(relname, temp_relname); /* heap_create will change this */
813 * get_temp_rel_by_username() couldn't check the simultaneous
814 * creation. Uniqueness will be really checked by unique
815 * indexes of system tables but we couldn't check it here.
816 * We have to pospone to create the disk file for this
818 * Another boolean parameter "storage_create" was added
819 * to heap_create() function. If the parameter is false
820 * heap_create() only registers an uncataloged relation
821 * to relation cache and heap_storage_create() should be
823 * We could pull its relation oid from the newly formed
824 * relation descriptor.
826 * Note: The call to heap_create() changes relname for
827 * noname and temp tables.
828 * The call to heap_storage_create() does all the "real"
829 * work of creating the disk file for the relation.
832 new_rel_desc = heap_create(relname, tupdesc, false, istemp, false);
834 new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
837 * since defining a relation also defines a complex type,
838 * we add a new system type corresponding to the new relation.
841 AddNewRelationType(relname, new_rel_oid);
844 * now add tuples to pg_attribute for the attributes in
848 AddNewAttributeTuples(new_rel_oid, tupdesc);
851 * now update the information in pg_class.
854 pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
856 AddNewRelationTuple(pg_class_desc,
863 StoreConstraints(new_rel_desc);
872 * We create the disk file for this relation here
874 heap_storage_create(new_rel_desc);
876 * ok, the relation has been cataloged, so close our relations
877 * and return the oid of the newly created relation.
879 * SOMEDAY: fill the STATISTIC relation properly.
882 heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */
883 heap_close(pg_class_desc, RowExclusiveLock);
889 /* ----------------------------------------------------------------
890 * heap_destroy_with_catalog - removes all record of named relation from catalogs
892 * 1) open relation, check for existence, etc.
893 * 2) remove inheritance information
895 * 4) remove pg_class tuple
896 * 5) remove pg_attribute tuples and related descriptions
897 * 6) remove pg_description tuples
898 * 7) remove pg_type tuples
899 * 8) RemoveConstraints ()
903 * Except for vital relations, removes relation from
904 * relation catalog, and related attributes from
905 * attribute catalog (needed?). (Anything else?)
907 * get proper relation from relation catalog (if not arg)
908 * check if relation is vital (strcmp()/reltype?)
909 * scan attribute catalog deleting attributes of reldesc
911 * delete relation from relation catalog
912 * (How are the tuples of the relation discarded?)
914 * XXX Must fix to work with indexes.
915 * There may be a better order for doing things.
916 * Problems with destroying a deleted database--cannot create
917 * a struct reldesc without having an open file descriptor.
918 * ----------------------------------------------------------------
921 /* --------------------------------
922 * RelationRemoveInheritance
924 * Note: for now, we cause an exception if relation is a
925 * superclass. Someday, we may want to allow this and merge
926 * the type info into subclass procedures.... this seems like
928 * --------------------------------
931 RelationRemoveInheritance(Relation relation)
933 Relation catalogRelation;
943 catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock);
946 * form a scan key for the subclasses of this class
950 ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_inherits_inhparent,
952 ObjectIdGetDatum(RelationGetRelid(relation)));
954 scan = heap_beginscan(catalogRelation,
961 * if any subclasses exist, then we disallow the deletion.
964 tuple = heap_getnext(scan, 0);
965 if (HeapTupleIsValid(tuple))
967 Oid subclass = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid;
970 heap_close(catalogRelation, RowExclusiveLock);
972 elog(ERROR, "Relation '%u' inherits '%s'",
973 subclass, RelationGetRelationName(relation));
978 * If we get here, it means the relation has no subclasses
979 * so we can trash it. First we remove dead INHERITS tuples.
982 entry.sk_attno = Anum_pg_inherits_inhrelid;
984 scan = heap_beginscan(catalogRelation,
990 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
992 heap_delete(catalogRelation, &tuple->t_self, NULL);
997 heap_close(catalogRelation, RowExclusiveLock);
1000 * now remove dead IPL tuples
1003 catalogRelation = heap_openr(InheritancePrecidenceListRelationName,
1006 entry.sk_attno = Anum_pg_ipl_iplrelid;
1008 scan = heap_beginscan(catalogRelation,
1014 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
1015 heap_delete(catalogRelation, &tuple->t_self, NULL);
1018 heap_close(catalogRelation, RowExclusiveLock);
1021 /* --------------------------------
1022 * RelationRemoveIndexes
1024 * --------------------------------
1027 RelationRemoveIndexes(Relation relation)
1029 Relation indexRelation;
1034 indexRelation = heap_openr(IndexRelationName, RowExclusiveLock);
1036 ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_index_indrelid,
1038 ObjectIdGetDatum(RelationGetRelid(relation)));
1040 scan = heap_beginscan(indexRelation,
1046 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
1047 index_destroy(((Form_pg_index) GETSTRUCT(tuple))->indexrelid);
1050 heap_close(indexRelation, RowExclusiveLock);
1053 /* --------------------------------
1054 * DeleteRelationTuple
1056 * --------------------------------
1059 DeleteRelationTuple(Relation rel)
1061 Relation pg_class_desc;
1068 pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
1070 tup = SearchSysCacheTupleCopy(RELOID,
1071 ObjectIdGetDatum(rel->rd_att->attrs[0]->attrelid),
1073 if (!HeapTupleIsValid(tup))
1075 heap_close(pg_class_desc, RowExclusiveLock);
1076 elog(ERROR, "Relation '%s' does not exist",
1077 RelationGetRelationName(rel));
1081 * delete the relation tuple from pg_class, and finish up.
1084 heap_delete(pg_class_desc, &tup->t_self, NULL);
1087 heap_close(pg_class_desc, RowExclusiveLock);
1090 /* --------------------------------
1091 * RelationTruncateIndexes - This routine is used to truncate all
1092 * indices associated with the heap relation to zero tuples.
1093 * The routine will truncate and then reconstruct the indices on
1094 * the relation specified by the heapRelation parameter.
1095 * --------------------------------
1098 RelationTruncateIndexes(Relation heapRelation)
1100 Relation indexRelation, currentIndex;
1103 HeapTuple indexTuple, procTuple, classTuple;
1104 Form_pg_index index;
1105 Oid heapId, indexId, procId, accessMethodId;
1106 Node *oldPred = NULL;
1108 List *cnfPred = NULL;
1109 AttrNumber *attributeNumberA;
1110 FuncIndexInfo fInfo, *funcInfo = NULL;
1111 int i, numberOfAttributes;
1114 heapId = RelationGetRelid(heapRelation);
1116 /* Scan pg_index to find indexes on heapRelation */
1118 indexRelation = heap_openr(IndexRelationName, AccessShareLock);
1119 ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, F_OIDEQ,
1120 ObjectIdGetDatum(heapId));
1121 scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry);
1122 while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
1125 * For each index, fetch index attributes so we can apply index_build
1127 index = (Form_pg_index) GETSTRUCT(indexTuple);
1128 indexId = index->indexrelid;
1129 procId = index->indproc;
1131 for (i = 0; i < INDEX_MAX_KEYS; i++)
1133 if (index->indkey[i] == InvalidAttrNumber)
1136 numberOfAttributes = i;
1138 /* If a valid where predicate, compute predicate Node */
1139 if (VARSIZE(&index->indpred) != 0)
1141 predString = fmgr(F_TEXTOUT, &index->indpred);
1142 oldPred = stringToNode(predString);
1145 predInfo = (PredInfo *) palloc(sizeof(PredInfo));
1146 predInfo->pred = (Node *) cnfPred;
1147 predInfo->oldPred = oldPred;
1149 /* Assign Index keys to attributes array */
1150 attributeNumberA = (AttrNumber *) palloc(numberOfAttributes *
1151 sizeof(AttrNumber));
1152 for (i = 0; i < numberOfAttributes; i++)
1153 attributeNumberA[i] = index->indkey[i];
1155 /* If this is a procedural index, initialize our FuncIndexInfo */
1156 if (procId != InvalidOid)
1159 FIsetnArgs(funcInfo, numberOfAttributes);
1160 procTuple = SearchSysCacheTuple(PROCOID, ObjectIdGetDatum(procId),
1162 if (!HeapTupleIsValid(procTuple))
1163 elog(ERROR, "RelationTruncateIndexes: index procedure not found");
1164 namecpy(&(funcInfo->funcName),
1165 &(((Form_pg_proc) GETSTRUCT(procTuple))->proname));
1166 FIsetProcOid(funcInfo, procTuple->t_data->t_oid);
1169 /* Fetch the classTuple associated with this index */
1170 classTuple = SearchSysCacheTupleCopy(RELOID, ObjectIdGetDatum(indexId),
1172 if (!HeapTupleIsValid(classTuple))
1173 elog(ERROR, "RelationTruncateIndexes: index access method not found");
1174 accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
1176 /* Open our index relation */
1177 currentIndex = index_open(indexId);
1178 if (currentIndex == NULL)
1179 elog(ERROR, "RelationTruncateIndexes: can't open index relation");
1181 /* Obtain exclusive lock on it, just to be sure */
1182 LockRelation(currentIndex, AccessExclusiveLock);
1185 * Release any buffers associated with this index. If they're dirty,
1186 * they're just dropped without bothering to flush to disk.
1188 ReleaseRelationBuffers(currentIndex);
1189 if (FlushRelationBuffers(currentIndex, (BlockNumber) 0, false) < 0)
1190 elog(ERROR, "RelationTruncateIndexes: unable to flush index from buffer pool");
1192 /* Now truncate the actual data and set blocks to zero */
1193 smgrtruncate(DEFAULT_SMGR, currentIndex, 0);
1194 currentIndex->rd_nblocks = 0;
1196 /* Initialize the index and rebuild */
1197 InitIndexStrategy(numberOfAttributes, currentIndex, accessMethodId);
1198 index_build(heapRelation, currentIndex, numberOfAttributes,
1199 attributeNumberA, 0, NULL, funcInfo, predInfo);
1202 * index_build will close both the heap and index relations
1203 * (but not give up the locks we hold on them). That's fine
1204 * for the index, but we need to open the heap again. We need
1205 * no new lock, since this backend still has the exclusive lock
1206 * grabbed by heap_truncate.
1208 heapRelation = heap_open(heapId, NoLock);
1209 Assert(heapRelation != NULL);
1212 /* Complete the scan and close pg_index */
1214 heap_close(indexRelation, AccessShareLock);
1217 /* ----------------------------
1220 * This routine is used to truncate the data from the
1221 * storage manager of any data within the relation handed
1223 * ----------------------------
1227 heap_truncate(char *relname)
1232 /* Open relation for processing, and grab exclusive access on it. */
1234 rel = heap_openr(relname, AccessExclusiveLock);
1238 * TRUNCATE TABLE within a transaction block is dangerous, because
1239 * if the transaction is later rolled back we have no way to
1240 * undo truncation of the relation's physical file. For now, allow it
1241 * but emit a warning message.
1242 * Someday we might want to consider postponing the physical truncate
1243 * until transaction commit, but that's a lot of work...
1244 * The only case that actually works right is for relations created
1245 * in the current transaction, since the post-abort state would be that
1246 * they don't exist anyway. So, no warning in that case.
1249 if (IsTransactionBlock() && ! rel->rd_myxactonly)
1250 elog(NOTICE, "Caution: TRUNCATE TABLE cannot be rolled back, so don't abort now");
1253 * Release any buffers associated with this relation. If they're dirty,
1254 * they're just dropped without bothering to flush to disk.
1257 ReleaseRelationBuffers(rel);
1258 if (FlushRelationBuffers(rel, (BlockNumber) 0, false) < 0)
1259 elog(ERROR, "heap_truncate: unable to flush relation from buffer pool");
1261 /* Now truncate the actual data and set blocks to zero */
1263 smgrtruncate(DEFAULT_SMGR, rel, 0);
1264 rel->rd_nblocks = 0;
1266 /* If this relation has indexes, truncate the indexes too */
1267 if (rel->rd_rel->relhasindex)
1268 RelationTruncateIndexes(rel);
1271 * Close the relation, but keep exclusive lock on it until commit.
1273 heap_close(rel, NoLock);
1276 * Is this really necessary?
1278 RelationForgetRelation(rid);
1282 /* --------------------------------
1283 * DeleteAttributeTuples
1285 * --------------------------------
1288 DeleteAttributeTuples(Relation rel)
1290 Relation pg_attribute_desc;
1298 pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock);
1300 for (attnum = FirstLowInvalidHeapAttributeNumber + 1;
1301 attnum <= rel->rd_att->natts;
1304 if (HeapTupleIsValid(tup = SearchSysCacheTupleCopy(ATTNUM,
1305 ObjectIdGetDatum(RelationGetRelid(rel)),
1306 Int16GetDatum(attnum),
1310 /*** Delete any comments associated with this attribute ***/
1312 DeleteComments(tup->t_data->t_oid);
1314 heap_delete(pg_attribute_desc, &tup->t_self, NULL);
1320 heap_close(pg_attribute_desc, RowExclusiveLock);
1323 /* --------------------------------
1326 * If the user attempts to destroy a relation and there
1327 * exists attributes in other relations of type
1328 * "relation we are deleting", then we have to do something
1329 * special. presently we disallow the destroy.
1330 * --------------------------------
1333 DeleteTypeTuple(Relation rel)
1335 Relation pg_type_desc;
1336 HeapScanDesc pg_type_scan;
1337 Relation pg_attribute_desc;
1338 HeapScanDesc pg_attribute_scan;
1349 pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
1352 * create a scan key to locate the type tuple corresponding
1356 ScanKeyEntryInitialize(&key, 0,
1357 Anum_pg_type_typrelid,
1359 ObjectIdGetDatum(RelationGetRelid(rel)));
1361 pg_type_scan = heap_beginscan(pg_type_desc,
1368 * use heap_getnext() to fetch the pg_type tuple. If this
1369 * tuple is not valid then something's wrong.
1372 tup = heap_getnext(pg_type_scan, 0);
1374 if (!HeapTupleIsValid(tup))
1376 heap_endscan(pg_type_scan);
1377 heap_close(pg_type_desc, RowExclusiveLock);
1378 elog(ERROR, "DeleteTypeTuple: %s type nonexistent",
1379 RelationGetRelationName(rel));
1383 * now scan pg_attribute. if any other relations have
1384 * attributes of the type of the relation we are deleteing
1385 * then we have to disallow the deletion. should talk to
1386 * stonebraker about this. -cim 6/19/90
1389 typoid = tup->t_data->t_oid;
1391 pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock);
1393 ScanKeyEntryInitialize(&attkey,
1395 Anum_pg_attribute_atttypid,
1399 pg_attribute_scan = heap_beginscan(pg_attribute_desc,
1406 * try and get a pg_attribute tuple. if we succeed it means
1407 * we can't delete the relation because something depends on
1411 atttup = heap_getnext(pg_attribute_scan, 0);
1413 if (HeapTupleIsValid(atttup))
1415 Oid relid = ((Form_pg_attribute) GETSTRUCT(atttup))->attrelid;
1417 heap_endscan(pg_attribute_scan);
1418 heap_close(pg_attribute_desc, RowExclusiveLock);
1419 heap_endscan(pg_type_scan);
1420 heap_close(pg_type_desc, RowExclusiveLock);
1422 elog(ERROR, "DeleteTypeTuple: att of type %s exists in relation %u",
1423 RelationGetRelationName(rel), relid);
1425 heap_endscan(pg_attribute_scan);
1426 heap_close(pg_attribute_desc, RowExclusiveLock);
1429 * Ok, it's safe so we delete the relation tuple
1430 * from pg_type and finish up. But first end the scan so that
1431 * we release the read lock on pg_type. -mer 13 Aug 1991
1435 heap_delete(pg_type_desc, &tup->t_self, NULL);
1437 heap_endscan(pg_type_scan);
1438 heap_close(pg_type_desc, RowExclusiveLock);
1441 /* --------------------------------
1442 * heap_destroy_with_catalog
1444 * --------------------------------
1447 heap_destroy_with_catalog(char *relname)
1451 bool istemp = (get_temp_rel_by_username(relname) != NULL);
1454 * Open and lock the relation.
1457 rel = heap_openr(relname, AccessExclusiveLock);
1461 * prevent deletion of system relations
1464 /* allow temp of pg_class? Guess so. */
1465 if (!istemp && !allowSystemTableMods &&
1466 IsSystemRelationName(RelationGetRelationName(rel)))
1467 elog(ERROR, "System relation '%s' cannot be destroyed",
1468 RelationGetRelationName(rel));
1471 * DROP TABLE within a transaction block is dangerous, because
1472 * if the transaction is later rolled back there will be no way to
1473 * undo the unlink of the relation's physical file. For now, allow it
1474 * but emit a warning message.
1475 * Someday we might want to consider postponing the physical unlink
1476 * until transaction commit, but that's a lot of work...
1477 * The only case that actually works right is for relations created
1478 * in the current transaction, since the post-abort state would be that
1479 * they don't exist anyway. So, no warning in that case.
1482 if (IsTransactionBlock() && ! rel->rd_myxactonly)
1483 elog(NOTICE, "Caution: DROP TABLE cannot be rolled back, so don't abort now");
1486 * remove inheritance information
1489 RelationRemoveInheritance(rel);
1492 * remove indexes if necessary
1495 if (rel->rd_rel->relhasindex)
1496 RelationRemoveIndexes(rel);
1499 * remove rules if necessary
1502 if (rel->rd_rules != NULL)
1503 RelationRemoveRules(rid);
1506 RelationRemoveTriggers(rel);
1509 * delete attribute tuples
1512 DeleteAttributeTuples(rel);
1519 DeleteComments(RelationGetRelid(rel));
1522 * delete type tuple. here we want to see the effects
1523 * of the deletions we just did, so we use setheapoverride().
1526 setheapoverride(true);
1527 DeleteTypeTuple(rel);
1528 setheapoverride(false);
1531 * delete relation tuple
1534 /* must delete fake tuple in cache */
1535 DeleteRelationTuple(rel);
1538 * release dirty buffers of this relation
1540 ReleaseRelationBuffers(rel);
1542 RemoveConstraints(rel);
1545 * unlink the relation's physical file and finish up.
1548 if (!(rel->rd_isnoname) || !(rel->rd_unlinked))
1549 smgrunlink(DEFAULT_SMGR, rel);
1551 rel->rd_unlinked = TRUE;
1554 * Close relcache entry, but *keep* AccessExclusiveLock on the
1555 * relation until transaction commit. This ensures no one else
1556 * will try to do something with the doomed relation.
1558 heap_close(rel, NoLock);
1561 * flush the relation from the relcache
1564 RelationForgetRelation(rid);
1567 remove_temp_relation(rid);
1572 * destroy and close temporary relations
1577 heap_destroy(Relation rel)
1579 ReleaseRelationBuffers(rel);
1580 if (!(rel->rd_isnoname) || !(rel->rd_unlinked))
1581 smgrunlink(DEFAULT_SMGR, rel);
1582 rel->rd_unlinked = TRUE;
1583 heap_close(rel, NoLock);
1584 RemoveFromNoNameRelList(rel);
1588 /**************************************************************
1589 functions to deal with the list of temporary relations
1590 **************************************************************/
1595 initialize temporary relations list
1596 the tempRelList is a list of temporary relations that
1597 are created in the course of the transactions
1598 they need to be destroyed properly at the end of the transactions
1600 MODIFIES the global variable tempRels
1604 malloc is used instead of palloc because we KNOW when we are
1605 going to free these things. Keeps us away from the memory context
1610 InitNoNameRelList(void)
1614 free(tempRels->rels);
1618 tempRels = (TempRelList *) malloc(sizeof(TempRelList));
1619 tempRels->size = NONAME_REL_LIST_SIZE;
1620 tempRels->rels = (Relation *) malloc(sizeof(Relation) * tempRels->size);
1621 MemSet(tempRels->rels, 0, sizeof(Relation) * tempRels->size);
1626 removes a relation from the TempRelList
1628 MODIFIES the global variable tempRels
1629 we don't really remove it, just mark it as NULL
1630 and DestroyNoNameRels will look for NULLs
1633 RemoveFromNoNameRelList(Relation r)
1640 for (i = 0; i < tempRels->num; i++)
1642 if (tempRels->rels[i] == r)
1644 tempRels->rels[i] = NULL;
1651 add a temporary relation to the TempRelList
1653 MODIFIES the global variable tempRels
1656 AddToNoNameRelList(Relation r)
1661 if (tempRels->num == tempRels->size)
1663 tempRels->size += NONAME_REL_LIST_SIZE;
1664 tempRels->rels = realloc(tempRels->rels,
1665 sizeof(Relation) * tempRels->size);
1667 tempRels->rels[tempRels->num] = r;
1672 go through the tempRels list and destroy each of the relations
1675 DestroyNoNameRels(void)
1683 for (i = 0; i < tempRels->num; i++)
1685 rel = tempRels->rels[i];
1686 /* rel may be NULL if it has been removed from the list already */
1690 free(tempRels->rels);
1696 * Store a default expression for column attnum of relation rel.
1697 * The expression must be presented as a nodeToString() string.
1698 * If updatePgAttribute is true, update the pg_attribute entry
1699 * for the column to show that a default exists.
1702 StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
1703 bool updatePgAttribute)
1709 Relation idescs[Num_pg_attrdef_indices];
1712 static char nulls[4] = {' ', ' ', ' ', ' '};
1714 Relation attridescs[Num_pg_attr_indices];
1716 Form_pg_attribute attStruct;
1719 * Need to construct source equivalent of given node-string.
1721 expr = stringToNode(adbin);
1723 * deparse_expression needs a RangeTblEntry list, so make one
1725 rte = makeNode(RangeTblEntry);
1726 rte->relname = RelationGetRelationName(rel);
1727 rte->refname = RelationGetRelationName(rel);
1728 rte->relid = RelationGetRelid(rel);
1730 rte->inFromCl = true;
1731 rte->skipAcl = false;
1732 adsrc = deparse_expression(expr, lcons(lcons(rte, NIL), NIL), false);
1734 values[Anum_pg_attrdef_adrelid - 1] = rel->rd_id;
1735 values[Anum_pg_attrdef_adnum - 1] = attnum;
1736 values[Anum_pg_attrdef_adbin - 1] = PointerGetDatum(textin(adbin));
1737 values[Anum_pg_attrdef_adsrc - 1] = PointerGetDatum(textin(adsrc));
1738 adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
1739 tuple = heap_formtuple(adrel->rd_att, values, nulls);
1740 heap_insert(adrel, tuple);
1741 CatalogOpenIndices(Num_pg_attrdef_indices, Name_pg_attrdef_indices,
1743 CatalogIndexInsert(idescs, Num_pg_attrdef_indices, adrel, tuple);
1744 CatalogCloseIndices(Num_pg_attrdef_indices, idescs);
1745 heap_close(adrel, RowExclusiveLock);
1747 pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
1748 pfree(DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
1752 if (! updatePgAttribute)
1753 return; /* done if pg_attribute is OK */
1755 attrrel = heap_openr(AttributeRelationName, RowExclusiveLock);
1756 atttup = SearchSysCacheTupleCopy(ATTNUM,
1757 ObjectIdGetDatum(rel->rd_id),
1758 (Datum) attnum, 0, 0);
1759 if (!HeapTupleIsValid(atttup))
1760 elog(ERROR, "cache lookup of attribute %d in relation %u failed",
1761 attnum, rel->rd_id);
1762 attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
1763 if (! attStruct->atthasdef)
1765 attStruct->atthasdef = true;
1766 heap_replace(attrrel, &atttup->t_self, atttup, NULL);
1767 /* keep catalog indices current */
1768 CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices,
1770 CatalogIndexInsert(attridescs, Num_pg_attr_indices, attrrel, atttup);
1771 CatalogCloseIndices(Num_pg_attr_indices, attridescs);
1773 heap_close(attrrel, RowExclusiveLock);
1778 * Store a constraint expression for the given relation.
1779 * The expression must be presented as a nodeToString() string.
1781 * Caller is responsible for updating the count of constraints
1782 * in the pg_class entry for the relation.
1785 StoreRelCheck(Relation rel, char *ccname, char *ccbin)
1791 Relation idescs[Num_pg_relcheck_indices];
1794 static char nulls[4] = {' ', ' ', ' ', ' '};
1797 * Convert condition to a normal boolean expression tree.
1799 expr = stringToNode(ccbin);
1800 expr = (Node *) make_ands_explicit((List *) expr);
1802 * deparse_expression needs a RangeTblEntry list, so make one
1804 rte = makeNode(RangeTblEntry);
1805 rte->relname = RelationGetRelationName(rel);
1806 rte->refname = RelationGetRelationName(rel);
1807 rte->relid = RelationGetRelid(rel);
1809 rte->inFromCl = true;
1810 rte->skipAcl = false;
1811 ccsrc = deparse_expression(expr, lcons(lcons(rte, NIL), NIL), false);
1813 values[Anum_pg_relcheck_rcrelid - 1] = rel->rd_id;
1814 values[Anum_pg_relcheck_rcname - 1] = PointerGetDatum(namein(ccname));
1815 values[Anum_pg_relcheck_rcbin - 1] = PointerGetDatum(textin(ccbin));
1816 values[Anum_pg_relcheck_rcsrc - 1] = PointerGetDatum(textin(ccsrc));
1817 rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
1818 tuple = heap_formtuple(rcrel->rd_att, values, nulls);
1819 heap_insert(rcrel, tuple);
1820 CatalogOpenIndices(Num_pg_relcheck_indices, Name_pg_relcheck_indices,
1822 CatalogIndexInsert(idescs, Num_pg_relcheck_indices, rcrel, tuple);
1823 CatalogCloseIndices(Num_pg_relcheck_indices, idescs);
1824 heap_close(rcrel, RowExclusiveLock);
1826 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
1827 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
1828 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
1834 * Store defaults and constraints passed in via the tuple constraint struct.
1836 * NOTE: only pre-cooked expressions will be passed this way, which is to
1837 * say expressions inherited from an existing relation. Newly parsed
1838 * expressions can be added later, by direct calls to StoreAttrDefault
1839 * and StoreRelCheck (see AddRelationRawConstraints()). We assume that
1840 * pg_attribute and pg_class entries for the relation were already set
1841 * to reflect the existence of these defaults/constraints.
1844 StoreConstraints(Relation rel)
1846 TupleConstr *constr = rel->rd_att->constr;
1852 for (i = 0; i < constr->num_defval; i++)
1853 StoreAttrDefault(rel, constr->defval[i].adnum,
1854 constr->defval[i].adbin, false);
1856 for (i = 0; i < constr->num_check; i++)
1857 StoreRelCheck(rel, constr->check[i].ccname,
1858 constr->check[i].ccbin);
1862 * AddRelationRawConstraints
1864 * Add raw (not-yet-transformed) column default expressions and/or constraint
1865 * check expressions to an existing relation. This is defined to do both
1866 * for efficiency in DefineRelation, but of course you can do just one or
1867 * the other by passing empty lists.
1869 * rel: relation to be modified
1870 * rawColDefaults: list of RawColumnDefault structures
1871 * rawConstraints: list of Constraint nodes
1873 * All entries in rawColDefaults will be processed. Entries in rawConstraints
1874 * will be processed only if they are CONSTR_CHECK type and contain a "raw"
1877 * NB: caller should have opened rel with AccessExclusiveLock, and should
1878 * hold that lock till end of transaction.
1881 AddRelationRawConstraints(Relation rel,
1882 List *rawColDefaults,
1883 List *rawConstraints)
1885 char *relname = RelationGetRelationName(rel);
1886 TupleDesc tupleDesc;
1887 TupleConstr *oldconstr;
1889 ConstrCheck *oldchecks;
1894 Relation relidescs[Num_pg_class_indices];
1896 Form_pg_class relStruct;
1899 * Get info about existing constraints.
1901 tupleDesc = RelationGetDescr(rel);
1902 oldconstr = tupleDesc->constr;
1905 numoldchecks = oldconstr->num_check;
1906 oldchecks = oldconstr->check;
1915 * Create a dummy ParseState and insert the target relation as
1916 * its sole rangetable entry. We need a ParseState for transformExpr.
1918 pstate = make_parsestate(NULL);
1919 makeRangeTable(pstate, NULL, NULL);
1920 addRangeTableEntry(pstate, relname, relname, false, true, true);
1923 * Process column default expressions.
1925 foreach(listptr, rawColDefaults)
1927 RawColumnDefault *colDef = (RawColumnDefault *) lfirst(listptr);
1931 Assert(colDef->raw_default != NULL);
1933 * Transform raw parsetree to executable expression.
1935 expr = transformExpr(pstate, colDef->raw_default, EXPR_COLUMN_FIRST);
1937 * Make sure default expr does not refer to any vars.
1939 if (contain_var_clause(expr))
1940 elog(ERROR, "Cannot use attribute(s) in DEFAULT clause");
1942 * Check that it will be possible to coerce the expression
1943 * to the column's type. We store the expression without
1944 * coercion, however, to avoid premature coercion in cases like
1946 * CREATE TABLE tbl (fld datetime DEFAULT 'now');
1948 * NB: this should match the code in updateTargetListEntry()
1949 * that will actually do the coercion, to ensure we don't accept
1950 * an unusable default expression.
1952 type_id = exprType(expr);
1953 if (type_id != InvalidOid)
1955 Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
1957 if (type_id != atp->atttypid)
1959 if (CoerceTargetExpr(NULL, expr,
1960 type_id, atp->atttypid) == NULL)
1961 elog(ERROR, "Attribute '%s' is of type '%s'"
1962 " but default expression is of type '%s'"
1963 "\n\tYou will need to rewrite or cast the expression",
1964 NameStr(atp->attname),
1965 typeidTypeName(atp->atttypid),
1966 typeidTypeName(type_id));
1970 * Might as well try to reduce any constant expressions.
1972 expr = eval_const_expressions(expr);
1974 * Must fix opids, in case any operators remain...
1980 StoreAttrDefault(rel, colDef->attnum, nodeToString(expr), true);
1984 * Process constraint expressions.
1986 numchecks = numoldchecks;
1987 foreach(listptr, rawConstraints)
1989 Constraint *cdef = (Constraint *) lfirst(listptr);
1993 if (cdef->contype != CONSTR_CHECK || cdef->raw_expr == NULL)
1995 Assert(cdef->cooked_expr == NULL);
1997 /* Check name uniqueness, or generate a new name */
1998 if (cdef->name != NULL)
2003 ccname = cdef->name;
2004 /* Check against old constraints */
2005 for (i = 0; i < numoldchecks; i++)
2007 if (strcmp(oldchecks[i].ccname, ccname) == 0)
2008 elog(ERROR, "Duplicate CHECK constraint name: '%s'",
2011 /* Check against other new constraints */
2012 foreach(listptr2, rawConstraints)
2014 Constraint *cdef2 = (Constraint *) lfirst(listptr2);
2016 if (cdef2 == cdef ||
2017 cdef2->contype != CONSTR_CHECK ||
2018 cdef2->raw_expr == NULL ||
2019 cdef2->name == NULL)
2021 if (strcmp(cdef2->name, ccname) == 0)
2022 elog(ERROR, "Duplicate CHECK constraint name: '%s'",
2028 ccname = (char *) palloc(NAMEDATALEN);
2029 snprintf(ccname, NAMEDATALEN, "$%d", numchecks + 1);
2032 * Transform raw parsetree to executable expression.
2034 expr = transformExpr(pstate, cdef->raw_expr, EXPR_COLUMN_FIRST);
2036 * Make sure it yields a boolean result.
2038 if (exprType(expr) != BOOLOID)
2039 elog(ERROR, "CHECK '%s' does not yield boolean result",
2042 * Make sure no outside relations are referred to.
2044 if (length(pstate->p_rtable) != 1)
2045 elog(ERROR, "Only relation '%s' can be referenced in CHECK",
2048 * Might as well try to reduce any constant expressions.
2050 expr = eval_const_expressions(expr);
2052 * Constraints are evaluated with execQual, which expects an
2053 * implicit-AND list, so convert expression to implicit-AND form.
2054 * (We could go so far as to convert to CNF, but that's probably
2057 expr = (Node *) make_ands_implicit((Expr *) expr);
2059 * Must fix opids in operator clauses.
2065 StoreRelCheck(rel, ccname, nodeToString(expr));
2071 * Update the count of constraints in the relation's pg_class tuple.
2072 * We do this even if there was no change, in order to ensure that an
2073 * SI update message is sent out for the pg_class tuple, which will
2074 * force other backends to rebuild their relcache entries for the rel.
2075 * (Of course, for a newly created rel there is no need for an SI message,
2076 * but for ALTER TABLE ADD ATTRIBUTE this'd be important.)
2078 relrel = heap_openr(RelationRelationName, RowExclusiveLock);
2079 reltup = SearchSysCacheTupleCopy(RELOID,
2080 ObjectIdGetDatum(rel->rd_id),
2082 if (!HeapTupleIsValid(reltup))
2083 elog(ERROR, "cache lookup of relation %u failed", rel->rd_id);
2084 relStruct = (Form_pg_class) GETSTRUCT(reltup);
2086 relStruct->relchecks = numchecks;
2088 heap_replace(relrel, &reltup->t_self, reltup, NULL);
2090 /* keep catalog indices current */
2091 CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices,
2093 CatalogIndexInsert(relidescs, Num_pg_class_indices, relrel, reltup);
2094 CatalogCloseIndices(Num_pg_class_indices, relidescs);
2096 heap_close(relrel, RowExclusiveLock);
2100 * Force rebuild of our own relcache entry, otherwise subsequent commands
2101 * in this transaction won't see the new defaults/constraints.
2102 * Must bump command counter or relcache rebuild won't see 'em either.
2104 * (This might seem unnecessary, since we are sending out an SI message;
2105 * but if the relation has just been created then relcache.c will ignore
2106 * the SI message on the grounds that the rel is transaction-local...)
2108 CommandCounterIncrement();
2109 RelationRebuildRelation(rel);
2113 RemoveAttrDefault(Relation rel)
2116 HeapScanDesc adscan;
2120 adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
2122 ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid,
2123 F_OIDEQ, rel->rd_id);
2125 adscan = heap_beginscan(adrel, 0, SnapshotNow, 1, &key);
2127 while (HeapTupleIsValid(tup = heap_getnext(adscan, 0)))
2128 heap_delete(adrel, &tup->t_self, NULL);
2130 heap_endscan(adscan);
2131 heap_close(adrel, RowExclusiveLock);
2135 RemoveRelCheck(Relation rel)
2138 HeapScanDesc rcscan;
2142 rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
2144 ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
2145 F_OIDEQ, rel->rd_id);
2147 rcscan = heap_beginscan(rcrel, 0, SnapshotNow, 1, &key);
2149 while (HeapTupleIsValid(tup = heap_getnext(rcscan, 0)))
2150 heap_delete(rcrel, &tup->t_self, NULL);
2152 heap_endscan(rcscan);
2153 heap_close(rcrel, RowExclusiveLock);
2157 RemoveConstraints(Relation rel)
2159 TupleConstr *constr = rel->rd_att->constr;
2164 if (constr->num_defval > 0)
2165 RemoveAttrDefault(rel);
2167 if (constr->num_check > 0)
2168 RemoveRelCheck(rel);