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_subscription_rel.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/lmgr.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 654 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().

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

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

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

Referenced by heap_create_with_catalog().

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

2207 {
2208  List *cookedConstraints = NIL;
2210  TupleConstr *oldconstr;
2211  int numoldchecks;
2212  ParseState *pstate;
2213  RangeTblEntry *rte;
2214  int numchecks;
2215  List *checknames;
2216  ListCell *cell;
2217  Node *expr;
2218  CookedConstraint *cooked;
2219 
2220  /*
2221  * Get info about existing constraints.
2222  */
2223  tupleDesc = RelationGetDescr(rel);
2224  oldconstr = tupleDesc->constr;
2225  if (oldconstr)
2226  numoldchecks = oldconstr->num_check;
2227  else
2228  numoldchecks = 0;
2229 
2230  /*
2231  * Create a dummy ParseState and insert the target relation as its sole
2232  * rangetable entry. We need a ParseState for transformExpr.
2233  */
2234  pstate = make_parsestate(NULL);
2235  rte = addRangeTableEntryForRelation(pstate,
2236  rel,
2237  NULL,
2238  false,
2239  true);
2240  addRTEtoQuery(pstate, rte, true, true, true);
2241 
2242  /*
2243  * Process column default expressions.
2244  */
2245  foreach(cell, newColDefaults)
2246  {
2247  RawColumnDefault *colDef = (RawColumnDefault *) lfirst(cell);
2248  Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
2249  Oid defOid;
2250 
2251  expr = cookDefault(pstate, colDef->raw_default,
2252  atp->atttypid, atp->atttypmod,
2253  NameStr(atp->attname));
2254 
2255  /*
2256  * If the expression is just a NULL constant, we do not bother to make
2257  * an explicit pg_attrdef entry, since the default behavior is
2258  * equivalent.
2259  *
2260  * Note a nonobvious property of this test: if the column is of a
2261  * domain type, what we'll get is not a bare null Const but a
2262  * CoerceToDomain expr, so we will not discard the default. This is
2263  * critical because the column default needs to be retained to
2264  * override any default that the domain might have.
2265  */
2266  if (expr == NULL ||
2267  (IsA(expr, Const) &&((Const *) expr)->constisnull))
2268  continue;
2269 
2270  defOid = StoreAttrDefault(rel, colDef->attnum, expr, is_internal);
2271 
2272  cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2273  cooked->contype = CONSTR_DEFAULT;
2274  cooked->conoid = defOid;
2275  cooked->name = NULL;
2276  cooked->attnum = colDef->attnum;
2277  cooked->expr = expr;
2278  cooked->skip_validation = false;
2279  cooked->is_local = is_local;
2280  cooked->inhcount = is_local ? 0 : 1;
2281  cooked->is_no_inherit = false;
2282  cookedConstraints = lappend(cookedConstraints, cooked);
2283  }
2284 
2285  /*
2286  * Process constraint expressions.
2287  */
2288  numchecks = numoldchecks;
2289  checknames = NIL;
2290  foreach(cell, newConstraints)
2291  {
2292  Constraint *cdef = (Constraint *) lfirst(cell);
2293  char *ccname;
2294  Oid constrOid;
2295 
2296  if (cdef->contype != CONSTR_CHECK)
2297  continue;
2298 
2299  if (cdef->raw_expr != NULL)
2300  {
2301  Assert(cdef->cooked_expr == NULL);
2302 
2303  /*
2304  * Transform raw parsetree to executable expression, and verify
2305  * it's valid as a CHECK constraint.
2306  */
2307  expr = cookConstraint(pstate, cdef->raw_expr,
2309  }
2310  else
2311  {
2312  Assert(cdef->cooked_expr != NULL);
2313 
2314  /*
2315  * Here, we assume the parser will only pass us valid CHECK
2316  * expressions, so we do no particular checking.
2317  */
2318  expr = stringToNode(cdef->cooked_expr);
2319  }
2320 
2321  /*
2322  * Check name uniqueness, or generate a name if none was given.
2323  */
2324  if (cdef->conname != NULL)
2325  {
2326  ListCell *cell2;
2327 
2328  ccname = cdef->conname;
2329  /* Check against other new constraints */
2330  /* Needed because we don't do CommandCounterIncrement in loop */
2331  foreach(cell2, checknames)
2332  {
2333  if (strcmp((char *) lfirst(cell2), ccname) == 0)
2334  ereport(ERROR,
2336  errmsg("check constraint \"%s\" already exists",
2337  ccname)));
2338  }
2339 
2340  /* save name for future checks */
2341  checknames = lappend(checknames, ccname);
2342 
2343  /*
2344  * Check against pre-existing constraints. If we are allowed to
2345  * merge with an existing constraint, there's no more to do here.
2346  * (We omit the duplicate constraint from the result, which is
2347  * what ATAddCheckConstraint wants.)
2348  */
2349  if (MergeWithExistingConstraint(rel, ccname, expr,
2350  allow_merge, is_local,
2351  cdef->initially_valid,
2352  cdef->is_no_inherit))
2353  continue;
2354  }
2355  else
2356  {
2357  /*
2358  * When generating a name, we want to create "tab_col_check" for a
2359  * column constraint and "tab_check" for a table constraint. We
2360  * no longer have any info about the syntactic positioning of the
2361  * constraint phrase, so we approximate this by seeing whether the
2362  * expression references more than one column. (If the user
2363  * played by the rules, the result is the same...)
2364  *
2365  * Note: pull_var_clause() doesn't descend into sublinks, but we
2366  * eliminated those above; and anyway this only needs to be an
2367  * approximate answer.
2368  */
2369  List *vars;
2370  char *colname;
2371 
2372  vars = pull_var_clause(expr, 0);
2373 
2374  /* eliminate duplicates */
2375  vars = list_union(NIL, vars);
2376 
2377  if (list_length(vars) == 1)
2378  colname = get_attname(RelationGetRelid(rel),
2379  ((Var *) linitial(vars))->varattno);
2380  else
2381  colname = NULL;
2382 
2384  colname,
2385  "check",
2386  RelationGetNamespace(rel),
2387  checknames);
2388 
2389  /* save name for future checks */
2390  checknames = lappend(checknames, ccname);
2391  }
2392 
2393  /*
2394  * OK, store it.
2395  */
2396  constrOid =
2397  StoreRelCheck(rel, ccname, expr, cdef->initially_valid, is_local,
2398  is_local ? 0 : 1, cdef->is_no_inherit, is_internal);
2399 
2400  numchecks++;
2401 
2402  cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2403  cooked->contype = CONSTR_CHECK;
2404  cooked->conoid = constrOid;
2405  cooked->name = ccname;
2406  cooked->attnum = 0;
2407  cooked->expr = expr;
2408  cooked->skip_validation = cdef->skip_validation;
2409  cooked->is_local = is_local;
2410  cooked->inhcount = is_local ? 0 : 1;
2411  cooked->is_no_inherit = cdef->is_no_inherit;
2412  cookedConstraints = lappend(cookedConstraints, cooked);
2413  }
2414 
2415  /*
2416  * Update the count of constraints in the relation's pg_class tuple. We do
2417  * this even if there was no change, in order to ensure that an SI update
2418  * message is sent out for the pg_class tuple, which will force other
2419  * backends to rebuild their relcache entries for the rel. (This is
2420  * critical if we added defaults but not constraints.)
2421  */
2422  SetRelationNumChecks(rel, numchecks);
2423 
2424  return cookedConstraints;
2425 }
#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:560
static void SetRelationNumChecks(Relation rel, int numchecks)
Definition: heap.c:2588
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:2631
#define RelationGetDescr(relation)
Definition: rel.h:429
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:2014
Node * raw_expr
Definition: parsenodes.h:2056
static Node * cookConstraint(ParseState *pstate, Node *raw_constraint, char *relname)
Definition: heap.c:2702
Form_pg_attribute * attrs
Definition: tupdesc.h:74
Definition: nodes.h:509
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:2049
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:163
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:111
#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:2438
int inhcount
Definition: heap.h:37
#define RelationGetRelationName(relation)
Definition: rel.h:437
Node * raw_default
Definition: heap.h:25
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
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:115
bool is_no_inherit
Definition: parsenodes.h:2055
bool initially_valid
Definition: parsenodes.h:2086
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#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:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
Oid conoid
Definition: heap.h:31
#define NameStr(name)
Definition: c.h:499
ConstrType contype
Definition: parsenodes.h:2046
Node * expr
Definition: heap.h:34
uint16 num_check
Definition: tupdesc.h:42
char * cooked_expr
Definition: parsenodes.h:2057
Oid StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr, bool is_internal)
Definition: heap.c:1901
Definition: regcomp.c:224
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
Definition: pg_list.h:45
bool skip_validation
Definition: parsenodes.h:2085
char * name
Definition: heap.h:32
#define RelationGetRelid(relation)
Definition: rel.h:417
bool is_local
Definition: heap.h:36
#define RelationGetNamespace(relation)
Definition: rel.h:444
void CheckAttributeNamesTypes ( TupleDesc  tupdesc,
char  relkind,
bool  allow_system_table_mods 
)

