PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
heap.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/multixact.h"
#include "access/sysattr.h"
#include "access/transam.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/binary_upgrade.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/objectaccess.h"
#include "catalog/partition.h"
#include "catalog/pg_attrdef.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_constraint_fn.h"
#include "catalog/pg_foreign_table.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_partitioned_table.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
#include "catalog/pg_type_fn.h"
#include "catalog/storage.h"
#include "catalog/storage_xlog.h"
#include "commands/tablecmds.h"
#include "commands/typecmds.h"
#include "miscadmin.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/var.h"
#include "parser/parse_coerce.h"
#include "parser/parse_collate.h"
#include "parser/parse_expr.h"
#include "parser/parse_relation.h"
#include "storage/predicate.h"
#include "storage/smgr.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/ruleutils.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
Include dependency graph for heap.c:

Go to the source code of this file.

Functions

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, Datum relacl, Datum reloptions)
 
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)
 
static void RelationRemoveInheritance (Oid relid)
 
static Oid StoreRelCheck (Relation rel, char *ccname, Node *expr, bool is_validated, bool is_local, int inhcount, bool is_no_inherit, bool is_internal)
 
static void StoreConstraints (Relation rel, List *cooked_constraints, bool is_internal)
 
static bool MergeWithExistingConstraint (Relation rel, char *ccname, Node *expr, bool allow_merge, bool is_local, bool is_initially_valid, bool is_no_inherit)
 
static void SetRelationNumChecks (Relation rel, int numchecks)
 
static NodecookConstraint (ParseState *pstate, Node *raw_constraint, char *relname)
 
static Listinsert_ordered_unique_oid (List *list, Oid datum)
 
Form_pg_attribute SystemAttributeDefinition (AttrNumber attno, bool relhasoids)
 
Form_pg_attribute SystemAttributeByName (const char *attname, bool relhasoids)
 
Relation heap_create (const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, Oid relfilenode, TupleDesc tupDesc, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, bool allow_system_table_mods)
 
void CheckAttributeNamesTypes (TupleDesc tupdesc, char relkind, bool allow_system_table_mods)
 
void CheckAttributeType (const char *attname, Oid atttypid, Oid attcollation, List *containing_rowtypes, bool allow_system_table_mods)
 
void InsertPgAttributeTuple (Relation pg_attribute_rel, Form_pg_attribute new_attribute, CatalogIndexState indstate)
 
static void AddNewAttributeTuples (Oid new_rel_oid, TupleDesc tupdesc, char relkind, bool oidislocal, int oidinhcount)
 
void InsertPgClassTuple (Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Datum relacl, Datum reloptions)
 
Oid heap_create_with_catalog (const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, Oid reltypeid, Oid reloftypeid, Oid ownerid, TupleDesc tupdesc, List *cooked_constraints, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, bool oidislocal, int oidinhcount, OnCommitAction oncommit, Datum reloptions, bool use_user_acl, bool allow_system_table_mods, bool is_internal, ObjectAddress *typaddress)
 
void heap_create_init_fork (Relation rel)
 
void DeleteRelationTuple (Oid relid)
 
void DeleteAttributeTuples (Oid relid)
 
void DeleteSystemAttributeTuples (Oid relid)
 
void RemoveAttributeById (Oid relid, AttrNumber attnum)
 
void RemoveAttrDefault (Oid relid, AttrNumber attnum, DropBehavior behavior, bool complain, bool internal)
 
void RemoveAttrDefaultById (Oid attrdefId)
 
void heap_drop_with_catalog (Oid relid)
 
Oid StoreAttrDefault (Relation rel, AttrNumber attnum, Node *expr, bool is_internal)
 
ListAddRelationNewConstraints (Relation rel, List *newColDefaults, List *newConstraints, bool allow_merge, bool is_local, bool is_internal)
 
NodecookDefault (ParseState *pstate, Node *raw_default, Oid atttypid, int32 atttypmod, char *attname)
 
void RemoveStatistics (Oid relid, AttrNumber attnum)
 
static void RelationTruncateIndexes (Relation heapRelation)
 
void heap_truncate (List *relids)
 
void heap_truncate_one_rel (Relation rel)
 
void heap_truncate_check_FKs (List *relations, bool tempTables)
 
Listheap_truncate_find_FKs (List *relationIds)
 
void StorePartitionKey (Relation rel, char strategy, int16 partnatts, AttrNumber *partattrs, List *partexprs, Oid *partopclass, Oid *partcollation)
 
void RemovePartitionKeyByRelId (Oid relid)
 
void StorePartitionBound (Relation rel, Relation parent, Node *bound)
 

Variables

Oid binary_upgrade_next_heap_pg_class_oid = InvalidOid
 
Oid binary_upgrade_next_toast_pg_class_oid = InvalidOid
 
static FormData_pg_attribute a1
 
static FormData_pg_attribute a2
 
static FormData_pg_attribute a3
 
static FormData_pg_attribute a4
 
static FormData_pg_attribute a5
 
static FormData_pg_attribute a6
 
static FormData_pg_attribute a7
 
static const Form_pg_attribute SysAtt [] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7}
 

Function Documentation

static void AddNewAttributeTuples ( Oid  new_rel_oid,
TupleDesc  tupdesc,
char  relkind,
bool  oidislocal,
int  oidinhcount 
)
static

Definition at line 650 of file heap.c.

References AttributeRelationId, tupleDesc::attrs, CatalogCloseIndexes(), CatalogOpenIndexes(), ObjectAddress::classId, CollationRelationId, DEFAULT_COLLATION_OID, DEPENDENCY_NORMAL, FormData_pg_attribute, heap_close, heap_open(), i, InsertPgAttributeTuple(), lengthof, tupleDesc::natts, ObjectAddress::objectId, ObjectIdAttributeNumber, ObjectAddress::objectSubId, OidIsValid, recordDependencyOn(), RelationRelationId, RELKIND_COMPOSITE_TYPE, RELKIND_VIEW, RowExclusiveLock, tupleDesc::tdhasoid, and TypeRelationId.

Referenced by heap_create_with_catalog().

655 {
656  Form_pg_attribute attr;
657  int i;
658  Relation rel;
659  CatalogIndexState indstate;
660  int natts = tupdesc->natts;
661  ObjectAddress myself,
662  referenced;
663 
664  /*
665  * open pg_attribute and its indexes.
666  */
668 
669  indstate = CatalogOpenIndexes(rel);
670 
671  /*
672  * First we add the user attributes. This is also a convenient place to
673  * add dependencies on their datatypes and collations.
674  */
675  for (i = 0; i < natts; i++)
676  {
677  attr = tupdesc->attrs[i];
678  /* Fill in the correct relation OID */
679  attr->attrelid = new_rel_oid;
680  /* Make sure these are OK, too */
681  attr->attstattarget = -1;
682  attr->attcacheoff = -1;
683 
684  InsertPgAttributeTuple(rel, attr, indstate);
685 
686  /* Add dependency info */
687  myself.classId = RelationRelationId;
688  myself.objectId = new_rel_oid;
689  myself.objectSubId = i + 1;
690  referenced.classId = TypeRelationId;
691  referenced.objectId = attr->atttypid;
692  referenced.objectSubId = 0;
693  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
694 
695  /* The default collation is pinned, so don't bother recording it */
696  if (OidIsValid(attr->attcollation) &&
697  attr->attcollation != DEFAULT_COLLATION_OID)
698  {
699  referenced.classId = CollationRelationId;
700  referenced.objectId = attr->attcollation;
701  referenced.objectSubId = 0;
702  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
703  }
704  }
705 
706  /*
707  * Next we add the system attributes. Skip OID if rel has no OIDs. Skip
708  * all for a view or type relation. We don't bother with making datatype
709  * dependencies here, since presumably all these types are pinned.
710  */
711  if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
712  {
713  for (i = 0; i < (int) lengthof(SysAtt); i++)
714  {
715  FormData_pg_attribute attStruct;
716 
717  /* skip OID where appropriate */
718  if (!tupdesc->tdhasoid &&
719  SysAtt[i]->attnum == ObjectIdAttributeNumber)
720  continue;
721 
722  memcpy(&attStruct, (char *) SysAtt[i], sizeof(FormData_pg_attribute));
723 
724  /* Fill in the correct relation OID in the copied tuple */
725  attStruct.attrelid = new_rel_oid;
726 
727  /* Fill in correct inheritance info for the OID column */
728  if (attStruct.attnum == ObjectIdAttributeNumber)
729  {
730  attStruct.attislocal = oidislocal;
731  attStruct.attinhcount = oidinhcount;
732  }
733 
734  InsertPgAttributeTuple(rel, &attStruct, indstate);
735  }
736  }
737 
738  /*
739  * clean up
740  */
741  CatalogCloseIndexes(indstate);
742 
744 }
static const Form_pg_attribute SysAtt[]
Definition: heap.c:190
bool tdhasoid
Definition: tupdesc.h:79
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define RelationRelationId
Definition: pg_class.h:29
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define AttributeRelationId
Definition: pg_attribute.h:33
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
#define heap_close(r, l)
Definition: heapam.h:97
#define lengthof(array)
Definition: c.h:558
#define TypeRelationId
Definition: pg_type.h:34
#define OidIsValid(objectId)
Definition: c.h:534
int natts
Definition: tupdesc.h:73
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:165
#define DEFAULT_COLLATION_OID
Definition: pg_collation.h:68
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define CollationRelationId
Definition: pg_collation.h:30
FormData_pg_attribute
Definition: pg_attribute.h:168
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:40
void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_attribute, CatalogIndexState indstate)
Definition: heap.c:595
#define RELKIND_VIEW
Definition: pg_class.h:164
int i
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:58
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,
Datum  relacl,
Datum  reloptions 
)
static

Definition at line 839 of file heap.c.

References GetOldestMultiXactId(), InsertPgClassTuple(), InvalidMultiXactId, InvalidTransactionId, RelationData::rd_att, RelationData::rd_rel, RecentXmin, RELKIND_INDEX, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_TOASTVALUE, and tupleDesc::tdtypeid.

Referenced by heap_create_with_catalog().

848 {
849  Form_pg_class new_rel_reltup;
850 
851  /*
852  * first we update some of the information in our uncataloged relation's
853  * relation descriptor.
854  */
855  new_rel_reltup = new_rel_desc->rd_rel;
856 
857  switch (relkind)
858  {
859  case RELKIND_RELATION:
860  case RELKIND_MATVIEW:
861  case RELKIND_INDEX:
862  case RELKIND_TOASTVALUE:
863  /* The relation is real, but as yet empty */
864  new_rel_reltup->relpages = 0;
865  new_rel_reltup->reltuples = 0;
866  new_rel_reltup->relallvisible = 0;
867  break;
868  case RELKIND_SEQUENCE:
869  /* Sequences always have a known size */
870  new_rel_reltup->relpages = 1;
871  new_rel_reltup->reltuples = 1;
872  new_rel_reltup->relallvisible = 0;
873  break;
874  default:
875  /* Views, etc, have no disk storage */
876  new_rel_reltup->relpages = 0;
877  new_rel_reltup->reltuples = 0;
878  new_rel_reltup->relallvisible = 0;
879  break;
880  }
881 
882  /* Initialize relfrozenxid and relminmxid */
883  if (relkind == RELKIND_RELATION ||
884  relkind == RELKIND_MATVIEW ||
885  relkind == RELKIND_TOASTVALUE)
886  {
887  /*
888  * Initialize to the minimum XID that could put tuples in the table.
889  * We know that no xacts older than RecentXmin are still running, so
890  * that will do.
891  */
892  new_rel_reltup->relfrozenxid = RecentXmin;
893 
894  /*
895  * Similarly, initialize the minimum Multixact to the first value that
896  * could possibly be stored in tuples in the table. Running
897  * transactions could reuse values from their local cache, so we are
898  * careful to consider all currently running multis.
899  *
900  * XXX this could be refined further, but is it worth the hassle?
901  */
902  new_rel_reltup->relminmxid = GetOldestMultiXactId();
903  }
904  else
905  {
906  /*
907  * Other relation types will not contain XIDs, so set relfrozenxid to
908  * InvalidTransactionId. (Note: a sequence does contain a tuple, but
909  * we force its xmin to be FrozenTransactionId always; see
910  * commands/sequence.c.)
911  */
912  new_rel_reltup->relfrozenxid = InvalidTransactionId;
913  new_rel_reltup->relminmxid = InvalidMultiXactId;
914  }
915 
916  new_rel_reltup->relowner = relowner;
917  new_rel_reltup->reltype = new_type_oid;
918  new_rel_reltup->reloftype = reloftype;
919 
920  /* relispartition is always set by updating this tuple later */
921  new_rel_reltup->relispartition = false;
922 
923  new_rel_desc->rd_att->tdtypeid = new_type_oid;
924 
925  /* Now build and insert the tuple */
926  InsertPgClassTuple(pg_class_desc, new_rel_desc, new_rel_oid,
927  relacl, reloptions);
928 }
Oid tdtypeid
Definition: tupdesc.h:77
#define RELKIND_MATVIEW
Definition: pg_class.h:167
TransactionId RecentXmin
Definition: snapmgr.c:165
Form_pg_class rd_rel
Definition: rel.h:113
void InsertPgClassTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Datum relacl, Datum reloptions)
Definition: heap.c:760
#define InvalidTransactionId
Definition: transam.h:31
MultiXactId GetOldestMultiXactId(void)
Definition: multixact.c:2487
#define RELKIND_TOASTVALUE
Definition: pg_class.h:163
#define InvalidMultiXactId
Definition: multixact.h:23
TupleDesc rd_att
Definition: rel.h:114
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define RELKIND_INDEX
Definition: pg_class.h:161
#define RELKIND_RELATION
Definition: pg_class.h:160
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
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 
)
static

Definition at line 938 of file heap.c.

References DEFAULT_TYPDELIM, InvalidOid, NULL, TYPCATEGORY_COMPOSITE, TypeCreate(), and TYPTYPE_COMPOSITE.

Referenced by heap_create_with_catalog().

945 {
946  return
947  TypeCreate(new_row_type, /* optional predetermined OID */
948  typeName, /* type name */
949  typeNamespace, /* type namespace */
950  new_rel_oid, /* relation oid */
951  new_rel_kind, /* relation kind */
952  ownerid, /* owner's ID */
953  -1, /* internal size (varlena) */
954  TYPTYPE_COMPOSITE, /* type-type (composite) */
955  TYPCATEGORY_COMPOSITE, /* type-category (ditto) */
956  false, /* composite types are never preferred */
957  DEFAULT_TYPDELIM, /* default array delimiter */
958  F_RECORD_IN, /* input procedure */
959  F_RECORD_OUT, /* output procedure */
960  F_RECORD_RECV, /* receive procedure */
961  F_RECORD_SEND, /* send procedure */
962  InvalidOid, /* typmodin procedure - none */
963  InvalidOid, /* typmodout procedure - none */
964  InvalidOid, /* analyze procedure - default */
965  InvalidOid, /* array element type - irrelevant */
966  false, /* this is not an array type */
967  new_array_type, /* array type if any */
968  InvalidOid, /* domain base type - irrelevant */
969  NULL, /* default value - none */
970  NULL, /* default binary representation */
971  false, /* passed by reference */
972  'd', /* alignment - must be the largest! */
973  'x', /* fully TOASTable */
974  -1, /* typmod */
975  0, /* array dimensions for typBaseType */
976  false, /* Type NOT NULL */
977  InvalidOid); /* rowtypes never have a collation */
978 }
#define TYPTYPE_COMPOSITE
Definition: pg_type.h:709
#define TYPCATEGORY_COMPOSITE
Definition: pg_type.h:718
#define InvalidOid
Definition: postgres_ext.h:36
#define DEFAULT_TYPDELIM
Definition: typecmds.h:22
#define NULL
Definition: c.h:226
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 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
List* AddRelationNewConstraints ( Relation  rel,
List newColDefaults,
List newConstraints,
bool  allow_merge,
bool  is_local,
bool  is_internal 
)

Definition at line 2186 of file heap.c.

References addRangeTableEntryForRelation(), addRTEtoQuery(), Assert, RawColumnDefault::attnum, CookedConstraint::attnum, tupleDesc::attrs, ChooseConstraintName(), Constraint::conname, CookedConstraint::conoid, tupleDesc::constr, CONSTR_CHECK, CONSTR_DEFAULT, CookedConstraint::contype, Constraint::contype, cookConstraint(), cookDefault(), Constraint::cooked_expr, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, CookedConstraint::expr, get_attname(), CookedConstraint::inhcount, Constraint::initially_valid, CookedConstraint::is_local, CookedConstraint::is_no_inherit, Constraint::is_no_inherit, IsA, lappend(), lfirst, linitial, list_length(), list_union(), make_parsestate(), MergeWithExistingConstraint(), CookedConstraint::name, NameStr, NIL, NULL, tupleConstr::num_check, palloc(), pull_var_clause(), RawColumnDefault::raw_default, Constraint::raw_expr, RelationData::rd_att, RelationGetDescr, RelationGetNamespace, RelationGetRelationName, RelationGetRelid, SetRelationNumChecks(), CookedConstraint::skip_validation, Constraint::skip_validation, StoreAttrDefault(), StoreRelCheck(), and stringToNode().

Referenced by ATAddCheckConstraint(), ATExecAddColumn(), ATExecColumnDefault(), and DefineRelation().

