From bb853aca8e5bb2b1175e608f7eaaaa480a332c2e Mon Sep 17 00:00:00 2001 From: amit Date: Thu, 8 Aug 2019 13:49:29 +0900 Subject: [PATCH v2 1/2] Improve RelOptInfo.partition_qual usage This includes following improvements: 1. Initialize partition_qual with necessary polishing in only one place, that is, in get_relation_info(), instead of having it be duplicated in places where it's used 2. get_relation_constraints() can use partition_qual instead of fetching it from the relcache --- src/backend/optimizer/util/plancat.c | 41 ++++++++++++++---------------------- src/backend/optimizer/util/relnode.c | 2 +- src/backend/partitioning/partprune.c | 32 ++++++---------------------- 3 files changed, 23 insertions(+), 52 deletions(-) diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 98e99481c6..2653a69220 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -115,6 +115,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Relation relation; bool hasindex; List *indexinfos = NIL; + List *partconstr; /* * We need not lock the relation since it was already locked, either by @@ -458,6 +459,17 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); + /* Initialize the partition constraint if any */ + partconstr = RelationGetPartitionQual(relation); + if (partconstr) + { + partconstr = (List *) expression_planner((Expr *) partconstr); + /* Fix Vars to have desired varno. */ + if (rel->relid != 1) + ChangeVarNodes((Node *) partconstr, 1, rel->relid, 0); + rel->partition_qual = partconstr; + } + table_close(relation, NoLock); /* @@ -1262,33 +1274,13 @@ get_relation_constraints(PlannerInfo *root, } } + table_close(relation, NoLock); + /* * Add partitioning constraints, if requested. */ - 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); - } - } - - table_close(relation, NoLock); + if (include_partition) + result = list_concat(result, rel->partition_qual); return result; } @@ -2149,7 +2141,6 @@ 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); } /* diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 37d228ce5d..49e1fc5b74 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -239,7 +239,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent) rel->part_scheme = NULL; rel->nparts = 0; rel->boundinfo = NULL; - rel->partition_qual = NIL; + rel->partition_qual = NIL; /* set in get_relation_info() */ rel->part_rels = NULL; rel->partexprs = NULL; rel->nullable_partexprs = NULL; diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index 2ed1e44c18..d399df6cf5 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -631,19 +631,10 @@ gen_partprune_steps(RelOptInfo *rel, List *clauses, PartClauseTarget target, * partition qual to the clause list in this case only. This may result * in the default partition being eliminated. */ - if (partition_bound_has_default(rel->boundinfo) && - rel->partition_qual != NIL) + if (partition_bound_has_default(rel->boundinfo) && rel->partition_qual) { - List *partqual = rel->partition_qual; - - partqual = (List *) expression_planner((Expr *) partqual); - - /* Fix Vars to have the desired varno */ - if (rel->relid != 1) - ChangeVarNodes((Node *) partqual, 1, rel->relid, 0); - /* Use list_copy to avoid modifying the passed-in List */ - clauses = list_concat(list_copy(clauses), partqual); + clauses = list_concat(list_copy(clauses), rel->partition_qual); } /* Down into the rabbit-hole. */ @@ -1024,22 +1015,11 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, * as contradictory and we're done. This is particularly helpful to * prune the default partition. */ - if (context->rel->partition_qual) + if (predicate_refuted_by(context->rel->partition_qual, + list_make1(clause), false)) { - List *partconstr; - - partconstr = (List *) - expression_planner((Expr *) context->rel->partition_qual); - if (context->rel->relid != 1) - ChangeVarNodes((Node *) partconstr, 1, - context->rel->relid, 0); - if (predicate_refuted_by(partconstr, - list_make1(clause), - false)) - { - context->contradictory = true; - return NIL; - } + context->contradictory = true; + return NIL; } /* -- 2.11.0