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)
 
void RemoveStatisticsExt (Oid relid, AttrNumber attnum)
 
Form_pg_attribute SystemAttributeDefinition (AttrNumber attno, bool relhasoids)
 
Form_pg_attribute SystemAttributeByName (const char *attname, bool relhasoids)
 
void CheckAttributeNamesTypes (TupleDesc tupdesc, char relkind, bool allow_system_table_mods)
 
void CheckAttributeType (const char *attname, Oid atttypid, Oid attcollation, List *containing_rowtypes, bool allow_system_table_mods)
 
void StorePartitionKey (Relation rel, char strategy, int16 partnatts, AttrNumber *partattrs, List *partexprs, Oid *partopclass, Oid *partcollation)
 
void RemovePartitionKeyByRelId (Oid relid)
 
void StorePartitionBound (Relation rel, Relation parent, Node *bound)
 

Typedef Documentation

Function Documentation

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

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

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

Definition at line 410 of file heap.c.

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

Referenced by addRangeTableEntryForFunction(), and heap_create_with_catalog().

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

Definition at line 488 of file heap.c.

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

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

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

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

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

Definition at line 1463 of file heap.c.

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

Referenced by heap_drop_with_catalog(), and index_drop().

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

Definition at line 1434 of file heap.c.

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

Referenced by heap_drop_with_catalog(), and index_drop().

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

Definition at line 1500 of file heap.c.

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

Referenced by DefineQueryRewrite().

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

Definition at line 250 of file heap.c.

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

Referenced by heap_create_with_catalog(), and index_create().

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

Definition at line 1380 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_create_with_catalog().

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

Definition at line 1019 of file heap.c.

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

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

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

Definition at line 1759 of file heap.c.

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

Referenced by doDeletion().

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

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

2907 {
2908  List *relations = NIL;
2909  ListCell *cell;
2910 
2911  /* Open relations for processing, and grab exclusive access on each */
2912  foreach(cell, relids)
2913  {
2914  Oid rid = lfirst_oid(cell);
2915  Relation rel;
2916 
2917  rel = heap_open(rid, AccessExclusiveLock);
2918  relations = lappend(relations, rel);
2919  }
2920 
2921  /* Don't allow truncate on tables that are referenced by foreign keys */
2922  heap_truncate_check_FKs(relations, true);
2923 
2924  /* OK to do it */
2925  foreach(cell, relations)
2926  {
2927  Relation rel = lfirst(cell);
2928 
2929  /* Truncate the relation */
2930  heap_truncate_one_rel(rel);
2931 
2932  /* Close the relation, but keep exclusive lock on it until commit */
2933  heap_close(rel, NoLock);
2934  }
2935 }
#define NIL
Definition: pg_list.h:69
void heap_truncate_one_rel(Relation rel)
Definition: heap.c:2947
void heap_truncate_check_FKs(List *relations, bool tempTables)
Definition: heap.c:2984
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
#define NoLock
Definition: lockdefs.h:34
List * lappend(List *list, void *datum)
Definition: list.c:128
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define lfirst(lc)
Definition: pg_list.h:106
#define AccessExclusiveLock
Definition: lockdefs.h:46
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
void heap_truncate_check_FKs ( List relations,
bool  tempTables 
)

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