2192 {
2193  List *cookedConstraints = NIL;
2195  TupleConstr *oldconstr;
2196  int numoldchecks;
2197  ParseState *pstate;
2198  RangeTblEntry *rte;
2199  int numchecks;
2200  List *checknames;
2201  ListCell *cell;
2202  Node *expr;
2203  CookedConstraint *cooked;
2204 
2205  /*
2206  * Get info about existing constraints.
2207  */
2208  tupleDesc = RelationGetDescr(rel);
2209  oldconstr = tupleDesc->constr;
2210  if (oldconstr)
2211  numoldchecks = oldconstr->num_check;
2212  else
2213  numoldchecks = 0;
2214 
2215  /*
2216  * Create a dummy ParseState and insert the target relation as its sole
2217  * rangetable entry. We need a ParseState for transformExpr.
2218  */
2219  pstate = make_parsestate(NULL);
2220  rte = addRangeTableEntryForRelation(pstate,
2221  rel,
2222  NULL,
2223  false,
2224  true);
2225  addRTEtoQuery(pstate, rte, true, true, true);
2226 
2227  /*
2228  * Process column default expressions.
2229  */
2230  foreach(cell, newColDefaults)
2231  {
2232  RawColumnDefault *colDef = (RawColumnDefault *) lfirst(cell);
2233  Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
2234  Oid defOid;
2235 
2236  expr = cookDefault(pstate, colDef->raw_default,
2237  atp->atttypid, atp->atttypmod,
2238  NameStr(atp->attname));
2239 
2240  /*
2241  * If the expression is just a NULL constant, we do not bother to make
2242  * an explicit pg_attrdef entry, since the default behavior is
2243  * equivalent.
2244  *
2245  * Note a nonobvious property of this test: if the column is of a
2246  * domain type, what we'll get is not a bare null Const but a
2247  * CoerceToDomain expr, so we will not discard the default. This is
2248  * critical because the column default needs to be retained to
2249  * override any default that the domain might have.
2250  */
2251  if (expr == NULL ||
2252  (IsA(expr, Const) &&((Const *) expr)->constisnull))
2253  continue;
2254 
2255  defOid = StoreAttrDefault(rel, colDef->attnum, expr, is_internal);
2256 
2257  cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2258  cooked->contype = CONSTR_DEFAULT;
2259  cooked->conoid = defOid;
2260  cooked->name = NULL;
2261  cooked->attnum = colDef->attnum;
2262  cooked->expr = expr;
2263  cooked->skip_validation = false;
2264  cooked->is_local = is_local;
2265  cooked->inhcount = is_local ? 0 : 1;
2266  cooked->is_no_inherit = false;
2267  cookedConstraints = lappend(cookedConstraints, cooked);
2268  }
2269 
2270  /*
2271  * Process constraint expressions.
2272  */
2273  numchecks = numoldchecks;
2274  checknames = NIL;
2275  foreach(cell, newConstraints)
2276  {
2277  Constraint *cdef = (Constraint *) lfirst(cell);
2278  char *ccname;
2279  Oid constrOid;
2280 
2281  if (cdef->contype != CONSTR_CHECK)
2282  continue;
2283 
2284  if (cdef->raw_expr != NULL)
2285  {
2286  Assert(cdef->cooked_expr == NULL);
2287 
2288  /*
2289  * Transform raw parsetree to executable expression, and verify
2290  * it's valid as a CHECK constraint.
2291  */
2292  expr = cookConstraint(pstate, cdef->raw_expr,
2294  }
2295  else
2296  {
2297  Assert(cdef->cooked_expr != NULL);
2298 
2299  /*
2300  * Here, we assume the parser will only pass us valid CHECK
2301  * expressions, so we do no particular checking.
2302  */
2303  expr = stringToNode(cdef->cooked_expr);
2304  }
2305 
2306  /*
2307  * Check name uniqueness, or generate a name if none was given.
2308  */
2309  if (cdef->conname != NULL)
2310  {
2311  ListCell *cell2;
2312 
2313  ccname = cdef->conname;
2314  /* Check against other new constraints */
2315  /* Needed because we don't do CommandCounterIncrement in loop */
2316  foreach(cell2, checknames)
2317  {
2318  if (strcmp((char *) lfirst(cell2), ccname) == 0)
2319  ereport(ERROR,
2321  errmsg("check constraint \"%s\" already exists",
2322  ccname)));
2323  }
2324 
2325  /* save name for future checks */
2326  checknames = lappend(checknames, ccname);
2327 
2328  /*
2329  * Check against pre-existing constraints. If we are allowed to
2330  * merge with an existing constraint, there's no more to do here.
2331  * (We omit the duplicate constraint from the result, which is
2332  * what ATAddCheckConstraint wants.)
2333  */
2334  if (MergeWithExistingConstraint(rel, ccname, expr,
2335  allow_merge, is_local,
2336  cdef->initially_valid,
2337  cdef->is_no_inherit))
2338  continue;
2339  }
2340  else
2341  {
2342  /*
2343  * When generating a name, we want to create "tab_col_check" for a
2344  * column constraint and "tab_check" for a table constraint. We
2345  * no longer have any info about the syntactic positioning of the
2346  * constraint phrase, so we approximate this by seeing whether the
2347  * expression references more than one column. (If the user
2348  * played by the rules, the result is the same...)
2349  *
2350  * Note: pull_var_clause() doesn't descend into sublinks, but we
2351  * eliminated those above; and anyway this only needs to be an
2352  * approximate answer.
2353  */
2354  List *vars;
2355  char *colname;
2356 
2357  vars = pull_var_clause(expr, 0);
2358 
2359  /* eliminate duplicates */
2360  vars = list_union(NIL, vars);
2361 
2362  if (list_length(vars) == 1)
2363  colname = get_attname(RelationGetRelid(rel),
2364  ((Var *) linitial(vars))->varattno);
2365  else
2366  colname = NULL;
2367 
2369  colname,
2370  "check",
2371  RelationGetNamespace(rel),
2372  checknames);
2373 
2374  /* save name for future checks */
2375  checknames = lappend(checknames, ccname);
2376  }
2377 
2378  /*
2379  * OK, store it.
2380  */
2381  constrOid =
2382  StoreRelCheck(rel, ccname, expr, cdef->initially_valid, is_local,
2383  is_local ? 0 : 1, cdef->is_no_inherit, is_internal);
2384 
2385  numchecks++;
2386 
2387  cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2388  cooked->contype = CONSTR_CHECK;
2389  cooked->conoid = constrOid;
2390  cooked->name = ccname;
2391  cooked->attnum = 0;
2392  cooked->expr = expr;
2393  cooked->skip_validation = cdef->skip_validation;
2394  cooked->is_local = is_local;
2395  cooked->inhcount = is_local ? 0 : 1;
2396  cooked->is_no_inherit = cdef->is_no_inherit;
2397  cookedConstraints = lappend(cookedConstraints, cooked);
2398  }
2399 
2400  /*
2401  * Update the count of constraints in the relation's pg_class tuple. We do
2402  * this even if there was no change, in order to ensure that an SI update
2403  * message is sent out for the pg_class tuple, which will force other
2404  * backends to rebuild their relcache entries for the rel. (This is
2405  * critical if we added defaults but not constraints.)
2406  */
2407  SetRelationNumChecks(rel, numchecks);
2408 
2409  return cookedConstraints;
2410 }
#define NIL
Definition: pg_list.h:69
char * ChooseConstraintName(const char *name1, const char *name2, const char *label, Oid namespaceid, List *others)
void * stringToNode(char *str)
Definition: read.c:38
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
static void SetRelationNumChecks(Relation rel, int numchecks)
Definition: heap.c:2573
bool is_no_inherit
Definition: heap.h:38
AttrNumber attnum
Definition: heap.h:24
Node * cookDefault(ParseState *pstate, Node *raw_default, Oid atttypid, int32 atttypmod, char *attname)
Definition: heap.c:2616
#define RelationGetDescr(relation)
Definition: rel.h:425
static Oid StoreRelCheck(Relation rel, char *ccname, Node *expr, bool is_validated, bool is_local, int inhcount, bool is_no_inherit, bool is_internal)
Definition: heap.c:1999
Node * raw_expr
Definition: parsenodes.h:1981
static Node * cookConstraint(ParseState *pstate, Node *raw_constraint, char *relname)
Definition: heap.c:2687
Form_pg_attribute * attrs
Definition: tupdesc.h:74
Definition: nodes.h:508
int errcode(int sqlerrcode)
Definition: elog.c:575
List * pull_var_clause(Node *node, int flags)
Definition: var.c:535
List * list_union(const List *list1, const List *list2)
Definition: list.c:697
char * conname
Definition: parsenodes.h:1974
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:141
char * get_attname(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:774
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
AttrNumber attnum
Definition: heap.h:33
#define linitial(l)
Definition: pg_list.h:110
#define ERROR
Definition: elog.h:43
static bool MergeWithExistingConstraint(Relation rel, char *ccname, Node *expr, bool allow_merge, bool is_local, bool is_initially_valid, bool is_no_inherit)
Definition: heap.c:2423
int inhcount
Definition: heap.h:37
#define RelationGetRelationName(relation)
Definition: rel.h:433
Node * raw_default
Definition: heap.h:25
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
bool skip_validation
Definition: heap.h:35
ConstrType contype
Definition: heap.h:30
#define ereport(elevel, rest)
Definition: elog.h:122
void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
List * lappend(List *list, void *datum)
Definition: list.c:128
TupleDesc rd_att
Definition: rel.h:114
bool is_no_inherit
Definition: parsenodes.h:1980
bool initially_valid
Definition: parsenodes.h:2010
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define lfirst(lc)
Definition: pg_list.h:106
TupleConstr * constr
Definition: tupdesc.h:76
static int list_length(const List *l)
Definition: pg_list.h:89
RangeTblEntry * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, Alias *alias, bool inh, bool inFromCl)
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
Oid conoid
Definition: heap.h:31
#define NameStr(name)
Definition: c.h:495
ConstrType contype
Definition: parsenodes.h:1971
Node * expr
Definition: heap.h:34
uint16 num_check
Definition: tupdesc.h:42
char * cooked_expr
Definition: parsenodes.h:1982
Oid StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr, bool is_internal)
Definition: heap.c:1886
Definition: regcomp.c:226
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:34
Definition: pg_list.h:45
bool skip_validation
Definition: parsenodes.h:2009
char * name
Definition: heap.h:32
#define RelationGetRelid(relation)
Definition: rel.h:413
bool is_local
Definition: heap.h:36
#define RelationGetNamespace(relation)
Definition: rel.h:440
void CheckAttributeNamesTypes ( TupleDesc  tupdesc,
char  relkind,
bool  allow_system_table_mods 
)

Definition at line 407 of file heap.c.

References tupleDesc::attrs, CheckAttributeType(), ereport, errcode(), errmsg(), ERROR, i, MaxHeapAttributeNumber, NameStr, tupleDesc::natts, NIL, NULL, RELKIND_COMPOSITE_TYPE, RELKIND_VIEW, SystemAttributeByName(), and tupleDesc::tdhasoid.

Referenced by addRangeTableEntryForFunction(), and heap_create_with_catalog().

409 {
410  int i;
411  int j;
412  int natts = tupdesc->natts;
413 
414  /* Sanity check on column count */
415  if (natts < 0 || natts > MaxHeapAttributeNumber)
416  ereport(ERROR,
417  (errcode(ERRCODE_TOO_MANY_COLUMNS),
418  errmsg("tables can have at most %d columns",
419  MaxHeapAttributeNumber)));
420 
421  /*
422  * first check for collision with system attribute names
423  *
424  * Skip this for a view or type relation, since those don't have system
425  * attributes.
426  */
427  if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
428  {
429  for (i = 0; i < natts; i++)
430  {
431  if (SystemAttributeByName(NameStr(tupdesc->attrs[i]->attname),
432  tupdesc->tdhasoid) != NULL)
433  ereport(ERROR,
434  (errcode(ERRCODE_DUPLICATE_COLUMN),
435  errmsg("column name \"%s\" conflicts with a system column name",
436  NameStr(tupdesc->attrs[i]->attname))));
437  }
438  }
439 
440  /*
441  * next check for repeated attribute names
442  */
443  for (i = 1; i < natts; i++)
444  {
445  for (j = 0; j < i; j++)
446  {
447  if (strcmp(NameStr(tupdesc->attrs[j]->attname),
448  NameStr(tupdesc->attrs[i]->attname)) == 0)
449  ereport(ERROR,
450  (errcode(ERRCODE_DUPLICATE_COLUMN),
451  errmsg("column name \"%s\" specified more than once",
452  NameStr(tupdesc->attrs[j]->attname))));
453  }
454  }
455 
456  /*
457  * next check the attribute types
458  */
459  for (i = 0; i < natts; i++)
460  {
461  CheckAttributeType(NameStr(tupdesc->attrs[i]->attname),
462  tupdesc->attrs[i]->atttypid,
463  tupdesc->attrs[i]->attcollation,
464  NIL, /* assume we're creating a new rowtype */
465  allow_system_table_mods);
466  }
467 }
#define NIL
Definition: pg_list.h:69
bool tdhasoid
Definition: tupdesc.h:79
Form_pg_attribute * attrs
Definition: tupdesc.h:74
Form_pg_attribute SystemAttributeByName(const char *attname, bool relhasoids)
Definition: heap.c:212
int errcode(int sqlerrcode)
Definition: elog.c:575
int natts
Definition: tupdesc.h:73
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:165
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
void CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation, List *containing_rowtypes, bool allow_system_table_mods)
Definition: heap.c:485
#define MaxHeapAttributeNumber
Definition: htup_details.h:47
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_VIEW
Definition: pg_class.h:164
int i
#define NameStr(name)
Definition: c.h:495
void CheckAttributeType ( const char *  attname,
Oid  atttypid,
Oid  attcollation,
List containing_rowtypes,
bool  allow_system_table_mods 
)

Definition at line 485 of file heap.c.

References AccessShareLock, ANYARRAYOID, tupleDesc::attrs, CheckAttributeType(), ereport, errcode(), errhint(), errmsg(), ERROR, format_type_be(), get_element_type(), get_typ_typrelid(), get_typtype(), getBaseType(), i, lcons_oid(), list_delete_first(), list_member_oid(), NameStr, tupleDesc::natts, OidIsValid, relation_close(), relation_open(), RelationGetDescr, type_is_collatable(), TYPTYPE_COMPOSITE, TYPTYPE_DOMAIN, and TYPTYPE_PSEUDO.

Referenced by ATExecAddColumn(), ATPrepAlterColumnType(), CheckAttributeNamesTypes(), CheckAttributeType(), and ConstructTupleDescriptor().

489 {
490  char att_typtype = get_typtype(atttypid);
491  Oid att_typelem;
492 
493  if (att_typtype == TYPTYPE_PSEUDO)
494  {
495  /*
496  * Refuse any attempt to create a pseudo-type column, except for a
497  * special hack for pg_statistic: allow ANYARRAY when modifying system
498  * catalogs (this allows creating pg_statistic and cloning it during
499  * VACUUM FULL)
500  */
501  if (atttypid != ANYARRAYOID || !allow_system_table_mods)
502  ereport(ERROR,
503  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
504  errmsg("column \"%s\" has pseudo-type %s",
505  attname, format_type_be(atttypid))));
506  }
507  else if (att_typtype == TYPTYPE_DOMAIN)
508  {
509  /*
510  * If it's a domain, recurse to check its base type.
511  */
512  CheckAttributeType(attname, getBaseType(atttypid), attcollation,
513  containing_rowtypes,
514  allow_system_table_mods);
515  }
516  else if (att_typtype == TYPTYPE_COMPOSITE)
517  {
518  /*
519  * For a composite type, recurse into its attributes.
520  */
521  Relation relation;
522  TupleDesc tupdesc;
523  int i;
524 
525  /*
526  * Check for self-containment. Eventually we might be able to allow
527  * this (just return without complaint, if so) but it's not clear how
528  * many other places would require anti-recursion defenses before it
529  * would be safe to allow tables to contain their own rowtype.
530  */
531  if (list_member_oid(containing_rowtypes, atttypid))
532  ereport(ERROR,
533  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
534  errmsg("composite type %s cannot be made a member of itself",
535  format_type_be(atttypid))));
536 
537  containing_rowtypes = lcons_oid(atttypid, containing_rowtypes);
538 
539  relation = relation_open(get_typ_typrelid(atttypid), AccessShareLock);
540 
541  tupdesc = RelationGetDescr(relation);
542 
543  for (i = 0; i < tupdesc->natts; i++)
544  {
545  Form_pg_attribute attr = tupdesc->attrs[i];
546 
547  if (attr->attisdropped)
548  continue;
549  CheckAttributeType(NameStr(attr->attname),
550  attr->atttypid, attr->attcollation,
551  containing_rowtypes,
552  allow_system_table_mods);
553  }
554 
555  relation_close(relation, AccessShareLock);
556 
557  containing_rowtypes = list_delete_first(containing_rowtypes);
558  }
559  else if (OidIsValid((att_typelem = get_element_type(atttypid))))
560  {
561  /*
562  * Must recurse into array types, too, in case they are composite.
563  */
564  CheckAttributeType(attname, att_typelem, attcollation,
565  containing_rowtypes,
566  allow_system_table_mods);
567  }
568 
569  /*
570  * This might not be strictly invalid per SQL standard, but it is pretty
571  * useless, and it cannot be dumped, so we must disallow it.
572  */
573  if (!OidIsValid(attcollation) && type_is_collatable(atttypid))
574  ereport(ERROR,
575  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
576  errmsg("no collation was derived for column \"%s\" with collatable type %s",
577  attname, format_type_be(atttypid)),
578  errhint("Use the COLLATE clause to set the collation explicitly.")));
579 }
#define TYPTYPE_DOMAIN
Definition: pg_type.h:710
int errhint(const char *fmt,...)
Definition: elog.c:987
#define RelationGetDescr(relation)
Definition: rel.h:425
#define TYPTYPE_COMPOSITE
Definition: pg_type.h:709
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2452
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
char get_typtype(Oid typid)
Definition: lsyscache.c:2347
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
List * lcons_oid(Oid datum, List *list)
Definition: list.c:295
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
int natts
Definition: tupdesc.h:73
Oid get_typ_typrelid(Oid typid)
Definition: lsyscache.c:2425
#define ERROR
Definition: elog.h:43
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
#define ereport(elevel, rest)
Definition: elog.h:122
void CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation, List *containing_rowtypes, bool allow_system_table_mods)
Definition: heap.c:485
#define ANYARRAYOID
Definition: pg_type.h:676
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define TYPTYPE_PSEUDO
Definition: pg_type.h:712
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define NameStr(name)
Definition: c.h:495
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2239
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:2774
List * list_delete_first(List *list)
Definition: list.c:666
static Node * cookConstraint ( ParseState pstate,
Node raw_constraint,
char *  relname 
)
static

Definition at line 2687 of file heap.c.

References assign_expr_collations(), coerce_to_boolean(), ereport, errcode(), errmsg(), ERROR, EXPR_KIND_CHECK_CONSTRAINT, list_length(), ParseState::p_rtable, and transformExpr().

Referenced by AddRelationNewConstraints().

2690 {
2691  Node *expr;
2692 
2693  /*
2694  * Transform raw parsetree to executable expression.
2695  */
2696  expr = transformExpr(pstate, raw_constraint, EXPR_KIND_CHECK_CONSTRAINT);
2697 
2698  /*
2699  * Make sure it yields a boolean result.
2700  */
2701  expr = coerce_to_boolean(pstate, expr, "CHECK");
2702 
2703  /*
2704  * Take care of collations.
2705  */
2706  assign_expr_collations(pstate, expr);
2707 
2708  /*
2709  * Make sure no outside relations are referred to (this is probably dead
2710  * code now that add_missing_from is history).
2711  */
2712  if (list_length(pstate->p_rtable) != 1)
2713  ereport(ERROR,
2714  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2715  errmsg("only table \"%s\" can be referenced in check constraint",
2716  relname)));
2717 
2718  return expr;
2719 }
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:147
Definition: nodes.h:508
int errcode(int sqlerrcode)
Definition: elog.c:575
void assign_expr_collations(ParseState *pstate, Node *expr)
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static int list_length(const List *l)
Definition: pg_list.h:89
int errmsg(const char *fmt,...)
Definition: elog.c:797
List * p_rtable
Definition: parse_node.h:168
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)
Node* cookDefault ( ParseState pstate,
Node raw_default,
Oid  atttypid,
int32  atttypmod,
char *  attname 
)

