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 {
254 const FormData_pg_attribute *att = SysAtt[j];
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/* ----------------------------------------------------------------
271 * heap_create - Create an uncataloged heap relation
272 *
273 * Note API change: the caller must now always provide the OID
274 * to use for the relation. The relfilenumber may be (and in
275 * the simplest cases is) left unspecified.
276 *
277 * create_storage indicates whether or not to create the storage.
278 * However, even if create_storage is true, no storage will be
279 * created if the relkind is one that doesn't have storage.
280 *
281 * rel->rd_rel is initialized by RelationBuildLocalRelation,
282 * and is mostly zeroes at return.
283 * ----------------------------------------------------------------
284 */
287 Oid relnamespace,
288 Oid reltablespace,
289 Oid relid,
290 RelFileNumber relfilenumber,
292 TupleDesc tupDesc,
293 char relkind,
294 char relpersistence,
295 bool shared_relation,
296 bool mapped_relation,
298 TransactionId *relfrozenxid,
299 MultiXactId *relminmxid,
300 bool create_storage)
301{
302 Relation rel;
303
304 /* The caller must have provided an OID for the relation. */
305 Assert(OidIsValid(relid));
306
307 /*
308 * Don't allow creating relations in pg_catalog directly, even though it
309 * is allowed to move user defined relations there. Semantics with search
310 * paths including pg_catalog are too confusing for now.
311 *
312 * But allow creating indexes on relations in pg_catalog even if
313 * allow_system_table_mods = off, upper layers already guarantee it's on a
314 * user defined relation, not a system one.
315 */
317 ((IsCatalogNamespace(relnamespace) && relkind != RELKIND_INDEX) ||
318 IsToastNamespace(relnamespace)) &&
322 errmsg("permission denied to create \"%s.%s\"",
323 get_namespace_name(relnamespace), relname),
324 errdetail("System catalog modifications are currently disallowed.")));
325
326 *relfrozenxid = InvalidTransactionId;
327 *relminmxid = InvalidMultiXactId;
328
329 /*
330 * Force reltablespace to zero if the relation kind does not support
331 * tablespaces. This is mainly just for cleanliness' sake.
332 */
333 if (!RELKIND_HAS_TABLESPACE(relkind))
334 reltablespace = InvalidOid;
335
336 /* Don't create storage for relkinds without physical storage. */
337 if (!RELKIND_HAS_STORAGE(relkind))
338 create_storage = false;
339 else
340 {
341 /*
342 * If relfilenumber is unspecified by the caller then create storage
343 * with oid same as relid.
344 */
345 if (!RelFileNumberIsValid(relfilenumber))
346 relfilenumber = relid;
347 }
348
349 /*
350 * Never allow a pg_class entry to explicitly specify the database's
351 * default tablespace in reltablespace; force it to zero instead. This
352 * ensures that if the database is cloned with a different default
353 * tablespace, the pg_class entry will still match where CREATE DATABASE
354 * will put the physically copied relation.
355 *
356 * Yes, this is a bit of a hack.
357 */
358 if (reltablespace == MyDatabaseTableSpace)
359 reltablespace = InvalidOid;
360
361 /*
362 * build the relcache entry.
363 */
365 relnamespace,
366 tupDesc,
367 relid,
368 accessmtd,
369 relfilenumber,
370 reltablespace,
373 relpersistence,
374 relkind);
375
376 /*
377 * Have the storage manager create the relation's disk file, if needed.
378 *
379 * For tables, the AM callback creates both the main and the init fork.
380 * For others, only the main fork is created; the other forks will be
381 * created on demand.
382 */
383 if (create_storage)
384 {
385 if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind))
387 relpersistence,
388 relfrozenxid, relminmxid);
389 else if (RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
390 RelationCreateStorage(rel->rd_locator, relpersistence, true);
391 else
392 Assert(false);
393 }
394
395 /*
396 * If a tablespace is specified, removal of that tablespace is normally
397 * protected by the existence of a physical file; but for relations with
398 * no files, add a pg_shdepend entry to account for that.
399 */
400 if (!create_storage && reltablespace != InvalidOid)
402 reltablespace);
403
404 /* ensure that stats are dropped if transaction aborts */
406
407 return rel;
408}
409
410/* ----------------------------------------------------------------
411 * heap_create_with_catalog - Create a cataloged relation
412 *
413 * this is done in multiple steps:
414 *
415 * 1) CheckAttributeNamesTypes() is used to make certain the tuple
416 * descriptor contains a valid set of attribute names and types
417 *
418 * 2) pg_class is opened and get_relname_relid()
419 * performs a scan to ensure that no relation with the
420 * same name already exists.
421 *
422 * 3) heap_create() is called to create the new relation on disk.
423 *
424 * 4) TypeCreate() is called to define a new type corresponding
425 * to the new relation.
426 *
427 * 5) AddNewRelationTuple() is called to register the
428 * relation in pg_class.
429 *
430 * 6) AddNewAttributeTuples() is called to register the
431 * new relation's schema in pg_attribute.
432 *
433 * 7) StoreConstraints() is called - vadim 08/22/97
434 *
435 * 8) the relations are closed and the new relation's oid
436 * is returned.
437 *
438 * ----------------------------------------------------------------
439 */
440
441/* --------------------------------
442 * CheckAttributeNamesTypes
443 *
444 * this is used to make certain the tuple descriptor contains a
445 * valid set of attribute names and datatypes. a problem simply
446 * generates ereport(ERROR) which aborts the current transaction.
447 *
448 * relkind is the relkind of the relation to be created.
449 * flags controls which datatypes are allowed, cf CheckAttributeType.
450 * --------------------------------
451 */
452void
454 int flags)
455{
456 int i;
457 int j;
458 int natts = tupdesc->natts;
459
460 /* Sanity check on column count */
464 errmsg("tables can have at most %d columns",
466
467 /*
468 * first check for collision with system attribute names
469 *
470 * Skip this for a view or type relation, since those don't have system
471 * attributes.
472 */
473 if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
474 {
475 for (i = 0; i < natts; i++)
476 {
477 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
478
479 if (SystemAttributeByName(NameStr(attr->attname)) != NULL)
482 errmsg("column name \"%s\" conflicts with a system column name",
483 NameStr(attr->attname))));
484 }
485 }
486
487 /*
488 * next check for repeated attribute names
489 */
490 for (i = 1; i < natts; i++)
491 {
492 for (j = 0; j < i; j++)
493 {
494 if (strcmp(NameStr(TupleDescAttr(tupdesc, j)->attname),
495 NameStr(TupleDescAttr(tupdesc, i)->attname)) == 0)
498 errmsg("column name \"%s\" specified more than once",
499 NameStr(TupleDescAttr(tupdesc, j)->attname))));
500 }
501 }
502
503 /*
504 * next check the attribute types
505 */
506 for (i = 0; i < natts; i++)
507 {
508 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
509
510 if (attr->attisdropped)
511 continue;
512 CheckAttributeType(NameStr(attr->attname),
513 attr->atttypid,
514 attr->attcollation,
515 NIL, /* assume we're creating a new rowtype */
516 flags | (attr->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL ? CHKATYPE_IS_VIRTUAL : 0));
517 }
518}
519
520/* --------------------------------
521 * CheckAttributeType
522 *
523 * Verify that the proposed datatype of an attribute is legal.
524 * This is needed mainly because there are types (and pseudo-types)
525 * in the catalogs that we do not support as elements of real tuples.
526 * We also check some other properties required of a table column.
527 *
528 * If the attribute is being proposed for addition to an existing table or
529 * composite type, pass a one-element list of the rowtype OID as
530 * containing_rowtypes. When checking a to-be-created rowtype, it's
531 * sufficient to pass NIL, because there could not be any recursive reference
532 * to a not-yet-existing rowtype.
533 *
534 * flags is a bitmask controlling which datatypes we allow. For the most
535 * part, pseudo-types are disallowed as attribute types, but there are some
536 * exceptions: ANYARRAYOID, RECORDOID, and RECORDARRAYOID can be allowed
537 * in some cases. (This works because values of those type classes are
538 * self-identifying to some extent. However, RECORDOID and RECORDARRAYOID
539 * are reliably identifiable only within a session, since the identity info
540 * may use a typmod that is only locally assigned. The caller is expected
541 * to know whether these cases are safe.)
542 *
543 * flags can also control the phrasing of the error messages. If
544 * CHKATYPE_IS_PARTKEY is specified, "attname" should be a partition key
545 * column number as text, not a real column name.
546 * --------------------------------
547 */
548void
550 Oid atttypid, Oid attcollation,
552 int flags)
553{
556
557 /* since this function recurses, it could be driven to stack overflow */
559
561 {
562 /*
563 * We disallow pseudo-type columns, with the exception of ANYARRAY,
564 * RECORD, and RECORD[] when the caller says that those are OK.
565 *
566 * We don't need to worry about recursive containment for RECORD and
567 * RECORD[] because (a) no named composite type should be allowed to
568 * contain those, and (b) two "anonymous" record types couldn't be
569 * considered to be the same type, so infinite recursion isn't
570 * possible.
571 */
572 if (!((atttypid == ANYARRAYOID && (flags & CHKATYPE_ANYARRAY)) ||
573 (atttypid == RECORDOID && (flags & CHKATYPE_ANYRECORD)) ||
574 (atttypid == RECORDARRAYOID && (flags & CHKATYPE_ANYRECORD))))
575 {
576 if (flags & CHKATYPE_IS_PARTKEY)
579 /* translator: first %s is an integer not a name */
580 errmsg("partition key column %s has pseudo-type %s",
582 else
585 errmsg("column \"%s\" has pseudo-type %s",
587 }
588 }
589 else if (att_typtype == TYPTYPE_DOMAIN)
590 {
591 /*
592 * Prevent virtual generated columns from having a domain type. We
593 * would have to enforce domain constraints when columns underlying
594 * the generated column change. This could possibly be implemented,
595 * but it's not.
596 */
597 if (flags & CHKATYPE_IS_VIRTUAL)
600 errmsg("virtual generated column \"%s\" cannot have a domain type", attname));
601
602 /*
603 * If it's a domain, recurse to check its base type.
604 */
607 flags);
608 }
609 else if (att_typtype == TYPTYPE_COMPOSITE)
610 {
611 /*
612 * For a composite type, recurse into its attributes.
613 */
614 Relation relation;
615 TupleDesc tupdesc;
616 int i;
617
618 /*
619 * Check for self-containment. Eventually we might be able to allow
620 * this (just return without complaint, if so) but it's not clear how
621 * many other places would require anti-recursion defenses before it
622 * would be safe to allow tables to contain their own rowtype.
623 */
627 errmsg("composite type %s cannot be made a member of itself",
629
631
633
634 tupdesc = RelationGetDescr(relation);
635
636 for (i = 0; i < tupdesc->natts; i++)
637 {
638 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
639
640 if (attr->attisdropped)
641 continue;
642 CheckAttributeType(NameStr(attr->attname),
643 attr->atttypid, attr->attcollation,
645 flags & ~CHKATYPE_IS_PARTKEY);
646 }
647
649
651 }
652 else if (att_typtype == TYPTYPE_RANGE)
653 {
654 /*
655 * If it's a range, recurse to check its subtype.
656 */
660 flags);
661 }
663 {
664 /*
665 * If it's a multirange, recurse to check its plain range type.
666 */
668 InvalidOid, /* range types are not collatable */
670 flags);
671 }
673 {
674 /*
675 * Must recurse into array types, too, in case they are composite.
676 */
679 flags);
680 }
681
682 /*
683 * For consistency with check_virtual_generated_security().
684 */
688 errmsg("virtual generated column \"%s\" cannot have a user-defined type", attname),
689 errdetail("Virtual generated columns that make use of user-defined types are not yet supported."));
690
691 /*
692 * This might not be strictly invalid per SQL standard, but it is pretty
693 * useless, and it cannot be dumped, so we must disallow it.
694 */
695 if (!OidIsValid(attcollation) && type_is_collatable(atttypid))
696 {
697 if (flags & CHKATYPE_IS_PARTKEY)
700 /* translator: first %s is an integer not a name */
701 errmsg("no collation was derived for partition key column %s with collatable type %s",
703 errhint("Use the COLLATE clause to set the collation explicitly.")));
704 else
707 errmsg("no collation was derived for column \"%s\" with collatable type %s",
709 errhint("Use the COLLATE clause to set the collation explicitly.")));
710 }
711}
712
713/*
714 * InsertPgAttributeTuples
715 * Construct and insert a set of tuples in pg_attribute.
716 *
717 * Caller has already opened and locked pg_attribute. tupdesc contains the
718 * attributes to insert. tupdesc_extra supplies the values for certain
719 * variable-length/nullable pg_attribute fields and must contain the same
720 * number of elements as tupdesc or be NULL. The other variable-length fields
721 * of pg_attribute are always initialized to null values.
722 *
723 * indstate is the index state for CatalogTupleInsertWithInfo. It can be
724 * passed as NULL, in which case we'll fetch the necessary info. (Don't do
725 * this when inserting multiple attributes, because it's a tad more
726 * expensive.)
727 *
728 * new_rel_oid is the relation OID assigned to the attributes inserted.
729 * If set to InvalidOid, the relation OID from tupdesc is used instead.
730 */
731void
733 TupleDesc tupdesc,
737{
738 TupleTableSlot **slot;
739 TupleDesc td;
740 int nslots;
741 int natts = 0;
742 int slotCount = 0;
743 bool close_index = false;
744
746
747 /* Initialize the number of slots to use */
748 nslots = Min(tupdesc->natts,
750 slot = palloc_array(TupleTableSlot *, nslots);
751 for (int i = 0; i < nslots; i++)
753
754 while (natts < tupdesc->natts)
755 {
756 Form_pg_attribute attrs = TupleDescAttr(tupdesc, natts);
758
760
761 memset(slot[slotCount]->tts_isnull, false,
762 slot[slotCount]->tts_tupleDescriptor->natts * sizeof(bool));
763
764 if (new_rel_oid != InvalidOid)
766 else
768
788 if (attrs_extra)
789 {
790 slot[slotCount]->tts_values[Anum_pg_attribute_attstattarget - 1] = attrs_extra->attstattarget.value;
791 slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = attrs_extra->attstattarget.isnull;
792
793 slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.value;
794 slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.isnull;
795 }
796 else
797 {
800 }
801
802 /*
803 * The remaining fields are not set for new columns.
804 */
808
810 slotCount++;
811
812 /*
813 * If slots are full or the end of processing has been reached, insert
814 * a batch of tuples.
815 */
816 if (slotCount == nslots || natts == tupdesc->natts - 1)
817 {
818 /* fetch index info only when we know we need it */
819 if (!indstate)
820 {
822 close_index = true;
823 }
824
825 /* insert the new tuples and update the indexes */
827 indstate);
828 slotCount = 0;
829 }
830
831 natts++;
832 }
833
834 if (close_index)
836 for (int i = 0; i < nslots; i++)
838 pfree(slot);
839}
840
841/* --------------------------------
842 * AddNewAttributeTuples
843 *
844 * this registers the new relation's schema by adding
845 * tuples to pg_attribute.
846 * --------------------------------
847 */
848static void
850 TupleDesc tupdesc,
851 char relkind)
852{
853 Relation rel;
855 int natts = tupdesc->natts;
858
859 /*
860 * open pg_attribute and its indexes.
861 */
863
865
867
868 /* add dependencies on their datatypes and collations */
869 for (int i = 0; i < natts; i++)
870 {
871 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
872
873 /* Add dependency info */
877
878 /* The default collation is pinned, so don't bother recording it */
879 if (OidIsValid(attr->attcollation) &&
880 attr->attcollation != DEFAULT_COLLATION_OID)
881 {
883 attr->attcollation);
885 }
886 }
887
888 /*
889 * Next we add the system attributes. Skip all for a view or type
890 * relation. We don't bother with making datatype dependencies here,
891 * since presumably all these types are pinned.
892 */
893 if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
894 {
895 TupleDesc td;
896
898
900 FreeTupleDesc(td);
901 }
902
903 /*
904 * clean up
905 */
907
909}
910
911/* --------------------------------
912 * InsertPgClassTuple
913 *
914 * Construct and insert a new tuple in pg_class.
915 *
916 * Caller has already opened and locked pg_class.
917 * Tuple data is taken from new_rel_desc->rd_rel, except for the
918 * variable-width fields which are not present in a cached reldesc.
919 * relacl and reloptions are passed in Datum form (to avoid having
920 * to reference the data types in heap.h). Pass (Datum) 0 to set them
921 * to NULL.
922 * --------------------------------
923 */
924void
929 Datum reloptions)
930{
931 Form_pg_class rd_rel = new_rel_desc->rd_rel;
933 bool nulls[Natts_pg_class];
935
936 /* This is a tad tedious, but way cleaner than what we used to do... */
937 memset(values, 0, sizeof(values));
938 memset(nulls, false, sizeof(nulls));
939
941 values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname);
942 values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace);
943 values[Anum_pg_class_reltype - 1] = ObjectIdGetDatum(rd_rel->reltype);
944 values[Anum_pg_class_reloftype - 1] = ObjectIdGetDatum(rd_rel->reloftype);
945 values[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(rd_rel->relowner);
946 values[Anum_pg_class_relam - 1] = ObjectIdGetDatum(rd_rel->relam);
947 values[Anum_pg_class_relfilenode - 1] = ObjectIdGetDatum(rd_rel->relfilenode);
948 values[Anum_pg_class_reltablespace - 1] = ObjectIdGetDatum(rd_rel->reltablespace);
949 values[Anum_pg_class_relpages - 1] = Int32GetDatum(rd_rel->relpages);
950 values[Anum_pg_class_reltuples - 1] = Float4GetDatum(rd_rel->reltuples);
951 values[Anum_pg_class_relallvisible - 1] = Int32GetDatum(rd_rel->relallvisible);
952 values[Anum_pg_class_relallfrozen - 1] = Int32GetDatum(rd_rel->relallfrozen);
953 values[Anum_pg_class_reltoastrelid - 1] = ObjectIdGetDatum(rd_rel->reltoastrelid);
954 values[Anum_pg_class_relhasindex - 1] = BoolGetDatum(rd_rel->relhasindex);
955 values[Anum_pg_class_relisshared - 1] = BoolGetDatum(rd_rel->relisshared);
956 values[Anum_pg_class_relpersistence - 1] = CharGetDatum(rd_rel->relpersistence);
957 values[Anum_pg_class_relkind - 1] = CharGetDatum(rd_rel->relkind);
958 values[Anum_pg_class_relnatts - 1] = Int16GetDatum(rd_rel->relnatts);
959 values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks);
960 values[Anum_pg_class_relhasrules - 1] = BoolGetDatum(rd_rel->relhasrules);
961 values[Anum_pg_class_relhastriggers - 1] = BoolGetDatum(rd_rel->relhastriggers);
962 values[Anum_pg_class_relrowsecurity - 1] = BoolGetDatum(rd_rel->relrowsecurity);
963 values[Anum_pg_class_relforcerowsecurity - 1] = BoolGetDatum(rd_rel->relforcerowsecurity);
964 values[Anum_pg_class_relhassubclass - 1] = BoolGetDatum(rd_rel->relhassubclass);
965 values[Anum_pg_class_relispopulated - 1] = BoolGetDatum(rd_rel->relispopulated);
966 values[Anum_pg_class_relreplident - 1] = CharGetDatum(rd_rel->relreplident);
967 values[Anum_pg_class_relispartition - 1] = BoolGetDatum(rd_rel->relispartition);
968 values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
969 values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
970 values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
971 if (relacl != (Datum) 0)
973 else
974 nulls[Anum_pg_class_relacl - 1] = true;
975 if (reloptions != (Datum) 0)
976 values[Anum_pg_class_reloptions - 1] = reloptions;
977 else
978 nulls[Anum_pg_class_reloptions - 1] = true;
979
980 /* relpartbound is set by updating this tuple, if necessary */
981 nulls[Anum_pg_class_relpartbound - 1] = true;
982
984
985 /* finally insert the new tuple, update the indexes, and clean up */
987
989}
990
991/* --------------------------------
992 * AddNewRelationTuple
993 *
994 * this registers the new relation in the catalogs by
995 * adding a tuple to pg_class.
996 * --------------------------------
997 */
998static void
1003 Oid reloftype,
1004 Oid relowner,
1005 char relkind,
1006 TransactionId relfrozenxid,
1007 TransactionId relminmxid,
1008 Datum relacl,
1009 Datum reloptions)
1010{
1012
1013 /*
1014 * first we update some of the information in our uncataloged relation's
1015 * relation descriptor.
1016 */
1017 new_rel_reltup = new_rel_desc->rd_rel;
1018
1019 /* The relation is empty */
1020 new_rel_reltup->relpages = 0;
1021 new_rel_reltup->reltuples = -1;
1022 new_rel_reltup->relallvisible = 0;
1023 new_rel_reltup->relallfrozen = 0;
1024
1025 /* Sequences always have a known size */
1026 if (relkind == RELKIND_SEQUENCE)
1027 {
1028 new_rel_reltup->relpages = 1;
1029 new_rel_reltup->reltuples = 1;
1030 }
1031
1032 new_rel_reltup->relfrozenxid = relfrozenxid;
1033 new_rel_reltup->relminmxid = relminmxid;
1034 new_rel_reltup->relowner = relowner;
1035 new_rel_reltup->reltype = new_type_oid;
1036 new_rel_reltup->reloftype = reloftype;
1037
1038 /* relispartition is always set by updating this tuple later */
1039 new_rel_reltup->relispartition = false;
1040
1041 /* fill rd_att's type ID with something sane even if reltype is zero */
1042 new_rel_desc->rd_att->tdtypeid = new_type_oid ? new_type_oid : RECORDOID;
1043 new_rel_desc->rd_att->tdtypmod = -1;
1044
1045 /* Now build and insert the tuple */
1047 relacl, reloptions);
1048}
1049
1050
1051/* --------------------------------
1052 * AddNewRelationType -
1053 *
1054 * define a composite type corresponding to the new relation
1055 * --------------------------------
1056 */
1057static ObjectAddress
1058AddNewRelationType(const char *typeName,
1061 char new_rel_kind,
1062 Oid ownerid,
1065{
1066 return
1067 TypeCreate(new_row_type, /* optional predetermined OID */
1068 typeName, /* type name */
1069 typeNamespace, /* type namespace */
1070 new_rel_oid, /* relation oid */
1071 new_rel_kind, /* relation kind */
1072 ownerid, /* owner's ID */
1073 -1, /* internal size (varlena) */
1074 TYPTYPE_COMPOSITE, /* type-type (composite) */
1075 TYPCATEGORY_COMPOSITE, /* type-category (ditto) */
1076 false, /* composite types are never preferred */
1077 DEFAULT_TYPDELIM, /* default array delimiter */
1078 F_RECORD_IN, /* input procedure */
1079 F_RECORD_OUT, /* output procedure */
1080 F_RECORD_RECV, /* receive procedure */
1081 F_RECORD_SEND, /* send procedure */
1082 InvalidOid, /* typmodin procedure - none */
1083 InvalidOid, /* typmodout procedure - none */
1084 InvalidOid, /* analyze procedure - default */
1085 InvalidOid, /* subscript procedure - none */
1086 InvalidOid, /* array element type - irrelevant */
1087 false, /* this is not an array type */
1088 new_array_type, /* array type if any */
1089 InvalidOid, /* domain base type - irrelevant */
1090 NULL, /* default value - none */
1091 NULL, /* default binary representation */
1092 false, /* passed by reference */
1093 TYPALIGN_DOUBLE, /* alignment - must be the largest! */
1094 TYPSTORAGE_EXTENDED, /* fully TOASTable */
1095 -1, /* typmod */
1096 0, /* array dimensions for typBaseType */
1097 false, /* Type NOT NULL */
1098 InvalidOid); /* rowtypes never have a collation */
1099}
1100
1101/* --------------------------------
1102 * heap_create_with_catalog
1103 *
1104 * creates a new cataloged relation. see comments above.
1105 *
1106 * Arguments:
1107 * relname: name to give to new rel
1108 * relnamespace: OID of namespace it goes in
1109 * reltablespace: OID of tablespace it goes in
1110 * relid: OID to assign to new rel, or InvalidOid to select a new OID
1111 * reltypeid: OID to assign to rel's rowtype, or InvalidOid to select one
1112 * reloftypeid: if a typed table, OID of underlying type; else InvalidOid
1113 * ownerid: OID of new rel's owner
1114 * accessmtd: OID of new rel's access method
1115 * tupdesc: tuple descriptor (source of column definitions)
1116 * cooked_constraints: list of precooked check constraints and defaults
1117 * relkind: relkind for new rel
1118 * relpersistence: rel's persistence status (permanent, temp, or unlogged)
1119 * shared_relation: true if it's to be a shared relation
1120 * mapped_relation: true if the relation will use the relfilenumber map
1121 * oncommit: ON COMMIT marking (only relevant if it's a temp table)
1122 * reloptions: reloptions in Datum form, or (Datum) 0 if none
1123 * use_user_acl: true if should look for user-defined default permissions;
1124 * if false, relacl is always set NULL
1125 * allow_system_table_mods: true to allow creation in system namespaces
1126 * is_internal: is this a system-generated catalog?
1127 * relrewrite: link to original relation during a table rewrite
1128 *
1129 * Output parameters:
1130 * typaddress: if not null, gets the object address of the new pg_type entry
1131 * (this must be null if the relkind is one that doesn't get a pg_type entry)
1132 *
1133 * Returns the OID of the new relation
1134 * --------------------------------
1135 */
1136Oid
1138 Oid relnamespace,
1139 Oid reltablespace,
1140 Oid relid,
1141 Oid reltypeid,
1143 Oid ownerid,
1144 Oid accessmtd,
1145 TupleDesc tupdesc,
1147 char relkind,
1148 char relpersistence,
1149 bool shared_relation,
1150 bool mapped_relation,
1151 OnCommitAction oncommit,
1152 Datum reloptions,
1153 bool use_user_acl,
1155 bool is_internal,
1158{
1161 Acl *relacl;
1165
1166 /* By default set to InvalidOid unless overridden by binary-upgrade */
1167 RelFileNumber relfilenumber = InvalidRelFileNumber;
1168 TransactionId relfrozenxid;
1169 MultiXactId relminmxid;
1170
1172
1173 /*
1174 * sanity checks
1175 */
1177
1178 /*
1179 * Validate proposed tupdesc for the desired relkind. If
1180 * allow_system_table_mods is on, allow ANYARRAY to be used; this is a
1181 * hack to allow creating pg_statistic and cloning it during VACUUM FULL.
1182 */
1183 CheckAttributeNamesTypes(tupdesc, relkind,
1185
1186 /*
1187 * This would fail later on anyway, if the relation already exists. But
1188 * by catching it here we can emit a nicer error message.
1189 */
1190 existing_relid = get_relname_relid(relname, relnamespace);
1192 ereport(ERROR,
1194 errmsg("relation \"%s\" already exists", relname)));
1195
1196 /*
1197 * Since we are going to create a rowtype as well, also check for
1198 * collision with an existing type name. If there is one and it's an
1199 * autogenerated array, we can rename it out of the way; otherwise we can
1200 * at least give a good error message.
1201 */
1204 ObjectIdGetDatum(relnamespace));
1206 {
1207 if (!moveArrayTypeName(old_type_oid, relname, relnamespace))
1208 ereport(ERROR,
1210 errmsg("type \"%s\" already exists", relname),
1211 errhint("A relation has an associated type of the same name, "
1212 "so you must use a name that doesn't conflict "
1213 "with any existing type.")));
1214 }
1215
1216 /*
1217 * Shared relations must be in pg_global (last-ditch check)
1218 */
1219 if (shared_relation && reltablespace != GLOBALTABLESPACE_OID)
1220 elog(ERROR, "shared relations must be placed in pg_global tablespace");
1221
1222 /*
1223 * Allocate an OID for the relation, unless we were told what to use.
1224 *
1225 * The OID will be the relfilenumber as well, so make sure it doesn't
1226 * collide with either pg_class OIDs or existing physical files.
1227 */
1228 if (!OidIsValid(relid))
1229 {
1230 /* Use binary-upgrade override for pg_class.oid and relfilenumber */
1231 if (IsBinaryUpgrade)
1232 {
1233 /*
1234 * Indexes are not supported here; they use
1235 * binary_upgrade_next_index_pg_class_oid.
1236 */
1237 Assert(relkind != RELKIND_INDEX);
1239
1240 if (relkind == RELKIND_TOASTVALUE)
1241 {
1242 /* There might be no TOAST table, so we have to test for it. */
1244 {
1247
1249 ereport(ERROR,
1251 errmsg("toast relfilenumber value not set when in binary upgrade mode")));
1252
1255 }
1256 }
1257 else
1258 {
1260 ereport(ERROR,
1262 errmsg("pg_class heap OID value not set when in binary upgrade mode")));
1263
1266
1267 if (RELKIND_HAS_STORAGE(relkind))
1268 {
1270 ereport(ERROR,
1272 errmsg("relfilenumber value not set when in binary upgrade mode")));
1273
1276 }
1277 }
1278 }
1279
1280 if (!OidIsValid(relid))
1281 relid = GetNewRelFileNumber(reltablespace, pg_class_desc,
1282 relpersistence);
1283 }
1284
1285 /*
1286 * Other sessions' catalog scans can't find this until we commit. Hence,
1287 * it doesn't hurt to hold AccessExclusiveLock. Do it here so callers
1288 * can't accidentally vary in their lock mode or acquisition timing.
1289 */
1291
1292 /*
1293 * Determine the relation's initial permissions.
1294 */
1295 if (use_user_acl)
1296 {
1297 switch (relkind)
1298 {
1299 case RELKIND_RELATION:
1300 case RELKIND_VIEW:
1301 case RELKIND_MATVIEW:
1305 relnamespace);
1306 break;
1307 case RELKIND_SEQUENCE:
1309 relnamespace);
1310 break;
1311 default:
1312 relacl = NULL;
1313 break;
1314 }
1315 }
1316 else
1317 relacl = NULL;
1318
1319 /*
1320 * Create the relcache entry (mostly dummy at this point) and the physical
1321 * disk file. (If we fail further down, it's the smgr's responsibility to
1322 * remove the disk file again.)
1323 *
1324 * NB: Note that passing create_storage = true is correct even for binary
1325 * upgrade. The storage we create here will be replaced later, but we
1326 * need to have something on disk in the meanwhile.
1327 */
1329 relnamespace,
1330 reltablespace,
1331 relid,
1332 relfilenumber,
1333 accessmtd,
1334 tupdesc,
1335 relkind,
1336 relpersistence,
1340 &relfrozenxid,
1341 &relminmxid,
1342 true);
1343
1345
1346 new_rel_desc->rd_rel->relrewrite = relrewrite;
1347
1348 /*
1349 * Decide whether to create a pg_type entry for the relation's rowtype.
1350 * These types are made except where the use of a relation as such is an
1351 * implementation detail: toast tables, sequences, indexes, and property
1352 * graphs.
1353 */
1354 if (!(relkind == RELKIND_SEQUENCE ||
1355 relkind == RELKIND_TOASTVALUE ||
1356 relkind == RELKIND_INDEX ||
1357 relkind == RELKIND_PARTITIONED_INDEX ||
1358 relkind == RELKIND_PROPGRAPH))
1359 {
1362 char *relarrayname;
1363
1364 /*
1365 * We'll make an array over the composite type, too. For largely
1366 * historical reasons, the array type's OID is assigned first.
1367 */
1369
1370 /*
1371 * Make the pg_type entry for the composite type. The OID of the
1372 * composite type can be preselected by the caller, but if reltypeid
1373 * is InvalidOid, we'll generate a new OID for it.
1374 *
1375 * NOTE: we could get a unique-index failure here, in case someone
1376 * else is creating the same type name in parallel but hadn't
1377 * committed yet when we checked for a duplicate name above.
1378 */
1380 relnamespace,
1381 relid,
1382 relkind,
1383 ownerid,
1384 reltypeid,
1386 new_type_oid = new_type_addr.objectId;
1387 if (typaddress)
1389
1390 /* Now create the array type. */
1391 relarrayname = makeArrayTypeName(relname, relnamespace);
1392
1393 TypeCreate(new_array_oid, /* force the type's OID to this */
1394 relarrayname, /* Array type name */
1395 relnamespace, /* Same namespace as parent */
1396 InvalidOid, /* Not composite, no relationOid */
1397 0, /* relkind, also N/A here */
1398 ownerid, /* owner's ID */
1399 -1, /* Internal size (varlena) */
1400 TYPTYPE_BASE, /* Not composite - typelem is */
1401 TYPCATEGORY_ARRAY, /* type-category (array) */
1402 false, /* array types are never preferred */
1403 DEFAULT_TYPDELIM, /* default array delimiter */
1404 F_ARRAY_IN, /* array input proc */
1405 F_ARRAY_OUT, /* array output proc */
1406 F_ARRAY_RECV, /* array recv (bin) proc */
1407 F_ARRAY_SEND, /* array send (bin) proc */
1408 InvalidOid, /* typmodin procedure - none */
1409 InvalidOid, /* typmodout procedure - none */
1410 F_ARRAY_TYPANALYZE, /* array analyze procedure */
1411 F_ARRAY_SUBSCRIPT_HANDLER, /* array subscript procedure */
1412 new_type_oid, /* array element type - the rowtype */
1413 true, /* yes, this is an array type */
1414 InvalidOid, /* this has no array type */
1415 InvalidOid, /* domain base type - irrelevant */
1416 NULL, /* default value - none */
1417 NULL, /* default binary representation */
1418 false, /* passed by reference */
1419 TYPALIGN_DOUBLE, /* alignment - must be the largest! */
1420 TYPSTORAGE_EXTENDED, /* fully TOASTable */
1421 -1, /* typmod */
1422 0, /* array dimensions for typBaseType */
1423 false, /* Type NOT NULL */
1424 InvalidOid); /* rowtypes never have a collation */
1425
1427 }
1428 else
1429 {
1430 /* Caller should not be expecting a type to be created. */
1433
1435 }
1436
1437 /*
1438 * now create an entry in pg_class for the relation.
1439 *
1440 * NOTE: we could get a unique-index failure here, in case someone else is
1441 * creating the same relation name in parallel but hadn't committed yet
1442 * when we checked for a duplicate name above.
1443 */
1446 relid,
1449 ownerid,
1450 relkind,
1451 relfrozenxid,
1452 relminmxid,
1454 reloptions);
1455
1456 /*
1457 * now add tuples to pg_attribute for the attributes in our new relation.
1458 */
1459 AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind);
1460
1461 /*
1462 * Make a dependency link to force the relation to be deleted if its
1463 * namespace is. Also make a dependency link to its owner, as well as
1464 * dependencies for any roles mentioned in the default ACL.
1465 *
1466 * For composite types, these dependencies are tracked for the pg_type
1467 * entry, so we needn't record them here. Likewise, TOAST tables don't
1468 * need a namespace dependency (they live in a pinned namespace) nor an
1469 * owner dependency (they depend indirectly through the parent table), nor
1470 * should they have any ACL entries. The same applies for extension
1471 * dependencies.
1472 *
1473 * Also, skip this in bootstrap mode, since we don't make dependencies
1474 * while bootstrapping.
1475 */
1476 if (relkind != RELKIND_COMPOSITE_TYPE &&
1477 relkind != RELKIND_TOASTVALUE &&
1479 {
1481 referenced;
1482 ObjectAddresses *addrs;
1483
1485
1487
1489
1491
1492 addrs = new_object_addresses();
1493
1496
1497 if (reloftypeid)
1498 {
1501 }
1502
1503 /*
1504 * Make a dependency link to force the relation to be deleted if its
1505 * access method is.
1506 *
1507 * No need to add an explicit dependency for the toast table, as the
1508 * main table depends on it. Partitioned tables may not have an
1509 * access method set.
1510 */
1511 if ((RELKIND_HAS_TABLE_AM(relkind) && relkind != RELKIND_TOASTVALUE) ||
1513 {
1516 }
1517
1519 free_object_addresses(addrs);
1520 }
1521
1522 /* Post creation hook for new relation */
1523 InvokeObjectPostCreateHookArg(RelationRelationId, relid, 0, is_internal);
1524
1525 /*
1526 * Store any supplied CHECK constraints and defaults.
1527 *
1528 * NB: this may do a CommandCounterIncrement and rebuild the relcache
1529 * entry, so the relation must be valid and self-consistent at this point.
1530 * In particular, there are not yet constraints and defaults anywhere.
1531 */
1533
1534 /*
1535 * If there's a special on-commit action, remember it
1536 */
1537 if (oncommit != ONCOMMIT_NOOP)
1538 register_on_commit_action(relid, oncommit);
1539
1540 /*
1541 * ok, the relation has been cataloged, so close our relations and return
1542 * the OID of the newly created relation.
1543 */
1544 table_close(new_rel_desc, NoLock); /* do not unlock till end of xact */
1546
1547 return relid;
1548}
1549
1550/*
1551 * RelationRemoveInheritance
1552 *
1553 * Formerly, this routine checked for child relations and aborted the
1554 * deletion if any were found. Now we rely on the dependency mechanism
1555 * to check for or delete child relations. By the time we get here,
1556 * there are no children and we need only remove any pg_inherits rows
1557 * linking this relation to its parent(s).
1558 */
1559static void
1583
1584/*
1585 * DeleteRelationTuple
1586 *
1587 * Remove pg_class row for the given relid.
1588 *
1589 * Note: this is shared by relation deletion and index deletion. It's
1590 * not intended for use anyplace else.
1591 */
1592void
1594{
1596 HeapTuple tup;
1597
1598 /* Grab an appropriate lock on the pg_class relation */
1600
1602 if (!HeapTupleIsValid(tup))
1603 elog(ERROR, "cache lookup failed for relation %u", relid);
1604
1605 /* delete the relation tuple from pg_class, and finish up */
1607
1609
1611}
1612
1613/*
1614 * DeleteAttributeTuples
1615 *
1616 * Remove pg_attribute rows for the given relid.
1617 *
1618 * Note: this is shared by relation deletion and index deletion. It's
1619 * not intended for use anyplace else.
1620 */
1621void
1623{
1625 SysScanDesc scan;
1626 ScanKeyData key[1];
1628
1629 /* Grab an appropriate lock on the pg_attribute relation */
1631
1632 /* Use the index to scan only attributes of the target relation */
1633 ScanKeyInit(&key[0],
1636 ObjectIdGetDatum(relid));
1637
1639 NULL, 1, key);
1640
1641 /* Delete all the matching tuples */
1642 while ((atttup = systable_getnext(scan)) != NULL)
1643 CatalogTupleDelete(attrel, &atttup->t_self);
1644
1645 /* Clean up after the scan */
1646 systable_endscan(scan);
1648}
1649
1650/*
1651 * DeleteSystemAttributeTuples
1652 *
1653 * Remove pg_attribute rows for system columns of the given relid.
1654 *
1655 * Note: this is only used when converting a table to a view. Views don't
1656 * have system columns, so we should remove them from pg_attribute.
1657 */
1658void
1660{
1662 SysScanDesc scan;
1663 ScanKeyData key[2];
1665
1666 /* Grab an appropriate lock on the pg_attribute relation */
1668
1669 /* Use the index to scan only system attributes of the target relation */
1670 ScanKeyInit(&key[0],
1673 ObjectIdGetDatum(relid));
1674 ScanKeyInit(&key[1],
1677 Int16GetDatum(0));
1678
1680 NULL, 2, key);
1681
1682 /* Delete all the matching tuples */
1683 while ((atttup = systable_getnext(scan)) != NULL)
1684 CatalogTupleDelete(attrel, &atttup->t_self);
1685
1686 /* Clean up after the scan */
1687 systable_endscan(scan);
1689}
1690
1691/*
1692 * RemoveAttributeById
1693 *
1694 * This is the guts of ALTER TABLE DROP COLUMN: actually mark the attribute
1695 * deleted in pg_attribute. We also remove pg_statistic entries for it.
1696 * (Everything else needed, such as getting rid of any pg_attrdef entry,
1697 * is handled by dependency.c.)
1698 */
1699void
1701{
1702 Relation rel;
1704 HeapTuple tuple;
1706 char newattname[NAMEDATALEN];
1708 bool nullsAtt[Natts_pg_attribute] = {0};
1709 bool replacesAtt[Natts_pg_attribute] = {0};
1710
1711 /*
1712 * Grab an exclusive lock on the target table, which we will NOT release
1713 * until end of transaction. (In the simple case where we are directly
1714 * dropping this column, ATExecDropColumn already did this ... but when
1715 * cascading from a drop of some other object, we may not have any lock.)
1716 */
1717 rel = relation_open(relid, AccessExclusiveLock);
1718
1720
1722 ObjectIdGetDatum(relid),
1724 if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
1725 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1726 attnum, relid);
1728
1729 /* Mark the attribute as dropped */
1730 attStruct->attisdropped = true;
1731
1732 /*
1733 * Set the type OID to invalid. A dropped attribute's type link cannot be
1734 * relied on (once the attribute is dropped, the type might be too).
1735 * Fortunately we do not need the type row --- the only really essential
1736 * information is the type's typlen and typalign, which are preserved in
1737 * the attribute's attlen and attalign. We set atttypid to zero here as a
1738 * means of catching code that incorrectly expects it to be valid.
1739 */
1740 attStruct->atttypid = InvalidOid;
1741
1742 /* Remove any not-null constraint the column may have */
1743 attStruct->attnotnull = false;
1744
1745 /* Unset this so no one tries to look up the generation expression */
1746 attStruct->attgenerated = '\0';
1747
1748 /*
1749 * Change the column name to something that isn't likely to conflict
1750 */
1752 "........pg.dropped.%d........", attnum);
1753 namestrcpy(&(attStruct->attname), newattname);
1754
1755 /* Clear the missing value */
1756 attStruct->atthasmissing = false;
1759
1760 /*
1761 * Clear the other nullable fields. This saves some space in pg_attribute
1762 * and removes no longer useful information.
1763 */
1772
1775
1776 CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
1777
1778 /*
1779 * Because updating the pg_attribute row will trigger a relcache flush for
1780 * the target relation, we need not do anything else to notify other
1781 * backends of the change.
1782 */
1783
1785
1786 RemoveStatistics(relid, attnum);
1787
1788 relation_close(rel, NoLock);
1789}
1790
1791/*
1792 * heap_drop_with_catalog - removes specified relation from catalogs
1793 *
1794 * Note that this routine is not responsible for dropping objects that are
1795 * linked to the pg_class entry via dependencies (for example, indexes and
1796 * constraints). Those are deleted by the dependency-tracing logic in
1797 * dependency.c before control gets here. In general, therefore, this routine
1798 * should never be called directly; go through performDeletion() instead.
1799 */
1800void
1802{
1803 Relation rel;
1804 HeapTuple tuple;
1807
1808 /*
1809 * To drop a partition safely, we must grab exclusive lock on its parent,
1810 * because another backend might be about to execute a query on the parent
1811 * table. If it relies on previously cached partition descriptor, then it
1812 * could attempt to access the just-dropped relation as its partition. We
1813 * must therefore take a table lock strong enough to prevent all queries
1814 * on the table from proceeding until we commit and send out a
1815 * shared-cache-inval notice that will make them update their partition
1816 * descriptors.
1817 */
1818 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1819 if (!HeapTupleIsValid(tuple))
1820 elog(ERROR, "cache lookup failed for relation %u", relid);
1821 if (((Form_pg_class) GETSTRUCT(tuple))->relispartition)
1822 {
1823 /*
1824 * We have to lock the parent if the partition is being detached,
1825 * because it's possible that some query still has a partition
1826 * descriptor that includes this partition.
1827 */
1828 parentOid = get_partition_parent(relid, true);
1830
1831 /*
1832 * If this is not the default partition, dropping it will change the
1833 * default partition's partition constraint, so we must lock it.
1834 */
1836 if (OidIsValid(defaultPartOid) && relid != defaultPartOid)
1838 }
1839
1840 ReleaseSysCache(tuple);
1841
1842 /*
1843 * Open and lock the relation.
1844 */
1845 rel = relation_open(relid, AccessExclusiveLock);
1846
1847 /*
1848 * There can no longer be anyone *else* touching the relation, but we
1849 * might still have open queries or cursors, or pending trigger events, in
1850 * our own session.
1851 */
1852 CheckTableNotInUse(rel, "DROP TABLE");
1853
1854 /*
1855 * This effectively deletes all rows in the table, and may be done in a
1856 * serializable transaction. In that case we must record a rw-conflict in
1857 * to this transaction from each transaction holding a predicate lock on
1858 * the table.
1859 */
1861
1862 /*
1863 * Delete pg_foreign_table tuple first.
1864 */
1865 if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1866 {
1869
1871
1874 elog(ERROR, "cache lookup failed for foreign table %u", relid);
1875
1876 CatalogTupleDelete(ftrel, &fttuple->t_self);
1877
1880 }
1881
1882 /*
1883 * If a partitioned table, delete the pg_partitioned_table tuple.
1884 */
1885 if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1887
1888 /*
1889 * If the relation being dropped is the default partition itself,
1890 * invalidate its entry in pg_partitioned_table.
1891 */
1892 if (relid == defaultPartOid)
1894
1895 /*
1896 * Schedule unlinking of the relation's physical files at commit.
1897 */
1898 if (RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
1900
1901 /* ensure that stats are dropped if transaction commits */
1903
1904 /*
1905 * Close relcache entry, but *keep* AccessExclusiveLock on the relation
1906 * until transaction commit. This ensures no one else will try to do
1907 * something with the doomed relation.
1908 */
1909 relation_close(rel, NoLock);
1910
1911 /*
1912 * Remove any associated relation synchronization states.
1913 */
1915
1916 /*
1917 * Forget any ON COMMIT action for the rel
1918 */
1920
1921 /*
1922 * Flush the relation from the relcache. We want to do this before
1923 * starting to remove catalog entries, just to be certain that no relcache
1924 * entry rebuild will happen partway through. (That should not really
1925 * matter, since we don't do CommandCounterIncrement here, but let's be
1926 * safe.)
1927 */
1929
1930 /*
1931 * remove inheritance information
1932 */
1934
1935 /*
1936 * delete statistics
1937 */
1938 RemoveStatistics(relid, 0);
1939
1940 /*
1941 * delete attribute tuples
1942 */
1943 DeleteAttributeTuples(relid);
1944
1945 /*
1946 * delete relation tuple
1947 */
1948 DeleteRelationTuple(relid);
1949
1950 if (OidIsValid(parentOid))
1951 {
1952 /*
1953 * If this is not the default partition, the partition constraint of
1954 * the default partition has changed to include the portion of the key
1955 * space previously covered by the dropped partition.
1956 */
1957 if (OidIsValid(defaultPartOid) && relid != defaultPartOid)
1959
1960 /*
1961 * Invalidate the parent's relcache so that the partition is no longer
1962 * included in its partition descriptor.
1963 */
1965 /* keep the lock */
1966 }
1967}
1968
1969
1970/*
1971 * RelationClearMissing
1972 *
1973 * Set atthasmissing and attmissingval to false/null for all attributes
1974 * where they are currently set. This can be safely and usefully done if
1975 * the table is rewritten (e.g. by VACUUM FULL or CLUSTER) where we know there
1976 * are no rows left with less than a full complement of attributes.
1977 *
1978 * The caller must have an AccessExclusive lock on the relation.
1979 */
1980void
1982{
1984 Oid relid = RelationGetRelid(rel);
1985 int natts = RelationGetNumberOfAttributes(rel);
1986 int attnum;
1991 HeapTuple tuple,
1992 newtuple;
1993
1994 memset(repl_val, 0, sizeof(repl_val));
1995 memset(repl_null, false, sizeof(repl_null));
1996 memset(repl_repl, false, sizeof(repl_repl));
1997
2000
2003
2004
2005 /* Get a lock on pg_attribute */
2007
2008 /* process each non-system attribute, including any dropped columns */
2009 for (attnum = 1; attnum <= natts; attnum++)
2010 {
2011 tuple = SearchSysCache2(ATTNUM,
2012 ObjectIdGetDatum(relid),
2014 if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
2015 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
2016 attnum, relid);
2017
2019
2020 /* ignore any where atthasmissing is not true */
2021 if (attrtuple->atthasmissing)
2022 {
2023 newtuple = heap_modify_tuple(tuple, RelationGetDescr(attr_rel),
2025
2026 CatalogTupleUpdate(attr_rel, &newtuple->t_self, newtuple);
2027
2028 heap_freetuple(newtuple);
2029 }
2030
2031 ReleaseSysCache(tuple);
2032 }
2033
2034 /*
2035 * Our update of the pg_attribute rows will force a relcache rebuild, so
2036 * there's nothing else to do here.
2037 */
2039}
2040
2041/*
2042 * StoreAttrMissingVal
2043 *
2044 * Set the missing value of a single attribute.
2045 */
2046void
2048{
2050 bool nullsAtt[Natts_pg_attribute] = {0};
2051 bool replacesAtt[Natts_pg_attribute] = {0};
2055 newtup;
2056
2057 /* This is only supported for plain tables */
2058 Assert(rel->rd_rel->relkind == RELKIND_RELATION);
2059
2060 /* Fetch the pg_attribute row */
2062
2066 if (!HeapTupleIsValid(atttup)) /* shouldn't happen */
2067 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
2068 attnum, RelationGetRelid(rel));
2070
2071 /* Make a one-element array containing the value */
2073 1,
2074 attStruct->atttypid,
2075 attStruct->attlen,
2076 attStruct->attbyval,
2077 attStruct->attalign));
2078
2079 /* Update the pg_attribute row */
2082
2085
2089
2090 /* clean up */
2093}
2094
2095/*
2096 * SetAttrMissing
2097 *
2098 * Set the missing value of a single attribute. This should only be used by
2099 * binary upgrade. Takes an AccessExclusive lock on the relation owning the
2100 * attribute.
2101 */
2102void
2103SetAttrMissing(Oid relid, char *attname, char *value)
2104{
2106 bool nullsAtt[Natts_pg_attribute] = {0};
2107 bool replacesAtt[Natts_pg_attribute] = {0};
2111 tablerel;
2113 newtup;
2114
2115 /* lock the table the attribute belongs to */
2117
2118 /* Don't do anything unless it's a plain table */
2119 if (tablerel->rd_rel->relkind != RELKIND_RELATION)
2120 {
2122 return;
2123 }
2124
2125 /* Lock the attribute row and get the data */
2129 elog(ERROR, "cache lookup failed for attribute %s of relation %u",
2130 attname, relid);
2132
2133 /* get an array value from the value string */
2136 ObjectIdGetDatum(attStruct->atttypid),
2137 Int32GetDatum(attStruct->atttypmod));
2138
2139 /* update the tuple - set atthasmissing and attmissingval */
2144
2148
2149 /* clean up */
2153}
2154
2155/*
2156 * Store a check-constraint expression for the given relation.
2157 *
2158 * Caller is responsible for updating the count of constraints
2159 * in the pg_class entry for the relation.
2160 *
2161 * The OID of the new constraint is returned.
2162 */
2163static Oid
2164StoreRelCheck(Relation rel, const char *ccname, Node *expr,
2165 bool is_enforced, bool is_validated, bool is_local,
2166 int16 inhcount, bool is_no_inherit, bool is_internal)
2167{
2168 char *ccbin;
2169 List *varList;
2170 int keycount;
2171 int16 *attNos;
2172 Oid constrOid;
2173
2174 /*
2175 * Flatten expression to string form for storage.
2176 */
2177 ccbin = nodeToString(expr);
2178
2179 /*
2180 * Find columns of rel that are used in expr
2181 *
2182 * NB: pull_var_clause is okay here only because we don't allow subselects
2183 * in check constraints; it would fail to examine the contents of
2184 * subselects.
2185 */
2186 varList = pull_var_clause(expr, 0);
2188
2189 if (keycount > 0)
2190 {
2191 ListCell *vl;
2192 int i = 0;
2193
2194 attNos = (int16 *) palloc(keycount * sizeof(int16));
2195 foreach(vl, varList)
2196 {
2197 Var *var = (Var *) lfirst(vl);
2198 int j;
2199
2200 for (j = 0; j < i; j++)
2201 if (attNos[j] == var->varattno)
2202 break;
2203 if (j == i)
2204 attNos[i++] = var->varattno;
2205 }
2206 keycount = i;
2207 }
2208 else
2209 attNos = NULL;
2210
2211 /*
2212 * Partitioned tables do not contain any rows themselves, so a NO INHERIT
2213 * constraint makes no sense.
2214 */
2215 if (is_no_inherit &&
2216 rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2217 ereport(ERROR,
2219 errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
2221
2222 /*
2223 * Create the Check Constraint
2224 */
2225 constrOid =
2226 CreateConstraintEntry(ccname, /* Constraint Name */
2227 RelationGetNamespace(rel), /* namespace */
2228 CONSTRAINT_CHECK, /* Constraint Type */
2229 false, /* Is Deferrable */
2230 false, /* Is Deferred */
2231 is_enforced, /* Is Enforced */
2233 InvalidOid, /* no parent constraint */
2234 RelationGetRelid(rel), /* relation */
2235 attNos, /* attrs in the constraint */
2236 keycount, /* # key attrs in the constraint */
2237 keycount, /* # total attrs in the constraint */
2238 InvalidOid, /* not a domain constraint */
2239 InvalidOid, /* no associated index */
2240 InvalidOid, /* Foreign key fields */
2241 NULL,
2242 NULL,
2243 NULL,
2244 NULL,
2245 0,
2246 ' ',
2247 ' ',
2248 NULL,
2249 0,
2250 ' ',
2251 NULL, /* not an exclusion constraint */
2252 expr, /* Tree form of check constraint */
2253 ccbin, /* Binary form of check constraint */
2254 is_local, /* conislocal */
2255 inhcount, /* coninhcount */
2256 is_no_inherit, /* connoinherit */
2257 false, /* conperiod */
2258 is_internal); /* internally constructed? */
2259
2260 pfree(ccbin);
2261
2262 return constrOid;
2263}
2264
2265/*
2266 * Store a not-null constraint for the given relation
2267 *
2268 * The OID of the new constraint is returned.
2269 */
2270static Oid
2272 bool is_validated, bool is_local, int inhcount,
2273 bool is_no_inherit)
2274{
2275 Oid constrOid;
2276
2278
2279 constrOid =
2283 false,
2284 false,
2285 true, /* Is Enforced */
2287 InvalidOid,
2288 RelationGetRelid(rel),
2289 &attnum,
2290 1,
2291 1,
2292 InvalidOid, /* not a domain constraint */
2293 InvalidOid, /* no associated index */
2294 InvalidOid, /* Foreign key fields */
2295 NULL,
2296 NULL,
2297 NULL,
2298 NULL,
2299 0,
2300 ' ',
2301 ' ',
2302 NULL,
2303 0,
2304 ' ',
2305 NULL, /* not an exclusion constraint */
2306 NULL,
2307 NULL,
2308 is_local,
2309 inhcount,
2310 is_no_inherit,
2311 false,
2312 false);
2313 return constrOid;
2314}
2315
2316/*
2317 * Store defaults and CHECK constraints (passed as a list of CookedConstraint).
2318 *
2319 * Each CookedConstraint struct is modified to store the new catalog tuple OID.
2320 *
2321 * NOTE: only pre-cooked expressions will be passed this way, which is to
2322 * say expressions inherited from an existing relation. Newly parsed
2323 * expressions can be added later, by direct calls to StoreAttrDefault
2324 * and StoreRelCheck (see AddRelationNewConstraints()).
2325 */
2326static void
2328{
2329 int numchecks = 0;
2330 ListCell *lc;
2331
2332 if (cooked_constraints == NIL)
2333 return; /* nothing to do */
2334
2335 /*
2336 * Deparsing of constraint expressions will fail unless the just-created
2337 * pg_attribute tuples for this relation are made visible. So, bump the
2338 * command counter. CAUTION: this will cause a relcache entry rebuild.
2339 */
2341
2342 foreach(lc, cooked_constraints)
2343 {
2345
2346 switch (con->contype)
2347 {
2348 case CONSTR_DEFAULT:
2349 con->conoid = StoreAttrDefault(rel, con->attnum, con->expr,
2350 is_internal);
2351 break;
2352 case CONSTR_CHECK:
2353 con->conoid =
2354 StoreRelCheck(rel, con->name, con->expr,
2355 con->is_enforced, !con->skip_validation,
2356 con->is_local, con->inhcount,
2357 con->is_no_inherit, is_internal);
2358 numchecks++;
2359 break;
2360
2361 default:
2362 elog(ERROR, "unrecognized constraint type: %d",
2363 (int) con->contype);
2364 }
2365 }
2366
2367 if (numchecks > 0)
2369}
2370
2371/*
2372 * AddRelationNewConstraints
2373 *
2374 * Add new column default expressions and/or constraint check expressions
2375 * to an existing relation. This is defined to do both for efficiency in
2376 * DefineRelation, but of course you can do just one or the other by passing
2377 * empty lists.
2378 *
2379 * rel: relation to be modified
2380 * newColDefaults: list of RawColumnDefault structures
2381 * newConstraints: list of Constraint nodes
2382 * allow_merge: true if check constraints may be merged with existing ones
2383 * is_local: true if definition is local, false if it's inherited
2384 * is_internal: true if result of some internal process, not a user request
2385 * queryString: used during expression transformation of default values and
2386 * cooked CHECK constraints
2387 *
2388 * All entries in newColDefaults will be processed. Entries in newConstraints
2389 * will be processed only if they are CONSTR_CHECK or CONSTR_NOTNULL types.
2390 *
2391 * Returns a list of CookedConstraint nodes that shows the cooked form of
2392 * the default and constraint expressions added to the relation.
2393 *
2394 * NB: caller should have opened rel with some self-conflicting lock mode,
2395 * and should hold that lock till end of transaction; for normal cases that'll
2396 * be AccessExclusiveLock, but if caller knows that the constraint is already
2397 * enforced by some other means, it can be ShareUpdateExclusiveLock. Also, we
2398 * assume the caller has done a CommandCounterIncrement if necessary to make
2399 * the relation's catalog tuples visible.
2400 */
2401List *
2405 bool allow_merge,
2406 bool is_local,
2407 bool is_internal,
2408 const char *queryString)
2409{
2413 int numoldchecks;
2414 ParseState *pstate;
2416 int numchecks;
2418 List *nnnames;
2419 Node *expr;
2421
2422 /*
2423 * Get info about existing constraints.
2424 */
2426 oldconstr = tupleDesc->constr;
2427 if (oldconstr)
2428 numoldchecks = oldconstr->num_check;
2429 else
2430 numoldchecks = 0;
2431
2432 /*
2433 * Create a dummy ParseState and insert the target relation as its sole
2434 * rangetable entry. We need a ParseState for transformExpr.
2435 */
2436 pstate = make_parsestate(NULL);
2437 pstate->p_sourcetext = queryString;
2439 rel,
2441 NULL,
2442 false,
2443 true);
2444 addNSItemToQuery(pstate, nsitem, true, true, true);
2445
2446 /*
2447 * Process column default expressions.
2448 */
2450 {
2451 Form_pg_attribute atp = TupleDescAttr(rel->rd_att, colDef->attnum - 1);
2452 Oid defOid;
2453
2454 expr = cookDefault(pstate, colDef->raw_default,
2455 atp->atttypid, atp->atttypmod,
2456 NameStr(atp->attname),
2457 atp->attgenerated);
2458
2459 /*
2460 * If the expression is just a NULL constant, we do not bother to make
2461 * an explicit pg_attrdef entry, since the default behavior is
2462 * equivalent. This applies to column defaults, but not for
2463 * generation expressions.
2464 *
2465 * Note a nonobvious property of this test: if the column is of a
2466 * domain type, what we'll get is not a bare null Const but a
2467 * CoerceToDomain expr, so we will not discard the default. This is
2468 * critical because the column default needs to be retained to
2469 * override any default that the domain might have.
2470 */
2471 if (expr == NULL ||
2472 (!colDef->generated &&
2473 IsA(expr, Const) &&
2474 castNode(Const, expr)->constisnull))
2475 continue;
2476
2477 defOid = StoreAttrDefault(rel, colDef->attnum, expr, is_internal);
2478
2480 cooked->contype = CONSTR_DEFAULT;
2481 cooked->conoid = defOid;
2482 cooked->name = NULL;
2483 cooked->attnum = colDef->attnum;
2484 cooked->expr = expr;
2485 cooked->is_enforced = true;
2486 cooked->skip_validation = false;
2487 cooked->is_local = is_local;
2488 cooked->inhcount = is_local ? 0 : 1;
2489 cooked->is_no_inherit = false;
2491 }
2492
2493 /*
2494 * Process constraint expressions.
2495 */
2497 checknames = NIL;
2498 nnnames = NIL;
2500 {
2501 Oid constrOid;
2502
2503 if (cdef->contype == CONSTR_CHECK)
2504 {
2505 char *ccname;
2506
2507 if (cdef->raw_expr != NULL)
2508 {
2509 Assert(cdef->cooked_expr == NULL);
2510
2511 /*
2512 * Transform raw parsetree to executable expression, and
2513 * verify it's valid as a CHECK constraint.
2514 */
2515 expr = cookConstraint(pstate, cdef->raw_expr,
2517 }
2518 else
2519 {
2520 Assert(cdef->cooked_expr != NULL);
2521
2522 /*
2523 * Here, we assume the parser will only pass us valid CHECK
2524 * expressions, so we do no particular checking.
2525 */
2526 expr = stringToNode(cdef->cooked_expr);
2527 }
2528
2529 /*
2530 * Check name uniqueness, or generate a name if none was given.
2531 */
2532 if (cdef->conname != NULL)
2533 {
2534 ccname = cdef->conname;
2535 /* Check against other new constraints */
2536 /* Needed because we don't do CommandCounterIncrement in loop */
2538 {
2539 if (strcmp(chkname, ccname) == 0)
2540 ereport(ERROR,
2542 errmsg("check constraint \"%s\" already exists",
2543 ccname)));
2544 }
2545
2546 /* save name for future checks */
2547 checknames = lappend(checknames, ccname);
2548
2549 /*
2550 * Check against pre-existing constraints. If we are allowed
2551 * to merge with an existing constraint, there's no more to do
2552 * here. (We omit the duplicate constraint from the result,
2553 * which is what ATAddCheckNNConstraint wants.)
2554 */
2555 if (MergeWithExistingConstraint(rel, ccname, expr,
2556 allow_merge, is_local,
2557 cdef->is_enforced,
2558 cdef->initially_valid,
2559 cdef->is_no_inherit))
2560 continue;
2561 }
2562 else
2563 {
2564 /*
2565 * When generating a name, we want to create "tab_col_check"
2566 * for a column constraint and "tab_check" for a table
2567 * constraint. We no longer have any info about the syntactic
2568 * positioning of the constraint phrase, so we approximate
2569 * this by seeing whether the expression references more than
2570 * one column. (If the user played by the rules, the result
2571 * is the same...)
2572 *
2573 * Note: pull_var_clause() doesn't descend into sublinks, but
2574 * we eliminated those above; and anyway this only needs to be
2575 * an approximate answer.
2576 */
2577 List *vars;
2578 char *colname;
2579
2580 vars = pull_var_clause(expr, 0);
2581
2582 /* eliminate duplicates */
2583 vars = list_union(NIL, vars);
2584
2585 if (list_length(vars) == 1)
2586 colname = get_attname(RelationGetRelid(rel),
2587 ((Var *) linitial(vars))->varattno,
2588 true);
2589 else
2590 colname = NULL;
2591
2593 colname,
2594 "check",
2596 checknames);
2597
2598 /* save name for future checks */
2599 checknames = lappend(checknames, ccname);
2600 }
2601
2602 /*
2603 * OK, store it.
2604 */
2605 constrOid =
2606 StoreRelCheck(rel, ccname, expr, cdef->is_enforced,
2607 cdef->initially_valid, is_local,
2608 is_local ? 0 : 1, cdef->is_no_inherit,
2609 is_internal);
2610
2611 numchecks++;
2612
2614 cooked->contype = CONSTR_CHECK;
2615 cooked->conoid = constrOid;
2616 cooked->name = ccname;
2617 cooked->attnum = 0;
2618 cooked->expr = expr;
2619 cooked->is_enforced = cdef->is_enforced;
2620 cooked->skip_validation = cdef->skip_validation;
2621 cooked->is_local = is_local;
2622 cooked->inhcount = is_local ? 0 : 1;
2623 cooked->is_no_inherit = cdef->is_no_inherit;
2625 }
2626 else if (cdef->contype == CONSTR_NOTNULL)
2627 {
2629 AttrNumber colnum;
2630 int16 inhcount = is_local ? 0 : 1;
2631 char *nnname;
2632
2633 /* Determine which column to modify */
2634 colnum = get_attnum(RelationGetRelid(rel), strVal(linitial(cdef->keys)));
2635 if (colnum == InvalidAttrNumber)
2636 ereport(ERROR,
2638 errmsg("column \"%s\" of relation \"%s\" does not exist",
2640 if (colnum < InvalidAttrNumber)
2641 ereport(ERROR,
2643 errmsg("cannot add not-null constraint on system column \"%s\"",
2644 strVal(linitial(cdef->keys))));
2645
2646 Assert(cdef->initially_valid != cdef->skip_validation);
2647
2648 /*
2649 * If the column already has a not-null constraint, we don't want
2650 * to add another one; adjust inheritance status as needed. This
2651 * also checks whether the existing constraint matches the
2652 * requested validity.
2653 */
2655 cdef->conname,
2656 is_local, cdef->is_no_inherit,
2657 cdef->skip_validation))
2658 continue;
2659
2660 /*
2661 * If a constraint name is specified, check that it isn't already
2662 * used. Otherwise, choose a non-conflicting one ourselves.
2663 */
2664 if (cdef->conname)
2665 {
2667 RelationGetRelid(rel),
2668 cdef->conname))
2669 ereport(ERROR,
2671 errmsg("constraint \"%s\" for relation \"%s\" already exists",
2672 cdef->conname, RelationGetRelationName(rel)));
2673 nnname = cdef->conname;
2674 }
2675 else
2677 strVal(linitial(cdef->keys)),
2678 "not_null",
2680 nnnames);
2682
2683 constrOid =
2684 StoreRelNotNull(rel, nnname, colnum,
2685 cdef->initially_valid,
2686 is_local,
2687 inhcount,
2688 cdef->is_no_inherit);
2689
2691 nncooked->contype = CONSTR_NOTNULL;
2692 nncooked->conoid = constrOid;
2693 nncooked->name = nnname;
2694 nncooked->attnum = colnum;
2695 nncooked->expr = NULL;
2696 nncooked->is_enforced = true;
2697 nncooked->skip_validation = cdef->skip_validation;
2698 nncooked->is_local = is_local;
2699 nncooked->inhcount = inhcount;
2700 nncooked->is_no_inherit = cdef->is_no_inherit;
2701
2703 }
2704 }
2705
2706 /*
2707 * Update the count of constraints in the relation's pg_class tuple. We do
2708 * this even if there was no change, in order to ensure that an SI update
2709 * message is sent out for the pg_class tuple, which will force other
2710 * backends to rebuild their relcache entries for the rel. (This is
2711 * critical if we added defaults but not constraints.)
2712 */
2714
2715 return cookedConstraints;
2716}
2717
2718/*
2719 * Check for a pre-existing check constraint that conflicts with a proposed
2720 * new one, and either adjust its conislocal/coninhcount settings or throw
2721 * error as needed.
2722 *
2723 * Returns true if merged (constraint is a duplicate), or false if it's
2724 * got a so-far-unique name, or throws error if conflict.
2725 *
2726 * XXX See MergeConstraintsIntoExisting too if you change this code.
2727 */
2728static bool
2729MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr,
2730 bool allow_merge, bool is_local,
2731 bool is_enforced,
2732 bool is_initially_valid,
2733 bool is_no_inherit)
2734{
2735 bool found;
2738 ScanKeyData skey[3];
2739 HeapTuple tup;
2740
2741 /* Search for a pg_constraint entry with same name and relation */
2743
2744 found = false;
2745
2746 ScanKeyInit(&skey[0],
2750 ScanKeyInit(&skey[1],
2754 ScanKeyInit(&skey[2],
2757 CStringGetDatum(ccname));
2758
2760 NULL, 3, skey);
2761
2762 /* There can be at most one matching row */
2764 {
2766
2767 /* Found it. Conflicts if not identical check constraint */
2768 if (con->contype == CONSTRAINT_CHECK)
2769 {
2770 Datum val;
2771 bool isnull;
2772
2775 conDesc->rd_att, &isnull);
2776 if (isnull)
2777 elog(ERROR, "null conbin for rel %s",
2780 found = true;
2781 }
2782
2783 /*
2784 * If the existing constraint is purely inherited (no local
2785 * definition) then interpret addition of a local constraint as a
2786 * legal merge. This allows ALTER ADD CONSTRAINT on parent and child
2787 * tables to be given in either order with same end state. However if
2788 * the relation is a partition, all inherited constraints are always
2789 * non-local, including those that were merged.
2790 */
2791 if (is_local && !con->conislocal && !rel->rd_rel->relispartition)
2792 allow_merge = true;
2793
2794 if (!found || !allow_merge)
2795 ereport(ERROR,
2797 errmsg("constraint \"%s\" for relation \"%s\" already exists",
2798 ccname, RelationGetRelationName(rel))));
2799
2800 /* If the child constraint is "no inherit" then cannot merge */
2801 if (con->connoinherit)
2802 ereport(ERROR,
2804 errmsg("constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"",
2805 ccname, RelationGetRelationName(rel))));
2806
2807 /*
2808 * Must not change an existing inherited constraint to "no inherit"
2809 * status. That's because inherited constraints should be able to
2810 * propagate to lower-level children.
2811 */
2812 if (con->coninhcount > 0 && is_no_inherit)
2813 ereport(ERROR,
2815 errmsg("constraint \"%s\" conflicts with inherited constraint on relation \"%s\"",
2816 ccname, RelationGetRelationName(rel))));
2817
2818 /*
2819 * If the child constraint is "not valid" then cannot merge with a
2820 * valid parent constraint.
2821 */
2822 if (is_initially_valid && con->conenforced && !con->convalidated)
2823 ereport(ERROR,
2825 errmsg("constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"",
2826 ccname, RelationGetRelationName(rel))));
2827
2828 /*
2829 * A non-enforced child constraint cannot be merged with an enforced
2830 * parent constraint. However, the reverse is allowed, where the child
2831 * constraint is enforced.
2832 */
2833 if ((!is_local && is_enforced && !con->conenforced) ||
2834 (is_local && !is_enforced && con->conenforced))
2835 ereport(ERROR,
2837 errmsg("constraint \"%s\" conflicts with NOT ENFORCED constraint on relation \"%s\"",
2838 ccname, RelationGetRelationName(rel))));
2839
2840 /* OK to update the tuple */
2842 (errmsg("merging constraint \"%s\" with inherited definition",
2843 ccname)));
2844
2847
2848 /*
2849 * In case of partitions, an inherited constraint must be inherited
2850 * only once since it cannot have multiple parents and it is never
2851 * considered local.
2852 */
2853 if (rel->rd_rel->relispartition)
2854 {
2855 con->coninhcount = 1;
2856 con->conislocal = false;
2857 }
2858 else
2859 {
2860 if (is_local)
2861 con->conislocal = true;
2862 else if (pg_add_s16_overflow(con->coninhcount, 1,
2863 &con->coninhcount))
2864 ereport(ERROR,
2866 errmsg("too many inheritance parents"));
2867 }
2868
2869 if (is_no_inherit)
2870 {
2871 Assert(is_local);
2872 con->connoinherit = true;
2873 }
2874
2875 /*
2876 * If the child constraint is required to be enforced while the parent
2877 * constraint is not, this should be allowed by marking the child
2878 * constraint as enforced. In the reverse case, an error would have
2879 * already been thrown before reaching this point.
2880 */
2881 if (is_enforced && !con->conenforced)
2882 {
2883 Assert(is_local);
2884 con->conenforced = true;
2885 con->convalidated = true;
2886 }
2887
2888 CatalogTupleUpdate(conDesc, &tup->t_self, tup);
2889 }
2890
2893
2894 return found;
2895}
2896
2897/*
2898 * Create the not-null constraints when creating a new relation
2899 *
2900 * These come from two sources: the 'constraints' list (of Constraint) is
2901 * specified directly by the user; the 'old_notnulls' list (of
2902 * CookedConstraint) comes from inheritance. We create one constraint
2903 * for each column, giving priority to user-specified ones, and setting
2904 * inhcount according to how many parents cause each column to get a
2905 * not-null constraint. If a user-specified name clashes with another
2906 * user-specified name, an error is raised. 'existing_constraints'
2907 * is a list of already defined constraint names, which should be avoided
2908 * when generating further ones.
2909 *
2910 * Returns a list of AttrNumber for columns that need to have the attnotnull
2911 * flag set.
2912 */
2913List *
2916{
2918 List *nnnames;
2919 List *nncols = NIL;
2920
2921 /*
2922 * We track two lists of names: nnnames keeps all the constraint names,
2923 * givennames tracks user-generated names. The distinction is important,
2924 * because we must raise error for user-generated name conflicts, but for
2925 * system-generated name conflicts we just generate another.
2926 */
2927 nnnames = list_copy(existing_constraints); /* don't scribble on input */
2928 givennames = NIL;
2929
2930 /*
2931 * First, create all not-null constraints that are directly specified by
2932 * the user. Note that inheritance might have given us another source for
2933 * each, so we must scan the old_notnulls list and increment inhcount for
2934 * each element with identical attnum. We delete from there any element
2935 * that we process.
2936 *
2937 * We don't use foreach() here because we have two nested loops over the
2938 * constraint list, with possible element deletions in the inner one. If
2939 * we used foreach_delete_current() it could only fix up the state of one
2940 * of the loops, so it seems cleaner to use looping over list indexes for
2941 * both loops. Note that any deletion will happen beyond where the outer
2942 * loop is, so its index never needs adjustment.
2943 */
2944 for (int outerpos = 0; outerpos < list_length(constraints); outerpos++)
2945 {
2946 Constraint *constr;
2948 char *conname;
2949 int inhcount = 0;
2950
2951 constr = list_nth_node(Constraint, constraints, outerpos);
2952
2953 Assert(constr->contype == CONSTR_NOTNULL);
2954
2956 strVal(linitial(constr->keys)));
2958 ereport(ERROR,
2960 errmsg("column \"%s\" of relation \"%s\" does not exist",
2961 strVal(linitial(constr->keys)),
2964 ereport(ERROR,
2966 errmsg("cannot add not-null constraint on system column \"%s\"",
2967 strVal(linitial(constr->keys))));
2968
2969 /*
2970 * A column can only have one not-null constraint, so discard any
2971 * additional ones that appear for columns we already saw; but check
2972 * that the NO INHERIT flags match.
2973 */
2974 for (int restpos = outerpos + 1; restpos < list_length(constraints);)
2975 {
2977
2978 other = list_nth_node(Constraint, constraints, restpos);
2979 if (strcmp(strVal(linitial(constr->keys)),
2980 strVal(linitial(other->keys))) == 0)
2981 {
2982 if (other->is_no_inherit != constr->is_no_inherit)
2983 ereport(ERROR,
2985 errmsg("conflicting NO INHERIT declaration for not-null constraint on column \"%s\"",
2986 strVal(linitial(constr->keys))));
2987
2988 /*
2989 * Preserve constraint name if one is specified, but raise an
2990 * error if conflicting ones are specified.
2991 */
2992 if (other->conname)
2993 {
2994 if (!constr->conname)
2995 constr->conname = pstrdup(other->conname);
2996 else if (strcmp(constr->conname, other->conname) != 0)
2997 ereport(ERROR,
2999 errmsg("conflicting not-null constraint names \"%s\" and \"%s\"",
3000 constr->conname, other->conname));
3001 }
3002
3003 /* XXX do we need to verify any other fields? */
3004 constraints = list_delete_nth_cell(constraints, restpos);
3005 }
3006 else
3007 restpos++;
3008 }
3009
3010 /*
3011 * Search in the list of inherited constraints for any entries on the
3012 * same column; determine an inheritance count from that. Also, if at
3013 * least one parent has a constraint for this column, then we must not
3014 * accept a user specification for a NO INHERIT one. Any constraint
3015 * from parents that we process here is deleted from the list: we no
3016 * longer need to process it in the loop below.
3017 */
3019 {
3020 if (old->attnum == attnum)
3021 {
3022 /*
3023 * If we get a constraint from the parent, having a local NO
3024 * INHERIT one doesn't work.
3025 */
3026 if (constr->is_no_inherit)
3027 ereport(ERROR,
3029 errmsg("cannot define not-null constraint with NO INHERIT on column \"%s\"",
3030 strVal(linitial(constr->keys))),
3031 errdetail("The column has an inherited not-null constraint.")));
3032
3033 inhcount++;
3035 }
3036 }
3037
3038 /*
3039 * Determine a constraint name, which may have been specified by the
3040 * user, or raise an error if a conflict exists with another
3041 * user-specified name.
3042 */
3043 if (constr->conname)
3044 {
3046 {
3047 if (strcmp(thisname, constr->conname) == 0)
3048 ereport(ERROR,
3050 errmsg("constraint \"%s\" for relation \"%s\" already exists",
3051 constr->conname,
3053 }
3054
3055 conname = constr->conname;
3056 givennames = lappend(givennames, conname);
3057 }
3058 else
3061 attnum, false),
3062 "not_null",
3064 nnnames);
3065 nnnames = lappend(nnnames, conname);
3066
3067 StoreRelNotNull(rel, conname,
3068 attnum, true, true,
3069 inhcount, constr->is_no_inherit);
3070
3072 }
3073
3074 /*
3075 * If any column remains in the old_notnulls list, we must create a not-
3076 * null constraint marked not-local for that column. Because multiple
3077 * parents could specify a not-null constraint for the same column, we
3078 * must count how many there are and set an appropriate inhcount
3079 * accordingly, deleting elements we've already processed.
3080 *
3081 * We don't use foreach() here because we have two nested loops over the
3082 * constraint list, with possible element deletions in the inner one. If
3083 * we used foreach_delete_current() it could only fix up the state of one
3084 * of the loops, so it seems cleaner to use looping over list indexes for
3085 * both loops. Note that any deletion will happen beyond where the outer
3086 * loop is, so its index never needs adjustment.
3087 */
3089 {
3091 char *conname = NULL;
3092 int inhcount = 1;
3093
3095 Assert(cooked->contype == CONSTR_NOTNULL);
3096 Assert(cooked->name);
3097
3098 /*
3099 * Preserve the first non-conflicting constraint name we come across.
3100 */
3101 if (conname == NULL)
3102 conname = cooked->name;
3103
3104 for (int restpos = outerpos + 1; restpos < list_length(old_notnulls);)
3105 {
3107
3109 Assert(other->name);
3110 if (other->attnum == cooked->attnum)
3111 {
3112 if (conname == NULL)
3113 conname = other->name;
3114
3115 inhcount++;
3117 }
3118 else
3119 restpos++;
3120 }
3121
3122 /* If we got a name, make sure it isn't one we've already used */
3123 if (conname != NULL)
3124 {
3126 {
3127 if (strcmp(thisname, conname) == 0)
3128 {
3129 conname = NULL;
3130 break;
3131 }
3132 }
3133 }
3134
3135 /* and choose a name, if needed */
3136 if (conname == NULL)
3139 cooked->attnum, false),
3140 "not_null",
3142 nnnames);
3143 nnnames = lappend(nnnames, conname);
3144
3145 /* ignore the origin constraint's is_local and inhcount */
3146 StoreRelNotNull(rel, conname, cooked->attnum, true,
3147 false, inhcount, false);
3148
3149 nncols = lappend_int(nncols, cooked->attnum);
3150 }
3151
3152 return nncols;
3153}
3154
3155/*
3156 * Update the count of constraints in the relation's pg_class tuple.
3157 *
3158 * Caller had better hold exclusive lock on the relation.
3159 *
3160 * An important side effect is that a SI update message will be sent out for
3161 * the pg_class tuple, which will force other backends to rebuild their
3162 * relcache entries for the rel. Also, this backend will rebuild its
3163 * own relcache entry at the next CommandCounterIncrement.
3164 */
3165static void
3167{
3171
3176 elog(ERROR, "cache lookup failed for relation %u",
3177 RelationGetRelid(rel));
3179
3180 if (relStruct->relchecks != numchecks)
3181 {
3182 relStruct->relchecks = numchecks;
3183
3185 }
3186 else
3187 {
3188 /* Skip the disk update, but force relcache inval anyway */
3190 }
3191
3194}
3195
3196/*
3197 * Check for references to generated columns
3198 */
3199static bool
3201{
3202 ParseState *pstate = context;
3203
3204 if (node == NULL)
3205 return false;
3206 else if (IsA(node, Var))
3207 {
3208 Var *var = (Var *) node;
3209 Oid relid;
3211
3212 relid = rt_fetch(var->varno, pstate->p_rtable)->relid;
3213 if (!OidIsValid(relid))
3214 return false; /* XXX shouldn't we raise an error? */
3215
3216 attnum = var->varattno;
3217
3218 if (attnum > 0 && get_attgenerated(relid, attnum))
3219 ereport(ERROR,
3221 errmsg("cannot use generated column \"%s\" in column generation expression",
3222 get_attname(relid, attnum, false)),
3223 errdetail("A generated column cannot reference another generated column."),
3224 parser_errposition(pstate, var->location)));
3225 /* A whole-row Var is necessarily self-referential, so forbid it */
3226 if (attnum == 0)
3227 ereport(ERROR,
3229 errmsg("cannot use whole-row variable in column generation expression"),
3230 errdetail("This would cause the generated column to depend on its own value."),
3231 parser_errposition(pstate, var->location)));
3232 /* System columns were already checked in the parser */
3233
3234 return false;
3235 }
3236 else
3238 context);
3239}
3240
3241static void
3243{
3244 check_nested_generated_walker(node, pstate);
3245}
3246
3247/*
3248 * Check security of virtual generated column expression.
3249 *
3250 * Just like selecting from a view is exploitable (CVE-2024-7348), selecting
3251 * from a table with virtual generated columns is exploitable. Users who are
3252 * concerned about this can avoid selecting from views, but telling them to
3253 * avoid selecting from tables is less practical.
3254 *
3255 * To address this, this restricts generation expressions for virtual
3256 * generated columns are restricted to using built-in functions and types. We
3257 * assume that built-in functions and types cannot be exploited for this
3258 * purpose. Note the overall security also requires that all functions in use
3259 * a immutable. (For example, there are some built-in non-immutable functions
3260 * that can run arbitrary SQL.) The immutability is checked elsewhere, since
3261 * that is a property that needs to hold independent of security
3262 * considerations.
3263 *
3264 * In the future, this could be expanded by some new mechanism to declare
3265 * other functions and types as safe or trusted for this purpose, but that is
3266 * to be designed.
3267 */
3268
3269/*
3270 * Callback for check_functions_in_node() that determines whether a function
3271 * is user-defined.
3272 */
3273static bool
3275{
3276 return (func_id >= FirstUnpinnedObjectId);
3277}
3278
3279/*
3280 * Checks for all the things we don't want in the generation expressions of
3281 * virtual generated columns for security reasons. Errors out if it finds
3282 * one.
3283 */
3284static bool
3286{
3287 ParseState *pstate = context;
3288
3289 if (node == NULL)
3290 return false;
3291
3292 if (!IsA(node, List))
3293 {
3295 ereport(ERROR,
3297 errmsg("generation expression uses user-defined function"),
3298 errdetail("Virtual generated columns that make use of user-defined functions are not yet supported."),
3299 parser_errposition(pstate, exprLocation(node)));
3300
3301 /*
3302 * check_functions_in_node() doesn't check some node types (see
3303 * comment there). We handle CoerceToDomain and MinMaxExpr by
3304 * checking for built-in types. The other listed node types cannot
3305 * call user-definable SQL-visible functions.
3306 *
3307 * We furthermore need this type check to handle built-in, immutable
3308 * polymorphic functions such as array_eq().
3309 */
3310 if (exprType(node) >= FirstUnpinnedObjectId)
3311 ereport(ERROR,
3313 errmsg("generation expression uses user-defined type"),
3314 errdetail("Virtual generated columns that make use of user-defined types are not yet supported."),
3315 parser_errposition(pstate, exprLocation(node)));
3316 }
3317
3319}
3320
3321static void
3326
3327/*
3328 * Take a raw default and convert it to a cooked format ready for
3329 * storage.
3330 *
3331 * Parse state should be set up to recognize any vars that might appear
3332 * in the expression. (Even though we plan to reject vars, it's more
3333 * user-friendly to give the correct error message than "unknown var".)
3334 *
3335 * If atttypid is not InvalidOid, coerce the expression to the specified
3336 * type (and typmod atttypmod). attname is only needed in this case:
3337 * it is used in the error message, if any.
3338 */
3339Node *
3341 Node *raw_default,
3342 Oid atttypid,
3343 int32 atttypmod,
3344 const char *attname,
3345 char attgenerated)
3346{
3347 Node *expr;
3348
3349 Assert(raw_default != NULL);
3350
3351 /*
3352 * Transform raw parsetree to executable expression.
3353 */
3354 expr = transformExpr(pstate, raw_default, attgenerated ? EXPR_KIND_GENERATED_COLUMN : EXPR_KIND_COLUMN_DEFAULT);
3355
3356 if (attgenerated)
3357 {
3358 /* Disallow refs to other generated columns */
3359 check_nested_generated(pstate, expr);
3360
3361 /* Disallow mutable functions */
3363 ereport(ERROR,
3365 errmsg("generation expression is not immutable")));
3366
3367 /* Check security of expressions for virtual generated column */
3368 if (attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
3370 }
3371 else
3372 {
3373 /*
3374 * For a default expression, transformExpr() should have rejected
3375 * column references.
3376 */
3377 Assert(!contain_var_clause(expr));
3378 }
3379
3380 /*
3381 * Coerce the expression to the correct type and typmod, if given. This
3382 * should match the parser's processing of non-defaulted expressions ---
3383 * see transformAssignedExpr().
3384 */
3385 if (OidIsValid(atttypid))
3386 {
3387 Oid type_id = exprType(expr);
3388
3389 expr = coerce_to_target_type(pstate, expr, type_id,
3390 atttypid, atttypmod,
3393 -1);
3394 if (expr == NULL)
3395 ereport(ERROR,
3397 errmsg("column \"%s\" is of type %s"
3398 " but default expression is of type %s",
3399 attname,
3401 format_type_be(type_id)),
3402 errhint("You will need to rewrite or cast the expression.")));
3403 }
3404
3405 /*
3406 * Finally, take care of collations in the finished expression.
3407 */
3408 assign_expr_collations(pstate, expr);
3409
3410 return expr;
3411}
3412
3413/*
3414 * Take a raw CHECK constraint expression and convert it to a cooked format
3415 * ready for storage.
3416 *
3417 * Parse state must be set up to recognize any vars that might appear
3418 * in the expression.
3419 */
3420static Node *
3423 char *relname)
3424{
3425 Node *expr;
3426
3427 /*
3428 * Transform raw parsetree to executable expression.
3429 */
3431
3432 /*
3433 * Make sure it yields a boolean result.
3434 */
3435 expr = coerce_to_boolean(pstate, expr, "CHECK");
3436
3437 /*
3438 * Take care of collations.
3439 */
3440 assign_expr_collations(pstate, expr);
3441
3442 /*
3443 * Make sure no outside relations are referred to (this is probably dead
3444 * code now that add_missing_from is history).
3445 */
3446 if (list_length(pstate->p_rtable) != 1)
3447 ereport(ERROR,
3449 errmsg("only table \"%s\" can be referenced in check constraint",
3450 relname)));
3451
3452 return expr;
3453}
3454
3455/*
3456 * CopyStatistics --- copy entries in pg_statistic from one rel to another
3457 */
3458void
3460{
3461 HeapTuple tup;
3462 SysScanDesc scan;
3463 ScanKeyData key[1];
3466
3468
3469 /* Now search for stat records */
3470 ScanKeyInit(&key[0],
3474
3476 true, NULL, 1, key);
3477
3478 while (HeapTupleIsValid((tup = systable_getnext(scan))))
3479 {
3481
3482 /* make a modifiable copy */
3485
3486 /* update the copy of the tuple and insert it */
3487 statform->starelid = torelid;
3488
3489 /* fetch index information when we know we need it */
3490 if (indstate == NULL)
3492
3494
3496 }
3497
3498 systable_endscan(scan);
3499
3500 if (indstate != NULL)
3503}
3504
3505/*
3506 * RemoveStatistics --- remove entries in pg_statistic for a rel or column
3507 *
3508 * If attnum is zero, remove all entries for rel; else remove only the one(s)
3509 * for that column.
3510 */
3511void
3513{
3515 SysScanDesc scan;
3516 ScanKeyData key[2];
3517 int nkeys;
3518 HeapTuple tuple;
3519
3521
3522 ScanKeyInit(&key[0],
3525 ObjectIdGetDatum(relid));
3526
3527 if (attnum == 0)
3528 nkeys = 1;
3529 else
3530 {
3531 ScanKeyInit(&key[1],
3535 nkeys = 2;
3536 }
3537
3539 NULL, nkeys, key);
3540
3541 /* we must loop even when attnum != 0, in case of inherited stats */
3542 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
3544
3545 systable_endscan(scan);
3546
3548}
3549
3550
3551/*
3552 * RelationTruncateIndexes - truncate all indexes associated
3553 * with the heap relation to zero tuples.
3554 *
3555 * The routine will truncate and then reconstruct the indexes on
3556 * the specified relation. Caller must hold exclusive lock on rel.
3557 */
3558static void
3560{
3562
3563 /* Ask the relcache to produce a list of the indexes of the rel */
3564 foreach(indlist, RelationGetIndexList(heapRelation))
3565 {
3568 IndexInfo *indexInfo;
3569
3570 /* Open the index relation; use exclusive lock, just to be sure */
3572
3573 /*
3574 * Fetch info needed for index_build. Since we know there are no
3575 * tuples that actually need indexing, we can use a dummy IndexInfo.
3576 * This is slightly cheaper to build, but the real point is to avoid
3577 * possibly running user-defined code in index expressions or
3578 * predicates. We might be getting invoked during ON COMMIT
3579 * processing, and we don't want to run any such code then.
3580 */
3581 indexInfo = BuildDummyIndexInfo(currentIndex);
3582
3583 /*
3584 * Now truncate the actual file (and discard buffers).
3585 */
3587
3588 /* Initialize the index and rebuild */
3589 /* Note: we do not need to re-establish pkey setting */
3590 index_build(heapRelation, currentIndex, indexInfo, true, false,
3591 true);
3592
3593 /* We're done with this index */
3595 }
3596}
3597
3598/*
3599 * heap_truncate
3600 *
3601 * This routine deletes all data within all the specified relations.
3602 *
3603 * This is not transaction-safe! There is another, transaction-safe
3604 * implementation in commands/tablecmds.c. We now use this only for
3605 * ON COMMIT truncation of temporary tables, where it doesn't matter.
3606 */
3607void
3609{
3610 List *relations = NIL;
3611 ListCell *cell;
3612
3613 /* Open relations for processing, and grab exclusive access on each */
3614 foreach(cell, relids)
3615 {
3616 Oid rid = lfirst_oid(cell);
3617 Relation rel;
3618
3619 rel = table_open(rid, AccessExclusiveLock);
3620 relations = lappend(relations, rel);
3621 }
3622
3623 /* Don't allow truncate on tables that are referenced by foreign keys */
3624 heap_truncate_check_FKs(relations, true);
3625
3626 /* OK to do it */
3627 foreach(cell, relations)
3628 {
3629 Relation rel = lfirst(cell);
3630
3631 /* Truncate the relation */
3633
3634 /* Close the relation, but keep exclusive lock on it until commit */
3635 table_close(rel, NoLock);
3636 }
3637}
3638
3639/*
3640 * heap_truncate_one_rel
3641 *
3642 * This routine deletes all data within the specified relation.
3643 *
3644 * This is not transaction-safe, because the truncation is done immediately
3645 * and cannot be rolled back later. Caller is responsible for having
3646 * checked permissions etc, and must have obtained AccessExclusiveLock.
3647 */
3648void
3650{
3652
3653 /*
3654 * Truncate the relation. Partitioned tables have no storage, so there is
3655 * nothing to do for them here.
3656 */
3657 if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
3658 return;
3659
3660 /* Truncate the underlying relation */
3662
3663 /* If the relation has indexes, truncate the indexes too */
3665
3666 /* If there is a toast table, truncate that too */
3667 toastrelid = rel->rd_rel->reltoastrelid;
3669 {
3671
3674 /* keep the lock... */
3676 }
3677}
3678
3679/*
3680 * heap_truncate_check_FKs
3681 * Check for foreign keys referencing a list of relations that
3682 * are to be truncated, and raise error if there are any
3683 *
3684 * We disallow such FKs (except self-referential ones) since the whole point
3685 * of TRUNCATE is to not scan the individual rows to be thrown away.
3686 *
3687 * This is split out so it can be shared by both implementations of truncate.
3688 * Caller should already hold a suitable lock on the relations.
3689 *
3690 * tempTables is only used to select an appropriate error message.
3691 */
3692void
3694{
3695 List *oids = NIL;
3697 ListCell *cell;
3698
3699 /*
3700 * Build a list of OIDs of the interesting relations.
3701 *
3702 * If a relation has no triggers, then it can neither have FKs nor be
3703 * referenced by a FK from another table, so we can ignore it. For
3704 * partitioned tables, FKs have no triggers, so we must include them
3705 * anyway.
3706 */
3707 foreach(cell, relations)
3708 {
3709 Relation rel = lfirst(cell);
3710
3711 if (rel->rd_rel->relhastriggers ||
3712 rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
3713 oids = lappend_oid(oids, RelationGetRelid(rel));
3714 }
3715
3716 /*
3717 * Fast path: if no relation has triggers, none has FKs either.
3718 */
3719 if (oids == NIL)
3720 return;
3721
3722 /*
3723 * Otherwise, must scan pg_constraint. We make one pass with all the
3724 * relations considered; if this finds nothing, then all is well.
3725 */
3727 if (dependents == NIL)
3728 return;
3729
3730 /*
3731 * Otherwise we repeat the scan once per relation to identify a particular
3732 * pair of relations to complain about. This is pretty slow, but
3733 * performance shouldn't matter much in a failure path. The reason for
3734 * doing things this way is to ensure that the message produced is not
3735 * dependent on chance row locations within pg_constraint.
3736 */
3737 foreach(cell, oids)
3738 {
3739 Oid relid = lfirst_oid(cell);
3740 ListCell *cell2;
3741
3743
3744 foreach(cell2, dependents)
3745 {
3747
3748 if (!list_member_oid(oids, relid2))
3749 {
3750 char *relname = get_rel_name(relid);
3751 char *relname2 = get_rel_name(relid2);
3752
3753 if (tempTables)
3754 ereport(ERROR,
3756 errmsg("unsupported ON COMMIT and foreign key combination"),
3757 errdetail("Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting.",
3758 relname2, relname)));
3759 else
3760 ereport(ERROR,
3762 errmsg("cannot truncate a table referenced in a foreign key constraint"),
3763 errdetail("Table \"%s\" references \"%s\".",
3764 relname2, relname),
3765 errhint("Truncate table \"%s\" at the same time, "
3766 "or use TRUNCATE ... CASCADE.",
3767 relname2)));
3768 }
3769 }
3770 }
3771}
3772
3773/*
3774 * heap_truncate_find_FKs
3775 * Find relations having foreign keys referencing any of the given rels
3776 *
3777 * Input and result are both lists of relation OIDs. The result contains
3778 * no duplicates, does *not* include any rels that were already in the input
3779 * list, and is sorted in OID order. (The last property is enforced mainly
3780 * to guarantee consistent behavior in the regression tests; we don't want
3781 * behavior to change depending on chance locations of rows in pg_constraint.)
3782 *
3783 * Note: caller should already have appropriate lock on all rels mentioned
3784 * in relationIds. Since adding or dropping an FK requires exclusive lock
3785 * on both rels, this ensures that the answer will be stable.
3786 */
3787List *
3789{
3790 List *result = NIL;
3791 List *oids;
3793 ListCell *cell;
3794 ScanKeyData key;
3797 HeapTuple tuple;
3798 bool restart;
3799
3800 oids = list_copy(relationIds);
3801
3802 /*
3803 * Must scan pg_constraint. Right now, it is a seqscan because there is
3804 * no available index on confrelid.
3805 */
3807
3808restart:
3809 restart = false;
3810 parent_cons = NIL;
3811
3813 NULL, 0, NULL);
3814
3816 {
3818
3819 /* Not a foreign key */
3820 if (con->contype != CONSTRAINT_FOREIGN)
3821 continue;
3822
3823 /* Not referencing one of our list of tables */
3824 if (!list_member_oid(oids, con->confrelid))
3825 continue;
3826
3827 /*
3828 * If this constraint has a parent constraint which we have not seen
3829 * yet, keep track of it for the second loop, below. Tracking parent
3830 * constraints allows us to climb up to the top-level constraint and
3831 * look for all possible relations referencing the partitioned table.
3832 */
3833 if (OidIsValid(con->conparentid) &&
3834 !list_member_oid(parent_cons, con->conparentid))
3835 parent_cons = lappend_oid(parent_cons, con->conparentid);
3836
3837 /*
3838 * Add referencer to result, unless present in input list. (Don't
3839 * worry about dupes: we'll fix that below).
3840 */
3841 if (!list_member_oid(relationIds, con->conrelid))
3842 result = lappend_oid(result, con->conrelid);
3843 }
3844
3846
3847 /*
3848 * Process each parent constraint we found to add the list of referenced
3849 * relations by them to the oids list. If we do add any new such
3850 * relations, redo the first loop above. Also, if we see that the parent
3851 * constraint in turn has a parent, add that so that we process all
3852 * relations in a single additional pass.
3853 */
3854 foreach(cell, parent_cons)
3855 {
3856 Oid parent = lfirst_oid(cell);
3857
3858 ScanKeyInit(&key,
3861 ObjectIdGetDatum(parent));
3862
3864 true, NULL, 1, &key);
3865
3866 tuple = systable_getnext(fkeyScan);
3867 if (HeapTupleIsValid(tuple))
3868 {
3870
3871 /*
3872 * pg_constraint rows always appear for partitioned hierarchies
3873 * this way: on the each side of the constraint, one row appears
3874 * for each partition that points to the top-most table on the
3875 * other side.
3876 *
3877 * Because of this arrangement, we can correctly catch all
3878 * relevant relations by adding to 'parent_cons' all rows with
3879 * valid conparentid, and to the 'oids' list all rows with a zero
3880 * conparentid. If any oids are added to 'oids', redo the first
3881 * loop above by setting 'restart'.
3882 */
3883 if (OidIsValid(con->conparentid))
3885 con->conparentid);
3886 else if (!list_member_oid(oids, con->confrelid))
3887 {
3888 oids = lappend_oid(oids, con->confrelid);
3889 restart = true;
3890 }
3891 }
3892
3894 }
3895
3897 if (restart)
3898 goto restart;
3899
3901 list_free(oids);
3902
3903 /* Now sort and de-duplicate the result list */
3906
3907 return result;
3908}
3909
3910/*
3911 * StorePartitionKey
3912 * Store information about the partition key rel into the catalog
3913 */
3914void
3916 char strategy,
3917 int16 partnatts,
3918 AttrNumber *partattrs,
3919 List *partexprs,
3921 Oid *partcollation)
3922{
3923 int i;
3929 HeapTuple tuple;
3931 bool nulls[Natts_pg_partitioned_table] = {0};
3934 ObjectAddresses *addrs;
3935
3936 Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
3937
3938 /* Copy the partition attribute numbers, opclass OIDs into arrays */
3939 partattrs_vec = buildint2vector(partattrs, partnatts);
3941 partcollation_vec = buildoidvector(partcollation, partnatts);
3942
3943 /* Convert the expressions (if any) to a text datum */
3944 if (partexprs)
3945 {
3946 char *exprString;
3947
3948 exprString = nodeToString(partexprs);
3951 }
3952 else
3953 partexprDatum = (Datum) 0;
3954
3956
3957 /* Only this can ever be NULL */
3958 if (!partexprDatum)
3959 nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
3960
3969
3971
3974
3975 /* Mark this relation as dependent on a few things as follows */
3976 addrs = new_object_addresses();
3978
3979 /* Operator class and collation per key column */
3980 for (i = 0; i < partnatts; i++)
3981 {
3984
3985 /* The default collation is pinned, so don't bother recording it */
3986 if (OidIsValid(partcollation[i]) &&
3987 partcollation[i] != DEFAULT_COLLATION_OID)
3988 {
3991 }
3992 }
3993
3995 free_object_addresses(addrs);
3996
3997 /*
3998 * The partitioning columns are made internally dependent on the table,
3999 * because we cannot drop any of them without dropping the whole table.
4000 * (ATExecDropColumn independently enforces that, but it's not bulletproof
4001 * so we need the dependencies too.)
4002 */
4003 for (i = 0; i < partnatts; i++)
4004 {
4005 if (partattrs[i] == 0)
4006 continue; /* ignore expressions here */
4007
4009 RelationGetRelid(rel), partattrs[i]);
4011 }
4012
4013 /*
4014 * Also consider anything mentioned in partition expressions. External
4015 * references (e.g. functions) get NORMAL dependencies. Table columns
4016 * mentioned in the expressions are handled the same as plain partitioning
4017 * columns, i.e. they become internally dependent on the whole table.
4018 */
4019 if (partexprs)
4021 (Node *) partexprs,
4022 RelationGetRelid(rel),
4025 true /* reverse the self-deps */ );
4026
4027 /*
4028 * We must invalidate the relcache so that the next
4029 * CommandCounterIncrement() will cause the same to be rebuilt using the
4030 * information in just created catalog entry.
4031 */
4033}
4034
4035/*
4036 * RemovePartitionKeyByRelId
4037 * Remove pg_partitioned_table entry for a relation
4038 */
4039void
4041{
4042 Relation rel;
4043 HeapTuple tuple;
4044
4046
4048 if (!HeapTupleIsValid(tuple))
4049 elog(ERROR, "cache lookup failed for partition key of relation %u",
4050 relid);
4051
4052 CatalogTupleDelete(rel, &tuple->t_self);
4053
4054 ReleaseSysCache(tuple);
4056}
4057
4058/*
4059 * StorePartitionBound
4060 * Update pg_class tuple of rel to store the partition bound and set
4061 * relispartition to true
4062 *
4063 * If this is the default partition, also update the default partition OID in
4064 * pg_partitioned_table.
4065 *
4066 * Also, invalidate the parent's relcache, so that the next rebuild will load
4067 * the new partition's info into its partition descriptor. If there is a
4068 * default partition, we must invalidate its relcache entry as well.
4069 */
4070void
4072{
4074 HeapTuple tuple,
4075 newtuple;
4080
4081 /* Update pg_class tuple */
4085 if (!HeapTupleIsValid(tuple))
4086 elog(ERROR, "cache lookup failed for relation %u",
4087 RelationGetRelid(rel));
4088
4089#ifdef USE_ASSERT_CHECKING
4090 {
4092 bool isnull;
4093
4095 Assert(!classForm->relispartition);
4097 &isnull);
4098 Assert(isnull);
4099 }
4100#endif
4101
4102 /* Fill in relpartbound value */
4103 memset(new_val, 0, sizeof(new_val));
4104 memset(new_null, false, sizeof(new_null));
4105 memset(new_repl, false, sizeof(new_repl));
4109 newtuple = heap_modify_tuple(tuple, RelationGetDescr(classRel),
4111 /* Also set the flag */
4112 ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true;
4113
4114 /*
4115 * We already checked for no inheritance children, but reset
4116 * relhassubclass in case it was left over.
4117 */
4118 if (rel->rd_rel->relkind == RELKIND_RELATION && rel->rd_rel->relhassubclass)
4119 ((Form_pg_class) GETSTRUCT(newtuple))->relhassubclass = false;
4120
4121 CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
4122 heap_freetuple(newtuple);
4124
4125 /*
4126 * If we're storing bounds for the default partition, update
4127 * pg_partitioned_table too.
4128 */
4129 if (bound->is_default)
4131 RelationGetRelid(rel));
4132
4133 /* Make these updates visible */
4135
4136 /*
4137 * The partition constraint for the default partition depends on the
4138 * partition bounds of every other partition, so we must invalidate the
4139 * relcache entry for that partition every time a partition is added or
4140 * removed.
4141 */
4146
4148}
void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
Definition aclchk.c:4371
Acl * get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid)
Definition aclchk.c:4291
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:190
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:835
#define Min(x, y)
Definition c.h:1091
#define Assert(condition)
Definition c.h:943
TransactionId MultiXactId
Definition c.h:746
int16_t int16
Definition c.h:619
int32_t int32
Definition c.h:620
#define lengthof(array)
Definition c.h:873
uint32 CommandId
Definition c.h:750
uint32 TransactionId
Definition c.h:736
#define OidIsValid(objectId)
Definition c.h:858
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
uint32 result
bool contain_mutable_functions_after_planning(Expr *expr)
Definition clauses.c:503
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:875
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define NOTICE
Definition elog.h:36
#define ereport(elevel,...)
Definition elog.h:152
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:89
#define palloc_array(type, count)
Definition fe_memutils.h:91
#define OidFunctionCall3(functionId, arg1, arg2, arg3)
Definition fmgr.h:730
char * format_type_be(Oid type_oid)
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:612
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:523
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
bool IsBinaryUpgrade
Definition globals.c:123
Oid MyDatabaseTableSpace
Definition globals.c:98
void RemoveAttributeById(Oid relid, AttrNumber attnum)
Definition heap.c:1700
void RelationClearMissing(Relation rel)
Definition heap.c:1981
void SetAttrMissing(Oid relid, char *attname, char *value)
Definition heap.c:2103
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:2164
List * heap_truncate_find_FKs(List *relationIds)
Definition heap.c:3788
void DeleteSystemAttributeTuples(Oid relid)
Definition heap.c:1659
void StorePartitionKey(Relation rel, char strategy, int16 partnatts, AttrNumber *partattrs, List *partexprs, Oid *partopclass, Oid *partcollation)
Definition heap.c:3915
static void StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal)
Definition heap.c:2327
static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relkind)
Definition heap.c:849
void DeleteRelationTuple(Oid relid)
Definition heap.c:1593
static void RelationTruncateIndexes(Relation heapRelation)
Definition heap.c:3559
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:999
void DeleteAttributeTuples(Oid relid)
Definition heap.c:1622
void RemoveStatistics(Oid relid, AttrNumber attnum)
Definition heap.c:3512
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:1058
static bool contains_user_functions_checker(Oid func_id, void *context)
Definition heap.c:3274
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:1137
void heap_truncate(List *relids)
Definition heap.c:3608
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:2729
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:2271
void CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation, List *containing_rowtypes, int flags)
Definition heap.c:549
const FormData_pg_attribute * SystemAttributeByName(const char *attname)
Definition heap.c:248
void CopyStatistics(Oid fromrelid, Oid torelid)
Definition heap.c:3459
List * AddRelationNotNullConstraints(Relation rel, List *constraints, List *old_notnulls, List *existing_constraints)
Definition heap.c:2914
static void check_virtual_generated_security(ParseState *pstate, Node *node)
Definition heap.c:3322
void heap_truncate_check_FKs(List *relations, bool tempTables)
Definition heap.c:3693
static const FormData_pg_attribute a6
Definition heap.c:215
static bool check_nested_generated_walker(Node *node, void *context)
Definition heap.c:3200
static void SetRelationNumChecks(Relation rel, int numchecks)
Definition heap.c:3166
static const FormData_pg_attribute a3
Definition heap.c:170
static void RelationRemoveInheritance(Oid relid)
Definition heap.c:1560
static const FormData_pg_attribute a2
Definition heap.c:157
void StorePartitionBound(Relation rel, Relation parent, PartitionBoundSpec *bound)
Definition heap.c:4071
void heap_drop_with_catalog(Oid relid)
Definition heap.c:1801
List * AddRelationNewConstraints(Relation rel, List *newColDefaults, List *newConstraints, bool allow_merge, bool is_local, bool is_internal, const char *queryString)
Definition heap.c:2402
void InsertPgClassTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Datum relacl, Datum reloptions)
Definition heap.c:925
static bool check_virtual_generated_security_walker(Node *node, void *context)
Definition heap.c:3285
void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, int flags)
Definition heap.c:453
static void check_nested_generated(ParseState *pstate, Node *node)
Definition heap.c:3242
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:732
Node * cookDefault(ParseState *pstate, Node *raw_default, Oid atttypid, int32 atttypmod, const char *attname, char attgenerated)
Definition heap.c:3340
void heap_truncate_one_rel(Relation rel)
Definition heap.c:3649
void RemovePartitionKeyByRelId(Oid relid)
Definition heap.c:4040
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:2047
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:286
static Node * cookConstraint(ParseState *pstate, Node *raw_constraint, char *relname)
Definition heap.c:3421
#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:1118
HeapTuple heap_copytuple(HeapTuple tuple)
Definition heaptuple.c:686
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1025
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1372
#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)
void index_build(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, bool isreindex, bool parallel, bool progress)
Definition index.c:3021
IndexInfo * BuildDummyIndexInfo(Relation index)
Definition index.c:2506
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:178
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:134
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 @177 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:1632
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition inval.c:1688
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:3660
char * get_rel_name(Oid relid)
Definition lsyscache.c:2159
AttrNumber get_attnum(Oid relid, const char *attname)
Definition lsyscache.c:1015
Oid get_element_type(Oid typid)
Definition lsyscache.c:2992
char get_attgenerated(Oid relid, AttrNumber attnum)
Definition lsyscache.c:1045
Oid get_multirange_range(Oid multirangeOid)
Definition lsyscache.c:3761
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition lsyscache.c:984
Oid get_range_collation(Oid rangeOid)
Definition lsyscache.c:3686
bool type_is_collatable(Oid typid)
Definition lsyscache.c:3314
Oid get_typ_typrelid(Oid typid)
Definition lsyscache.c:2964
char get_typtype(Oid typid)
Definition lsyscache.c:2862
Oid getBaseType(Oid typid)
Definition lsyscache.c:2754
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3599
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition lsyscache.c:2116
char * pstrdup(const char *in)
Definition mcxt.c:1910
void pfree(void *pointer)
Definition mcxt.c:1619
void * palloc(Size size)
Definition mcxt.c:1390
#define IsBootstrapProcessingMode()
Definition miscadmin.h:495
#define IsNormalProcessingMode()
Definition miscadmin.h:497
#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:1928
int exprLocation(const Node *expr)
Definition nodeFuncs.c:1403
#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
static char * errmsg
#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:811
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:121
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:71
@ EXPR_KIND_GENERATED_COLUMN
Definition parse_node.h:84
@ EXPR_KIND_CHECK_CONSTRAINT
Definition parse_node.h:69
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:423
#define list_make1_oid(x1)
Definition pg_list.h:274
#define foreach_ptr(type, var, lst)
Definition pg_list.h:501
static void * list_nth(const List *list, int n)
Definition pg_list.h:331
#define linitial(l)
Definition pg_list.h:178
#define foreach_node(type, var, lst)
Definition pg_list.h:528
#define list_nth_node(type, list, n)
Definition pg_list.h:359
#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:261
static Datum Float4GetDatum(float4 X)
Definition postgres.h:481
static Datum TransactionIdGetDatum(TransactionId X)
Definition postgres.h:292
static Datum Int16GetDatum(int16 X)
Definition postgres.h:172
static Datum MultiXactIdGetDatum(MultiXactId X)
Definition postgres.h:302
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static Datum NameGetDatum(const NameData *X)
Definition postgres.h:406
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:383
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#define PointerGetDatum(X)
Definition postgres.h:354
static Datum CharGetDatum(char X)
Definition postgres.h:132
#define InvalidOid
unsigned int Oid
void CheckTableForSerializableConflictIn(Relation relation)
Definition predicate.c:4348
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:516
#define RelationGetDescr(relation)
Definition rel.h:542
#define RelationGetNumberOfAttributes(relation)
Definition rel.h:522
#define RelationGetRelationName(relation)
Definition rel.h:550
#define RelationGetNamespace(relation)
Definition rel.h:557
List * RelationGetIndexList(Relation relation)
Definition relcache.c:4837
void RelationForgetRelation(Oid rid)
Definition relcache.c:2893
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:3515
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:206
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition relation.c:48
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:214
List * p_rtable
Definition parse_node.h:215
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:133
Datum * tts_values
Definition tuptable.h:131
ParseLoc location
Definition primnodes.h:311
AttrNumber varattno
Definition primnodes.h:275
int varno
Definition primnodes.h:270
Definition c.h:815
#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:265
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:231
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition syscache.c:476
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596
#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:1687
static void table_relation_nontransactional_truncate(Relation rel)
Definition tableam.h:1705
void CheckTableNotInUse(Relation rel, const char *stmt)
Definition tablecmds.c:4473
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:560
TupleDesc CreateTupleDesc(int natts, Form_pg_attribute *attrs)
Definition tupdesc.c:216
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:476
Oid AssignTypeArrayOid(void)
Definition typecmds.c:2480
#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:1130