PostgreSQL Source Code  git master
partition.c File Reference
#include "postgres.h"
#include "access/attmap.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "access/table.h"
#include "catalog/indexing.h"
#include "catalog/partition.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_partitioned_table.h"
#include "nodes/makefuncs.h"
#include "optimizer/optimizer.h"
#include "partitioning/partbounds.h"
#include "rewrite/rewriteManip.h"
#include "utils/fmgroids.h"
#include "utils/partcache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Include dependency graph for partition.c:

Go to the source code of this file.

Functions

static Oid get_partition_parent_worker (Relation inhRel, Oid relid, bool *detach_pending)
 
static void get_partition_ancestors_worker (Relation inhRel, Oid relid, List **ancestors)
 
Oid get_partition_parent (Oid relid, bool even_if_detached)
 
Listget_partition_ancestors (Oid relid)
 
Oid index_get_partition (Relation partition, Oid indexId)
 
Listmap_partition_varattnos (List *expr, int fromrel_varno, Relation to_rel, Relation from_rel)
 
bool has_partition_attrs (Relation rel, Bitmapset *attnums, bool *used_in_expr)
 
Oid get_default_partition_oid (Oid parentId)
 
void update_default_partition_oid (Oid parentId, Oid defaultPartId)
 
Listget_proposed_default_constraint (List *new_part_constraints)
 

Function Documentation

◆ get_default_partition_oid()

Oid get_default_partition_oid ( Oid  parentId)

Definition at line 316 of file partition.c.

317 {
318  HeapTuple tuple;
319  Oid defaultPartId = InvalidOid;
320 
321  tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(parentId));
322 
323  if (HeapTupleIsValid(tuple))
324  {
325  Form_pg_partitioned_table part_table_form;
326 
327  part_table_form = (Form_pg_partitioned_table) GETSTRUCT(tuple);
328  defaultPartId = part_table_form->partdefid;
329  ReleaseSysCache(tuple);
330  }
331 
332  return defaultPartId;
333 }
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
FormData_pg_partitioned_table * Form_pg_partitioned_table
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:267
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:219

References GETSTRUCT, HeapTupleIsValid, InvalidOid, ObjectIdGetDatum(), ReleaseSysCache(), and SearchSysCache1().

Referenced by heap_drop_with_catalog(), and RelationBuildPartitionDesc().

◆ get_partition_ancestors()

List* get_partition_ancestors ( Oid  relid)

Definition at line 135 of file partition.c.

136 {
137  List *result = NIL;
138  Relation inhRel;
139 
140  inhRel = table_open(InheritsRelationId, AccessShareLock);
141 
142  get_partition_ancestors_worker(inhRel, relid, &result);
143 
144  table_close(inhRel, AccessShareLock);
145 
146  return result;
147 }
#define AccessShareLock
Definition: lockdefs.h:36
static void get_partition_ancestors_worker(Relation inhRel, Oid relid, List **ancestors)
Definition: partition.c:154
#define NIL
Definition: pg_list.h:68
Definition: pg_list.h:54
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References AccessShareLock, get_partition_ancestors_worker(), NIL, table_close(), and table_open().

Referenced by build_column_default(), ExecGetAncestorResultRels(), ExecInitPartitionInfo(), filter_partitions(), get_rel_sync_entry(), index_concurrently_swap(), pg_partition_ancestors(), pg_partition_root(), pg_partition_tree(), and RelationBuildPublicationDesc().

◆ get_partition_ancestors_worker()

static void get_partition_ancestors_worker ( Relation  inhRel,
Oid  relid,
List **  ancestors 
)
static

Definition at line 154 of file partition.c.

155 {
156  Oid parentOid;
157  bool detach_pending;
158 
159  /*
160  * Recursion ends at the topmost level, ie., when there's no parent; also
161  * when the partition is being detached.
162  */
163  parentOid = get_partition_parent_worker(inhRel, relid, &detach_pending);
164  if (parentOid == InvalidOid || detach_pending)
165  return;
166 
167  *ancestors = lappend_oid(*ancestors, parentOid);
168  get_partition_ancestors_worker(inhRel, parentOid, ancestors);
169 }
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
static Oid get_partition_parent_worker(Relation inhRel, Oid relid, bool *detach_pending)
Definition: partition.c:86