Definition at line 410 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().

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

Definition at line 488 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().

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

Definition at line 2702 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().

2705 {
2706  Node *expr;
2707 
2708  /*
2709  * Transform raw parsetree to executable expression.
2710  */
2711  expr = transformExpr(pstate, raw_constraint, EXPR_KIND_CHECK_CONSTRAINT);
2712 
2713  /*
2714  * Make sure it yields a boolean result.
2715  */
2716  expr = coerce_to_boolean(pstate, expr, "CHECK");
2717 
2718  /*
2719  * Take care of collations.
2720  */
2721  assign_expr_collations(pstate, expr);
2722 
2723  /*
2724  * Make sure no outside relations are referred to (this is probably dead
2725  * code now that add_missing_from is history).
2726  */
2727  if (list_length(pstate->p_rtable) != 1)
2728  ereport(ERROR,
2729  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2730  errmsg("only table \"%s\" can be referenced in check constraint",
2731  relname)));
2732 
2733  return expr;
2734 }
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:147
Definition: nodes.h:509
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:169
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 2631 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().

2636 {
2637  Node *expr;
2638 
2639  Assert(raw_default != NULL);
2640 
2641  /*
2642  * Transform raw parsetree to executable expression.
2643  */
2644  expr = transformExpr(pstate, raw_default, EXPR_KIND_COLUMN_DEFAULT);
2645 
2646  /*
2647  * Make sure default expr does not refer to any vars (we need this check
2648  * since the pstate includes the target table).
2649  */
2650  if (contain_var_clause(expr))
2651  ereport(ERROR,
2652  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2653  errmsg("cannot use column references in default expression")));
2654 
2655  /*
2656  * transformExpr() should have already rejected subqueries, aggregates,
2657  * window functions, and SRFs, based on the EXPR_KIND_ for a default
2658  * expression.
2659  */
2660 
2661  /*
2662  * Coerce the expression to the correct type and typmod, if given. This
2663  * should match the parser's processing of non-defaulted expressions ---
2664  * see transformAssignedExpr().
2665  */
2666  if (OidIsValid(atttypid))
2667  {
2668  Oid type_id = exprType(expr);
2669 
2670  expr = coerce_to_target_type(pstate, expr, type_id,
2671  atttypid, atttypmod,
2674  -1);
2675  if (expr == NULL)
2676  ereport(ERROR,
2677  (errcode(ERRCODE_DATATYPE_MISMATCH),
2678  errmsg("column \"%s\" is of type %s"
2679  " but default expression is of type %s",
2680  attname,
2681  format_type_be(atttypid),
2682  format_type_be(type_id)),
2683  errhint("You will need to rewrite or cast the expression.")));
2684  }
2685 
2686  /*
2687  * Finally, take care of collations in the finished expression.
2688  */
2689  assign_expr_collations(pstate, expr);
2690 
2691  return expr;
2692 }
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:509
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:538
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:229
#define Assert(condition)
Definition: c.h:675
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 1463 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().

1464 {
1465  Relation attrel;
1466  SysScanDesc scan;
1467  ScanKeyData key[1];
1468  HeapTuple atttup;
1469 
1470  /* Grab an appropriate lock on the pg_attribute relation */
1472 
1473  /* Use the index to scan only attributes of the target relation */
1474  ScanKeyInit(&key[0],
1476  BTEqualStrategyNumber, F_OIDEQ,
1477  ObjectIdGetDatum(relid));
1478 
1479  scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,
1480  NULL, 1, key);
1481 
1482  /* Delete all the matching tuples */
1483  while ((atttup = systable_getnext(scan)) != NULL)
1484  CatalogTupleDelete(attrel, &atttup->t_self);
1485 
1486  /* Clean up after the scan */
1487  systable_endscan(scan);
1488  heap_close(attrel, RowExclusiveLock);
1489 }
#define AttributeRelidNumIndexId
Definition: indexing.h:94
#define Anum_pg_attribute_attrelid
Definition: pg_attribute.h:195
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#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:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define NULL
Definition: c.h:229
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 1434 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().

1435 {
1436  Relation pg_class_desc;
1437  HeapTuple tup;
1438 
1439  /* Grab an appropriate lock on the pg_class relation */
1440  pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);
1441 
1442  tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1443  if (!HeapTupleIsValid(tup))
1444  elog(ERROR, "cache lookup failed for relation %u", relid);
1445 
1446  /* delete the relation tuple from pg_class, and finish up */
1447  CatalogTupleDelete(pg_class_desc, &tup->t_self);
1448 
1449  ReleaseSysCache(tup);
1450 
1451  heap_close(pg_class_desc, RowExclusiveLock);
1452 }
#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:156
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:1117
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
void DeleteSystemAttributeTuples ( Oid  relid)

Definition at line 1500 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().

1501 {
1502  Relation attrel;
1503  SysScanDesc scan;
1504  ScanKeyData key[2];
1505  HeapTuple atttup;
1506 
1507  /* Grab an appropriate lock on the pg_attribute relation */
1509 
1510  /* Use the index to scan only system attributes of the target relation */
1511  ScanKeyInit(&key[0],
1513  BTEqualStrategyNumber, F_OIDEQ,
1514  ObjectIdGetDatum(relid));
1515  ScanKeyInit(&key[1],
1517  BTLessEqualStrategyNumber, F_INT2LE,
1518  Int16GetDatum(0));
1519 
1520  scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,
1521  NULL, 2, key);
1522 
1523  /* Delete all the matching tuples */
1524  while ((atttup = systable_getnext(scan)) != NULL)
1525  CatalogTupleDelete(attrel, &atttup->t_self);
1526 
1527  /* Clean up after the scan */
1528  systable_endscan(scan);
1529  heap_close(attrel, RowExclusiveLock);
1530 }
#define AttributeRelidNumIndexId
Definition: indexing.h:94
#define Anum_pg_attribute_attrelid
Definition: pg_attribute.h:195
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define Anum_pg_attribute_attnum
Definition: pg_attribute.h:200
#define Int16GetDatum(X)
Definition: postgres.h:457
#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:328
#define BTLessEqualStrategyNumber
Definition: stratnum.h:30
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define NULL
Definition: c.h:229
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 250 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_PARTITIONED_TABLE, RELKIND_SEQUENCE, and RELKIND_VIEW.

Referenced by heap_create_with_catalog(), and index_create().

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

References Assert, INIT_FORKNUM, log_smgrcreate(), RelFileNodeBackend::node, RelationData::rd_rel, RelationData::rd_smgr, RelationOpenSmgr, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_TOASTVALUE, SMgrRelationData::smgr_rnode, smgrcreate(), and smgrimmedsync().

Referenced by ExecuteTruncate(), and heap_create_with_catalog().

1381 {
1382  Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
1383  rel->rd_rel->relkind == RELKIND_MATVIEW ||
1384  rel->rd_rel->relkind == RELKIND_TOASTVALUE);
1385  RelationOpenSmgr(rel);
1386  smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
1389 }
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:376
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
#define RELKIND_MATVIEW
Definition: pg_class.h:165
Form_pg_class rd_rel
Definition: rel.h:114
#define RelationOpenSmgr(relation)
Definition: rel.h:461
RelFileNodeBackend smgr_rnode
Definition: smgr.h:43
#define RELKIND_TOASTVALUE
Definition: pg_class.h:163
RelFileNode node
Definition: relfilenode.h:74
#define Assert(condition)
Definition: c.h:675
void log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum)
Definition: storage.c:125
#define RELKIND_RELATION
Definition: pg_class.h:160
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 1019 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().

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

Definition at line 1756 of file heap.c.

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

Referenced by doDeletion().