2985 {
2986  List *oids = NIL;
2987  List *dependents;
2988  ListCell *cell;
2989 
2990  /*
2991  * Build a list of OIDs of the interesting relations.
2992  *
2993  * If a relation has no triggers, then it can neither have FKs nor be
2994  * referenced by a FK from another table, so we can ignore it.
2995  */
2996  foreach(cell, relations)
2997  {
2998  Relation rel = lfirst(cell);
2999 
3000  if (rel->rd_rel->relhastriggers)
3001  oids = lappend_oid(oids, RelationGetRelid(rel));
3002  }
3003 
3004  /*
3005  * Fast path: if no relation has triggers, none has FKs either.
3006  */
3007  if (oids == NIL)
3008  return;
3009 
3010  /*
3011  * Otherwise, must scan pg_constraint. We make one pass with all the
3012  * relations considered; if this finds nothing, then all is well.
3013  */
3014  dependents = heap_truncate_find_FKs(oids);
3015  if (dependents == NIL)
3016  return;
3017 
3018  /*
3019  * Otherwise we repeat the scan once per relation to identify a particular
3020  * pair of relations to complain about. This is pretty slow, but
3021  * performance shouldn't matter much in a failure path. The reason for
3022  * doing things this way is to ensure that the message produced is not
3023  * dependent on chance row locations within pg_constraint.
3024  */
3025  foreach(cell, oids)
3026  {
3027  Oid relid = lfirst_oid(cell);
3028  ListCell *cell2;
3029 
3030  dependents = heap_truncate_find_FKs(list_make1_oid(relid));
3031 
3032  foreach(cell2, dependents)
3033  {
3034  Oid relid2 = lfirst_oid(cell2);
3035 
3036  if (!list_member_oid(oids, relid2))
3037  {
3038  char *relname = get_rel_name(relid);
3039  char *relname2 = get_rel_name(relid2);
3040 
3041  if (tempTables)
3042  ereport(ERROR,
3043  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3044  errmsg("unsupported ON COMMIT and foreign key combination"),
3045  errdetail("Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting.",
3046  relname2, relname)));
3047  else
3048  ereport(ERROR,
3049  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3050  errmsg("cannot truncate a table referenced in a foreign key constraint"),
3051  errdetail("Table \"%s\" references \"%s\".",
3052  relname2, relname),
3053  errhint("Truncate table \"%s\" at the same time, "
3054  "or use TRUNCATE ... CASCADE.",
3055  relname2)));
3056  }
3057  }
3058  }
3059 }
#define NIL
Definition: pg_list.h:69
int errhint(const char *fmt,...)
Definition: elog.c:987
int errcode(int sqlerrcode)
Definition: elog.c:575
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
#define list_make1_oid(x1)
Definition: pg_list.h:151
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define lfirst(lc)
Definition: pg_list.h:106
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: pg_list.h:45
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1726
#define RelationGetRelid(relation)
Definition: rel.h:417
List * heap_truncate_find_FKs(List *relationIds)
Definition: heap.c:3076
#define lfirst_oid(lc)
Definition: pg_list.h:108
List* heap_truncate_find_FKs ( List relationIds)

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

3077 {
3078  List *result = NIL;
3079  Relation fkeyRel;
3080  SysScanDesc fkeyScan;
3081  HeapTuple tuple;
3082 
3083  /*
3084  * Must scan pg_constraint. Right now, it is a seqscan because there is
3085  * no available index on confrelid.
3086  */
3088 
3089  fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false,
3090  NULL, 0, NULL);
3091 
3092  while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan)))
3093  {
3095 
3096  /* Not a foreign key */
3097  if (con->contype != CONSTRAINT_FOREIGN)
3098  continue;
3099 
3100  /* Not referencing one of our list of tables */
3101  if (!list_member_oid(relationIds, con->confrelid))
3102  continue;
3103 
3104  /* Add referencer unless already in input or result list */
3105  if (!list_member_oid(relationIds, con->conrelid))
3106  result = insert_ordered_unique_oid(result, con->conrelid);
3107  }
3108 
3109  systable_endscan(fkeyScan);
3110  heap_close(fkeyRel, AccessShareLock);
3111 
3112  return result;
3113 }
#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:1618
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
static List * insert_ordered_unique_oid(List *list, Oid datum)
Definition: heap.c:3126
#define ConstraintRelationId
Definition: pg_constraint.h:29
Definition: pg_list.h:45
void heap_truncate_one_rel ( Relation  rel)

Definition at line 2947 of file heap.c.

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

Referenced by ExecuteTruncate(), and heap_truncate().

