PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
heap.h File Reference
Include dependency graph for heap.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  RawColumnDefault
 
struct  CookedConstraint
 

Typedefs

typedef struct RawColumnDefault RawColumnDefault
 
typedef struct CookedConstraint CookedConstraint
 

Functions

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)
 
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 heap_drop_with_catalog (Oid relid)
 
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 InsertPgAttributeTuple (Relation pg_attribute_rel, Form_pg_attribute new_attribute, CatalogIndexState indstate)
 
void InsertPgClassTuple (Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Datum relacl, Datum reloptions)
 
ListAddRelationNewConstraints (Relation rel, List *newColDefaults, List *newConstraints, bool allow_merge, bool is_local, bool is_internal)
 
Oid StoreAttrDefault (Relation rel, AttrNumber attnum, Node *expr, bool is_internal)
 
NodecookDefault (ParseState *pstate, Node *raw_default, Oid atttypid, int32 atttypmod, char *attname)
 
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 RemoveStatistics (Oid relid, AttrNumber attnum)
 
Form_pg_attribute SystemAttributeDefinition (AttrNumber attno, bool relhasoids)
 
Form_pg_attribute SystemAttributeByName (const char *attname, bool relhasoids)
 
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 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)
 

Typedef Documentation

Function Documentation

List* AddRelationNewConstraints ( Relation  rel,
List newColDefaults,
List newConstraints,
bool  allow_merge,
bool  is_local,
bool  is_internal 
)

Definition at line 2186 of file heap.c.

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

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

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

Definition at line 407 of file heap.c.

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

Referenced by addRangeTableEntryForFunction(), and heap_create_with_catalog().

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

Definition at line 485 of file heap.c.

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

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

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

Definition at line 2616 of file heap.c.

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

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

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

Definition at line 1457 of file heap.c.

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

Referenced by heap_drop_with_catalog(), and index_drop().

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

Definition at line 1428 of file heap.c.

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

Referenced by heap_drop_with_catalog(), and index_drop().

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

Definition at line 1494 of file heap.c.

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

Referenced by DefineQueryRewrite().

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

Definition at line 248 of file heap.c.

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

Referenced by heap_create_with_catalog(), and index_create().

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

Definition at line 1377 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_create_with_catalog().

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

Definition at line 1015 of file heap.c.

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

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

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

Definition at line 1750 of file heap.c.

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

Referenced by doDeletion().

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

Definition at line 2817 of file heap.c.

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

Referenced by PreCommit_on_commit_actions().

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

Definition at line 2895 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_truncate().

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

Definition at line 2987 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_truncate_check_FKs().

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

Definition at line 2858 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_truncate().

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

Definition at line 595 of file heap.c.

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

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

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

Definition at line 760 of file heap.c.

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

Referenced by AddNewRelationTuple(), and index_create().

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

Definition at line 1623 of file heap.c.

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

Referenced by ATExecAlterColumnType(), and ATExecColumnDefault().

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

Definition at line 1677 of file heap.c.

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

Referenced by doDeletion().

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

Definition at line 1535 of file heap.c.

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

Referenced by doDeletion().

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

Definition at line 3180 of file heap.c.

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

Referenced by heap_drop_with_catalog().

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

Definition at line 2729 of file heap.c.

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

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

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

Definition at line 1886 of file heap.c.

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

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

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

Definition at line 3207 of file heap.c.

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

Referenced by ATExecAttachPartition(), and DefineRelation().

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

Definition at line 3071 of file heap.c.

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

Referenced by DefineRelation().

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

Definition at line 212 of file heap.c.

References lengthof, NameStr, NULL, and ObjectIdAttributeNumber.

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

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

Definition at line 198 of file heap.c.

References elog, ERROR, lengthof, and ObjectIdAttributeNumber.

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

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