1757 {
1758  Relation rel;
1759  HeapTuple tuple;
1760  Oid parentOid = InvalidOid;
1761 
1762  /*
1763  * To drop a partition safely, we must grab exclusive lock on its parent,
1764  * because another backend might be about to execute a query on the parent
1765  * table. If it relies on previously cached partition descriptor, then it
1766  * could attempt to access the just-dropped relation as its partition. We
1767  * must therefore take a table lock strong enough to prevent all queries
1768  * on the table from proceeding until we commit and send out a
1769  * shared-cache-inval notice that will make them update their index lists.
1770  */
1771  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1772  if (((Form_pg_class) GETSTRUCT(tuple))->relispartition)
1773  {
1774  parentOid = get_partition_parent(relid);
1776  }
1777 
1778  ReleaseSysCache(tuple);
1779 
1780  /*
1781  * Open and lock the relation.
1782  */
1783  rel = relation_open(relid, AccessExclusiveLock);
1784 
1785  /*
1786  * There can no longer be anyone *else* touching the relation, but we
1787  * might still have open queries or cursors, or pending trigger events, in
1788  * our own session.
1789  */
1790  CheckTableNotInUse(rel, "DROP TABLE");
1791 
1792  /*
1793  * This effectively deletes all rows in the table, and may be done in a
1794  * serializable transaction. In that case we must record a rw-conflict in
1795  * to this transaction from each transaction holding a predicate lock on
1796  * the table.
1797  */
1799 
1800  /*
1801  * Delete pg_foreign_table tuple first.
1802  */
1803  if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1804  {
1805  Relation rel;
1806  HeapTuple tuple;
1807 
1809 
1811  if (!HeapTupleIsValid(tuple))
1812  elog(ERROR, "cache lookup failed for foreign table %u", relid);
1813 
1814  CatalogTupleDelete(rel, &tuple->t_self);
1815 
1816  ReleaseSysCache(tuple);
1818  }
1819 
1820  /*
1821  * If a partitioned table, delete the pg_partitioned_table tuple.
1822  */
1823  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1825 
1826  /*
1827  * Schedule unlinking of the relation's physical files at commit.
1828  */
1829  if (rel->rd_rel->relkind != RELKIND_VIEW &&
1830  rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
1831  rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
1832  rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1833  {
1834  RelationDropStorage(rel);
1835  }
1836 
1837  /*
1838  * Close relcache entry, but *keep* AccessExclusiveLock on the relation
1839  * until transaction commit. This ensures no one else will try to do
1840  * something with the doomed relation.
1841  */
1842  relation_close(rel, NoLock);
1843 
1844  /*
1845  * Remove any associated relation synchronization states.
1846  */
1848 
1849  /*
1850  * Forget any ON COMMIT action for the rel
1851  */
1852  remove_on_commit_action(relid);
1853 
1854  /*
1855  * Flush the relation from the relcache. We want to do this before
1856  * starting to remove catalog entries, just to be certain that no relcache
1857  * entry rebuild will happen partway through. (That should not really
1858  * matter, since we don't do CommandCounterIncrement here, but let's be
1859  * safe.)
1860  */
1861  RelationForgetRelation(relid);
1862 
1863  /*
1864  * remove inheritance information
1865  */
1867 
1868  /*
1869  * delete statistics
1870  */
1871  RemoveStatistics(relid, 0);
1872 
1873  /*
1874  * delete attribute tuples
1875  */
1876  DeleteAttributeTuples(relid);
1877 
1878  /*
1879  * delete relation tuple
1880  */
1881  DeleteRelationTuple(relid);
1882 
1883  if (OidIsValid(parentOid))
1884  {
1885  /*
1886  * Invalidate the parent's relcache so that the partition is no longer
1887  * included in its partition descriptor.
1888  */
1889  CacheInvalidateRelcacheByRelid(parentOid);
1890  /* keep the lock */
1891  }
1892 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
void RemoveSubscriptionRel(Oid subid, Oid relid)
void remove_on_commit_action(Oid relid)
Definition: tablecmds.c:12744
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1260
void RelationForgetRelation(Oid rid)
Definition: relcache.c:2680
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:114
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:166
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
Oid get_partition_parent(Oid relid)
Definition: partition.c:851
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition: inval.c:1292
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:167
void CheckTableNotInUse(Relation rel, const char *stmt)
Definition: tablecmds.c:2997
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
void RelationDropStorage(Relation rel)
Definition: storage.c:145
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define InvalidOid
Definition: postgres_ext.h:36
void DeleteRelationTuple(Oid relid)
Definition: heap.c:1434
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static void RelationRemoveInheritance(Oid relid)
Definition: heap.c:1401
void CheckTableForSerializableConflictIn(Relation relation)
Definition: predicate.c:4391
void DeleteAttributeTuples(Oid relid)
Definition: heap.c:1463
void RemoveStatistics(Oid relid, AttrNumber attnum)
Definition: heap.c:2744
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define AccessExclusiveLock
Definition: lockdefs.h:46
void RemovePartitionKeyByRelId(Oid relid)
Definition: heap.c:3195
#define RELKIND_VIEW
Definition: pg_class.h:164
#define ForeignTableRelationId
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1114
#define elog
Definition: elog.h:219
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:105
void heap_truncate ( List relids)

Definition at line 2832 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().

2833 {
2834  List *relations = NIL;
2835  ListCell *cell;
2836 
2837  /* Open relations for processing, and grab exclusive access on each */
2838  foreach(cell, relids)
2839  {
2840  Oid rid = lfirst_oid(cell);
2841  Relation rel;
2842 
2843  rel = heap_open(rid, AccessExclusiveLock);
2844  relations = lappend(relations, rel);
2845  }
2846 
2847  /* Don't allow truncate on tables that are referenced by foreign keys */
2848  heap_truncate_check_FKs(relations, true);
2849 
2850  /* OK to do it */
2851  foreach(cell, relations)
2852  {
2853  Relation rel = lfirst(cell);
2854 
2855  /* Truncate the relation */
2856  heap_truncate_one_rel(rel);
2857 
2858  /* Close the relation, but keep exclusive lock on it until commit */
2859  heap_close(rel, NoLock);
2860  }
2861 }
#define NIL
Definition: pg_list.h:69
void heap_truncate_one_rel(Relation rel)
Definition: heap.c:2873
void heap_truncate_check_FKs(List *relations, bool tempTables)
Definition: heap.c:2910
#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:1284
#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 2910 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().

2911 {
2912  List *oids = NIL;
2913  List *dependents;
2914  ListCell *cell;
2915 
2916  /*
2917  * Build a list of OIDs of the interesting relations.
2918  *
2919  * If a relation has no triggers, then it can neither have FKs nor be
2920  * referenced by a FK from another table, so we can ignore it.
2921  */
2922  foreach(cell, relations)
2923  {
2924  Relation rel = lfirst(cell);
2925 
2926  if (rel->rd_rel->relhastriggers)
2927  oids = lappend_oid(oids, RelationGetRelid(rel));
2928  }
2929 
2930  /*
2931  * Fast path: if no relation has triggers, none has FKs either.
2932  */
2933  if (oids == NIL)
2934  return;
2935 
2936  /*
2937  * Otherwise, must scan pg_constraint. We make one pass with all the
2938  * relations considered; if this finds nothing, then all is well.
2939  */
2940  dependents = heap_truncate_find_FKs(oids);
2941  if (dependents == NIL)
2942  return;
2943 
2944  /*
2945  * Otherwise we repeat the scan once per relation to identify a particular
2946  * pair of relations to complain about. This is pretty slow, but
2947  * performance shouldn't matter much in a failure path. The reason for
2948  * doing things this way is to ensure that the message produced is not
2949  * dependent on chance row locations within pg_constraint.
2950  */
2951  foreach(cell, oids)
2952  {
2953  Oid relid = lfirst_oid(cell);
2954  ListCell *cell2;
2955 
2956  dependents = heap_truncate_find_FKs(list_make1_oid(relid));
2957 
2958  foreach(cell2, dependents)
2959  {
2960  Oid relid2 = lfirst_oid(cell2);
2961 
2962  if (!list_member_oid(oids, relid2))
2963  {
2964  char *relname = get_rel_name(relid);
2965  char *relname2 = get_rel_name(relid2);
2966 
2967  if (tempTables)
2968  ereport(ERROR,
2969  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2970  errmsg("unsupported ON COMMIT and foreign key combination"),
2971  errdetail("Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting.",
2972  relname2, relname)));
2973  else
2974  ereport(ERROR,
2975  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2976  errmsg("cannot truncate a table referenced in a foreign key constraint"),
2977  errdetail("Table \"%s\" references \"%s\".",
2978  relname2, relname),
2979  errhint("Truncate table \"%s\" at the same time, "
2980  "or use TRUNCATE ... CASCADE.",
2981  relname2)));
2982  }
2983  }
2984  }
2985 }
#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:114
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:151
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:1726
#define RelationGetRelid(relation)
Definition: rel.h:417
List * heap_truncate_find_FKs(List *relationIds)
Definition: heap.c:3002
#define lfirst_oid(lc)
Definition: pg_list.h:108
List* heap_truncate_find_FKs ( List relationIds)