Definition at line 2616 of file heap.c.

References Assert, assign_expr_collations(), COERCE_IMPLICIT_CAST, coerce_to_target_type(), COERCION_ASSIGNMENT, contain_var_clause(), ereport, errcode(), errhint(), errmsg(), ERROR, EXPR_KIND_COLUMN_DEFAULT, exprType(), format_type_be(), NULL, OidIsValid, and transformExpr().

Referenced by AddRelationNewConstraints(), AlterDomainDefault(), and DefineDomain().

2621 {
2622  Node *expr;
2623 
2624  Assert(raw_default != NULL);
2625 
2626  /*
2627  * Transform raw parsetree to executable expression.
2628  */
2629  expr = transformExpr(pstate, raw_default, EXPR_KIND_COLUMN_DEFAULT);
2630 
2631  /*
2632  * Make sure default expr does not refer to any vars (we need this check
2633  * since the pstate includes the target table).
2634  */
2635  if (contain_var_clause(expr))
2636  ereport(ERROR,
2637  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2638  errmsg("cannot use column references in default expression")));
2639 
2640  /*
2641  * transformExpr() should have already rejected subqueries, aggregates,
2642  * window functions, and SRFs, based on the EXPR_KIND_ for a default
2643  * expression.
2644  */
2645 
2646  /*
2647  * Coerce the expression to the correct type and typmod, if given. This
2648  * should match the parser's processing of non-defaulted expressions ---
2649  * see transformAssignedExpr().
2650  */
2651  if (OidIsValid(atttypid))
2652  {
2653  Oid type_id = exprType(expr);
2654 
2655  expr = coerce_to_target_type(pstate, expr, type_id,
2656  atttypid, atttypmod,
2659  -1);
2660  if (expr == NULL)
2661  ereport(ERROR,
2662  (errcode(ERRCODE_DATATYPE_MISMATCH),
2663  errmsg("column \"%s\" is of type %s"
2664  " but default expression is of type %s",
2665  attname,
2666  format_type_be(atttypid),
2667  format_type_be(type_id)),
2668  errhint("You will need to rewrite or cast the expression.")));
2669  }
2670 
2671  /*
2672  * Finally, take care of collations in the finished expression.
2673  */
2674  assign_expr_collations(pstate, expr);
2675 
2676  return expr;
2677 }
int errhint(const char *fmt,...)
Definition: elog.c:987
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:147
Definition: nodes.h:508
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
bool contain_var_clause(Node *node)
Definition: var.c:331
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
void assign_expr_collations(ParseState *pstate, Node *expr)
#define ERROR
Definition: elog.h:43
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
Definition: parse_coerce.c:77
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int errmsg(const char *fmt,...)
Definition: elog.c:797
void DeleteAttributeTuples ( Oid  relid)

Definition at line 1457 of file heap.c.

References Anum_pg_attribute_attrelid, AttributeRelationId, AttributeRelidNumIndexId, BTEqualStrategyNumber, CatalogTupleDelete(), heap_close, heap_open(), NULL, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by heap_drop_with_catalog(), and index_drop().

1458 {
1459  Relation attrel;
1460  SysScanDesc scan;
1461  ScanKeyData key[1];
1462  HeapTuple atttup;
1463 
1464  /* Grab an appropriate lock on the pg_attribute relation */
1466 
1467  /* Use the index to scan only attributes of the target relation */
1468  ScanKeyInit(&key[0],
1470  BTEqualStrategyNumber, F_OIDEQ,
1471  ObjectIdGetDatum(relid));
1472 
1473  scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,
1474  NULL, 1, key);
1475 
1476  /* Delete all the matching tuples */
1477  while ((atttup = systable_getnext(scan)) != NULL)
1478  CatalogTupleDelete(attrel, &atttup->t_self);
1479 
1480  /* Clean up after the scan */
1481  systable_endscan(scan);
1482  heap_close(attrel, RowExclusiveLock);
1483 }
#define AttributeRelidNumIndexId
Definition: indexing.h:94
#define Anum_pg_attribute_attrelid
Definition: pg_attribute.h:192
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define AttributeRelationId
Definition: pg_attribute.h:33
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define NULL
Definition: c.h:226
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void DeleteRelationTuple ( Oid  relid)

Definition at line 1428 of file heap.c.

References CatalogTupleDelete(), elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RelationRelationId, ReleaseSysCache(), RELOID, RowExclusiveLock, SearchSysCache1, and HeapTupleData::t_self.

Referenced by heap_drop_with_catalog(), and index_drop().

1429 {
1430  Relation pg_class_desc;
1431  HeapTuple tup;
1432 
1433  /* Grab an appropriate lock on the pg_class relation */
1434  pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);
1435 
1436  tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1437  if (!HeapTupleIsValid(tup))
1438  elog(ERROR, "cache lookup failed for relation %u", relid);
1439 
1440  /* delete the relation tuple from pg_class, and finish up */
1441  CatalogTupleDelete(pg_class_desc, &tup->t_self);
1442 
1443  ReleaseSysCache(tup);
1444 
1445  heap_close(pg_class_desc, RowExclusiveLock);
1446 }
#define RelationRelationId
Definition: pg_class.h:29
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
void DeleteSystemAttributeTuples ( Oid  relid)

Definition at line 1494 of file heap.c.

References Anum_pg_attribute_attnum, Anum_pg_attribute_attrelid, AttributeRelationId, AttributeRelidNumIndexId, BTEqualStrategyNumber, BTLessEqualStrategyNumber, CatalogTupleDelete(), heap_close, heap_open(), Int16GetDatum, NULL, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by DefineQueryRewrite().

1495 {
1496  Relation attrel;
1497  SysScanDesc scan;
1498  ScanKeyData key[2];
1499  HeapTuple atttup;
1500 
1501  /* Grab an appropriate lock on the pg_attribute relation */
1503 
1504  /* Use the index to scan only system attributes of the target relation */
1505  ScanKeyInit(&key[0],
1507  BTEqualStrategyNumber, F_OIDEQ,
1508  ObjectIdGetDatum(relid));
1509  ScanKeyInit(&key[1],
1511  BTLessEqualStrategyNumber, F_INT2LE,
1512  Int16GetDatum(0));
1513 
1514  scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,
1515  NULL, 2, key);
1516 
1517  /* Delete all the matching tuples */
1518  while ((atttup = systable_getnext(scan)) != NULL)
1519  CatalogTupleDelete(attrel, &atttup->t_self);
1520 
1521  /* Clean up after the scan */
1522  systable_endscan(scan);
1523  heap_close(attrel, RowExclusiveLock);
1524 }
#define AttributeRelidNumIndexId
Definition: indexing.h:94
#define Anum_pg_attribute_attrelid
Definition: pg_attribute.h:192
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define Anum_pg_attribute_attnum
Definition: pg_attribute.h:197
#define Int16GetDatum(X)
Definition: postgres.h:459
#define AttributeRelationId
Definition: pg_attribute.h:33
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
#define BTLessEqualStrategyNumber
Definition: stratnum.h:30
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define NULL
Definition: c.h:226
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Relation heap_create ( const char *  relname,
Oid  relnamespace,
Oid  reltablespace,
Oid  relid,
Oid  relfilenode,
TupleDesc  tupDesc,
char  relkind,
char  relpersistence,
bool  shared_relation,
bool  mapped_relation,
bool  allow_system_table_mods 
)

Definition at line 248 of file heap.c.

References Assert, ereport, errcode(), errdetail(), errmsg(), ERROR, get_namespace_name(), InvalidOid, IsNormalProcessingMode, IsSystemNamespace(), IsToastNamespace(), MyDatabaseTableSpace, OidIsValid, RelationData::rd_node, RelationBuildLocalRelation(), RelationCreateStorage(), RelationOpenSmgr, RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_INDEX, RELKIND_SEQUENCE, and RELKIND_VIEW.

Referenced by heap_create_with_catalog(), and index_create().

259 {
260  bool create_storage;
261  Relation rel;
262 
263  /* The caller must have provided an OID for the relation. */
264  Assert(OidIsValid(relid));
265 
266  /*
267  * Don't allow creating relations in pg_catalog directly, even though it
268  * is allowed to move user defined relations there. Semantics with search
269  * paths including pg_catalog are too confusing for now.
270  *
271  * But allow creating indexes on relations in pg_catalog even if
272  * allow_system_table_mods = off, upper layers already guarantee it's on a
273  * user defined relation, not a system one.
274  */
275  if (!allow_system_table_mods &&
276  ((IsSystemNamespace(relnamespace) && relkind != RELKIND_INDEX) ||
277  IsToastNamespace(relnamespace)) &&
279  ereport(ERROR,
280  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
281  errmsg("permission denied to create \"%s.%s\"",
282  get_namespace_name(relnamespace), relname),
283  errdetail("System catalog modifications are currently disallowed.")));
284 
285  /*
286  * Decide if we need storage or not, and handle a couple other special
287  * cases for particular relkinds.
288  */
289  switch (relkind)
290  {
291  case RELKIND_VIEW:
294  create_storage = false;
295 
296  /*
297  * Force reltablespace to zero if the relation has no physical
298  * storage. This is mainly just for cleanliness' sake.
299  */
300  reltablespace = InvalidOid;
301  break;
302  case RELKIND_SEQUENCE:
303  create_storage = true;
304 
305  /*
306  * Force reltablespace to zero for sequences, since we don't
307  * support moving them around into different tablespaces.
308  */
309  reltablespace = InvalidOid;
310  break;
311  default:
312  create_storage = true;
313  break;
314  }
315 
316  /*
317  * Unless otherwise requested, the physical ID (relfilenode) is initially
318  * the same as the logical ID (OID). When the caller did specify a
319  * relfilenode, it already exists; do not attempt to create it.
320  */
321  if (OidIsValid(relfilenode))
322  create_storage = false;
323  else
324  relfilenode = relid;
325 
326  /*
327  * Never allow a pg_class entry to explicitly specify the database's
328  * default tablespace in reltablespace; force it to zero instead. This
329  * ensures that if the database is cloned with a different default
330  * tablespace, the pg_class entry will still match where CREATE DATABASE
331  * will put the physically copied relation.
332  *
333  * Yes, this is a bit of a hack.
334  */
335  if (reltablespace == MyDatabaseTableSpace)
336  reltablespace = InvalidOid;
337 
338  /*
339  * build the relcache entry.
340  */
341  rel = RelationBuildLocalRelation(relname,
342  relnamespace,
343  tupDesc,
344  relid,
345  relfilenode,
346  reltablespace,
347  shared_relation,
348  mapped_relation,
349  relpersistence,
350  relkind);
351 
352  /*
353  * Have the storage manager create the relation's disk file, if needed.
354  *
355  * We only create the main fork here, other forks will be created on
356  * demand.
357  */
358  if (create_storage)
359  {
360  RelationOpenSmgr(rel);
361  RelationCreateStorage(rel->rd_node, relpersistence);
362  }
363 
364  return rel;
365 }
Relation RelationBuildLocalRelation(const char *relname, Oid relnamespace, TupleDesc tupDesc, Oid relid, Oid relfilenode, Oid reltablespace, bool shared_relation, bool mapped_relation, char relpersistence, char relkind)
Definition: relcache.c:3178
int errcode(int sqlerrcode)
Definition: elog.c:575
bool IsToastNamespace(Oid namespaceId)
Definition: catalog.c:176
#define OidIsValid(objectId)
Definition: c.h:534
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:165
Oid MyDatabaseTableSpace
Definition: globals.c:78
#define RelationOpenSmgr(relation)
Definition: rel.h:457
#define ERROR
Definition: elog.h:43
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
#define IsNormalProcessingMode()
Definition: miscadmin.h:367
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:166
#define ereport(elevel, rest)
Definition: elog.h:122
bool IsSystemNamespace(Oid namespaceId)
Definition: catalog.c:162
#define InvalidOid
Definition: postgres_ext.h:36
RelFileNode rd_node
Definition: rel.h:85
#define Assert(condition)
Definition: c.h:671
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_VIEW
Definition: pg_class.h:164
#define RELKIND_INDEX
Definition: pg_class.h:161
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
void RelationCreateStorage(RelFileNode rnode, char relpersistence)
Definition: storage.c:78
void heap_create_init_fork ( Relation  rel)

Definition at line 1377 of file heap.c.

References INIT_FORKNUM, log_smgrcreate(), RelFileNodeBackend::node, RelationData::rd_smgr, RelationOpenSmgr, SMgrRelationData::smgr_rnode, smgrcreate(), and smgrimmedsync().

Referenced by ExecuteTruncate(), and heap_create_with_catalog().

1378 {
1379  RelationOpenSmgr(rel);
1380  smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
1383 }
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:376
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
#define RelationOpenSmgr(relation)
Definition: rel.h:457
RelFileNodeBackend smgr_rnode
Definition: smgr.h:43
RelFileNode node
Definition: relfilenode.h:74
void log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum)
Definition: storage.c:125
void smgrimmedsync(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:734
Oid heap_create_with_catalog ( const char *  relname,
Oid  relnamespace,
Oid  reltablespace,
Oid  relid,
Oid  reltypeid,
Oid  reloftypeid,
Oid  ownerid,
TupleDesc  tupdesc,
List cooked_constraints,
char  relkind,
char  relpersistence,
bool  shared_relation,
bool  mapped_relation,
bool  oidislocal,
int  oidinhcount,
OnCommitAction  oncommit,
Datum  reloptions,
bool  use_user_acl,
bool  allow_system_table_mods,
bool  is_internal,
ObjectAddress typaddress 
)

Definition at line 1015 of file heap.c.

References ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, aclmembers(), AddNewAttributeTuples(), AddNewRelationTuple(), AddNewRelationType(), Assert, AssignTypeArrayOid(), binary_upgrade_next_heap_pg_class_oid, binary_upgrade_next_toast_pg_class_oid, CheckAttributeNamesTypes(), ObjectAddress::classId, CStringGetDatum, DEFAULT_TYPDELIM, DEPENDENCY_NORMAL, elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errhint(), errmsg(), ERROR, get_relname_relid(), get_user_default_acl(), GetNewRelFileNode(), GetSysCacheOid2, GLOBALTABLESPACE_OID, heap_close, heap_create(), heap_create_init_fork(), heap_open(), InvalidOid, InvokeObjectPostCreateHookArg, IsBinaryUpgrade, IsBootstrapProcessingMode, IsNormalProcessingMode, IsUnderPostmaster, makeArrayTypeName(), moveArrayTypeName(), NamespaceRelationId, NoLock, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, ONCOMMIT_NOOP, pfree(), PointerGetDatum, RelationData::rd_att, recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), register_on_commit_action(), RelationGetRelid, RelationRelationId, RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_MATVIEW, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_TOASTVALUE, RELKIND_VIEW, RELPERSISTENCE_UNLOGGED, RowExclusiveLock, StoreConstraints(), TYPCATEGORY_ARRAY, TypeCreate(), TYPENAMENSP, TypeRelationId, TYPTYPE_BASE, and updateAclDependencies().

Referenced by create_toast_table(), DefineRelation(), and make_new_heap().

