1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Don't constraint-exclude partitioned tables as much

We only need to invoke constraint exclusion on partitioned tables when
they are a partition, and they themselves contain a default partition;
it's not necessary otherwise, and it's expensive, so avoid it.  Also, we
were trying once for each clause separately, but we can do it for all
the clauses at once.

While at it, centralize setting of RelOptInfo->partition_qual instead of
computing it in slightly different ways in different places.

Per complaints from Simon Riggs about 4e85642d935e; reviewed by Yuzuko
Hosoya, Kyotaro Horiguchi.

Author: Amit Langote.  I (Álvaro) again mangled the patch somewhat.
Discussion: https://postgr.es/m/CANP8+j+tMCY=nEcQeqQam85=uopLBtX-2vHiLD2bbp7iQQUKpA@mail.gmail.com
This commit is contained in:
Alvaro Herrera
2019-08-13 10:26:04 -04:00
parent 416c75cf38
commit 815ef2f568
2 changed files with 65 additions and 65 deletions

View File

@@ -78,6 +78,9 @@ static void set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel,
static PartitionScheme find_partition_scheme(PlannerInfo *root, Relation rel);
static void set_baserel_partition_key_exprs(Relation relation,
RelOptInfo *rel);
static void set_baserel_partition_constraint(Relation relation,
RelOptInfo *rel);
/*
* get_relation_info -
@@ -1267,25 +1270,9 @@ get_relation_constraints(PlannerInfo *root,
*/
if (include_partition && relation->rd_rel->relispartition)
{
List *pcqual = RelationGetPartitionQual(relation);
if (pcqual)
{
/*
* 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.
*/
pcqual = (List *) eval_const_expressions(root, (Node *) pcqual);
/* Fix Vars to have the desired varno */
if (varno != 1)
ChangeVarNodes((Node *) pcqual, 1, varno, 0);
result = list_concat(result, pcqual);
}
/* make sure rel->partition_qual is set */
set_baserel_partition_constraint(relation, rel);
result = list_concat(result, rel->partition_qual);
}
table_close(relation, NoLock);
@@ -2149,7 +2136,7 @@ set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel,
rel->boundinfo = partdesc->boundinfo;
rel->nparts = partdesc->nparts;
set_baserel_partition_key_exprs(relation, rel);
rel->partition_qual = RelationGetPartitionQual(relation);
set_baserel_partition_constraint(relation, rel);
}
/*
@@ -2324,3 +2311,35 @@ set_baserel_partition_key_exprs(Relation relation,
*/
rel->nullable_partexprs = (List **) palloc0(sizeof(List *) * partnatts);
}
/*
* set_baserel_partition_constraint
*
* Builds the partition constraint for the given base relation and sets it
* in the given RelOptInfo. All Var nodes are restamped with the relid of the
* given relation.
*/
static void
set_baserel_partition_constraint(Relation relation, RelOptInfo *rel)
{
List *partconstr;
if (rel->partition_qual) /* already done */
return;
/*
* 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.
*/
partconstr = RelationGetPartitionQual(relation);
if (partconstr)
{
partconstr = (List *) expression_planner((Expr *) partconstr);
if (rel->relid != 1)
ChangeVarNodes((Node *) partconstr, 1, rel->relid, 0);
rel->partition_qual = partconstr;
}
}