Definition at line 3002 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, result, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by ExecuteTruncate(), and heap_truncate_check_FKs().

3003 {
3004  List *result = NIL;
3005  Relation fkeyRel;
3006  SysScanDesc fkeyScan;
3007  HeapTuple tuple;
3008 
3009  /*
3010  * Must scan pg_constraint. Right now, it is a seqscan because there is
3011  * no available index on confrelid.
3012  */
3014 
3015  fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false,
3016  NULL, 0, NULL);
3017 
3018  while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan)))
3019  {
3021 
3022  /* Not a foreign key */
3023  if (con->contype != CONSTRAINT_FOREIGN)
3024  continue;
3025 
3026  /* Not referencing one of our list of tables */
3027  if (!list_member_oid(relationIds, con->confrelid))
3028  continue;
3029 
3030  /* Add referencer unless already in input or result list */
3031  if (!list_member_oid(relationIds, con->conrelid))
3032  result = insert_ordered_unique_oid(result, con->conrelid);
3033  }
3034 
3035  systable_endscan(fkeyScan);
3036  heap_close(fkeyRel, AccessShareLock);
3037 
3038  return result;
3039 }
#define NIL
Definition: pg_list.h:69
#define CONSTRAINT_FOREIGN
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define AccessShareLock
Definition: lockdefs.h:36
return result
Definition: formatting.c:1632
#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:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#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:229
static List * insert_ordered_unique_oid(List *list, Oid datum)
Definition: heap.c:3052
#define ConstraintRelationId
Definition: pg_constraint.h:29
Definition: pg_list.h:45
void heap_truncate_one_rel ( Relation  rel)

Definition at line 2873 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_truncate().

2874 {
2875  Oid toastrelid;
2876 
2877  /* Truncate the actual file (and discard buffers) */
2878  RelationTruncate(rel, 0);
2879 
2880  /* If the relation has indexes, truncate the indexes too */
2882 
2883  /* If there is a toast table, truncate that too */
2884  toastrelid = rel->rd_rel->reltoastrelid;
2885  if (OidIsValid(toastrelid))
2886  {
2887  Relation toastrel = heap_open(toastrelid, AccessExclusiveLock);
2888 
2889  RelationTruncate(toastrel, 0);
2890  RelationTruncateIndexes(toastrel);
2891  /* keep the lock... */
2892  heap_close(toastrel, NoLock);
2893  }
2894 }
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define NoLock
Definition: lockdefs.h:34
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define AccessExclusiveLock
Definition: lockdefs.h:46
static void RelationTruncateIndexes(Relation heapRelation)
Definition: heap.c:2791
void RelationTruncate(Relation rel, BlockNumber nblocks)
Definition: storage.c:227
static List * insert_ordered_unique_oid ( List list,
Oid  datum 
)
static

Definition at line 3052 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().

3053 {
3054  ListCell *prev;
3055 
3056  /* Does the datum belong at the front? */
3057  if (list == NIL || datum < linitial_oid(list))
3058  return lcons_oid(datum, list);
3059  /* Does it match the first entry? */
3060  if (datum == linitial_oid(list))
3061  return list; /* duplicate, so don't insert */
3062  /* No, so find the entry it belongs after */
3063  prev = list_head(list);
3064  for (;;)
3065  {
3066  ListCell *curr = lnext(prev);
3067 
3068  if (curr == NULL || datum < lfirst_oid(curr))
3069  break; /* it belongs after 'prev', before 'curr' */
3070 
3071  if (datum == lfirst_oid(curr))
3072  return list; /* duplicate, so don't insert */
3073 
3074  prev = curr;
3075  }
3076  /* Insert datum into list after 'prev' */
3077  lappend_cell_oid(list, prev, datum);
3078  return list;
3079 }
#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:229
#define linitial_oid(l)
Definition: pg_list.h:113
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 598 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_attidentity, 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().

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

Definition at line 764 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().

769 {
770  Form_pg_class rd_rel = new_rel_desc->rd_rel;
772  bool nulls[Natts_pg_class];
773  HeapTuple tup;
774 
775  /* This is a tad tedious, but way cleaner than what we used to do... */
776  memset(values, 0, sizeof(values));
777  memset(nulls, false, sizeof(nulls));
778 
779  values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname);
780  values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace);
781  values[Anum_pg_class_reltype - 1] = ObjectIdGetDatum(rd_rel->reltype);
782  values[Anum_pg_class_reloftype - 1] = ObjectIdGetDatum(rd_rel->reloftype);
783  values[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(rd_rel->relowner);
784  values[Anum_pg_class_relam - 1] = ObjectIdGetDatum(rd_rel->relam);
785  values[Anum_pg_class_relfilenode - 1] = ObjectIdGetDatum(rd_rel->relfilenode);
786  values[Anum_pg_class_reltablespace - 1] = ObjectIdGetDatum(rd_rel->reltablespace);
787  values[Anum_pg_class_relpages - 1] = Int32GetDatum(rd_rel->relpages);
788  values[Anum_pg_class_reltuples - 1] = Float4GetDatum(rd_rel->reltuples);
789  values[Anum_pg_class_relallvisible - 1] = Int32GetDatum(rd_rel->relallvisible);
790  values[Anum_pg_class_reltoastrelid - 1] = ObjectIdGetDatum(rd_rel->reltoastrelid);
791  values[Anum_pg_class_relhasindex - 1] = BoolGetDatum(rd_rel->relhasindex);
792  values[Anum_pg_class_relisshared - 1] = BoolGetDatum(rd_rel->relisshared);
793  values[Anum_pg_class_relpersistence - 1] = CharGetDatum(rd_rel->relpersistence);
794  values[Anum_pg_class_relkind - 1] = CharGetDatum(rd_rel->relkind);
795  values[Anum_pg_class_relnatts - 1] = Int16GetDatum(rd_rel->relnatts);
796  values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks);
797  values[Anum_pg_class_relhasoids - 1] = BoolGetDatum(rd_rel->relhasoids);
798  values[Anum_pg_class_relhaspkey - 1] = BoolGetDatum(rd_rel->relhaspkey);
799  values[Anum_pg_class_relhasrules - 1] = BoolGetDatum(rd_rel->relhasrules);
800  values[Anum_pg_class_relhastriggers - 1] = BoolGetDatum(rd_rel->relhastriggers);
801  values[Anum_pg_class_relrowsecurity - 1] = BoolGetDatum(rd_rel->relrowsecurity);
802  values[Anum_pg_class_relforcerowsecurity - 1] = BoolGetDatum(rd_rel->relforcerowsecurity);
803  values[Anum_pg_class_relhassubclass - 1] = BoolGetDatum(rd_rel->relhassubclass);
804  values[Anum_pg_class_relispopulated - 1] = BoolGetDatum(rd_rel->relispopulated);
805  values[Anum_pg_class_relreplident - 1] = CharGetDatum(rd_rel->relreplident);
806  values[Anum_pg_class_relispartition - 1] = BoolGetDatum(rd_rel->relispartition);
807  values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
808  values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
809  if (relacl != (Datum) 0)
810  values[Anum_pg_class_relacl - 1] = relacl;
811  else
812  nulls[Anum_pg_class_relacl - 1] = true;
813  if (reloptions != (Datum) 0)
814  values[Anum_pg_class_reloptions - 1] = reloptions;
815  else
816  nulls[Anum_pg_class_reloptions - 1] = true;
817 
818  /* relpartbound is set by updating this tuple, if necessary */
819  nulls[Anum_pg_class_relpartbound - 1] = true;
820 
821  tup = heap_form_tuple(RelationGetDescr(pg_class_desc), values, nulls);
822 
823  /*
824  * The new tuple must have the oid already chosen for the rel. Sure would
825  * be embarrassing to do this sort of thing in polite company.
826  */
827  HeapTupleSetOid(tup, new_rel_oid);
828 
829  /* finally insert the new tuple, update the indexes, and clean up */
830  CatalogTupleInsert(pg_class_desc, tup);
831 
832  heap_freetuple(tup);
833 }
#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:601
#define Anum_pg_class_relacl
Definition: pg_class.h:133
#define MultiXactIdGetDatum(X)
Definition: postgres.h:534
#define RelationGetDescr(relation)
Definition: rel.h:429
#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:457
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
Form_pg_class rd_rel
Definition: rel.h:114
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1372
#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:513
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:1803
#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:527
#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:372
#define Anum_pg_class_reltuples
Definition: pg_class.h:112
#define BoolGetDatum(X)
Definition: postgres.h:408
#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:422
static Datum values[MAXATTR]
Definition: bootstrap.c:163
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define Int32GetDatum(X)
Definition: postgres.h:485
#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 2438 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().