1036 {
1037  Relation pg_class_desc;
1038  Relation new_rel_desc;
1039  Acl *relacl;
1040  Oid existing_relid;
1041  Oid old_type_oid;
1042  Oid new_type_oid;
1043  ObjectAddress new_type_addr;
1044  Oid new_array_oid = InvalidOid;
1045 
1046  pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);
1047 
1048  /*
1049  * sanity checks
1050  */
1052 
1053  CheckAttributeNamesTypes(tupdesc, relkind, allow_system_table_mods);
1054 
1055  /*
1056  * This would fail later on anyway, if the relation already exists. But
1057  * by catching it here we can emit a nicer error message.
1058  */
1059  existing_relid = get_relname_relid(relname, relnamespace);
1060  if (existing_relid != InvalidOid)
1061  ereport(ERROR,
1062  (errcode(ERRCODE_DUPLICATE_TABLE),
1063  errmsg("relation \"%s\" already exists", relname)));
1064 
1065  /*
1066  * Since we are going to create a rowtype as well, also check for
1067  * collision with an existing type name. If there is one and it's an
1068  * autogenerated array, we can rename it out of the way; otherwise we can
1069  * at least give a good error message.
1070  */
1071  old_type_oid = GetSysCacheOid2(TYPENAMENSP,
1072  CStringGetDatum(relname),
1073  ObjectIdGetDatum(relnamespace));
1074  if (OidIsValid(old_type_oid))
1075  {
1076  if (!moveArrayTypeName(old_type_oid, relname, relnamespace))
1077  ereport(ERROR,
1079  errmsg("type \"%s\" already exists", relname),
1080  errhint("A relation has an associated type of the same name, "
1081  "so you must use a name that doesn't conflict "
1082  "with any existing type.")));
1083  }
1084 
1085  /*
1086  * Shared relations must be in pg_global (last-ditch check)
1087  */
1088  if (shared_relation && reltablespace != GLOBALTABLESPACE_OID)
1089  elog(ERROR, "shared relations must be placed in pg_global tablespace");
1090 
1091  /*
1092  * Allocate an OID for the relation, unless we were told what to use.
1093  *
1094  * The OID will be the relfilenode as well, so make sure it doesn't
1095  * collide with either pg_class OIDs or existing physical files.
1096  */
1097  if (!OidIsValid(relid))
1098  {
1099  /* Use binary-upgrade override for pg_class.oid/relfilenode? */
1100  if (IsBinaryUpgrade &&
1101  (relkind == RELKIND_RELATION || relkind == RELKIND_SEQUENCE ||
1102  relkind == RELKIND_VIEW || relkind == RELKIND_MATVIEW ||
1103  relkind == RELKIND_COMPOSITE_TYPE || relkind == RELKIND_FOREIGN_TABLE ||
1104  relkind == RELKIND_PARTITIONED_TABLE))
1105  {
1107  ereport(ERROR,
1108  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1109  errmsg("pg_class heap OID value not set when in binary upgrade mode")));
1110 
1113  }
1114  /* There might be no TOAST table, so we have to test for it. */
1115  else if (IsBinaryUpgrade &&
1117  relkind == RELKIND_TOASTVALUE)
1118  {
1121  }
1122  else
1123  relid = GetNewRelFileNode(reltablespace, pg_class_desc,
1124  relpersistence);
1125  }
1126 
1127  /*
1128  * Determine the relation's initial permissions.
1129  */
1130  if (use_user_acl)
1131  {
1132  switch (relkind)
1133  {
1134  case RELKIND_RELATION:
1135  case RELKIND_VIEW:
1136  case RELKIND_MATVIEW:
1137  case RELKIND_FOREIGN_TABLE:
1139  relacl = get_user_default_acl(ACL_OBJECT_RELATION, ownerid,
1140  relnamespace);
1141  break;
1142  case RELKIND_SEQUENCE:
1143  relacl = get_user_default_acl(ACL_OBJECT_SEQUENCE, ownerid,
1144  relnamespace);
1145  break;
1146  default:
1147  relacl = NULL;
1148  break;
1149  }
1150  }
1151  else
1152  relacl = NULL;
1153 
1154  /*
1155  * Create the relcache entry (mostly dummy at this point) and the physical
1156  * disk file. (If we fail further down, it's the smgr's responsibility to
1157  * remove the disk file again.)
1158  */
1159  new_rel_desc = heap_create(relname,
1160  relnamespace,
1161  reltablespace,
1162  relid,
1163  InvalidOid,
1164  tupdesc,
1165  relkind,
1166  relpersistence,
1167  shared_relation,
1168  mapped_relation,
1169  allow_system_table_mods);
1170 
1171  Assert(relid == RelationGetRelid(new_rel_desc));
1172 
1173  /*
1174  * Decide whether to create an array type over the relation's rowtype. We
1175  * do not create any array types for system catalogs (ie, those made
1176  * during initdb). We do not create them where the use of a relation as
1177  * such is an implementation detail: toast tables, sequences and indexes.
1178  */
1179  if (IsUnderPostmaster && (relkind == RELKIND_RELATION ||
1180  relkind == RELKIND_VIEW ||
1181  relkind == RELKIND_MATVIEW ||
1182  relkind == RELKIND_FOREIGN_TABLE ||
1183  relkind == RELKIND_COMPOSITE_TYPE ||
1184  relkind == RELKIND_PARTITIONED_TABLE))
1185  new_array_oid = AssignTypeArrayOid();
1186 
1187  /*
1188  * Since defining a relation also defines a complex type, we add a new
1189  * system type corresponding to the new relation. The OID of the type can
1190  * be preselected by the caller, but if reltypeid is InvalidOid, we'll
1191  * generate a new OID for it.
1192  *
1193  * NOTE: we could get a unique-index failure here, in case someone else is
1194  * creating the same type name in parallel but hadn't committed yet when
1195  * we checked for a duplicate name above.
1196  */
1197  new_type_addr = AddNewRelationType(relname,
1198  relnamespace,
1199  relid,
1200  relkind,
1201  ownerid,
1202  reltypeid,
1203  new_array_oid);
1204  new_type_oid = new_type_addr.objectId;
1205  if (typaddress)
1206  *typaddress = new_type_addr;
1207 
1208  /*
1209  * Now make the array type if wanted.
1210  */
1211  if (OidIsValid(new_array_oid))
1212  {
1213  char *relarrayname;
1214 
1215  relarrayname = makeArrayTypeName(relname, relnamespace);
1216 
1217  TypeCreate(new_array_oid, /* force the type's OID to this */
1218  relarrayname, /* Array type name */
1219  relnamespace, /* Same namespace as parent */
1220  InvalidOid, /* Not composite, no relationOid */
1221  0, /* relkind, also N/A here */
1222  ownerid, /* owner's ID */
1223  -1, /* Internal size (varlena) */
1224  TYPTYPE_BASE, /* Not composite - typelem is */
1225  TYPCATEGORY_ARRAY, /* type-category (array) */
1226  false, /* array types are never preferred */
1227  DEFAULT_TYPDELIM, /* default array delimiter */
1228  F_ARRAY_IN, /* array input proc */
1229  F_ARRAY_OUT, /* array output proc */
1230  F_ARRAY_RECV, /* array recv (bin) proc */
1231  F_ARRAY_SEND, /* array send (bin) proc */
1232  InvalidOid, /* typmodin procedure - none */
1233  InvalidOid, /* typmodout procedure - none */
1234  F_ARRAY_TYPANALYZE, /* array analyze procedure */
1235  new_type_oid, /* array element type - the rowtype */
1236  true, /* yes, this is an array type */
1237  InvalidOid, /* this has no array type */
1238  InvalidOid, /* domain base type - irrelevant */
1239  NULL, /* default value - none */
1240  NULL, /* default binary representation */
1241  false, /* passed by reference */
1242  'd', /* alignment - must be the largest! */
1243  'x', /* fully TOASTable */
1244  -1, /* typmod */
1245  0, /* array dimensions for typBaseType */
1246  false, /* Type NOT NULL */
1247  InvalidOid); /* rowtypes never have a collation */
1248 
1249  pfree(relarrayname);
1250  }
1251 
1252  /*
1253  * now create an entry in pg_class for the relation.
1254  *
1255  * NOTE: we could get a unique-index failure here, in case someone else is
1256  * creating the same relation name in parallel but hadn't committed yet
1257  * when we checked for a duplicate name above.
1258  */
1259  AddNewRelationTuple(pg_class_desc,
1260  new_rel_desc,
1261  relid,
1262  new_type_oid,
1263  reloftypeid,
1264  ownerid,
1265  relkind,
1266  PointerGetDatum(relacl),
1267  reloptions);
1268 
1269  /*
1270  * now add tuples to pg_attribute for the attributes in our new relation.
1271  */
1272  AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind,
1273  oidislocal, oidinhcount);
1274 
1275  /*
1276  * Make a dependency link to force the relation to be deleted if its
1277  * namespace is. Also make a dependency link to its owner, as well as
1278  * dependencies for any roles mentioned in the default ACL.
1279  *
1280  * For composite types, these dependencies are tracked for the pg_type
1281  * entry, so we needn't record them here. Likewise, TOAST tables don't
1282  * need a namespace dependency (they live in a pinned namespace) nor an
1283  * owner dependency (they depend indirectly through the parent table), nor
1284  * should they have any ACL entries. The same applies for extension
1285  * dependencies.
1286  *
1287  * Also, skip this in bootstrap mode, since we don't make dependencies
1288  * while bootstrapping.
1289  */
1290  if (relkind != RELKIND_COMPOSITE_TYPE &&
1291  relkind != RELKIND_TOASTVALUE &&
1293  {
1294  ObjectAddress myself,
1295  referenced;
1296 
1297  myself.classId = RelationRelationId;
1298  myself.objectId = relid;
1299  myself.objectSubId = 0;
1300  referenced.classId = NamespaceRelationId;
1301  referenced.objectId = relnamespace;
1302  referenced.objectSubId = 0;
1303  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1304 
1306 
1307  recordDependencyOnCurrentExtension(&myself, false);
1308 
1309  if (reloftypeid)
1310  {
1311  referenced.classId = TypeRelationId;
1312  referenced.objectId = reloftypeid;
1313  referenced.objectSubId = 0;
1314  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1315  }
1316 
1317  if (relacl != NULL)
1318  {
1319  int nnewmembers;
1320  Oid *newmembers;
1321 
1322  nnewmembers = aclmembers(relacl, &newmembers);
1324  ownerid,
1325  0, NULL,
1326  nnewmembers, newmembers);
1327  }
1328  }
1329 
1330  /* Post creation hook for new relation */
1331  InvokeObjectPostCreateHookArg(RelationRelationId, relid, 0, is_internal);
1332 
1333  /*
1334  * Store any supplied constraints and defaults.
1335  *
1336  * NB: this may do a CommandCounterIncrement and rebuild the relcache
1337  * entry, so the relation must be valid and self-consistent at this point.
1338  * In particular, there are not yet constraints and defaults anywhere.
1339  */
1340  StoreConstraints(new_rel_desc, cooked_constraints, is_internal);
1341 
1342  /*
1343  * If there's a special on-commit action, remember it
1344  */
1345  if (oncommit != ONCOMMIT_NOOP)
1346  register_on_commit_action(relid, oncommit);
1347 
1348  if (relpersistence == RELPERSISTENCE_UNLOGGED)
1349  {
1350  Assert(relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW ||
1351  relkind == RELKIND_TOASTVALUE ||
1352  relkind == RELKIND_PARTITIONED_TABLE);
1353 
1354  heap_create_init_fork(new_rel_desc);
1355  }
1356 
1357  /*
1358  * ok, the relation has been cataloged, so close our relations and return
1359  * the OID of the newly created relation.
1360  */
1361  heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */
1362  heap_close(pg_class_desc, RowExclusiveLock);
1363 
1364  return relid;
1365 }
void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:420
#define NamespaceRelationId
Definition: pg_namespace.h:34
void register_on_commit_action(Oid relid, OnCommitAction action)
Definition: tablecmds.c:12373
char * makeArrayTypeName(const char *typeName, Oid typeNamespace)
Definition: pg_type.c:747
int errhint(const char *fmt,...)
Definition: elog.c:987
#define RELPERSISTENCE_UNLOGGED
Definition: pg_class.h:171
void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, bool allow_system_table_mods)
Definition: heap.c:407
Oid binary_upgrade_next_heap_pg_class_oid
Definition: heap.c:84
#define TYPTYPE_BASE
Definition: pg_type.h:708
Oid binary_upgrade_next_toast_pg_class_oid
Definition: heap.c:85
#define PointerGetDatum(X)
Definition: postgres.h:564
#define RelationRelationId
Definition: pg_class.h:29
#define RELKIND_MATVIEW
Definition: pg_class.h:167
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
int errcode(int sqlerrcode)
Definition: elog.c:575
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
#define heap_close(r, l)
Definition: heapam.h:97
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:158
unsigned int Oid
Definition: postgres_ext.h:31
#define TypeRelationId
Definition: pg_type.h:34
#define OidIsValid(objectId)
Definition: c.h:534
bool IsBinaryUpgrade
Definition: globals.c:101
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:165
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:178
void pfree(void *pointer)
Definition: mcxt.c:992
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Relation heap_create(const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, Oid relfilenode, TupleDesc tupDesc, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, bool allow_system_table_mods)
Definition: heap.c:248
#define TYPCATEGORY_ARRAY
Definition: pg_type.h:716
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1651
#define NoLock
Definition: lockdefs.h:34
bool moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace)
Definition: pg_type.c:813
#define IsNormalProcessingMode()
Definition: miscadmin.h:367
void heap_create_init_fork(Relation rel)
Definition: heap.c:1377
bool IsUnderPostmaster
Definition: globals.c:100
#define RowExclusiveLock
Definition: lockdefs.h:38
Acl * get_user_default_acl(GrantObjectType objtype, Oid ownerId, Oid nsp_oid)
Definition: aclchk.c:5194
#define CStringGetDatum(X)
Definition: postgres.h:586
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:938
static void StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal)
Definition: heap.c:2116
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:166
#define ereport(elevel, rest)
Definition: elog.h:122
static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relkind, bool oidislocal, int oidinhcount)
Definition: heap.c:650
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
#define RELKIND_TOASTVALUE
Definition: pg_class.h:163
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
Definition: objectaccess.h:147
TupleDesc rd_att
Definition: rel.h:114
#define InvalidOid
Definition: postgres_ext.h:36
#define DEFAULT_TYPDELIM
Definition: typecmds.h:22
int aclmembers(const Acl *acl, Oid **roleids)
Definition: acl.c:1457
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:139
Oid GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence)
Definition: catalog.c:386
Oid AssignTypeArrayOid(void)
Definition: typecmds.c:2027
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, Datum relacl, Datum reloptions)
Definition: heap.c:839
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_VIEW
Definition: pg_class.h:164
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 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
#define elog
Definition: elog.h:219
#define RELKIND_RELATION
Definition: pg_class.h:160
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:34
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
#define RelationGetRelid(relation)
Definition: rel.h:413
void heap_drop_with_catalog ( Oid  relid)

Definition at line 1750 of file heap.c.

References AccessExclusiveLock, CacheInvalidateRelcache(), CatalogTupleDelete(), CheckTableForSerializableConflictIn(), CheckTableNotInUse(), DeleteAttributeTuples(), DeleteRelationTuple(), elog, ERROR, FOREIGNTABLEREL, ForeignTableRelationId, get_partition_parent(), heap_close, heap_open(), HeapTupleIsValid, NoLock, NULL, ObjectIdGetDatum, RelationData::rd_rel, relation_close(), relation_open(), RelationDropStorage(), RelationForgetRelation(), RelationRemoveInheritance(), ReleaseSysCache(), RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_PARTITIONED_TABLE, RELKIND_VIEW, remove_on_commit_action(), RemovePartitionKeyByRelId(), RemoveStatistics(), RowExclusiveLock, SearchSysCache1, and HeapTupleData::t_self.

Referenced by doDeletion().

1751 {
1752  Relation rel;
1753  Oid parentOid;
1754  Relation parent = NULL;
1755 
1756  /*
1757  * Open and lock the relation.
1758  */
1759  rel = relation_open(relid, AccessExclusiveLock);
1760 
1761  /*
1762  * If the relation is a partition, we must grab exclusive lock on its
1763  * parent because we need to update its partition descriptor. We must take
1764  * a table lock strong enough to prevent all queries on the parent from
1765  * proceeding until we commit and send out a shared-cache-inval notice
1766  * that will make them update their partition descriptor. Sometimes, doing
1767  * this is cycles spent uselessly, especially if the parent will be
1768  * dropped as part of the same command anyway.
1769  */
1770  if (rel->rd_rel->relispartition)
1771  {
1772  parentOid = get_partition_parent(relid);
1773  parent = heap_open(parentOid, AccessExclusiveLock);
1774  }
1775 
1776  /*
1777  * There can no longer be anyone *else* touching the relation, but we
1778  * might still have open queries or cursors, or pending trigger events, in
1779  * our own session.
1780  */
1781  CheckTableNotInUse(rel, "DROP TABLE");
1782 
1783  /*
1784  * This effectively deletes all rows in the table, and may be done in a
1785  * serializable transaction. In that case we must record a rw-conflict in
1786  * to this transaction from each transaction holding a predicate lock on
1787  * the table.
1788  */
1790 
1791  /*
1792  * Delete pg_foreign_table tuple first.
1793  */
1794  if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1795  {
1796  Relation rel;
1797  HeapTuple tuple;
1798 
1800 
1802  if (!HeapTupleIsValid(tuple))
1803  elog(ERROR, "cache lookup failed for foreign table %u", relid);
1804 
1805  CatalogTupleDelete(rel, &tuple->t_self);
1806 
1807  ReleaseSysCache(tuple);
1809  }
1810 
1811  /*
1812  * If a partitioned table, delete the pg_partitioned_table tuple.
1813  */
1814  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1816 
1817  /*
1818  * Schedule unlinking of the relation's physical files at commit.
1819  */
1820  if (rel->rd_rel->relkind != RELKIND_VIEW &&
1821  rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
1822  rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
1823  {
1824  RelationDropStorage(rel);
1825  }
1826 
1827  /*
1828  * Close relcache entry, but *keep* AccessExclusiveLock on the relation
1829  * until transaction commit. This ensures no one else will try to do
1830  * something with the doomed relation.
1831  */
1832  relation_close(rel, NoLock);
1833 
1834  /*
1835  * Forget any ON COMMIT action for the rel
1836  */
1837  remove_on_commit_action(relid);
1838 
1839  /*
1840  * Flush the relation from the relcache. We want to do this before
1841  * starting to remove catalog entries, just to be certain that no relcache
1842  * entry rebuild will happen partway through. (That should not really
1843  * matter, since we don't do CommandCounterIncrement here, but let's be
1844  * safe.)
1845  */
1846  RelationForgetRelation(relid);
1847 
1848  /*
1849  * remove inheritance information
1850  */
1852 
1853  /*
1854  * delete statistics
1855  */
1856  RemoveStatistics(relid, 0);
1857 
1858  /*
1859  * delete attribute tuples
1860  */
1861  DeleteAttributeTuples(relid);
1862 
1863  /*
1864  * delete relation tuple
1865  */
1866  DeleteRelationTuple(relid);
1867 
1868  if (parent)
1869  {
1870  /*
1871  * Invalidate the parent's relcache so that the partition is no longer
1872  * included in its partition descriptor.
1873  */
1874  CacheInvalidateRelcache(parent);
1875  heap_close(parent, NoLock); /* keep the lock */
1876  }
1877 }
void remove_on_commit_action(Oid relid)
Definition: tablecmds.c:12404
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
void RelationForgetRelation(Oid rid)
Definition: relcache.c:2679
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:113
unsigned int Oid
Definition: postgres_ext.h:31
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:165
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Oid get_partition_parent(Oid relid)
Definition: partition.c:858
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:166
void CheckTableNotInUse(Relation rel, const char *stmt)
Definition: tablecmds.c:2950
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
void RelationDropStorage(Relation rel)
Definition: storage.c:145
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
void DeleteRelationTuple(Oid relid)
Definition: heap.c:1428
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
static void RelationRemoveInheritance(Oid relid)
Definition: heap.c:1395
void CheckTableForSerializableConflictIn(Relation relation)
Definition: predicate.c:4327
void DeleteAttributeTuples(Oid relid)
Definition: heap.c:1457
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1225
void RemoveStatistics(Oid relid, AttrNumber attnum)
Definition: heap.c:2729
#define AccessExclusiveLock
Definition: lockdefs.h:46
void RemovePartitionKeyByRelId(Oid relid)
Definition: heap.c:3180
#define RELKIND_VIEW
Definition: pg_class.h:164
#define ForeignTableRelationId
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
#define elog
Definition: elog.h:219
void heap_truncate ( List relids)

Definition at line 2817 of file heap.c.

References AccessExclusiveLock, heap_close, heap_open(), heap_truncate_check_FKs(), heap_truncate_one_rel(), lappend(), lfirst, lfirst_oid, NIL, and NoLock.

Referenced by PreCommit_on_commit_actions().

2818 {
2819  List *relations = NIL;
2820  ListCell *cell;
2821 
2822  /* Open relations for processing, and grab exclusive access on each */
2823  foreach(cell, relids)
2824  {
2825  Oid rid = lfirst_oid(cell);
2826  Relation rel;
2827 
2828  rel = heap_open(rid, AccessExclusiveLock);
2829  relations = lappend(relations, rel);
2830  }
2831 
2832  /* Don't allow truncate on tables that are referenced by foreign keys */
2833  heap_truncate_check_FKs(relations, true);
2834 
2835  /* OK to do it */
2836  foreach(cell, relations)
2837  {
2838  Relation rel = lfirst(cell);
2839 
2840  /* Truncate the relation */
2841  heap_truncate_one_rel(rel);
2842 
2843  /* Close the relation, but keep exclusive lock on it until commit */
2844  heap_close(rel, NoLock);
2845  }
2846 }
#define NIL
Definition: pg_list.h:69
void heap_truncate_one_rel(Relation rel)
Definition: heap.c:2858
void heap_truncate_check_FKs(List *relations, bool tempTables)
Definition: heap.c:2895
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
#define NoLock
Definition: lockdefs.h:34
List * lappend(List *list, void *datum)
Definition: list.c:128
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define lfirst(lc)
Definition: pg_list.h:106
#define AccessExclusiveLock
Definition: lockdefs.h:46
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
void heap_truncate_check_FKs ( List relations,
bool  tempTables 
)

Definition at line 2895 of file heap.c.

References ereport, errcode(), errdetail(), errhint(), errmsg(), ERROR, get_rel_name(), heap_truncate_find_FKs(), lappend_oid(), lfirst, lfirst_oid, list_make1_oid, list_member_oid(), NIL, RelationData::rd_rel, and RelationGetRelid.

Referenced by ExecuteTruncate(), and heap_truncate().

2896 {
2897  List *oids = NIL;
2898  List *dependents;
2899  ListCell *cell;
2900 
2901  /*
2902  * Build a list of OIDs of the interesting relations.
2903  *
2904  * If a relation has no triggers, then it can neither have FKs nor be
2905  * referenced by a FK from another table, so we can ignore it.
2906  */
2907  foreach(cell, relations)
2908  {
2909  Relation rel = lfirst(cell);
2910 
2911  if (rel->rd_rel->relhastriggers)
2912  oids = lappend_oid(oids, RelationGetRelid(rel));
2913  }
2914 
2915  /*
2916  * Fast path: if no relation has triggers, none has FKs either.
2917  */
2918  if (oids == NIL)
2919  return;
2920 
2921  /*
2922  * Otherwise, must scan pg_constraint. We make one pass with all the
2923  * relations considered; if this finds nothing, then all is well.
2924  */
2925  dependents = heap_truncate_find_FKs(oids);
2926  if (dependents == NIL)
2927  return;
2928 
2929  /*
2930  * Otherwise we repeat the scan once per relation to identify a particular
2931  * pair of relations to complain about. This is pretty slow, but
2932  * performance shouldn't matter much in a failure path. The reason for
2933  * doing things this way is to ensure that the message produced is not
2934  * dependent on chance row locations within pg_constraint.
2935  */
2936  foreach(cell, oids)
2937  {
2938  Oid relid = lfirst_oid(cell);
2939  ListCell *cell2;
2940 
2941  dependents = heap_truncate_find_FKs(list_make1_oid(relid));
2942 
2943  foreach(cell2, dependents)
2944  {
2945  Oid relid2 = lfirst_oid(cell2);
2946 
2947  if (!list_member_oid(oids, relid2))
2948  {
2949  char *relname = get_rel_name(relid);
2950  char *relname2 = get_rel_name(relid2);
2951 
2952  if (tempTables)
2953  ereport(ERROR,
2954  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2955  errmsg("unsupported ON COMMIT and foreign key combination"),
2956  errdetail("Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting.",
2957  relname2, relname)));
2958  else
2959  ereport(ERROR,
2960  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2961  errmsg("cannot truncate a table referenced in a foreign key constraint"),
2962  errdetail("Table \"%s\" references \"%s\".",
2963  relname2, relname),
2964  errhint("Truncate table \"%s\" at the same time, "
2965  "or use TRUNCATE ... CASCADE.",
2966  relname2)));
2967  }
2968  }
2969  }
2970 }
#define NIL
Definition: pg_list.h:69
int errhint(const char *fmt,...)
Definition: elog.c:987
int errcode(int sqlerrcode)
Definition: elog.c:575
Form_pg_class rd_rel
Definition: rel.h:113
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
#define list_make1_oid(x1)
Definition: pg_list.h:145
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define lfirst(lc)
Definition: pg_list.h:106
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: pg_list.h:45
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1694
#define RelationGetRelid(relation)
Definition: rel.h:413
List * heap_truncate_find_FKs(List *relationIds)
Definition: heap.c:2987
#define lfirst_oid(lc)
Definition: pg_list.h:108
List* heap_truncate_find_FKs ( List relationIds)

