PostgreSQL Source Code git master
Loading...
Searching...
No Matches
heap.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * heap.c
4 * code to create and destroy POSTGRES heap relations
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/catalog/heap.c
12 *
13 *
14 * INTERFACE ROUTINES
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
18 *
19 * NOTES
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
23 * manager,
24 * just like the poorly named "NewXXX" routines do. The
25 * "New" routines are all going to die soon, once and for all!
26 * -cim 1/13/91
27 *
28 *-------------------------------------------------------------------------
29 */
30#include "postgres.h"
31
32#include "access/genam.h"
33#include "access/multixact.h"
34#include "access/relation.h"
35#include "access/table.h"
36#include "access/tableam.h"
38#include "catalog/catalog.h"
39#include "catalog/heap.h"
40#include "catalog/index.h"
42#include "catalog/partition.h"
43#include "catalog/pg_am.h"
44#include "catalog/pg_attrdef.h"
48#include "catalog/pg_inherits.h"
50#include "catalog/pg_opclass.h"
55#include "catalog/pg_type.h"
56#include "catalog/storage.h"
57#include "commands/tablecmds.h"
58#include "commands/typecmds.h"
59#include "common/int.h"
60#include "miscadmin.h"
61#include "nodes/nodeFuncs.h"
62#include "optimizer/optimizer.h"
63#include "parser/parse_coerce.h"
65#include "parser/parse_expr.h"
67#include "parser/parsetree.h"
69#include "pgstat.h"
70#include "storage/lmgr.h"
71#include "storage/predicate.h"
72#include "utils/array.h"
73#include "utils/builtins.h"
74#include "utils/fmgroids.h"
75#include "utils/inval.h"
76#include "utils/lsyscache.h"
77#include "utils/syscache.h"
78
79
80/* Potentially set by pg_upgrade_support functions */
85
90 Oid reloftype,
92 char relkind,
93 TransactionId relfrozenxid,
94 TransactionId relminmxid,
96 Datum reloptions);
97static ObjectAddress AddNewRelationType(const char *typeName,
100 char new_rel_kind,
101 Oid ownerid,
104static void RelationRemoveInheritance(Oid relid);
105static Oid StoreRelCheck(Relation rel, const char *ccname, Node *expr,
106 bool is_enforced, bool is_validated, bool is_local,
107 int16 inhcount, bool is_no_inherit, bool is_internal);
109 bool is_internal);
110static bool MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr,
111 bool allow_merge, bool is_local,
112 bool is_enforced,
114 bool is_no_inherit);
115static void SetRelationNumChecks(Relation rel, int numchecks);
116static Node *cookConstraint(ParseState *pstate,
118 char *relname);
119
120
121/* ----------------------------------------------------------------
122 * XXX UGLY HARD CODED BADNESS FOLLOWS XXX
123 *
124 * these should all be moved to someplace in the lib/catalog
125 * module, if not obliterated first.
126 * ----------------------------------------------------------------
127 */
128
129
130/*
131 * Note:
132 * Should the system special case these attributes in the future?
133 * Advantage: consume much less space in the ATTRIBUTE relation.
134 * Disadvantage: special cases will be all over the place.
135 */
136
137/*
138 * The initializers below do not include trailing variable length fields,
139 * but that's OK - we're never going to reference anything beyond the
140 * fixed-size portion of the structure anyway. Fields that can default
141 * to zeroes are also not mentioned.
142 */
143
144static const FormData_pg_attribute a1 = {
145 .attname = {"ctid"},
146 .atttypid = TIDOID,
147 .attlen = sizeof(ItemPointerData),
149 .atttypmod = -1,
150 .attbyval = false,
153 .attnotnull = true,
154 .attislocal = true,
155};
156
157static const FormData_pg_attribute a2 = {
158 .attname = {"xmin"},
159 .atttypid = XIDOID,
160 .attlen = sizeof(TransactionId),
162 .atttypmod = -1,
163 .attbyval = true,
166 .attnotnull = true,
167 .attislocal = true,
168};
169
170static const FormData_pg_attribute a3 = {
171 .attname = {"cmin"},
172 .atttypid = CIDOID,
173 .attlen = sizeof(CommandId),
175 .atttypmod = -1,
176 .attbyval = true,
179 .attnotnull = true,
180 .attislocal = true,
181};
182
183static const FormData_pg_attribute a4 = {
184 .attname = {"xmax"},
185 .atttypid = XIDOID,
186 .attlen = sizeof(TransactionId),
188 .atttypmod = -1,
189 .attbyval = true,
192 .attnotnull = true,
193 .attislocal = true,
194};
195
196static const FormData_pg_attribute a5 = {
197 .attname = {"cmax"},
198 .atttypid = CIDOID,
199 .attlen = sizeof(CommandId),
201 .atttypmod = -1,
202 .attbyval = true,
205 .attnotnull = true,
206 .attislocal = true,
207};
208
209/*
210 * We decided to call this attribute "tableoid" rather than say
211 * "classoid" on the basis that in the future there may be more than one
212 * table of a particular class/type. In any case table is still the word
213 * used in SQL.
214 */
215static const FormData_pg_attribute a6 = {
216 .attname = {"tableoid"},
217 .atttypid = OIDOID,
218 .attlen = sizeof(Oid),
220 .atttypmod = -1,
221 .attbyval = true,
224 .attnotnull = true,
225 .attislocal = true,
226};
227
228static const FormData_pg_attribute *const SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6};
229
230/*
231 * This function returns a Form_pg_attribute pointer for a system attribute.
232 * Note that we elog if the presented attno is invalid, which would only
233 * happen if there's a problem upstream.
234 */
237{
238 if (attno >= 0 || attno < -(int) lengthof(SysAtt))
239 elog(ERROR, "invalid system attribute number %d", attno);
240 return SysAtt[-attno - 1];
241}
242
243/*
244 * If the given name is a system attribute name, return a Form_pg_attribute
245 * pointer for a prototype definition. If not, return NULL.
246 */
249{
250 int j;
251
252 for (j = 0; j < (int) lengthof(SysAtt); j++)
253 {
255
256 if (strcmp(NameStr(att->attname), attname) == 0)
257 return att;
258 }
259
260 return NULL;
261}
262
263
264/* ----------------------------------------------------------------
265 * XXX END OF UGLY HARD CODED BADNESS XXX
266 * ---------------------------------------------------------------- */
267
268
269/* ----------------------------------------------------------------
270 * heap_create - Create an uncataloged heap relation
271 *
272 * Note API change: the caller must now always provide the OID
273 * to use for the relation. The relfilenumber may be (and in
274 * the simplest cases is) left unspecified.
275 *
276 * create_storage indicates whether or not to create the storage.
277 * However, even if create_storage is true, no storage will be
278 * created if the relkind is one that doesn't have storage.
279 *
280 * rel->rd_rel is initialized by RelationBuildLocalRelation,
281 * and is mostly zeroes at return.
282 * ----------------------------------------------------------------
283 */
286 Oid relnamespace,
287 Oid reltablespace,
288 Oid relid,
289 RelFileNumber relfilenumber,
291 TupleDesc tupDesc,
292 char relkind,
293 char relpersistence,
294 bool shared_relation,
295 bool mapped_relation,
297 TransactionId *relfrozenxid,
298 MultiXactId *relminmxid,
299 bool create_storage)
300{
301 Relation rel;
302
303 /* The caller must have provided an OID for the relation. */
304 Assert(OidIsValid(relid));
305
306 /*
307 * Don't allow creating relations in pg_catalog directly, even though it
308 * is allowed to move user defined relations there. Semantics with search
309 * paths including pg_catalog are too confusing for now.
310 *
311 * But allow creating indexes on relations in pg_catalog even if
312 * allow_system_table_mods = off, upper layers already guarantee it's on a
313 * user defined relation, not a system one.
314 */
316 ((IsCatalogNamespace(relnamespace) && relkind != RELKIND_INDEX) ||
317 IsToastNamespace(relnamespace)) &&
321 errmsg("permission denied to create \"%s.%s\"",
322 get_namespace_name(relnamespace), relname),
323 errdetail("System catalog modifications are currently disallowed.")));
324
325 *relfrozenxid = InvalidTransactionId;
326 *relminmxid = InvalidMultiXactId;
327
328 /*
329 * Force reltablespace to zero if the relation kind does not support
330 * tablespaces. This is mainly just for cleanliness' sake.
331 */
332 if (!RELKIND_HAS_TABLESPACE(relkind))
333 reltablespace = InvalidOid;
334
335 /* Don't create storage for relkinds without physical storage. */
336 if (!RELKIND_HAS_STORAGE(relkind))
337 create_storage = false;
338 else
339 {
340 /*
341 * If relfilenumber is unspecified by the caller then create storage
342 * with oid same as relid.
343 */
344 if (!RelFileNumberIsValid(relfilenumber))
345 relfilenumber = relid;
346 }
347
348 /*
349 * Never allow a pg_class entry to explicitly specify the database's
350 * default tablespace in reltablespace; force it to zero instead. This
351 * ensures that if the database is cloned with a different default
352 * tablespace, the pg_class entry will still match where CREATE DATABASE
353 * will put the physically copied relation.
354 *
355 * Yes, this is a bit of a hack.
356 */
357 if (reltablespace == MyDatabaseTableSpace)
358 reltablespace = InvalidOid;
359
360 /*
361 * build the relcache entry.
362 */
364 relnamespace,
365 tupDesc,
366 relid,
367 accessmtd,
368 relfilenumber,
369 reltablespace,
372 relpersistence,
373 relkind);
374
375 /*
376 * Have the storage manager create the relation's disk file, if needed.
377 *
378 * For tables, the AM callback creates both the main and the init fork.
379 * For others, only the main fork is created; the other forks will be
380 * created on demand.
381 */
382 if (create_storage)
383 {
384 if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind))
386 relpersistence,
387 relfrozenxid, relminmxid);
388 else if (RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
389 RelationCreateStorage(rel->rd_locator, relpersistence, true);
390 else
391 Assert(false);
392 }
393
394 /*
395 * If a tablespace is specified, removal of that tablespace is normally
396 * protected by the existence of a physical file; but for relations with
397 * no files, add a pg_shdepend entry to account for that.
398 */
399 if (!create_storage && reltablespace != InvalidOid)
401 reltablespace);
402
403 /* ensure that stats are dropped if transaction aborts */
405
406 return rel;
407}
408
409/* ----------------------------------------------------------------
410 * heap_create_with_catalog - Create a cataloged relation
411 *
412 * this is done in multiple steps:
413 *
414 * 1) CheckAttributeNamesTypes() is used to make certain the tuple
415 * descriptor contains a valid set of attribute names and types
416 *
417 * 2) pg_class is opened and get_relname_relid()
418 * performs a scan to ensure that no relation with the
419 * same name already exists.
420 *
421 * 3) heap_create() is called to create the new relation on disk.
422 *
423 * 4) TypeCreate() is called to define a new type corresponding
424 * to the new relation.
425 *
426 * 5) AddNewRelationTuple() is called to register the
427 * relation in pg_class.
428 *
429 * 6) AddNewAttributeTuples() is called to register the
430 * new relation's schema in pg_attribute.
431 *
432 * 7) StoreConstraints() is called - vadim 08/22/97
433 *
434 * 8) the relations are closed and the new relation's oid
435 * is returned.
436 *
437 * ----------------------------------------------------------------
438 */
439
440/* --------------------------------
441 * CheckAttributeNamesTypes
442 *
443 * this is used to make certain the tuple descriptor contains a
444 * valid set of attribute names and datatypes. a problem simply
445 * generates ereport(ERROR) which aborts the current transaction.
446 *
447 * relkind is the relkind of the relation to be created.
448 * flags controls which datatypes are allowed, cf CheckAttributeType.
449 * --------------------------------
450 */
451void
453 int flags)
454{
455 int i;
456 int j;
457 int natts = tupdesc->natts;
458
459 /* Sanity check on column count */
463 errmsg("tables can have at most %d columns",
465
466 /*
467 * first check for collision with system attribute names
468 *
469 * Skip this for a view or type relation, since those don't have system
470 * attributes.
471 */
472 if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
473 {
474 for (i = 0; i < natts; i++)
475 {
476 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
477
478 if (SystemAttributeByName(NameStr(attr->attname)) != NULL)
481 errmsg("column name \"%s\" conflicts with a system column name",
482 NameStr(attr->attname))));
483 }
484 }
485
486 /*
487 * next check for repeated attribute names
488 */
489 for (i = 1; i < natts; i++)
490 {
491 for (j = 0; j < i; j++)
492 {
493 if (strcmp(NameStr(TupleDescAttr(tupdesc, j)->attname),
494 NameStr(TupleDescAttr(tupdesc, i)->attname)) == 0)
497 errmsg("column name \"%s\" specified more than once",
498 NameStr(TupleDescAttr(tupdesc, j)->attname))));
499 }
500 }
501
502 /*
503 * next check the attribute types
504 */
505 for (i = 0; i < natts; i++)
506 {
508 TupleDescAttr(tupdesc, i)->atttypid,
509 TupleDescAttr(tupdesc, i)->attcollation,
510 NIL, /* assume we're creating a new rowtype */
511 flags | (TupleDescAttr(tupdesc, i)->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL ? CHKATYPE_IS_VIRTUAL : 0));
512 }
513}
514
515/* --------------------------------
516 * CheckAttributeType
517 *
518 * Verify that the proposed datatype of an attribute is legal.
519 * This is needed mainly because there are types (and pseudo-types)
520 * in the catalogs that we do not support as elements of real tuples.
521 * We also check some other properties required of a table column.
522 *
523 * If the attribute is being proposed for addition to an existing table or
524 * composite type, pass a one-element list of the rowtype OID as
525 * containing_rowtypes. When checking a to-be-created rowtype, it's
526 * sufficient to pass NIL, because there could not be any recursive reference
527 * to a not-yet-existing rowtype.
528 *
529 * flags is a bitmask controlling which datatypes we allow. For the most
530 * part, pseudo-types are disallowed as attribute types, but there are some
531 * exceptions: ANYARRAYOID, RECORDOID, and RECORDARRAYOID can be allowed
532 * in some cases. (This works because values of those type classes are
533 * self-identifying to some extent. However, RECORDOID and RECORDARRAYOID
534 * are reliably identifiable only within a session, since the identity info
535 * may use a typmod that is only locally assigned. The caller is expected
536 * to know whether these cases are safe.)
537 *
538 * flags can also control the phrasing of the error messages. If
539 * CHKATYPE_IS_PARTKEY is specified, "attname" should be a partition key
540 * column number as text, not a real column name.
541 * --------------------------------
542 */
543void
545 Oid atttypid, Oid attcollation,
547 int flags)
548{
551
552 /* since this function recurses, it could be driven to stack overflow */
554
556 {
557 /*
558 * We disallow pseudo-type columns, with the exception of ANYARRAY,
559 * RECORD, and RECORD[] when the caller says that those are OK.
560 *
561 * We don't need to worry about recursive containment for RECORD and
562 * RECORD[] because (a) no named composite type should be allowed to
563 * contain those, and (b) two "anonymous" record types couldn't be
564 * considered to be the same type, so infinite recursion isn't
565 * possible.
566 */
567 if (!((atttypid == ANYARRAYOID && (flags & CHKATYPE_ANYARRAY)) ||
568 (atttypid == RECORDOID && (flags & CHKATYPE_ANYRECORD)) ||
569 (atttypid == RECORDARRAYOID && (flags & CHKATYPE_ANYRECORD))))
570 {
571 if (flags & CHKATYPE_IS_PARTKEY)
574 /* translator: first %s is an integer not a name */
575 errmsg("partition key column %s has pseudo-type %s",
577 else
580 errmsg("column \"%s\" has pseudo-type %s",
582 }
583 }
584 else if (att_typtype == TYPTYPE_DOMAIN)
585 {
586 /*
587 * Prevent virtual generated columns from having a domain type. We
588 * would have to enforce domain constraints when columns underlying
589 * the generated column change. This could possibly be implemented,
590 * but it's not.
591 */
592 if (flags & CHKATYPE_IS_VIRTUAL)
595 errmsg("virtual generated column \"%s\" cannot have a domain type", attname));
596
597 /*
598 * If it's a domain, recurse to check its base type.
599 */
602 flags);
603 }
604 else if (att_typtype == TYPTYPE_COMPOSITE)
605 {
606 /*
607 * For a composite type, recurse into its attributes.
608 */
609 Relation relation;
610 TupleDesc tupdesc;
611 int i;
612
613 /*
614 * Check for self-containment. Eventually we might be able to allow
615 * this (just return without complaint, if so) but it's not clear how
616 * many other places would require anti-recursion defenses before it
617 * would be safe to allow tables to contain their own rowtype.
618 */
622 errmsg("composite type %s cannot be made a member of itself",
624
626
628
629 tupdesc = RelationGetDescr(relation);
630
631 for (i = 0; i < tupdesc->natts; i++)
632 {
633 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
634
635 if (attr->attisdropped)
636 continue;
637 CheckAttributeType(NameStr(attr->attname),
638 attr->atttypid, attr->attcollation,
640 flags & ~CHKATYPE_IS_PARTKEY);
641 }
642
644
646 }
647 else if (att_typtype == TYPTYPE_RANGE)
648 {
649 /*
650 * If it's a range, recurse to check its subtype.
651 */
655 flags);
656 }
658 {
659 /*
660 * Must recurse into array types, too, in case they are composite.
661 */
664 flags);
665 }
666
667 /*
668 * For consistency with check_virtual_generated_security().
669 */
673 errmsg("virtual generated column \"%s\" cannot have a user-defined type", attname),
674 errdetail("Virtual generated columns that make use of user-defined types are not yet supported."));
675
676 /*
677 * This might not be strictly invalid per SQL standard, but it is pretty
678 * useless, and it cannot be dumped, so we must disallow it.
679 */
680 if (!OidIsValid(attcollation) && type_is_collatable(atttypid))
681 {
682 if (flags & CHKATYPE_IS_PARTKEY)
685 /* translator: first %s is an integer not a name */
686 errmsg("no collation was derived for partition key column %s with collatable type %s",
688 errhint("Use the COLLATE clause to set the collation explicitly.")));
689 else
692 errmsg("no collation was derived for column \"%s\" with collatable type %s",
694 errhint("Use the COLLATE clause to set the collation explicitly.")));
695 }
696}
697
698/*
699 * InsertPgAttributeTuples
700 * Construct and insert a set of tuples in pg_attribute.
701 *
702 * Caller has already opened and locked pg_attribute. tupdesc contains the
703 * attributes to insert. tupdesc_extra supplies the values for certain
704 * variable-length/nullable pg_attribute fields and must contain the same
705 * number of elements as tupdesc or be NULL. The other variable-length fields
706 * of pg_attribute are always initialized to null values.
707 *
708 * indstate is the index state for CatalogTupleInsertWithInfo. It can be
709 * passed as NULL, in which case we'll fetch the necessary info. (Don't do
710 * this when inserting multiple attributes, because it's a tad more
711 * expensive.)
712 *
713 * new_rel_oid is the relation OID assigned to the attributes inserted.
714 * If set to InvalidOid, the relation OID from tupdesc is used instead.
715 */
716void
718 TupleDesc tupdesc,
722{
723 TupleTableSlot **slot;
724 TupleDesc td;
725 int nslots;
726 int natts = 0;
727 int slotCount = 0;
728 bool close_index = false;
729
731
732 /* Initialize the number of slots to use */
733 nslots = Min(tupdesc->natts,
735 slot = palloc_array(TupleTableSlot *, nslots);
736 for (int i = 0; i < nslots; i++)
738
739 while (natts < tupdesc->natts)
740 {
741 Form_pg_attribute attrs = TupleDescAttr(tupdesc, natts);
743
745
746 memset(slot[slotCount]->tts_isnull, false,
747 slot[slotCount]->tts_tupleDescriptor->natts * sizeof(bool));
748
749 if (new_rel_oid != InvalidOid)
751 else
753
773 if (attrs_extra)
774 {
775 slot[slotCount]->tts_values[Anum_pg_attribute_attstattarget - 1] = attrs_extra->attstattarget.value;
776 slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = attrs_extra->attstattarget.isnull;
777
778 slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.value;
779 slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.isnull;
780 }
781 else
782 {
785 }
786
787 /*
788 * The remaining fields are not set for new columns.
789 */
793
795 slotCount++;
796
797 /*
798 * If slots are full or the end of processing has been reached, insert
799 * a batch of tuples.
800 */
801 if (slotCount == nslots || natts == tupdesc->natts - 1)
802 {
803 /* fetch index info only when we know we need it */
804 if (!indstate)
805 {
807 close_index = true;
808 }
809
810 /* insert the new tuples and update the indexes */
812 indstate);
813 slotCount = 0;
814 }
815
816 natts++;
817 }
818
819 if (close_index)
821 for (int i = 0; i < nslots; i++)
823 pfree(slot);
824}
825
826/* --------------------------------
827 * AddNewAttributeTuples
828 *
829 * this registers the new relation's schema by adding
830 * tuples to pg_attribute.
831 * --------------------------------
832 */
833static void
835 TupleDesc tupdesc,
836 char relkind)
837{
838 Relation rel;
840 int natts = tupdesc->natts;
843
844 /*
845 * open pg_attribute and its indexes.
846 */
848
850
852
853 /* add dependencies on their datatypes and collations */
854 for (int i = 0; i < natts; i++)
855 {
856 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
857
858 /* Add dependency info */
862
863 /* The default collation is pinned, so don't bother recording it */
864 if (OidIsValid(attr->attcollation) &&
865 attr->attcollation != DEFAULT_COLLATION_OID)
866 {
868 attr->attcollation);
870 }
871 }
872
873 /*
874 * Next we add the system attributes. Skip all for a view or type
875 * relation. We don't bother with making datatype dependencies here,
876 * since presumably all these types are pinned.
877 */
878 if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
879 {
880 TupleDesc td;
881
883
885 FreeTupleDesc(td);
886 }
887
888 /*
889 * clean up
890 */
892
894}
895
896/* --------------------------------
897 * InsertPgClassTuple
898 *
899 * Construct and insert a new tuple in pg_class.
900 *
901 * Caller has already opened and locked pg_class.
902 * Tuple data is taken from new_rel_desc->rd_rel, except for the
903 * variable-width fields which are not present in a cached reldesc.
904 * relacl and reloptions are passed in Datum form (to avoid having
905 * to reference the data types in heap.h). Pass (Datum) 0 to set them
906 * to NULL.
907 * --------------------------------
908 */
909void
914 Datum reloptions)
915{
916 Form_pg_class rd_rel = new_rel_desc->rd_rel;
918 bool nulls[Natts_pg_class];
920
921 /* This is a tad tedious, but way cleaner than what we used to do... */
922 memset(values, 0, sizeof(values));
923 memset(nulls, false, sizeof(nulls));
924
926 values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname);
927 values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace);
928 values[Anum_pg_class_reltype - 1] = ObjectIdGetDatum(rd_rel->reltype);
929 values[Anum_pg_class_reloftype - 1] = ObjectIdGetDatum(rd_rel->reloftype);
930 values[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(rd_rel->relowner);
931 values[Anum_pg_class_relam - 1] = ObjectIdGetDatum(rd_rel->relam);
932 values[Anum_pg_class_relfilenode - 1] = ObjectIdGetDatum(rd_rel->relfilenode);
933 values[Anum_pg_class_reltablespace - 1] = ObjectIdGetDatum(rd_rel->reltablespace);
934 values[Anum_pg_class_relpages - 1] = Int32GetDatum(rd_rel->relpages);
935 values[Anum_pg_class_reltuples - 1] = Float4GetDatum(rd_rel->reltuples);
936 values[Anum_pg_class_relallvisible - 1] = Int32GetDatum(rd_rel->relallvisible);
937 values[Anum_pg_class_relallfrozen - 1] = Int32GetDatum(rd_rel->relallfrozen);
938 values[Anum_pg_class_reltoastrelid - 1] = ObjectIdGetDatum(rd_rel->reltoastrelid);
939 values[Anum_pg_class_relhasindex - 1] = BoolGetDatum(rd_rel->relhasindex);
940 values[Anum_pg_class_relisshared - 1] = BoolGetDatum(rd_rel->relisshared);
941 values[Anum_pg_class_relpersistence - 1] = CharGetDatum(rd_rel->relpersistence);
942 values[Anum_pg_class_relkind - 1] = CharGetDatum(rd_rel->relkind);
943 values[Anum_pg_class_relnatts - 1] = Int16GetDatum(rd_rel->relnatts);
944 values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks);
945 values[Anum_pg_class_relhasrules - 1] = BoolGetDatum(rd_rel->relhasrules);
946 values[Anum_pg_class_relhastriggers - 1] = BoolGetDatum(rd_rel->relhastriggers);
947 values[Anum_pg_class_relrowsecurity - 1] = BoolGetDatum(rd_rel->relrowsecurity);
948 values[Anum_pg_class_relforcerowsecurity - 1] = BoolGetDatum(rd_rel->relforcerowsecurity);
949 values[Anum_pg_class_relhassubclass - 1] = BoolGetDatum(rd_rel->relhassubclass);
950 values[Anum_pg_class_relispopulated - 1] = BoolGetDatum(rd_rel->relispopulated);
951 values[Anum_pg_class_relreplident - 1] = CharGetDatum(rd_rel->relreplident);
952 values[Anum_pg_class_relispartition - 1] = BoolGetDatum(rd_rel->relispartition);
953 values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
954 values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
955 values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
956 if (relacl != (Datum) 0)
958 else
959 nulls[Anum_pg_class_relacl - 1] = true;
960 if (reloptions != (Datum) 0)
961 values[Anum_pg_class_reloptions - 1] = reloptions;
962 else
963 nulls[Anum_pg_class_reloptions - 1] = true;
964
965 /* relpartbound is set by updating this tuple, if necessary */
966 nulls[Anum_pg_class_relpartbound - 1] = true;
967
969
970 /* finally insert the new tuple, update the indexes, and clean up */
972
974}
975
976/* --------------------------------
977 * AddNewRelationTuple
978 *
979 * this registers the new relation in the catalogs by
980 * adding a tuple to pg_class.
981 * --------------------------------
982 */
983static void
988 Oid reloftype,
990 char relkind,
991 TransactionId relfrozenxid,
992 TransactionId relminmxid,
994 Datum reloptions)
995{
997
998 /*
999 * first we update some of the information in our uncataloged relation's
1000 * relation descriptor.
1001 */
1002 new_rel_reltup = new_rel_desc->rd_rel;
1003
1004 /* The relation is empty */
1005 new_rel_reltup->relpages = 0;
1006 new_rel_reltup->reltuples = -1;
1007 new_rel_reltup->relallvisible = 0;
1008 new_rel_reltup->relallfrozen = 0;
1009
1010 /* Sequences always have a known size */
1011 if (relkind == RELKIND_SEQUENCE)
1012 {
1013 new_rel_reltup->relpages = 1;
1014 new_rel_reltup->reltuples = 1;
1015 }
1016
1017 new_rel_reltup->relfrozenxid = relfrozenxid;
1018 new_rel_reltup->relminmxid = relminmxid;
1019 new_rel_reltup->relowner = relowner;
1020 new_rel_reltup->reltype = new_type_oid;
1021 new_rel_reltup->reloftype = reloftype;
1022
1023 /* relispartition is always set by updating this tuple later */
1024 new_rel_reltup->relispartition = false;
1025
1026 /* fill rd_att's type ID with something sane even if reltype is zero */
1027 new_rel_desc->rd_att->tdtypeid = new_type_oid ? new_type_oid : RECORDOID;
1028 new_rel_desc->rd_att->tdtypmod = -1;
1029
1030 /* Now build and insert the tuple */
1032 relacl, reloptions);
1033}
1034
1035
1036/* --------------------------------
1037 * AddNewRelationType -
1038 *
1039 * define a composite type corresponding to the new relation
1040 * --------------------------------
1041 */
1042static ObjectAddress
1043AddNewRelationType(const char *typeName,
1046 char new_rel_kind,
1047 Oid ownerid,
1050{
1051 return
1052 TypeCreate(new_row_type, /* optional predetermined OID */
1053 typeName, /* type name */
1054 typeNamespace, /* type namespace */
1055 new_rel_oid, /* relation oid */
1056 new_rel_kind, /* relation kind */
1057 ownerid, /* owner's ID */
1058 -1, /* internal size (varlena) */
1059 TYPTYPE_COMPOSITE, /* type-type (composite) */
1060 TYPCATEGORY_COMPOSITE, /* type-category (ditto) */
1061 false, /* composite types are never preferred */
1062 DEFAULT_TYPDELIM, /* default array delimiter */
1063 F_RECORD_IN, /* input procedure */
1064 F_RECORD_OUT, /* output procedure */
1065 F_RECORD_RECV, /* receive procedure */
1066 F_RECORD_SEND, /* send procedure */
1067 InvalidOid, /* typmodin procedure - none */
1068 InvalidOid, /* typmodout procedure - none */
1069 InvalidOid, /* analyze procedure - default */
1070 InvalidOid, /* subscript procedure - none */
1071 InvalidOid, /* array element type - irrelevant */
1072 false, /* this is not an array type */
1073 new_array_type, /* array type if any */
1074 InvalidOid, /* domain base type - irrelevant */
1075 NULL, /* default value - none */
1076 NULL, /* default binary representation */
1077 false, /* passed by reference */
1078 TYPALIGN_DOUBLE, /* alignment - must be the largest! */
1079 TYPSTORAGE_EXTENDED, /* fully TOASTable */
1080 -1, /* typmod */
1081 0, /* array dimensions for typBaseType */
1082 false, /* Type NOT NULL */
1083 InvalidOid); /* rowtypes never have a collation */
1084}
1085
1086/* --------------------------------
1087 * heap_create_with_catalog
1088 *
1089 * creates a new cataloged relation. see comments above.
1090 *
1091 * Arguments:
1092 * relname: name to give to new rel
1093 * relnamespace: OID of namespace it goes in
1094 * reltablespace: OID of tablespace it goes in
1095 * relid: OID to assign to new rel, or InvalidOid to select a new OID
1096 * reltypeid: OID to assign to rel's rowtype, or InvalidOid to select one
1097 * reloftypeid: if a typed table, OID of underlying type; else InvalidOid
1098 * ownerid: OID of new rel's owner
1099 * accessmtd: OID of new rel's access method
1100 * tupdesc: tuple descriptor (source of column definitions)
1101 * cooked_constraints: list of precooked check constraints and defaults
1102 * relkind: relkind for new rel
1103 * relpersistence: rel's persistence status (permanent, temp, or unlogged)
1104 * shared_relation: true if it's to be a shared relation
1105 * mapped_relation: true if the relation will use the relfilenumber map
1106 * oncommit: ON COMMIT marking (only relevant if it's a temp table)
1107 * reloptions: reloptions in Datum form, or (Datum) 0 if none
1108 * use_user_acl: true if should look for user-defined default permissions;
1109 * if false, relacl is always set NULL
1110 * allow_system_table_mods: true to allow creation in system namespaces
1111 * is_internal: is this a system-generated catalog?
1112 * relrewrite: link to original relation during a table rewrite
1113 *
1114 * Output parameters:
1115 * typaddress: if not null, gets the object address of the new pg_type entry
1116 * (this must be null if the relkind is one that doesn't get a pg_type entry)
1117 *
1118 * Returns the OID of the new relation
1119 * --------------------------------
1120 */
1121Oid
1123 Oid relnamespace,
1124 Oid reltablespace,
1125 Oid relid,
1126 Oid reltypeid,
1128 Oid ownerid,
1129 Oid accessmtd,
1130 TupleDesc tupdesc,
1132 char relkind,
1133 char relpersistence,
1134 bool shared_relation,
1135 bool mapped_relation,
1136 OnCommitAction oncommit,
1137 Datum reloptions,
1138 bool use_user_acl,
1140 bool is_internal,
1143{
1146 Acl *relacl;
1150
1151 /* By default set to InvalidOid unless overridden by binary-upgrade */
1152 RelFileNumber relfilenumber = InvalidRelFileNumber;
1153 TransactionId relfrozenxid;
1154 MultiXactId relminmxid;
1155
1157
1158 /*
1159 * sanity checks
1160 */
1162
1163 /*
1164 * Validate proposed tupdesc for the desired relkind. If
1165 * allow_system_table_mods is on, allow ANYARRAY to be used; this is a
1166 * hack to allow creating pg_statistic and cloning it during VACUUM FULL.
1167 */
1168 CheckAttributeNamesTypes(tupdesc, relkind,
1170
1171 /*
1172 * This would fail later on anyway, if the relation already exists. But
1173 * by catching it here we can emit a nicer error message.
1174 */
1175 existing_relid = get_relname_relid(relname, relnamespace);
1177 ereport(ERROR,
1179 errmsg("relation \"%s\" already exists", relname)));
1180
1181 /*
1182 * Since we are going to create a rowtype as well, also check for
1183 * collision with an existing type name. If there is one and it's an
1184 * autogenerated array, we can rename it out of the way; otherwise we can
1185 * at least give a good error message.
1186 */
1189 ObjectIdGetDatum(relnamespace));
1191 {
1192 if (!moveArrayTypeName(old_type_oid, relname, relnamespace))
1193 ereport(ERROR,
1195 errmsg("type \"%s\" already exists", relname),
1196 errhint("A relation has an associated type of the same name, "
1197 "so you must use a name that doesn't conflict "
1198 "with any existing type.")));
1199 }
1200
1201 /*
1202 * Shared relations must be in pg_global (last-ditch check)
1203 */
1204 if (shared_relation && reltablespace != GLOBALTABLESPACE_OID)
1205 elog(ERROR, "shared relations must be placed in pg_global tablespace");
1206
1207 /*
1208 * Allocate an OID for the relation, unless we were told what to use.
1209 *
1210 * The OID will be the relfilenumber as well, so make sure it doesn't
1211 * collide with either pg_class OIDs or existing physical files.
1212 */
1213 if (!OidIsValid(relid))
1214 {
1215 /* Use binary-upgrade override for pg_class.oid and relfilenumber */
1216 if (IsBinaryUpgrade)
1217 {
1218 /*
1219 * Indexes are not supported here; they use
1220 * binary_upgrade_next_index_pg_class_oid.
1221 */
1222 Assert(relkind != RELKIND_INDEX);
1224
1225 if (relkind == RELKIND_TOASTVALUE)
1226 {
1227 /* There might be no TOAST table, so we have to test for it. */
1229 {
1232
1234 ereport(ERROR,
1236 errmsg("toast relfilenumber value not set when in binary upgrade mode")));
1237
1240 }
1241 }
1242 else
1243 {
1245 ereport(ERROR,
1247 errmsg("pg_class heap OID value not set when in binary upgrade mode")));
1248
1251
1252 if (RELKIND_HAS_STORAGE(relkind))
1253 {
1255 ereport(ERROR,
1257 errmsg("relfilenumber value not set when in binary upgrade mode")));
1258
1261 }
1262 }
1263 }
1264
1265 if (!OidIsValid(relid))
1266 relid = GetNewRelFileNumber(reltablespace, pg_class_desc,
1267 relpersistence);
1268 }
1269
1270 /*
1271 * Other sessions' catalog scans can't find this until we commit. Hence,
1272 * it doesn't hurt to hold AccessExclusiveLock. Do it here so callers
1273 * can't accidentally vary in their lock mode or acquisition timing.
1274 */
1276
1277 /*
1278 * Determine the relation's initial permissions.
1279 */
1280 if (use_user_acl)
1281 {
1282 switch (relkind)
1283 {
1284 case RELKIND_RELATION:
1285 case RELKIND_VIEW:
1286 case RELKIND_MATVIEW:
1290 relnamespace);
1291 break;
1292 case RELKIND_SEQUENCE:
1294 relnamespace);
1295 break;
1296 default:
1297 relacl = NULL;
1298 break;
1299 }
1300 }
1301 else
1302 relacl = NULL;
1303
1304 /*
1305 * Create the relcache entry (mostly dummy at this point) and the physical
1306 * disk file. (If we fail further down, it's the smgr's responsibility to
1307 * remove the disk file again.)
1308 *
1309 * NB: Note that passing create_storage = true is correct even for binary
1310 * upgrade. The storage we create here will be replaced later, but we
1311 * need to have something on disk in the meanwhile.
1312 */
1314 relnamespace,
1315 reltablespace,
1316 relid,
1317 relfilenumber,
1318 accessmtd,
1319 tupdesc,
1320 relkind,
1321 relpersistence,
1325 &relfrozenxid,
1326 &relminmxid,
1327 true);
1328
1330
1331 new_rel_desc->rd_rel->relrewrite = relrewrite;
1332
1333 /*
1334 * Decide whether to create a pg_type entry for the relation's rowtype.
1335 * These types are made except where the use of a relation as such is an
1336 * implementation detail: toast tables, sequences and indexes.
1337 */
1338 if (!(relkind == RELKIND_SEQUENCE ||
1339 relkind == RELKIND_TOASTVALUE ||
1340 relkind == RELKIND_INDEX ||
1341 relkind == RELKIND_PARTITIONED_INDEX))
1342 {
1345 char *relarrayname;
1346
1347 /*
1348 * We'll make an array over the composite type, too. For largely
1349 * historical reasons, the array type's OID is assigned first.
1350 */
1352
1353 /*
1354 * Make the pg_type entry for the composite type. The OID of the
1355 * composite type can be preselected by the caller, but if reltypeid
1356 * is InvalidOid, we'll generate a new OID for it.
1357 *
1358 * NOTE: we could get a unique-index failure here, in case someone
1359 * else is creating the same type name in parallel but hadn't
1360 * committed yet when we checked for a duplicate name above.
1361 */
1363 relnamespace,
1364 relid,
1365 relkind,
1366 ownerid,
1367 reltypeid,
1369 new_type_oid = new_type_addr.objectId;
1370 if (typaddress)
1372
1373 /* Now create the array type. */
1374 relarrayname = makeArrayTypeName(relname, relnamespace);
1375
1376 TypeCreate(new_array_oid, /* force the type's OID to this */
1377 relarrayname, /* Array type name */
1378 relnamespace, /* Same namespace as parent */
1379 InvalidOid, /* Not composite, no relationOid */
1380 0, /* relkind, also N/A here */
1381 ownerid, /* owner's ID */
1382 -1, /* Internal size (varlena) */
1383 TYPTYPE_BASE, /* Not composite - typelem is */
1384 TYPCATEGORY_ARRAY, /* type-category (array) */
1385 false, /* array types are never preferred */
1386 DEFAULT_TYPDELIM, /* default array delimiter */
1387 F_ARRAY_IN, /* array input proc */
1388 F_ARRAY_OUT, /* array output proc */
1389 F_ARRAY_RECV, /* array recv (bin) proc */
1390 F_ARRAY_SEND, /* array send (bin) proc */
1391 InvalidOid, /* typmodin procedure - none */
1392 InvalidOid, /* typmodout procedure - none */
1393 F_ARRAY_TYPANALYZE, /* array analyze procedure */
1394 F_ARRAY_SUBSCRIPT_HANDLER, /* array subscript procedure */
1395 new_type_oid, /* array element type - the rowtype */
1396 true, /* yes, this is an array type */
1397 InvalidOid, /* this has no array type */
1398 InvalidOid, /* domain base type - irrelevant */
1399 NULL, /* default value - none */
1400 NULL, /* default binary representation */
1401 false, /* passed by reference */
1402 TYPALIGN_DOUBLE, /* alignment - must be the largest! */
1403 TYPSTORAGE_EXTENDED, /* fully TOASTable */
1404 -1, /* typmod */
1405 0, /* array dimensions for typBaseType */
1406 false, /* Type NOT NULL */
1407 InvalidOid); /* rowtypes never have a collation */
1408
1410 }
1411 else
1412 {
1413 /* Caller should not be expecting a type to be created. */
1416
1418 }
1419
1420 /*
1421 * now create an entry in pg_class for the relation.
1422 *
1423 * NOTE: we could get a unique-index failure here, in case someone else is
1424 * creating the same relation name in parallel but hadn't committed yet
1425 * when we checked for a duplicate name above.
1426 */
1429 relid,
1432 ownerid,
1433 relkind,
1434 relfrozenxid,
1435 relminmxid,
1437 reloptions);
1438
1439 /*
1440 * now add tuples to pg_attribute for the attributes in our new relation.
1441 */
1442 AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind);
1443
1444 /*
1445 * Make a dependency link to force the relation to be deleted if its
1446 * namespace is. Also make a dependency link to its owner, as well as
1447 * dependencies for any roles mentioned in the default ACL.
1448 *
1449 * For composite types, these dependencies are tracked for the pg_type
1450 * entry, so we needn't record them here. Likewise, TOAST tables don't
1451 * need a namespace dependency (they live in a pinned namespace) nor an
1452 * owner dependency (they depend indirectly through the parent table), nor
1453 * should they have any ACL entries. The same applies for extension
1454 * dependencies.
1455 *
1456 * Also, skip this in bootstrap mode, since we don't make dependencies
1457 * while bootstrapping.
1458 */
1459 if (relkind != RELKIND_COMPOSITE_TYPE &&
1460 relkind != RELKIND_TOASTVALUE &&
1462 {
1464 referenced;
1465 ObjectAddresses *addrs;
1466
1468
1470
1472
1474
1475 addrs = new_object_addresses();
1476
1479
1480 if (reloftypeid)
1481 {
1484 }
1485
1486 /*
1487 * Make a dependency link to force the relation to be deleted if its
1488 * access method is.
1489 *
1490 * No need to add an explicit dependency for the toast table, as the
1491 * main table depends on it. Partitioned tables may not have an
1492 * access method set.
1493 */
1494 if ((RELKIND_HAS_TABLE_AM(relkind) && relkind != RELKIND_TOASTVALUE) ||
1496 {
1499 }
1500
1502 free_object_addresses(addrs);
1503 }
1504
1505 /* Post creation hook for new relation */
1506 InvokeObjectPostCreateHookArg(RelationRelationId, relid, 0, is_internal);
1507
1508 /*
1509 * Store any supplied CHECK constraints and defaults.
1510 *
1511 * NB: this may do a CommandCounterIncrement and rebuild the relcache
1512 * entry, so the relation must be valid and self-consistent at this point.
1513 * In particular, there are not yet constraints and defaults anywhere.
1514 */
1516
1517 /*
1518 * If there's a special on-commit action, remember it
1519 */
1520 if (oncommit != ONCOMMIT_NOOP)
1521 register_on_commit_action(relid, oncommit);
1522
1523 /*
1524 * ok, the relation has been cataloged, so close our relations and return
1525 * the OID of the newly created relation.
1526 */
1527 table_close(new_rel_desc, NoLock); /* do not unlock till end of xact */
1529
1530 return relid;
1531}
1532
1533/*
1534 * RelationRemoveInheritance
1535 *
1536 * Formerly, this routine checked for child relations and aborted the
1537 * deletion if any were found. Now we rely on the dependency mechanism
1538 * to check for or delete child relations. By the time we get here,
1539 * there are no children and we need only remove any pg_inherits rows
1540 * linking this relation to its parent(s).
1541 */
1542static void
1566
1567/*
1568 * DeleteRelationTuple
1569 *
1570 * Remove pg_class row for the given relid.
1571 *
1572 * Note: this is shared by relation deletion and index deletion. It's
1573 * not intended for use anyplace else.
1574 */
1575void
1577{
1579 HeapTuple tup;
1580
1581 /* Grab an appropriate lock on the pg_class relation */
1583
1585 if (!HeapTupleIsValid(tup))
1586 elog(ERROR, "cache lookup failed for relation %u", relid);
1587
1588 /* delete the relation tuple from pg_class, and finish up */
1590
1592
1594}
1595
1596/*
1597 * DeleteAttributeTuples
1598 *
1599 * Remove pg_attribute rows for the given relid.
1600 *
1601 * Note: this is shared by relation deletion and index deletion. It's
1602 * not intended for use anyplace else.
1603 */
1604void
1606{
1608 SysScanDesc scan;
1609 ScanKeyData key[1];
1611
1612 /* Grab an appropriate lock on the pg_attribute relation */
1614
1615 /* Use the index to scan only attributes of the target relation */
1616 ScanKeyInit(&key[0],
1619 ObjectIdGetDatum(relid));
1620
1622 NULL, 1, key);
1623
1624 /* Delete all the matching tuples */
1625 while ((atttup = systable_getnext(scan)) != NULL)
1626 CatalogTupleDelete(attrel, &atttup->t_self);
1627
1628 /* Clean up after the scan */
1629 systable_endscan(scan);
1631}
1632
1633/*
1634 * DeleteSystemAttributeTuples
1635 *
1636 * Remove pg_attribute rows for system columns of the given relid.
1637 *
1638 * Note: this is only used when converting a table to a view. Views don't
1639 * have system columns, so we should remove them from pg_attribute.
1640 */
1641void
1643{
1645 SysScanDesc scan;
1646 ScanKeyData key[2];
1648
1649 /* Grab an appropriate lock on the pg_attribute relation */
1651
1652 /* Use the index to scan only system attributes of the target relation */
1653 ScanKeyInit(&key[0],
1656 ObjectIdGetDatum(relid));
1657 ScanKeyInit(&key[1],
1660 Int16GetDatum(0));
1661
1663 NULL, 2, key);
1664
1665 /* Delete all the matching tuples */
1666 while ((atttup = systable_getnext(scan)) != NULL)
1667 CatalogTupleDelete(attrel, &atttup->t_self);
1668
1669 /* Clean up after the scan */
1670 systable_endscan(scan);
1672}
1673
1674/*
1675 * RemoveAttributeById
1676 *
1677 * This is the guts of ALTER TABLE DROP COLUMN: actually mark the attribute
1678 * deleted in pg_attribute. We also remove pg_statistic entries for it.
1679 * (Everything else needed, such as getting rid of any pg_attrdef entry,
1680 * is handled by dependency.c.)
1681 */
1682void
1684{
1685 Relation rel;
1687 HeapTuple tuple;
1689 char newattname[NAMEDATALEN];
1691 bool nullsAtt[Natts_pg_attribute] = {0};
1692 bool replacesAtt[Natts_pg_attribute] = {0};
1693
1694 /*
1695 * Grab an exclusive lock on the target table, which we will NOT release
1696 * until end of transaction. (In the simple case where we are directly
1697 * dropping this column, ATExecDropColumn already did this ... but when
1698 * cascading from a drop of some other object, we may not have any lock.)
1699 */
1700 rel = relation_open(relid, AccessExclusiveLock);
1701
1703
1705 ObjectIdGetDatum(relid),
1707 if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
1708 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1709 attnum, relid);
1711
1712 /* Mark the attribute as dropped */
1713 attStruct->attisdropped = true;
1714
1715 /*
1716 * Set the type OID to invalid. A dropped attribute's type link cannot be
1717 * relied on (once the attribute is dropped, the type might be too).
1718 * Fortunately we do not need the type row --- the only really essential
1719 * information is the type's typlen and typalign, which are preserved in
1720 * the attribute's attlen and attalign. We set atttypid to zero here as a
1721 * means of catching code that incorrectly expects it to be valid.
1722 */
1723 attStruct->atttypid = InvalidOid;
1724
1725 /* Remove any not-null constraint the column may have */
1726 attStruct->attnotnull = false;
1727
1728 /* Unset this so no one tries to look up the generation expression */
1729 attStruct->attgenerated = '\0';
1730
1731 /*
1732 * Change the column name to something that isn't likely to conflict
1733 */
1735 "........pg.dropped.%d........", attnum);
1736 namestrcpy(&(attStruct->attname), newattname);
1737
1738 /* Clear the missing value */
1739 attStruct->atthasmissing = false;
1742
1743 /*
1744 * Clear the other nullable fields. This saves some space in pg_attribute
1745 * and removes no longer useful information.
1746 */
1755
1758
1759 CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
1760
1761 /*
1762 * Because updating the pg_attribute row will trigger a relcache flush for
1763 * the target relation, we need not do anything else to notify other
1764 * backends of the change.
1765 */
1766
1768
1769 RemoveStatistics(relid, attnum);
1770
1771 relation_close(rel, NoLock);
1772}
1773
1774/*
1775 * heap_drop_with_catalog - removes specified relation from catalogs
1776 *
1777 * Note that this routine is not responsible for dropping objects that are
1778 * linked to the pg_class entry via dependencies (for example, indexes and
1779 * constraints). Those are deleted by the dependency-tracing logic in
1780 * dependency.c before control gets here. In general, therefore, this routine
1781 * should never be called directly; go through performDeletion() instead.
1782 */
1783void
1785{
1786 Relation rel;
1787 HeapTuple tuple;
1790
1791 /*
1792 * To drop a partition safely, we must grab exclusive lock on its parent,
1793 * because another backend might be about to execute a query on the parent
1794 * table. If it relies on previously cached partition descriptor, then it
1795 * could attempt to access the just-dropped relation as its partition. We
1796 * must therefore take a table lock strong enough to prevent all queries
1797 * on the table from proceeding until we commit and send out a
1798 * shared-cache-inval notice that will make them update their partition
1799 * descriptors.
1800 */
1801 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1802 if (!HeapTupleIsValid(tuple))
1803 elog(ERROR, "cache lookup failed for relation %u", relid);
1804 if (((Form_pg_class) GETSTRUCT(tuple))->relispartition)
1805 {
1806 /*
1807 * We have to lock the parent if the partition is being detached,
1808 * because it's possible that some query still has a partition
1809 * descriptor that includes this partition.
1810 */
1811 parentOid = get_partition_parent(relid, true);
1813
1814 /*
1815 * If this is not the default partition, dropping it will change the
1816 * default partition's partition constraint, so we must lock it.
1817 */
1819 if (OidIsValid(defaultPartOid) && relid != defaultPartOid)
1821 }
1822
1823 ReleaseSysCache(tuple);
1824
1825 /*
1826 * Open and lock the relation.
1827 */
1828 rel = relation_open(relid, AccessExclusiveLock);
1829
1830 /*
1831 * There can no longer be anyone *else* touching the relation, but we
1832 * might still have open queries or cursors, or pending trigger events, in
1833 * our own session.
1834 */
1835 CheckTableNotInUse(rel, "DROP TABLE");
1836
1837 /*
1838 * This effectively deletes all rows in the table, and may be done in a
1839 * serializable transaction. In that case we must record a rw-conflict in
1840 * to this transaction from each transaction holding a predicate lock on
1841 * the table.
1842 */
1844
1845 /*
1846 * Delete pg_foreign_table tuple first.
1847 */
1848 if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1849 {
1852
1854
1857 elog(ERROR, "cache lookup failed for foreign table %u", relid);
1858
1859 CatalogTupleDelete(ftrel, &fttuple->t_self);
1860
1863 }
1864
1865 /*
1866 * If a partitioned table, delete the pg_partitioned_table tuple.
1867 */
1868 if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1870
1871 /*
1872 * If the relation being dropped is the default partition itself,
1873 * invalidate its entry in pg_partitioned_table.
1874 */
1875 if (relid == defaultPartOid)
1877
1878 /*
1879 * Schedule unlinking of the relation's physical files at commit.
1880 */
1881 if (RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
1883
1884 /* ensure that stats are dropped if transaction commits */
1886
1887 /*
1888 * Close relcache entry, but *keep* AccessExclusiveLock on the relation
1889 * until transaction commit. This ensures no one else will try to do
1890 * something with the doomed relation.
1891 */
1892 relation_close(rel, NoLock);
1893
1894 /*
1895 * Remove any associated relation synchronization states.
1896 */
1898
1899 /*
1900 * Forget any ON COMMIT action for the rel
1901 */
1903
1904 /*
1905 * Flush the relation from the relcache. We want to do this before
1906 * starting to remove catalog entries, just to be certain that no relcache
1907 * entry rebuild will happen partway through. (That should not really
1908 * matter, since we don't do CommandCounterIncrement here, but let's be
1909 * safe.)
1910 */
1912
1913 /*
1914 * remove inheritance information
1915 */
1917
1918 /*
1919 * delete statistics
1920 */
1921 RemoveStatistics(relid, 0);
1922
1923 /*
1924 * delete attribute tuples
1925 */
1926 DeleteAttributeTuples(relid);
1927
1928 /*
1929 * delete relation tuple
1930 */
1931 DeleteRelationTuple(relid);
1932
1933 if (OidIsValid(parentOid))
1934 {
1935 /*
1936 * If this is not the default partition, the partition constraint of
1937 * the default partition has changed to include the portion of the key
1938 * space previously covered by the dropped partition.
1939 */
1940 if (OidIsValid(defaultPartOid) && relid != defaultPartOid)
1942
1943 /*
1944 * Invalidate the parent's relcache so that the partition is no longer
1945 * included in its partition descriptor.
1946 */
1948 /* keep the lock */
1949 }
1950}
1951
1952
1953/*
1954 * RelationClearMissing
1955 *
1956 * Set atthasmissing and attmissingval to false/null for all attributes
1957 * where they are currently set. This can be safely and usefully done if
1958 * the table is rewritten (e.g. by VACUUM FULL or CLUSTER) where we know there
1959 * are no rows left with less than a full complement of attributes.
1960 *
1961 * The caller must have an AccessExclusive lock on the relation.
1962 */
1963void
1965{
1967 Oid relid = RelationGetRelid(rel);
1968 int natts = RelationGetNumberOfAttributes(rel);
1969 int attnum;
1974 HeapTuple tuple,
1975 newtuple;
1976
1977 memset(repl_val, 0, sizeof(repl_val));
1978 memset(repl_null, false, sizeof(repl_null));
1979 memset(repl_repl, false, sizeof(repl_repl));
1980
1983
1986
1987
1988 /* Get a lock on pg_attribute */
1990
1991 /* process each non-system attribute, including any dropped columns */
1992 for (attnum = 1; attnum <= natts; attnum++)
1993 {
1994 tuple = SearchSysCache2(ATTNUM,
1995 ObjectIdGetDatum(relid),
1997 if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
1998 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1999 attnum, relid);
2000
2002
2003 /* ignore any where atthasmissing is not true */
2004 if (attrtuple->atthasmissing)
2005 {
2006 newtuple = heap_modify_tuple(tuple, RelationGetDescr(attr_rel),
2008
2009 CatalogTupleUpdate(attr_rel, &newtuple->t_self, newtuple);
2010
2011 heap_freetuple(newtuple);
2012 }
2013
2014 ReleaseSysCache(tuple);
2015 }
2016
2017 /*
2018 * Our update of the pg_attribute rows will force a relcache rebuild, so
2019 * there's nothing else to do here.
2020 */
2022}
2023
2024/*
2025 * StoreAttrMissingVal
2026 *
2027 * Set the missing value of a single attribute.
2028 */
2029void
2031{
2033 bool nullsAtt[Natts_pg_attribute] = {0};
2034 bool replacesAtt[Natts_pg_attribute] = {0};
2038 newtup;
2039
2040 /* This is only supported for plain tables */
2041 Assert(rel->rd_rel->relkind == RELKIND_RELATION);
2042
2043 /* Fetch the pg_attribute row */
2045
2049 if (!HeapTupleIsValid(atttup)) /* shouldn't happen */
2050 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
2051 attnum, RelationGetRelid(rel));
2053
2054 /* Make a one-element array containing the value */
2056 1,
2057 attStruct->atttypid,
2058 attStruct->attlen,
2059 attStruct->attbyval,
2060 attStruct->attalign));
2061
2062 /* Update the pg_attribute row */
2065
2068
2072
2073 /* clean up */
2076}
2077
2078/*
2079 * SetAttrMissing
2080 *
2081 * Set the missing value of a single attribute. This should only be used by
2082 * binary upgrade. Takes an AccessExclusive lock on the relation owning the
2083 * attribute.
2084 */
2085void
2086SetAttrMissing(Oid relid, char *attname, char *value)
2087{
2089 bool nullsAtt[Natts_pg_attribute] = {0};
2090 bool replacesAtt[Natts_pg_attribute] = {0};
2094 tablerel;
2096 newtup;
2097
2098 /* lock the table the attribute belongs to */
2100
2101 /* Don't do anything unless it's a plain table */
2102 if (tablerel->rd_rel->relkind != RELKIND_RELATION)
2103 {
2105 return;
2106 }
2107
2108 /* Lock the attribute row and get the data */
2112 elog(ERROR, "cache lookup failed for attribute %s of relation %u",
2113 attname, relid);
2115
2116 /* get an array value from the value string */
2119 ObjectIdGetDatum(attStruct->atttypid),
2120 Int32GetDatum(attStruct->atttypmod));
2121
2122 /* update the tuple - set atthasmissing and attmissingval */
2127
2131
2132 /* clean up */
2136}
2137
2138/*
2139 * Store a check-constraint expression for the given relation.
2140 *
2141 * Caller is responsible for updating the count of constraints
2142 * in the pg_class entry for the relation.
2143 *
2144 * The OID of the new constraint is returned.
2145 */
2146static Oid
2147StoreRelCheck(Relation rel, const char *ccname, Node *expr,
2148 bool is_enforced, bool is_validated, bool is_local,
2149 int16 inhcount, bool is_no_inherit, bool is_internal)
2150{
2151 char *ccbin;
2152 List *varList;
2153 int keycount;
2154 int16 *attNos;
2155 Oid constrOid;
2156
2157 /*
2158 * Flatten expression to string form for storage.
2159 */
2160 ccbin = nodeToString(expr);
2161
2162 /*
2163 * Find columns of rel that are used in expr
2164 *
2165 * NB: pull_var_clause is okay here only because we don't allow subselects
2166 * in check constraints; it would fail to examine the contents of
2167 * subselects.
2168 */
2169 varList = pull_var_clause(expr, 0);
2171
2172 if (keycount > 0)
2173 {
2174 ListCell *vl;
2175 int i = 0;
2176
2177 attNos = (int16 *) palloc(keycount * sizeof(int16));
2178 foreach(vl, varList)
2179 {
2180 Var *var = (Var *) lfirst(vl);
2181 int j;
2182
2183 for (j = 0; j < i; j++)
2184 if (attNos[j] == var->varattno)
2185 break;
2186 if (j == i)
2187 attNos[i++] = var->varattno;
2188 }
2189 keycount = i;
2190 }
2191 else
2192 attNos = NULL;
2193
2194 /*
2195 * Partitioned tables do not contain any rows themselves, so a NO INHERIT
2196 * constraint makes no sense.
2197 */
2198 if (is_no_inherit &&
2199 rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2200 ereport(ERROR,
2202 errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
2204
2205 /*
2206 * Create the Check Constraint
2207 */
2208 constrOid =
2209 CreateConstraintEntry(ccname, /* Constraint Name */
2210 RelationGetNamespace(rel), /* namespace */
2211 CONSTRAINT_CHECK, /* Constraint Type */
2212 false, /* Is Deferrable */
2213 false, /* Is Deferred */
2214 is_enforced, /* Is Enforced */
2216 InvalidOid, /* no parent constraint */
2217 RelationGetRelid(rel), /* relation */
2218 attNos, /* attrs in the constraint */
2219 keycount, /* # key attrs in the constraint */
2220 keycount, /* # total attrs in the constraint */
2221 InvalidOid, /* not a domain constraint */
2222 InvalidOid, /* no associated index */
2223 InvalidOid, /* Foreign key fields */
2224 NULL,
2225 NULL,
2226 NULL,
2227 NULL,
2228 0,
2229 ' ',
2230 ' ',
2231 NULL,
2232 0,
2233 ' ',
2234 NULL, /* not an exclusion constraint */
2235 expr, /* Tree form of check constraint */
2236 ccbin, /* Binary form of check constraint */
2237 is_local, /* conislocal */
2238 inhcount, /* coninhcount */
2239 is_no_inherit, /* connoinherit */
2240 false, /* conperiod */
2241 is_internal); /* internally constructed? */
2242
2243 pfree(ccbin);
2244
2245 return constrOid;
2246}
2247
2248/*
2249 * Store a not-null constraint for the given relation
2250 *
2251 * The OID of the new constraint is returned.
2252 */
2253static Oid
2255 bool is_validated, bool is_local, int inhcount,
2256 bool is_no_inherit)
2257{
2258 Oid constrOid;
2259
2261
2262 constrOid =
2266 false,
2267 false,
2268 true, /* Is Enforced */
2270 InvalidOid,
2271 RelationGetRelid(rel),
2272 &attnum,
2273 1,
2274 1,
2275 InvalidOid, /* not a domain constraint */
2276 InvalidOid, /* no associated index */
2277 InvalidOid, /* Foreign key fields */
2278 NULL,
2279 NULL,
2280 NULL,
2281 NULL,
2282 0,
2283 ' ',
2284 ' ',
2285 NULL,
2286 0,
2287 ' ',
2288 NULL, /* not an exclusion constraint */
2289 NULL,
2290 NULL,
2291 is_local,
2292 inhcount,
2293 is_no_inherit,
2294 false,
2295 false);
2296 return constrOid;
2297}
2298
2299/*
2300 * Store defaults and CHECK constraints (passed as a list of CookedConstraint).
2301 *
2302 * Each CookedConstraint struct is modified to store the new catalog tuple OID.
2303 *
2304 * NOTE: only pre-cooked expressions will be passed this way, which is to
2305 * say expressions inherited from an existing relation. Newly parsed
2306 * expressions can be added later, by direct calls to StoreAttrDefault
2307 * and StoreRelCheck (see AddRelationNewConstraints()).
2308 */
2309static void
2311{
2312 int numchecks = 0;
2313 ListCell *lc;
2314
2315 if (cooked_constraints == NIL)
2316 return; /* nothing to do */
2317
2318 /*
2319 * Deparsing of constraint expressions will fail unless the just-created
2320 * pg_attribute tuples for this relation are made visible. So, bump the
2321 * command counter. CAUTION: this will cause a relcache entry rebuild.
2322 */
2324
2325 foreach(lc, cooked_constraints)
2326 {
2328
2329 switch (con->contype)
2330 {
2331 case CONSTR_DEFAULT:
2332 con->conoid = StoreAttrDefault(rel, con->attnum, con->expr,
2333 is_internal);
2334 break;
2335 case CONSTR_CHECK:
2336 con->conoid =
2337 StoreRelCheck(rel, con->name, con->expr,
2338 con->is_enforced, !con->skip_validation,
2339 con->is_local, con->inhcount,
2340 con->is_no_inherit, is_internal);
2341 numchecks++;
2342 break;
2343
2344 default:
2345 elog(ERROR, "unrecognized constraint type: %d",
2346 (int) con->contype);
2347 }
2348 }
2349
2350 if (numchecks > 0)
2352}
2353
2354/*
2355 * AddRelationNewConstraints
2356 *
2357 * Add new column default expressions and/or constraint check expressions
2358 * to an existing relation. This is defined to do both for efficiency in
2359 * DefineRelation, but of course you can do just one or the other by passing
2360 * empty lists.
2361 *
2362 * rel: relation to be modified
2363 * newColDefaults: list of RawColumnDefault structures
2364 * newConstraints: list of Constraint nodes
2365 * allow_merge: true if check constraints may be merged with existing ones
2366 * is_local: true if definition is local, false if it's inherited
2367 * is_internal: true if result of some internal process, not a user request
2368 * queryString: used during expression transformation of default values and
2369 * cooked CHECK constraints
2370 *
2371 * All entries in newColDefaults will be processed. Entries in newConstraints
2372 * will be processed only if they are CONSTR_CHECK or CONSTR_NOTNULL types.
2373 *
2374 * Returns a list of CookedConstraint nodes that shows the cooked form of
2375 * the default and constraint expressions added to the relation.
2376 *
2377 * NB: caller should have opened rel with some self-conflicting lock mode,
2378 * and should hold that lock till end of transaction; for normal cases that'll
2379 * be AccessExclusiveLock, but if caller knows that the constraint is already
2380 * enforced by some other means, it can be ShareUpdateExclusiveLock. Also, we
2381 * assume the caller has done a CommandCounterIncrement if necessary to make
2382 * the relation's catalog tuples visible.
2383 */
2384List *
2388 bool allow_merge,
2389 bool is_local,
2390 bool is_internal,
2391 const char *queryString)
2392{
2396 int numoldchecks;
2397 ParseState *pstate;
2399 int numchecks;
2401 List *nnnames;
2402 Node *expr;
2404
2405 /*
2406 * Get info about existing constraints.
2407 */
2409 oldconstr = tupleDesc->constr;
2410 if (oldconstr)
2411 numoldchecks = oldconstr->num_check;
2412 else
2413 numoldchecks = 0;
2414
2415 /*
2416 * Create a dummy ParseState and insert the target relation as its sole
2417 * rangetable entry. We need a ParseState for transformExpr.
2418 */
2419 pstate = make_parsestate(NULL);
2420 pstate->p_sourcetext = queryString;
2422 rel,
2424 NULL,
2425 false,
2426 true);
2427 addNSItemToQuery(pstate, nsitem, true, true, true);
2428
2429 /*
2430 * Process column default expressions.
2431 */
2433 {
2434 Form_pg_attribute atp = TupleDescAttr(rel->rd_att, colDef->attnum - 1);
2435 Oid defOid;
2436
2437 expr = cookDefault(pstate, colDef->raw_default,
2438 atp->atttypid, atp->atttypmod,
2439 NameStr(atp->attname),
2440 atp->attgenerated);
2441
2442 /*
2443 * If the expression is just a NULL constant, we do not bother to make
2444 * an explicit pg_attrdef entry, since the default behavior is
2445 * equivalent. This applies to column defaults, but not for
2446 * generation expressions.
2447 *
2448 * Note a nonobvious property of this test: if the column is of a
2449 * domain type, what we'll get is not a bare null Const but a
2450 * CoerceToDomain expr, so we will not discard the default. This is
2451 * critical because the column default needs to be retained to
2452 * override any default that the domain might have.
2453 */
2454 if (expr == NULL ||
2455 (!colDef->generated &&
2456 IsA(expr, Const) &&
2457 castNode(Const, expr)->constisnull))
2458 continue;
2459
2460 defOid = StoreAttrDefault(rel, colDef->attnum, expr, is_internal);
2461
2463 cooked->contype = CONSTR_DEFAULT;
2464 cooked->conoid = defOid;
2465 cooked->name = NULL;
2466 cooked->attnum = colDef->attnum;
2467 cooked->expr = expr;
2468 cooked->is_enforced = true;
2469 cooked->skip_validation = false;
2470 cooked->is_local = is_local;
2471 cooked->inhcount = is_local ? 0 : 1;
2472 cooked->is_no_inherit = false;
2474 }
2475
2476 /*
2477 * Process constraint expressions.
2478 */
2480 checknames = NIL;
2481 nnnames = NIL;
2483 {
2484 Oid constrOid;
2485
2486 if (cdef->contype == CONSTR_CHECK)
2487 {
2488 char *ccname;
2489
2490 if (cdef->raw_expr != NULL)
2491 {
2492 Assert(cdef->cooked_expr == NULL);
2493
2494 /*
2495 * Transform raw parsetree to executable expression, and
2496 * verify it's valid as a CHECK constraint.
2497 */
2498 expr = cookConstraint(pstate, cdef->raw_expr,
2500 }
2501 else
2502 {
2503 Assert(cdef->cooked_expr != NULL);
2504
2505 /*
2506 * Here, we assume the parser will only pass us valid CHECK
2507 * expressions, so we do no particular checking.
2508 */
2509 expr = stringToNode(cdef->cooked_expr);
2510 }
2511
2512 /*
2513 * Check name uniqueness, or generate a name if none was given.
2514 */
2515 if (cdef->conname != NULL)
2516 {
2517 ccname = cdef->conname;
2518 /* Check against other new constraints */
2519 /* Needed because we don't do CommandCounterIncrement in loop */
2521 {
2522 if (strcmp(chkname, ccname) == 0)
2523 ereport(ERROR,
2525 errmsg("check constraint \"%s\" already exists",
2526 ccname)));
2527 }
2528
2529 /* save name for future checks */
2530 checknames = lappend(checknames, ccname);
2531
2532 /*
2533 * Check against pre-existing constraints. If we are allowed
2534 * to merge with an existing constraint, there's no more to do
2535 * here. (We omit the duplicate constraint from the result,
2536 * which is what ATAddCheckNNConstraint wants.)
2537 */
2538 if (MergeWithExistingConstraint(rel, ccname, expr,
2539 allow_merge, is_local,
2540 cdef->is_enforced,
2541 cdef->initially_valid,
2542 cdef->is_no_inherit))
2543 continue;
2544 }
2545 else
2546 {
2547 /*
2548 * When generating a name, we want to create "tab_col_check"
2549 * for a column constraint and "tab_check" for a table
2550 * constraint. We no longer have any info about the syntactic
2551 * positioning of the constraint phrase, so we approximate
2552 * this by seeing whether the expression references more than
2553 * one column. (If the user played by the rules, the result
2554 * is the same...)
2555 *
2556 * Note: pull_var_clause() doesn't descend into sublinks, but
2557 * we eliminated those above; and anyway this only needs to be
2558 * an approximate answer.
2559 */
2560 List *vars;
2561 char *colname;
2562
2563 vars = pull_var_clause(expr, 0);
2564
2565 /* eliminate duplicates */
2566 vars = list_union(NIL, vars);
2567
2568 if (list_length(vars) == 1)
2569 colname = get_attname(RelationGetRelid(rel),
2570 ((Var *) linitial(vars))->varattno,
2571 true);
2572 else
2573 colname = NULL;
2574
2576 colname,
2577 "check",
2579 checknames);
2580
2581 /* save name for future checks */
2582 checknames = lappend(checknames, ccname);
2583 }
2584
2585 /*
2586 * OK, store it.
2587 */
2588 constrOid =
2589 StoreRelCheck(rel, ccname, expr, cdef->is_enforced,
2590 cdef->initially_valid, is_local,
2591 is_local ? 0 : 1, cdef->is_no_inherit,
2592 is_internal);
2593
2594 numchecks++;
2595
2597 cooked->contype = CONSTR_CHECK;
2598 cooked->conoid = constrOid;
2599 cooked->name = ccname;
2600 cooked->attnum = 0;
2601 cooked->expr = expr;
2602 cooked->is_enforced = cdef->is_enforced;
2603 cooked->skip_validation = cdef->skip_validation;
2604 cooked->is_local = is_local;
2605 cooked->inhcount = is_local ? 0 : 1;
2606 cooked->is_no_inherit = cdef->is_no_inherit;
2608 }
2609 else if (cdef->contype == CONSTR_NOTNULL)
2610 {
2612 AttrNumber colnum;
2613 int16 inhcount = is_local ? 0 : 1;
2614 char *nnname;
2615
2616 /* Determine which column to modify */
2617 colnum = get_attnum(RelationGetRelid(rel), strVal(linitial(cdef->keys)));
2618 if (colnum == InvalidAttrNumber)
2619 ereport(ERROR,
2621 errmsg("column \"%s\" of relation \"%s\" does not exist",
2623 if (colnum < InvalidAttrNumber)
2624 ereport(ERROR,
2626 errmsg("cannot add not-null constraint on system column \"%s\"",
2627 strVal(linitial(cdef->keys))));
2628
2629 Assert(cdef->initially_valid != cdef->skip_validation);
2630
2631 /*
2632 * If the column already has a not-null constraint, we don't want
2633 * to add another one; adjust inheritance status as needed. This
2634 * also checks whether the existing constraint matches the
2635 * requested validity.
2636 */
2638 cdef->conname,
2639 is_local, cdef->is_no_inherit,
2640 cdef->skip_validation))
2641 continue;
2642
2643 /*
2644 * If a constraint name is specified, check that it isn't already
2645 * used. Otherwise, choose a non-conflicting one ourselves.
2646 */
2647 if (cdef->conname)
2648 {
2650 RelationGetRelid(rel),
2651 cdef->conname))
2652 ereport(ERROR,
2654 errmsg("constraint \"%s\" for relation \"%s\" already exists",
2655 cdef->conname, RelationGetRelationName(rel)));
2656 nnname = cdef->conname;
2657 }
2658 else
2660 strVal(linitial(cdef->keys)),
2661 "not_null",
2663 nnnames);
2665
2666 constrOid =
2667 StoreRelNotNull(rel, nnname, colnum,
2668 cdef->initially_valid,
2669 is_local,
2670 inhcount,
2671 cdef->is_no_inherit);
2672
2674 nncooked->contype = CONSTR_NOTNULL;
2675 nncooked->conoid = constrOid;
2676 nncooked->name = nnname;
2677 nncooked->attnum = colnum;
2678 nncooked->expr = NULL;
2679 nncooked->is_enforced = true;
2680 nncooked->skip_validation = cdef->skip_validation;
2681 nncooked->is_local = is_local;
2682 nncooked->inhcount = inhcount;
2683 nncooked->is_no_inherit = cdef->is_no_inherit;
2684
2686 }
2687 }
2688
2689 /*
2690 * Update the count of constraints in the relation's pg_class tuple. We do
2691 * this even if there was no change, in order to ensure that an SI update
2692 * message is sent out for the pg_class tuple, which will force other
2693 * backends to rebuild their relcache entries for the rel. (This is
2694 * critical if we added defaults but not constraints.)
2695 */
2697
2698 return cookedConstraints;
2699}
2700
2701/*
2702 * Check for a pre-existing check constraint that conflicts with a proposed
2703 * new one, and either adjust its conislocal/coninhcount settings or throw
2704 * error as needed.
2705 *
2706 * Returns true if merged (constraint is a duplicate), or false if it's
2707 * got a so-far-unique name, or throws error if conflict.
2708 *
2709 * XXX See MergeConstraintsIntoExisting too if you change this code.
2710 */
2711static bool
2712MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr,
2713 bool allow_merge, bool is_local,
2714 bool is_enforced,
2715 bool is_initially_valid,
2716 bool is_no_inherit)
2717{
2718 bool found;
2721 ScanKeyData skey[3];
2722 HeapTuple tup;
2723
2724 /* Search for a pg_constraint entry with same name and relation */
2726
2727 found = false;
2728
2729 ScanKeyInit(&skey[0],
2733 ScanKeyInit(&skey[1],
2737 ScanKeyInit(&skey[2],
2740 CStringGetDatum(ccname));
2741
2743 NULL, 3, skey);
2744
2745 /* There can be at most one matching row */
2747 {
2749
2750 /* Found it. Conflicts if not identical check constraint */
2751 if (con->contype == CONSTRAINT_CHECK)
2752 {
2753 Datum val;
2754 bool isnull;
2755
2758 conDesc->rd_att, &isnull);
2759 if (isnull)
2760 elog(ERROR, "null conbin for rel %s",
2763 found = true;
2764 }
2765
2766 /*
2767 * If the existing constraint is purely inherited (no local
2768 * definition) then interpret addition of a local constraint as a
2769 * legal merge. This allows ALTER ADD CONSTRAINT on parent and child
2770 * tables to be given in either order with same end state. However if
2771 * the relation is a partition, all inherited constraints are always
2772 * non-local, including those that were merged.
2773 */
2774 if (is_local && !con->conislocal && !rel->rd_rel->relispartition)
2775 allow_merge = true;
2776
2777 if (!found || !allow_merge)
2778 ereport(ERROR,
2780 errmsg("constraint \"%s\" for relation \"%s\" already exists",
2781 ccname, RelationGetRelationName(rel))));
2782
2783 /* If the child constraint is "no inherit" then cannot merge */
2784 if (con->connoinherit)
2785 ereport(ERROR,
2787 errmsg("constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"",
2788 ccname, RelationGetRelationName(rel))));
2789
2790 /*
2791 * Must not change an existing inherited constraint to "no inherit"
2792 * status. That's because inherited constraints should be able to
2793 * propagate to lower-level children.
2794 */
2795 if (con->coninhcount > 0 && is_no_inherit)
2796 ereport(ERROR,
2798 errmsg("constraint \"%s\" conflicts with inherited constraint on relation \"%s\"",
2799 ccname, RelationGetRelationName(rel))));
2800
2801 /*
2802 * If the child constraint is "not valid" then cannot merge with a
2803 * valid parent constraint.
2804 */
2805 if (is_initially_valid && con->conenforced && !con->convalidated)
2806 ereport(ERROR,
2808 errmsg("constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"",
2809 ccname, RelationGetRelationName(rel))));
2810
2811 /*
2812 * A non-enforced child constraint cannot be merged with an enforced
2813 * parent constraint. However, the reverse is allowed, where the child
2814 * constraint is enforced.
2815 */
2816 if ((!is_local && is_enforced && !con->conenforced) ||
2817 (is_local && !is_enforced && con->conenforced))
2818 ereport(ERROR,
2820 errmsg("constraint \"%s\" conflicts with NOT ENFORCED constraint on relation \"%s\"",
2821 ccname, RelationGetRelationName(rel))));
2822
2823 /* OK to update the tuple */
2825 (errmsg("merging constraint \"%s\" with inherited definition",
2826 ccname)));
2827
2830
2831 /*
2832 * In case of partitions, an inherited constraint must be inherited
2833 * only once since it cannot have multiple parents and it is never
2834 * considered local.
2835 */
2836 if (rel->rd_rel->relispartition)
2837 {
2838 con->coninhcount = 1;
2839 con->conislocal = false;
2840 }
2841 else
2842 {
2843 if (is_local)
2844 con->conislocal = true;
2845 else if (pg_add_s16_overflow(con->coninhcount, 1,
2846 &con->coninhcount))
2847 ereport(ERROR,
2849 errmsg("too many inheritance parents"));
2850 }
2851
2852 if (is_no_inherit)
2853 {
2854 Assert(is_local);
2855 con->connoinherit = true;
2856 }
2857
2858 /*
2859 * If the child constraint is required to be enforced while the parent
2860 * constraint is not, this should be allowed by marking the child
2861 * constraint as enforced. In the reverse case, an error would have
2862 * already been thrown before reaching this point.
2863 */
2864 if (is_enforced && !con->conenforced)
2865 {
2866 Assert(is_local);
2867 con->conenforced = true;
2868 con->convalidated = true;
2869 }
2870
2871 CatalogTupleUpdate(conDesc, &tup->t_self, tup);
2872 }
2873
2876
2877 return found;
2878}
2879
2880/*
2881 * Create the not-null constraints when creating a new relation
2882 *
2883 * These come from two sources: the 'constraints' list (of Constraint) is
2884 * specified directly by the user; the 'old_notnulls' list (of
2885 * CookedConstraint) comes from inheritance. We create one constraint
2886 * for each column, giving priority to user-specified ones, and setting
2887 * inhcount according to how many parents cause each column to get a
2888 * not-null constraint. If a user-specified name clashes with another
2889 * user-specified name, an error is raised. 'existing_constraints'
2890 * is a list of already defined constraint names, which should be avoided
2891 * when generating further ones.
2892 *
2893 * Returns a list of AttrNumber for columns that need to have the attnotnull
2894 * flag set.
2895 */
2896List *
2899{
2901 List *nnnames;
2902 List *nncols = NIL;
2903
2904 /*
2905 * We track two lists of names: nnnames keeps all the constraint names,
2906 * givennames tracks user-generated names. The distinction is important,
2907 * because we must raise error for user-generated name conflicts, but for
2908 * system-generated name conflicts we just generate another.
2909 */
2910 nnnames = list_copy(existing_constraints); /* don't scribble on input */
2911 givennames = NIL;
2912
2913 /*
2914 * First, create all not-null constraints that are directly specified by
2915 * the user. Note that inheritance might have given us another source for
2916 * each, so we must scan the old_notnulls list and increment inhcount for
2917 * each element with identical attnum. We delete from there any element
2918 * that we process.
2919 *
2920 * We don't use foreach() here because we have two nested loops over the
2921 * constraint list, with possible element deletions in the inner one. If
2922 * we used foreach_delete_current() it could only fix up the state of one
2923 * of the loops, so it seems cleaner to use looping over list indexes for
2924 * both loops. Note that any deletion will happen beyond where the outer
2925 * loop is, so its index never needs adjustment.
2926 */
2927 for (int outerpos = 0; outerpos < list_length(constraints); outerpos++)
2928 {
2929 Constraint *constr;
2931 char *conname;
2932 int inhcount = 0;
2933
2934 constr = list_nth_node(Constraint, constraints, outerpos);
2935
2936 Assert(constr->contype == CONSTR_NOTNULL);
2937
2939 strVal(linitial(constr->keys)));
2941 ereport(ERROR,
2943 errmsg("column \"%s\" of relation \"%s\" does not exist",
2944 strVal(linitial(constr->keys)),
2947 ereport(ERROR,
2949 errmsg("cannot add not-null constraint on system column \"%s\"",
2950 strVal(linitial(constr->keys))));
2951
2952 /*
2953 * A column can only have one not-null constraint, so discard any
2954 * additional ones that appear for columns we already saw; but check
2955 * that the NO INHERIT flags match.
2956 */
2957 for (int restpos = outerpos + 1; restpos < list_length(constraints);)
2958 {
2960
2961 other = list_nth_node(Constraint, constraints, restpos);
2962 if (strcmp(strVal(linitial(constr->keys)),
2963 strVal(linitial(other->keys))) == 0)
2964 {
2965 if (other->is_no_inherit != constr->is_no_inherit)
2966 ereport(ERROR,
2968 errmsg("conflicting NO INHERIT declaration for not-null constraint on column \"%s\"",
2969 strVal(linitial(constr->keys))));
2970
2971 /*
2972 * Preserve constraint name if one is specified, but raise an
2973 * error if conflicting ones are specified.
2974 */
2975 if (other->conname)
2976 {
2977 if (!constr->conname)
2978 constr->conname = pstrdup(other->conname);
2979 else if (strcmp(constr->conname, other->conname) != 0)
2980 ereport(ERROR,
2982 errmsg("conflicting not-null constraint names \"%s\" and \"%s\"",
2983 constr->conname, other->conname));
2984 }
2985
2986 /* XXX do we need to verify any other fields? */
2987 constraints = list_delete_nth_cell(constraints, restpos);
2988 }
2989 else
2990 restpos++;
2991 }
2992
2993 /*
2994 * Search in the list of inherited constraints for any entries on the
2995 * same column; determine an inheritance count from that. Also, if at
2996 * least one parent has a constraint for this column, then we must not
2997 * accept a user specification for a NO INHERIT one. Any constraint
2998 * from parents that we process here is deleted from the list: we no
2999 * longer need to process it in the loop below.
3000 */
3002 {
3003 if (old->attnum == attnum)
3004 {
3005 /*
3006 * If we get a constraint from the parent, having a local NO
3007 * INHERIT one doesn't work.
3008 */
3009 if (constr->is_no_inherit)
3010 ereport(ERROR,
3012 errmsg("cannot define not-null constraint with NO INHERIT on column \"%s\"",
3013 strVal(linitial(constr->keys))),
3014 errdetail("The column has an inherited not-null constraint.")));
3015
3016 inhcount++;
3018 }
3019 }
3020
3021 /*
3022 * Determine a constraint name, which may have been specified by the
3023 * user, or raise an error if a conflict exists with another
3024 * user-specified name.
3025 */
3026 if (constr->conname)
3027 {
3029 {
3030 if (strcmp(thisname, constr->conname) == 0)
3031 ereport(ERROR,
3033 errmsg("constraint \"%s\" for relation \"%s\" already exists",
3034 constr->conname,
3036 }
3037
3038 conname = constr->conname;
3039 givennames = lappend(givennames, conname);
3040 }
3041 else
3044 attnum, false),
3045 "not_null",
3047 nnnames);
3048 nnnames = lappend(nnnames, conname);
3049
3050 StoreRelNotNull(rel, conname,
3051 attnum, true, true,
3052 inhcount, constr->is_no_inherit);
3053
3055 }
3056
3057 /*
3058 * If any column remains in the old_notnulls list, we must create a not-
3059 * null constraint marked not-local for that column. Because multiple
3060 * parents could specify a not-null constraint for the same column, we
3061 * must count how many there are and set an appropriate inhcount
3062 * accordingly, deleting elements we've already processed.
3063 *
3064 * We don't use foreach() here because we have two nested loops over the
3065 * constraint list, with possible element deletions in the inner one. If
3066 * we used foreach_delete_current() it could only fix up the state of one
3067 * of the loops, so it seems cleaner to use looping over list indexes for
3068 * both loops. Note that any deletion will happen beyond where the outer
3069 * loop is, so its index never needs adjustment.
3070 */
3072 {
3074 char *conname = NULL;
3075 int inhcount = 1;
3076
3078 Assert(cooked->contype == CONSTR_NOTNULL);
3079 Assert(cooked->name);
3080
3081 /*
3082 * Preserve the first non-conflicting constraint name we come across.
3083 */
3084 if (conname == NULL)
3085 conname = cooked->name;
3086
3087 for (int restpos = outerpos + 1; restpos < list_length(old_notnulls);)
3088 {
3090
3092 Assert(other->name);
3093 if (other->attnum == cooked->attnum)
3094 {
3095 if (conname == NULL)
3096 conname = other->name;
3097
3098 inhcount++;
3100 }
3101 else
3102 restpos++;
3103 }
3104
3105 /* If we got a name, make sure it isn't one we've already used */
3106 if (conname != NULL)
3107 {
3109 {
3110 if (strcmp(thisname, conname) == 0)
3111 {
3112 conname = NULL;
3113 break;
3114 }
3115 }
3116 }
3117
3118 /* and choose a name, if needed */
3119 if (conname == NULL)
3122 cooked->attnum, false),
3123 "not_null",
3125 nnnames);
3126 nnnames = lappend(nnnames, conname);
3127
3128 /* ignore the origin constraint's is_local and inhcount */
3129 StoreRelNotNull(rel, conname, cooked->attnum, true,
3130 false, inhcount, false);
3131
3132 nncols = lappend_int(nncols, cooked->attnum);
3133 }
3134
3135 return nncols;
3136}
3137
3138/*
3139 * Update the count of constraints in the relation's pg_class tuple.
3140 *
3141 * Caller had better hold exclusive lock on the relation.
3142 *
3143 * An important side effect is that a SI update message will be sent out for
3144 * the pg_class tuple, which will force other backends to rebuild their
3145 * relcache entries for the rel. Also, this backend will rebuild its
3146 * own relcache entry at the next CommandCounterIncrement.
3147 */
3148static void
3150{
3154
3159 elog(ERROR, "cache lookup failed for relation %u",
3160 RelationGetRelid(rel));
3162
3163 if (relStruct->relchecks != numchecks)
3164 {
3165 relStruct->relchecks = numchecks;
3166
3168 }
3169 else
3170 {
3171 /* Skip the disk update, but force relcache inval anyway */
3173 }
3174
3177}
3178
3179/*
3180 * Check for references to generated columns
3181 */
3182static bool
3184{
3185 ParseState *pstate = context;
3186
3187 if (node == NULL)
3188 return false;
3189 else if (IsA(node, Var))
3190 {
3191 Var *var = (Var *) node;
3192 Oid relid;
3194
3195 relid = rt_fetch(var->varno, pstate->p_rtable)->relid;
3196 if (!OidIsValid(relid))
3197 return false; /* XXX shouldn't we raise an error? */
3198
3199 attnum = var->varattno;
3200
3201 if (attnum > 0 && get_attgenerated(relid, attnum))
3202 ereport(ERROR,
3204 errmsg("cannot use generated column \"%s\" in column generation expression",
3205 get_attname(relid, attnum, false)),
3206 errdetail("A generated column cannot reference another generated column."),
3207 parser_errposition(pstate, var->location)));
3208 /* A whole-row Var is necessarily self-referential, so forbid it */
3209 if (attnum == 0)
3210 ereport(ERROR,
3212 errmsg("cannot use whole-row variable in column generation expression"),
3213 errdetail("This would cause the generated column to depend on its own value."),
3214 parser_errposition(pstate, var->location)));
3215 /* System columns were already checked in the parser */
3216
3217 return false;
3218 }
3219 else
3221 context);
3222}
3223
3224static void
3226{
3227 check_nested_generated_walker(node, pstate);
3228}
3229
3230/*
3231 * Check security of virtual generated column expression.
3232 *
3233 * Just like selecting from a view is exploitable (CVE-2024-7348), selecting
3234 * from a table with virtual generated columns is exploitable. Users who are
3235 * concerned about this can avoid selecting from views, but telling them to
3236 * avoid selecting from tables is less practical.
3237 *
3238 * To address this, this restricts generation expressions for virtual
3239 * generated columns are restricted to using built-in functions and types. We
3240 * assume that built-in functions and types cannot be exploited for this
3241 * purpose. Note the overall security also requires that all functions in use
3242 * a immutable. (For example, there are some built-in non-immutable functions
3243 * that can run arbitrary SQL.) The immutability is checked elsewhere, since
3244 * that is a property that needs to hold independent of security
3245 * considerations.
3246 *
3247 * In the future, this could be expanded by some new mechanism to declare
3248 * other functions and types as safe or trusted for this purpose, but that is
3249 * to be designed.
3250 */
3251
3252/*
3253 * Callback for check_functions_in_node() that determines whether a function
3254 * is user-defined.
3255 */
3256static bool
3258{
3259 return (func_id >= FirstUnpinnedObjectId);
3260}
3261
3262/*
3263 * Checks for all the things we don't want in the generation expressions of
3264 * virtual generated columns for security reasons. Errors out if it finds
3265 * one.
3266 */
3267static bool
3269{
3270 ParseState *pstate = context;
3271
3272 if (node == NULL)
3273 return false;
3274
3275 if (!IsA(node, List))
3276 {
3278 ereport(ERROR,
3280 errmsg("generation expression uses user-defined function"),
3281 errdetail("Virtual generated columns that make use of user-defined functions are not yet supported."),
3282 parser_errposition(pstate, exprLocation(node)));
3283
3284 /*
3285 * check_functions_in_node() doesn't check some node types (see
3286 * comment there). We handle CoerceToDomain and MinMaxExpr by
3287 * checking for built-in types. The other listed node types cannot
3288 * call user-definable SQL-visible functions.
3289 *
3290 * We furthermore need this type check to handle built-in, immutable
3291 * polymorphic functions such as array_eq().
3292 */
3293 if (exprType(node) >= FirstUnpinnedObjectId)
3294 ereport(ERROR,
3296 errmsg("generation expression uses user-defined type"),
3297 errdetail("Virtual generated columns that make use of user-defined types are not yet supported."),
3298 parser_errposition(pstate, exprLocation(node)));
3299 }
3300
3302}
3303
3304static void
3309
3310/*
3311 * Take a raw default and convert it to a cooked format ready for
3312 * storage.
3313 *
3314 * Parse state should be set up to recognize any vars that might appear
3315 * in the expression. (Even though we plan to reject vars, it's more
3316 * user-friendly to give the correct error message than "unknown var".)
3317 *
3318 * If atttypid is not InvalidOid, coerce the expression to the specified
3319 * type (and typmod atttypmod). attname is only needed in this case:
3320 * it is used in the error message, if any.
3321 */
3322Node *
3324 Node *raw_default,
3325 Oid atttypid,
3326 int32 atttypmod,
3327 const char *attname,
3328 char attgenerated)
3329{
3330 Node *expr;
3331
3332 Assert(raw_default != NULL);
3333
3334 /*
3335 * Transform raw parsetree to executable expression.
3336 */
3337 expr = transformExpr(pstate, raw_default, attgenerated ? EXPR_KIND_GENERATED_COLUMN : EXPR_KIND_COLUMN_DEFAULT);
3338
3339 if (attgenerated)
3340 {
3341 /* Disallow refs to other generated columns */
3342 check_nested_generated(pstate, expr);
3343
3344 /* Disallow mutable functions */
3346 ereport(ERROR,
3348 errmsg("generation expression is not immutable")));
3349
3350 /* Check security of expressions for virtual generated column */
3351 if (attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
3353 }
3354 else
3355 {
3356 /*
3357 * For a default expression, transformExpr() should have rejected
3358 * column references.
3359 */
3360 Assert(!contain_var_clause(expr));
3361 }
3362
3363 /*
3364 * Coerce the expression to the correct type and typmod, if given. This
3365 * should match the parser's processing of non-defaulted expressions ---
3366 * see transformAssignedExpr().
3367 */
3368 if (OidIsValid(atttypid))
3369 {
3370 Oid type_id = exprType(expr);
3371
3372 expr = coerce_to_target_type(pstate, expr, type_id,
3373 atttypid, atttypmod,
3376 -1);
3377 if (expr == NULL)
3378 ereport(ERROR,
3380 errmsg("column \"%s\" is of type %s"
3381 " but default expression is of type %s",
3382 attname,
3384 format_type_be(type_id)),
3385 errhint("You will need to rewrite or cast the expression.")));
3386 }
3387
3388 /*
3389 * Finally, take care of collations in the finished expression.
3390 */
3391 assign_expr_collations(pstate, expr);
3392
3393 return expr;
3394}
3395
3396/*
3397 * Take a raw CHECK constraint expression and convert it to a cooked format
3398 * ready for storage.
3399 *
3400 * Parse state must be set up to recognize any vars that might appear
3401 * in the expression.
3402 */
3403static Node *
3406 char *relname)
3407{
3408 Node *expr;
3409
3410 /*
3411 * Transform raw parsetree to executable expression.
3412 */
3414
3415 /*
3416 * Make sure it yields a boolean result.
3417 */
3418 expr = coerce_to_boolean(pstate, expr, "CHECK");
3419
3420 /*
3421 * Take care of collations.
3422 */
3423 assign_expr_collations(pstate, expr);
3424
3425 /*
3426 * Make sure no outside relations are referred to (this is probably dead
3427 * code now that add_missing_from is history).
3428 */
3429 if (list_length(pstate->p_rtable) != 1)
3430 ereport(ERROR,
3432 errmsg("only table \"%s\" can be referenced in check constraint",
3433 relname)));
3434
3435 return expr;
3436}
3437
3438/*
3439 * CopyStatistics --- copy entries in pg_statistic from one rel to another
3440 */
3441void
3443{
3444 HeapTuple tup;
3445 SysScanDesc scan;
3446 ScanKeyData key[1];
3449
3451
3452 /* Now search for stat records */
3453 ScanKeyInit(&key[0],
3457
3459 true, NULL, 1, key);
3460
3461 while (HeapTupleIsValid((tup = systable_getnext(scan))))
3462 {
3464
3465 /* make a modifiable copy */
3468
3469 /* update the copy of the tuple and insert it */
3470 statform->starelid = torelid;
3471
3472 /* fetch index information when we know we need it */
3473 if (indstate == NULL)
3475
3477
3479 }
3480
3481 systable_endscan(scan);
3482
3483 if (indstate != NULL)
3486}
3487
3488/*
3489 * RemoveStatistics --- remove entries in pg_statistic for a rel or column
3490 *
3491 * If attnum is zero, remove all entries for rel; else remove only the one(s)
3492 * for that column.
3493 */
3494void
3496{
3498 SysScanDesc scan;
3499 ScanKeyData key[2];
3500 int nkeys;
3501 HeapTuple tuple;
3502
3504
3505 ScanKeyInit(&key[0],
3508 ObjectIdGetDatum(relid));
3509
3510 if (attnum == 0)
3511 nkeys = 1;
3512 else
3513 {
3514 ScanKeyInit(&key[1],
3518 nkeys = 2;
3519 }
3520
3522 NULL, nkeys, key);
3523
3524 /* we must loop even when attnum != 0, in case of inherited stats */
3525 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
3527
3528 systable_endscan(scan);
3529
3531}
3532
3533
3534/*
3535 * RelationTruncateIndexes - truncate all indexes associated
3536 * with the heap relation to zero tuples.
3537 *
3538 * The routine will truncate and then reconstruct the indexes on
3539 * the specified relation. Caller must hold exclusive lock on rel.
3540 */
3541static void
3543{
3545
3546 /* Ask the relcache to produce a list of the indexes of the rel */
3547 foreach(indlist, RelationGetIndexList(heapRelation))
3548 {
3551 IndexInfo *indexInfo;
3552
3553 /* Open the index relation; use exclusive lock, just to be sure */
3555
3556 /*
3557 * Fetch info needed for index_build. Since we know there are no
3558 * tuples that actually need indexing, we can use a dummy IndexInfo.
3559 * This is slightly cheaper to build, but the real point is to avoid
3560 * possibly running user-defined code in index expressions or
3561 * predicates. We might be getting invoked during ON COMMIT
3562 * processing, and we don't want to run any such code then.
3563 */
3564 indexInfo = BuildDummyIndexInfo(currentIndex);
3565
3566 /*
3567 * Now truncate the actual file (and discard buffers).
3568 */
3570
3571 /* Initialize the index and rebuild */
3572 /* Note: we do not need to re-establish pkey setting */
3573 index_build(heapRelation, currentIndex, indexInfo, true, false);
3574
3575 /* We're done with this index */
3577 }
3578}
3579
3580/*
3581 * heap_truncate
3582 *
3583 * This routine deletes all data within all the specified relations.
3584 *
3585 * This is not transaction-safe! There is another, transaction-safe
3586 * implementation in commands/tablecmds.c. We now use this only for
3587 * ON COMMIT truncation of temporary tables, where it doesn't matter.
3588 */
3589void
3591{
3592 List *relations = NIL;
3593 ListCell *cell;
3594
3595 /* Open relations for processing, and grab exclusive access on each */
3596 foreach(cell, relids)
3597 {
3598 Oid rid = lfirst_oid(cell);
3599 Relation rel;
3600
3602 relations = lappend(relations, rel);
3603 }
3604
3605 /* Don't allow truncate on tables that are referenced by foreign keys */
3606 heap_truncate_check_FKs(relations, true);
3607
3608 /* OK to do it */
3609 foreach(cell, relations)
3610 {
3611 Relation rel = lfirst(cell);
3612
3613 /* Truncate the relation */
3615
3616 /* Close the relation, but keep exclusive lock on it until commit */
3617 table_close(rel, NoLock);
3618 }
3619}
3620
3621/*
3622 * heap_truncate_one_rel
3623 *
3624 * This routine deletes all data within the specified relation.
3625 *
3626 * This is not transaction-safe, because the truncation is done immediately
3627 * and cannot be rolled back later. Caller is responsible for having
3628 * checked permissions etc, and must have obtained AccessExclusiveLock.
3629 */
3630void
3632{
3634
3635 /*
3636 * Truncate the relation. Partitioned tables have no storage, so there is
3637 * nothing to do for them here.
3638 */
3639 if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
3640 return;
3641
3642 /* Truncate the underlying relation */
3644
3645 /* If the relation has indexes, truncate the indexes too */
3647
3648 /* If there is a toast table, truncate that too */
3649 toastrelid = rel->rd_rel->reltoastrelid;
3651 {
3653
3656 /* keep the lock... */
3658 }
3659}
3660
3661/*
3662 * heap_truncate_check_FKs
3663 * Check for foreign keys referencing a list of relations that
3664 * are to be truncated, and raise error if there are any
3665 *
3666 * We disallow such FKs (except self-referential ones) since the whole point
3667 * of TRUNCATE is to not scan the individual rows to be thrown away.
3668 *
3669 * This is split out so it can be shared by both implementations of truncate.
3670 * Caller should already hold a suitable lock on the relations.
3671 *
3672 * tempTables is only used to select an appropriate error message.
3673 */
3674void
3676{
3677 List *oids = NIL;
3679 ListCell *cell;
3680
3681 /*
3682 * Build a list of OIDs of the interesting relations.
3683 *
3684 * If a relation has no triggers, then it can neither have FKs nor be
3685 * referenced by a FK from another table, so we can ignore it. For
3686 * partitioned tables, FKs have no triggers, so we must include them
3687 * anyway.
3688 */
3689 foreach(cell, relations)
3690 {
3691 Relation rel = lfirst(cell);
3692
3693 if (rel->rd_rel->relhastriggers ||
3694 rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
3695 oids = lappend_oid(oids, RelationGetRelid(rel));
3696 }
3697
3698 /*
3699 * Fast path: if no relation has triggers, none has FKs either.
3700 */
3701 if (oids == NIL)
3702 return;
3703
3704 /*
3705 * Otherwise, must scan pg_constraint. We make one pass with all the
3706 * relations considered; if this finds nothing, then all is well.
3707 */
3709 if (dependents == NIL)
3710 return;
3711
3712 /*
3713 * Otherwise we repeat the scan once per relation to identify a particular
3714 * pair of relations to complain about. This is pretty slow, but
3715 * performance shouldn't matter much in a failure path. The reason for
3716 * doing things this way is to ensure that the message produced is not
3717 * dependent on chance row locations within pg_constraint.
3718 */
3719 foreach(cell, oids)
3720 {
3721 Oid relid = lfirst_oid(cell);
3722 ListCell *cell2;
3723
3725
3726 foreach(cell2, dependents)
3727 {
3729
3730 if (!list_member_oid(oids, relid2))
3731 {
3732 char *relname = get_rel_name(relid);
3733 char *relname2 = get_rel_name(relid2);
3734
3735 if (tempTables)
3736 ereport(ERROR,
3738 errmsg("unsupported ON COMMIT and foreign key combination"),
3739 errdetail("Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting.",
3740 relname2, relname)));
3741 else
3742 ereport(ERROR,
3744 errmsg("cannot truncate a table referenced in a foreign key constraint"),
3745 errdetail("Table \"%s\" references \"%s\".",
3746 relname2, relname),
3747 errhint("Truncate table \"%s\" at the same time, "
3748 "or use TRUNCATE ... CASCADE.",
3749 relname2)));
3750 }
3751 }
3752 }
3753}
3754
3755/*
3756 * heap_truncate_find_FKs
3757 * Find relations having foreign keys referencing any of the given rels
3758 *
3759 * Input and result are both lists of relation OIDs. The result contains
3760 * no duplicates, does *not* include any rels that were already in the input
3761 * list, and is sorted in OID order. (The last property is enforced mainly
3762 * to guarantee consistent behavior in the regression tests; we don't want
3763 * behavior to change depending on chance locations of rows in pg_constraint.)
3764 *
3765 * Note: caller should already have appropriate lock on all rels mentioned
3766 * in relationIds. Since adding or dropping an FK requires exclusive lock
3767 * on both rels, this ensures that the answer will be stable.
3768 */
3769List *
3771{
3772 List *result = NIL;
3773 List *oids;
3775 ListCell *cell;
3776 ScanKeyData key;
3779 HeapTuple tuple;
3780 bool restart;
3781
3782 oids = list_copy(relationIds);
3783
3784 /*
3785 * Must scan pg_constraint. Right now, it is a seqscan because there is
3786 * no available index on confrelid.
3787 */
3789
3790restart:
3791 restart = false;
3792 parent_cons = NIL;
3793
3795 NULL, 0, NULL);
3796
3798 {
3800
3801 /* Not a foreign key */
3802 if (con->contype != CONSTRAINT_FOREIGN)
3803 continue;
3804
3805 /* Not referencing one of our list of tables */
3806 if (!list_member_oid(oids, con->confrelid))
3807 continue;
3808
3809 /*
3810 * If this constraint has a parent constraint which we have not seen
3811 * yet, keep track of it for the second loop, below. Tracking parent
3812 * constraints allows us to climb up to the top-level constraint and
3813 * look for all possible relations referencing the partitioned table.
3814 */
3815 if (OidIsValid(con->conparentid) &&
3816 !list_member_oid(parent_cons, con->conparentid))
3817 parent_cons = lappend_oid(parent_cons, con->conparentid);
3818
3819 /*
3820 * Add referencer to result, unless present in input list. (Don't
3821 * worry about dupes: we'll fix that below).
3822 */
3823 if (!list_member_oid(relationIds, con->conrelid))
3824 result = lappend_oid(result, con->conrelid);
3825 }
3826
3828
3829 /*
3830 * Process each parent constraint we found to add the list of referenced
3831 * relations by them to the oids list. If we do add any new such
3832 * relations, redo the first loop above. Also, if we see that the parent
3833 * constraint in turn has a parent, add that so that we process all
3834 * relations in a single additional pass.
3835 */
3836 foreach(cell, parent_cons)
3837 {
3838 Oid parent = lfirst_oid(cell);
3839
3840 ScanKeyInit(&key,
3843 ObjectIdGetDatum(parent));
3844
3846 true, NULL, 1, &key);
3847
3848 tuple = systable_getnext(fkeyScan);
3849 if (HeapTupleIsValid(tuple))
3850 {
3852
3853 /*
3854 * pg_constraint rows always appear for partitioned hierarchies
3855 * this way: on the each side of the constraint, one row appears
3856 * for each partition that points to the top-most table on the
3857 * other side.
3858 *
3859 * Because of this arrangement, we can correctly catch all
3860 * relevant relations by adding to 'parent_cons' all rows with
3861 * valid conparentid, and to the 'oids' list all rows with a zero
3862 * conparentid. If any oids are added to 'oids', redo the first
3863 * loop above by setting 'restart'.
3864 */
3865 if (OidIsValid(con->conparentid))
3867 con->conparentid);
3868 else if (!list_member_oid(oids, con->confrelid))
3869 {
3870 oids = lappend_oid(oids, con->confrelid);
3871 restart = true;
3872 }
3873 }
3874
3876 }
3877
3879 if (restart)
3880 goto restart;
3881
3883 list_free(oids);
3884
3885 /* Now sort and de-duplicate the result list */
3886 list_sort(result, list_oid_cmp);
3887 list_deduplicate_oid(result);
3888
3889 return result;
3890}
3891
3892/*
3893 * StorePartitionKey
3894 * Store information about the partition key rel into the catalog
3895 */
3896void
3898 char strategy,
3899 int16 partnatts,
3900 AttrNumber *partattrs,
3901 List *partexprs,
3903 Oid *partcollation)
3904{
3905 int i;
3911 HeapTuple tuple;
3913 bool nulls[Natts_pg_partitioned_table] = {0};
3916 ObjectAddresses *addrs;
3917
3918 Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
3919
3920 /* Copy the partition attribute numbers, opclass OIDs into arrays */
3921 partattrs_vec = buildint2vector(partattrs, partnatts);
3923 partcollation_vec = buildoidvector(partcollation, partnatts);
3924
3925 /* Convert the expressions (if any) to a text datum */
3926 if (partexprs)
3927 {
3928 char *exprString;
3929
3930 exprString = nodeToString(partexprs);
3933 }
3934 else
3935 partexprDatum = (Datum) 0;
3936
3938
3939 /* Only this can ever be NULL */
3940 if (!partexprDatum)
3941 nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
3942
3951
3953
3956
3957 /* Mark this relation as dependent on a few things as follows */
3958 addrs = new_object_addresses();
3960
3961 /* Operator class and collation per key column */
3962 for (i = 0; i < partnatts; i++)
3963 {
3966
3967 /* The default collation is pinned, so don't bother recording it */
3968 if (OidIsValid(partcollation[i]) &&
3969 partcollation[i] != DEFAULT_COLLATION_OID)
3970 {
3973 }
3974 }
3975
3977 free_object_addresses(addrs);
3978
3979 /*
3980 * The partitioning columns are made internally dependent on the table,
3981 * because we cannot drop any of them without dropping the whole table.
3982 * (ATExecDropColumn independently enforces that, but it's not bulletproof
3983 * so we need the dependencies too.)
3984 */
3985 for (i = 0; i < partnatts; i++)
3986 {
3987 if (partattrs[i] == 0)
3988 continue; /* ignore expressions here */
3989
3991 RelationGetRelid(rel), partattrs[i]);
3993 }
3994
3995 /*
3996 * Also consider anything mentioned in partition expressions. External
3997 * references (e.g. functions) get NORMAL dependencies. Table columns
3998 * mentioned in the expressions are handled the same as plain partitioning
3999 * columns, i.e. they become internally dependent on the whole table.
4000 */
4001 if (partexprs)
4003 (Node *) partexprs,
4004 RelationGetRelid(rel),
4007 true /* reverse the self-deps */ );
4008
4009 /*
4010 * We must invalidate the relcache so that the next
4011 * CommandCounterIncrement() will cause the same to be rebuilt using the
4012 * information in just created catalog entry.
4013 */
4015}
4016
4017/*
4018 * RemovePartitionKeyByRelId
4019 * Remove pg_partitioned_table entry for a relation
4020 */
4021void
4023{
4024 Relation rel;
4025 HeapTuple tuple;
4026
4028
4030 if (!HeapTupleIsValid(tuple))
4031 elog(ERROR, "cache lookup failed for partition key of relation %u",
4032 relid);
4033
4034 CatalogTupleDelete(rel, &tuple->t_self);
4035
4036 ReleaseSysCache(tuple);
4038}
4039
4040/*
4041 * StorePartitionBound
4042 * Update pg_class tuple of rel to store the partition bound and set
4043 * relispartition to true
4044 *
4045 * If this is the default partition, also update the default partition OID in
4046 * pg_partitioned_table.
4047 *
4048 * Also, invalidate the parent's relcache, so that the next rebuild will load
4049 * the new partition's info into its partition descriptor. If there is a
4050 * default partition, we must invalidate its relcache entry as well.
4051 */
4052void
4054{
4056 HeapTuple tuple,
4057 newtuple;
4062
4063 /* Update pg_class tuple */
4067 if (!HeapTupleIsValid(tuple))
4068 elog(ERROR, "cache lookup failed for relation %u",
4069 RelationGetRelid(rel));
4070
4071#ifdef USE_ASSERT_CHECKING
4072 {
4074 bool isnull;
4075
4077 Assert(!classForm->relispartition);
4079 &isnull);
4080 Assert(isnull);
4081 }
4082#endif
4083
4084 /* Fill in relpartbound value */
4085 memset(new_val, 0, sizeof(new_val));
4086 memset(new_null, false, sizeof(new_null));
4087 memset(new_repl, false, sizeof(new_repl));
4091 newtuple = heap_modify_tuple(tuple, RelationGetDescr(classRel),
4093 /* Also set the flag */
4094 ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true;
4095
4096 /*
4097 * We already checked for no inheritance children, but reset
4098 * relhassubclass in case it was left over.
4099 */
4100 if (rel->rd_rel->relkind == RELKIND_RELATION && rel->rd_rel->relhassubclass)
4101 ((Form_pg_class) GETSTRUCT(newtuple))->relhassubclass = false;
4102
4103 CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
4104 heap_freetuple(newtuple);
4106
4107 /*
4108 * If we're storing bounds for the default partition, update
4109 * pg_partitioned_table too.
4110 */
4111 if (bound->is_default)
4113 RelationGetRelid(rel));
4114
4115 /* Make these updates visible */
4117
4118 /*
4119 * The partition constraint for the default partition depends on the
4120 * partition bounds of every other partition, so we must invalidate the
4121 * relcache entry for that partition every time a partition is added or
4122 * removed.
4123 */
4128
4130}
void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
Definition aclchk.c:4345
Acl * get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid)
Definition aclchk.c:4265
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
int16 AttrNumber
Definition attnum.h:21
#define InvalidAttrNumber
Definition attnum.h:23
static Datum values[MAXATTR]
Definition bootstrap.c:147
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:798
#define Min(x, y)
Definition c.h:1040
#define Assert(condition)
Definition c.h:906
TransactionId MultiXactId
Definition c.h:709
int16_t int16
Definition c.h:574
int32_t int32
Definition c.h:575
#define lengthof(array)
Definition c.h:836
uint32 CommandId
Definition c.h:713
uint32 TransactionId
Definition c.h:699
#define OidIsValid(objectId)
Definition c.h:821
bool IsToastNamespace(Oid namespaceId)
Definition catalog.c:261
RelFileNumber GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence)
Definition catalog.c:557
bool IsCatalogNamespace(Oid namespaceId)
Definition catalog.c:243
bool contain_mutable_functions_after_planning(Expr *expr)
Definition clauses.c:499
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool reverse_self)
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
ObjectAddresses * new_object_addresses(void)
void free_object_addresses(ObjectAddresses *addrs)
@ DEPENDENCY_INTERNAL
Definition dependency.h:35
@ DEPENDENCY_NORMAL
Definition dependency.h:33
int errcode(int sqlerrcode)
Definition elog.c:874
int errmsg(const char *fmt,...)
Definition elog.c:1093
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define NOTICE
Definition elog.h:35
#define ereport(elevel,...)
Definition elog.h:150
bool equal(const void *a, const void *b)
Definition equalfuncs.c:223
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
const TupleTableSlotOps TTSOpsHeapTuple
Definition execTuples.c:85
#define palloc_object(type)
Definition fe_memutils.h:74
#define palloc_array(type, count)
Definition fe_memutils.h:76
#define OidFunctionCall3(functionId, arg1, arg2, arg3)
Definition fmgr.h:726
char * format_type_be(Oid type_oid)
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
bool IsBinaryUpgrade
Definition globals.c:121
Oid MyDatabaseTableSpace
Definition globals.c:96
void RemoveAttributeById(Oid relid, AttrNumber attnum)
Definition heap.c:1683
void RelationClearMissing(Relation rel)
Definition heap.c:1964
void SetAttrMissing(Oid relid, char *attname, char *value)
Definition heap.c:2086
static Oid StoreRelCheck(Relation rel, const char *ccname, Node *expr, bool is_enforced, bool is_validated, bool is_local, int16 inhcount, bool is_no_inherit, bool is_internal)
Definition heap.c:2147
List * heap_truncate_find_FKs(List *relationIds)
Definition heap.c:3770
void DeleteSystemAttributeTuples(Oid relid)
Definition heap.c:1642
void StorePartitionKey(Relation rel, char strategy, int16 partnatts, AttrNumber *partattrs, List *partexprs, Oid *partopclass, Oid *partcollation)
Definition heap.c:3897
static void StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal)
Definition heap.c:2310
static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relkind)
Definition heap.c:834
void DeleteRelationTuple(Oid relid)
Definition heap.c:1576
static void RelationTruncateIndexes(Relation heapRelation)
Definition heap.c:3542
RelFileNumber binary_upgrade_next_heap_pg_class_relfilenumber
Definition heap.c:83
static void AddNewRelationTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Oid new_type_oid, Oid reloftype, Oid relowner, char relkind, TransactionId relfrozenxid, TransactionId relminmxid, Datum relacl, Datum reloptions)
Definition heap.c:984
void DeleteAttributeTuples(Oid relid)
Definition heap.c:1605
void RemoveStatistics(Oid relid, AttrNumber attnum)
Definition heap.c:3495
static const FormData_pg_attribute a4
Definition heap.c:183
RelFileNumber binary_upgrade_next_toast_pg_class_relfilenumber
Definition heap.c:84
static ObjectAddress AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, char new_rel_kind, Oid ownerid, Oid new_row_type, Oid new_array_type)
Definition heap.c:1043
static bool contains_user_functions_checker(Oid func_id, void *context)
Definition heap.c:3257
static const FormData_pg_attribute a1
Definition heap.c:144
Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, Oid reltypeid, Oid reloftypeid, Oid ownerid, Oid accessmtd, TupleDesc tupdesc, List *cooked_constraints, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, OnCommitAction oncommit, Datum reloptions, bool use_user_acl, bool allow_system_table_mods, bool is_internal, Oid relrewrite, ObjectAddress *typaddress)
Definition heap.c:1122
void heap_truncate(List *relids)
Definition heap.c:3590
static bool MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr, bool allow_merge, bool is_local, bool is_enforced, bool is_initially_valid, bool is_no_inherit)
Definition heap.c:2712
static const FormData_pg_attribute *const SysAtt[]
Definition heap.c:228
static Oid StoreRelNotNull(Relation rel, const char *nnname, AttrNumber attnum, bool is_validated, bool is_local, int inhcount, bool is_no_inherit)
Definition heap.c:2254
void CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation, List *containing_rowtypes, int flags)
Definition heap.c:544
const FormData_pg_attribute * SystemAttributeByName(const char *attname)
Definition heap.c:248
void CopyStatistics(Oid fromrelid, Oid torelid)
Definition heap.c:3442
List * AddRelationNotNullConstraints(Relation rel, List *constraints, List *old_notnulls, List *existing_constraints)
Definition heap.c:2897
static void check_virtual_generated_security(ParseState *pstate, Node *node)
Definition heap.c:3305
void heap_truncate_check_FKs(List *relations, bool tempTables)
Definition heap.c:3675
static const FormData_pg_attribute a6
Definition heap.c:215
static bool check_nested_generated_walker(Node *node, void *context)
Definition heap.c:3183
static void SetRelationNumChecks(Relation rel, int numchecks)
Definition heap.c:3149
static const FormData_pg_attribute a3
Definition heap.c:170
static void RelationRemoveInheritance(Oid relid)
Definition heap.c:1543
static const FormData_pg_attribute a2
Definition heap.c:157
void StorePartitionBound(Relation rel, Relation parent, PartitionBoundSpec *bound)
Definition heap.c:4053
void heap_drop_with_catalog(Oid relid)
Definition heap.c:1784
List * AddRelationNewConstraints(Relation rel, List *newColDefaults, List *newConstraints, bool allow_merge, bool is_local, bool is_internal, const char *queryString)
Definition heap.c:2385
void InsertPgClassTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Datum relacl, Datum reloptions)
Definition heap.c:910
static bool check_virtual_generated_security_walker(Node *node, void *context)
Definition heap.c:3268
void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, int flags)
Definition heap.c:452
static void check_nested_generated(ParseState *pstate, Node *node)
Definition heap.c:3225
Oid binary_upgrade_next_toast_pg_class_oid
Definition heap.c:82
void InsertPgAttributeTuples(Relation pg_attribute_rel, TupleDesc tupdesc, Oid new_rel_oid, const FormExtraData_pg_attribute tupdesc_extra[], CatalogIndexState indstate)
Definition heap.c:717
Node * cookDefault(ParseState *pstate, Node *raw_default, Oid atttypid, int32 atttypmod, const char *attname, char attgenerated)
Definition heap.c:3323
void heap_truncate_one_rel(Relation rel)
Definition heap.c:3631
void RemovePartitionKeyByRelId(Oid relid)
Definition heap.c:4022
Oid binary_upgrade_next_heap_pg_class_oid
Definition heap.c:81
const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)
Definition heap.c:236
static const FormData_pg_attribute a5
Definition heap.c:196
void StoreAttrMissingVal(Relation rel, AttrNumber attnum, Datum missingval)
Definition heap.c:2030
Relation heap_create(const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, RelFileNumber relfilenumber, Oid accessmtd, TupleDesc tupDesc, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, bool allow_system_table_mods, TransactionId *relfrozenxid, MultiXactId *relminmxid, bool create_storage)
Definition heap.c:285
static Node * cookConstraint(ParseState *pstate, Node *raw_constraint, char *relname)
Definition heap.c:3404
#define CHKATYPE_ANYRECORD
Definition heap.h:24
#define CHKATYPE_ANYARRAY
Definition heap.h:23
#define CHKATYPE_IS_VIRTUAL
Definition heap.h:26
#define CHKATYPE_IS_PARTKEY
Definition heap.h:25
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1210
HeapTuple heap_copytuple(HeapTuple tuple)
Definition heaptuple.c:778
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1117
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
#define MaxHeapAttributeNumber
static Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
IndexInfo * BuildDummyIndexInfo(Relation index)
Definition index.c:2486
void index_build(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, bool isreindex, bool parallel)
Definition index.c:3000
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:177
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:133
void CatalogTuplesMultiInsertWithInfo(Relation heapRel, TupleTableSlot **slot, int ntuples, CatalogIndexState indstate)
Definition indexing.c:273
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
void CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition indexing.c:256
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition indexing.c:61
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition indexing.c:43
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
#define MAX_CATALOG_MULTI_INSERT_BYTES
Definition indexing.h:33
long val
Definition informix.c:689
static struct @174 value
int2vector * buildint2vector(const int16 *int2s, int n)
Definition int.c:114
static bool pg_add_s16_overflow(int16 a, int16 b, int16 *result)
Definition int.h:67
void CacheInvalidateRelcache(Relation relation)
Definition inval.c:1635
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition inval.c:1691
int j
Definition isn.c:78
int i
Definition isn.c:77
List * lappend(List *list, void *datum)
Definition list.c:339
void list_sort(List *list, list_sort_comparator cmp)
Definition list.c:1674
List * list_delete_nth_cell(List *list, int n)
Definition list.c:767
List * list_copy(const List *oldlist)
Definition list.c:1573
List * lappend_int(List *list, int datum)
Definition list.c:357
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
List * list_append_unique_oid(List *list, Oid datum)
Definition list.c:1380
void list_deduplicate_oid(List *list)
Definition list.c:1495
int list_oid_cmp(const ListCell *p1, const ListCell *p2)
Definition list.c:1703
List * list_delete_last(List *list)
Definition list.c:957
void list_free(List *list)
Definition list.c:1546
bool list_member_oid(const List *list, Oid datum)
Definition list.c:722
List * list_union(const List *list1, const List *list2)
Definition list.c:1066
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition lmgr.c:107
#define NoLock
Definition lockdefs.h:34
#define AccessExclusiveLock
Definition lockdefs.h:43
#define AccessShareLock
Definition lockdefs.h:36
#define RowExclusiveLock
Definition lockdefs.h:38
Oid get_range_subtype(Oid rangeOid)
Definition lsyscache.c:3559
char * get_rel_name(Oid relid)
Definition lsyscache.c:2078
AttrNumber get_attnum(Oid relid, const char *attname)
Definition lsyscache.c:934
Oid get_element_type(Oid typid)
Definition lsyscache.c:2911
char get_attgenerated(Oid relid, AttrNumber attnum)
Definition lsyscache.c:964
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition lsyscache.c:903
Oid get_range_collation(Oid rangeOid)
Definition lsyscache.c:3585
bool type_is_collatable(Oid typid)
Definition lsyscache.c:3233
Oid get_typ_typrelid(Oid typid)
Definition lsyscache.c:2883
char get_typtype(Oid typid)
Definition lsyscache.c:2781
Oid getBaseType(Oid typid)
Definition lsyscache.c:2673
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3518
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition lsyscache.c:2035
char * pstrdup(const char *in)
Definition mcxt.c:1781
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc(Size size)
Definition mcxt.c:1387
#define IsBootstrapProcessingMode()
Definition miscadmin.h:477
#define IsNormalProcessingMode()
Definition miscadmin.h:479
#define InvalidMultiXactId
Definition multixact.h:25
void namestrcpy(Name name, const char *str)
Definition name.c:233
Oid exprType(const Node *expr)
Definition nodeFuncs.c:42
bool check_functions_in_node(Node *node, check_function_callback checker, void *context)
Definition nodeFuncs.c:1909
int exprLocation(const Node *expr)
Definition nodeFuncs.c:1384
#define expression_tree_walker(n, w, c)
Definition nodeFuncs.h:153
#define IsA(nodeptr, _type_)
Definition nodes.h:164
#define castNode(_type_, nodeptr)
Definition nodes.h:182
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
#define ObjectAddressSet(addr, class_id, object_id)
#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id)
oidvector * buildoidvector(const Oid *oids, int n)
Definition oid.c:87
char * nodeToString(const void *obj)
Definition outfuncs.c:802
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
void assign_expr_collations(ParseState *pstate, Node *expr)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition parse_expr.c:120
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
ParseState * make_parsestate(ParseState *parentParseState)
Definition parse_node.c:39
@ EXPR_KIND_COLUMN_DEFAULT
Definition parse_node.h:70
@ EXPR_KIND_GENERATED_COLUMN
Definition parse_node.h:83
@ EXPR_KIND_CHECK_CONSTRAINT
Definition parse_node.h:68
void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, LOCKMODE lockmode, Alias *alias, bool inh, bool inFromCl)
@ CONSTR_DEFAULT
@ CONSTR_NOTNULL
@ CONSTR_CHECK
@ OBJECT_SEQUENCE
@ OBJECT_TABLE
#define rt_fetch(rangetable_index, rangetable)
Definition parsetree.h:31
PartitionDesc RelationGetPartitionDesc(Relation rel, bool omit_detached)
Definition partdesc.c:71
Oid get_default_oid_from_partdesc(PartitionDesc partdesc)
Definition partdesc.c:501
void update_default_partition_oid(Oid parentId, Oid defaultPartId)
Definition partition.c:340
Oid get_default_partition_oid(Oid parentId)
Definition partition.c:315
Oid get_partition_parent(Oid relid, bool even_if_detached)
Definition partition.c:53
Oid StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr, bool is_internal)
Definition pg_attrdef.c:37
FormData_pg_attribute
NameData attname
char attstorage
bool attbyval
char attalign
int16 attnum
FormData_pg_attribute * Form_pg_attribute
bool attnotnull
NameData relname
Definition pg_class.h:40
FormData_pg_class * Form_pg_class
Definition pg_class.h:160
#define NAMEDATALEN
Oid CreateConstraintEntry(const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, bool isEnforced, bool isValidated, Oid parentConstrId, Oid relId, const int16 *constraintKey, int constraintNKeys, int constraintNTotalKeys, Oid domainId, Oid indexRelId, Oid foreignRelId, const int16 *foreignKey, const Oid *pfEqOp, const Oid *ppEqOp, const Oid *ffEqOp, int foreignNKeys, char foreignUpdateType, char foreignDeleteType, const int16 *fkDeleteSetCols, int numFkDeleteSetCols, char foreignMatchType, const Oid *exclOp, Node *conExpr, const char *conBin, bool conIsLocal, int16 conInhCount, bool conNoInherit, bool conPeriod, bool is_internal)
bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, const char *conname)
bool AdjustNotNullInheritance(Oid relid, AttrNumber attnum, const char *new_conname, bool is_local, bool is_no_inherit, bool is_notvalid)
char * ChooseConstraintName(const char *name1, const char *name2, const char *label, Oid namespaceid, List *others)
@ CONSTRAINT_RELATION
END_CATALOG_STRUCT typedef FormData_pg_constraint * Form_pg_constraint
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition pg_depend.c:47
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition pg_depend.c:195
#define lfirst(lc)
Definition pg_list.h:172
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
#define foreach_delete_current(lst, var_or_cell)
Definition pg_list.h:391
#define list_make1_oid(x1)
Definition pg_list.h:242
#define foreach_ptr(type, var, lst)
Definition pg_list.h:469
static void * list_nth(const List *list, int n)
Definition pg_list.h:299
#define linitial(l)
Definition pg_list.h:178
#define foreach_node(type, var, lst)
Definition pg_list.h:496
#define list_nth_node(type, list, n)
Definition pg_list.h:327
#define lfirst_oid(lc)
Definition pg_list.h:174
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
void recordDependencyOnTablespace(Oid classId, Oid objectId, Oid tablespace)
FormData_pg_statistic * Form_pg_statistic
void RemoveSubscriptionRel(Oid subid, Oid relid)
ObjectAddress TypeCreate(Oid newTypeOid, const char *typeName, Oid typeNamespace, Oid relationOid, char relationKind, Oid ownerId, int16 internalSize, char typeType, char typeCategory, bool typePreferred, char typDelim, Oid inputProcedure, Oid outputProcedure, Oid receiveProcedure, Oid sendProcedure, Oid typmodinProcedure, Oid typmodoutProcedure, Oid analyzeProcedure, Oid subscriptProcedure, Oid elementType, bool isImplicitArray, Oid arrayType, Oid baseType, const char *defaultTypeValue, char *defaultTypeBin, bool passedByValue, char alignment, char storage, int32 typeMod, int32 typNDims, bool typeNotNull, Oid typeCollation)
Definition pg_type.c:195
bool moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace)
Definition pg_type.c:903
char * makeArrayTypeName(const char *typeName, Oid typeNamespace)
Definition pg_type.c:838
void pgstat_create_relation(Relation rel)
void pgstat_drop_relation(Relation rel)
#define snprintf
Definition port.h:260
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
static Datum Float4GetDatum(float4 X)
Definition postgres.h:478
static Datum TransactionIdGetDatum(TransactionId X)
Definition postgres.h:302
static Datum Int16GetDatum(int16 X)
Definition postgres.h:182
static Datum MultiXactIdGetDatum(MultiXactId X)
Definition postgres.h:312
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
static Datum NameGetDatum(const NameData *X)
Definition postgres.h:403
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
static Datum CharGetDatum(char X)
Definition postgres.h:132
#define InvalidOid
unsigned int Oid
void CheckTableForSerializableConflictIn(Relation relation)
Definition predicate.c:4417
static int fb(int x)
OnCommitAction
Definition primnodes.h:58
@ ONCOMMIT_NOOP
Definition primnodes.h:59
@ COERCE_IMPLICIT_CAST
Definition primnodes.h:769
@ COERCION_ASSIGNMENT
Definition primnodes.h:748
void * stringToNode(const char *str)
Definition read.c:90
#define RelationGetRelid(relation)
Definition rel.h:514
#define RelationGetDescr(relation)
Definition rel.h:540
#define RelationGetNumberOfAttributes(relation)
Definition rel.h:520
#define RelationGetRelationName(relation)
Definition rel.h:548
#define RelationGetNamespace(relation)
Definition rel.h:555
List * RelationGetIndexList(Relation relation)
Definition relcache.c:4831
void RelationForgetRelation(Oid rid)
Definition relcache.c:2888
Relation RelationBuildLocalRelation(const char *relname, Oid relnamespace, TupleDesc tupDesc, Oid relid, Oid accessmtd, RelFileNumber relfilenumber, Oid reltablespace, bool shared_relation, bool mapped_relation, char relpersistence, char relkind)
Definition relcache.c:3510
Oid RelFileNumber
Definition relpath.h:25
#define InvalidRelFileNumber
Definition relpath.h:26
#define RelFileNumberIsValid(relnumber)
Definition relpath.h:27
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
void relation_close(Relation relation, LOCKMODE lockmode)
Definition relation.c:205
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition relation.c:47
void check_stack_depth(void)
Definition stack_depth.c:95
SMgrRelation RelationCreateStorage(RelFileLocator rlocator, char relpersistence, bool register_delete)
Definition storage.c:122
void RelationDropStorage(Relation rel)
Definition storage.c:207
void RelationTruncate(Relation rel, BlockNumber nblocks)
Definition storage.c:289
#define BTEqualStrategyNumber
Definition stratnum.h:31
#define BTLessEqualStrategyNumber
Definition stratnum.h:30
#define ERRCODE_DUPLICATE_OBJECT
Definition streamutil.c:30
List * keys
ConstrType contype
bool is_no_inherit
char * conname
char * name
Definition heap.h:40
AttrNumber attnum
Definition heap.h:41
bool skip_validation
Definition heap.h:44
bool is_enforced
Definition heap.h:43
bool is_no_inherit
Definition heap.h:47
int16 inhcount
Definition heap.h:46
bool is_local
Definition heap.h:45
ConstrType contype
Definition heap.h:37
Node * expr
Definition heap.h:42
ItemPointerData t_self
Definition htup.h:65
Definition pg_list.h:54
Definition nodes.h:135
const char * p_sourcetext
Definition parse_node.h:191
List * p_rtable
Definition parse_node.h:192
TupleDesc rd_att
Definition rel.h:112
RelFileLocator rd_locator
Definition rel.h:57
Form_pg_class rd_rel
Definition rel.h:111
bool * tts_isnull
Definition tuptable.h:126
Datum * tts_values
Definition tuptable.h:124
ParseLoc location
Definition primnodes.h:311
AttrNumber varattno
Definition primnodes.h:275
int varno
Definition primnodes.h:270
Definition c.h:778
#define MinTransactionIdAttributeNumber
Definition sysattr.h:22
#define MaxCommandIdAttributeNumber
Definition sysattr.h:25
#define MaxTransactionIdAttributeNumber
Definition sysattr.h:24
#define TableOidAttributeNumber
Definition sysattr.h:26
#define SelfItemPointerAttributeNumber
Definition sysattr.h:21
#define MinCommandIdAttributeNumber
Definition sysattr.h:23
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:230
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition syscache.c:475
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
#define SearchSysCacheCopy1(cacheId, key1)
Definition syscache.h:91
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition syscache.h:93
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition syscache.h:111
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
static void table_relation_set_new_filelocator(Relation rel, const RelFileLocator *newrlocator, char persistence, TransactionId *freezeXid, MultiXactId *minmulti)
Definition tableam.h:1611
static void table_relation_nontransactional_truncate(Relation rel)
Definition tableam.h:1629
void CheckTableNotInUse(Relation rel, const char *stmt)
Definition tablecmds.c:4424
void remove_on_commit_action(Oid relid)
void register_on_commit_action(Oid relid, OnCommitAction action)
#define FirstUnpinnedObjectId
Definition transam.h:196
#define InvalidTransactionId
Definition transam.h:31
void FreeTupleDesc(TupleDesc tupdesc)
Definition tupdesc.c:485
TupleDesc CreateTupleDesc(int natts, Form_pg_attribute *attrs)
Definition tupdesc.c:212
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:160
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:457
Oid AssignTypeArrayOid(void)
Definition typecmds.c:2473
#define DEFAULT_TYPDELIM
Definition typecmds.h:22
#define strVal(v)
Definition value.h:82
bool contain_var_clause(Node *node)
Definition var.c:406
List * pull_var_clause(Node *node, int flags)
Definition var.c:653
void CommandCounterIncrement(void)
Definition xact.c:1101