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 2201 of file heap.c.

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

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

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

Referenced by addRangeTableEntryForFunction(), and heap_create_with_catalog().

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

Definition at line 488 of file heap.c.

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

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

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

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

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

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

Definition at line 1463 of file heap.c.

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

Referenced by heap_drop_with_catalog(), and index_drop().

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

Definition at line 1434 of file heap.c.

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

Referenced by heap_drop_with_catalog(), and index_drop().

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

Definition at line 1500 of file heap.c.

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

Referenced by DefineQueryRewrite().

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

Definition at line 250 of file heap.c.

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

Referenced by heap_create_with_catalog(), and index_create().

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

Definition at line 1380 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_create_with_catalog().

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

Definition at line 1019 of file heap.c.

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

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

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

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

Referenced by doDeletion().

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

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

Referenced by PreCommit_on_commit_actions().

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

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

Referenced by ExecuteTruncate(), and heap_truncate().

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

Definition at line 3002 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_truncate_check_FKs().

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

Definition at line 2873 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_truncate().

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

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

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

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

Definition at line 764 of file heap.c.

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

Referenced by AddNewRelationTuple(), and index_create().

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

Definition at line 1629 of file heap.c.

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

Referenced by ATExecAlterColumnType(), and ATExecColumnDefault().

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

Definition at line 1683 of file heap.c.

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

Referenced by doDeletion().

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

Definition at line 1541 of file heap.c.

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

Referenced by doDeletion().

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

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

3201 {
3202  Relation rel;
3203  HeapTuple tuple;
3204 
3206 
3207  tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(relid));
3208  if (!HeapTupleIsValid(tuple))
3209  elog(ERROR, "cache lookup failed for partition key of relation %u",
3210  relid);
3211 
3212  CatalogTupleDelete(rel, &tuple->t_self);
3213 
3214  ReleaseSysCache(tuple);
3216 }
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define PartitionedRelationId
#define RowExclusiveLock
Definition: lockdefs.h:38
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
void RemoveStatistics ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 2744 of file heap.c.

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

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

2745 {
2746  Relation pgstatistic;
2747  SysScanDesc scan;
2748  ScanKeyData key[2];
2749  int nkeys;
2750  HeapTuple tuple;
2751 
2753 
2754  ScanKeyInit(&key[0],
2756  BTEqualStrategyNumber, F_OIDEQ,
2757  ObjectIdGetDatum(relid));
2758 
2759  if (attnum == 0)
2760  nkeys = 1;
2761  else
2762  {
2763  ScanKeyInit(&key[1],
2765  BTEqualStrategyNumber, F_INT2EQ,
2766  Int16GetDatum(attnum));
2767  nkeys = 2;
2768  }
2769 
2770  scan = systable_beginscan(pgstatistic, StatisticRelidAttnumInhIndexId, true,
2771  NULL, nkeys, key);
2772 
2773  /* we must loop even when attnum != 0, in case of inherited stats */
2774  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
2775  CatalogTupleDelete(pgstatistic, &tuple->t_self);
2776 
2777  systable_endscan(scan);
2778 
2779  heap_close(pgstatistic, RowExclusiveLock);
2780 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define Int16GetDatum(X)
Definition: postgres.h:457
#define Anum_pg_statistic_staattnum
Definition: pg_statistic.h:137
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_statistic_starelid
Definition: pg_statistic.h:136
#define StatisticRelationId
Definition: pg_statistic.h:29
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define StatisticRelidAttnumInhIndexId
Definition: indexing.h:234
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Oid StoreAttrDefault ( Relation  rel,
AttrNumber  attnum,
Node expr,
bool  is_internal 
)

Definition at line 1901 of file heap.c.

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

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

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

Definition at line 3227 of file heap.c.

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

Referenced by ATExecAttachPartition(), and DefineRelation().

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

Definition at line 3086 of file heap.c.

References Anum_pg_partitioned_table_partattrs, Anum_pg_partitioned_table_partclass, Anum_pg_partitioned_table_partcollation, Anum_pg_partitioned_table_partexprs, Anum_pg_partitioned_table_partnatts, Anum_pg_partitioned_table_partrelid, Anum_pg_partitioned_table_partstrat, Assert, buildint2vector(), buildoidvector(), CacheInvalidateRelcache(), CatalogTupleInsert(), CharGetDatum, ObjectAddress::classId, CollationRelationId, CStringGetTextDatum, DEFAULT_COLLATION_OID, DEPENDENCY_AUTO, DEPENDENCY_NORMAL, heap_close, heap_form_tuple(), heap_open(), i, Int16GetDatum, 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().

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

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

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

Definition at line 200 of file heap.c.

References elog, ERROR, lengthof, and ObjectIdAttributeNumber.

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

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