PostgreSQL Source Code  git master
partition.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "access/table.h"
#include "access/tupconvert.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)
 
static void get_partition_ancestors_worker (Relation inhRel, Oid relid, List **ancestors)
 
Oid get_partition_parent (Oid relid)
 
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 *found_whole_row)
 
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 298 of file partition.c.

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

Referenced by heap_drop_with_catalog(), and RelationBuildPartitionDesc().

299 {
300  HeapTuple tuple;
301  Oid defaultPartId = InvalidOid;
302 
303  tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(parentId));
304 
305  if (HeapTupleIsValid(tuple))
306  {
307  Form_pg_partitioned_table part_table_form;
308 
309  part_table_form = (Form_pg_partitioned_table) GETSTRUCT(tuple);
310  defaultPartId = part_table_form->partdefid;
311  ReleaseSysCache(tuple);
312  }
313 
314  return defaultPartId;
315 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
FormData_pg_partitioned_table * Form_pg_partitioned_table
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78

◆ get_partition_ancestors()

List* get_partition_ancestors ( Oid  relid)

Definition at line 115 of file partition.c.

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

Referenced by ExecInitPartitionInfo(), index_concurrently_swap(), pg_partition_ancestors(), pg_partition_root(), and pg_partition_tree().

116 {
117  List *result = NIL;
118  Relation inhRel;
119 
120  inhRel = table_open(InheritsRelationId, AccessShareLock);
121 
122  get_partition_ancestors_worker(inhRel, relid, &result);
123 
124  table_close(inhRel, AccessShareLock);
125 
126  return result;
127 }
#define NIL
Definition: pg_list.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define AccessShareLock
Definition: lockdefs.h:36
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
static void get_partition_ancestors_worker(Relation inhRel, Oid relid, List **ancestors)
Definition: partition.c:134

◆ get_partition_ancestors_worker()

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

Definition at line 134 of file partition.c.

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

Referenced by get_partition_ancestors().

135 {
136  Oid parentOid;
137 
138  /* Recursion ends at the topmost level, ie., when there's no parent */
139  parentOid = get_partition_parent_worker(inhRel, relid);
140  if (parentOid == InvalidOid)
141  return;
142 
143  *ancestors = lappend_oid(*ancestors, parentOid);
144  get_partition_ancestors_worker(inhRel, parentOid, ancestors);
145 }
static Oid get_partition_parent_worker(Relation inhRel, Oid relid)
Definition: partition.c:73
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:358
#define InvalidOid
Definition: postgres_ext.h:36
static void get_partition_ancestors_worker(Relation inhRel, Oid relid, List **ancestors)
Definition: partition.c:134

◆ get_partition_parent()

Oid get_partition_parent ( Oid  relid)

Definition at line 50 of file partition.c.

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

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