2948 {
2949  Oid toastrelid;
2950 
2951  /* Truncate the actual file (and discard buffers) */
2952  RelationTruncate(rel, 0);
2953 
2954  /* If the relation has indexes, truncate the indexes too */
2956 
2957  /* If there is a toast table, truncate that too */
2958  toastrelid = rel->rd_rel->reltoastrelid;
2959  if (OidIsValid(toastrelid))
2960  {
2961  Relation toastrel = heap_open(toastrelid, AccessExclusiveLock);
2962 
2963  RelationTruncate(toastrel, 0);
2964  RelationTruncateIndexes(toastrel);
2965  /* keep the lock... */
2966  heap_close(toastrel, NoLock);
2967  }
2968 }
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define NoLock
Definition: lockdefs.h:34
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define AccessExclusiveLock
Definition: lockdefs.h:46
static void RelationTruncateIndexes(Relation heapRelation)
Definition: heap.c:2865
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:429
#define Anum_pg_attribute_atthasdef
Definition: pg_attribute.h:208
#define Int16GetDatum(X)
Definition: postgres.h:457
#define Anum_pg_attribute_attndims
Definition: pg_attribute.h:201
#define Anum_pg_attribute_attacl
Definition: pg_attribute.h:214
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#define Anum_pg_attribute_attislocal
Definition: pg_attribute.h:211
#define Anum_pg_attribute_attisdropped
Definition: pg_attribute.h:210
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define Anum_pg_attribute_attstattarget
Definition: pg_attribute.h:198
#define Anum_pg_attribute_atttypmod
Definition: pg_attribute.h:203
#define Anum_pg_attribute_attcacheoff
Definition: pg_attribute.h:202
#define Anum_pg_attribute_attidentity
Definition: pg_attribute.h:209
uintptr_t Datum
Definition: postgres.h:372
#define Anum_pg_attribute_attalign
Definition: pg_attribute.h:206
#define BoolGetDatum(X)
Definition: postgres.h:408
#define NULL
Definition: c.h:229
#define Anum_pg_attribute_attnotnull
Definition: pg_attribute.h:207
#define Anum_pg_attribute_attfdwoptions
Definition: pg_attribute.h:216
#define CharGetDatum(X)
Definition: postgres.h:422
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define Int32GetDatum(X)
Definition: postgres.h:485
#define Anum_pg_attribute_attoptions
Definition: pg_attribute.h:215
#define Natts_pg_attribute
Definition: pg_attribute.h:194
#define Anum_pg_attribute_attcollation
Definition: pg_attribute.h:213
Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:186
#define Anum_pg_attribute_attstorage
Definition: pg_attribute.h:205
#define Anum_pg_attribute_attname
Definition: pg_attribute.h:196
void InsertPgClassTuple ( Relation  pg_class_desc,
Relation  new_rel_desc,
Oid  new_rel_oid,
Datum  relacl,
Datum  reloptions 
)

Definition at line 764 of file heap.c.

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

Referenced by AddNewRelationTuple(), and index_create().

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

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

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

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

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

3270 {
3271  Relation rel;
3272  HeapTuple tuple;
3273 
3275 
3276  tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(relid));
3277  if (!HeapTupleIsValid(tuple))
3278  elog(ERROR, "cache lookup failed for partition key of relation %u",
3279  relid);
3280 
3281  CatalogTupleDelete(rel, &tuple->t_self);
3282 
3283  ReleaseSysCache(tuple);
3285 }
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:152
#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:1116
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
void RemoveStatistics ( Oid  relid,
AttrNumber  attnum 
)

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

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

Definition at line 2795 of file heap.c.

References Anum_pg_statistic_ext_stxrelid, BTEqualStrategyNumber, CatalogTupleDelete(), deleteDependencyRecordsFor(), GETSTRUCT, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, i, NULL, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), StatisticExtRelationId, StatisticExtRelidIndexId, systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by heap_drop_with_catalog(), and RemoveAttributeById().