2442 {
2443  bool found;
2444  Relation conDesc;
2445  SysScanDesc conscan;
2446  ScanKeyData skey[2];
2447  HeapTuple tup;
2448 
2449  /* Search for a pg_constraint entry with same name and relation */
2451 
2452  found = false;
2453 
2454  ScanKeyInit(&skey[0],
2456  BTEqualStrategyNumber, F_NAMEEQ,
2457  CStringGetDatum(ccname));
2458 
2459  ScanKeyInit(&skey[1],
2461  BTEqualStrategyNumber, F_OIDEQ,
2463 
2464  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
2465  NULL, 2, skey);
2466 
2467  while (HeapTupleIsValid(tup = systable_getnext(conscan)))
2468  {
2470 
2471  if (con->conrelid == RelationGetRelid(rel))
2472  {
2473  /* Found it. Conflicts if not identical check constraint */
2474  if (con->contype == CONSTRAINT_CHECK)
2475  {
2476  Datum val;
2477  bool isnull;
2478 
2479  val = fastgetattr(tup,
2481  conDesc->rd_att, &isnull);
2482  if (isnull)
2483  elog(ERROR, "null conbin for rel %s",
2485  if (equal(expr, stringToNode(TextDatumGetCString(val))))
2486  found = true;
2487  }
2488 
2489  /*
2490  * If the existing constraint is purely inherited (no local
2491  * definition) then interpret addition of a local constraint as a
2492  * legal merge. This allows ALTER ADD CONSTRAINT on parent and
2493  * child tables to be given in either order with same end state.
2494  * However if the relation is a partition, all inherited
2495  * constraints are always non-local, including those that were
2496  * merged.
2497  */
2498  if (is_local && !con->conislocal && !rel->rd_rel->relispartition)
2499  allow_merge = true;
2500 
2501  if (!found || !allow_merge)
2502  ereport(ERROR,
2504  errmsg("constraint \"%s\" for relation \"%s\" already exists",
2505  ccname, RelationGetRelationName(rel))));
2506 
2507  /* If the child constraint is "no inherit" then cannot merge */
2508  if (con->connoinherit)
2509  ereport(ERROR,
2510  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2511  errmsg("constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"",
2512  ccname, RelationGetRelationName(rel))));
2513 
2514  /*
2515  * Must not change an existing inherited constraint to "no
2516  * inherit" status. That's because inherited constraints should
2517  * be able to propagate to lower-level children.
2518  */
2519  if (con->coninhcount > 0 && is_no_inherit)
2520  ereport(ERROR,
2521  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2522  errmsg("constraint \"%s\" conflicts with inherited constraint on relation \"%s\"",
2523  ccname, RelationGetRelationName(rel))));
2524 
2525  /*
2526  * If the child constraint is "not valid" then cannot merge with a
2527  * valid parent constraint
2528  */
2529  if (is_initially_valid && !con->convalidated)
2530  ereport(ERROR,
2531  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2532  errmsg("constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"",
2533  ccname, RelationGetRelationName(rel))));
2534 
2535  /* OK to update the tuple */
2536  ereport(NOTICE,
2537  (errmsg("merging constraint \"%s\" with inherited definition",
2538  ccname)));
2539 
2540  tup = heap_copytuple(tup);
2541  con = (Form_pg_constraint) GETSTRUCT(tup);
2542 
2543  /*
2544  * In case of partitions, an inherited constraint must be
2545  * inherited only once since it cannot have multiple parents and
2546  * it is never considered local.
2547  */
2548  if (rel->rd_rel->relispartition)
2549  {
2550  con->coninhcount = 1;
2551  con->conislocal = false;
2552  }
2553  else
2554  {
2555  if (is_local)
2556  con->conislocal = true;
2557  else
2558  con->coninhcount++;
2559  }
2560 
2561  if (is_no_inherit)
2562  {
2563  Assert(is_local);
2564  con->connoinherit = true;
2565  }
2566  CatalogTupleUpdate(conDesc, &tup->t_self, tup);
2567  break;
2568  }
2569  }
2570 
2571  systable_endscan(conscan);
2572  heap_close(conDesc, RowExclusiveLock);
2573 
2574  return found;
2575 }
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:499
#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:2962
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:114
#define Anum_pg_constraint_conbin
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define CONSTRAINT_CHECK
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:584
#define RelationGetRelationName(relation)
Definition: rel.h:437
#define ereport(elevel, rest)
Definition: elog.h:122
#define TextDatumGetCString(d)
Definition: builtins.h:92
uintptr_t Datum
Definition: postgres.h:372
#define Anum_pg_constraint_connamespace
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
TupleDesc rd_att
Definition: rel.h:115
#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:229
#define Assert(condition)
Definition: c.h:675
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:31
#define RelationGetRelid(relation)
Definition: rel.h:417
long val
Definition: informix.c:689
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define RelationGetNamespace(relation)
Definition: rel.h:444
static void RelationRemoveInheritance ( Oid  relid)
static

Definition at line 1401 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().

1402 {
1403  Relation catalogRelation;
1404  SysScanDesc scan;
1405  ScanKeyData key;
1406  HeapTuple tuple;
1407 
1408  catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
1409 
1410  ScanKeyInit(&key,
1412  BTEqualStrategyNumber, F_OIDEQ,
1413  ObjectIdGetDatum(relid));
1414 
1415  scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, true,
1416  NULL, 1, &key);
1417 
1418  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1419  CatalogTupleDelete(catalogRelation, &tuple->t_self);
1420 
1421  systable_endscan(scan);
1422  heap_close(catalogRelation, RowExclusiveLock);
1423 }
#define Anum_pg_inherits_inhrelid
Definition: pg_inherits.h:50
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
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:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#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 2791 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().

2792 {
2793  ListCell *indlist;
2794 
2795  /* Ask the relcache to produce a list of the indexes of the rel */
2796  foreach(indlist, RelationGetIndexList(heapRelation))
2797  {
2798  Oid indexId = lfirst_oid(indlist);
2799  Relation currentIndex;
2800  IndexInfo *indexInfo;
2801 
2802  /* Open the index relation; use exclusive lock, just to be sure */
2803  currentIndex = index_open(indexId, AccessExclusiveLock);
2804 
2805  /* Fetch info needed for index_build */
2806  indexInfo = BuildIndexInfo(currentIndex);
2807 
2808  /*
2809  * Now truncate the actual file (and discard buffers).
2810  */
2811  RelationTruncate(currentIndex, 0);
2812 
2813  /* Initialize the index and rebuild */
2814  /* Note: we do not need to re-establish pkey setting */
2815  index_build(heapRelation, currentIndex, indexInfo, false, true);
2816 
2817  /* We're done with this index */
2818  index_close(currentIndex, NoLock);
2819  }
2820 }
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:1640
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:4345
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 1629 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().

1631 {
1632  Relation attrdef_rel;
1633  ScanKeyData scankeys[2];
1634  SysScanDesc scan;
1635  HeapTuple tuple;
1636  bool found = false;
1637 
1639 
1640  ScanKeyInit(&scankeys[0],
1642  BTEqualStrategyNumber, F_OIDEQ,
1643  ObjectIdGetDatum(relid));
1644  ScanKeyInit(&scankeys[1],
1646  BTEqualStrategyNumber, F_INT2EQ,
1647  Int16GetDatum(attnum));
1648 
1649  scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true,
1650  NULL, 2, scankeys);
1651 
1652  /* There should be at most one matching tuple, but we loop anyway */
1653  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1654  {
1655  ObjectAddress object;
1656 
1657  object.classId = AttrDefaultRelationId;
1658  object.objectId = HeapTupleGetOid(tuple);
1659  object.objectSubId = 0;
1660 
1661  performDeletion(&object, behavior,
1662  internal ? PERFORM_DELETION_INTERNAL : 0);
1663 
1664  found = true;
1665  }
1666 
1667  systable_endscan(scan);
1668  heap_close(attrdef_rel, RowExclusiveLock);
1669 
1670  if (complain && !found)
1671  elog(ERROR, "could not find attrdef tuple for relation %u attnum %d",
1672  relid, attnum);
1673 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define Int16GetDatum(X)
Definition: postgres.h:457
#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:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:303
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#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:229
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:174
void RemoveAttrDefaultById ( Oid  attrdefId)

