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, PartitionBoundSpec *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 2227 of file heap.c.

References addRangeTableEntryForRelation(), addRTEtoQuery(), Assert, RawColumnDefault::attnum, CookedConstraint::attnum, 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, 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(), stringToNode(), and TupleDescAttr.

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

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

Definition at line 410 of file heap.c.

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

Referenced by addRangeTableEntryForFunction(), and heap_create_with_catalog().

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

Definition at line 490 of file heap.c.

References AccessShareLock, ANYARRAYOID, 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, TupleDescAttr, type_is_collatable(), TYPTYPE_COMPOSITE, TYPTYPE_DOMAIN, and TYPTYPE_PSEUDO.

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

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

Definition at line 2657 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(), OidIsValid, and transformExpr().

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

2662 {
2663  Node *expr;
2664 
2665  Assert(raw_default != NULL);
2666 
2667  /*
2668  * Transform raw parsetree to executable expression.
2669  */
2670  expr = transformExpr(pstate, raw_default, EXPR_KIND_COLUMN_DEFAULT);
2671 
2672  /*
2673  * Make sure default expr does not refer to any vars (we need this check
2674  * since the pstate includes the target table).
2675  */
2676  if (contain_var_clause(expr))
2677  ereport(ERROR,
2678  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2679  errmsg("cannot use column references in default expression")));
2680 
2681  /*
2682  * transformExpr() should have already rejected subqueries, aggregates,
2683  * window functions, and SRFs, based on the EXPR_KIND_ for a default
2684  * expression.
2685  */
2686 
2687  /*
2688  * Coerce the expression to the correct type and typmod, if given. This
2689  * should match the parser's processing of non-defaulted expressions ---
2690  * see transformAssignedExpr().
2691  */
2692  if (OidIsValid(atttypid))
2693  {
2694  Oid type_id = exprType(expr);
2695 
2696  expr = coerce_to_target_type(pstate, expr, type_id,
2697  atttypid, atttypmod,
2700  -1);
2701  if (expr == NULL)
2702  ereport(ERROR,
2703  (errcode(ERRCODE_DATATYPE_MISMATCH),
2704  errmsg("column \"%s\" is of type %s"
2705  " but default expression is of type %s",
2706  attname,
2707  format_type_be(atttypid),
2708  format_type_be(type_id)),
2709  errhint("You will need to rewrite or cast the expression.")));
2710  }
2711 
2712  /*
2713  * Finally, take care of collations in the finished expression.
2714  */
2715  assign_expr_collations(pstate, expr);
2716 
2717  return expr;
2718 }
int errhint(const char *fmt,...)
Definition: elog.c:987
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:146
Definition: nodes.h:510
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:532
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:78
#define ereport(elevel, rest)
Definition: elog.h:122
#define Assert(condition)
Definition: c.h:681
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 1465 of file heap.c.

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

Referenced by heap_drop_with_catalog(), and index_drop().

1466 {
1467  Relation attrel;
1468  SysScanDesc scan;
1469  ScanKeyData key[1];
1470  HeapTuple atttup;
1471 
1472  /* Grab an appropriate lock on the pg_attribute relation */
1474 
1475  /* Use the index to scan only attributes of the target relation */
1476  ScanKeyInit(&key[0],
1478  BTEqualStrategyNumber, F_OIDEQ,
1479  ObjectIdGetDatum(relid));
1480 
1481  scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,
1482  NULL, 1, key);
1483 
1484  /* Delete all the matching tuples */
1485  while ((atttup = systable_getnext(scan)) != NULL)
1486  CatalogTupleDelete(attrel, &atttup->t_self);
1487 
1488  /* Clean up after the scan */
1489  systable_endscan(scan);
1490  heap_close(attrel, RowExclusiveLock);
1491 }
#define AttributeRelidNumIndexId
Definition: indexing.h:94
#define Anum_pg_attribute_attrelid
Definition: pg_attribute.h:195
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define AttributeRelationId
Definition: pg_attribute.h:33
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
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 1436 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().

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

Definition at line 1502 of file heap.c.

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

Referenced by DefineQueryRewrite().

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

Definition at line 250 of file heap.c.

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

Referenced by heap_create_with_catalog(), and index_create().

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

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

Referenced by ExecuteTruncate(), and heap_create_with_catalog().

