From ec26b2b84bb91684072577b9d7d9615d8485d67b Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Fri, 20 Oct 2023 19:00:26 +0800 Subject: [PATCH] Expose some functions to support PAX for partition tables 1. ComputePartitionAttrs: expose function 2. transformPartitionBound: add argument of PartitionKey 3. transformPartitionRangeBounds: add argument of PartitionKey 4. list_sort_arg: sort the List with context argument in cmp function --- src/backend/commands/tablecmds.c | 6 ++-- src/backend/nodes/list.c | 14 +++++++++ src/backend/parser/parse_partition_gp.c | 40 ++++--------------------- src/backend/parser/parse_utilcmd.c | 14 ++++----- src/include/commands/tablecmds.h | 2 ++ src/include/nodes/pg_list.h | 3 ++ src/include/parser/parse_utilcmd.h | 2 +- 7 files changed, 33 insertions(+), 48 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 0ec65204be2..eac95eeb920 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -533,8 +533,6 @@ static void ATExecExpandTableCTAS(AlterTableCmd *rootCmd, Relation rel, AlterTab static void ATExecSetDistributedBy(Relation rel, Node *node, AlterTableCmd *cmd); static PartitionSpec *transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy); -static void ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNumber *partattrs, - List **partexprs, Oid *partopclass, Oid *partcollation, char strategy); static void CreateInheritance(Relation child_rel, Relation parent_rel); static void RemoveInheritance(Relation child_rel, Relation parent_rel, bool allow_detached); @@ -1241,7 +1239,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, NULL, false, false); addNSItemToQuery(pstate, nsitem, false, true, true); - bound = transformPartitionBound(pstate, parent, stmt->partbound); + bound = transformPartitionBound(pstate, parent, RelationGetPartitionKey(parent), stmt->partbound); /* * Check first that the new partition's bound is valid and does not @@ -20435,7 +20433,7 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy) * Compute per-partition-column information from a list of PartitionElems. * Expressions in the PartitionElems must be parse-analyzed already. */ -static void +void ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNumber *partattrs, List **partexprs, Oid *partopclass, Oid *partcollation, char strategy) diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c index 12847e35ea3..cb4800c3589 100644 --- a/src/backend/nodes/list.c +++ b/src/backend/nodes/list.c @@ -1572,6 +1572,20 @@ list_sort(List *list, list_sort_comparator cmp) qsort(list->elements, len, sizeof(ListCell), (qsort_comparator) cmp); } +void +list_sort_arg(List *list, list_sort_arg_comparator cmp, void *arg) +{ + typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg); + int len; + + check_list_invariants(list); + + /* Nothing to do if there's less than two elements */ + len = list_length(list); + if (len > 1) + qsort_arg(list->elements, len, sizeof(ListCell), (qsort_arg_comparator) cmp, arg); +} + /* * list_sort comparator for sorting a list into ascending int order. */ diff --git a/src/backend/parser/parse_partition_gp.c b/src/backend/parser/parse_partition_gp.c index f47728a99dc..2897fdbd737 100644 --- a/src/backend/parser/parse_partition_gp.c +++ b/src/backend/parser/parse_partition_gp.c @@ -85,11 +85,11 @@ static char *extract_tablename_from_options(List **options); * Used when sorting CreateStmts across all partitions. */ static int32 -qsort_stmt_cmp(const void *a, const void *b, void *arg) +qsort_stmt_cmp(const ListCell *a, const ListCell *b, void *arg) { int32 cmpval = 0; - CreateStmt *b1cstmt = *(CreateStmt **) a; - CreateStmt *b2cstmt = *(CreateStmt **) b; + CreateStmt *b1cstmt = lfirst_node(CreateStmt, a); + CreateStmt *b2cstmt = lfirst_node(CreateStmt, b); PartitionKey partKey = (PartitionKey) arg; PartitionBoundSpec *b1 = b1cstmt->partbound; PartitionBoundSpec *b2 = b2cstmt->partbound; @@ -317,36 +317,6 @@ consts_to_datums(PartitionKey partkey, List *consts) return datums; } -/* - * Sort a list of CreateStmts in-place. - */ -static void -list_qsort_arg(List *list, qsort_arg_comparator cmp, void *arg) -{ - int len = list_length(list); - ListCell *cell; - CreateStmt **create_stmts; - int i; - - /* Empty list is easy */ - if (len == 0) - return; - - /* Flatten list into an array, so we can use qsort */ - create_stmts = (CreateStmt **) palloc(sizeof(CreateStmt *) * len); - i = 0; - foreach(cell, list) - create_stmts[i++] = (CreateStmt *) lfirst(cell); - - qsort_arg(create_stmts, len, sizeof(CreateStmt *), cmp, arg); - - i = 0; - foreach(cell, list) - cell->ptr_value = create_stmts[i++]; - - pfree(create_stmts); -} - /* * Sort the list of GpPartitionBoundSpecs based first on START, if START does * not exist, use END. After sort, if any stmt contains an implicit START or @@ -359,7 +329,7 @@ deduceImplicitRangeBounds(ParseState *pstate, Relation parentrel, List *stmts) /* GPDB_14_MERGE_FIXEME: most places use true for new api, need to check */ PartitionDesc desc = RelationGetPartitionDesc(parentrel, true); - list_qsort_arg(stmts, qsort_stmt_cmp, key); + list_sort_arg(stmts, qsort_stmt_cmp, key); /* * This works slightly differenly, depending on whether this is a @@ -1111,7 +1081,7 @@ generateListPartition(ParseState *pstate, boundspec->listdatums = listdatums; boundspec->location = -1; - boundspec = transformPartitionBound(pstate, parentrel, boundspec); + boundspec = transformPartitionBound(pstate, parentrel, RelationGetPartitionKey(parentrel), boundspec); childstmt = makePartitionCreateStmt(parentrel, elem->partName, boundspec, subPart, elem, partnamecomp); diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index e0c8423d45c..b83ebc67524 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -155,7 +155,7 @@ static void transformColumnType(CreateStmtContext *cxt, ColumnDef *column); static void setSchemaName(char *context_schema, char **stmt_schema_name); static void transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd); static List *transformPartitionRangeBounds(ParseState *pstate, List *blist, - Relation parent); + Relation parent, PartitionKey key); static void validateInfiniteBounds(ParseState *pstate, List *blist); static DistributedBy *getLikeDistributionPolicy(TableLikeClause *e); @@ -5127,7 +5127,7 @@ transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd) Assert(RelationGetPartitionKey(parentRel) != NULL); if (cmd->bound != NULL) cxt->partbound = transformPartitionBound(cxt->pstate, parentRel, - cmd->bound); + RelationGetPartitionKey(parentRel), cmd->bound); break; case RELKIND_PARTITIONED_INDEX: @@ -5169,11 +5169,10 @@ transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd) * Transform a partition bound specification */ PartitionBoundSpec * -transformPartitionBound(ParseState *pstate, Relation parent, +transformPartitionBound(ParseState *pstate, Relation parent, PartitionKey key, PartitionBoundSpec *spec) { PartitionBoundSpec *result_spec; - PartitionKey key = RelationGetPartitionKey(parent); char strategy = get_partition_strategy(key); int partnatts = get_partition_natts(key); List *partexprs = get_partition_exprs(key); @@ -5306,10 +5305,10 @@ transformPartitionBound(ParseState *pstate, Relation parent, */ result_spec->lowerdatums = transformPartitionRangeBounds(pstate, spec->lowerdatums, - parent); + parent, key); result_spec->upperdatums = transformPartitionRangeBounds(pstate, spec->upperdatums, - parent); + parent, key); } else elog(ERROR, "unexpected partition strategy: %d", (int) strategy); @@ -5324,10 +5323,9 @@ transformPartitionBound(ParseState *pstate, Relation parent, */ static List * transformPartitionRangeBounds(ParseState *pstate, List *blist, - Relation parent) + Relation parent, PartitionKey key) { List *result = NIL; - PartitionKey key = RelationGetPartitionKey(parent); List *partexprs = get_partition_exprs(key); ListCell *lc; int i, diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index cd5ea589b15..13b52157185 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -124,6 +124,8 @@ extern void RangeVarCallbackOwnsRelation(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg); extern bool PartConstraintImpliedByRelConstraint(Relation scanrel, List *partConstraint); +extern void ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNumber *partattrs, + List **partexprs, Oid *partopclass, Oid *partcollation, char strategy); /* GPDB specific functions */ extern void ATExecGPPartCmds(Relation origrel, AlterTableCmd *cmd); diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h index ef4a2c24899..7dead2e9d8f 100644 --- a/src/include/nodes/pg_list.h +++ b/src/include/nodes/pg_list.h @@ -627,6 +627,9 @@ extern pg_nodiscard List *list_copy_deep(const List *oldlist); typedef int (*list_sort_comparator) (const ListCell *a, const ListCell *b); extern void list_sort(List *list, list_sort_comparator cmp); +typedef int (*list_sort_arg_comparator) (const ListCell *a, const ListCell *b, void *arg); +extern void list_sort_arg(List *list, list_sort_arg_comparator cmp, void *arg); + extern int list_int_cmp(const ListCell *p1, const ListCell *p2); extern int list_oid_cmp(const ListCell *p1, const ListCell *p2); diff --git a/src/include/parser/parse_utilcmd.h b/src/include/parser/parse_utilcmd.h index d4f0bd25f07..836c283dcde 100644 --- a/src/include/parser/parse_utilcmd.h +++ b/src/include/parser/parse_utilcmd.h @@ -35,7 +35,7 @@ extern void transformRuleStmt(RuleStmt *stmt, const char *queryString, List **actions, Node **whereClause); extern List *transformCreateSchemaStmt(CreateSchemaStmt *stmt); extern PartitionBoundSpec *transformPartitionBound(ParseState *pstate, Relation parent, - PartitionBoundSpec *spec); + PartitionKey key, PartitionBoundSpec *spec); extern List *expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause); extern IndexStmt *generateClonedIndexStmt(RangeVar *heapRel,