Definition at line 1683 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().

1684 {
1685  Relation attrdef_rel;
1686  Relation attr_rel;
1687  Relation myrel;
1688  ScanKeyData scankeys[1];
1689  SysScanDesc scan;
1690  HeapTuple tuple;
1691  Oid myrelid;
1692  AttrNumber myattnum;
1693 
1694  /* Grab an appropriate lock on the pg_attrdef relation */
1696 
1697  /* Find the pg_attrdef tuple */
1698  ScanKeyInit(&scankeys[0],
1700  BTEqualStrategyNumber, F_OIDEQ,
1701  ObjectIdGetDatum(attrdefId));
1702 
1703  scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndexId, true,
1704  NULL, 1, scankeys);
1705 
1706  tuple = systable_getnext(scan);
1707  if (!HeapTupleIsValid(tuple))
1708  elog(ERROR, "could not find tuple for attrdef %u", attrdefId);
1709 
1710  myrelid = ((Form_pg_attrdef) GETSTRUCT(tuple))->adrelid;
1711  myattnum = ((Form_pg_attrdef) GETSTRUCT(tuple))->adnum;
1712 
1713  /* Get an exclusive lock on the relation owning the attribute */
1714  myrel = relation_open(myrelid, AccessExclusiveLock);
1715 
1716  /* Now we can delete the pg_attrdef row */
1717  CatalogTupleDelete(attrdef_rel, &tuple->t_self);
1718 
1719  systable_endscan(scan);
1720  heap_close(attrdef_rel, RowExclusiveLock);
1721 
1722  /* Fix the pg_attribute row */
1724 
1725  tuple = SearchSysCacheCopy2(ATTNUM,
1726  ObjectIdGetDatum(myrelid),
1727  Int16GetDatum(myattnum));
1728  if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
1729  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1730  myattnum, myrelid);
1731 
1732  ((Form_pg_attribute) GETSTRUCT(tuple))->atthasdef = false;
1733 
1734  CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
1735 
1736  /*
1737  * Our update of the pg_attribute row will force a relcache rebuild, so
1738  * there's nothing else to do here.
1739  */
1740  heap_close(attr_rel, RowExclusiveLock);
1741 
1742  /* Keep lock on attribute's rel until end of xact */
1743  relation_close(myrel, NoLock);
1744 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define Int16GetDatum(X)
Definition: postgres.h:457
#define AttrDefaultOidIndexId
Definition: indexing.h:89
#define AttributeRelationId
Definition: pg_attribute.h:33
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1260
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:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:187
FormData_pg_attrdef * Form_pg_attrdef
Definition: pg_attrdef.h:47
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
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:1114
#define elog
Definition: elog.h:219
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition: syscache.h:167
#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 1541 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().

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

Definition at line 3195 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().

3196 {
3197  Relation rel;
3198  HeapTuple tuple;
3199 
3201 
3202  tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(relid));
3203  if (!HeapTupleIsValid(tuple))
3204  elog(ERROR, "cache lookup failed for partition key of relation %u",
3205  relid);
3206 
3207  CatalogTupleDelete(rel, &tuple->t_self);
3208 
3209  ReleaseSysCache(tuple);
3211 }
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:156
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:1117
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
void RemoveStatistics ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 2744 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().

2745 {
2746  Relation pgstatistic;
2747  SysScanDesc scan;
2748  ScanKeyData key[2];
2749  int nkeys;
2750  HeapTuple tuple;
2751 
2753 
2754  ScanKeyInit(&key[0],
2756  BTEqualStrategyNumber, F_OIDEQ,
2757  ObjectIdGetDatum(relid));
2758 
2759  if (attnum == 0)
2760  nkeys = 1;
2761  else
2762  {
2763  ScanKeyInit(&key[1],
2765  BTEqualStrategyNumber, F_INT2EQ,
2766  Int16GetDatum(attnum));
2767  nkeys = 2;
2768  }
2769 
2770  scan = systable_beginscan(pgstatistic, StatisticRelidAttnumInhIndexId, true,
2771  NULL, nkeys, key);
2772 
2773  /* we must loop even when attnum != 0, in case of inherited stats */
2774  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
2775  CatalogTupleDelete(pgstatistic, &tuple->t_self);
2776 
2777  systable_endscan(scan);
2778 
2779  heap_close(pgstatistic, RowExclusiveLock);
2780 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define Int16GetDatum(X)
Definition: postgres.h:457
#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:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
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:1284
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define StatisticRelidAttnumInhIndexId
Definition: indexing.h:234
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 2588 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().

2589 {
2590  Relation relrel;
2591  HeapTuple reltup;
2592  Form_pg_class relStruct;
2593 
2595  reltup = SearchSysCacheCopy1(RELOID,
2597  if (!HeapTupleIsValid(reltup))
2598  elog(ERROR, "cache lookup failed for relation %u",
2599  RelationGetRelid(rel));
2600  relStruct = (Form_pg_class) GETSTRUCT(reltup);
2601 
2602  if (relStruct->relchecks != numchecks)
2603  {
2604  relStruct->relchecks = numchecks;
2605 
2606  CatalogTupleUpdate(relrel, &reltup->t_self, reltup);
2607  }
2608  else
2609  {
2610  /* Skip the disk update, but force relcache inval anyway */
2612  }
2613 
2614  heap_freetuple(reltup);
2615  heap_close(relrel, RowExclusiveLock);
2616 }
#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:1372
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:1284
#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:1233
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:165
#define elog
Definition: elog.h:219
#define RelationGetRelid(relation)
Definition: rel.h:417
Oid StoreAttrDefault ( Relation  rel,
AttrNumber  attnum,
Node expr,
bool  is_internal 
)

Definition at line 1901 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().

1903 {
1904  char *adbin;
1905  char *adsrc;
1906  Relation adrel;
1907  HeapTuple tuple;
1908  Datum values[4];
1909  static bool nulls[4] = {false, false, false, false};
1910  Relation attrrel;
1911  HeapTuple atttup;
1912  Form_pg_attribute attStruct;
1913  Oid attrdefOid;
1914  ObjectAddress colobject,
1915  defobject;
1916 
1917  /*
1918  * Flatten expression to string form for storage.
1919  */
1920  adbin = nodeToString(expr);
1921 
1922  /*
1923  * Also deparse it to form the mostly-obsolete adsrc field.
1924  */
1925  adsrc = deparse_expression(expr,
1927  RelationGetRelid(rel)),
1928  false, false);
1929 
1930  /*
1931  * Make the pg_attrdef entry.
1932  */
1933  values[Anum_pg_attrdef_adrelid - 1] = RelationGetRelid(rel);
1934  values[Anum_pg_attrdef_adnum - 1] = attnum;
1935  values[Anum_pg_attrdef_adbin - 1] = CStringGetTextDatum(adbin);
1936  values[Anum_pg_attrdef_adsrc - 1] = CStringGetTextDatum(adsrc);
1937 
1939 
1940  tuple = heap_form_tuple(adrel->rd_att, values, nulls);
1941  attrdefOid = CatalogTupleInsert(adrel, tuple);
1942 
1943  defobject.classId = AttrDefaultRelationId;
1944  defobject.objectId = attrdefOid;
1945  defobject.objectSubId = 0;
1946 
1947  heap_close(adrel, RowExclusiveLock);
1948 
1949  /* now can free some of the stuff allocated above */
1952  heap_freetuple(tuple);
1953  pfree(adbin);
1954  pfree(adsrc);
1955 
1956  /*
1957  * Update the pg_attribute entry for the column to show that a default
1958  * exists.
1959  */
1961  atttup = SearchSysCacheCopy2(ATTNUM,
1963  Int16GetDatum(attnum));
1964  if (!HeapTupleIsValid(atttup))
1965  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1966  attnum, RelationGetRelid(rel));
1967  attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
1968  if (!attStruct->atthasdef)
1969  {
1970  attStruct->atthasdef = true;
1971  CatalogTupleUpdate(attrrel, &atttup->t_self, atttup);
1972  }
1973  heap_close(attrrel, RowExclusiveLock);
1974  heap_freetuple(atttup);
1975 
1976  /*
1977  * Make a dependency so that the pg_attrdef entry goes away if the column
1978  * (or whole table) is deleted.
1979  */
1980  colobject.classId = RelationRelationId;
1981  colobject.objectId = RelationGetRelid(rel);
1982  colobject.objectSubId = attnum;
1983 
1984  recordDependencyOn(&defobject, &colobject, DEPENDENCY_AUTO);
1985 
1986  /*
1987  * Record dependencies on objects used in the expression, too.
1988  */
1989  recordDependencyOnExpr(&defobject, expr, NIL, DEPENDENCY_NORMAL);
1990 
1991  /*
1992  * Post creation hook for attribute defaults.
1993  *
1994  * XXX. ALTER TABLE ALTER COLUMN SET/DROP DEFAULT is implemented with a
1995  * couple of deletion/creation of the attribute's default entry, so the
1996  * callee should check existence of an older version of this entry if it
1997  * needs to distinguish.
1998  */
2000  RelationGetRelid(rel), attnum, is_internal);
2001 
2002  return attrdefOid;
2003 }
#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:457
#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:1372
unsigned int Oid
Definition: postgres_ext.h:31
void pfree(void *pointer)
Definition: mcxt.c:950
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:3036
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
Definition: dependency.c:1351
#define RelationGetRelationName(relation)
Definition: rel.h:437
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
uintptr_t Datum
Definition: postgres.h:372
#define Anum_pg_attrdef_adsrc
Definition: pg_attrdef.h:57
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
Definition: objectaccess.h:147
TupleDesc rd_att
Definition: rel.h:115
#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:2977
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define DatumGetPointer(X)
Definition: postgres.h:555
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define CStringGetTextDatum(s)
Definition: builtins.h:91
char * nodeToString(const void *obj)
Definition: outfuncs.c:4219
#define elog
Definition: elog.h:219
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition: syscache.h:167
#define AttrDefaultRelationId
Definition: pg_attrdef.h:29
#define RelationGetRelid(relation)
Definition: rel.h:417
static void StoreConstraints ( Relation  rel,
List cooked_constraints,
bool  is_internal 
)
static