Definition at line 2987 of file heap.c.

References AccessShareLock, CONSTRAINT_FOREIGN, ConstraintRelationId, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, insert_ordered_unique_oid(), InvalidOid, list_member_oid(), NIL, NULL, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by ExecuteTruncate(), and heap_truncate_check_FKs().

2988 {
2989  List *result = NIL;
2990  Relation fkeyRel;
2991  SysScanDesc fkeyScan;
2992  HeapTuple tuple;
2993 
2994  /*
2995  * Must scan pg_constraint. Right now, it is a seqscan because there is
2996  * no available index on confrelid.
2997  */
2999 
3000  fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false,
3001  NULL, 0, NULL);
3002 
3003  while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan)))
3004  {
3006 
3007  /* Not a foreign key */
3008  if (con->contype != CONSTRAINT_FOREIGN)
3009  continue;
3010 
3011  /* Not referencing one of our list of tables */
3012  if (!list_member_oid(relationIds, con->confrelid))
3013  continue;
3014 
3015  /* Add referencer unless already in input or result list */
3016  if (!list_member_oid(relationIds, con->conrelid))
3017  result = insert_ordered_unique_oid(result, con->conrelid);
3018  }
3019 
3020  systable_endscan(fkeyScan);
3021  heap_close(fkeyRel, AccessShareLock);
3022 
3023  return result;
3024 }
#define NIL
Definition: pg_list.h:69
#define CONSTRAINT_FOREIGN
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
static List * insert_ordered_unique_oid(List *list, Oid datum)
Definition: heap.c:3037
#define ConstraintRelationId
Definition: pg_constraint.h:29
Definition: pg_list.h:45
void heap_truncate_one_rel ( Relation  rel)

Definition at line 2858 of file heap.c.

References AccessExclusiveLock, heap_close, heap_open(), NoLock, OidIsValid, RelationData::rd_rel, RelationTruncate(), and RelationTruncateIndexes().

Referenced by ExecuteTruncate(), and heap_truncate().

2859 {
2860  Oid toastrelid;
2861 
2862  /* Truncate the actual file (and discard buffers) */
2863  RelationTruncate(rel, 0);
2864 
2865  /* If the relation has indexes, truncate the indexes too */
2867 
2868  /* If there is a toast table, truncate that too */
2869  toastrelid = rel->rd_rel->reltoastrelid;
2870  if (OidIsValid(toastrelid))
2871  {
2872  Relation toastrel = heap_open(toastrelid, AccessExclusiveLock);
2873 
2874  RelationTruncate(toastrel, 0);
2875  RelationTruncateIndexes(toastrel);
2876  /* keep the lock... */
2877  heap_close(toastrel, NoLock);
2878  }
2879 }
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:113
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define NoLock
Definition: lockdefs.h:34
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define AccessExclusiveLock
Definition: lockdefs.h:46
static void RelationTruncateIndexes(Relation heapRelation)
Definition: heap.c:2776
void RelationTruncate(Relation rel, BlockNumber nblocks)
Definition: storage.c:227
static List * insert_ordered_unique_oid ( List list,
Oid  datum 
)
static

Definition at line 3037 of file heap.c.

References lappend_cell_oid(), lcons_oid(), lfirst_oid, linitial_oid, sort-test::list, list_head(), lnext, NIL, and NULL.

Referenced by heap_truncate_find_FKs().

3038 {
3039  ListCell *prev;
3040 
3041  /* Does the datum belong at the front? */
3042  if (list == NIL || datum < linitial_oid(list))
3043  return lcons_oid(datum, list);
3044  /* Does it match the first entry? */
3045  if (datum == linitial_oid(list))
3046  return list; /* duplicate, so don't insert */
3047  /* No, so find the entry it belongs after */
3048  prev = list_head(list);
3049  for (;;)
3050  {
3051  ListCell *curr = lnext(prev);
3052 
3053  if (curr == NULL || datum < lfirst_oid(curr))
3054  break; /* it belongs after 'prev', before 'curr' */
3055 
3056  if (datum == lfirst_oid(curr))
3057  return list; /* duplicate, so don't insert */
3058 
3059  prev = curr;
3060  }
3061  /* Insert datum into list after 'prev' */
3062  lappend_cell_oid(list, prev, datum);
3063  return list;
3064 }
#define NIL
Definition: pg_list.h:69
List * lcons_oid(Oid datum, List *list)
Definition: list.c:295
ListCell * lappend_cell_oid(List *list, ListCell *prev, Oid datum)
Definition: list.c:235
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
#define lnext(lc)
Definition: pg_list.h:105
#define NULL
Definition: c.h:226
#define linitial_oid(l)
Definition: pg_list.h:112
tuple list
Definition: sort-test.py:11
#define lfirst_oid(lc)
Definition: pg_list.h:108
void InsertPgAttributeTuple ( Relation  pg_attribute_rel,
Form_pg_attribute  new_attribute,
CatalogIndexState  indstate 
)

Definition at line 595 of file heap.c.

References Anum_pg_attribute_attacl, Anum_pg_attribute_attalign, Anum_pg_attribute_attbyval, Anum_pg_attribute_attcacheoff, Anum_pg_attribute_attcollation, Anum_pg_attribute_attfdwoptions, Anum_pg_attribute_atthasdef, Anum_pg_attribute_attinhcount, Anum_pg_attribute_attisdropped, Anum_pg_attribute_attislocal, Anum_pg_attribute_attlen, Anum_pg_attribute_attname, Anum_pg_attribute_attndims, Anum_pg_attribute_attnotnull, Anum_pg_attribute_attnum, Anum_pg_attribute_attoptions, Anum_pg_attribute_attrelid, Anum_pg_attribute_attstattarget, Anum_pg_attribute_attstorage, Anum_pg_attribute_atttypid, Anum_pg_attribute_atttypmod, BoolGetDatum, CatalogTupleInsert(), CatalogTupleInsertWithInfo(), CharGetDatum, heap_form_tuple(), heap_freetuple(), Int16GetDatum, Int32GetDatum, NameGetDatum, Natts_pg_attribute, NULL, ObjectIdGetDatum, RelationGetDescr, and values.

Referenced by AddNewAttributeTuples(), AppendAttributeTuples(), and ATExecAddColumn().

598 {
600  bool nulls[Natts_pg_attribute];
601  HeapTuple tup;
602 
603  /* This is a tad tedious, but way cleaner than what we used to do... */
604  memset(values, 0, sizeof(values));
605  memset(nulls, false, sizeof(nulls));
606 
607  values[Anum_pg_attribute_attrelid - 1] = ObjectIdGetDatum(new_attribute->attrelid);
608  values[Anum_pg_attribute_attname - 1] = NameGetDatum(&new_attribute->attname);
609  values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(new_attribute->atttypid);
610  values[Anum_pg_attribute_attstattarget - 1] = Int32GetDatum(new_attribute->attstattarget);
611  values[Anum_pg_attribute_attlen - 1] = Int16GetDatum(new_attribute->attlen);
612  values[Anum_pg_attribute_attnum - 1] = Int16GetDatum(new_attribute->attnum);
613  values[Anum_pg_attribute_attndims - 1] = Int32GetDatum(new_attribute->attndims);
614  values[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(new_attribute->attcacheoff);
615  values[Anum_pg_attribute_atttypmod - 1] = Int32GetDatum(new_attribute->atttypmod);
616  values[Anum_pg_attribute_attbyval - 1] = BoolGetDatum(new_attribute->attbyval);
617  values[Anum_pg_attribute_attstorage - 1] = CharGetDatum(new_attribute->attstorage);
618  values[Anum_pg_attribute_attalign - 1] = CharGetDatum(new_attribute->attalign);
619  values[Anum_pg_attribute_attnotnull - 1] = BoolGetDatum(new_attribute->attnotnull);
620  values[Anum_pg_attribute_atthasdef - 1] = BoolGetDatum(new_attribute->atthasdef);
621  values[Anum_pg_attribute_attisdropped - 1] = BoolGetDatum(new_attribute->attisdropped);
622  values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(new_attribute->attislocal);
623  values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(new_attribute->attinhcount);
624  values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(new_attribute->attcollation);
625 
626  /* start out with empty permissions and empty options */
627  nulls[Anum_pg_attribute_attacl - 1] = true;
628  nulls[Anum_pg_attribute_attoptions - 1] = true;
629  nulls[Anum_pg_attribute_attfdwoptions - 1] = true;
630 
631  tup = heap_form_tuple(RelationGetDescr(pg_attribute_rel), values, nulls);
632 
633  /* finally insert the new tuple, update the indexes, and clean up */
634  if (indstate != NULL)
635  CatalogTupleInsertWithInfo(pg_attribute_rel, tup, indstate);
636  else
637  CatalogTupleInsert(pg_attribute_rel, tup);
638 
639  heap_freetuple(tup);
640 }
#define Anum_pg_attribute_attrelid
Definition: pg_attribute.h:192
#define Anum_pg_attribute_attinhcount
Definition: pg_attribute.h:208
#define Anum_pg_attribute_atttypid
Definition: pg_attribute.h:194
#define Anum_pg_attribute_attlen
Definition: pg_attribute.h:196
#define NameGetDatum(X)
Definition: postgres.h:603
#define Anum_pg_attribute_attbyval
Definition: pg_attribute.h:201
#define Anum_pg_attribute_attnum
Definition: pg_attribute.h:197
#define RelationGetDescr(relation)
Definition: rel.h:425
#define Anum_pg_attribute_atthasdef
Definition: pg_attribute.h:205
#define Int16GetDatum(X)
Definition: postgres.h:459
#define Anum_pg_attribute_attndims
Definition: pg_attribute.h:198
#define Anum_pg_attribute_attacl
Definition: pg_attribute.h:210
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#define Anum_pg_attribute_attislocal
Definition: pg_attribute.h:207
#define Anum_pg_attribute_attisdropped
Definition: pg_attribute.h:206
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define Anum_pg_attribute_attstattarget
Definition: pg_attribute.h:195
#define Anum_pg_attribute_atttypmod
Definition: pg_attribute.h:200
#define Anum_pg_attribute_attcacheoff
Definition: pg_attribute.h:199
uintptr_t Datum
Definition: postgres.h:374
#define Anum_pg_attribute_attalign
Definition: pg_attribute.h:203
#define BoolGetDatum(X)
Definition: postgres.h:410
#define NULL
Definition: c.h:226
#define Anum_pg_attribute_attnotnull
Definition: pg_attribute.h:204
#define Anum_pg_attribute_attfdwoptions
Definition: pg_attribute.h:212
#define CharGetDatum(X)
Definition: postgres.h:424
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define Int32GetDatum(X)
Definition: postgres.h:487
#define Anum_pg_attribute_attoptions
Definition: pg_attribute.h:211
#define Natts_pg_attribute
Definition: pg_attribute.h:191
#define Anum_pg_attribute_attcollation
Definition: pg_attribute.h:209
Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:186
#define Anum_pg_attribute_attstorage
Definition: pg_attribute.h:202
#define Anum_pg_attribute_attname
Definition: pg_attribute.h:193
void InsertPgClassTuple ( Relation  pg_class_desc,
Relation  new_rel_desc,
Oid  new_rel_oid,
Datum  relacl,
Datum  reloptions 
)

Definition at line 760 of file heap.c.

References Anum_pg_class_relacl, Anum_pg_class_relallvisible, Anum_pg_class_relam, Anum_pg_class_relchecks, Anum_pg_class_relfilenode, Anum_pg_class_relforcerowsecurity, Anum_pg_class_relfrozenxid, Anum_pg_class_relhasindex, Anum_pg_class_relhasoids, Anum_pg_class_relhaspkey, Anum_pg_class_relhasrules, Anum_pg_class_relhassubclass, Anum_pg_class_relhastriggers, Anum_pg_class_relispartition, Anum_pg_class_relispopulated, Anum_pg_class_relisshared, Anum_pg_class_relkind, Anum_pg_class_relminmxid, Anum_pg_class_relname, Anum_pg_class_relnamespace, Anum_pg_class_relnatts, Anum_pg_class_reloftype, Anum_pg_class_reloptions, Anum_pg_class_relowner, Anum_pg_class_relpages, Anum_pg_class_relpartbound, Anum_pg_class_relpersistence, Anum_pg_class_relreplident, Anum_pg_class_relrowsecurity, Anum_pg_class_reltablespace, Anum_pg_class_reltoastrelid, Anum_pg_class_reltuples, Anum_pg_class_reltype, BoolGetDatum, CatalogTupleInsert(), CharGetDatum, Float4GetDatum(), heap_form_tuple(), heap_freetuple(), HeapTupleSetOid, Int16GetDatum, Int32GetDatum, MultiXactIdGetDatum, NameGetDatum, Natts_pg_class, ObjectIdGetDatum, RelationData::rd_rel, RelationGetDescr, TransactionIdGetDatum, and values.

Referenced by AddNewRelationTuple(), and index_create().

765 {
766  Form_pg_class rd_rel = new_rel_desc->rd_rel;
768  bool nulls[Natts_pg_class];
769  HeapTuple tup;
770 
771  /* This is a tad tedious, but way cleaner than what we used to do... */
772  memset(values, 0, sizeof(values));
773  memset(nulls, false, sizeof(nulls));
774 
775  values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname);
776  values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace);
777  values[Anum_pg_class_reltype - 1] = ObjectIdGetDatum(rd_rel->reltype);
778  values[Anum_pg_class_reloftype - 1] = ObjectIdGetDatum(rd_rel->reloftype);
779  values[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(rd_rel->relowner);
780  values[Anum_pg_class_relam - 1] = ObjectIdGetDatum(rd_rel->relam);
781  values[Anum_pg_class_relfilenode - 1] = ObjectIdGetDatum(rd_rel->relfilenode);
782  values[Anum_pg_class_reltablespace - 1] = ObjectIdGetDatum(rd_rel->reltablespace);
783  values[Anum_pg_class_relpages - 1] = Int32GetDatum(rd_rel->relpages);
784  values[Anum_pg_class_reltuples - 1] = Float4GetDatum(rd_rel->reltuples);
785  values[Anum_pg_class_relallvisible - 1] = Int32GetDatum(rd_rel->relallvisible);
786  values[Anum_pg_class_reltoastrelid - 1] = ObjectIdGetDatum(rd_rel->reltoastrelid);
787  values[Anum_pg_class_relhasindex - 1] = BoolGetDatum(rd_rel->relhasindex);
788  values[Anum_pg_class_relisshared - 1] = BoolGetDatum(rd_rel->relisshared);
789  values[Anum_pg_class_relpersistence - 1] = CharGetDatum(rd_rel->relpersistence);
790  values[Anum_pg_class_relkind - 1] = CharGetDatum(rd_rel->relkind);
791  values[Anum_pg_class_relnatts - 1] = Int16GetDatum(rd_rel->relnatts);
792  values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks);
793  values[Anum_pg_class_relhasoids - 1] = BoolGetDatum(rd_rel->relhasoids);
794  values[Anum_pg_class_relhaspkey - 1] = BoolGetDatum(rd_rel->relhaspkey);
795  values[Anum_pg_class_relhasrules - 1] = BoolGetDatum(rd_rel->relhasrules);
796  values[Anum_pg_class_relhastriggers - 1] = BoolGetDatum(rd_rel->relhastriggers);
797  values[Anum_pg_class_relrowsecurity - 1] = BoolGetDatum(rd_rel->relrowsecurity);
798  values[Anum_pg_class_relforcerowsecurity - 1] = BoolGetDatum(rd_rel->relforcerowsecurity);
799  values[Anum_pg_class_relhassubclass - 1] = BoolGetDatum(rd_rel->relhassubclass);
800  values[Anum_pg_class_relispopulated - 1] = BoolGetDatum(rd_rel->relispopulated);
801  values[Anum_pg_class_relreplident - 1] = CharGetDatum(rd_rel->relreplident);
802  values[Anum_pg_class_relispartition - 1] = BoolGetDatum(rd_rel->relispartition);
803  values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
804  values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
805  if (relacl != (Datum) 0)
806  values[Anum_pg_class_relacl - 1] = relacl;
807  else
808  nulls[Anum_pg_class_relacl - 1] = true;
809  if (reloptions != (Datum) 0)
810  values[Anum_pg_class_reloptions - 1] = reloptions;
811  else
812  nulls[Anum_pg_class_reloptions - 1] = true;
813 
814  /* relpartbound is set by updating this tuple, if necessary */
815  nulls[Anum_pg_class_relpartbound - 1] = true;
816 
817  tup = heap_form_tuple(RelationGetDescr(pg_class_desc), values, nulls);
818 
819  /*
820  * The new tuple must have the oid already chosen for the rel. Sure would
821  * be embarrassing to do this sort of thing in polite company.
822  */
823  HeapTupleSetOid(tup, new_rel_oid);
824 
825  /* finally insert the new tuple, update the indexes, and clean up */
826  CatalogTupleInsert(pg_class_desc, tup);
827 
828  heap_freetuple(tup);
829 }
#define Natts_pg_class
Definition: pg_class.h:102
#define Anum_pg_class_relhasindex
Definition: pg_class.h:115
#define Anum_pg_class_relpersistence
Definition: pg_class.h:117
#define NameGetDatum(X)
Definition: postgres.h:603
#define Anum_pg_class_relacl
Definition: pg_class.h:133
#define MultiXactIdGetDatum(X)
Definition: postgres.h:536
#define RelationGetDescr(relation)
Definition: rel.h:425
#define Anum_pg_class_relispartition
Definition: pg_class.h:130
#define Anum_pg_class_reloptions
Definition: pg_class.h:134
#define Anum_pg_class_reltablespace
Definition: pg_class.h:110
#define Int16GetDatum(X)
Definition: postgres.h:459
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
Form_pg_class rd_rel
Definition: rel.h:113
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#define Anum_pg_class_relispopulated
Definition: pg_class.h:128
#define Anum_pg_class_relnatts
Definition: pg_class.h:119
#define Anum_pg_class_relnamespace
Definition: pg_class.h:104
#define Anum_pg_class_relfilenode
Definition: pg_class.h:109
#define HeapTupleSetOid(tuple, oid)
Definition: htup_details.h:698
#define Anum_pg_class_relhasrules
Definition: pg_class.h:123
#define Anum_pg_class_relkind
Definition: pg_class.h:118
#define Anum_pg_class_relhasoids
Definition: pg_class.h:121
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define Anum_pg_class_reltype
Definition: pg_class.h:105
#define Anum_pg_class_reloftype
Definition: pg_class.h:106
Datum Float4GetDatum(float4 X)
Definition: fmgr.c:2114
#define Anum_pg_class_relname
Definition: pg_class.h:103
#define Anum_pg_class_relpages
Definition: pg_class.h:111
#define Anum_pg_class_relminmxid
Definition: pg_class.h:132
#define Anum_pg_class_relreplident
Definition: pg_class.h:129
#define TransactionIdGetDatum(X)
Definition: postgres.h:529
#define Anum_pg_class_relhassubclass
Definition: pg_class.h:125
#define Anum_pg_class_relisshared
Definition: pg_class.h:116
uintptr_t Datum
Definition: postgres.h:374
#define Anum_pg_class_reltuples
Definition: pg_class.h:112
#define BoolGetDatum(X)
Definition: postgres.h:410
#define Anum_pg_class_relpartbound
Definition: pg_class.h:135
#define Anum_pg_class_relhaspkey
Definition: pg_class.h:122
#define Anum_pg_class_relallvisible
Definition: pg_class.h:113
#define Anum_pg_class_reltoastrelid
Definition: pg_class.h:114
#define CharGetDatum(X)
Definition: postgres.h:424
static Datum values[MAXATTR]
Definition: bootstrap.c:162
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define Int32GetDatum(X)
Definition: postgres.h:487
#define Anum_pg_class_relforcerowsecurity
Definition: pg_class.h:127
#define Anum_pg_class_relam
Definition: pg_class.h:108
#define Anum_pg_class_relfrozenxid
Definition: pg_class.h:131
#define Anum_pg_class_relhastriggers
Definition: pg_class.h:124
#define Anum_pg_class_relchecks
Definition: pg_class.h:120
#define Anum_pg_class_relrowsecurity
Definition: pg_class.h:126
#define Anum_pg_class_relowner
Definition: pg_class.h:107
static bool MergeWithExistingConstraint ( Relation  rel,
char *  ccname,
Node expr,
bool  allow_merge,
bool  is_local,
bool  is_initially_valid,
bool  is_no_inherit 
)
static

