greenplumn CGPOptimizer 源码
greenplumn CGPOptimizer 代码
文件路径:/src/backend/gpopt/CGPOptimizer.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2012 Greenplum, Inc.
//
// @filename:
// CGPOptimizer.cpp
//
// @doc:
// Entry point to GP optimizer
//
// @test:
//
//
//---------------------------------------------------------------------------
#include "gpopt/CGPOptimizer.h"
#include "gpopt/utils/CMemoryPoolPalloc.h"
#include "gpopt/utils/CMemoryPoolPallocManager.h"
#include "gpopt/utils/COptTasks.h"
// the following headers are needed to reference optimizer library initializers
#include "gpos/_api.h"
#include "gpos/memory/CMemoryPoolManager.h"
#include "gpopt/gpdbwrappers.h"
#include "gpopt/init.h"
#include "naucrates/exception.h"
#include "naucrates/init.h"
#include "utils/guc.h"
#include "utils/memutils.h"
extern MemoryContext MessageContext;
//---------------------------------------------------------------------------
// @function:
// CGPOptimizer::PlstmtOptimize
//
// @doc:
// Optimize given query using GP optimizer
//
//---------------------------------------------------------------------------
PlannedStmt *
CGPOptimizer::GPOPTOptimizedPlan(
Query *query,
bool *
had_unexpected_failure // output : set to true if optimizer unexpectedly failed to produce plan
)
{
SOptContext gpopt_context;
PlannedStmt *plStmt = nullptr;
*had_unexpected_failure = false;
GPOS_TRY
{
plStmt = COptTasks::GPOPTOptimizedPlan(query, &gpopt_context);
// clean up context
gpopt_context.Free(gpopt_context.epinQuery, gpopt_context.epinPlStmt);
}
GPOS_CATCH_EX(ex)
{
// clone the error message before context free.
CHAR *serialized_error_msg =
gpopt_context.CloneErrorMsg(MessageContext);
// clean up context
gpopt_context.Free(gpopt_context.epinQuery, gpopt_context.epinPlStmt);
// Special handler for a few common user-facing errors. In particular,
// we want to use the correct error code for these, in case an application
// tries to do something smart with them. Also, ERRCODE_INTERNAL_ERROR
// is handled specially in elog.c, and we don't want that for "normal"
// application errors.
if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL,
gpdxl::ExmiQuery2DXLNotNullViolation))
{
if (errstart(ERROR, TEXTDOMAIN))
{
errcode(ERRCODE_NOT_NULL_VIOLATION);
errmsg("%s", serialized_error_msg);
errfinish(ex.Filename(), ex.Line(), nullptr);
}
}
else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL, gpdxl::ExmiOptimizerError) ||
gpopt_context.m_should_error_out)
{
Assert(nullptr != serialized_error_msg);
if (errstart(ERROR, TEXTDOMAIN))
{
errcode(ERRCODE_INTERNAL_ERROR);
errmsg("%s", serialized_error_msg);
errfinish(ex.Filename(), ex.Line(), nullptr);
}
}
else if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError))
{
PG_RE_THROW();
}
else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL,
gpdxl::ExmiNoAvailableMemory))
{
if (errstart(ERROR, TEXTDOMAIN))
{
errcode(ERRCODE_INTERNAL_ERROR);
errmsg("no available memory to allocate string buffer");
errfinish(ex.Filename(), ex.Line(), nullptr);
}
}
else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL,
gpdxl::ExmiInvalidComparisonTypeCode))
{
if (errstart(ERROR, TEXTDOMAIN))
{
errcode(ERRCODE_INTERNAL_ERROR);
errmsg(
"invalid comparison type code. Valid values are Eq, NEq, LT, LEq, GT, GEq.");
errfinish(ex.Filename(), ex.Line(), nullptr);
}
}
// Failed to produce a plan, but it wasn't an error that should
// be propagated to the user. Log the failure if needed, and
// return without a plan. The caller should fall back to the
// Postgres planner.
if (optimizer_trace_fallback)
{
if (errstart(INFO, TEXTDOMAIN))
{
errcode(ERRCODE_FEATURE_NOT_SUPPORTED);
errmsg(
"GPORCA failed to produce a plan, falling back to planner");
if (serialized_error_msg)
{
errdetail("%s", serialized_error_msg);
}
errfinish(ex.Filename(), ex.Line(), nullptr);
}
}
*had_unexpected_failure = gpopt_context.m_is_unexpected_failure;
if (serialized_error_msg)
{
pfree(serialized_error_msg);
}
}
GPOS_CATCH_END;
return plStmt;
}
//---------------------------------------------------------------------------
// @function:
// CGPOptimizer::SerializeDXLPlan
//
// @doc:
// Serialize planned statement into DXL
//
//---------------------------------------------------------------------------
char *
CGPOptimizer::SerializeDXLPlan(Query *query)
{
GPOS_TRY;
{
return COptTasks::Optimize(query);
}
GPOS_CATCH_EX(ex);
{
if (errstart(ERROR, TEXTDOMAIN))
{
errcode(ERRCODE_INTERNAL_ERROR);
errmsg("optimizer failed to produce plan");
errfinish(ex.Filename(), ex.Line(), nullptr);
}
}
GPOS_CATCH_END;
return nullptr;
}
//---------------------------------------------------------------------------
// @function:
// InitGPOPT()
//
// @doc:
// Initialize GPTOPT and dependent libraries
//
//---------------------------------------------------------------------------
void
CGPOptimizer::InitGPOPT()
{
if (optimizer_use_gpdb_allocators)
{
CMemoryPoolPallocManager::Init();
}
struct gpos_init_params params = {gpdb::IsAbortRequested};
gpos_init(¶ms);
gpdxl_init();
gpopt_init();
}
//---------------------------------------------------------------------------
// @function:
// TerminateGPOPT()
//
// @doc:
// Terminate GPOPT and dependent libraries
//
//---------------------------------------------------------------------------
void
CGPOptimizer::TerminateGPOPT()
{
gpopt_terminate();
gpdxl_terminate();
gpos_terminate();
}
//---------------------------------------------------------------------------
// @function:
// GPOPTOptimizedPlan
//
// @doc:
// Expose GP optimizer API to C files
//
//---------------------------------------------------------------------------
extern "C" {
PlannedStmt *
GPOPTOptimizedPlan(Query *query, bool *had_unexpected_failure)
{
return CGPOptimizer::GPOPTOptimizedPlan(query, had_unexpected_failure);
}
}
//---------------------------------------------------------------------------
// @function:
// SerializeDXLPlan
//
// @doc:
// Serialize planned statement to DXL
//
//---------------------------------------------------------------------------
extern "C" {
char *
SerializeDXLPlan(Query *query)
{
return CGPOptimizer::SerializeDXLPlan(query);
}
}
//---------------------------------------------------------------------------
// @function:
// InitGPOPT()
//
// @doc:
// Initialize GPTOPT and dependent libraries
//
//---------------------------------------------------------------------------
extern "C" {
void
InitGPOPT()
{
GPOS_TRY
{
return CGPOptimizer::InitGPOPT();
}
GPOS_CATCH_EX(ex)
{
if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError))
{
PG_RE_THROW();
}
}
GPOS_CATCH_END;
}
}
//---------------------------------------------------------------------------
// @function:
// TerminateGPOPT()
//
// @doc:
// Terminate GPOPT and dependent libraries
//
//---------------------------------------------------------------------------
extern "C" {
void
TerminateGPOPT()
{
GPOS_TRY
{
return CGPOptimizer::TerminateGPOPT();
}
GPOS_CATCH_EX(ex)
{
if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError))
{
PG_RE_THROW();
}
}
GPOS_CATCH_END;
}
}
// EOF
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