CGPOptimizer.cpp 6.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//---------------------------------------------------------------------------
//	Greenplum Database
//	Copyright (C) 2012 Greenplum, Inc.
//
//	@filename:
//		CGPOptimizer.cpp
//
//	@doc:
//		Entry point to GP optimizer
//
//	@test:
//
//
//---------------------------------------------------------------------------

#include "gpopt/CGPOptimizer.h"
#include "gpopt/utils/COptTasks.h"
18 19
#include "gpopt/utils/CMemoryPoolPalloc.h"
#include "gpopt/utils/CMemoryPoolPallocManager.h"
20 21

// the following headers are needed to reference optimizer library initializers
22
#include "naucrates/init.h"
23 24
#include "gpopt/init.h"
#include "gpos/_api.h"
25
#include "gpopt/gpdbwrappers.h"
26
#include "gpos/memory/CMemoryPoolManager.h"
27

28
#include "naucrates/exception.h"
29
#include "utils/guc.h"
30
#include "utils/memutils.h"
31

32 33
extern MemoryContext MessageContext;

34 35 36 37 38 39 40 41 42
//---------------------------------------------------------------------------
//	@function:
//		CGPOptimizer::PlstmtOptimize
//
//	@doc:
//		Optimize given query using GP optimizer
//
//---------------------------------------------------------------------------
PlannedStmt *
J
Jesse Zhang 已提交
43
CGPOptimizer::GPOPTOptimizedPlan(
44
	Query *query,
J
Jesse Zhang 已提交
45 46 47
	bool *
		had_unexpected_failure	// output : set to true if optimizer unexpectedly failed to produce plan
)
48
{
49
	SOptContext gpopt_context;
J
Jesse Zhang 已提交
50
	PlannedStmt *plStmt = NULL;
51 52
	GPOS_TRY
	{
J
Jesse Zhang 已提交
53 54
		plStmt = COptTasks::GPOPTOptimizedPlan(query, &gpopt_context,
											   had_unexpected_failure);
55
		// clean up context
56
		gpopt_context.Free(gpopt_context.epinQuery, gpopt_context.epinPlStmt);
57 58 59
	}
	GPOS_CATCH_EX(ex)
	{
60
		// clone the error message before context free.
J
Jesse Zhang 已提交
61 62
		CHAR *serialized_error_msg =
			gpopt_context.CloneErrorMsg(MessageContext);
63
		// clean up context
64
		gpopt_context.Free(gpopt_context.epinQuery, gpopt_context.epinPlStmt);
65 66 67 68 69 70

		// 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.
J
Jesse Zhang 已提交
71 72
		if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL,
						  gpdxl::ExmiQuery2DXLNotNullViolation))
73
		{
74
			errstart(ERROR, ex.Filename(), ex.Line(), NULL, TEXTDOMAIN);
75
			errfinish(errcode(ERRCODE_NOT_NULL_VIOLATION),
J
Jesse Zhang 已提交
76
					  errmsg("%s", serialized_error_msg));
77 78 79
		}

		else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL, gpdxl::ExmiOptimizerError) ||
J
Jesse Zhang 已提交
80
				 NULL != serialized_error_msg)
81
		{
82 83
			Assert(NULL != serialized_error_msg);
			errstart(ERROR, ex.Filename(), ex.Line(), NULL, TEXTDOMAIN);
84
			errfinish(errcode(ERRCODE_INTERNAL_ERROR),
J
Jesse Zhang 已提交
85
					  errmsg("%s", serialized_error_msg));
86 87 88 89 90
		}
		else if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError))
		{
			PG_RE_THROW();
		}
J
Jesse Zhang 已提交
91 92
		else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL,
							   gpdxl::ExmiNoAvailableMemory))
93
		{
94
			errstart(ERROR, ex.Filename(), ex.Line(), NULL, TEXTDOMAIN);
95
			errfinish(errcode(ERRCODE_INTERNAL_ERROR),
J
Jesse Zhang 已提交
96
					  errmsg("No available memory to allocate string buffer."));
97
		}
J
Jesse Zhang 已提交
98 99
		else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL,
							   gpdxl::ExmiInvalidComparisonTypeCode))
