Permalink
Browse files

Fix hypo_get_partition_constraints to follow upstream behavior.

  • Loading branch information...
rjuju committed Nov 24, 2018
1 parent 908fcba commit 1c87601182c84a4ca8c1d868745024fbf65a8f49
Showing with 50 additions and 16 deletions.
  1. +6 −1 hypopg_analyze.c
  2. +43 −14 hypopg_table.c
  3. +1 −1 include/hypopg_table.h
@@ -111,6 +111,11 @@ hypo_clauselist_selectivity(PlannerInfo *root, RelOptInfo *rel, List *clauses,
rtable = list_make1(rte);

parse = makeNode(Query);
/*
* makeNode() does a palloc0fast, so the commandType should already be
* CMD_UNKNOWN, but force it for safety.
*/
parse->commandType = CMD_UNKNOWN;
parse->rtable = rtable;
root_dummy->parse = parse;

@@ -141,7 +146,7 @@ hypo_clauselist_selectivity(PlannerInfo *root, RelOptInfo *rel, List *clauses,
root_dummy->parse->rtable = list_make1(rte);

/* get the partition constraints, setup for a rel with relid 1 */
clauses = hypo_get_partition_constraints(root_dummy, rel, part);
clauses = hypo_get_partition_constraints(root_dummy, rel, part, true);

/*
* and remove the hypothetical oid to avoid computing selectivity with
@@ -2326,7 +2326,7 @@ hypo_markDummyIfExcluded(PlannerInfo *root, RelOptInfo *rel,
Assert(rte->relkind == 'r');

/* get its partition constraints */
constraints = hypo_get_partition_constraints(root, rel, parent);
constraints = hypo_get_partition_constraints(root, rel, parent, false);

/*
* We do not currently enforce that CHECK constraints contain only
@@ -2388,7 +2388,8 @@ hypo_set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel,
if (OidIsValid(entry->parentid))
{
hypoTable *parent = hypo_find_table(entry->parentid, false);
rel->partition_qual = hypo_get_partition_constraints(root, rel, parent);
rel->partition_qual = hypo_get_partition_constraints(root, rel, parent,
false);
}
}
#endif
@@ -2399,39 +2400,67 @@ hypo_set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel,
* ancestors if any. The main processing is done in
* hypo_get_partition_quals_inh.
*
* The force_generation is used to make sure that hypo_clauselist_selectivity()
* will get all the constraints, since it's required for a proper selectivity
* estimation.
*
* It is inspired on get_relation_constraints()
*/
List *
hypo_get_partition_constraints(PlannerInfo *root, RelOptInfo *rel, hypoTable *parent)
hypo_get_partition_constraints(PlannerInfo *root, RelOptInfo *rel,
hypoTable *parent, bool force_generation)
{
Index varno = rel->relid;
Oid childOid;
hypoTable *child;
List *constraints;
List *pcqual;

childOid = HYPO_TABLE_RTI_GET_HYPOOID(rel->relid, root);
child = hypo_find_table(childOid, false);

Assert(child->parentid == parent->oid);

/* get its partition constraints */
constraints = hypo_get_partition_quals_inh(child, parent);
pcqual = hypo_get_partition_quals_inh(child, parent);

if (constraints)
#if PG_VERSION_NUM >= 110000
Assert(
(force_generation &&
list_length(root->parse->rtable) == 1 &&
root->parse->commandType == CMD_UNKNOWN &&
hypo_table_oid_is_hypothetical(root->simple_rte_array[1]->relid))
|| !force_generation
);

/*
* For selects, partition pruning uses the parent table's partition bound
* descriptor, instead of constraint exclusion which is driven by the
* individual partition's partition constraint.
*/
if ((enable_partition_pruning && root->parse->commandType != CMD_SELECT)
|| force_generation)
{
#endif
if (pcqual)
{
/*
* Run each expression through const-simplification and
* canonicalization similar to check constraints.
* Run the partition quals through const-simplification similar to
* check constraints. We skip canonicalize_qual, though, because
* partition quals should be in canonical form already; also, since
* the qual is in implicit-AND format, we'd have to explicitly convert
* it to explicit-AND format and back again.
*/
constraints = (List *) eval_const_expressions(root, (Node *) constraints);
/* FIXME this func will be modified at pg11 */
// constraints = (List *) canonicalize_qual((Expr *) constraints, true);
pcqual = (List *) eval_const_expressions(root, (Node *) pcqual);

/* Fix Vars to have the desired varno */
if (rel->relid != 1)
ChangeVarNodes((Node *) constraints, 1, rel->relid, 0);
if (varno != 1)
ChangeVarNodes((Node *) pcqual, 1, varno, 0);
}
#if PG_VERSION_NUM >= 110000
}
#endif

return constraints;
return pcqual;
}

/*
@@ -84,7 +84,7 @@ Datum hypopg_reset_table(PG_FUNCTION_ARGS);
#if PG_VERSION_NUM >= 100000
hypoTable *hypo_find_table(Oid tableid, bool missing_ok);
List *hypo_get_partition_constraints(PlannerInfo *root, RelOptInfo *rel,
hypoTable *parent);
hypoTable *parent, bool force_generation);
List *hypo_get_partition_quals_inh(hypoTable *part, hypoTable *parent);
hypoTable *hypo_table_name_get_entry(const char *name);
bool hypo_table_oid_is_hypothetical(Oid relid);

0 comments on commit 1c87601

Please sign in to comment.