2796 {
2797  Relation pgstatisticext;
2798  SysScanDesc scan;
2799  ScanKeyData key;
2800  HeapTuple tuple;
2801 
2802  /*
2803  * Scan pg_statistic_ext to delete relevant tuples
2804  */
2806 
2807  ScanKeyInit(&key,
2809  BTEqualStrategyNumber, F_OIDEQ,
2810  ObjectIdGetDatum(relid));
2811 
2812  scan = systable_beginscan(pgstatisticext,
2814  true, NULL, 1, &key);
2815 
2816  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
2817  {
2818  bool delete = false;
2819 
2820  if (attnum == 0)
2821  delete = true;
2822  else if (attnum != 0)
2823  {
2824  Form_pg_statistic_ext staForm;
2825  int i;
2826 
2827  /*
2828  * Decode the stxkeys array and delete any stats that involve the
2829  * specified column.
2830  */
2831  staForm = (Form_pg_statistic_ext) GETSTRUCT(tuple);
2832  for (i = 0; i < staForm->stxkeys.dim1; i++)
2833  {
2834  if (staForm->stxkeys.values[i] == attnum)
2835  {
2836  delete = true;
2837  break;
2838  }
2839  }
2840  }
2841 
2842  if (delete)
2843  {
2844  CatalogTupleDelete(pgstatisticext, &tuple->t_self);
2846  HeapTupleGetOid(tuple),
2847  false);
2848  }
2849  }
2850 
2851  systable_endscan(scan);
2852 
2853  heap_close(pgstatisticext, RowExclusiveLock);
2854 }
#define Anum_pg_statistic_ext_stxrelid
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
Definition: pg_depend.c:191
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
#define StatisticExtRelidIndexId
Definition: indexing.h:190
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define StatisticExtRelationId
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
#define BTEqualStrategyNumber
Definition: stratnum.h:31
FormData_pg_statistic_ext * Form_pg_statistic_ext
Oid StoreAttrDefault ( Relation  rel,
AttrNumber  attnum,
Node expr,
bool  is_internal 
)

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

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

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

3297 {
3298  Relation classRel;
3299  HeapTuple tuple,
3300  newtuple;
3301  Datum new_val[Natts_pg_class];
3302  bool new_null[Natts_pg_class],
3303  new_repl[Natts_pg_class];
3304 
3305  /* Update pg_class tuple */
3307  tuple = SearchSysCacheCopy1(RELOID,
3309  if (!HeapTupleIsValid(tuple))
3310  elog(ERROR, "cache lookup failed for relation %u",
3311  RelationGetRelid(rel));
3312 
3313 #ifdef USE_ASSERT_CHECKING
3314  {
3315  Form_pg_class classForm;
3316  bool isnull;
3317 
3318  classForm = (Form_pg_class) GETSTRUCT(tuple);
3319  Assert(!classForm->relispartition);
3321  &isnull);
3322  Assert(isnull);
3323  }
3324 #endif
3325 
3326  /* Fill in relpartbound value */
3327  memset(new_val, 0, sizeof(new_val));
3328  memset(new_null, false, sizeof(new_null));
3329  memset(new_repl, false, sizeof(new_repl));
3331  new_null[Anum_pg_class_relpartbound - 1] = false;
3332  new_repl[Anum_pg_class_relpartbound - 1] = true;
3333  newtuple = heap_modify_tuple(tuple, RelationGetDescr(classRel),
3334  new_val, new_null, new_repl);
3335  /* Also set the flag */
3336  ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true;
3337  CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
3338  heap_freetuple(newtuple);
3339  heap_close(classRel, RowExclusiveLock);
3340 
3341  CacheInvalidateRelcache(parent);
3342 }
#define Natts_pg_class
Definition: pg_class.h:102
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:429
#define RelationRelationId
Definition: pg_class.h:29
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#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:1278
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define Anum_pg_class_relpartbound
Definition: pg_class.h:135
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:675
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1226
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:161
#define CStringGetTextDatum(s)
Definition: builtins.h:91
char * nodeToString(const void *obj)
Definition: outfuncs.c:4217
#define elog
Definition: elog.h:219
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
#define RelationGetRelid(relation)
Definition: rel.h:417
void StorePartitionKey ( Relation  rel,
char  strategy,
int16  partnatts,
AttrNumber partattrs,
List partexprs,
Oid partopclass,
Oid partcollation 
)

Definition at line 3160 of file heap.c.

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

Referenced by DefineRelation().