1383 {
1384  Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
1385  rel->rd_rel->relkind == RELKIND_MATVIEW ||
1386  rel->rd_rel->relkind == RELKIND_TOASTVALUE);
1387  RelationOpenSmgr(rel);
1388  smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
1391 }
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:376
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
#define RELKIND_MATVIEW
Definition: pg_class.h:165
Form_pg_class rd_rel
Definition: rel.h:114
#define RelationOpenSmgr(relation)
Definition: rel.h:460
RelFileNodeBackend smgr_rnode
Definition: smgr.h:43
#define RELKIND_TOASTVALUE
Definition: pg_class.h:163
RelFileNode node
Definition: relfilenode.h:74
#define Assert(condition)
Definition: c.h:681
void log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum)
Definition: storage.c:125
#define RELKIND_RELATION
Definition: pg_class.h:160
void smgrimmedsync(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:734
Oid heap_create_with_catalog ( const char *  relname,
Oid  relnamespace,
Oid  reltablespace,
Oid  relid,
Oid  reltypeid,
Oid  reloftypeid,
Oid  ownerid,
TupleDesc  tupdesc,
List cooked_constraints,
char  relkind,
char  relpersistence,
bool  shared_relation,
bool  mapped_relation,
bool  oidislocal,
int  oidinhcount,
OnCommitAction  oncommit,
Datum  reloptions,
bool  use_user_acl,
bool  allow_system_table_mods,
bool  is_internal,
ObjectAddress typaddress 
)

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

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

Definition at line 1758 of file heap.c.

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

Referenced by doDeletion().

1759 {
1760  Relation rel;
1761  HeapTuple tuple;
1762  Oid parentOid = InvalidOid,
1763  defaultPartOid = InvalidOid;
1764 
1765  /*
1766  * To drop a partition safely, we must grab exclusive lock on its parent,
1767  * because another backend might be about to execute a query on the parent
1768  * table. If it relies on previously cached partition descriptor, then it
1769  * could attempt to access the just-dropped relation as its partition. We
1770  * must therefore take a table lock strong enough to prevent all queries
1771  * on the table from proceeding until we commit and send out a
1772  * shared-cache-inval notice that will make them update their index lists.
1773  */
1774  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1775  if (((Form_pg_class) GETSTRUCT(tuple))->relispartition)
1776  {
1777  parentOid = get_partition_parent(relid);
1779 
1780  /*
1781  * If this is not the default partition, dropping it will change the
1782  * default partition's partition constraint, so we must lock it.
1783  */
1784  defaultPartOid = get_default_partition_oid(parentOid);
1785  if (OidIsValid(defaultPartOid) && relid != defaultPartOid)
1786  LockRelationOid(defaultPartOid, AccessExclusiveLock);
1787  }
1788 
1789  ReleaseSysCache(tuple);
1790 
1791  /*
1792  * Open and lock the relation.
1793  */
1794  rel = relation_open(relid, AccessExclusiveLock);
1795 
1796  /*
1797  * There can no longer be anyone *else* touching the relation, but we
1798  * might still have open queries or cursors, or pending trigger events, in
1799  * our own session.
1800  */
1801  CheckTableNotInUse(rel, "DROP TABLE");
1802 
1803  /*
1804  * This effectively deletes all rows in the table, and may be done in a
1805  * serializable transaction. In that case we must record a rw-conflict in
1806  * to this transaction from each transaction holding a predicate lock on
1807  * the table.
1808  */
1810 
1811  /*
1812  * Delete pg_foreign_table tuple first.
1813  */
1814  if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1815  {
1816  Relation rel;
1817  HeapTuple tuple;
1818 
1820 
1822  if (!HeapTupleIsValid(tuple))
1823  elog(ERROR, "cache lookup failed for foreign table %u", relid);
1824 
1825  CatalogTupleDelete(rel, &tuple->t_self);
1826 
1827  ReleaseSysCache(tuple);
1829  }
1830 
1831  /*
1832  * If a partitioned table, delete the pg_partitioned_table tuple.
1833  */
1834  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1836 
1837  /*
1838  * If the relation being dropped is the default partition itself,
1839  * invalidate its entry in pg_partitioned_table.
1840  */
1841  if (relid == defaultPartOid)
1843 
1844  /*
1845  * Schedule unlinking of the relation's physical files at commit.
1846  */
1847  if (rel->rd_rel->relkind != RELKIND_VIEW &&
1848  rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
1849  rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
1850  rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1851  {
1852  RelationDropStorage(rel);
1853  }
1854 
1855  /*
1856  * Close relcache entry, but *keep* AccessExclusiveLock on the relation
1857  * until transaction commit. This ensures no one else will try to do
1858  * something with the doomed relation.
1859  */
1860  relation_close(rel, NoLock);
1861 
1862  /*
1863  * Remove any associated relation synchronization states.
1864  */
1866 
1867  /*
1868  * Forget any ON COMMIT action for the rel
1869  */
1870  remove_on_commit_action(relid);
1871 
1872  /*
1873  * Flush the relation from the relcache. We want to do this before
1874  * starting to remove catalog entries, just to be certain that no relcache
1875  * entry rebuild will happen partway through. (That should not really
1876  * matter, since we don't do CommandCounterIncrement here, but let's be
1877  * safe.)
1878  */
1879  RelationForgetRelation(relid);
1880 
1881  /*
1882  * remove inheritance information
1883  */
1885 
1886  /*
1887  * delete statistics
1888  */
1889  RemoveStatistics(relid, 0);
1890 
1891  /*
1892  * delete attribute tuples
1893  */
1894  DeleteAttributeTuples(relid);
1895 
1896  /*
1897  * delete relation tuple
1898  */
1899  DeleteRelationTuple(relid);
1900 
1901  if (OidIsValid(parentOid))
1902  {
1903  /*
1904  * If this is not the default partition, the partition constraint of
1905  * the default partition has changed to include the portion of the key
1906  * space previously covered by the dropped partition.
1907  */
1908  if (OidIsValid(defaultPartOid) && relid != defaultPartOid)
1909  CacheInvalidateRelcacheByRelid(defaultPartOid);
1910 
1911  /*
1912  * Invalidate the parent's relcache so that the partition is no longer
1913  * included in its partition descriptor.
1914  */
1915  CacheInvalidateRelcacheByRelid(parentOid);
1916  /* keep the lock */
1917  }
1918 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
void RemoveSubscriptionRel(Oid subid, Oid relid)
void update_default_partition_oid(Oid parentId, Oid defaultPartId)
Definition: partition.c:2846
void remove_on_commit_action(Oid relid)
Definition: tablecmds.c:12886
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1266
void RelationForgetRelation(Oid rid)
Definition: relcache.c:2688
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:166
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
Oid get_partition_parent(Oid relid)
Definition: partition.c:1122
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition: inval.c:1292
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:167
void CheckTableNotInUse(Relation rel, const char *stmt)
Definition: tablecmds.c:3062
Oid get_default_partition_oid(Oid parentId)
Definition: partition.c:2821
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
void RelationDropStorage(Relation rel)
Definition: storage.c:145
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define InvalidOid
Definition: postgres_ext.h:36
void DeleteRelationTuple(Oid relid)
Definition: heap.c:1436
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static void RelationRemoveInheritance(Oid relid)
Definition: heap.c:1403
void CheckTableForSerializableConflictIn(Relation relation)
Definition: predicate.c:4410
void DeleteAttributeTuples(Oid relid)
Definition: heap.c:1465
void RemoveStatistics(Oid relid, AttrNumber attnum)
Definition: heap.c:2770
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define AccessExclusiveLock
Definition: lockdefs.h:45
void RemovePartitionKeyByRelId(Oid relid)
Definition: heap.c:3227
#define RELKIND_VIEW
Definition: pg_class.h:164
#define ForeignTableRelationId
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1120
#define elog
Definition: elog.h:219
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:105
void heap_truncate ( List relids)

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

2859 {
2860  List *relations = NIL;
2861  ListCell *cell;
2862 
2863  /* Open relations for processing, and grab exclusive access on each */
2864  foreach(cell, relids)
2865  {
2866  Oid rid = lfirst_oid(cell);
2867  Relation rel;
2868 
2869  rel = heap_open(rid, AccessExclusiveLock);
2870  relations = lappend(relations, rel);
2871  }
2872 
2873  /* Don't allow truncate on tables that are referenced by foreign keys */
2874  heap_truncate_check_FKs(relations, true);
2875 
2876  /* OK to do it */
2877  foreach(cell, relations)
2878  {
2879  Relation rel = lfirst(cell);
2880 
2881  /* Truncate the relation */
2882  heap_truncate_one_rel(rel);
2883 
2884  /* Close the relation, but keep exclusive lock on it until commit */
2885  heap_close(rel, NoLock);
2886  }
2887 }
#define NIL
Definition: pg_list.h:69
void heap_truncate_one_rel(Relation rel)
Definition: heap.c:2899
void heap_truncate_check_FKs(List *relations, bool tempTables)
Definition: heap.c:2936
#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:1290
#define lfirst(lc)
Definition: pg_list.h:106
#define AccessExclusiveLock
Definition: lockdefs.h:45
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 2936 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().

2937 {
2938  List *oids = NIL;
2939  List *dependents;
2940  ListCell *cell;
2941 
2942  /*
2943  * Build a list of OIDs of the interesting relations.
2944  *
2945  * If a relation has no triggers, then it can neither have FKs nor be
2946  * referenced by a FK from another table, so we can ignore it.
2947  */
2948  foreach(cell, relations)
2949  {
2950  Relation rel = lfirst(cell);
2951 
2952  if (rel->rd_rel->relhastriggers)
2953  oids = lappend_oid(oids, RelationGetRelid(rel));
2954  }
2955 
2956  /*
2957  * Fast path: if no relation has triggers, none has FKs either.
2958  */
2959  if (oids == NIL)
2960  return;
2961 
2962  /*
2963  * Otherwise, must scan pg_constraint. We make one pass with all the
2964  * relations considered; if this finds nothing, then all is well.
2965  */
2966  dependents = heap_truncate_find_FKs(oids);
2967  if (dependents == NIL)
2968  return;
2969 
2970  /*
2971  * Otherwise we repeat the scan once per relation to identify a particular
2972  * pair of relations to complain about. This is pretty slow, but
2973  * performance shouldn't matter much in a failure path. The reason for
2974  * doing things this way is to ensure that the message produced is not
2975  * dependent on chance row locations within pg_constraint.
2976  */
2977  foreach(cell, oids)
2978  {
2979  Oid relid = lfirst_oid(cell);
2980  ListCell *cell2;
2981 
2982  dependents = heap_truncate_find_FKs(list_make1_oid(relid));
2983 
2984  foreach(cell2, dependents)
2985  {
2986  Oid relid2 = lfirst_oid(cell2);
2987 
2988  if (!list_member_oid(oids, relid2))
2989  {
2990  char *relname = get_rel_name(relid);
2991  char *relname2 = get_rel_name(relid2);
2992 
2993  if (tempTables)
2994  ereport(ERROR,
2995  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2996  errmsg("unsupported ON COMMIT and foreign key combination"),
2997  errdetail("Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting.",
2998  relname2, relname)));
2999  else
3000  ereport(ERROR,
3001  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3002  errmsg("cannot truncate a table referenced in a foreign key constraint"),
3003  errdetail("Table \"%s\" references \"%s\".",
3004  relname2, relname),
3005  errhint("Truncate table \"%s\" at the same time, "
3006  "or use TRUNCATE ... CASCADE.",
3007  relname2)));
3008  }
3009  }
3010  }
3011 }
#define NIL
Definition: pg_list.h:69
int errhint(const char *fmt,...)
Definition: elog.c:987
int errcode(int sqlerrcode)
Definition: elog.c:575
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
#define list_make1_oid(x1)
Definition: pg_list.h:151
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define lfirst(lc)
Definition: pg_list.h:106
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: pg_list.h:45
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1726
#define RelationGetRelid(relation)
Definition: rel.h:416
List * heap_truncate_find_FKs(List *relationIds)
Definition: heap.c:3028
#define lfirst_oid(lc)
Definition: pg_list.h:108
List* heap_truncate_find_FKs ( List relationIds)

Definition at line 3028 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_truncate_check_FKs().

3029 {
3030  List *result = NIL;
3031  Relation fkeyRel;
3032  SysScanDesc fkeyScan;
3033  HeapTuple tuple;
3034 
3035  /*
3036  * Must scan pg_constraint. Right now, it is a seqscan because there is
3037  * no available index on confrelid.
3038  */
3040 
3041  fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false,
3042  NULL, 0, NULL);
3043 
3044  while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan)))
3045  {
3047 
3048  /* Not a foreign key */
3049  if (con->contype != CONSTRAINT_FOREIGN)
3050  continue;
3051 
3052  /* Not referencing one of our list of tables */
3053  if (!list_member_oid(relationIds, con->confrelid))
3054  continue;
3055 
3056  /* Add referencer unless already in input or result list */
3057  if (!list_member_oid(relationIds, con->conrelid))
3058  result = insert_ordered_unique_oid(result, con->conrelid);
3059  }
3060 
3061  systable_endscan(fkeyScan);
3062  heap_close(fkeyRel, AccessShareLock);
3063 
3064  return result;
3065 }
#define NIL
Definition: pg_list.h:69
#define CONSTRAINT_FOREIGN
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#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
static List * insert_ordered_unique_oid(List *list, Oid datum)
Definition: heap.c:3078
#define ConstraintRelationId
Definition: pg_constraint.h:29
Definition: pg_list.h:45
void heap_truncate_one_rel ( Relation  rel)

