diff --git a/hypopg_import.c b/hypopg_import.c index cbf6cd9..c38343d 100644 --- a/hypopg_import.c +++ b/hypopg_import.c @@ -37,6 +37,14 @@ #include "utils/ruleutils.h" #endif #include "optimizer/clauses.h" +#if PG_VERSION_NUM >= 110000 +#include "catalog/partition.h" +#include "optimizer/cost.h" +#include "optimizer/paths.h" +#include "partitioning/partbounds.h" +#include "utils/partcache.h" +#include "partitioning/partdefs.h" +#endif #include "optimizer/planner.h" #include "optimizer/var.h" #include "parser/parse_coerce.h" @@ -49,9 +57,8 @@ #include "utils/rel.h" #include "utils/syscache.h" -#include "include/hypopg_import.h" -int max_parallel_workers_per_gather = 2; +#include "include/hypopg_import.h" @@ -819,6 +826,7 @@ make_one_range_bound(PartitionKey key, int index, List *datums, bool lower) return bound; } + /* * Copied from src/backend/catalog/partition.c, not exported * @@ -831,74 +839,9 @@ qsort_partition_rbound_cmp(const void *a, const void *b, void *arg) PartitionRangeBound *b2 = (*(PartitionRangeBound *const *) b); PartitionKey key = (PartitionKey) arg; - return partition_rbound_cmp(key, b1->datums, b1->kind, b1->lower, b2); -} - -/* - * Copied from src/backend/catalog/partition.c, not exported - * - * partition_rbound_cmp - * - * Return for two range bounds whether the 1st one (specified in datums1, - * kind1, and lower1) is <, =, or > the bound specified in *b2. - * - * Note that if the values of the two range bounds compare equal, then we take - * into account whether they are upper or lower bounds, and an upper bound is - * considered to be smaller than a lower bound. This is important to the way - * that RelationBuildPartitionDesc() builds the PartitionBoundInfoData - * structure, which only stores the upper bound of a common boundary between - * two contiguous partitions. - */ -int32 -partition_rbound_cmp(PartitionKey key, - Datum *datums1, PartitionRangeDatumKind *kind1, - bool lower1, PartitionRangeBound *b2) -{ - int32 cmpval = 0; /* placate compiler */ - int i; - Datum *datums2 = b2->datums; - PartitionRangeDatumKind *kind2 = b2->kind; - bool lower2 = b2->lower; - - for (i = 0; i < key->partnatts; i++) - { - /* - * First, handle cases where the column is unbounded, which should not - * invoke the comparison procedure, and should not consider any later - * columns. Note that the PartitionRangeDatumKind enum elements - * compare the same way as the values they represent. - */ - if (kind1[i] < kind2[i]) - return -1; - else if (kind1[i] > kind2[i]) - return 1; - else if (kind1[i] != PARTITION_RANGE_DATUM_VALUE) - - /* - * The column bounds are both MINVALUE or both MAXVALUE. No later - * columns should be considered, but we still need to compare - * whether they are upper or lower bounds. - */ - break; - - cmpval = DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[i], - key->partcollation[i], - datums1[i], - datums2[i])); - if (cmpval != 0) - break; - } - - /* - * If the comparison is anything other than equal, we're done. If they - * compare equal though, we still have to consider whether the boundaries - * are inclusive or exclusive. Exclusive one is considered smaller of the - * two. - */ - if (cmpval == 0 && lower1 != lower2) - cmpval = lower1 ? 1 : -1; - - return cmpval; + return partition_rbound_cmp(key->partnatts, key->partsupfunc, + key->partcollation, b1->datums, b1->kind, + b1->lower, b2); } /* ---------- diff --git a/hypopg_table.c b/hypopg_table.c index a737703..9569ce1 100644 --- a/hypopg_table.c +++ b/hypopg_table.c @@ -26,8 +26,9 @@ #include "access/htup_details.h" #include "access/nbtree.h" #include "catalog/namespace.h" +#include "catalog/partition.h" #include "catalog/pg_class.h" -#include "catalog/pg_inherits_fn.h" +#include "catalog/pg_inherits.h" #include "catalog/pg_opclass.h" #include "catalog/pg_type.h" #include "nodes/makefuncs.h" @@ -48,8 +49,10 @@ #include "utils/datum.h" #include "utils/fmgroids.h" #include "utils/lsyscache.h" +#include "utils/partcache.h" #include "utils/ruleutils.h" #include "utils/syscache.h" +#include "partitioning/partbounds.h" #endif #include "include/hypopg.h" @@ -1851,50 +1854,50 @@ hypo_injectHypotheticalPartitioning(PlannerInfo *root, pcinfo->parent_relid = oldsize; pcinfo->child_rels = partitioned_child_rels; root->pcinfo_list = lappend(root->pcinfo_list, pcinfo); - + /* add partition info to this rel */ hypo_partition_table(root, rel, parent); } - - /* + + /* * If this rel is partition, we add the partition constraints to the - * rte->securityQuals so that the relation which is need not be scanned - * is marked as Dummy at the set_append_rel_size() and the rel->rows is - * computed correctly at the set_baserel_size_estimates(). We shouldn't - * rewrite the rel->pages and the rel->tuples here, because they will be + * rte->securityQuals so that the relation which is need not be scanned + * is marked as Dummy at the set_append_rel_size() and the rel->rows is + * computed correctly at the set_baserel_size_estimates(). We shouldn't + * rewrite the rel->pages and the rel->tuples here, because they will be * rewritten at the later hook. * - * TODO: should comfirm that the tuples will not referred till the + * TODO: should comfirm that the tuples will not referred till the * set_baserel_size_esimates() and think about rel->reltarget->width * */ if (rel->reloptkind != RELOPT_BASEREL &&HYPO_RTI_IS_TAGGED(rel->relid,root)) - { + { List *constraints; - + /* get its partition constraints */ constraints = hypo_get_partition_constraints(root, rel, parent); - + /* - * to compute rel->rows at set_baserel_size_estimates using parent's + * to compute rel->rows at set_baserel_size_estimates using parent's * statistics, parent's tuples and baserestrictinfo, we add the partition * constraints to its rte->securityQuals */ planner_rt_fetch(rel->relid, root)->securityQuals = list_make1(constraints); - } + } } /* * If this rel is partition, we remove the partition constraints from the - * its rel->baserestrictinfo and rewrite some items of its RelOptInfo: - * the rel->pages, the rel->tuples rel->baserestrictcost. After that + * its rel->baserestrictinfo and rewrite some items of its RelOptInfo: + * the rel->pages, the rel->tuples rel->baserestrictcost. After that * we call the set_plain_rel_pathlist() to re-create its pathlist using * the new RelOptInfo. * */ -void hypo_setPartitionPathlist(PlannerInfo *root, RelOptInfo *rel, +void hypo_setPartitionPathlist(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte) { ListCell *l; @@ -1904,19 +1907,19 @@ void hypo_setPartitionPathlist(PlannerInfo *root, RelOptInfo *rel, List *constraints = hypo_get_partition_constraints(root, rel, parent); PlannerInfo *root_dummy; Selectivity selectivity; - double pages; + double pages; - /* - * get the parent's rel and copy its rel->baserestrictinfo to + /* + * get the parent's rel and copy its rel->baserestrictinfo to * the own rel->baserestrictinfo. - * this part is inspired on set_append_rel_size(). + * this part is inspired on set_append_rel_size(). */ - foreach(l, root->append_rel_list) + foreach(l, root->append_rel_list) { AppendRelInfo *appinfo = (AppendRelInfo *)lfirst(l); List *childquals = NIL; Index cq_min_security = UINT_MAX; - ListCell *lc; + ListCell *lc; if(appinfo->child_relid == rti) { @@ -1928,19 +1931,19 @@ void hypo_setPartitionPathlist(PlannerInfo *root, RelOptInfo *rel, RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); Node *childqual; ListCell *lc2; - + Assert(IsA(rinfo, RestrictInfo)); childqual = adjust_appendrel_attrs(root, (Node *) rinfo->clause, 1, &appinfo); childqual = eval_const_expressions(root, childqual); - + /* might have gotten an AND clause, if so flatten it */ foreach(lc2, make_ands_implicit((Expr *) childqual)) { Node *onecq = (Node *) lfirst(lc2); bool pseudoconstant; - + /* check for pseudoconstant (no Vars or volatile functions) */ pseudoconstant = !contain_vars_of_level(onecq, 0) && @@ -1964,34 +1967,34 @@ void hypo_setPartitionPathlist(PlannerInfo *root, RelOptInfo *rel, } rel->baserestrictinfo = childquals; rel->baserestrict_min_security = cq_min_security; - break; + break; } - } - - /* + } + + /* * make dummy PlannerInfo to compute the selectivity, and then rewrite * tuples and pages using this selectivity */ root_dummy = makeNode(PlannerInfo); root_dummy = root; root_dummy->simple_rel_array[rti] = rel; - - selectivity = clauselist_selectivity(root_dummy, + + selectivity = clauselist_selectivity(root_dummy, constraints, 0, JOIN_INNER, NULL); - + pages = ceil(rel->pages * selectivity); rel->pages = (BlockNumber)pages; rel->tuples = clamp_row_est(rel->tuples * selectivity); - + /* recompute the rel->baserestrictcost*/ cost_qual_eval(&rel->baserestrictcost, rel->baserestrictinfo, root); - - /* - * call the set_plain_rel_pathlist() to re-create its pathlist using - * the new RelOptInfo + + /* + * call the set_plain_rel_pathlist() to re-create its pathlist using + * the new RelOptInfo */ set_plain_rel_pathlist(root, rel, rte); } diff --git a/include/hypopg_import.h b/include/hypopg_import.h index 7f88688..74d732e 100644 --- a/include/hypopg_import.h +++ b/include/hypopg_import.h @@ -15,6 +15,7 @@ #include "nodes/pg_list.h" #include "optimizer/planner.h" #include "optimizer/pathnode.h" +#include "partitioning/partbounds.h" #include "utils/rel.h" @@ -37,6 +38,7 @@ extern char *get_am_name(Oid amOid); extern void get_opclass_name(Oid opclass, Oid actual_datatype, StringInfo buf); #if PG_VERSION_NUM >= 100000 +#if PG_VERSION_NUM < 110000 /* * Imported from src/backend/catalog/partition.c, not exported */ @@ -78,6 +80,7 @@ typedef struct PartitionRangeBound PartitionRangeDatumKind *kind; /* the kind of each datum */ bool lower; /* this is the lower (vs upper) bound */ } PartitionRangeBound; +#endif /* Context info needed for invoking a recursive querytree display routine */ typedef struct @@ -109,9 +112,6 @@ int32 qsort_partition_list_value_cmp(const void *a, const void *b, void *arg); PartitionRangeBound *make_one_range_bound(PartitionKey key, int index, List *datums, bool lower); int32 qsort_partition_rbound_cmp(const void *a, const void *b, void *arg); -int32 partition_rbound_cmp(PartitionKey key, - Datum *datums1, PartitionRangeDatumKind *kind1, - bool lower1, PartitionRangeBound *b2); void get_const_expr(Const *constval, deparse_context *context, int showtype); void get_const_collation(Const *constval, deparse_context *context);