References get_partition_parent_worker(), InvalidOid, and lappend_oid().

Referenced by get_partition_ancestors().

◆ get_partition_parent()

Oid get_partition_parent ( Oid  relid,
bool  even_if_detached 
)

Definition at line 54 of file partition.c.

55 {
56  Relation catalogRelation;
57  Oid result;
58  bool detach_pending;
59 
60  catalogRelation = table_open(InheritsRelationId, AccessShareLock);
61 
62  result = get_partition_parent_worker(catalogRelation, relid,
63  &detach_pending);
64 
65  if (!OidIsValid(result))
66  elog(ERROR, "could not find tuple for parent of relation %u", relid);
67 
68  if (detach_pending && !even_if_detached)
69  elog(ERROR, "relation %u has no parent because it's being detached",
70  relid);
71 
72  table_close(catalogRelation, AccessShareLock);
73 
74  return result;
75 }
#define OidIsValid(objectId)
Definition: c.h:764
#define ERROR
Definition: elog.h:39

References AccessShareLock, elog(), ERROR, get_partition_parent_worker(), OidIsValid, table_close(), and table_open().

Referenced by ATExecAttachPartitionIdx(), ATExecDropNotNull(), DetachPartitionFinalize(), generate_partition_qual(), heap_drop_with_catalog(), index_get_partition(), RangeVarCallbackForDropRelation(), renametrig(), and validatePartitionedIndex().

◆ get_partition_parent_worker()

static Oid get_partition_parent_worker ( Relation  inhRel,
Oid  relid,
bool detach_pending 
)
static

Definition at line 86 of file partition.c.