Definition at line 2131 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().

2132 {
2133  int numchecks = 0;
2134  ListCell *lc;
2135 
2136  if (cooked_constraints == NIL)
2137  return; /* nothing to do */
2138 
2139  /*
2140  * Deparsing of constraint expressions will fail unless the just-created
2141  * pg_attribute tuples for this relation are made visible. So, bump the
2142  * command counter. CAUTION: this will cause a relcache entry rebuild.
2143  */
2145 
2146  foreach(lc, cooked_constraints)
2147  {
2148  CookedConstraint *con = (CookedConstraint *) lfirst(lc);
2149 
2150  switch (con->contype)
2151  {
2152  case CONSTR_DEFAULT:
2153  con->conoid = StoreAttrDefault(rel, con->attnum, con->expr,
2154  is_internal);
2155  break;
2156  case CONSTR_CHECK:
2157  con->conoid =
2158  StoreRelCheck(rel, con->name, con->expr,
2159  !con->skip_validation, con->is_local,
2160  con->inhcount, con->is_no_inherit,
2161  is_internal);
2162  numchecks++;
2163  break;
2164  default:
2165  elog(ERROR, "unrecognized constraint type: %d",
2166  (int) con->contype);
2167  }
2168  }
2169 
2170  if (numchecks > 0)
2171  SetRelationNumChecks(rel, numchecks);
2172 }
#define NIL
Definition: pg_list.h:69
static void SetRelationNumChecks(Relation rel, int numchecks)
Definition: heap.c:2588
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:2014
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:922
#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:1901
char * name
Definition: heap.h:32
bool is_local
Definition: heap.h:36
void StorePartitionBound ( Relation  rel,
Relation  parent,
Node bound 
)

Definition at line 3222 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().

3223 {
3224  Relation classRel;
3225  HeapTuple tuple,
3226  newtuple;
3227  Datum new_val[Natts_pg_class];
3228  bool new_null[Natts_pg_class],
3229  new_repl[Natts_pg_class];
3230 
3231  /* Update pg_class tuple */
3233  tuple = SearchSysCacheCopy1(RELOID,
3235  if (!HeapTupleIsValid(tuple))
3236  elog(ERROR, "cache lookup failed for relation %u",
3237  RelationGetRelid(rel));
3238 
3239 #ifdef USE_ASSERT_CHECKING
3240  {
3241  Form_pg_class classForm;
3242  bool isnull;
3243 
3244  classForm = (Form_pg_class) GETSTRUCT(tuple);
3245  Assert(!classForm->relispartition);
3247  &isnull);
3248  Assert(isnull);
3249  }
3250 #endif
3251 
3252  /* Fill in relpartbound value */
3253  memset(new_val, 0, sizeof(new_val));
3254  memset(new_null, false, sizeof(new_null));
3255  memset(new_repl, false, sizeof(new_repl));
3257  new_null[Anum_pg_class_relpartbound - 1] = false;
3258  new_repl[Anum_pg_class_relpartbound - 1] = true;
3259  newtuple = heap_modify_tuple(tuple, RelationGetDescr(classRel),
3260  new_val, new_null, new_repl);
3261  /* Also set the flag */
3262  ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true;
3263  CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
3264  heap_freetuple(newtuple);
3265  heap_close(classRel, RowExclusiveLock);
3266 
3267  CacheInvalidateRelcache(parent);
3268 }
#define Natts_pg_class
Definition: pg_class.h:102
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:429
#define RelationRelationId
Definition: pg_class.h:29
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1372
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:372
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1279
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define Anum_pg_class_relpartbound
Definition: pg_class.h:135
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:675
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1233
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:165
#define CStringGetTextDatum(s)
Definition: builtins.h:91
char * nodeToString(const void *obj)
Definition: outfuncs.c:4219
#define elog
Definition: elog.h:219
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:791
#define RelationGetRelid(relation)
Definition: rel.h:417
void StorePartitionKey ( Relation  rel,
char  strategy,
int16  partnatts,
AttrNumber partattrs,
List partexprs,
Oid partopclass,
Oid partcollation 
)

Definition at line 3086 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().

