HAWQ-850. Planner supports refineCachedPlan interface.
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/c31209db Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/c31209db Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/c31209db Branch: refs/heads/HAWQ-543 Commit: c31209db7add5fdc252ba4a205eaee6699536e24 Parents: 48a79cc Author: hzhang2 <zhanghuan...@163.com> Authored: Fri Jun 24 09:21:18 2016 +0800 Committer: hzhang2 <zhanghuan...@163.com> Committed: Fri Jun 24 09:21:18 2016 +0800 ---------------------------------------------------------------------- src/backend/optimizer/plan/planner.c | 133 ++++++++++++++++++++++++++++++ src/include/optimizer/planner.h | 5 ++ 2 files changed, 138 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/c31209db/src/backend/optimizer/plan/planner.c ---------------------------------------------------------------------- diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index ecc4ce6..3006d33 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -292,6 +292,139 @@ optimize_query(Query *parse, ParamListInfo boundParams) } #endif +/** + * in PBE, plan will be cached, but splitAllocResult and resource maybe dynamic + * we need to refine cached plan, with new splitAllocResult and resource + * also note that plan need to be regenerated when resource number changed. + */ +PlannedStmt *refineCachedPlan(PlannedStmt * plannedstmt, + Query *parse, + int cursorOptions, + ParamListInfo boundParams) +{ + PlannedStmt *result = plannedstmt; + ResourceNegotiatorResult *ppResult = (ResourceNegotiatorResult *) palloc(sizeof(ResourceNegotiatorResult)); + SplitAllocResult initResult = {NULL, NULL, NIL, 0, NIL, NULL}; + ppResult->saResult = initResult; + ppResult->stmt = plannedstmt; + instr_time starttime, endtime; + + SplitAllocResult *allocResult = NULL; + Query *my_parse = copyObject(parse); + + /* If this is a parallel plan. request resource and allocate split again*/ + if (plannedstmt->planTree->dispatch == DISPATCH_PARALLEL) + { + /* + * Now, we want to allocate resource. + */ + allocResult = calculate_planner_segment_num(my_parse, plannedstmt->resource->life, + plannedstmt->rtable, plannedstmt->intoPolicy, + plannedstmt->nMotionNodes + plannedstmt->nInitPlans + 1, + -1); + + Assert(allocResult); + + ppResult->saResult = *allocResult; + pfree(allocResult); + } else { + if ((ppResult != NULL)) + { + pfree(ppResult); + ppResult = NULL; + } + return plannedstmt; + } + + /* if vseg number changed, we need to regenerate plan. */ + if(plannedstmt->planner_segments != ppResult->saResult.planner_segments) { + gp_segments_for_planner = ppResult->saResult.planner_segments; + int optimizer_segments_saved_value = optimizer_segments; + +#ifdef USE_ORCA + /** + * If the new optimizer is enabled, try that first. If it does not return a plan, + * then fall back to the planner. + * TODO: caragg 11/08/2013: Enable ORCA when running in utility mode (MPP-21841) + */ + if (optimizer && AmIMaster() && (GP_ROLE_UTILITY != Gp_role) && plannedstmt->planTree->dispatch == DISPATCH_PARALLEL) + { + if (gp_log_optimization_time) + { + INSTR_TIME_SET_CURRENT(starttime); + } + START_MEMORY_ACCOUNT(MemoryAccounting_CreateAccount(0, MEMORY_OWNER_TYPE_Optimizer)); + { + if (optimizer_segments == 0) // value not set by user + { + optimizer_segments = gp_segments_for_planner; + } + + result = optimize_query(parse, boundParams); + if (ppResult->stmt && ppResult->stmt->intoPolicy + && result && result->intoPolicy) + { + result->intoPolicy->bucketnum = + ppResult->stmt->intoPolicy->bucketnum; + } + optimizer_segments = optimizer_segments_saved_value; + } + END_MEMORY_ACCOUNT(); + + if (gp_log_optimization_time) + { + INSTR_TIME_SET_CURRENT(endtime); + INSTR_TIME_SUBTRACT(endtime, starttime); + elog(LOG, "Optimizer Time: %.3f ms", INSTR_TIME_GET_MILLISEC(endtime)); + } + } +#endif + + if (!result) + { + if (gp_log_optimization_time) + { + INSTR_TIME_SET_CURRENT(starttime); + } + START_MEMORY_ACCOUNT(MemoryAccounting_CreateAccount(0, MEMORY_OWNER_TYPE_Planner)); + { + if (NULL != planner_hook) + { + result = (*planner_hook) (parse, cursorOptions, boundParams, plannedstmt->resource->life); + } + else + { + result = standard_planner(parse, cursorOptions, boundParams); + } + + if (gp_log_optimization_time) + { + INSTR_TIME_SET_CURRENT(endtime); + INSTR_TIME_SUBTRACT(endtime, starttime); + elog(LOG, "Planner Time: %.3f ms", INSTR_TIME_GET_MILLISEC(endtime)); + } + } + END_MEMORY_ACCOUNT(); + } + } + + /* add resource and split information to it*/ + result->resource = ppResult->saResult.resource; + result->resource_parameters = ppResult->saResult.resource_parameters; + result->scantable_splits = ppResult->saResult.alloc_results; + result->planner_segments = ppResult->saResult.planner_segments; + result->datalocalityInfo = ppResult->saResult.datalocalityInfo; + result->datalocalityTime = ppResult->saResult.datalocalityTime; + + if ((ppResult != NULL)) + { + pfree(ppResult); + ppResult = NULL; + } + + return result; +} + /***************************************************************************** * * Query optimizer entry point http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/c31209db/src/include/optimizer/planner.h ---------------------------------------------------------------------- diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h index cc2eb7d..6b3a22b 100644 --- a/src/include/optimizer/planner.h +++ b/src/include/optimizer/planner.h @@ -36,6 +36,11 @@ extern PlannedStmt *planner(Query *parse, ParamListInfo boundParams, QueryResourceLife resourceLife); +extern PlannedStmt *refineCachedPlan(PlannedStmt * plannedstmt, + Query *parse, + int cursorOptions, + ParamListInfo boundParams); + extern Plan *subquery_planner(PlannerGlobal *glob, Query *parse, PlannerInfo *parent_root,