87 {
88  SysScanDesc scan;
89  ScanKeyData key[2];
90  Oid result = InvalidOid;
91  HeapTuple tuple;
92 
93  *detach_pending = false;
94 
95  ScanKeyInit(&key[0],
96  Anum_pg_inherits_inhrelid,
97  BTEqualStrategyNumber, F_OIDEQ,
98  ObjectIdGetDatum(relid));
99  ScanKeyInit(&key[1],
100  Anum_pg_inherits_inhseqno,
101  BTEqualStrategyNumber, F_INT4EQ,
102  Int32GetDatum(1));
103 
104  scan = systable_beginscan(inhRel, InheritsRelidSeqnoIndexId, true,
105  NULL, 2, key);
106  tuple = systable_getnext(scan);
107  if (HeapTupleIsValid(tuple))
108  {
110 
111  /* Let caller know of partition being detached */
112  if (form->inhdetachpending)
113  *detach_pending = true;
114  result = form->inhparent;
115  }
116 
117  systable_endscan(scan);
118 
119  return result;
120 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:599
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:506
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
FormData_pg_inherits * Form_pg_inherits
Definition: pg_inherits.h:45
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

References BTEqualStrategyNumber, GETSTRUCT, HeapTupleIsValid, Int32GetDatum(), InvalidOid, sort-test::key, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by get_partition_ancestors_worker(), and get_partition_parent().

◆ get_proposed_default_constraint()

List* get_proposed_default_constraint ( List new_part_constraints)

Definition at line 371 of file partition.c.

372 {
373  Expr *defPartConstraint;
374 
375  defPartConstraint = make_ands_explicit(new_part_constraints);
376 
377  /*
378  * Derive the partition constraints of default partition by negating the
379  * given partition constraints. The partition constraint never evaluates
380  * to NULL, so negating it like this is safe.
381  */
382  defPartConstraint = makeBoolExpr(NOT_EXPR,
383  list_make1(defPartConstraint),
384  -1);
385 
386  /* Simplify, to put the negated expression into canonical form */
387  defPartConstraint =
388  (Expr *) eval_const_expressions(NULL,
389  (Node *) defPartConstraint);
390  defPartConstraint = canonicalize_qual(defPartConstraint, true);
391 
392  return make_ands_implicit(defPartConstraint);
393 }
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition: clauses.c:2237
List * make_ands_implicit(Expr *clause)
Definition: makefuncs.c:722
Expr * make_ands_explicit(List *andclauses)
Definition: makefuncs.c:711
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:372
#define list_make1(x1)
Definition: pg_list.h:212
Expr * canonicalize_qual(Expr *qual, bool is_check)
Definition: prepqual.c:294
@ NOT_EXPR
Definition: primnodes.h:866
Definition: nodes.h:129

References canonicalize_qual(), eval_const_expressions(), list_make1, make_ands_explicit(), make_ands_implicit(), makeBoolExpr(), and NOT_EXPR.

Referenced by ATExecAttachPartition(), and check_default_partition_contents().

◆ has_partition_attrs()

bool has_partition_attrs ( Relation  rel,
Bitmapset attnums,
bool used_in_expr 
)

Definition at line 256 of file partition.c.

257 {
259  int partnatts;
260  List *partexprs;
261  ListCell *partexprs_item;
262  int i;
263 
264  if (attnums == NULL || rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
265  return false;
266 
268  partnatts = get_partition_natts(key);
269  partexprs = get_partition_exprs(key);
270 
271  partexprs_item = list_head(partexprs);
272  for (i = 0; i < partnatts; i++)
273  {
275 
276  if (partattno != 0)
277  {
279  attnums))
280  {
281  if (used_in_expr)
282  *used_in_expr = false;
283  return true;
284  }
285  }
286  else
287  {
288  /* Arbitrary expression */
289  Node *expr = (Node *) lfirst(partexprs_item);
290  Bitmapset *expr_attrs = NULL;
291 
292  /* Find all attributes referenced */
293  pull_varattnos(expr, 1, &expr_attrs);
294  partexprs_item = lnext(partexprs, partexprs_item);
295 
296  if (bms_overlap(attnums, expr_attrs))
297  {
298  if (used_in_expr)
299  *used_in_expr = true;
300  return true;
301  }
302  }
303  }
304 
305  return false;
306 }
int16 AttrNumber
Definition: attnum.h:21
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:523
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:595
int i
Definition: isn.c:73
PartitionKey RelationGetPartitionKey(Relation rel)
Definition: partcache.c:54
static int16 get_partition_col_attnum(PartitionKey key, int col)
Definition: partcache.h:80
static int get_partition_natts(PartitionKey key)
Definition: partcache.h:65
static List * get_partition_exprs(PartitionKey key)
Definition: partcache.h:71
#define lfirst(lc)
Definition: pg_list.h:172
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343
Form_pg_class rd_rel
Definition: rel.h:111
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
Definition: var.c:291

References bms_is_member(), bms_overlap(), FirstLowInvalidHeapAttributeNumber, get_partition_col_attnum(), get_partition_exprs(), get_partition_natts(), i, sort-test::key, lfirst, list_head(), lnext(), pull_varattnos(), RelationData::rd_rel, and RelationGetPartitionKey().

Referenced by ATExecDropColumn(), ATPrepAlterColumnType(), and expand_partitioned_rtentry().

◆ index_get_partition()

Oid index_get_partition ( Relation  partition,
Oid  indexId 
)

Definition at line 177 of file partition.c.

178 {
179  List *idxlist = RelationGetIndexList(partition);
180  ListCell *l;
181 
182  foreach(l, idxlist)
183  {
184  Oid partIdx = lfirst_oid(l);
185  HeapTuple tup;
186  Form_pg_class classForm;
187  bool ispartition;
188 
189  tup = SearchSysCache1(RELOID, ObjectIdGetDatum(partIdx));
190  if (!HeapTupleIsValid(tup))
191  elog(ERROR, "cache lookup failed for relation %u", partIdx);
192  classForm = (Form_pg_class) GETSTRUCT(tup);
193  ispartition = classForm->relispartition;
194  ReleaseSysCache(tup);
195  if (!ispartition)
196  continue;
197  if (get_partition_parent(partIdx, false) == indexId)
198  {
199  list_free(idxlist);
200  return partIdx;
201  }
202  }
203 
204  list_free(idxlist);
205  return InvalidOid;
206 }
void list_free(List *list)
Definition: list.c:1546
Oid get_partition_parent(Oid relid, bool even_if_detached)
Definition: partition.c:54
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define lfirst_oid(lc)
Definition: pg_list.h:174
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4755

