1 /*-------------------------------------------------------------------------
4 * code to create and destroy POSTGRES heap relations
6 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.158 2001/01/24 19:42:51 momjian Exp $
15 * heap_create() - Create an uncataloged heap relation
16 * heap_create_with_catalog() - Create a cataloged relation
17 * heap_drop_with_catalog() - Removes named relation from catalogs
20 * this code taken from access/heap/create.c, which contains
21 * the old heap_create_with_catalog, amcreate, and amdestroy.
22 * those routines will soon call these routines using the function
24 * just like the poorly named "NewXXX" routines do. The
25 * "New" routines are all going to die soon, once and for all!
28 *-------------------------------------------------------------------------
32 #include "access/heapam.h"
33 #include "access/genam.h"
34 #include "catalog/catalog.h"
35 #include "catalog/catname.h"
36 #include "catalog/heap.h"
37 #include "catalog/index.h"
38 #include "catalog/indexing.h"
39 #include "catalog/pg_attrdef.h"
40 #include "catalog/pg_inherits.h"
41 #include "catalog/pg_index.h"
42 #include "catalog/pg_ipl.h"
43 #include "catalog/pg_proc.h"
44 #include "catalog/pg_relcheck.h"
45 #include "catalog/pg_statistic.h"
46 #include "catalog/pg_type.h"
47 #include "commands/comment.h"
48 #include "commands/trigger.h"
49 #include "miscadmin.h"
50 #include "optimizer/clauses.h"
51 #include "optimizer/planmain.h"
52 #include "optimizer/var.h"
53 #include "nodes/makefuncs.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 "parser/parse_type.h"
59 #include "rewrite/rewriteRemove.h"
60 #include "storage/smgr.h"
61 #include "utils/builtins.h"
62 #include "utils/catcache.h"
63 #include "utils/fmgroids.h"
64 #include "utils/lsyscache.h"
65 #include "utils/relcache.h"
66 #include "utils/syscache.h"
67 #include "utils/temprel.h"
70 static void AddNewRelationTuple(Relation pg_class_desc,
71 Relation new_rel_desc, Oid new_rel_oid,
73 char relkind, char *temp_relname);
74 static void DeleteAttributeTuples(Relation rel);
75 static void DeleteRelationTuple(Relation rel);
76 static void DeleteTypeTuple(Relation rel);
77 static void RelationRemoveIndexes(Relation relation);
78 static void RelationRemoveInheritance(Relation relation);
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);
85 static void RemoveStatistics(Relation rel);
88 /* ----------------------------------------------------------------
89 * XXX UGLY HARD CODED BADNESS FOLLOWS XXX
91 * these should all be moved to someplace in the lib/catalog
92 * module, if not obliterated first.
93 * ----------------------------------------------------------------
99 * Should the executor special case these attributes in the future?
100 * Advantage: consume 1/2 the space in the ATTRIBUTE relation.
101 * Disadvantage: having rules to compute values in these tuples may
102 * be more difficult if not impossible.
105 static FormData_pg_attribute a1 = {
106 0xffffffff, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
107 SelfItemPointerAttributeNumber, 0, -1, -1, '\0', 'p', '\0', 'i', '\0', '\0'
110 static FormData_pg_attribute a2 = {
111 0xffffffff, {"oid"}, OIDOID, 0, sizeof(Oid),
112 ObjectIdAttributeNumber, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0'
115 static FormData_pg_attribute a3 = {
116 0xffffffff, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
117 MinTransactionIdAttributeNumber, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0'
120 static FormData_pg_attribute a4 = {
121 0xffffffff, {"cmin"}, CIDOID, 0, sizeof(CommandId),
122 MinCommandIdAttributeNumber, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0'
125 static FormData_pg_attribute a5 = {
126 0xffffffff, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
127 MaxTransactionIdAttributeNumber, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0'
130 static FormData_pg_attribute a6 = {
131 0xffffffff, {"cmax"}, CIDOID, 0, sizeof(CommandId),
132 MaxCommandIdAttributeNumber, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0'
136 We decide to call this attribute "tableoid" rather than say
137 "classoid" on the basis that in the future there may be more than one
138 table of a particular class/type. In any case table is still the word
141 static FormData_pg_attribute a7 = {
142 0xffffffff, {"tableoid"}, OIDOID, 0, sizeof(Oid),
143 TableOidAttributeNumber, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0'
146 static Form_pg_attribute HeapAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
148 /* ----------------------------------------------------------------
149 * XXX END OF UGLY HARD CODED BADNESS XXX
150 * ---------------------------------------------------------------- */
153 /* ----------------------------------------------------------------
154 * heap_create - Create an uncataloged heap relation
156 * Fields relpages, reltuples, reltuples, relkeys, relhistory,
157 * relisindexed, and relkind of rel->rd_rel are initialized
158 * to all zeros, as are rd_last and rd_hook. Rd_refcnt is set to 1.
160 * Remove the system relation specific code to elsewhere eventually.
162 * Eventually, must place information about this temporary relation
163 * into the transaction context block.
165 * NOTE: if istemp is TRUE then heap_create will overwrite relname with
166 * the unique "real" name chosen for the temp relation.
168 * If storage_create is TRUE then heap_storage_create is called here,
169 * else caller must call heap_storage_create later.
170 * ----------------------------------------------------------------
173 heap_create(char *relname,
177 bool allow_system_table_mods)
179 static unsigned int uniqueId = 0;
184 int natts = tupDesc->natts;
186 MemoryContext oldcxt;
187 Oid tblNode = MyDatabaseId;
193 AssertArg(natts > 0);
195 if (relname && !allow_system_table_mods &&
196 IsSystemRelationName(relname) && IsNormalProcessingMode())
198 elog(ERROR, "Illegal class name '%s'"
199 "\n\tThe 'pg_' name prefix is reserved for system catalogs",
204 * real ugly stuff to assign the proper relid in the relation
205 * descriptor follows.
208 if (relname && IsSystemRelationName(relname))
210 if (strcmp(TypeRelationName, relname) == 0)
213 relid = RelOid_pg_type;
215 else if (strcmp(AttributeRelationName, relname) == 0)
218 relid = RelOid_pg_attribute;
220 else if (strcmp(ProcedureRelationName, relname) == 0)
223 relid = RelOid_pg_proc;
225 else if (strcmp(RelationRelationName, relname) == 0)
228 relid = RelOid_pg_class;
230 else if (strcmp(ShadowRelationName, relname) == 0)
232 tblNode = InvalidOid;
233 relid = RelOid_pg_shadow;
235 else if (strcmp(GroupRelationName, relname) == 0)
237 tblNode = InvalidOid;
238 relid = RelOid_pg_group;
240 else if (strcmp(DatabaseRelationName, relname) == 0)
242 tblNode = InvalidOid;
243 relid = RelOid_pg_database;
245 else if (strcmp(VariableRelationName, relname) == 0)
247 tblNode = InvalidOid;
248 relid = RelOid_pg_variable;
250 else if (strcmp(LogRelationName, relname) == 0)
252 tblNode = InvalidOid;
253 relid = RelOid_pg_log;
255 else if (strcmp(AttrDefaultRelationName, relname) == 0)
256 relid = RelOid_pg_attrdef;
257 else if (strcmp(RelCheckRelationName, relname) == 0)
258 relid = RelOid_pg_relcheck;
259 else if (strcmp(TriggerRelationName, relname) == 0)
260 relid = RelOid_pg_trigger;
264 if (IsSharedSystemRelationName(relname))
265 tblNode = InvalidOid;
273 /* replace relname of caller with a unique name for a temp relation */
274 snprintf(relname, NAMEDATALEN, "pg_temp.%d.%u",
275 (int) MyProcPid, uniqueId++);
279 * switch to the cache context to create the relcache entry.
282 if (!CacheMemoryContext)
283 CreateCacheMemoryContext();
285 oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
288 * allocate a new relation descriptor.
291 rel = (Relation) palloc(sizeof(RelationData));
292 MemSet((char *) rel, 0, sizeof(RelationData));
293 rel->rd_fd = -1; /* physical file is not open */
295 RelationSetReferenceCount(rel, 1);
298 * create a new tuple descriptor from the one passed in
300 rel->rd_att = CreateTupleDescCopyConstr(tupDesc);
303 * nail the reldesc if this is a bootstrap create reln and
304 * we may need it in the cache later on in the bootstrap
305 * process so we don't ever want it kicked out. e.g. pg_attribute!!!
309 rel->rd_isnailed = true;
312 * initialize the fields of our new relation descriptor
315 rel->rd_rel = (Form_pg_class) palloc(sizeof *rel->rd_rel);
316 MemSet((char *) rel->rd_rel, 0, sizeof *rel->rd_rel);
317 strcpy(RelationGetPhysicalRelationName(rel), relname);
318 rel->rd_rel->relkind = RELKIND_UNCATALOGED;
319 rel->rd_rel->relnatts = natts;
321 rel->rd_rel->relchecks = tupDesc->constr->num_check;
323 for (i = 0; i < natts; i++)
324 rel->rd_att->attrs[i]->attrelid = relid;
326 RelationGetRelid(rel) = relid;
330 /* for system relations, set the reltype field here */
331 rel->rd_rel->reltype = relid;
334 rel->rd_node.tblNode = tblNode;
335 rel->rd_node.relNode = relid;
336 rel->rd_rel->relfilenode = relid;
339 * done building relcache entry.
342 MemoryContextSwitchTo(oldcxt);
345 * have the storage manager create the relation.
349 heap_storage_create(rel);
351 RelationRegisterRelation(rel);
357 heap_storage_create(Relation rel)
359 Assert(rel->rd_fd < 0);
360 rel->rd_fd = smgrcreate(DEFAULT_SMGR, rel);
361 Assert(rel->rd_fd >= 0);
364 /* ----------------------------------------------------------------
365 * heap_create_with_catalog - Create a cataloged relation
367 * this is done in 6 steps:
369 * 1) CheckAttributeNames() is used to make certain the tuple
370 * descriptor contains a valid set of attribute names
372 * 2) pg_class is opened and RelationFindRelid()
373 * performs a scan to ensure that no relation with the
374 * same name already exists.
376 * 3) heap_create_with_catalog() is called to create the new relation
379 * 4) TypeDefine() is called to define a new type corresponding
380 * to the new relation.
382 * 5) AddNewAttributeTuples() is called to register the
383 * new relation's schema in pg_attribute.
385 * 6) AddNewRelationTuple() is called to register the
386 * relation itself in the catalogs.
388 * 7) StoreConstraints is called () - vadim 08/22/97
390 * 8) the relations are closed and the new relation's oid
394 * A new relation is inserted into the RELATION relation
395 * with the specified attribute(s) (newly inserted into
396 * the ATTRIBUTE relation). How does concurrency control
397 * work? Is it automatic now? Expects the caller to have
398 * attname, atttypid, atttyparg, attproc, and attlen domains filled.
399 * Create fills the attnum domains sequentually from zero,
400 * fills the attdispersion domains with zeros, and fills the
401 * attrelid fields with the relid.
403 * scan relation catalog for name conflict
404 * scan type catalog for typids (if not arg)
405 * create and insert attribute(s) into attribute catalog
406 * create new relation
407 * insert new relation into attribute catalog
409 * Should coordinate with heap_create_with_catalog(). Either
410 * it should not be called or there should be a way to prevent
411 * the relation from being removed at the end of the
412 * transaction if it is successful ('u'/'r' may be enough).
413 * Also, if the transaction does not commit, then the
414 * relation should be removed.
416 * XXX amcreate ignores "off" when inserting (for now).
417 * XXX amcreate (like the other utilities) needs to understand indexes.
419 * ----------------------------------------------------------------
422 /* --------------------------------
423 * CheckAttributeNames
425 * this is used to make certain the tuple descriptor contains a
426 * valid set of attribute names. a problem simply generates
427 * elog(ERROR) which aborts the current transaction.
428 * --------------------------------
431 CheckAttributeNames(TupleDesc tupdesc)
435 int natts = tupdesc->natts;
438 * first check for collision with system attribute names
441 * also, warn user if attribute to be created has
442 * an unknown typid (usually as a result of a 'retrieve into'
445 for (i = 0; i < natts; i++)
447 for (j = 0; j < (int) (sizeof(HeapAtt) / sizeof(HeapAtt[0])); j++)
449 if (strcmp(NameStr(HeapAtt[j]->attname),
450 NameStr(tupdesc->attrs[i]->attname)) == 0)
452 elog(ERROR, "Attribute '%s' has a name conflict"
453 "\n\tName matches an existing system attribute",
454 NameStr(HeapAtt[j]->attname));
457 if (tupdesc->attrs[i]->atttypid == UNKNOWNOID)
459 elog(NOTICE, "Attribute '%s' has an unknown type"
460 "\n\tRelation created; continue",
461 NameStr(tupdesc->attrs[i]->attname));
466 * next check for repeated attribute names
469 for (i = 1; i < natts; i++)
471 for (j = 0; j < i; j++)
473 if (strcmp(NameStr(tupdesc->attrs[j]->attname),
474 NameStr(tupdesc->attrs[i]->attname)) == 0)
476 elog(ERROR, "Attribute '%s' is repeated",
477 NameStr(tupdesc->attrs[j]->attname));
483 /* --------------------------------
486 * Find any existing relation of the given name.
487 * --------------------------------
490 RelnameFindRelid(const char *relname)
495 * If this is not bootstrap (initdb) time, use the catalog index on
498 if (!IsBootstrapProcessingMode())
500 relid = GetSysCacheOid(RELNAME,
501 PointerGetDatum(relname),
506 Relation pg_class_desc;
508 HeapScanDesc pg_class_scan;
511 pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
514 * At bootstrap time, we have to do this the hard way. Form the
518 ScanKeyEntryInitialize(&key,
520 (AttrNumber) Anum_pg_class_relname,
521 (RegProcedure) F_NAMEEQ,
528 pg_class_scan = heap_beginscan(pg_class_desc,
535 * get a tuple. if the tuple is NULL then it means we
536 * didn't find an existing relation.
539 tuple = heap_getnext(pg_class_scan, 0);
541 if (HeapTupleIsValid(tuple))
542 relid = tuple->t_data->t_oid;
546 heap_endscan(pg_class_scan);
548 heap_close(pg_class_desc, AccessShareLock);
553 /* --------------------------------
554 * AddNewAttributeTuples
556 * this registers the new relation's schema by adding
557 * tuples to pg_attribute.
558 * --------------------------------
561 AddNewAttributeTuples(Oid new_rel_oid,
564 Form_pg_attribute *dpp;
569 Relation idescs[Num_pg_attr_indices];
570 int natts = tupdesc->natts;
576 rel = heap_openr(AttributeRelationName, RowExclusiveLock);
579 * Check if we have any indices defined on pg_attribute.
582 hasindex = RelationGetForm(rel)->relhasindex;
584 CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
587 * first we add the user attributes..
590 dpp = tupdesc->attrs;
591 for (i = 0; i < natts; i++)
593 /* Fill in the correct relation OID */
594 (*dpp)->attrelid = new_rel_oid;
595 /* Make sure these are OK, too */
596 (*dpp)->attdispersion = 0;
597 (*dpp)->attcacheoff = -1;
599 tup = heap_addheader(Natts_pg_attribute,
600 ATTRIBUTE_TUPLE_SIZE,
603 heap_insert(rel, tup);
606 CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
613 * next we add the system attributes..
617 for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)
619 /* Fill in the correct relation OID */
620 /* HACK: we are writing on static data here */
621 (*dpp)->attrelid = new_rel_oid;
622 /* Unneeded since they should be OK in the constant data anyway */
623 /* (*dpp)->attdispersion = 0; */
624 /* (*dpp)->attcacheoff = -1; */
626 tup = heap_addheader(Natts_pg_attribute,
627 ATTRIBUTE_TUPLE_SIZE,
630 heap_insert(rel, tup);
633 CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
639 heap_close(rel, RowExclusiveLock);
642 * close pg_attribute indices
645 CatalogCloseIndices(Num_pg_attr_indices, idescs);
648 /* --------------------------------
649 * AddNewRelationTuple
651 * this registers the new relation in the catalogs by
652 * adding a tuple to pg_class.
653 * --------------------------------
656 AddNewRelationTuple(Relation pg_class_desc,
657 Relation new_rel_desc,
663 Form_pg_class new_rel_reltup;
665 Relation idescs[Num_pg_class_indices];
668 * first we munge some of the information in our
669 * uncataloged relation's relation descriptor.
672 new_rel_reltup = new_rel_desc->rd_rel;
675 * Here we insert bogus estimates of the size of the new relation.
676 * In reality, of course, the new relation has 0 tuples and pages,
677 * and if we were tracking these statistics accurately then we'd
678 * set the fields that way. But at present the stats will be updated
679 * only by VACUUM or CREATE INDEX, and the user might insert a lot of
680 * tuples before he gets around to doing either of those. So, instead
681 * of saying the relation is empty, we insert guesstimates. The point
682 * is to keep the optimizer from making really stupid choices on
683 * never-yet-vacuumed tables; so the estimates need only be large
684 * enough to discourage the optimizer from using nested-loop plans.
685 * With this hack, nested-loop plans will be preferred only after
686 * the table has been proven to be small by VACUUM or CREATE INDEX.
687 * Maintaining the stats on-the-fly would solve the problem more cleanly,
688 * but the overhead of that would likely cost more than it'd save.
689 * (NOTE: CREATE INDEX inserts the same bogus estimates if it finds the
690 * relation has 0 rows and pages. See index.c.)
693 new_rel_reltup->relpages = 10; /* bogus estimates */
694 new_rel_reltup->reltuples = 1000;
696 new_rel_reltup->relowner = GetUserId();
697 new_rel_reltup->relkind = relkind;
698 new_rel_reltup->relnatts = natts;
701 * now form a tuple to add to pg_class
702 * XXX Natts_pg_class_fixed is a hack - see pg_class.h
705 tup = heap_addheader(Natts_pg_class_fixed,
707 (char *) new_rel_reltup);
708 tup->t_data->t_oid = new_rel_oid;
711 * finally insert the new tuple and free it.
713 heap_insert(pg_class_desc, tup);
716 create_temp_relation(temp_relname, tup);
718 if (!IsIgnoringSystemIndexes())
722 * First, open the catalog indices and insert index tuples for the
725 CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
726 CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class_desc, tup);
727 CatalogCloseIndices(Num_pg_class_indices, idescs);
734 /* --------------------------------
735 * AddNewRelationType -
737 * define a complex type corresponding to the new relation
738 * --------------------------------
741 AddNewRelationType(char *typeName, Oid new_rel_oid)
746 * The sizes are set to oid size because it makes implementing sets
747 * MUCH easier, and no one (we hope) uses these fields to figure out
748 * how much space to allocate for the type. An oid is the type used
749 * for a set definition. When a user requests a set, what they
750 * actually get is the oid of a tuple in the pg_proc catalog, so the
751 * size of the "set" is the size of an oid. Similarly, byval being
752 * true makes sets much easier, and it isn't used by anything else.
753 * Note the assumption that OIDs are the same size as int4s.
755 new_type_oid = TypeCreate(typeName, /* type name */
756 new_rel_oid, /* relation oid */
757 sizeof(Oid), /* internal size */
758 sizeof(Oid), /* external size */
759 'c', /* type-type (catalog) */
760 ',', /* default array delimiter */
761 "int4in", /* input procedure */
762 "int4out", /* output procedure */
763 "int4in", /* receive procedure */
764 "int4out", /* send procedure */
765 NULL, /* array element type - irrelevent */
766 "-", /* default type value */
767 (bool) 1, /* passed by value */
768 'i', /* default alignment */
769 'p'); /* Not TOASTable */
772 /* --------------------------------
773 * heap_create_with_catalog
775 * creates a new cataloged relation. see comments above.
776 * --------------------------------
779 heap_create_with_catalog(char *relname,
783 bool allow_system_table_mods)
785 Relation pg_class_desc;
786 Relation new_rel_desc;
788 int natts = tupdesc->natts;
789 char *temp_relname = NULL;
795 Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode());
796 if (natts <= 0 || natts > MaxHeapAttributeNumber)
797 elog(ERROR, "Number of attributes is out of range"
798 "\n\tFrom 1 to %d attributes may be specified",
799 MaxHeapAttributeNumber);
801 CheckAttributeNames(tupdesc);
803 /* temp tables can mask non-temp tables */
804 if ((!istemp && RelnameFindRelid(relname)) ||
805 (istemp && is_temp_rel_name(relname)))
806 elog(ERROR, "Relation '%s' already exists", relname);
810 /* save user relation name because heap_create changes it */
811 temp_relname = pstrdup(relname); /* save original value */
812 relname = palloc(NAMEDATALEN);
813 strcpy(relname, temp_relname); /* heap_create will change this */
817 * RelnameFindRelid couldn't detect simultaneous
818 * creation. Uniqueness will be really checked by unique
819 * indexes of system tables but we couldn't check it here.
820 * We have to postpone creating the disk file for this
822 * Another boolean parameter "storage_create" was added
823 * to heap_create() function. If the parameter is false
824 * heap_create() only registers an uncataloged relation
825 * to relation cache and heap_storage_create() should be
827 * We could pull its relation oid from the newly formed
828 * relation descriptor.
830 * Note: The call to heap_create() changes relname for
831 * temp tables; it becomes the true physical relname.
832 * The call to heap_storage_create() does all the "real"
833 * work of creating the disk file for the relation.
836 new_rel_desc = heap_create(relname, tupdesc, istemp, false,
837 allow_system_table_mods);
839 new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
842 * since defining a relation also defines a complex type,
843 * we add a new system type corresponding to the new relation.
846 AddNewRelationType(relname, new_rel_oid);
849 * now add tuples to pg_attribute for the attributes in
853 AddNewAttributeTuples(new_rel_oid, tupdesc);
856 * now update the information in pg_class.
859 pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
861 AddNewRelationTuple(pg_class_desc,
868 StoreConstraints(new_rel_desc);
877 * We create the disk file for this relation here
879 if (relkind != RELKIND_VIEW)
880 heap_storage_create(new_rel_desc);
883 * ok, the relation has been cataloged, so close our relations
884 * and return the oid of the newly created relation.
886 * SOMEDAY: fill the STATISTIC relation properly.
889 heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */
890 heap_close(pg_class_desc, RowExclusiveLock);
896 /* ----------------------------------------------------------------
897 * heap_drop_with_catalog - removes all record of named relation from catalogs
899 * 1) open relation, check for existence, etc.
900 * 2) remove inheritance information
902 * 4) remove pg_class tuple
903 * 5) remove pg_attribute tuples and related descriptions
904 * 6) remove pg_description tuples
905 * 7) remove pg_type tuples
906 * 8) RemoveConstraints ()
910 * Except for vital relations, removes relation from
911 * relation catalog, and related attributes from
912 * attribute catalog (needed?). (Anything else?)
914 * get proper relation from relation catalog (if not arg)
915 * check if relation is vital (strcmp()/reltype?)
916 * scan attribute catalog deleting attributes of reldesc
918 * delete relation from relation catalog
919 * (How are the tuples of the relation discarded?)
921 * XXX Must fix to work with indexes.
922 * There may be a better order for doing things.
923 * Problems with destroying a deleted database--cannot create
924 * a struct reldesc without having an open file descriptor.
925 * ----------------------------------------------------------------
928 /* --------------------------------
929 * RelationRemoveInheritance
931 * Note: for now, we cause an exception if relation is a
932 * superclass. Someday, we may want to allow this and merge
933 * the type info into subclass procedures.... this seems like
935 * --------------------------------
938 RelationRemoveInheritance(Relation relation)
940 Relation catalogRelation;
950 catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock);
953 * form a scan key for the subclasses of this class
957 ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_inherits_inhparent,
959 ObjectIdGetDatum(RelationGetRelid(relation)));
961 scan = heap_beginscan(catalogRelation,
968 * if any subclasses exist, then we disallow the deletion.
971 tuple = heap_getnext(scan, 0);
972 if (HeapTupleIsValid(tuple))
974 Oid subclass = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid;
977 subclassname = get_rel_name(subclass);
978 /* Just in case get_rel_name fails... */
980 elog(ERROR, "Relation \"%s\" inherits from \"%s\"",
981 subclassname, RelationGetRelationName(relation));
983 elog(ERROR, "Relation %u inherits from \"%s\"",
984 subclass, RelationGetRelationName(relation));
989 * If we get here, it means the relation has no subclasses
990 * so we can trash it. First we remove dead INHERITS tuples.
993 entry.sk_attno = Anum_pg_inherits_inhrelid;
995 scan = heap_beginscan(catalogRelation,
1001 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
1003 simple_heap_delete(catalogRelation, &tuple->t_self);
1008 heap_close(catalogRelation, RowExclusiveLock);
1011 * now remove dead IPL tuples
1014 catalogRelation = heap_openr(InheritancePrecidenceListRelationName,
1017 entry.sk_attno = Anum_pg_ipl_iplrelid;
1019 scan = heap_beginscan(catalogRelation,
1025 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
1027 simple_heap_delete(catalogRelation, &tuple->t_self);
1031 heap_close(catalogRelation, RowExclusiveLock);
1034 /* --------------------------------
1035 * RelationRemoveIndexes
1037 * --------------------------------
1040 RelationRemoveIndexes(Relation relation)
1042 Relation indexRelation;
1047 indexRelation = heap_openr(IndexRelationName, RowExclusiveLock);
1049 ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_index_indrelid,
1051 ObjectIdGetDatum(RelationGetRelid(relation)));
1053 scan = heap_beginscan(indexRelation,
1059 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
1061 index_drop(((Form_pg_index) GETSTRUCT(tuple))->indexrelid);
1062 /* advance cmd counter to make catalog changes visible */
1063 CommandCounterIncrement();
1067 heap_close(indexRelation, RowExclusiveLock);
1070 /* --------------------------------
1071 * DeleteRelationTuple
1073 * --------------------------------
1076 DeleteRelationTuple(Relation rel)
1078 Relation pg_class_desc;
1085 pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
1087 tup = SearchSysCacheCopy(RELOID,
1088 ObjectIdGetDatum(rel->rd_id),
1090 if (!HeapTupleIsValid(tup))
1091 elog(ERROR, "Relation \"%s\" does not exist",
1092 RelationGetRelationName(rel));
1095 * delete the relation tuple from pg_class, and finish up.
1098 simple_heap_delete(pg_class_desc, &tup->t_self);
1099 heap_freetuple(tup);
1101 heap_close(pg_class_desc, RowExclusiveLock);
1104 /* --------------------------------
1105 * RelationTruncateIndexes - This routine is used to truncate all
1106 * indices associated with the heap relation to zero tuples.
1107 * The routine will truncate and then reconstruct the indices on
1108 * the relation specified by the heapId parameter.
1109 * --------------------------------
1112 RelationTruncateIndexes(Oid heapId)
1114 Relation indexRelation;
1117 HeapTuple indexTuple;
1119 /* Scan pg_index to find indexes on specified heap */
1120 indexRelation = heap_openr(IndexRelationName, AccessShareLock);
1121 ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, F_OIDEQ,
1122 ObjectIdGetDatum(heapId));
1123 scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry);
1125 while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
1129 IndexInfo *indexInfo;
1130 HeapTuple classTuple;
1131 Relation heapRelation,
1135 * For each index, fetch info needed for index_build
1137 indexId = ((Form_pg_index) GETSTRUCT(indexTuple))->indexrelid;
1138 indexInfo = BuildIndexInfo(indexTuple);
1140 /* Fetch access method from pg_class tuple for this index */
1141 classTuple = SearchSysCache(RELOID,
1142 ObjectIdGetDatum(indexId),
1144 if (!HeapTupleIsValid(classTuple))
1145 elog(ERROR, "RelationTruncateIndexes: index %u not found in pg_class",
1147 accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
1148 ReleaseSysCache(classTuple);
1151 * We have to re-open the heap rel each time through this loop
1152 * because index_build will close it again. We need grab no lock,
1153 * however, because we assume heap_truncate is holding an exclusive
1154 * lock on the heap rel.
1156 heapRelation = heap_open(heapId, NoLock);
1158 /* Open the index relation */
1159 currentIndex = index_open(indexId);
1161 /* Obtain exclusive lock on it, just to be sure */
1162 LockRelation(currentIndex, AccessExclusiveLock);
1165 * Drop any buffers associated with this index. If they're
1166 * dirty, they're just dropped without bothering to flush to disk.
1168 DropRelationBuffers(currentIndex);
1170 /* Now truncate the actual data and set blocks to zero */
1171 smgrtruncate(DEFAULT_SMGR, currentIndex, 0);
1172 currentIndex->rd_nblocks = 0;
1174 /* Initialize the index and rebuild */
1175 InitIndexStrategy(indexInfo->ii_NumIndexAttrs,
1176 currentIndex, accessMethodId);
1177 index_build(heapRelation, currentIndex, indexInfo, NULL);
1179 * index_build will close both the heap and index relations (but
1180 * not give up the locks we hold on them).
1184 /* Complete the scan and close pg_index */
1186 heap_close(indexRelation, AccessShareLock);
1189 /* ----------------------------
1192 * This routine is used to truncate the data from the
1193 * storage manager of any data within the relation handed
1195 * ----------------------------
1199 heap_truncate(char *relname)
1204 /* Open relation for processing, and grab exclusive access on it. */
1206 rel = heap_openr(relname, AccessExclusiveLock);
1207 rid = RelationGetRelid(rel);
1210 * TRUNCATE TABLE within a transaction block is dangerous, because
1211 * if the transaction is later rolled back we have no way to
1212 * undo truncation of the relation's physical file. Disallow it
1213 * except for a rel created in the current xact (which would be deleted
1214 * on abort, anyway).
1217 if (IsTransactionBlock() && !rel->rd_myxactonly)
1218 elog(ERROR, "TRUNCATE TABLE cannot run inside a BEGIN/END block");
1221 * Release any buffers associated with this relation. If they're
1222 * dirty, they're just dropped without bothering to flush to disk.
1224 DropRelationBuffers(rel);
1226 /* Now truncate the actual data and set blocks to zero */
1228 smgrtruncate(DEFAULT_SMGR, rel, 0);
1229 rel->rd_nblocks = 0;
1231 /* If this relation has indexes, truncate the indexes too */
1232 RelationTruncateIndexes(rid);
1235 * Close the relation, but keep exclusive lock on it until commit.
1237 heap_close(rel, NoLock);
1241 /* --------------------------------
1242 * DeleteAttributeTuples
1244 * --------------------------------
1247 DeleteAttributeTuples(Relation rel)
1249 Relation pg_attribute_desc;
1257 pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock);
1259 for (attnum = FirstLowInvalidHeapAttributeNumber + 1;
1260 attnum <= rel->rd_att->natts;
1263 tup = SearchSysCacheCopy(ATTNUM,
1264 ObjectIdGetDatum(RelationGetRelid(rel)),
1265 Int16GetDatum(attnum),
1267 if (HeapTupleIsValid(tup))
1269 /*** Delete any comments associated with this attribute ***/
1270 DeleteComments(tup->t_data->t_oid);
1272 simple_heap_delete(pg_attribute_desc, &tup->t_self);
1273 heap_freetuple(tup);
1277 heap_close(pg_attribute_desc, RowExclusiveLock);
1280 /* --------------------------------
1283 * If the user attempts to destroy a relation and there
1284 * exists attributes in other relations of type
1285 * "relation we are deleting", then we have to do something
1286 * special. presently we disallow the destroy.
1287 * --------------------------------
1290 DeleteTypeTuple(Relation rel)
1292 Relation pg_type_desc;
1293 HeapScanDesc pg_type_scan;
1294 Relation pg_attribute_desc;
1295 HeapScanDesc pg_attribute_scan;
1306 pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
1309 * create a scan key to locate the type tuple corresponding
1313 ScanKeyEntryInitialize(&key, 0,
1314 Anum_pg_type_typrelid,
1316 ObjectIdGetDatum(RelationGetRelid(rel)));
1318 pg_type_scan = heap_beginscan(pg_type_desc,
1325 * use heap_getnext() to fetch the pg_type tuple. If this
1326 * tuple is not valid then something's wrong.
1329 tup = heap_getnext(pg_type_scan, 0);
1331 if (!HeapTupleIsValid(tup))
1333 heap_endscan(pg_type_scan);
1334 heap_close(pg_type_desc, RowExclusiveLock);
1335 elog(ERROR, "DeleteTypeTuple: type \"%s\" does not exist",
1336 RelationGetRelationName(rel));
1340 * now scan pg_attribute. if any other relations have
1341 * attributes of the type of the relation we are deleteing
1342 * then we have to disallow the deletion. should talk to
1343 * stonebraker about this. -cim 6/19/90
1346 typoid = tup->t_data->t_oid;
1348 pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock);
1350 ScanKeyEntryInitialize(&attkey,
1352 Anum_pg_attribute_atttypid,
1356 pg_attribute_scan = heap_beginscan(pg_attribute_desc,
1363 * try and get a pg_attribute tuple. if we succeed it means
1364 * we can't delete the relation because something depends on
1368 atttup = heap_getnext(pg_attribute_scan, 0);
1370 if (HeapTupleIsValid(atttup))
1372 Oid relid = ((Form_pg_attribute) GETSTRUCT(atttup))->attrelid;
1374 heap_endscan(pg_attribute_scan);
1375 heap_close(pg_attribute_desc, RowExclusiveLock);
1376 heap_endscan(pg_type_scan);
1377 heap_close(pg_type_desc, RowExclusiveLock);
1379 elog(ERROR, "DeleteTypeTuple: att of type %s exists in relation %u",
1380 RelationGetRelationName(rel), relid);
1382 heap_endscan(pg_attribute_scan);
1383 heap_close(pg_attribute_desc, RowExclusiveLock);
1386 * Ok, it's safe so we delete the relation tuple
1387 * from pg_type and finish up.
1390 simple_heap_delete(pg_type_desc, &tup->t_self);
1392 heap_endscan(pg_type_scan);
1393 heap_close(pg_type_desc, RowExclusiveLock);
1396 /* --------------------------------
1397 * heap_drop_with_catalog
1399 * --------------------------------
1402 heap_drop_with_catalog(const char *relname,
1403 bool allow_system_table_mods)
1407 bool has_toasttable;
1408 bool istemp = is_temp_rel_name(relname);
1412 * Open and lock the relation.
1415 rel = heap_openr(relname, AccessExclusiveLock);
1416 rid = RelationGetRelid(rel);
1417 has_toasttable = rel->rd_rel->reltoastrelid != InvalidOid;
1420 * prevent deletion of system relations
1423 /* allow temp of pg_class? Guess so. */
1424 if (!istemp && !allow_system_table_mods &&
1425 IsSystemRelationName(RelationGetRelationName(rel)))
1426 elog(ERROR, "System relation \"%s\" may not be dropped",
1427 RelationGetRelationName(rel));
1430 * Release all buffers that belong to this relation, after writing
1431 * any that are dirty
1434 i = FlushRelationBuffers(rel, (BlockNumber) 0);
1436 elog(ERROR, "heap_drop_with_catalog: FlushRelationBuffers returned %d",
1440 * remove rules if necessary
1443 if (rel->rd_rules != NULL)
1444 RelationRemoveRules(rid);
1447 RelationRemoveTriggers(rel);
1450 * remove inheritance information
1453 RelationRemoveInheritance(rel);
1456 * remove indexes if necessary
1459 RelationRemoveIndexes(rel);
1462 * delete attribute tuples
1465 DeleteAttributeTuples(rel);
1468 * delete comments, statistics, and constraints
1471 DeleteComments(RelationGetRelid(rel));
1473 RemoveStatistics(rel);
1475 RemoveConstraints(rel);
1481 DeleteTypeTuple(rel);
1484 * delete relation tuple
1487 DeleteRelationTuple(rel);
1490 * unlink the relation's physical file and finish up.
1493 if (rel->rd_rel->relkind != RELKIND_VIEW)
1494 smgrunlink(DEFAULT_SMGR, rel);
1497 * Close relcache entry, but *keep* AccessExclusiveLock on the
1498 * relation until transaction commit. This ensures no one else will
1499 * try to do something with the doomed relation.
1501 heap_close(rel, NoLock);
1504 * flush the relation from the relcache
1507 RelationForgetRelation(rid);
1509 /* and from the temp-table map */
1511 remove_temp_rel_by_relid(rid);
1515 char toast_relname[NAMEDATALEN];
1517 sprintf(toast_relname, "pg_toast_%u", rid);
1518 heap_drop_with_catalog(toast_relname, true);
1524 * Store a default expression for column attnum of relation rel.
1525 * The expression must be presented as a nodeToString() string.
1526 * If updatePgAttribute is true, update the pg_attribute entry
1527 * for the column to show that a default exists.
1530 StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
1531 bool updatePgAttribute)
1537 Relation idescs[Num_pg_attrdef_indices];
1540 static char nulls[4] = {' ', ' ', ' ', ' '};
1542 Relation attridescs[Num_pg_attr_indices];
1544 Form_pg_attribute attStruct;
1547 * Need to construct source equivalent of given node-string.
1549 expr = stringToNode(adbin);
1552 * deparse_expression needs a RangeTblEntry list, so make one
1554 rte = makeNode(RangeTblEntry);
1555 rte->relname = RelationGetRelationName(rel);
1556 rte->relid = RelationGetRelid(rel);
1557 rte->eref = makeNode(Attr);
1558 rte->eref->relname = RelationGetRelationName(rel);
1560 rte->inFromCl = true;
1561 adsrc = deparse_expression(expr, makeList1(makeList1(rte)), false);
1563 values[Anum_pg_attrdef_adrelid - 1] = RelationGetRelid(rel);
1564 values[Anum_pg_attrdef_adnum - 1] = attnum;
1565 values[Anum_pg_attrdef_adbin - 1] = DirectFunctionCall1(textin,
1566 CStringGetDatum(adbin));
1567 values[Anum_pg_attrdef_adsrc - 1] = DirectFunctionCall1(textin,
1568 CStringGetDatum(adsrc));
1569 adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
1570 tuple = heap_formtuple(adrel->rd_att, values, nulls);
1571 heap_insert(adrel, tuple);
1572 CatalogOpenIndices(Num_pg_attrdef_indices, Name_pg_attrdef_indices,
1574 CatalogIndexInsert(idescs, Num_pg_attrdef_indices, adrel, tuple);
1575 CatalogCloseIndices(Num_pg_attrdef_indices, idescs);
1576 heap_close(adrel, RowExclusiveLock);
1578 pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
1579 pfree(DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
1580 heap_freetuple(tuple);
1583 if (!updatePgAttribute)
1584 return; /* done if pg_attribute is OK */
1586 attrrel = heap_openr(AttributeRelationName, RowExclusiveLock);
1587 atttup = SearchSysCacheCopy(ATTNUM,
1588 ObjectIdGetDatum(RelationGetRelid(rel)),
1589 Int16GetDatum(attnum),
1591 if (!HeapTupleIsValid(atttup))
1592 elog(ERROR, "cache lookup of attribute %d in relation %u failed",
1593 attnum, RelationGetRelid(rel));
1594 attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
1595 if (!attStruct->atthasdef)
1597 attStruct->atthasdef = true;
1598 simple_heap_update(attrrel, &atttup->t_self, atttup);
1599 /* keep catalog indices current */
1600 CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices,
1602 CatalogIndexInsert(attridescs, Num_pg_attr_indices, attrrel, atttup);
1603 CatalogCloseIndices(Num_pg_attr_indices, attridescs);
1605 heap_close(attrrel, RowExclusiveLock);
1606 heap_freetuple(atttup);
1610 * Store a constraint expression for the given relation.
1611 * The expression must be presented as a nodeToString() string.
1613 * Caller is responsible for updating the count of constraints
1614 * in the pg_class entry for the relation.
1617 StoreRelCheck(Relation rel, char *ccname, char *ccbin)
1623 Relation idescs[Num_pg_relcheck_indices];
1626 static char nulls[4] = {' ', ' ', ' ', ' '};
1629 * Convert condition to a normal boolean expression tree.
1631 expr = stringToNode(ccbin);
1632 expr = (Node *) make_ands_explicit((List *) expr);
1635 * deparse_expression needs a RangeTblEntry list, so make one
1637 rte = makeNode(RangeTblEntry);
1638 rte->relname = RelationGetRelationName(rel);
1639 rte->relid = RelationGetRelid(rel);
1640 rte->eref = makeNode(Attr);
1641 rte->eref->relname = RelationGetRelationName(rel);
1643 rte->inFromCl = true;
1644 ccsrc = deparse_expression(expr, makeList1(makeList1(rte)), false);
1646 values[Anum_pg_relcheck_rcrelid - 1] = RelationGetRelid(rel);
1647 values[Anum_pg_relcheck_rcname - 1] = DirectFunctionCall1(namein,
1648 CStringGetDatum(ccname));
1649 values[Anum_pg_relcheck_rcbin - 1] = DirectFunctionCall1(textin,
1650 CStringGetDatum(ccbin));
1651 values[Anum_pg_relcheck_rcsrc - 1] = DirectFunctionCall1(textin,
1652 CStringGetDatum(ccsrc));
1653 rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
1654 tuple = heap_formtuple(rcrel->rd_att, values, nulls);
1655 heap_insert(rcrel, tuple);
1656 CatalogOpenIndices(Num_pg_relcheck_indices, Name_pg_relcheck_indices,
1658 CatalogIndexInsert(idescs, Num_pg_relcheck_indices, rcrel, tuple);
1659 CatalogCloseIndices(Num_pg_relcheck_indices, idescs);
1660 heap_close(rcrel, RowExclusiveLock);
1662 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
1663 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
1664 pfree(DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
1665 heap_freetuple(tuple);
1670 * Store defaults and constraints passed in via the tuple constraint struct.
1672 * NOTE: only pre-cooked expressions will be passed this way, which is to
1673 * say expressions inherited from an existing relation. Newly parsed
1674 * expressions can be added later, by direct calls to StoreAttrDefault
1675 * and StoreRelCheck (see AddRelationRawConstraints()). We assume that
1676 * pg_attribute and pg_class entries for the relation were already set
1677 * to reflect the existence of these defaults/constraints.
1680 StoreConstraints(Relation rel)
1682 TupleConstr *constr = rel->rd_att->constr;
1689 * deparsing of constraint expressions will fail unless the
1690 * just-created pg_attribute tuples for this relation are made
1691 * visible. So, bump the command counter.
1693 CommandCounterIncrement();
1695 for (i = 0; i < constr->num_defval; i++)
1696 StoreAttrDefault(rel, constr->defval[i].adnum,
1697 constr->defval[i].adbin, false);
1699 for (i = 0; i < constr->num_check; i++)
1700 StoreRelCheck(rel, constr->check[i].ccname,
1701 constr->check[i].ccbin);
1705 * AddRelationRawConstraints
1707 * Add raw (not-yet-transformed) column default expressions and/or constraint
1708 * check expressions to an existing relation. This is defined to do both
1709 * for efficiency in DefineRelation, but of course you can do just one or
1710 * the other by passing empty lists.
1712 * rel: relation to be modified
1713 * rawColDefaults: list of RawColumnDefault structures
1714 * rawConstraints: list of Constraint nodes
1716 * All entries in rawColDefaults will be processed. Entries in rawConstraints
1717 * will be processed only if they are CONSTR_CHECK type and contain a "raw"
1720 * NB: caller should have opened rel with AccessExclusiveLock, and should
1721 * hold that lock till end of transaction. Also, we assume the caller has
1722 * done a CommandCounterIncrement if necessary to make the relation's catalog
1726 AddRelationRawConstraints(Relation rel,
1727 List *rawColDefaults,
1728 List *rawConstraints)
1730 char *relname = RelationGetRelationName(rel);
1731 TupleDesc tupleDesc;
1732 TupleConstr *oldconstr;
1734 ConstrCheck *oldchecks;
1740 Relation relidescs[Num_pg_class_indices];
1742 Form_pg_class relStruct;
1745 * Get info about existing constraints.
1747 tupleDesc = RelationGetDescr(rel);
1748 oldconstr = tupleDesc->constr;
1751 numoldchecks = oldconstr->num_check;
1752 oldchecks = oldconstr->check;
1761 * Create a dummy ParseState and insert the target relation as its
1762 * sole rangetable entry. We need a ParseState for transformExpr.
1764 pstate = make_parsestate(NULL);
1765 makeRangeTable(pstate, NULL);
1766 rte = addRangeTableEntry(pstate, relname, NULL, false, true);
1767 addRTEtoJoinList(pstate, rte);
1770 * Process column default expressions.
1772 foreach(listptr, rawColDefaults)
1774 RawColumnDefault *colDef = (RawColumnDefault *) lfirst(listptr);
1778 Assert(colDef->raw_default != NULL);
1781 * Transform raw parsetree to executable expression.
1783 expr = transformExpr(pstate, colDef->raw_default, EXPR_COLUMN_FIRST);
1786 * Make sure default expr does not refer to any vars.
1788 if (contain_var_clause(expr))
1789 elog(ERROR, "Cannot use attribute(s) in DEFAULT clause");
1792 * No subplans or aggregates, either...
1794 if (contain_subplans(expr))
1795 elog(ERROR, "Cannot use subselect in DEFAULT clause");
1796 if (contain_agg_clause(expr))
1797 elog(ERROR, "Cannot use aggregate in DEFAULT clause");
1800 * Check that it will be possible to coerce the expression to the
1801 * column's type. We store the expression without coercion,
1802 * however, to avoid premature coercion in cases like
1804 * CREATE TABLE tbl (fld datetime DEFAULT 'now');
1806 * NB: this should match the code in updateTargetListEntry() that
1807 * will actually do the coercion, to ensure we don't accept an
1808 * unusable default expression.
1810 type_id = exprType(expr);
1811 if (type_id != InvalidOid)
1813 Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
1815 if (type_id != atp->atttypid)
1817 if (CoerceTargetExpr(NULL, expr, type_id,
1818 atp->atttypid, atp->atttypmod) == NULL)
1819 elog(ERROR, "Attribute '%s' is of type '%s'"
1820 " but default expression is of type '%s'"
1821 "\n\tYou will need to rewrite or cast the expression",
1822 NameStr(atp->attname),
1823 typeidTypeName(atp->atttypid),
1824 typeidTypeName(type_id));
1829 * Might as well try to reduce any constant expressions.
1831 expr = eval_const_expressions(expr);
1834 * Must fix opids, in case any operators remain...
1841 StoreAttrDefault(rel, colDef->attnum, nodeToString(expr), true);
1845 * Process constraint expressions.
1847 numchecks = numoldchecks;
1848 foreach(listptr, rawConstraints)
1850 Constraint *cdef = (Constraint *) lfirst(listptr);
1854 if (cdef->contype != CONSTR_CHECK || cdef->raw_expr == NULL)
1856 Assert(cdef->cooked_expr == NULL);
1858 /* Check name uniqueness, or generate a new name */
1859 if (cdef->name != NULL)
1864 ccname = cdef->name;
1865 /* Check against old constraints */
1866 for (i = 0; i < numoldchecks; i++)
1868 if (strcmp(oldchecks[i].ccname, ccname) == 0)
1869 elog(ERROR, "Duplicate CHECK constraint name: '%s'",
1872 /* Check against other new constraints */
1873 foreach(listptr2, rawConstraints)
1875 Constraint *cdef2 = (Constraint *) lfirst(listptr2);
1877 if (cdef2 == cdef ||
1878 cdef2->contype != CONSTR_CHECK ||
1879 cdef2->raw_expr == NULL ||
1880 cdef2->name == NULL)
1882 if (strcmp(cdef2->name, ccname) == 0)
1883 elog(ERROR, "Duplicate CHECK constraint name: '%s'",
1889 ccname = (char *) palloc(NAMEDATALEN);
1890 snprintf(ccname, NAMEDATALEN, "$%d", numchecks + 1);
1894 * Transform raw parsetree to executable expression.
1896 expr = transformExpr(pstate, cdef->raw_expr, EXPR_COLUMN_FIRST);
1899 * Make sure it yields a boolean result.
1901 if (exprType(expr) != BOOLOID)
1902 elog(ERROR, "CHECK '%s' does not yield boolean result",
1906 * Make sure no outside relations are referred to.
1908 if (length(pstate->p_rtable) != 1)
1909 elog(ERROR, "Only relation \"%s\" can be referenced in CHECK",
1913 * No subplans or aggregates, either...
1915 if (contain_subplans(expr))
1916 elog(ERROR, "Cannot use subselect in CHECK clause");
1917 if (contain_agg_clause(expr))
1918 elog(ERROR, "Cannot use aggregate in CHECK clause");
1921 * Might as well try to reduce any constant expressions.
1923 expr = eval_const_expressions(expr);
1926 * Constraints are evaluated with execQual, which expects an
1927 * implicit-AND list, so convert expression to implicit-AND form.
1928 * (We could go so far as to convert to CNF, but that's probably
1931 expr = (Node *) make_ands_implicit((Expr *) expr);
1934 * Must fix opids in operator clauses.
1941 StoreRelCheck(rel, ccname, nodeToString(expr));
1947 * Update the count of constraints in the relation's pg_class tuple.
1948 * We do this even if there was no change, in order to ensure that an
1949 * SI update message is sent out for the pg_class tuple, which will
1950 * force other backends to rebuild their relcache entries for the rel.
1951 * (Of course, for a newly created rel there is no need for an SI
1952 * message, but for ALTER TABLE ADD ATTRIBUTE this'd be important.)
1954 relrel = heap_openr(RelationRelationName, RowExclusiveLock);
1955 reltup = SearchSysCacheCopy(RELOID,
1956 ObjectIdGetDatum(RelationGetRelid(rel)),
1958 if (!HeapTupleIsValid(reltup))
1959 elog(ERROR, "cache lookup of relation %u failed",
1960 RelationGetRelid(rel));
1961 relStruct = (Form_pg_class) GETSTRUCT(reltup);
1963 relStruct->relchecks = numchecks;
1965 simple_heap_update(relrel, &reltup->t_self, reltup);
1967 /* keep catalog indices current */
1968 CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices,
1970 CatalogIndexInsert(relidescs, Num_pg_class_indices, relrel, reltup);
1971 CatalogCloseIndices(Num_pg_class_indices, relidescs);
1973 heap_freetuple(reltup);
1974 heap_close(relrel, RowExclusiveLock);
1978 RemoveAttrDefault(Relation rel)
1981 HeapScanDesc adscan;
1985 adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
1987 ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid,
1988 F_OIDEQ, RelationGetRelid(rel));
1990 adscan = heap_beginscan(adrel, 0, SnapshotNow, 1, &key);
1992 while (HeapTupleIsValid(tup = heap_getnext(adscan, 0)))
1994 simple_heap_delete(adrel, &tup->t_self);
1997 heap_endscan(adscan);
1998 heap_close(adrel, RowExclusiveLock);
2002 RemoveRelCheck(Relation rel)
2005 HeapScanDesc rcscan;
2009 rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
2011 ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
2012 F_OIDEQ, RelationGetRelid(rel));
2014 rcscan = heap_beginscan(rcrel, 0, SnapshotNow, 1, &key);
2016 while (HeapTupleIsValid(tup = heap_getnext(rcscan, 0)))
2018 simple_heap_delete(rcrel, &tup->t_self);
2021 heap_endscan(rcscan);
2022 heap_close(rcrel, RowExclusiveLock);
2026 RemoveConstraints(Relation rel)
2028 TupleConstr *constr = rel->rd_att->constr;
2033 if (constr->num_defval > 0)
2034 RemoveAttrDefault(rel);
2036 if (constr->num_check > 0)
2037 RemoveRelCheck(rel);
2041 RemoveStatistics(Relation rel)
2043 Relation pgstatistic;
2048 pgstatistic = heap_openr(StatisticRelationName, RowExclusiveLock);
2050 ScanKeyEntryInitialize(&key, 0x0, Anum_pg_statistic_starelid,
2052 ObjectIdGetDatum(RelationGetRelid(rel)));
2053 scan = heap_beginscan(pgstatistic, false, SnapshotNow, 1, &key);
2055 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
2057 simple_heap_delete(pgstatistic, &tuple->t_self);
2061 heap_close(pgstatistic, RowExclusiveLock);