Definition at line 2423 of file heap.c.

References Anum_pg_constraint_conbin, Anum_pg_constraint_conname, Anum_pg_constraint_connamespace, Assert, BTEqualStrategyNumber, CatalogTupleUpdate(), CONSTRAINT_CHECK, ConstraintNameNspIndexId, ConstraintRelationId, CStringGetDatum, elog, equal(), ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, fastgetattr, GETSTRUCT, heap_close, heap_copytuple(), heap_open(), HeapTupleIsValid, NOTICE, NULL, ObjectIdGetDatum, RelationData::rd_att, RelationData::rd_rel, RelationGetNamespace, RelationGetRelationName, RelationGetRelid, RowExclusiveLock, ScanKeyInit(), stringToNode(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, TextDatumGetCString, and val.

Referenced by AddRelationNewConstraints().

2427 {
2428  bool found;
2429  Relation conDesc;
2430  SysScanDesc conscan;
2431  ScanKeyData skey[2];
2432  HeapTuple tup;
2433 
2434  /* Search for a pg_constraint entry with same name and relation */
2436 
2437  found = false;
2438 
2439  ScanKeyInit(&skey[0],
2441  BTEqualStrategyNumber, F_NAMEEQ,
2442  CStringGetDatum(ccname));
2443 
2444  ScanKeyInit(&skey[1],
2446  BTEqualStrategyNumber, F_OIDEQ,
2448 
2449  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
2450  NULL, 2, skey);
2451 
2452  while (HeapTupleIsValid(tup = systable_getnext(conscan)))
2453  {
2455 
2456  if (con->conrelid == RelationGetRelid(rel))
2457  {
2458  /* Found it. Conflicts if not identical check constraint */
2459  if (con->contype == CONSTRAINT_CHECK)
2460  {
2461  Datum val;
2462  bool isnull;
2463 
2464  val = fastgetattr(tup,
2466  conDesc->rd_att, &isnull);
2467  if (isnull)
2468  elog(ERROR, "null conbin for rel %s",
2470  if (equal(expr, stringToNode(TextDatumGetCString(val))))
2471  found = true;
2472  }
2473 
2474  /*
2475  * If the existing constraint is purely inherited (no local
2476  * definition) then interpret addition of a local constraint as a
2477  * legal merge. This allows ALTER ADD CONSTRAINT on parent and
2478  * child tables to be given in either order with same end state.
2479  * However if the relation is a partition, all inherited
2480  * constraints are always non-local, including those that were
2481  * merged.
2482  */
2483  if (is_local && !con->conislocal && !rel->rd_rel->relispartition)
2484  allow_merge = true;
2485 
2486  if (!found || !allow_merge)
2487  ereport(ERROR,
2489  errmsg("constraint \"%s\" for relation \"%s\" already exists",
2490  ccname, RelationGetRelationName(rel))));
2491 
2492  /* If the child constraint is "no inherit" then cannot merge */
2493  if (con->connoinherit)
2494  ereport(ERROR,
2495  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2496  errmsg("constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"",
2497  ccname, RelationGetRelationName(rel))));
2498 
2499  /*
2500  * Must not change an existing inherited constraint to "no
2501  * inherit" status. That's because inherited constraints should
2502  * be able to propagate to lower-level children.
2503  */
2504  if (con->coninhcount > 0 && is_no_inherit)
2505  ereport(ERROR,
2506  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2507  errmsg("constraint \"%s\" conflicts with inherited constraint on relation \"%s\"",
2508  ccname, RelationGetRelationName(rel))));
2509 
2510  /*
2511  * If the child constraint is "not valid" then cannot merge with a
2512  * valid parent constraint
2513  */
2514  if (is_initially_valid && !con->convalidated)
2515  ereport(ERROR,
2516  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2517  errmsg("constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"",
2518  ccname, RelationGetRelationName(rel))));
2519 
2520  /* OK to update the tuple */
2521  ereport(NOTICE,
2522  (errmsg("merging constraint \"%s\" with inherited definition",
2523  ccname)));
2524 
2525  tup = heap_copytuple(tup);
2526  con = (Form_pg_constraint) GETSTRUCT(tup);
2527 
2528  /*
2529  * In case of partitions, an inherited constraint must be
2530  * inherited only once since it cannot have multiple parents and
2531  * it is never considered local.
2532  */
2533  if (rel->rd_rel->relispartition)
2534  {
2535  con->coninhcount = 1;
2536  con->conislocal = false;
2537  }
2538  else
2539  {
2540  if (is_local)
2541  con->conislocal = true;
2542  else
2543  con->coninhcount++;
2544  }
2545 
2546  if (is_no_inherit)
2547  {
2548  Assert(is_local);
2549  con->connoinherit = true;
2550  }
2551  CatalogTupleUpdate(conDesc, &tup->t_self, tup);
2552  break;
2553  }
2554  }
2555 
2556  systable_endscan(conscan);
2557  heap_close(conDesc, RowExclusiveLock);
2558 
2559  return found;
2560 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
void * stringToNode(char *str)
Definition: read.c:38
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define fastgetattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:719
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:2870
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
#define Anum_pg_constraint_conname
Form_pg_class rd_rel
Definition: rel.h:113
#define Anum_pg_constraint_conbin
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
#define CONSTRAINT_CHECK
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:586
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define ereport(elevel, rest)
Definition: elog.h:122
#define TextDatumGetCString(d)
Definition: builtins.h:91
uintptr_t Datum
Definition: postgres.h:374
#define Anum_pg_constraint_connamespace
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
TupleDesc rd_att
Definition: rel.h:114
#define NOTICE
Definition: elog.h:37
#define ConstraintNameNspIndexId
Definition: indexing.h:124
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define elog
Definition: elog.h:219
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:34
#define RelationGetRelid(relation)
Definition: rel.h:413
long val
Definition: informix.c:689
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define RelationGetNamespace(relation)
Definition: rel.h:440
static void RelationRemoveInheritance ( Oid  relid)
static

Definition at line 1395 of file heap.c.

References Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, CatalogTupleDelete(), heap_close, heap_open(), HeapTupleIsValid, InheritsRelationId, InheritsRelidSeqnoIndexId, NULL, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by heap_drop_with_catalog().

1396 {
1397  Relation catalogRelation;
1398  SysScanDesc scan;
1399  ScanKeyData key;
1400  HeapTuple tuple;
1401 
1402  catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
1403 
1404  ScanKeyInit(&key,
1406  BTEqualStrategyNumber, F_OIDEQ,
1407  ObjectIdGetDatum(relid));
1408 
1409  scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, true,
1410  NULL, 1, &key);
1411 
1412  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1413  CatalogTupleDelete(catalogRelation, &tuple->t_self);
1414 
1415  systable_endscan(scan);
1416  heap_close(catalogRelation, RowExclusiveLock);
1417 }
#define Anum_pg_inherits_inhrelid
Definition: pg_inherits.h:50
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define InheritsRelidSeqnoIndexId
Definition: indexing.h:167
#define InheritsRelationId
Definition: pg_inherits.h:29
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
static void RelationTruncateIndexes ( Relation  heapRelation)
static

Definition at line 2776 of file heap.c.

References AccessExclusiveLock, BuildIndexInfo(), index_build(), index_close(), index_open(), lfirst_oid, NoLock, RelationGetIndexList(), and RelationTruncate().

Referenced by heap_truncate_one_rel().

2777 {
2778  ListCell *indlist;
2779 
2780  /* Ask the relcache to produce a list of the indexes of the rel */
2781  foreach(indlist, RelationGetIndexList(heapRelation))
2782  {
2783  Oid indexId = lfirst_oid(indlist);
2784  Relation currentIndex;
2785  IndexInfo *indexInfo;
2786 
2787  /* Open the index relation; use exclusive lock, just to be sure */
2788  currentIndex = index_open(indexId, AccessExclusiveLock);
2789 
2790  /* Fetch info needed for index_build */
2791  indexInfo = BuildIndexInfo(currentIndex);
2792 
2793  /*
2794  * Now truncate the actual file (and discard buffers).
2795  */
2796  RelationTruncate(currentIndex, 0);
2797 
2798  /* Initialize the index and rebuild */
2799  /* Note: we do not need to re-establish pkey setting */
2800  index_build(heapRelation, currentIndex, indexInfo, false, true);
2801 
2802  /* We're done with this index */
2803  index_close(currentIndex, NoLock);
2804  }
2805 }
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:1639
unsigned int Oid
Definition: postgres_ext.h:31
#define NoLock
Definition: lockdefs.h:34
void index_build(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, bool isprimary, bool isreindex)
Definition: index.c:2000
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4336
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
#define AccessExclusiveLock
Definition: lockdefs.h:46
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
#define lfirst_oid(lc)
Definition: pg_list.h:108
void RelationTruncate(Relation rel, BlockNumber nblocks)
Definition: storage.c:227
void RemoveAttrDefault ( Oid  relid,
AttrNumber  attnum,
DropBehavior  behavior,
bool  complain,
bool  internal 
)

Definition at line 1623 of file heap.c.

References Anum_pg_attrdef_adnum, Anum_pg_attrdef_adrelid, AttrDefaultIndexId, AttrDefaultRelationId, BTEqualStrategyNumber, ObjectAddress::classId, elog, ERROR, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, Int16GetDatum, NULL, ObjectAddressStack::object, ObjectIdGetDatum, PERFORM_DELETION_INTERNAL, performDeletion(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by ATExecAlterColumnType(), and ATExecColumnDefault().

1625 {
1626  Relation attrdef_rel;
1627  ScanKeyData scankeys[2];
1628  SysScanDesc scan;
1629  HeapTuple tuple;
1630  bool found = false;
1631 
1633 
1634  ScanKeyInit(&scankeys[0],
1636  BTEqualStrategyNumber, F_OIDEQ,
1637  ObjectIdGetDatum(relid));
1638  ScanKeyInit(&scankeys[1],
1640  BTEqualStrategyNumber, F_INT2EQ,
1641  Int16GetDatum(attnum));
1642 
1643  scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true,
1644  NULL, 2, scankeys);
1645 
1646  /* There should be at most one matching tuple, but we loop anyway */
1647  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1648  {
1649  ObjectAddress object;
1650 
1651  object.classId = AttrDefaultRelationId;
1652  object.objectId = HeapTupleGetOid(tuple);
1653  object.objectSubId = 0;
1654 
1655  performDeletion(&object, behavior,
1656  internal ? PERFORM_DELETION_INTERNAL : 0);
1657 
1658  found = true;
1659  }
1660 
1661  systable_endscan(scan);
1662  heap_close(attrdef_rel, RowExclusiveLock);
1663 
1664  if (complain && !found)
1665  elog(ERROR, "could not find attrdef tuple for relation %u attnum %d",
1666  relid, attnum);
1667 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define Int16GetDatum(X)
Definition: postgres.h:459
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define AttrDefaultIndexId
Definition: indexing.h:87
#define RowExclusiveLock
Definition: lockdefs.h:38
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
Definition: dependency.c:301
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define Anum_pg_attrdef_adrelid
Definition: pg_attrdef.h:54
#define Anum_pg_attrdef_adnum
Definition: pg_attrdef.h:55
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
#define AttrDefaultRelationId
Definition: pg_attrdef.h:29
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define PERFORM_DELETION_INTERNAL
Definition: dependency.h:173
void RemoveAttrDefaultById ( Oid  attrdefId)

Definition at line 1677 of file heap.c.

References AccessExclusiveLock, ATTNUM, AttrDefaultOidIndexId, AttrDefaultRelationId, AttributeRelationId, BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), elog, ERROR, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, Int16GetDatum, NoLock, NULL, ObjectIdAttributeNumber, ObjectIdGetDatum, relation_close(), relation_open(), RowExclusiveLock, ScanKeyInit(), SearchSysCacheCopy2, systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by doDeletion().