3167 {
3168  int i;
3169  int2vector *partattrs_vec;
3170  oidvector *partopclass_vec;
3171  oidvector *partcollation_vec;
3172  Datum partexprDatum;
3173  Relation pg_partitioned_table;
3174  HeapTuple tuple;
3176  bool nulls[Natts_pg_partitioned_table];
3177  ObjectAddress myself;
3178  ObjectAddress referenced;
3179 
3180  Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
3181 
3182  tuple = SearchSysCache1(PARTRELID,
3184 
3185  /* Copy the partition attribute numbers, opclass OIDs into arrays */
3186  partattrs_vec = buildint2vector(partattrs, partnatts);
3187  partopclass_vec = buildoidvector(partopclass, partnatts);
3188  partcollation_vec = buildoidvector(partcollation, partnatts);
3189 
3190  /* Convert the expressions (if any) to a text datum */
3191  if (partexprs)
3192  {
3193  char *exprString;
3194 
3195  exprString = nodeToString(partexprs);
3196  partexprDatum = CStringGetTextDatum(exprString);
3197  pfree(exprString);
3198  }
3199  else
3200  partexprDatum = (Datum) 0;
3201 
3202  pg_partitioned_table = heap_open(PartitionedRelationId, RowExclusiveLock);
3203 
3204  MemSet(nulls, false, sizeof(nulls));
3205 
3206  /* Only this can ever be NULL */
3207  if (!partexprDatum)
3208  nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
3209 
3211  values[Anum_pg_partitioned_table_partstrat - 1] = CharGetDatum(strategy);
3212  values[Anum_pg_partitioned_table_partnatts - 1] = Int16GetDatum(partnatts);
3213  values[Anum_pg_partitioned_table_partattrs - 1] = PointerGetDatum(partattrs_vec);
3214  values[Anum_pg_partitioned_table_partclass - 1] = PointerGetDatum(partopclass_vec);
3215  values[Anum_pg_partitioned_table_partcollation - 1] = PointerGetDatum(partcollation_vec);
3216  values[Anum_pg_partitioned_table_partexprs - 1] = partexprDatum;
3217 
3218  tuple = heap_form_tuple(RelationGetDescr(pg_partitioned_table), values, nulls);
3219 
3220  CatalogTupleInsert(pg_partitioned_table, tuple);
3221  heap_close(pg_partitioned_table, RowExclusiveLock);
3222 
3223  /* Mark this relation as dependent on a few things as follows */
3224  myself.classId = RelationRelationId;
3225  myself.objectId = RelationGetRelid(rel);;
3226  myself.objectSubId = 0;
3227 
3228  /* Operator class and collation per key column */
3229  for (i = 0; i < partnatts; i++)
3230  {
3231  referenced.classId = OperatorClassRelationId;
3232  referenced.objectId = partopclass[i];
3233  referenced.objectSubId = 0;
3234 
3235  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3236 
3237  referenced.classId = CollationRelationId;
3238  referenced.objectId = partcollation[i];
3239  referenced.objectSubId = 0;
3240 
3241  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3242  }
3243 
3244  /*
3245  * Anything mentioned in the expressions. We must ignore the column
3246  * references, which will depend on the table itself; there is no separate
3247  * partition key object.
3248  */
3249  if (partexprs)
3251  (Node *) partexprs,
3252  RelationGetRelid(rel),
3254  DEPENDENCY_AUTO, true);
3255 
3256  /*
3257  * We must invalidate the relcache so that the next
3258  * CommandCounterIncrement() will cause the same to be rebuilt using the
3259  * information in just created catalog entry.
3260  */
3262 }
Definition: c.h:478
#define RelationGetDescr(relation)
Definition: rel.h:429
#define Anum_pg_partitioned_table_partexprs
#define PointerGetDatum(X)
Definition: postgres.h:562
#define RelationRelationId
Definition: pg_class.h:29
int2vector * buildint2vector(const int16 *int2s, int n)
Definition: int.c:112
#define Int16GetDatum(X)
Definition: postgres.h:457
#define OperatorClassRelationId
Definition: pg_opclass.h:49
Definition: nodes.h:509
#define MemSet(start, val, len)
Definition: c.h:857
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:114
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
#define Anum_pg_partitioned_table_partrelid
void pfree(void *pointer)
Definition: mcxt.c:950
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define Anum_pg_partitioned_table_partcollation
#define PartitionedRelationId
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_partitioned_table_partnatts
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
Definition: c.h:467
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define CollationRelationId
Definition: pg_collation.h:30
#define Anum_pg_partitioned_table_partstrat
#define Assert(condition)
Definition: c.h:675
oidvector * buildoidvector(const Oid *oids, int n)
Definition: oid.c:167
#define Natts_pg_partitioned_table
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool ignore_self)
Definition: dependency.c:1379
#define CharGetDatum(X)
Definition: postgres.h:422
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1226
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:4217
#define Anum_pg_partitioned_table_partclass
#define Anum_pg_partitioned_table_partattrs
#define RelationGetRelid(relation)
Definition: rel.h:417
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