Definition at line 2899 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_truncate().

2900 {
2901  Oid toastrelid;
2902 
2903  /* Truncate the actual file (and discard buffers) */
2904  RelationTruncate(rel, 0);
2905 
2906  /* If the relation has indexes, truncate the indexes too */
2908 
2909  /* If there is a toast table, truncate that too */
2910  toastrelid = rel->rd_rel->reltoastrelid;
2911  if (OidIsValid(toastrelid))
2912  {
2913  Relation toastrel = heap_open(toastrelid, AccessExclusiveLock);
2914 
2915  RelationTruncate(toastrel, 0);
2916  RelationTruncateIndexes(toastrel);
2917  /* keep the lock... */
2918  heap_close(toastrel, NoLock);
2919  }
2920 }
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define NoLock
Definition: lockdefs.h:34
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define AccessExclusiveLock
Definition: lockdefs.h:45
static void RelationTruncateIndexes(Relation heapRelation)
Definition: heap.c:2817
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 600 of file heap.c.

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

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

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

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

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

Definition at line 1631 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, ObjectAddressStack::object, ObjectIdGetDatum, PERFORM_DELETION_INTERNAL, performDeletion(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by ATExecAlterColumnType(), and ATExecColumnDefault().

1633 {
1634  Relation attrdef_rel;
1635  ScanKeyData scankeys[2];
1636  SysScanDesc scan;
1637  HeapTuple tuple;
1638  bool found = false;
1639 
1641 
1642  ScanKeyInit(&scankeys[0],
1644  BTEqualStrategyNumber, F_OIDEQ,
1645  ObjectIdGetDatum(relid));
1646  ScanKeyInit(&scankeys[1],
1648  BTEqualStrategyNumber, F_INT2EQ,
1649  Int16GetDatum(attnum));
1650 
1651  scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true,
1652  NULL, 2, scankeys);
1653 
1654  /* There should be at most one matching tuple, but we loop anyway */
1655  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1656  {
1657  ObjectAddress object;
1658 
1659  object.classId = AttrDefaultRelationId;
1660  object.objectId = HeapTupleGetOid(tuple);
1661  object.objectSubId = 0;
1662 
1663  performDeletion(&object, behavior,
1664  internal ? PERFORM_DELETION_INTERNAL : 0);
1665 
1666  found = true;
1667  }
1668 
1669  systable_endscan(scan);
1670  heap_close(attrdef_rel, RowExclusiveLock);
1671 
1672  if (complain && !found)
1673  elog(ERROR, "could not find attrdef tuple for relation %u attnum %d",
1674  relid, attnum);
1675 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define Int16GetDatum(X)
Definition: postgres.h:457
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define AttrDefaultIndexId
Definition: indexing.h:87
#define RowExclusiveLock
Definition: lockdefs.h:38
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
Definition: dependency.c:303
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#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
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
#define AttrDefaultRelationId
Definition: pg_attrdef.h:29
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define PERFORM_DELETION_INTERNAL
Definition: dependency.h:174
void RemoveAttrDefaultById ( Oid  attrdefId)

Definition at line 1685 of file heap.c.

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

Referenced by doDeletion().

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

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

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

3228 {
3229  Relation rel;
3230  HeapTuple tuple;
3231 
3233 
3234  tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(relid));
3235  if (!HeapTupleIsValid(tuple))
3236  elog(ERROR, "cache lookup failed for partition key of relation %u",
3237  relid);
3238 
3239  CatalogTupleDelete(rel, &tuple->t_self);
3240 
3241  ReleaseSysCache(tuple);
3243 }
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define PartitionedRelationId
#define RowExclusiveLock
Definition: lockdefs.h:38
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
void RemoveStatistics ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 2770 of file heap.c.