3093 {
3094  int i;
3095  int2vector *partattrs_vec;
3096  oidvector *partopclass_vec;
3097  oidvector *partcollation_vec;
3098  Datum partexprDatum;
3099  Relation pg_partitioned_table;
3100  HeapTuple tuple;
3102  bool nulls[Natts_pg_partitioned_table];
3103  ObjectAddress myself;
3104  ObjectAddress referenced;
3105 
3106  Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
3107 
3108  tuple = SearchSysCache1(PARTRELID,
3110 
3111  /* Copy the partition attribute numbers, opclass OIDs into arrays */
3112  partattrs_vec = buildint2vector(partattrs, partnatts);
3113  partopclass_vec = buildoidvector(partopclass, partnatts);
3114  partcollation_vec = buildoidvector(partcollation, partnatts);
3115 
3116  /* Convert the expressions (if any) to a text datum */
3117  if (partexprs)
3118  {
3119  char *exprString;
3120 
3121  exprString = nodeToString(partexprs);
3122  partexprDatum = CStringGetTextDatum(exprString);
3123  pfree(exprString);
3124  }
3125  else
3126  partexprDatum = (Datum) 0;
3127 
3128  pg_partitioned_table = heap_open(PartitionedRelationId, RowExclusiveLock);
3129 
3130  MemSet(nulls, false, sizeof(nulls));
3131 
3132  /* Only this can ever be NULL */
3133  if (!partexprDatum)
3134  nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
3135 
3137  values[Anum_pg_partitioned_table_partstrat - 1] = CharGetDatum(strategy);
3138  values[Anum_pg_partitioned_table_partnatts - 1] = Int16GetDatum(partnatts);
3139  values[Anum_pg_partitioned_table_partattrs - 1] = PointerGetDatum(partattrs_vec);
3140  values[Anum_pg_partitioned_table_partclass - 1] = PointerGetDatum(partopclass_vec);
3141  values[Anum_pg_partitioned_table_partcollation - 1] = PointerGetDatum(partcollation_vec);
3142  values[Anum_pg_partitioned_table_partexprs - 1] = partexprDatum;
3143 
3144  tuple = heap_form_tuple(RelationGetDescr(pg_partitioned_table), values, nulls);
3145 
3146  CatalogTupleInsert(pg_partitioned_table, tuple);
3147  heap_close(pg_partitioned_table, RowExclusiveLock);
3148 
3149  /* Mark this relation as dependent on a few things as follows */
3150  myself.classId = RelationRelationId;
3151  myself.objectId = RelationGetRelid(rel);;
3152  myself.objectSubId = 0;
3153 
3154  /* Operator class and collation per key column */
3155  for (i = 0; i < partnatts; i++)
3156  {
3157  referenced.classId = OperatorClassRelationId;
3158  referenced.objectId = partopclass[i];
3159  referenced.objectSubId = 0;
3160 
3161  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3162 
3163  referenced.classId = CollationRelationId;
3164  referenced.objectId = partcollation[i];
3165  referenced.objectSubId = 0;
3166 
3167  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3168  }
3169 
3170  /*
3171  * Anything mentioned in the expressions. We must ignore the column
3172  * references, which will depend on the table itself; there is no separate
3173  * partition key object.
3174  */
3175  if (partexprs)
3177  (Node *) partexprs,
3178  RelationGetRelid(rel),
3180  DEPENDENCY_AUTO, true);
3181 
3182  /*
3183  * We must invalidate the relcache so that the next
3184  * CommandCounterIncrement() will cause the same to be rebuilt using the
3185  * information in just created catalog entry.
3186  */
3188 }
Definition: c.h:478
#define RelationGetDescr(relation)
Definition: rel.h:429
#define Anum_pg_partitioned_table_partexprs
#define PointerGetDatum(X)
Definition: postgres.h:562
#define RelationRelationId
Definition: pg_class.h:29
int2vector * buildint2vector(const int16 *int2s, int n)
Definition: int.c:112
#define Int16GetDatum(X)
Definition: postgres.h:457
#define OperatorClassRelationId
Definition: pg_opclass.h:49
Definition: nodes.h:509
#define MemSet(start, val, len)
Definition: c.h:857
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:114
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#define Anum_pg_partitioned_table_partrelid
void pfree(void *pointer)
Definition: mcxt.c:950
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
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:467
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define CollationRelationId
Definition: pg_collation.h:30
#define Anum_pg_partitioned_table_partstrat
#define Assert(condition)
Definition: c.h:675
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:1392
#define CharGetDatum(X)
Definition: postgres.h:422
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1233
static Datum values[MAXATTR]
Definition: bootstrap.c:163
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:91
char * nodeToString(const void *obj)
Definition: outfuncs.c:4219
#define Anum_pg_partitioned_table_partclass
#define Anum_pg_partitioned_table_partattrs
#define RelationGetRelid(relation)
Definition: rel.h:417
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 2014 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().

2017 {
2018  char *ccbin;
2019  char *ccsrc;
2020  List *varList;
2021  int keycount;
2022  int16 *attNos;
2023  Oid constrOid;
2024 
2025  /*
2026  * Flatten expression to string form for storage.
2027  */
2028  ccbin = nodeToString(expr);
2029 
2030  /*
2031  * Also deparse it to form the mostly-obsolete consrc field.
2032  */
2033  ccsrc = deparse_expression(expr,
2035  RelationGetRelid(rel)),
2036  false, false);
2037 
2038  /*
2039  * Find columns of rel that are used in expr
2040  *
2041  * NB: pull_var_clause is okay here only because we don't allow subselects
2042  * in check constraints; it would fail to examine the contents of
2043  * subselects.
2044  */
2045  varList = pull_var_clause(expr, 0);
2046  keycount = list_length(varList);
2047 
2048  if (keycount > 0)
2049  {
2050  ListCell *vl;
2051  int i = 0;
2052 
2053  attNos = (int16 *) palloc(keycount * sizeof(int16));
2054  foreach(vl, varList)
2055  {
2056  Var *var = (Var *) lfirst(vl);
2057  int j;
2058 
2059  for (j = 0; j < i; j++)
2060  if (attNos[j] == var->varattno)
2061  break;
2062  if (j == i)
2063  attNos[i++] = var->varattno;
2064  }
2065  keycount = i;
2066  }
2067  else
2068  attNos = NULL;
2069 
2070  /*
2071  * Partitioned tables do not contain any rows themselves, so a NO INHERIT
2072  * constraint makes no sense.
2073  */
2074  if (is_no_inherit &&
2075  rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2076  ereport(ERROR,
2077  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2078  errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
2079  RelationGetRelationName(rel))));
2080 
2081  /*
2082  * Create the Check Constraint
2083  */
2084  constrOid =
2085  CreateConstraintEntry(ccname, /* Constraint Name */
2086  RelationGetNamespace(rel), /* namespace */
2087  CONSTRAINT_CHECK, /* Constraint Type */
2088  false, /* Is Deferrable */
2089  false, /* Is Deferred */
2090  is_validated,
2091  RelationGetRelid(rel), /* relation */
2092  attNos, /* attrs in the constraint */
2093  keycount, /* # attrs in the constraint */
2094  InvalidOid, /* not a domain constraint */
2095  InvalidOid, /* no associated index */
2096  InvalidOid, /* Foreign key fields */
2097  NULL,
2098  NULL,
2099  NULL,
2100  NULL,
2101  0,
2102  ' ',
2103  ' ',
2104  ' ',
2105  NULL, /* not an exclusion constraint */
2106  expr, /* Tree form of check constraint */
2107  ccbin, /* Binary form of check constraint */
2108  ccsrc, /* Source form of check constraint */
2109  is_local, /* conislocal */
2110  inhcount, /* coninhcount */
2111  is_no_inherit, /* connoinherit */
2112  is_internal); /* internally constructed? */
2113 
2114  pfree(ccbin);
2115  pfree(ccsrc);
2116 
2117  return constrOid;
2118 }
signed short int16
Definition: c.h:255
int errcode(int sqlerrcode)
Definition: elog.c:575
AttrNumber varattno
Definition: primnodes.h:168
List * pull_var_clause(Node *node, int flags)
Definition: var.c:535
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:163
#define CONSTRAINT_CHECK
void pfree(void *pointer)
Definition: mcxt.c:950
#define ERROR
Definition: elog.h:43
List * deparse_context_for(const char *aliasname, Oid relid)
Definition: ruleutils.c:3036
#define RelationGetRelationName(relation)
Definition: rel.h:437
#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:229
#define lfirst(lc)
Definition: pg_list.h:106
char * deparse_expression(Node *expr, List *dpcontext, bool forceprefix, bool showimplicit)
Definition: ruleutils.c:2977
static int list_length(const List *l)
Definition: pg_list.h:89
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
char * nodeToString(const void *obj)
Definition: outfuncs.c:4219
Definition: pg_list.h:45
#define RelationGetRelid(relation)
Definition: rel.h:417
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:444
Form_pg_attribute SystemAttributeByName ( const char *  attname,
bool  relhasoids 
)

Definition at line 214 of file heap.c.

References lengthof, NameStr, NULL, and ObjectIdAttributeNumber.

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

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

Definition at line 200 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().

201 {
202  if (attno >= 0 || attno < -(int) lengthof(SysAtt))
203  elog(ERROR, "invalid system attribute number %d", attno);
204  if (attno == ObjectIdAttributeNumber && !relhasoids)
205  elog(ERROR, "invalid system attribute number %d", attno);
206  return SysAtt[-attno - 1];
207 }
static const Form_pg_attribute SysAtt[]
Definition: heap.c:192
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define lengthof(array)
Definition: c.h:562
#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, '\0', false, true, 0
}
uint32 TransactionId
Definition: c.h:397
#define XIDOID
Definition: pg_type.h:336
#define MinTransactionIdAttributeNumber
Definition: sysattr.h:23

Definition at line 156 of file heap.c.

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

Definition at line 162 of file heap.c.

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

Definition at line 168 of file heap.c.

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

Definition at line 174 of file heap.c.

Initial value:
= {
0, {"tableoid"}, OIDOID, 0, sizeof(Oid),
true, 'p', 'i', true, false, '\0', 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 186 of file heap.c.

Oid binary_upgrade_next_heap_pg_class_oid = InvalidOid

Definition at line 86 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 192 of file heap.c.