1678 {
1679  Relation attrdef_rel;
1680  Relation attr_rel;
1681  Relation myrel;
1682  ScanKeyData scankeys[1];
1683  SysScanDesc scan;
1684  HeapTuple tuple;
1685  Oid myrelid;
1686  AttrNumber myattnum;
1687 
1688  /* Grab an appropriate lock on the pg_attrdef relation */
1690 
1691  /* Find the pg_attrdef tuple */
1692  ScanKeyInit(&scankeys[0],
1694  BTEqualStrategyNumber, F_OIDEQ,
1695  ObjectIdGetDatum(attrdefId));
1696 
1697  scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndexId, true,
1698  NULL, 1, scankeys);
1699 
1700  tuple = systable_getnext(scan);
1701  if (!HeapTupleIsValid(tuple))
1702  elog(ERROR, "could not find tuple for attrdef %u", attrdefId);
1703 
1704  myrelid = ((Form_pg_attrdef) GETSTRUCT(tuple))->adrelid;
1705  myattnum = ((Form_pg_attrdef) GETSTRUCT(tuple))->adnum;
1706 
1707  /* Get an exclusive lock on the relation owning the attribute */
1708  myrel = relation_open(myrelid, AccessExclusiveLock);
1709 
1710  /* Now we can delete the pg_attrdef row */
1711  CatalogTupleDelete(attrdef_rel, &tuple->t_self);
1712 
1713  systable_endscan(scan);
1714  heap_close(attrdef_rel, RowExclusiveLock);
1715 
1716  /* Fix the pg_attribute row */
1718 
1719  tuple = SearchSysCacheCopy2(ATTNUM,
1720  ObjectIdGetDatum(myrelid),
1721  Int16GetDatum(myattnum));
1722  if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
1723  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1724  myattnum, myrelid);
1725 
1726  ((Form_pg_attribute) GETSTRUCT(tuple))->atthasdef = false;
1727 
1728  CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
1729 
1730  /*
1731  * Our update of the pg_attribute row will force a relcache rebuild, so
1732  * there's nothing else to do here.
1733  */
1734  heap_close(attr_rel, RowExclusiveLock);
1735 
1736  /* Keep lock on attribute's rel until end of xact */
1737  relation_close(myrel, NoLock);
1738 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define Int16GetDatum(X)
Definition: postgres.h:459
#define AttrDefaultOidIndexId
Definition: indexing.h:89
#define AttributeRelationId
Definition: pg_attribute.h:33
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
FormData_pg_attrdef * Form_pg_attrdef
Definition: pg_attrdef.h:47
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define AccessExclusiveLock
Definition: lockdefs.h:46
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
#define elog
Definition: elog.h:219
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition: syscache.h:160
#define AttrDefaultRelationId
Definition: pg_attrdef.h:29
int16 AttrNumber
Definition: attnum.h:21
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void RemoveAttributeById ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 1535 of file heap.c.

References AccessExclusiveLock, ATTNUM, AttributeRelationId, CatalogTupleDelete(), CatalogTupleUpdate(), elog, ERROR, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, Int16GetDatum, InvalidOid, NAMEDATALEN, namestrcpy(), NoLock, ObjectIdGetDatum, relation_close(), relation_open(), RemoveStatistics(), RowExclusiveLock, SearchSysCacheCopy2, snprintf(), and HeapTupleData::t_self.

Referenced by doDeletion().

1536 {
1537  Relation rel;
1538  Relation attr_rel;
1539  HeapTuple tuple;
1540  Form_pg_attribute attStruct;
1541  char newattname[NAMEDATALEN];
1542 
1543  /*
1544  * Grab an exclusive lock on the target table, which we will NOT release
1545  * until end of transaction. (In the simple case where we are directly
1546  * dropping this column, AlterTableDropColumn already did this ... but
1547  * when cascading from a drop of some other object, we may not have any
1548  * lock.)
1549  */
1550  rel = relation_open(relid, AccessExclusiveLock);
1551 
1553 
1554  tuple = SearchSysCacheCopy2(ATTNUM,
1555  ObjectIdGetDatum(relid),
1556  Int16GetDatum(attnum));
1557  if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
1558  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1559  attnum, relid);
1560  attStruct = (Form_pg_attribute) GETSTRUCT(tuple);
1561 
1562  if (attnum < 0)
1563  {
1564  /* System attribute (probably OID) ... just delete the row */
1565 
1566  CatalogTupleDelete(attr_rel, &tuple->t_self);
1567  }
1568  else
1569  {
1570  /* Dropping user attributes is lots harder */
1571 
1572  /* Mark the attribute as dropped */
1573  attStruct->attisdropped = true;
1574 
1575  /*
1576  * Set the type OID to invalid. A dropped attribute's type link
1577  * cannot be relied on (once the attribute is dropped, the type might
1578  * be too). Fortunately we do not need the type row --- the only
1579  * really essential information is the type's typlen and typalign,
1580  * which are preserved in the attribute's attlen and attalign. We set
1581  * atttypid to zero here as a means of catching code that incorrectly
1582  * expects it to be valid.
1583  */
1584  attStruct->atttypid = InvalidOid;
1585 
1586  /* Remove any NOT NULL constraint the column may have */
1587  attStruct->attnotnull = false;
1588 
1589  /* We don't want to keep stats for it anymore */
1590  attStruct->attstattarget = 0;
1591 
1592  /*
1593  * Change the column name to something that isn't likely to conflict
1594  */
1595  snprintf(newattname, sizeof(newattname),
1596  "........pg.dropped.%d........", attnum);
1597  namestrcpy(&(attStruct->attname), newattname);
1598 
1599  CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
1600  }
1601 
1602  /*
1603  * Because updating the pg_attribute row will trigger a relcache flush for
1604  * the target relation, we need not do anything else to notify other
1605  * backends of the change.
1606  */
1607 
1608  heap_close(attr_rel, RowExclusiveLock);
1609 
1610  if (attnum > 0)
1611  RemoveStatistics(relid, attnum);
1612 
1613  relation_close(rel, NoLock);
1614 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define Int16GetDatum(X)
Definition: postgres.h:459
#define AttributeRelationId
Definition: pg_attribute.h:33
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
int namestrcpy(Name name, const char *str)
Definition: name.c:217
#define NAMEDATALEN
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
void RemoveStatistics(Oid relid, AttrNumber attnum)
Definition: heap.c:2729
#define AccessExclusiveLock
Definition: lockdefs.h:46
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
#define elog
Definition: elog.h:219
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition: syscache.h:160
void RemovePartitionKeyByRelId ( Oid  relid)

Definition at line 3180 of file heap.c.

References CatalogTupleDelete(), elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, PartitionedRelationId, PARTRELID, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, and HeapTupleData::t_self.

Referenced by heap_drop_with_catalog().

3181 {
3182  Relation rel;
3183  HeapTuple tuple;
3184 
3186 
3187  tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(relid));
3188  if (!HeapTupleIsValid(tuple))
3189  elog(ERROR, "cache lookup failed for partition key of relation %u",
3190  relid);
3191 
3192  CatalogTupleDelete(rel, &tuple->t_self);
3193 
3194  ReleaseSysCache(tuple);
3196 }
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define PartitionedRelationId
#define RowExclusiveLock
Definition: lockdefs.h:38
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
void RemoveStatistics ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 2729 of file heap.c.

References Anum_pg_statistic_staattnum, Anum_pg_statistic_starelid, BTEqualStrategyNumber, CatalogTupleDelete(), heap_close, heap_open(), HeapTupleIsValid, Int16GetDatum, NULL, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), StatisticRelationId, StatisticRelidAttnumInhIndexId, systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by ATExecAlterColumnType(), heap_drop_with_catalog(), index_drop(), and RemoveAttributeById().

2730 {
2731  Relation pgstatistic;
2732  SysScanDesc scan;
2733  ScanKeyData key[2];
2734  int nkeys;
2735  HeapTuple tuple;
2736 
2738 
2739  ScanKeyInit(&key[0],
2741  BTEqualStrategyNumber, F_OIDEQ,
2742  ObjectIdGetDatum(relid));
2743 
2744  if (attnum == 0)
2745  nkeys = 1;
2746  else
2747  {
2748  ScanKeyInit(&key[1],
2750  BTEqualStrategyNumber, F_INT2EQ,
2751  Int16GetDatum(attnum));
2752  nkeys = 2;
2753  }
2754 
2755  scan = systable_beginscan(pgstatistic, StatisticRelidAttnumInhIndexId, true,
2756  NULL, nkeys, key);
2757 
2758  /* we must loop even when attnum != 0, in case of inherited stats */
2759  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
2760  CatalogTupleDelete(pgstatistic, &tuple->t_self);
2761 
2762  systable_endscan(scan);
2763 
2764  heap_close(pgstatistic, RowExclusiveLock);
2765 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define Int16GetDatum(X)
Definition: postgres.h:459
#define Anum_pg_statistic_staattnum
Definition: pg_statistic.h:137
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_statistic_starelid
Definition: pg_statistic.h:136
#define StatisticRelationId
Definition: pg_statistic.h:29
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define StatisticRelidAttnumInhIndexId
Definition: indexing.h:227
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
static void SetRelationNumChecks ( Relation  rel,
int  numchecks 
)
static

Definition at line 2573 of file heap.c.

References CacheInvalidateRelcache(), CatalogTupleUpdate(), elog, ERROR, GETSTRUCT, heap_close, heap_freetuple(), heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RelationGetRelid, RelationRelationId, RELOID, RowExclusiveLock, SearchSysCacheCopy1, and HeapTupleData::t_self.

Referenced by AddRelationNewConstraints(), and StoreConstraints().

2574 {
2575  Relation relrel;
2576  HeapTuple reltup;
2577  Form_pg_class relStruct;
2578 
2580  reltup = SearchSysCacheCopy1(RELOID,
2582  if (!HeapTupleIsValid(reltup))
2583  elog(ERROR, "cache lookup failed for relation %u",
2584  RelationGetRelid(rel));
2585  relStruct = (Form_pg_class) GETSTRUCT(reltup);
2586 
2587  if (relStruct->relchecks != numchecks)
2588  {
2589  relStruct->relchecks = numchecks;
2590 
2591  CatalogTupleUpdate(relrel, &reltup->t_self, reltup);
2592  }
2593  else
2594  {
2595  /* Skip the disk update, but force relcache inval anyway */
2597  }
2598 
2599  heap_freetuple(reltup);
2600  heap_close(relrel, RowExclusiveLock);
2601 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationRelationId
Definition: pg_class.h:29
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1225
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
#define elog
Definition: elog.h:219
#define RelationGetRelid(relation)
Definition: rel.h:413
Oid StoreAttrDefault ( Relation  rel,
AttrNumber  attnum,
Node expr,
bool  is_internal 
)

Definition at line 1886 of file heap.c.

References Anum_pg_attrdef_adbin, Anum_pg_attrdef_adnum, Anum_pg_attrdef_adrelid, Anum_pg_attrdef_adsrc, ATTNUM, AttrDefaultRelationId, AttributeRelationId, CatalogTupleInsert(), CatalogTupleUpdate(), ObjectAddress::classId, CStringGetTextDatum, DatumGetPointer, deparse_context_for(), deparse_expression(), DEPENDENCY_AUTO, DEPENDENCY_NORMAL, elog, ERROR, GETSTRUCT, heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), HeapTupleIsValid, Int16GetDatum, InvokeObjectPostCreateHookArg, NIL, nodeToString(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, pfree(), RelationData::rd_att, recordDependencyOn(), recordDependencyOnExpr(), RelationGetRelationName, RelationGetRelid, RelationRelationId, RowExclusiveLock, SearchSysCacheCopy2, HeapTupleData::t_self, and values.

Referenced by AddRelationNewConstraints(), ATExecAlterColumnType(), and StoreConstraints().

1888 {
1889  char *adbin;
1890  char *adsrc;
1891  Relation adrel;
1892  HeapTuple tuple;
1893  Datum values[4];
1894  static bool nulls[4] = {false, false, false, false};
1895  Relation attrrel;
1896  HeapTuple atttup;
1897  Form_pg_attribute attStruct;
1898  Oid attrdefOid;
1899  ObjectAddress colobject,
1900  defobject;
1901 
1902  /*
1903  * Flatten expression to string form for storage.
1904  */
1905  adbin = nodeToString(expr);
1906 
1907  /*
1908  * Also deparse it to form the mostly-obsolete adsrc field.
1909  */
1910  adsrc = deparse_expression(expr,
1912  RelationGetRelid(rel)),
1913  false, false);
1914 
1915  /*
1916  * Make the pg_attrdef entry.
1917  */
1918  values[Anum_pg_attrdef_adrelid - 1] = RelationGetRelid(rel);
1919  values[Anum_pg_attrdef_adnum - 1] = attnum;
1920  values[Anum_pg_attrdef_adbin - 1] = CStringGetTextDatum(adbin);
1921  values[Anum_pg_attrdef_adsrc - 1] = CStringGetTextDatum(adsrc);
1922 
1924 
1925  tuple = heap_form_tuple(adrel->rd_att, values, nulls);
1926  attrdefOid = CatalogTupleInsert(adrel, tuple);
1927 
1928  defobject.classId = AttrDefaultRelationId;
1929  defobject.objectId = attrdefOid;
1930  defobject.objectSubId = 0;
1931 
1932  heap_close(adrel, RowExclusiveLock);
1933 
1934  /* now can free some of the stuff allocated above */
1937  heap_freetuple(tuple);
1938  pfree(adbin);
1939  pfree(adsrc);
1940 
1941  /*
1942  * Update the pg_attribute entry for the column to show that a default
1943  * exists.
1944  */
1946  atttup = SearchSysCacheCopy2(ATTNUM,
1948  Int16GetDatum(attnum));
1949  if (!HeapTupleIsValid(atttup))
1950  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1951  attnum, RelationGetRelid(rel));
1952  attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
1953  if (!attStruct->atthasdef)
1954  {
1955  attStruct->atthasdef = true;
1956  CatalogTupleUpdate(attrrel, &atttup->t_self, atttup);
1957  }
1958  heap_close(attrrel, RowExclusiveLock);
1959  heap_freetuple(atttup);
1960 
1961  /*
1962  * Make a dependency so that the pg_attrdef entry goes away if the column
1963  * (or whole table) is deleted.
1964  */
1965  colobject.classId = RelationRelationId;
1966  colobject.objectId = RelationGetRelid(rel);
1967  colobject.objectSubId = attnum;
1968 
1969  recordDependencyOn(&defobject, &colobject, DEPENDENCY_AUTO);
1970 
1971  /*
1972  * Record dependencies on objects used in the expression, too.
1973  */
1974  recordDependencyOnExpr(&defobject, expr, NIL, DEPENDENCY_NORMAL);
1975 
1976  /*
1977  * Post creation hook for attribute defaults.
1978  *
1979  * XXX. ALTER TABLE ALTER COLUMN SET/DROP DEFAULT is implemented with a
1980  * couple of deletion/creation of the attribute's default entry, so the
1981  * callee should check existence of an older version of this entry if it
1982  * needs to distinguish.
1983  */
1985  RelationGetRelid(rel), attnum, is_internal);
1986 
1987  return attrdefOid;
1988 }
#define NIL
Definition: pg_list.h:69
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationRelationId
Definition: pg_class.h:29
#define Int16GetDatum(X)
Definition: postgres.h:459
#define AttributeRelationId
Definition: pg_attribute.h:33
#define Anum_pg_attrdef_adbin
Definition: pg_attrdef.h:56
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
void pfree(void *pointer)
Definition: mcxt.c:992
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
List * deparse_context_for(const char *aliasname, Oid relid)
Definition: ruleutils.c:2854
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
Definition: dependency.c:1332
#define RelationGetRelationName(relation)
Definition: rel.h:433
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
uintptr_t Datum
Definition: postgres.h:374
#define Anum_pg_attrdef_adsrc
Definition: pg_attrdef.h:57
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
Definition: objectaccess.h:147
TupleDesc rd_att
Definition: rel.h:114
#define Anum_pg_attrdef_adrelid
Definition: pg_attrdef.h:54
#define Anum_pg_attrdef_adnum
Definition: pg_attrdef.h:55
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
char * deparse_expression(Node *expr, List *dpcontext, bool forceprefix, bool showimplicit)
Definition: ruleutils.c:2795
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define DatumGetPointer(X)
Definition: postgres.h:557
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define CStringGetTextDatum(s)
Definition: builtins.h:90
char * nodeToString(const void *obj)
Definition: outfuncs.c:3981
#define elog
Definition: elog.h:219
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition: syscache.h:160
#define AttrDefaultRelationId
Definition: pg_attrdef.h:29
#define RelationGetRelid(relation)
Definition: rel.h:413
static void StoreConstraints ( Relation  rel,
List cooked_constraints,
bool  is_internal 
)
static

Definition at line 2116 of file heap.c.

References CookedConstraint::attnum, CommandCounterIncrement(), CookedConstraint::conoid, CONSTR_CHECK, CONSTR_DEFAULT, CookedConstraint::contype, elog, ERROR, CookedConstraint::expr, CookedConstraint::inhcount, CookedConstraint::is_local, CookedConstraint::is_no_inherit, lfirst, CookedConstraint::name, NIL, SetRelationNumChecks(), CookedConstraint::skip_validation, StoreAttrDefault(), and StoreRelCheck().

Referenced by heap_create_with_catalog().

2117 {
2118  int numchecks = 0;
2119  ListCell *lc;
2120 
2121  if (cooked_constraints == NIL)
2122  return; /* nothing to do */
2123 
2124  /*
2125  * Deparsing of constraint expressions will fail unless the just-created
2126  * pg_attribute tuples for this relation are made visible. So, bump the
2127  * command counter. CAUTION: this will cause a relcache entry rebuild.
2128  */
2130 
2131  foreach(lc, cooked_constraints)
2132  {
2133  CookedConstraint *con = (CookedConstraint *) lfirst(lc);
2134 
2135  switch (con->contype)
2136  {
2137  case CONSTR_DEFAULT:
2138  con->conoid = StoreAttrDefault(rel, con->attnum, con->expr,
2139  is_internal);
2140  break;
2141  case CONSTR_CHECK:
2142  con->conoid =
2143  StoreRelCheck(rel, con->name, con->expr,
2144  !con->skip_validation, con->is_local,
2145  con->inhcount, con->is_no_inherit,
2146  is_internal);
2147  numchecks++;
2148  break;
2149  default:
2150  elog(ERROR, "unrecognized constraint type: %d",
2151  (int) con->contype);
2152  }
2153  }
2154 
2155  if (numchecks > 0)
2156  SetRelationNumChecks(rel, numchecks);
2157 }
#define NIL
Definition: pg_list.h:69
static void SetRelationNumChecks(Relation rel, int numchecks)
Definition: heap.c:2573
bool is_no_inherit
Definition: heap.h:38
static Oid StoreRelCheck(Relation rel, char *ccname, Node *expr, bool is_validated, bool is_local, int inhcount, bool is_no_inherit, bool is_internal)
Definition: heap.c:1999
AttrNumber attnum
Definition: heap.h:33
#define ERROR
Definition: elog.h:43
int inhcount
Definition: heap.h:37
bool skip_validation
Definition: heap.h:35
ConstrType contype
Definition: heap.h:30
void CommandCounterIncrement(void)
Definition: xact.c:921
#define lfirst(lc)
Definition: pg_list.h:106
Oid conoid
Definition: heap.h:31
Node * expr
Definition: heap.h:34
#define elog
Definition: elog.h:219
Oid StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr, bool is_internal)
Definition: heap.c:1886
char * name
Definition: heap.h:32
bool is_local
Definition: heap.h:36
void StorePartitionBound ( Relation  rel,
Relation  parent,
Node bound 
)