References Anum_pg_statistic_staattnum, Anum_pg_statistic_starelid, BTEqualStrategyNumber, CatalogTupleDelete(), heap_close, heap_open(), HeapTupleIsValid, Int16GetDatum, 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().

2771 {
2772  Relation pgstatistic;
2773  SysScanDesc scan;
2774  ScanKeyData key[2];
2775  int nkeys;
2776  HeapTuple tuple;
2777 
2779 
2780  ScanKeyInit(&key[0],
2782  BTEqualStrategyNumber, F_OIDEQ,
2783  ObjectIdGetDatum(relid));
2784 
2785  if (attnum == 0)
2786  nkeys = 1;
2787  else
2788  {
2789  ScanKeyInit(&key[1],
2791  BTEqualStrategyNumber, F_INT2EQ,
2792  Int16GetDatum(attnum));
2793  nkeys = 2;
2794  }
2795 
2796  scan = systable_beginscan(pgstatistic, StatisticRelidAttnumInhIndexId, true,
2797  NULL, nkeys, key);
2798 
2799  /* we must loop even when attnum != 0, in case of inherited stats */
2800  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
2801  CatalogTupleDelete(pgstatistic, &tuple->t_self);
2802 
2803  systable_endscan(scan);
2804 
2805  heap_close(pgstatistic, RowExclusiveLock);
2806 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define Int16GetDatum(X)
Definition: postgres.h:457
#define Anum_pg_statistic_staattnum
Definition: pg_statistic.h:137
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_statistic_starelid
Definition: pg_statistic.h:136
#define StatisticRelationId
Definition: pg_statistic.h:29
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define StatisticRelidAttnumInhIndexId
Definition: indexing.h:234
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Oid StoreAttrDefault ( Relation  rel,
AttrNumber  attnum,
Node expr,
bool  is_internal 
)

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

1929 {
1930  char *adbin;
1931  char *adsrc;
1932  Relation adrel;
1933  HeapTuple tuple;
1934  Datum values[4];
1935  static bool nulls[4] = {false, false, false, false};
1936  Relation attrrel;
1937  HeapTuple atttup;
1938  Form_pg_attribute attStruct;
1939  Oid attrdefOid;
1940  ObjectAddress colobject,
1941  defobject;
1942 
1943  /*
1944  * Flatten expression to string form for storage.
1945  */
1946  adbin = nodeToString(expr);
1947 
1948  /*
1949  * Also deparse it to form the mostly-obsolete adsrc field.
1950  */
1951  adsrc = deparse_expression(expr,
1953  RelationGetRelid(rel)),
1954  false, false);
1955 
1956  /*
1957  * Make the pg_attrdef entry.
1958  */
1959  values[Anum_pg_attrdef_adrelid - 1] = RelationGetRelid(rel);
1960  values[Anum_pg_attrdef_adnum - 1] = attnum;
1961  values[Anum_pg_attrdef_adbin - 1] = CStringGetTextDatum(adbin);
1962  values[Anum_pg_attrdef_adsrc - 1] = CStringGetTextDatum(adsrc);
1963 
1965 
1966  tuple = heap_form_tuple(adrel->rd_att, values, nulls);
1967  attrdefOid = CatalogTupleInsert(adrel, tuple);
1968 
1969  defobject.classId = AttrDefaultRelationId;
1970  defobject.objectId = attrdefOid;
1971  defobject.objectSubId = 0;
1972 
1973  heap_close(adrel, RowExclusiveLock);
1974 
1975  /* now can free some of the stuff allocated above */
1978  heap_freetuple(tuple);
1979  pfree(adbin);
1980  pfree(adsrc);
1981 
1982  /*
1983  * Update the pg_attribute entry for the column to show that a default
1984  * exists.
1985  */
1987  atttup = SearchSysCacheCopy2(ATTNUM,
1989  Int16GetDatum(attnum));
1990  if (!HeapTupleIsValid(atttup))
1991  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1992  attnum, RelationGetRelid(rel));
1993  attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
1994  if (!attStruct->atthasdef)
1995  {
1996  attStruct->atthasdef = true;
1997  CatalogTupleUpdate(attrrel, &atttup->t_self, atttup);
1998  }
1999  heap_close(attrrel, RowExclusiveLock);
2000  heap_freetuple(atttup);
2001 
2002  /*
2003  * Make a dependency so that the pg_attrdef entry goes away if the column
2004  * (or whole table) is deleted.
2005  */
2006  colobject.classId = RelationRelationId;
2007  colobject.objectId = RelationGetRelid(rel);
2008  colobject.objectSubId = attnum;
2009 
2010  recordDependencyOn(&defobject, &colobject, DEPENDENCY_AUTO);
2011 
2012  /*
2013  * Record dependencies on objects used in the expression, too.
2014  */
2015  recordDependencyOnExpr(&defobject, expr, NIL, DEPENDENCY_NORMAL);
2016 
2017  /*
2018  * Post creation hook for attribute defaults.
2019  *
2020  * XXX. ALTER TABLE ALTER COLUMN SET/DROP DEFAULT is implemented with a
2021  * couple of deletion/creation of the attribute's default entry, so the
2022  * callee should check existence of an older version of this entry if it
2023  * needs to distinguish.
2024  */
2026  RelationGetRelid(rel), attnum, is_internal);
2027 
2028  return attrdefOid;
2029 }
#define NIL
Definition: pg_list.h:69
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationRelationId
Definition: pg_class.h:29
#define Int16GetDatum(X)
Definition: postgres.h:457
#define AttributeRelationId
Definition: pg_attribute.h:33
#define Anum_pg_attrdef_adbin
Definition: pg_attrdef.h:56
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:695
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
unsigned int Oid
Definition: postgres_ext.h:31
void pfree(void *pointer)
Definition: mcxt.c:949
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
List * deparse_context_for(const char *aliasname, Oid relid)
Definition: ruleutils.c:3044
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
Definition: dependency.c:1351
#define RelationGetRelationName(relation)
Definition: rel.h:436
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
uintptr_t Datum
Definition: postgres.h:372
#define Anum_pg_attrdef_adsrc
Definition: pg_attrdef.h:57
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
Definition: objectaccess.h:147
TupleDesc rd_att
Definition: rel.h:115
#define Anum_pg_attrdef_adrelid
Definition: pg_attrdef.h:54
#define Anum_pg_attrdef_adnum
Definition: pg_attrdef.h:55
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
char * deparse_expression(Node *expr, List *dpcontext, bool forceprefix, bool showimplicit)
Definition: ruleutils.c:2985
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define DatumGetPointer(X)
Definition: postgres.h:555
static Datum values[MAXATTR]
Definition: bootstrap.c:164
#define CStringGetTextDatum(s)
Definition: builtins.h:91
char * nodeToString(const void *obj)
Definition: outfuncs.c:4259
#define elog
Definition: elog.h:219
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition: syscache.h:175
#define AttrDefaultRelationId
Definition: pg_attrdef.h:29
#define RelationGetRelid(relation)
Definition: rel.h:416
void StorePartitionBound ( Relation  rel,
Relation  parent,
PartitionBoundSpec bound 
)