51 {
52  Relation catalogRelation;
53  Oid result;
54 
55  catalogRelation = table_open(InheritsRelationId, AccessShareLock);
56 
57  result = get_partition_parent_worker(catalogRelation, relid);
58 
59  if (!OidIsValid(result))
60  elog(ERROR, "could not find tuple for parent of relation %u", relid);
61 
62  table_close(catalogRelation, AccessShareLock);
63 
64  return result;
65 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
static Oid get_partition_parent_worker(Relation inhRel, Oid relid)
Definition: partition.c:73
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:645
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:228
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ get_partition_parent_worker()

static Oid get_partition_parent_worker ( Relation  inhRel,
Oid  relid 
)
static

Definition at line 73 of file partition.c.

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

Referenced by get_partition_ancestors_worker(), and get_partition_parent().

74 {
75  SysScanDesc scan;
76  ScanKeyData key[2];
77  Oid result = InvalidOid;
78  HeapTuple tuple;
79 
80  ScanKeyInit(&key[0],
81  Anum_pg_inherits_inhrelid,
82  BTEqualStrategyNumber, F_OIDEQ,
83  ObjectIdGetDatum(relid));
84  ScanKeyInit(&key[1],
85  Anum_pg_inherits_inhseqno,
86  BTEqualStrategyNumber, F_INT4EQ,
87  Int32GetDatum(1));
88 
89  scan = systable_beginscan(inhRel, InheritsRelidSeqnoIndexId, true,
90  NULL, 2, key);
91  tuple = systable_getnext(scan);
92  if (HeapTupleIsValid(tuple))
93  {
95 
96  result = form->inhparent;
97  }
98 
99  systable_endscan(scan);
100 
101  return result;
102 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define InheritsRelidSeqnoIndexId
Definition: indexing.h:171
FormData_pg_inherits * Form_pg_inherits
Definition: pg_inherits.h:44
#define Int32GetDatum(X)
Definition: postgres.h:479
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_proposed_default_constraint()

List* get_proposed_default_constraint ( List new_part_constraints)

Definition at line 353 of file partition.c.

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().

354 {
355  Expr *defPartConstraint;
356 
357  defPartConstraint = make_ands_explicit(new_part_constraints);
358 
359  /*
360  * Derive the partition constraints of default partition by negating the
361  * given partition constraints. The partition constraint never evaluates
362  * to NULL, so negating it like this is safe.
363  */
364  defPartConstraint = makeBoolExpr(NOT_EXPR,
365  list_make1(defPartConstraint),
366  -1);
367 
368  /* Simplify, to put the negated expression into canonical form */
369  defPartConstraint =
370  (Expr *) eval_const_expressions(NULL,
371  (Node *) defPartConstraint);
372  defPartConstraint = canonicalize_qual(defPartConstraint, true);
373 
374  return make_ands_implicit(defPartConstraint);
375 }
Definition: nodes.h:525
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition: clauses.c:2253
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:367
#define list_make1(x1)
Definition: pg_list.h:227
Expr * canonicalize_qual(Expr *qual, bool is_check)
Definition: prepqual.c:292
Expr * make_ands_explicit(List *andclauses)
Definition: makefuncs.c:705
List * make_ands_implicit(Expr *clause)
Definition: makefuncs.c:716

◆ has_partition_attrs()

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

Definition at line 238 of file partition.c.

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().

239 {
241  int partnatts;
242  List *partexprs;
243  ListCell *partexprs_item;
244  int i;
245 
246  if (attnums == NULL || rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
247  return false;
248 
249  key = RelationGetPartitionKey(rel);
250  partnatts = get_partition_natts(key);
251  partexprs = get_partition_exprs(key);
252 
253  partexprs_item = list_head(partexprs);
254  for (i = 0; i < partnatts; i++)
255  {
256  AttrNumber partattno = get_partition_col_attnum(key, i);
257 
258  if (partattno != 0)
259  {
261  attnums))
262  {
263  if (used_in_expr)
264  *used_in_expr = false;
265  return true;
266  }
267  }
268  else
269  {
270  /* Arbitrary expression */
271  Node *expr = (Node *) lfirst(partexprs_item);
272  Bitmapset *expr_attrs = NULL;
273 
274  /* Find all attributes referenced */
275  pull_varattnos(expr, 1, &expr_attrs);
276  partexprs_item = lnext(partexprs, partexprs_item);
277 
278  if (bms_overlap(attnums, expr_attrs))
279  {
280  if (used_in_expr)
281  *used_in_expr = true;
282  return true;
283  }
284  }
285  }
286 
287  return false;
288 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
Definition: nodes.h:525
static int get_partition_natts(PartitionKey key)
Definition: partcache.h:63
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
Form_pg_class rd_rel
Definition: rel.h:83
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
Definition: var.c:219
static List * get_partition_exprs(PartitionKey key)
Definition: partcache.h:69
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
static int16 get_partition_col_attnum(PartitionKey key, int col)
Definition: partcache.h:78
#define lfirst(lc)
Definition: pg_list.h:190
#define RelationGetPartitionKey(relation)
Definition: rel.h:603
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:494
int i
Definition: pg_list.h:50
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:427
int16 AttrNumber
Definition: attnum.h:21

◆ index_get_partition()

Oid index_get_partition ( Relation  partition,
Oid  indexId 
)

Definition at line 153 of file partition.c.

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

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

154 {
155  List *idxlist = RelationGetIndexList(partition);
156  ListCell *l;
157 
158  foreach(l, idxlist)
159  {
160  Oid partIdx = lfirst_oid(l);
161  HeapTuple tup;
162  Form_pg_class classForm;
163  bool ispartition;
164 
165  tup = SearchSysCache1(RELOID, ObjectIdGetDatum(partIdx));
166  if (!HeapTupleIsValid(tup))
167  elog(ERROR, "cache lookup failed for relation %u", partIdx);
168  classForm = (Form_pg_class) GETSTRUCT(tup);
169  ispartition = classForm->relispartition;
170  ReleaseSysCache(tup);
171  if (!ispartition)
172  continue;
173  if (get_partition_parent(lfirst_oid(l)) == indexId)
174  {
175  list_free(idxlist);
176  return partIdx;
177  }
178  }
179 
180  return InvalidOid;
181 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Oid get_partition_parent(Oid relid)
Definition: partition.c:50
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4347
FormData_pg_class * Form_pg_class
Definition: pg_class.h:150
void list_free(List *list)
Definition: list.c:1377
#define elog(elevel,...)
Definition: elog.h:228
Definition: pg_list.h:50
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ map_partition_varattnos()

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

Definition at line 201 of file partition.c.

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

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

204 {
205  bool my_found_whole_row = false;
206 
207  if (expr != NIL)
208  {
209  AttrNumber *part_attnos;
210 
211  part_attnos = convert_tuples_by_name_map(RelationGetDescr(to_rel),
212  RelationGetDescr(from_rel));
213  expr = (List *) map_variable_attnos((Node *) expr,
214  fromrel_varno, 0,
215  part_attnos,
216  RelationGetDescr(from_rel)->natts,
217  RelationGetForm(to_rel)->reltype,
218  &my_found_whole_row);
219  }
220 
221  if (found_whole_row)
222  *found_whole_row = my_found_whole_row;
223 
224  return expr;
225 }
#define NIL
Definition: pg_list.h:65
#define RelationGetDescr(relation)
Definition: rel.h:448
#define RelationGetForm(relation)
Definition: rel.h:416
Definition: nodes.h:525
Node * map_variable_attnos(Node *node, int target_varno, int sublevels_up, const AttrNumber *attno_map, int map_length, Oid to_rowtype, bool *found_whole_row)
AttrNumber * convert_tuples_by_name_map(TupleDesc indesc, TupleDesc outdesc)
Definition: tupconvert.c:245
Definition: pg_list.h:50
int16 AttrNumber
Definition: attnum.h:21

◆ update_default_partition_oid()

void update_default_partition_oid ( Oid  parentId,
Oid  defaultPartId 
)

Definition at line 323 of file partition.c.

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

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

324 {
325  HeapTuple tuple;
326  Relation pg_partitioned_table;
327  Form_pg_partitioned_table part_table_form;
328 
329  pg_partitioned_table = table_open(PartitionedRelationId, RowExclusiveLock);
330 
331  tuple = SearchSysCacheCopy1(PARTRELID, ObjectIdGetDatum(parentId));
332 
333  if (!HeapTupleIsValid(tuple))
334  elog(ERROR, "cache lookup failed for partition key of relation %u",
335  parentId);
336 
337  part_table_form = (Form_pg_partitioned_table) GETSTRUCT(tuple);
338  part_table_form->partdefid = defaultPartId;
339  CatalogTupleUpdate(pg_partitioned_table, &tuple->t_self, tuple);
340 
341  heap_freetuple(tuple);
342  table_close(pg_partitioned_table, RowExclusiveLock);
343 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
FormData_pg_partitioned_table * Form_pg_partitioned_table
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:174
#define elog(elevel,...)
Definition: elog.h:228
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39