greenplumn COptTasks 源码
greenplumn COptTasks 代码
文件路径:/src/backend/gpopt/utils/COptTasks.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2011 EMC Greenplum, Inc.
//
// @filename:
// COptTasks.cpp
//
// @doc:
// Routines to perform optimization related tasks using the gpos framework
//
// @test:
//
//
//---------------------------------------------------------------------------
#include "gpopt/utils/COptTasks.h"
extern "C" {
#include "cdb/cdbvars.h"
#include "utils/fmgroids.h"
#include "utils/guc.h"
}
#include "gpos/_api.h"
#include "gpos/base.h"
#include "gpos/common/CAutoP.h"
#include "gpos/error/CException.h"
#include "gpos/io/COstreamString.h"
#include "gpos/memory/CAutoMemoryPool.h"
#include "gpos/task/CAutoTraceFlag.h"
#include "gpdbcost/CCostModelGPDB.h"
#include "gpopt/base/CAutoOptCtxt.h"
#include "gpopt/config/CConfigParamMapping.h"
#include "gpopt/engine/CCTEConfig.h"
#include "gpopt/engine/CEnumeratorConfig.h"
#include "gpopt/engine/CHint.h"
#include "gpopt/engine/CStatisticsConfig.h"
#include "gpopt/eval/CConstExprEvaluatorDXL.h"
#include "gpopt/exception.h"
#include "gpopt/gpdbwrappers.h"
#include "gpopt/mdcache/CAutoMDAccessor.h"
#include "gpopt/mdcache/CMDCache.h"
#include "gpopt/minidump/CMinidumperUtils.h"
#include "gpopt/optimizer/COptimizer.h"
#include "gpopt/optimizer/COptimizerConfig.h"
#include "gpopt/relcache/CMDProviderRelcache.h"
#include "gpopt/translate/CContextDXLToPlStmt.h"
#include "gpopt/translate/CTranslatorDXLToExpr.h"
#include "gpopt/translate/CTranslatorDXLToPlStmt.h"
#include "gpopt/translate/CTranslatorExprToDXL.h"
#include "gpopt/translate/CTranslatorQueryToDXL.h"
#include "gpopt/translate/CTranslatorRelcacheToDXL.h"
#include "gpopt/translate/CTranslatorUtils.h"
#include "gpopt/utils/CConstExprEvaluatorProxy.h"
#include "gpopt/utils/gpdbdefs.h"
#include "gpopt/xforms/CXformFactory.h"
#include "naucrates/base/CQueryToDXLResult.h"
#include "naucrates/dxl/CDXLUtils.h"
#include "naucrates/dxl/CIdGenerator.h"
#include "naucrates/dxl/operators/CDXLNode.h"
#include "naucrates/dxl/parser/CParseHandlerDXL.h"
#include "naucrates/exception.h"
#include "naucrates/init.h"
#include "naucrates/md/CMDIdCast.h"
#include "naucrates/md/CMDIdRelStats.h"
#include "naucrates/md/CMDIdScCmp.h"
#include "naucrates/md/CSystemId.h"
#include "naucrates/md/IMDId.h"
#include "naucrates/md/IMDRelStats.h"
#include "naucrates/traceflags/traceflags.h"
using namespace gpos;
using namespace gpopt;
using namespace gpdxl;
using namespace gpdbcost;
// size of error buffer
#define GPOPT_ERROR_BUFFER_SIZE 10 * 1024 * 1024
// definition of default AutoMemoryPool
#define AUTO_MEM_POOL(amp) CAutoMemoryPool amp(CAutoMemoryPool::ElcExc)
// default id for the source system
const CSystemId default_sysid(IMDId::EmdidGPDB, GPOS_WSZ_STR_LENGTH("GPDB"));
//---------------------------------------------------------------------------
// @function:
// SOptContext::SOptContext
//
// @doc:
// Ctor
//
//---------------------------------------------------------------------------
SOptContext::SOptContext() = default;
//---------------------------------------------------------------------------
// @function:
// SOptContext::Free
//
// @doc:
// Free all members except those pointed to by either input or
// output
//
//---------------------------------------------------------------------------
void
SOptContext::Free(SOptContext::EPin input, SOptContext::EPin output) const
{
if (nullptr != m_query_dxl && epinQueryDXL != input &&
epinQueryDXL != output)
{
gpdb::GPDBFree(m_query_dxl);
}
if (nullptr != m_query && epinQuery != input && epinQuery != output)
{
gpdb::GPDBFree(m_query);
}
if (nullptr != m_plan_dxl && epinPlanDXL != input && epinPlanDXL != output)
{
gpdb::GPDBFree(m_plan_dxl);
}
if (nullptr != m_plan_stmt && epinPlStmt != input && epinPlStmt != output)
{
gpdb::GPDBFree(m_plan_stmt);
}
if (nullptr != m_error_msg && epinErrorMsg != input &&
epinErrorMsg != output)
{
gpdb::GPDBFree(m_error_msg);
}
}
//---------------------------------------------------------------------------
// @function:
// SOptContext::CloneErrorMsg
//
// @doc:
// Clone m_error_msg to given memory context. Return NULL if there is no
// error message.
//
//---------------------------------------------------------------------------
CHAR *
SOptContext::CloneErrorMsg(MemoryContext context) const
{
if (nullptr == context || nullptr == m_error_msg)
{
return nullptr;
}
return gpdb::MemCtxtStrdup(context, m_error_msg);
}
//---------------------------------------------------------------------------
// @function:
// SOptContext::Cast
//
// @doc:
// Casting function
//
//---------------------------------------------------------------------------
SOptContext *
SOptContext::Cast(void *ptr)
{
GPOS_ASSERT(nullptr != ptr);
return reinterpret_cast<SOptContext *>(ptr);
}
//---------------------------------------------------------------------------
// @function:
// CreateMultiByteCharStringFromWCString
//
// @doc:
// Return regular string from wide-character string
//
//---------------------------------------------------------------------------
CHAR *
COptTasks::CreateMultiByteCharStringFromWCString(const WCHAR *wcstr)
{
GPOS_ASSERT(nullptr != wcstr);
const ULONG input_len = GPOS_WSZ_LENGTH(wcstr);
const ULONG wchar_size = GPOS_SIZEOF(WCHAR);
const ULONG max_len = (input_len + 1) * wchar_size;
CHAR *str = (CHAR *) gpdb::GPDBAlloc(max_len);
gpos::clib::Wcstombs(str, const_cast<WCHAR *>(wcstr), max_len);
str[max_len - 1] = '\0';
return str;
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::Execute
//
// @doc:
// Execute a task using GPOS. TODO extend gpos to provide
// this functionality
//
//---------------------------------------------------------------------------
void
COptTasks::Execute(void *(*func)(void *), void *func_arg)
{
Assert(func);
CHAR *err_buf = (CHAR *) palloc(GPOPT_ERROR_BUFFER_SIZE);
err_buf[0] = '\0';
// initialize DXL support
InitDXL();
bool abort_flag = false;
CAutoMemoryPool amp(CAutoMemoryPool::ElcNone);
gpos_exec_params params;
params.func = func;
params.arg = func_arg;
params.stack_start = ¶ms;
params.error_buffer = err_buf;
params.error_buffer_size = GPOPT_ERROR_BUFFER_SIZE;
params.abort_requested = &abort_flag;
// execute task and send log message to server log
GPOS_TRY
{
(void) gpos_exec(¶ms);
}
GPOS_CATCH_EX(ex)
{
LogExceptionMessageAndDelete(err_buf);
GPOS_RETHROW(ex);
}
GPOS_CATCH_END;
LogExceptionMessageAndDelete(err_buf);
}
void
COptTasks::LogExceptionMessageAndDelete(CHAR *err_buf)
{
if ('\0' != err_buf[0])
{
elog(LOG, "%s",
CreateMultiByteCharStringFromWCString((WCHAR *) err_buf));
}
pfree(err_buf);
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::ConvertToPlanStmtFromDXL
//
// @doc:
// Translate a DXL tree into a planned statement
//
//---------------------------------------------------------------------------
PlannedStmt *
COptTasks::ConvertToPlanStmtFromDXL(
CMemoryPool *mp, CMDAccessor *md_accessor, const Query *orig_query,
const CDXLNode *dxlnode, bool can_set_tag,
DistributionHashOpsKind distribution_hashops)
{
GPOS_ASSERT(nullptr != md_accessor);
GPOS_ASSERT(nullptr != dxlnode);
/*
* Since GPDB 7 (commit 0ae9004), plan node IDs start from 0 in GPDB.
* GPDB 6 and lower had plan node IDs starting from 0.
*/
CIdGenerator plan_id_generator(0 /* ulStartId */);
CIdGenerator motion_id_generator(1 /* ulStartId */);
CIdGenerator param_id_generator(0 /* ulStartId */);
CContextDXLToPlStmt dxl_to_plan_stmt_ctxt(
mp, &plan_id_generator, &motion_id_generator, ¶m_id_generator,
distribution_hashops);
// translate DXL -> PlannedStmt
CTranslatorDXLToPlStmt dxl_to_plan_stmt_translator(
mp, md_accessor, &dxl_to_plan_stmt_ctxt, gpdb::GetGPSegmentCount());
return dxl_to_plan_stmt_translator.GetPlannedStmtFromDXL(
dxlnode, orig_query, can_set_tag);
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::LoadSearchStrategy
//
// @doc:
// Load search strategy from given file
//
//---------------------------------------------------------------------------
CSearchStageArray *
COptTasks::LoadSearchStrategy(CMemoryPool *mp, char *path)
{
CSearchStageArray *search_strategy_arr = nullptr;
CParseHandlerDXL *dxl_parse_handler = nullptr;
GPOS_TRY
{
if (nullptr != path)
{
dxl_parse_handler =
CDXLUtils::GetParseHandlerForDXLFile(mp, path, nullptr);
if (nullptr != dxl_parse_handler)
{
elog(DEBUG2, "\n[OPT]: Using search strategy in (%s)", path);
search_strategy_arr = dxl_parse_handler->GetSearchStageArray();
search_strategy_arr->AddRef();
}
}
}
GPOS_CATCH_EX(ex)
{
if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError))
{
GPOS_RETHROW(ex);
}
elog(DEBUG2, "\n[OPT]: Using default search strategy");
GPOS_RESET_EX;
}
GPOS_CATCH_END;
GPOS_DELETE(dxl_parse_handler);
return search_strategy_arr;
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::CreateOptimizerConfig
//
// @doc:
// Create the optimizer configuration
//
//---------------------------------------------------------------------------
COptimizerConfig *
COptTasks::CreateOptimizerConfig(CMemoryPool *mp, ICostModel *cost_model)
{
// get chosen plan number, cost threshold
ULLONG plan_id = (ULLONG) optimizer_plan_id;
ULLONG num_samples = (ULLONG) optimizer_samples_number;
DOUBLE cost_threshold = (DOUBLE) optimizer_cost_threshold;
DOUBLE damping_factor_filter = (DOUBLE) optimizer_damping_factor_filter;
DOUBLE damping_factor_join = (DOUBLE) optimizer_damping_factor_join;
DOUBLE damping_factor_groupby = (DOUBLE) optimizer_damping_factor_groupby;
ULONG cte_inlining_cutoff = (ULONG) optimizer_cte_inlining_bound;
ULONG join_arity_for_associativity_commutativity =
(ULONG) optimizer_join_arity_for_associativity_commutativity;
ULONG array_expansion_threshold =
(ULONG) optimizer_array_expansion_threshold;
ULONG join_order_threshold = (ULONG) optimizer_join_order_threshold;
ULONG broadcast_threshold = (ULONG) optimizer_penalize_broadcast_threshold;
ULONG push_group_by_below_setop_threshold =
(ULONG) optimizer_push_group_by_below_setop_threshold;
ULONG xform_bind_threshold = (ULONG) optimizer_xform_bind_threshold;
return GPOS_NEW(mp) COptimizerConfig(
GPOS_NEW(mp)
CEnumeratorConfig(mp, plan_id, num_samples, cost_threshold),
GPOS_NEW(mp)
CStatisticsConfig(mp, damping_factor_filter, damping_factor_join,
damping_factor_groupby, MAX_STATS_BUCKETS),
GPOS_NEW(mp) CCTEConfig(cte_inlining_cutoff), cost_model,
GPOS_NEW(mp)
CHint(gpos::int_max /* optimizer_parts_to_force_sort_on_insert */,
join_arity_for_associativity_commutativity,
array_expansion_threshold, join_order_threshold,
broadcast_threshold,
false, /* don't create Assert nodes for constraints, we'll
* enforce them ourselves in the executor */
push_group_by_below_setop_threshold, xform_bind_threshold),
GPOS_NEW(mp) CWindowOids(OID(F_WINDOW_ROW_NUMBER), OID(F_WINDOW_RANK)));
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::SetCostModelParams
//
// @doc:
// Set cost model parameters
//
//---------------------------------------------------------------------------
void
COptTasks::SetCostModelParams(ICostModel *cost_model)
{
GPOS_ASSERT(nullptr != cost_model);
if (optimizer_nestloop_factor > 1.0)
{
// change NLJ cost factor
ICostModelParams::SCostParam *cost_param =
cost_model->GetCostModelParams()->PcpLookup(
CCostModelParamsGPDB::EcpNLJFactor);
CDouble nlj_factor(optimizer_nestloop_factor);
cost_model->GetCostModelParams()->SetParam(
cost_param->Id(), nlj_factor, nlj_factor - 0.5, nlj_factor + 0.5);
}
if (optimizer_sort_factor > 1.0 || optimizer_sort_factor < 1.0)
{
// change sort cost factor
ICostModelParams::SCostParam *cost_param =
cost_model->GetCostModelParams()->PcpLookup(
CCostModelParamsGPDB::EcpSortTupWidthCostUnit);
CDouble sort_factor(optimizer_sort_factor);
cost_model->GetCostModelParams()->SetParam(
cost_param->Id(), cost_param->Get() * optimizer_sort_factor,
cost_param->GetLowerBoundVal() * optimizer_sort_factor,
cost_param->GetUpperBoundVal() * optimizer_sort_factor);
}
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::GetCostModel
//
// @doc:
// Generate an instance of optimizer cost model
//
//---------------------------------------------------------------------------
ICostModel *
COptTasks::GetCostModel(CMemoryPool *mp, ULONG num_segments)
{
ICostModel *cost_model = GPOS_NEW(mp) CCostModelGPDB(mp, num_segments);
SetCostModelParams(cost_model);
return cost_model;
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::OptimizeTask
//
// @doc:
// task that does the optimizes query to physical DXL
//
//---------------------------------------------------------------------------
void *
COptTasks::OptimizeTask(void *ptr)
{
GPOS_ASSERT(nullptr != ptr);
SOptContext *opt_ctxt = SOptContext::Cast(ptr);
GPOS_ASSERT(nullptr != opt_ctxt->m_query);
GPOS_ASSERT(nullptr == opt_ctxt->m_plan_dxl);
GPOS_ASSERT(nullptr == opt_ctxt->m_plan_stmt);
AUTO_MEM_POOL(amp);
CMemoryPool *mp = amp.Pmp();
// Does the metadatacache need to be reset?
//
// On the first call, before the cache has been initialized, we
// don't care about the return value of MDCacheNeedsReset(). But
// we need to call it anyway, to give it a chance to initialize
// the invalidation mechanism.
bool reset_mdcache = gpdb::MDCacheNeedsReset();
// initialize metadata cache, or purge if needed, or change size if requested
if (!CMDCache::FInitialized())
{
CMDCache::Init();
CMDCache::SetCacheQuota(optimizer_mdcache_size * 1024L);
}
else if (reset_mdcache)
{
CMDCache::Reset();
CMDCache::SetCacheQuota(optimizer_mdcache_size * 1024L);
}
else if (CMDCache::ULLGetCacheQuota() !=
(ULLONG) optimizer_mdcache_size * 1024L)
{
CMDCache::SetCacheQuota(optimizer_mdcache_size * 1024L);
}
// load search strategy
CSearchStageArray *search_strategy_arr =
LoadSearchStrategy(mp, optimizer_search_strategy_path);
CBitSet *trace_flags = nullptr;
CBitSet *enabled_trace_flags = nullptr;
CBitSet *disabled_trace_flags = nullptr;
CDXLNode *plan_dxl = nullptr;
IMdIdArray *col_stats = nullptr;
MdidHashSet *rel_stats = nullptr;
GPOS_TRY
{
// set trace flags
trace_flags = CConfigParamMapping::PackConfigParamInBitset(
mp, CXform::ExfSentinel);
SetTraceflags(mp, trace_flags, &enabled_trace_flags,
&disabled_trace_flags);
// set up relcache MD provider
CMDProviderRelcache *relcache_provider =
GPOS_NEW(mp) CMDProviderRelcache(mp);
{
// scope for MD accessor
CMDAccessor mda(mp, CMDCache::Pcache(), default_sysid,
relcache_provider);
ULONG num_segments = gpdb::GetGPSegmentCount();
ULONG num_segments_for_costing = optimizer_segments;
if (0 == num_segments_for_costing)
{
num_segments_for_costing = num_segments;
}
CAutoP<CTranslatorQueryToDXL> query_to_dxl_translator;
query_to_dxl_translator = CTranslatorQueryToDXL::QueryToDXLInstance(
mp, &mda, (Query *) opt_ctxt->m_query);
ICostModel *cost_model = GetCostModel(mp, num_segments_for_costing);
COptimizerConfig *optimizer_config =
CreateOptimizerConfig(mp, cost_model);
CConstExprEvaluatorProxy expr_eval_proxy(mp, &mda);
IConstExprEvaluator *expr_evaluator =
GPOS_NEW(mp) CConstExprEvaluatorDXL(mp, &mda, &expr_eval_proxy);
CDXLNode *query_dxl =
query_to_dxl_translator->TranslateQueryToDXL();
CDXLNodeArray *query_output_dxlnode_array =
query_to_dxl_translator->GetQueryOutputCols();
CDXLNodeArray *cte_dxlnode_array =
query_to_dxl_translator->GetCTEs();
GPOS_ASSERT(nullptr != query_output_dxlnode_array);
BOOL is_master_only =
!optimizer_enable_motions ||
(!optimizer_enable_motions_masteronly_queries &&
!query_to_dxl_translator->HasDistributedTables());
// See NoteDistributionPolicyOpclasses() in src/backend/gpopt/translate/CTranslatorQueryToDXL.cpp
BOOL use_legacy_opfamilies =
(query_to_dxl_translator->GetDistributionHashOpsKind() ==
DistrUseLegacyHashOps);
CAutoTraceFlag atf1(EopttraceDisableMotions, is_master_only);
CAutoTraceFlag atf2(EopttraceUseLegacyOpfamilies,
use_legacy_opfamilies);
plan_dxl = COptimizer::PdxlnOptimize(
mp, &mda, query_dxl, query_output_dxlnode_array,
cte_dxlnode_array, expr_evaluator, num_segments, gp_session_id,
gp_command_count, search_strategy_arr, optimizer_config);
if (opt_ctxt->m_should_serialize_plan_dxl)
{
// serialize DXL to xml
CWStringDynamic plan_str(mp);
COstreamString oss(&plan_str);
CDXLUtils::SerializePlan(
mp, oss, plan_dxl,
optimizer_config->GetEnumeratorCfg()->GetPlanId(),
optimizer_config->GetEnumeratorCfg()->GetPlanSpaceSize(),
true /*serialize_header_footer*/, true /*indentation*/);
opt_ctxt->m_plan_dxl =
CreateMultiByteCharStringFromWCString(plan_str.GetBuffer());
}
// translate DXL->PlStmt only when needed
if (opt_ctxt->m_should_generate_plan_stmt)
{
// always use opt_ctxt->m_query->can_set_tag as the query_to_dxl_translator->Pquery() is a mutated Query object
// that may not have the correct can_set_tag
opt_ctxt->m_plan_stmt =
(PlannedStmt *) gpdb::CopyObject(ConvertToPlanStmtFromDXL(
mp, &mda, opt_ctxt->m_query, plan_dxl,
opt_ctxt->m_query->canSetTag,
query_to_dxl_translator->GetDistributionHashOpsKind()));
}
CStatisticsConfig *stats_conf = optimizer_config->GetStatsConf();
col_stats = GPOS_NEW(mp) IMdIdArray(mp);
stats_conf->CollectMissingStatsColumns(col_stats);
rel_stats = GPOS_NEW(mp) MdidHashSet(mp);
PrintMissingStatsWarning(mp, &mda, col_stats, rel_stats);
rel_stats->Release();
col_stats->Release();
expr_evaluator->Release();
query_dxl->Release();
optimizer_config->Release();
plan_dxl->Release();
}
}
GPOS_CATCH_EX(ex)
{
ResetTraceflags(enabled_trace_flags, disabled_trace_flags);
CRefCount::SafeRelease(rel_stats);
CRefCount::SafeRelease(col_stats);
CRefCount::SafeRelease(enabled_trace_flags);
CRefCount::SafeRelease(disabled_trace_flags);
CRefCount::SafeRelease(trace_flags);
CRefCount::SafeRelease(plan_dxl);
CMDCache::Shutdown();
IErrorContext *errctxt = CTask::Self()->GetErrCtxt();
opt_ctxt->m_should_error_out = ShouldErrorOut(ex);
opt_ctxt->m_is_unexpected_failure = IsLoggableFailure(ex);
opt_ctxt->m_error_msg =
CreateMultiByteCharStringFromWCString(errctxt->GetErrorMsg());
GPOS_RETHROW(ex);
}
GPOS_CATCH_END;
// cleanup
ResetTraceflags(enabled_trace_flags, disabled_trace_flags);
CRefCount::SafeRelease(enabled_trace_flags);
CRefCount::SafeRelease(disabled_trace_flags);
CRefCount::SafeRelease(trace_flags);
if (!optimizer_metadata_caching)
{
CMDCache::Shutdown();
}
return nullptr;
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::PrintMissingStatsWarning
//
// @doc:
// Print warning messages for columns with missing statistics
//
//---------------------------------------------------------------------------
void
COptTasks::PrintMissingStatsWarning(CMemoryPool *mp, CMDAccessor *md_accessor,
IMdIdArray *col_stats,
MdidHashSet *rel_stats)
{
GPOS_ASSERT(nullptr != md_accessor);
GPOS_ASSERT(nullptr != col_stats);
GPOS_ASSERT(nullptr != rel_stats);
CWStringDynamic wcstr(mp);
COstreamString oss(&wcstr);
const ULONG num_missing_col_stats = col_stats->Size();
for (ULONG ul = 0; ul < num_missing_col_stats; ul++)
{
IMDId *mdid = (*col_stats)[ul];
CMDIdColStats *mdid_col_stats = CMDIdColStats::CastMdid(mdid);
IMDId *rel_mdid = mdid_col_stats->GetRelMdId();
const ULONG pos = mdid_col_stats->Position();
const IMDRelation *rel = md_accessor->RetrieveRel(rel_mdid);
if (IMDRelation::ErelstorageExternal != rel->RetrieveRelStorageType())
{
if (!rel_stats->Contains(rel_mdid))
{
if (0 != ul)
{
oss << ", ";
}
rel_mdid->AddRef();
rel_stats->Insert(rel_mdid);
oss << rel->Mdname().GetMDName()->GetBuffer();
}
CMDName mdname = rel->GetMdCol(pos)->Mdname();
char msgbuf[NAMEDATALEN * 2 + 100];
snprintf(msgbuf, sizeof(msgbuf),
"Missing statistics for column: %s.%s",
CreateMultiByteCharStringFromWCString(
rel->Mdname().GetMDName()->GetBuffer()),
CreateMultiByteCharStringFromWCString(
mdname.GetMDName()->GetBuffer()));
GpdbEreport(ERRCODE_SUCCESSFUL_COMPLETION, LOG, msgbuf, nullptr);
}
}
if (0 < rel_stats->Size())
{
int length = NAMEDATALEN * rel_stats->Size() + 200;
char msgbuf[length];
snprintf(
msgbuf, sizeof(msgbuf),
"One or more columns in the following table(s) do not have statistics: %s",
CreateMultiByteCharStringFromWCString(wcstr.GetBuffer()));
GpdbEreport(
ERRCODE_SUCCESSFUL_COMPLETION, NOTICE, msgbuf,
"For non-partitioned tables, run analyze <table_name>(<column_list>)."
" For partitioned tables, run analyze rootpartition <table_name>(<column_list>)."
" See log for columns missing statistics.");
}
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::Optimize
//
// @doc:
// optimizes a query to physical DXL
//
//---------------------------------------------------------------------------
char *
COptTasks::Optimize(Query *query)
{
Assert(query);
SOptContext gpopt_context;
gpopt_context.m_query = query;
gpopt_context.m_should_serialize_plan_dxl = true;
Execute(&OptimizeTask, &gpopt_context);
// clean up context
gpopt_context.Free(gpopt_context.epinQuery, gpopt_context.epinPlanDXL);
return gpopt_context.m_plan_dxl;
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::GPOPTOptimizedPlan
//
// @doc:
// optimizes a query to plannedstmt
//
//---------------------------------------------------------------------------
PlannedStmt *
COptTasks::GPOPTOptimizedPlan(Query *query, SOptContext *gpopt_context)
{
Assert(query);
Assert(gpopt_context);
gpopt_context->m_query = query;
gpopt_context->m_should_generate_plan_stmt = true;
Execute(&OptimizeTask, gpopt_context);
return gpopt_context->m_plan_stmt;
}
//---------------------------------------------------------------------------
// @function:
// COptTasks::SetXform
//
// @doc:
// Enable/Disable a given xform
//
//---------------------------------------------------------------------------
bool
COptTasks::SetXform(char *xform_str, bool should_disable)
{
CXform *xform = CXformFactory::Pxff()->Pxf(xform_str);
if (nullptr != xform)
{
optimizer_xforms[xform->Exfid()] = should_disable;
return true;
}
return false;
}
// EOF
相关信息
相关文章
greenplumn CConstExprEvaluatorProxy 源码
greenplumn CMemoryPoolPalloc 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