Definition at line 3255 of file heap.c.

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

Referenced by ATExecAttachPartition(), and DefineRelation().

3256 {
3257  Relation classRel;
3258  HeapTuple tuple,
3259  newtuple;
3260  Datum new_val[Natts_pg_class];
3261  bool new_null[Natts_pg_class],
3262  new_repl[Natts_pg_class];
3263  Oid defaultPartOid;
3264 
3265  /* Update pg_class tuple */
3267  tuple = SearchSysCacheCopy1(RELOID,
3269  if (!HeapTupleIsValid(tuple))
3270  elog(ERROR, "cache lookup failed for relation %u",
3271  RelationGetRelid(rel));
3272 
3273 #ifdef USE_ASSERT_CHECKING
3274  {
3275  Form_pg_class classForm;
3276  bool isnull;
3277 
3278  classForm = (Form_pg_class) GETSTRUCT(tuple);
3279  Assert(!classForm->relispartition);
3281  &isnull);
3282  Assert(isnull);
3283  }
3284 #endif
3285 
3286  /* Fill in relpartbound value */
3287  memset(new_val, 0, sizeof(new_val));
3288  memset(new_null, false, sizeof(new_null));
3289  memset(new_repl, false, sizeof(new_repl));
3291  new_null[Anum_pg_class_relpartbound - 1] = false;
3292  new_repl[Anum_pg_class_relpartbound - 1] = true;
3293  newtuple = heap_modify_tuple(tuple, RelationGetDescr(classRel),
3294  new_val, new_null, new_repl);
3295  /* Also set the flag */
3296  ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true;
3297  CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
3298  heap_freetuple(newtuple);
3299  heap_close(classRel, RowExclusiveLock);
3300 
3301  /*
3302  * The partition constraint for the default partition depends on the
3303  * partition bounds of every other partition, so we must invalidate the
3304  * relcache entry for that partition every time a partition is added or
3305  * removed.
3306  */
3307  defaultPartOid = get_default_oid_from_partdesc(RelationGetPartitionDesc(parent));
3308  if (OidIsValid(defaultPartOid))
3309  CacheInvalidateRelcacheByRelid(defaultPartOid);
3310 
3311  CacheInvalidateRelcache(parent);
3312 }
#define Natts_pg_class
Definition: pg_class.h:102
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:428
#define RelationRelationId
Definition: pg_class.h:29
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition: inval.c:1292
uintptr_t Datum
Definition: postgres.h:372
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define Anum_pg_class_relpartbound
Definition: pg_class.h:135
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:681
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1233
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:173
#define CStringGetTextDatum(s)
Definition: builtins.h:91
char * nodeToString(const void *obj)
Definition: outfuncs.c:4259
#define elog
Definition: elog.h:219
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:794
#define RelationGetRelid(relation)
Definition: rel.h:416
Oid get_default_oid_from_partdesc(PartitionDesc partdesc)
Definition: partition.c:2804
#define RelationGetPartitionDesc(relation)
Definition: rel.h:632
void StorePartitionKey ( Relation  rel,
char  strategy,
int16  partnatts,
AttrNumber partattrs,
List partexprs,
Oid partopclass,
Oid partcollation 
)