100
		{
101
			errstart(ERROR, ex.Filename(), ex.Line(), NULL, TEXTDOMAIN);
J
Jesse Zhang 已提交
102 103 104 105
			errfinish(
				errcode(ERRCODE_INTERNAL_ERROR),
				errmsg(
					"Invalid comparison type code. Valid values are Eq, NEq, LT, LEq, GT, GEq."));
106 107 108
		}
	}
	GPOS_CATCH_END;
109
	return plStmt;
110 111 112 113 114 115 116 117 118 119 120 121
}


//---------------------------------------------------------------------------
//	@function:
//		CGPOptimizer::SzDXL
//
//	@doc:
//		Serialize planned statement into DXL
//
//---------------------------------------------------------------------------
char *
J
Jesse Zhang 已提交
122
CGPOptimizer::SerializeDXLPlan(Query *query)
123
{
124
	return COptTasks::Optimize(query);
125 126
}

127 128 129 130 131 132 133 134 135
//---------------------------------------------------------------------------
//	@function:
//		InitGPOPT()
//
//	@doc:
//		Initialize GPTOPT and dependent libraries
//
//---------------------------------------------------------------------------
void
J
Jesse Zhang 已提交
136
CGPOptimizer::InitGPOPT()
137
{
138 139 140 141 142 143 144 145 146 147
	if (optimizer_use_gpdb_allocators)
	{
		CMemoryPoolPallocManager::Init();
	}

	struct gpos_init_params params = {gpdb::IsAbortRequested};

	gpos_init(&params);
	gpdxl_init();
	gpopt_init();
148 149 150 151 152 153 154 155 156 157 158
}

//---------------------------------------------------------------------------
//	@function:
//		TerminateGPOPT()
//
//	@doc:
//		Terminate GPOPT and dependent libraries
//
//---------------------------------------------------------------------------
void
J
Jesse Zhang 已提交
159
CGPOptimizer::TerminateGPOPT()
160
{
161 162 163
	gpopt_terminate();
	gpdxl_terminate();
	gpos_terminate();
164
}
165 166 167

//---------------------------------------------------------------------------
//	@function:
168
//		GPOPTOptimizedPlan
169 170 171 172 173
//
//	@doc:
//		Expose GP optimizer API to C files
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
174 175 176
extern "C" {
PlannedStmt *
GPOPTOptimizedPlan(Query *query, bool *had_unexpected_failure)
177
{
178
	return CGPOptimizer::GPOPTOptimizedPlan(query, had_unexpected_failure);
179 180 181 182 183
}
}

//---------------------------------------------------------------------------
//	@function:
184
//		SerializeDXLPlan
185 186 187 188 189
//
//	@doc:
//		Serialize planned statement to DXL
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
190 191 192
extern "C" {
char *
SerializeDXLPlan(Query *query)
193
{
194
	return CGPOptimizer::SerializeDXLPlan(query);
195 196 197
}
}

198 199 200 201 202 203 204 205
//---------------------------------------------------------------------------
//	@function:
//		InitGPOPT()
//
//	@doc:
//		Initialize GPTOPT and dependent libraries
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
206 207 208
extern "C" {
void
InitGPOPT()
209
{
210 211 212 213 214 215 216 217 218 219 220 221
	GPOS_TRY
	{
		return CGPOptimizer::InitGPOPT();
	}
	GPOS_CATCH_EX(ex)
	{
		if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError))
		{
			PG_RE_THROW();
		}
	}
	GPOS_CATCH_END;
222 223 224 225 226 227 228 229 230 231 232
}
}

//---------------------------------------------------------------------------
//	@function:
//		TerminateGPOPT()
//
//	@doc:
//		Terminate GPOPT and dependent libraries
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
233 234 235
extern "C" {
void
TerminateGPOPT()
236
{
237 238 239 240 241 242 243 244 245 246 247 248
	GPOS_TRY
	{
		return CGPOptimizer::TerminateGPOPT();
	}
	GPOS_CATCH_EX(ex)
	{
		if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError))
		{
			PG_RE_THROW();
		}
	}
	GPOS_CATCH_END;
249 250 251
}
}

252
// EOF