Definition at line 3207 of file heap.c.

References Anum_pg_class_relpartbound, Assert, CacheInvalidateRelcache(), CatalogTupleUpdate(), CStringGetTextDatum, elog, ERROR, GETSTRUCT, heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleIsValid, Natts_pg_class, nodeToString(), ObjectIdGetDatum, RelationGetDescr, RelationGetRelid, RelationRelationId, RELOID, RowExclusiveLock, SearchSysCacheCopy1, SysCacheGetAttr(), and HeapTupleData::t_self.

Referenced by ATExecAttachPartition(), and DefineRelation().

3208 {
3209  Relation classRel;
3210  HeapTuple tuple,
3211  newtuple;
3212  Datum new_val[Natts_pg_class];
3213  bool new_null[Natts_pg_class],
3214  new_repl[Natts_pg_class];
3215 
3216  /* Update pg_class tuple */
3218  tuple = SearchSysCacheCopy1(RELOID,
3220  if (!HeapTupleIsValid(tuple))
3221  elog(ERROR, "cache lookup failed for relation %u",
3222  RelationGetRelid(rel));
3223 
3224 #ifdef USE_ASSERT_CHECKING
3225  {
3226  Form_pg_class classForm;
3227  bool isnull;
3228 
3229  classForm = (Form_pg_class) GETSTRUCT(tuple);
3230  Assert(!classForm->relispartition);
3232  &isnull);
3233  Assert(isnull);
3234  }
3235 #endif
3236 
3237  /* Fill in relpartbound value */
3238  memset(new_val, 0, sizeof(new_val));
3239  memset(new_null, false, sizeof(new_null));
3240  memset(new_repl, false, sizeof(new_repl));
3242  new_null[Anum_pg_class_relpartbound - 1] = false;
3243  new_repl[Anum_pg_class_relpartbound - 1] = true;
3244  newtuple = heap_modify_tuple(tuple, RelationGetDescr(classRel),
3245  new_val, new_null, new_repl);
3246  /* Also set the flag */
3247  ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true;
3248  CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
3249  heap_freetuple(newtuple);
3250  heap_close(classRel, RowExclusiveLock);
3251 
3252  CacheInvalidateRelcache(parent);
3253 }
#define Natts_pg_class
Definition: pg_class.h:102
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:425
#define RelationRelationId
Definition: pg_class.h:29
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
uintptr_t Datum
Definition: postgres.h:374
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define Anum_pg_class_relpartbound
Definition: pg_class.h:135
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:671
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1225
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
#define CStringGetTextDatum(s)
Definition: builtins.h:90
char * nodeToString(const void *obj)
Definition: outfuncs.c:3981
#define elog
Definition: elog.h:219
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
#define RelationGetRelid(relation)
Definition: rel.h:413
void StorePartitionKey ( Relation  rel,
char  strategy,
int16  partnatts,
AttrNumber partattrs,
List partexprs,
Oid partopclass,
Oid partcollation 
)

Definition at line 3071 of file heap.c.

References Anum_pg_partitioned_table_partattrs, Anum_pg_partitioned_table_partclass, Anum_pg_partitioned_table_partcollation, Anum_pg_partitioned_table_partexprs, Anum_pg_partitioned_table_partnatts, Anum_pg_partitioned_table_partrelid, Anum_pg_partitioned_table_partstrat, Assert, buildint2vector(), buildoidvector(), CacheInvalidateRelcache(), CatalogTupleInsert(), CharGetDatum, ObjectAddress::classId, CollationRelationId, CStringGetTextDatum, DEPENDENCY_AUTO, DEPENDENCY_NORMAL, heap_close, heap_form_tuple(), heap_open(), i, Int16GetDatum, MemSet, Natts_pg_partitioned_table, nodeToString(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OperatorClassRelationId, PartitionedRelationId, PARTRELID, pfree(), PointerGetDatum, RelationData::rd_rel, recordDependencyOn(), recordDependencyOnSingleRelExpr(), RelationGetDescr, RelationGetRelid, RelationRelationId, RELKIND_PARTITIONED_TABLE, RowExclusiveLock, SearchSysCache1, and values.

Referenced by DefineRelation().

3078 {
3079  int i;
3080  int2vector *partattrs_vec;
3081  oidvector *partopclass_vec;
3082  oidvector *partcollation_vec;
3083  Datum partexprDatum;
3084  Relation pg_partitioned_table;
3085  HeapTuple tuple;
3087  bool nulls[Natts_pg_partitioned_table];
3088  ObjectAddress myself;
3089  ObjectAddress referenced;
3090 
3091  Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
3092 
3093  tuple = SearchSysCache1(PARTRELID,
3095 
3096  /* Copy the partition attribute numbers, opclass OIDs into arrays */
3097  partattrs_vec = buildint2vector(partattrs, partnatts);
3098  partopclass_vec = buildoidvector(partopclass, partnatts);
3099  partcollation_vec = buildoidvector(partcollation, partnatts);
3100 
3101  /* Convert the expressions (if any) to a text datum */
3102  if (partexprs)
3103  {
3104  char *exprString;
3105 
3106  exprString = nodeToString(partexprs);
3107  partexprDatum = CStringGetTextDatum(exprString);
3108  pfree(exprString);
3109  }
3110  else
3111  partexprDatum = (Datum) 0;
3112 
3113  pg_partitioned_table = heap_open(PartitionedRelationId, RowExclusiveLock);
3114 
3115  MemSet(nulls, false, sizeof(nulls));
3116 
3117  /* Only this can ever be NULL */
3118  if (!partexprDatum)
3119  nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
3120 
3122  values[Anum_pg_partitioned_table_partstrat - 1] = CharGetDatum(strategy);
3123  values[Anum_pg_partitioned_table_partnatts - 1] = Int16GetDatum(partnatts);
3124  values[Anum_pg_partitioned_table_partattrs - 1] = PointerGetDatum(partattrs_vec);
3125  values[Anum_pg_partitioned_table_partclass - 1] = PointerGetDatum(partopclass_vec);
3126  values[Anum_pg_partitioned_table_partcollation - 1] = PointerGetDatum(partcollation_vec);
3127  values[Anum_pg_partitioned_table_partexprs - 1] = partexprDatum;
3128 
3129  tuple = heap_form_tuple(RelationGetDescr(pg_partitioned_table), values, nulls);
3130 
3131  CatalogTupleInsert(pg_partitioned_table, tuple);
3132  heap_close(pg_partitioned_table, RowExclusiveLock);
3133 
3134  /* Mark this relation as dependent on a few things as follows */
3135  myself.classId = RelationRelationId;
3136  myself.objectId = RelationGetRelid(rel);;
3137  myself.objectSubId = 0;
3138 
3139  /* Operator class and collation per key column */
3140  for (i = 0; i < partnatts; i++)
3141  {
3142  referenced.classId = OperatorClassRelationId;
3143  referenced.objectId = partopclass[i];
3144  referenced.objectSubId = 0;
3145 
3146  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3147 
3148  referenced.classId = CollationRelationId;
3149  referenced.objectId = partcollation[i];
3150  referenced.objectSubId = 0;
3151 
3152  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3153  }
3154 
3155  /*
3156  * Anything mentioned in the expressions. We must ignore the column
3157  * references, which will depend on the table itself; there is no separate
3158  * partition key object.
3159  */
3160  if (partexprs)
3162  (Node *) partexprs,
3163  RelationGetRelid(rel),
3165  DEPENDENCY_AUTO, true);
3166 
3167  /*
3168  * We must invalidate the relcache so that the next
3169  * CommandCounterIncrement() will cause the same to be rebuilt using the
3170  * information in just created catalog entry.
3171  */
3173 }
Definition: c.h:474
#define RelationGetDescr(relation)
Definition: rel.h:425
#define Anum_pg_partitioned_table_partexprs
#define PointerGetDatum(X)
Definition: postgres.h:564
#define RelationRelationId
Definition: pg_class.h:29
int2vector * buildint2vector(const int16 *int2s, int n)
Definition: int.c:112
#define Int16GetDatum(X)
Definition: postgres.h:459
#define OperatorClassRelationId
Definition: pg_opclass.h:49
Definition: nodes.h:508
#define MemSet(start, val, len)
Definition: c.h:853
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:113
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define Anum_pg_partitioned_table_partrelid
void pfree(void *pointer)
Definition: mcxt.c:992
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define Anum_pg_partitioned_table_partcollation
#define PartitionedRelationId
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_partitioned_table_partnatts
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
Definition: c.h:463
uintptr_t Datum
Definition: postgres.h:374
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define CollationRelationId
Definition: pg_collation.h:30
#define Anum_pg_partitioned_table_partstrat
#define Assert(condition)
Definition: c.h:671
oidvector * buildoidvector(const Oid *oids, int n)
Definition: oid.c:167
#define Natts_pg_partitioned_table
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool ignore_self)
Definition: dependency.c:1373
#define CharGetDatum(X)
Definition: postgres.h:424
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1225
static Datum values[MAXATTR]
Definition: bootstrap.c:162
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:90
char * nodeToString(const void *obj)
Definition: outfuncs.c:3981
#define Anum_pg_partitioned_table_partclass
#define Anum_pg_partitioned_table_partattrs
#define RelationGetRelid(relation)
Definition: rel.h:413
static Oid StoreRelCheck ( Relation  rel,
char *  ccname,
Node expr,
bool  is_validated,
bool  is_local,
int  inhcount,
bool  is_no_inherit,
bool  is_internal 
)
static

Definition at line 1999 of file heap.c.

References CONSTRAINT_CHECK, CreateConstraintEntry(), deparse_context_for(), deparse_expression(), ereport, errcode(), errmsg(), ERROR, i, InvalidOid, lfirst, list_length(), nodeToString(), NULL, palloc(), pfree(), pull_var_clause(), RelationData::rd_rel, RelationGetNamespace, RelationGetRelationName, RelationGetRelid, RELKIND_PARTITIONED_TABLE, and Var::varattno.

Referenced by AddRelationNewConstraints(), and StoreConstraints().

2002 {
2003  char *ccbin;
2004  char *ccsrc;
2005  List *varList;
2006  int keycount;
2007  int16 *attNos;
2008  Oid constrOid;
2009 
2010  /*
2011  * Flatten expression to string form for storage.
2012  */
2013  ccbin = nodeToString(expr);
2014 
2015  /*
2016  * Also deparse it to form the mostly-obsolete consrc field.
2017  */
2018  ccsrc = deparse_expression(expr,
2020  RelationGetRelid(rel)),
2021  false, false);
2022 
2023  /*
2024  * Find columns of rel that are used in expr
2025  *
2026  * NB: pull_var_clause is okay here only because we don't allow subselects
2027  * in check constraints; it would fail to examine the contents of
2028  * subselects.
2029  */
2030  varList = pull_var_clause(expr, 0);
2031  keycount = list_length(varList);
2032 
2033  if (keycount > 0)
2034  {
2035  ListCell *vl;
2036  int i = 0;
2037 
2038  attNos = (int16 *) palloc(keycount * sizeof(int16));
2039  foreach(vl, varList)
2040  {
2041  Var *var = (Var *) lfirst(vl);
2042  int j;
2043 
2044  for (j = 0; j < i; j++)
2045  if (attNos[j] == var->varattno)
2046  break;
2047  if (j == i)
2048  attNos[i++] = var->varattno;
2049  }
2050  keycount = i;
2051  }
2052  else
2053  attNos = NULL;
2054 
2055  /*
2056  * Partitioned tables do not contain any rows themselves, so a NO INHERIT
2057  * constraint makes no sense.
2058  */
2059  if (is_no_inherit &&
2060  rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2061  ereport(ERROR,
2062  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2063  errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
2064  RelationGetRelationName(rel))));
2065 
2066  /*
2067  * Create the Check Constraint
2068  */
2069  constrOid =
2070  CreateConstraintEntry(ccname, /* Constraint Name */
2071  RelationGetNamespace(rel), /* namespace */
2072  CONSTRAINT_CHECK, /* Constraint Type */
2073  false, /* Is Deferrable */
2074  false, /* Is Deferred */
2075  is_validated,
2076  RelationGetRelid(rel), /* relation */
2077  attNos, /* attrs in the constraint */
2078  keycount, /* # attrs in the constraint */
2079  InvalidOid, /* not a domain constraint */
2080  InvalidOid, /* no associated index */
2081  InvalidOid, /* Foreign key fields */
2082  NULL,
2083  NULL,
2084  NULL,
2085  NULL,
2086  0,
2087  ' ',
2088  ' ',
2089  ' ',
2090  NULL, /* not an exclusion constraint */
2091  expr, /* Tree form of check constraint */
2092  ccbin, /* Binary form of check constraint */
2093  ccsrc, /* Source form of check constraint */
2094  is_local, /* conislocal */
2095  inhcount, /* coninhcount */
2096  is_no_inherit, /* connoinherit */
2097  is_internal); /* internally constructed? */
2098 
2099  pfree(ccbin);
2100  pfree(ccsrc);
2101 
2102  return constrOid;
2103 }
signed short int16
Definition: c.h:252
int errcode(int sqlerrcode)
Definition: elog.c:575
AttrNumber varattno
Definition: primnodes.h:146
List * pull_var_clause(Node *node, int flags)
Definition: var.c:535
Form_pg_class rd_rel
Definition: rel.h:113
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:141
#define CONSTRAINT_CHECK
void pfree(void *pointer)
Definition: mcxt.c:992
#define ERROR
Definition: elog.h:43
List * deparse_context_for(const char *aliasname, Oid relid)
Definition: ruleutils.c:2854
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define ereport(elevel, rest)
Definition: elog.h:122
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
char * deparse_expression(Node *expr, List *dpcontext, bool forceprefix, bool showimplicit)
Definition: ruleutils.c:2795
static int list_length(const List *l)
Definition: pg_list.h:89
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
char * nodeToString(const void *obj)
Definition: outfuncs.c:3981
Definition: pg_list.h:45
#define RelationGetRelid(relation)
Definition: rel.h:413
Oid CreateConstraintEntry(const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, bool isValidated, Oid relId, const int16 *constraintKey, int constraintNKeys, Oid domainId, Oid indexRelId, Oid foreignRelId, const int16 *foreignKey, const Oid *pfEqOp, const Oid *ppEqOp, const Oid *ffEqOp, int foreignNKeys, char foreignUpdateType, char foreignDeleteType, char foreignMatchType, const Oid *exclOp, Node *conExpr, const char *conBin, const char *conSrc, bool conIsLocal, int conInhCount, bool conNoInherit, bool is_internal)
Definition: pg_constraint.c:49
#define RelationGetNamespace(relation)
Definition: rel.h:440
Form_pg_attribute SystemAttributeByName ( const char *  attname,
bool  relhasoids 
)

Definition at line 212 of file heap.c.

References lengthof, NameStr, NULL, and ObjectIdAttributeNumber.

Referenced by CheckAttributeNamesTypes(), specialAttNum(), SPI_fnumber(), and transformIndexConstraint().

213 {
214  int j;
215 
216  for (j = 0; j < (int) lengthof(SysAtt); j++)
217  {
218  Form_pg_attribute att = SysAtt[j];
219 
220  if (relhasoids || att->attnum != ObjectIdAttributeNumber)
221  {
222  if (strcmp(NameStr(att->attname), attname) == 0)
223  return att;
224  }
225  }
226 
227  return NULL;
228 }
static const Form_pg_attribute SysAtt[]
Definition: heap.c:190
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define lengthof(array)
Definition: c.h:558
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
#define NULL
Definition: c.h:226
#define NameStr(name)
Definition: c.h:495
Form_pg_attribute SystemAttributeDefinition ( AttrNumber  attno,
bool  relhasoids 
)

Definition at line 198 of file heap.c.

References elog, ERROR, lengthof, and ObjectIdAttributeNumber.

Referenced by attnumAttName(), attnumTypeId(), build_index_tlist(), ConstructTupleDescriptor(), SPI_fname(), SPI_gettype(), SPI_gettypeid(), SPI_getvalue(), and transformIndexConstraint().

199 {
200  if (attno >= 0 || attno < -(int) lengthof(SysAtt))
201  elog(ERROR, "invalid system attribute number %d", attno);
202  if (attno == ObjectIdAttributeNumber && !relhasoids)
203  elog(ERROR, "invalid system attribute number %d", attno);
204  return SysAtt[-attno - 1];
205 }
static const Form_pg_attribute SysAtt[]
Definition: heap.c:190
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define lengthof(array)
Definition: c.h:558
#define ERROR
Definition: elog.h:43
#define elog
Definition: elog.h:219

Variable Documentation

Initial value:
= {
0, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
true, 'p', 'i', true, false, false, true, 0
}
uint32 TransactionId
Definition: c.h:394
#define XIDOID
Definition: pg_type.h:336
#define MinTransactionIdAttributeNumber
Definition: sysattr.h:23

Definition at line 154 of file heap.c.

Initial value:
= {
0, {"cmin"}, CIDOID, 0, sizeof(CommandId),
true, 'p', 'i', true, false, false, true, 0
}
uint32 CommandId
Definition: c.h:408
#define MinCommandIdAttributeNumber
Definition: sysattr.h:24
#define CIDOID
Definition: pg_type.h:340

Definition at line 160 of file heap.c.

Initial value:
= {
0, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
true, 'p', 'i', true, false, false, true, 0
}
uint32 TransactionId
Definition: c.h:394
#define XIDOID
Definition: pg_type.h:336
#define MaxTransactionIdAttributeNumber
Definition: sysattr.h:25

Definition at line 166 of file heap.c.

Initial value:
= {
0, {"cmax"}, CIDOID, 0, sizeof(CommandId),
true, 'p', 'i', true, false, false, true, 0
}
uint32 CommandId
Definition: c.h:408
#define MaxCommandIdAttributeNumber
Definition: sysattr.h:26
#define CIDOID
Definition: pg_type.h:340

Definition at line 172 of file heap.c.

Initial value:
= {
0, {"tableoid"}, OIDOID, 0, sizeof(Oid),
true, 'p', 'i', true, false, false, true, 0
}
#define OIDOID
Definition: pg_type.h:328
unsigned int Oid
Definition: postgres_ext.h:31
#define TableOidAttributeNumber
Definition: sysattr.h:27

Definition at line 184 of file heap.c.

Oid binary_upgrade_next_heap_pg_class_oid = InvalidOid

Definition at line 84 of file heap.c.

Referenced by binary_upgrade_set_next_heap_pg_class_oid(), and heap_create_with_catalog().

Oid binary_upgrade_next_toast_pg_class_oid = InvalidOid
const Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7}
static

Definition at line 190 of file heap.c.