References elog(), ERROR, get_partition_parent(), GETSTRUCT, HeapTupleIsValid, InvalidOid, lfirst_oid, list_free(), ObjectIdGetDatum(), RelationGetIndexList(), ReleaseSysCache(), and SearchSysCache1().

Referenced by addFkRecurseReferenced(), CloneFkReferenced(), and refuseDupeIndexAttach().

◆ map_partition_varattnos()

List* map_partition_varattnos ( List expr,
int  fromrel_varno,
Relation  to_rel,
Relation  from_rel 
)

Definition at line 223 of file partition.c.

225 {
226  if (expr != NIL)
227  {
228  AttrMap *part_attmap;
229  bool found_whole_row;
230 
231  part_attmap = build_attrmap_by_name(RelationGetDescr(to_rel),
232  RelationGetDescr(from_rel),
233  false);
234  expr = (List *) map_variable_attnos((Node *) expr,
235  fromrel_varno, 0,
236  part_attmap,
237  RelationGetForm(to_rel)->reltype,
238  &found_whole_row);
239  /* Since we provided a to_rowtype, we may ignore found_whole_row. */
240  }
241 
242  return expr;
243 }
AttrMap * build_attrmap_by_name(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)
Definition: attmap.c:178
#define RelationGetForm(relation)
Definition: rel.h:498
#define RelationGetDescr(relation)
Definition: rel.h:530
Node * map_variable_attnos(Node *node, int target_varno, int sublevels_up, const AttrMap *attno_map, Oid to_rowtype, bool *found_whole_row)
Definition: attmap.h:35

References build_attrmap_by_name(), map_variable_attnos(), NIL, RelationGetDescr, and RelationGetForm.

Referenced by ATExecAttachPartition(), check_default_partition_contents(), CloneRowTriggersToPartition(), CreateTriggerFiringOn(), generate_partition_qual(), and QueuePartitionConstraintValidation().

◆ update_default_partition_oid()

void update_default_partition_oid ( Oid  parentId,
Oid  defaultPartId 
)

Definition at line 341 of file partition.c.

342 {
343  HeapTuple tuple;
344  Relation pg_partitioned_table;
345  Form_pg_partitioned_table part_table_form;
346 
347  pg_partitioned_table = table_open(PartitionedRelationId, RowExclusiveLock);
348 
349  tuple = SearchSysCacheCopy1(PARTRELID, ObjectIdGetDatum(parentId));
350 
351  if (!HeapTupleIsValid(tuple))
352  elog(ERROR, "cache lookup failed for partition key of relation %u",
353  parentId);
354 
355  part_table_form = (Form_pg_partitioned_table) GETSTRUCT(tuple);
356  part_table_form->partdefid = defaultPartId;
357  CatalogTupleUpdate(pg_partitioned_table, &tuple->t_self, tuple);
358 
359  heap_freetuple(tuple);
360  table_close(pg_partitioned_table, RowExclusiveLock);
361 }
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
#define RowExclusiveLock
Definition: lockdefs.h:38
ItemPointerData t_self
Definition: htup.h:65
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:86

References CatalogTupleUpdate(), elog(), ERROR, GETSTRUCT, heap_freetuple(), HeapTupleIsValid, ObjectIdGetDatum(), RowExclusiveLock, SearchSysCacheCopy1, HeapTupleData::t_self, table_close(), and table_open().

Referenced by DetachPartitionFinalize(), heap_drop_with_catalog(), and StorePartitionBound().