Definition at line 3112 of file heap.c.

References Anum_pg_partitioned_table_partattrs, Anum_pg_partitioned_table_partclass, Anum_pg_partitioned_table_partcollation, Anum_pg_partitioned_table_partdefid, 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, DEFAULT_COLLATION_OID, DEPENDENCY_AUTO, DEPENDENCY_NORMAL, heap_close, heap_form_tuple(), heap_open(), i, Int16GetDatum, InvalidOid, MemSet, Natts_pg_partitioned_table, nodeToString(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, OperatorClassRelationId, PartitionedRelationId, PARTRELID, pfree(), PointerGetDatum, RelationData::rd_rel, recordDependencyOn(), recordDependencyOnSingleRelExpr(), RelationGetDescr, RelationGetRelid, RelationRelationId, RELKIND_PARTITIONED_TABLE, RowExclusiveLock, SearchSysCache1(), and values.

Referenced by DefineRelation().

3119 {
3120  int i;
3121  int2vector *partattrs_vec;
3122  oidvector *partopclass_vec;
3123  oidvector *partcollation_vec;
3124  Datum partexprDatum;
3125  Relation pg_partitioned_table;
3126  HeapTuple tuple;
3128  bool nulls[Natts_pg_partitioned_table];
3129  ObjectAddress myself;
3130  ObjectAddress referenced;
3131 
3132  Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
3133 
3134  tuple = SearchSysCache1(PARTRELID,
3136 
3137  /* Copy the partition attribute numbers, opclass OIDs into arrays */
3138  partattrs_vec = buildint2vector(partattrs, partnatts);
3139  partopclass_vec = buildoidvector(partopclass, partnatts);
3140  partcollation_vec = buildoidvector(partcollation, partnatts);
3141 
3142  /* Convert the expressions (if any) to a text datum */
3143  if (partexprs)
3144  {
3145  char *exprString;
3146 
3147  exprString = nodeToString(partexprs);
3148  partexprDatum = CStringGetTextDatum(exprString);
3149  pfree(exprString);
3150  }
3151  else
3152  partexprDatum = (Datum) 0;
3153 
3154  pg_partitioned_table = heap_open(PartitionedRelationId, RowExclusiveLock);
3155 
3156  MemSet(nulls, false, sizeof(nulls));
3157 
3158  /* Only this can ever be NULL */
3159  if (!partexprDatum)
3160  nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
3161 
3163  values[Anum_pg_partitioned_table_partstrat - 1] = CharGetDatum(strategy);
3164  values[Anum_pg_partitioned_table_partnatts - 1] = Int16GetDatum(partnatts);
3166  values[Anum_pg_partitioned_table_partattrs - 1] = PointerGetDatum(partattrs_vec);
3167  values[Anum_pg_partitioned_table_partclass - 1] = PointerGetDatum(partopclass_vec);
3168  values[Anum_pg_partitioned_table_partcollation - 1] = PointerGetDatum(partcollation_vec);
3169  values[Anum_pg_partitioned_table_partexprs - 1] = partexprDatum;
3170 
3171  tuple = heap_form_tuple(RelationGetDescr(pg_partitioned_table), values, nulls);
3172 
3173  CatalogTupleInsert(pg_partitioned_table, tuple);
3174  heap_close(pg_partitioned_table, RowExclusiveLock);
3175 
3176  /* Mark this relation as dependent on a few things as follows */
3177  myself.classId = RelationRelationId;
3178  myself.objectId = RelationGetRelid(rel);;
3179  myself.objectSubId = 0;
3180 
3181  /* Operator class and collation per key column */
3182  for (i = 0; i < partnatts; i++)
3183  {
3184  referenced.classId = OperatorClassRelationId;
3185  referenced.objectId = partopclass[i];
3186  referenced.objectSubId = 0;
3187 
3188  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3189 
3190  /* The default collation is pinned, so don't bother recording it */
3191  if (OidIsValid(partcollation[i]) &&
3192  partcollation[i] != DEFAULT_COLLATION_OID)
3193  {
3194  referenced.classId = CollationRelationId;
3195  referenced.objectId = partcollation[i];
3196  referenced.objectSubId = 0;
3197  }
3198 
3199  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3200  }
3201 
3202  /*
3203  * Anything mentioned in the expressions. We must ignore the column
3204  * references, which will depend on the table itself; there is no separate
3205  * partition key object.
3206  */
3207  if (partexprs)
3209  (Node *) partexprs,
3210  RelationGetRelid(rel),
3212  DEPENDENCY_AUTO, true);
3213 
3214  /*
3215  * We must invalidate the relcache so that the next
3216  * CommandCounterIncrement() will cause the same to be rebuilt using the
3217  * information in just created catalog entry.
3218  */
3220 }
Definition: c.h:472
#define RelationGetDescr(relation)
Definition: rel.h:428
#define Anum_pg_partitioned_table_partexprs
#define PointerGetDatum(X)
Definition: postgres.h:562
#define RelationRelationId
Definition: pg_class.h:29
int2vector * buildint2vector(const int16 *int2s, int n)
Definition: int.c:112
#define Int16GetDatum(X)
Definition: postgres.h:457
#define OperatorClassRelationId
Definition: pg_opclass.h:49
Definition: nodes.h:510
#define MemSet(start, val, len)
Definition: c.h:863
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:695
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:114
#define OidIsValid(objectId)
Definition: c.h:532
#define Anum_pg_partitioned_table_partrelid
void pfree(void *pointer)
Definition: mcxt.c:949
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define Anum_pg_partitioned_table_partcollation
#define PartitionedRelationId
#define DEFAULT_COLLATION_OID
Definition: pg_collation.h:75
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_partitioned_table_partdefid
#define Anum_pg_partitioned_table_partnatts
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
Definition: c.h:461
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define CollationRelationId
Definition: pg_collation.h:30
#define InvalidOid
Definition: postgres_ext.h:36
#define Anum_pg_partitioned_table_partstrat
#define Assert(condition)
Definition: c.h:681
oidvector * buildoidvector(const Oid *oids, int n)
Definition: oid.c:167
#define Natts_pg_partitioned_table
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool ignore_self)
Definition: dependency.c:1392
#define CharGetDatum(X)
Definition: postgres.h:422
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1233
static Datum values[MAXATTR]
Definition: bootstrap.c:164
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:91
char * nodeToString(const void *obj)
Definition: outfuncs.c:4259
#define Anum_pg_partitioned_table_partclass
#define Anum_pg_partitioned_table_partattrs
#define RelationGetRelid(relation)
Definition: rel.h:416
Form_pg_attribute SystemAttributeByName ( const char *  attname,
bool  relhasoids 
)

Definition at line 214 of file heap.c.

References lengthof, NameStr, and ObjectIdAttributeNumber.

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

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

Definition at line 200 of file heap.c.

References elog, ERROR, lengthof, and ObjectIdAttributeNumber.

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

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