Skip to content

Commit ef6087e

Browse files
committed
Minor preparatory refactoring for UPDATE row movement.
Generalize is_partition_attr to has_partition_attrs and make it accessible from outside tablecmds.c. Change map_partition_varattnos to clarify that it can be used for mapping between any two relations in a partitioning hierarchy, not just parent -> child. Amit Khandekar, reviewed by Amit Langote, David Rowley, and me. Some comment changes by me. Discussion: http://postgr.es/m/CAJ3gD9fWfxgKC+PfJZF3hkgAcNOy-LpfPxVYitDEXKHjeieWQQ@mail.gmail.com
1 parent ac3ff8b commit ef6087e

File tree

3 files changed

+87
-77
lines changed

3 files changed

+87
-77
lines changed

src/backend/catalog/partition.c

Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,10 +1446,13 @@ get_qual_from_partbound(Relation rel, Relation parent,
14461446

14471447
/*
14481448
* map_partition_varattnos - maps varattno of any Vars in expr from the
1449-
* parent attno to partition attno.
1449+
* attno's of 'from_rel' to the attno's of 'to_rel' partition, each of which
1450+
* may be either a leaf partition or a partitioned table, but both of which
1451+
* must be from the same partitioning hierarchy.
14501452
*
1451-
* We must allow for cases where physical attnos of a partition can be
1452-
* different from the parent's.
1453+
* Even though all of the same column names must be present in all relations
1454+
* in the hierarchy, and they must also have the same types, the attnos may
1455+
* be different.
14531456
*
14541457
* If found_whole_row is not NULL, *found_whole_row returns whether a
14551458
* whole-row variable was found in the input expression.
@@ -1459,8 +1462,8 @@ get_qual_from_partbound(Relation rel, Relation parent,
14591462
* are working on Lists, so it's less messy to do the casts internally.
14601463
*/
14611464
List *
1462-
map_partition_varattnos(List *expr, int target_varno,
1463-
Relation partrel, Relation parent,
1465+
map_partition_varattnos(List *expr, int fromrel_varno,
1466+
Relation to_rel, Relation from_rel,
14641467
bool *found_whole_row)
14651468
{
14661469
bool my_found_whole_row = false;
@@ -1469,14 +1472,14 @@ map_partition_varattnos(List *expr, int target_varno,
14691472
{
14701473
AttrNumber *part_attnos;
14711474

1472-
part_attnos = convert_tuples_by_name_map(RelationGetDescr(partrel),
1473-
RelationGetDescr(parent),
1475+
part_attnos = convert_tuples_by_name_map(RelationGetDescr(to_rel),
1476+
RelationGetDescr(from_rel),
14741477
gettext_noop("could not convert row type"));
14751478
expr = (List *) map_variable_attnos((Node *) expr,
1476-
target_varno, 0,
1479+
fromrel_varno, 0,
14771480
part_attnos,
1478-
RelationGetDescr(parent)->natts,
1479-
RelationGetForm(partrel)->reltype,
1481+
RelationGetDescr(from_rel)->natts,
1482+
RelationGetForm(to_rel)->reltype,
14801483
&my_found_whole_row);
14811484
}
14821485

@@ -2598,6 +2601,70 @@ get_partition_for_tuple(Relation relation, Datum *values, bool *isnull)
25982601
return part_index;
25992602
}
26002603

2604+
/*
2605+
* Checks if any of the 'attnums' is a partition key attribute for rel
2606+
*
2607+
* Sets *used_in_expr if any of the 'attnums' is found to be referenced in some
2608+
* partition key expression. It's possible for a column to be both used
2609+
* directly and as part of an expression; if that happens, *used_in_expr may
2610+
* end up as either true or false. That's OK for current uses of this
2611+
* function, because *used_in_expr is only used to tailor the error message
2612+
* text.
2613+
*/
2614+
bool
2615+
has_partition_attrs(Relation rel, Bitmapset *attnums,
2616+
bool *used_in_expr)
2617+
{
2618+
PartitionKey key;
2619+
int partnatts;
2620+
List *partexprs;
2621+
ListCell *partexprs_item;
2622+
int i;
2623+
2624+
if (attnums == NULL || rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
2625+
return false;
2626+
2627+
key = RelationGetPartitionKey(rel);
2628+
partnatts = get_partition_natts(key);
2629+
partexprs = get_partition_exprs(key);
2630+
2631+
partexprs_item = list_head(partexprs);
2632+
for (i = 0; i < partnatts; i++)
2633+
{
2634+
AttrNumber partattno = get_partition_col_attnum(key, i);
2635+
2636+
if (partattno != 0)
2637+
{
2638+
if (bms_is_member(partattno - FirstLowInvalidHeapAttributeNumber,
2639+
attnums))
2640+
{
2641+
if (used_in_expr)
2642+
*used_in_expr = false;
2643+
return true;
2644+
}
2645+
}
2646+
else
2647+
{
2648+
/* Arbitrary expression */
2649+
Node *expr = (Node *) lfirst(partexprs_item);
2650+
Bitmapset *expr_attrs = NULL;
2651+
2652+
/* Find all attributes referenced */
2653+
pull_varattnos(expr, 1, &expr_attrs);
2654+
partexprs_item = lnext(partexprs_item);
2655+
2656+
if (bms_overlap(attnums, expr_attrs))
2657+
{
2658+
if (used_in_expr)
2659+
*used_in_expr = true;
2660+
return true;
2661+
}
2662+
}
2663+
}
2664+
2665+
return false;
2666+
}
2667+
26012668
/*
26022669
* qsort_partition_hbound_cmp
26032670
*

src/backend/commands/tablecmds.c

Lines changed: 6 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,6 @@ static void RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid,
468468
Oid oldRelOid, void *arg);
469469
static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid,
470470
Oid oldrelid, void *arg);
471-
static bool is_partition_attr(Relation rel, AttrNumber attnum, bool *used_in_expr);
472471
static PartitionSpec *transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy);
473472
static void ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs,
474473
List **partexprs, Oid *partopclass, Oid *partcollation, char strategy);
@@ -6491,68 +6490,6 @@ ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
64916490
cmd->subtype = AT_DropColumnRecurse;
64926491
}
64936492

6494-
/*
6495-
* Checks if attnum is a partition attribute for rel
6496-
*
6497-
* Sets *used_in_expr if attnum is found to be referenced in some partition
6498-
* key expression. It's possible for a column to be both used directly and
6499-
* as part of an expression; if that happens, *used_in_expr may end up as
6500-
* either true or false. That's OK for current uses of this function, because
6501-
* *used_in_expr is only used to tailor the error message text.
6502-
*/
6503-
static bool
6504-
is_partition_attr(Relation rel, AttrNumber attnum, bool *used_in_expr)
6505-
{
6506-
PartitionKey key;
6507-
int partnatts;
6508-
List *partexprs;
6509-
ListCell *partexprs_item;
6510-
int i;
6511-
6512-
if (rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
6513-
return false;
6514-
6515-
key = RelationGetPartitionKey(rel);
6516-
partnatts = get_partition_natts(key);
6517-
partexprs = get_partition_exprs(key);
6518-
6519-
partexprs_item = list_head(partexprs);
6520-
for (i = 0; i < partnatts; i++)
6521-
{
6522-
AttrNumber partattno = get_partition_col_attnum(key, i);
6523-
6524-
if (partattno != 0)
6525-
{
6526-
if (attnum == partattno)
6527-
{
6528-
if (used_in_expr)
6529-
*used_in_expr = false;
6530-
return true;
6531-
}
6532-
}
6533-
else
6534-
{
6535-
/* Arbitrary expression */
6536-
Node *expr = (Node *) lfirst(partexprs_item);
6537-
Bitmapset *expr_attrs = NULL;
6538-
6539-
/* Find all attributes referenced */
6540-
pull_varattnos(expr, 1, &expr_attrs);
6541-
partexprs_item = lnext(partexprs_item);
6542-
6543-
if (bms_is_member(attnum - FirstLowInvalidHeapAttributeNumber,
6544-
expr_attrs))
6545-
{
6546-
if (used_in_expr)
6547-
*used_in_expr = true;
6548-
return true;
6549-
}
6550-
}
6551-
}
6552-
6553-
return false;
6554-
}
6555-
65566493
/*
65576494
* Return value is the address of the dropped column.
65586495
*/
@@ -6613,7 +6550,9 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
66136550
colName)));
66146551

66156552
/* Don't drop columns used in the partition key */
6616-
if (is_partition_attr(rel, attnum, &is_expr))
6553+
if (has_partition_attrs(rel,
6554+
bms_make_singleton(attnum - FirstLowInvalidHeapAttributeNumber),
6555+
&is_expr))
66176556
{
66186557
if (!is_expr)
66196558
ereport(ERROR,
@@ -8837,7 +8776,9 @@ ATPrepAlterColumnType(List **wqueue,
88378776
colName)));
88388777

88398778
/* Don't alter columns used in the partition key */
8840-
if (is_partition_attr(rel, attnum, &is_expr))
8779+
if (has_partition_attrs(rel,
8780+
bms_make_singleton(attnum - FirstLowInvalidHeapAttributeNumber),
8781+
&is_expr))
88418782
{
88428783
if (!is_expr)
88438784
ereport(ERROR,

src/include/catalog/partition.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,13 @@ extern void check_new_partition_bound(char *relname, Relation parent,
5454
extern Oid get_partition_parent(Oid relid);
5555
extern List *get_qual_from_partbound(Relation rel, Relation parent,
5656
PartitionBoundSpec *spec);
57-
extern List *map_partition_varattnos(List *expr, int target_varno,
58-
Relation partrel, Relation parent,
57+
extern List *map_partition_varattnos(List *expr, int fromrel_varno,
58+
Relation to_rel, Relation from_rel,
5959
bool *found_whole_row);
6060
extern List *RelationGetPartitionQual(Relation rel);
6161
extern Expr *get_partition_qual_relid(Oid relid);
62+
extern bool has_partition_attrs(Relation rel, Bitmapset *attnums,
63+
bool *used_in_expr);
6264

6365
extern Oid get_default_oid_from_partdesc(PartitionDesc partdesc);
6466
extern Oid get_default_partition_oid(Oid parentId);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy