COptTasks.cpp 49.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
//---------------------------------------------------------------------------
//	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/gpdbdefs.h"
#include "gpopt/utils/CConstExprEvaluatorProxy.h"
#include "gpopt/utils/COptTasks.h"
#include "gpopt/relcache/CMDProviderRelcache.h"
#include "gpopt/config/CConfigParamMapping.h"
#include "gpopt/translate/CTranslatorDXLToExpr.h"
#include "gpopt/translate/CTranslatorExprToDXL.h"
#include "gpopt/translate/CTranslatorUtils.h"
#include "gpopt/translate/CTranslatorQueryToDXL.h"
#include "gpopt/translate/CTranslatorDXLToPlStmt.h"
#include "gpopt/translate/CContextDXLToPlStmt.h"
#include "gpopt/translate/CTranslatorRelcacheToDXL.h"
#include "gpopt/eval/CConstExprEvaluatorDXL.h"
29
#include "gpopt/engine/CHint.h"
30 31 32

#include "cdb/cdbvars.h"
#include "utils/guc.h"
33
#include "utils/fmgroids.h"
34 35

#include "gpos/base.h"
36
#include "gpos/error/CException.h"
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
#undef setstate

#include "gpos/_api.h"
#include "gpos/common/CAutoP.h"
#include "gpos/io/COstreamFile.h"
#include "gpos/io/COstreamString.h"
#include "gpos/memory/CAutoMemoryPool.h"
#include "gpos/task/CAutoTraceFlag.h"
#include "gpos/common/CAutoP.h"

#include "gpopt/translate/CTranslatorDXLToExpr.h"
#include "gpopt/translate/CTranslatorExprToDXL.h"

#include "gpopt/base/CAutoOptCtxt.h"
#include "gpopt/engine/CEnumeratorConfig.h"
#include "gpopt/engine/CStatisticsConfig.h"
#include "gpopt/engine/CCTEConfig.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/xforms/CXformFactory.h"
#include "gpopt/exception.h"

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
#include "naucrates/init.h"
#include "naucrates/traceflags/traceflags.h"

#include "naucrates/base/CQueryToDXLResult.h"

#include "naucrates/md/IMDId.h"
#include "naucrates/md/CMDIdRelStats.h"

#include "naucrates/md/CSystemId.h"
#include "naucrates/md/IMDRelStats.h"
#include "naucrates/md/CMDIdCast.h"
#include "naucrates/md/CMDIdScCmp.h"

#include "naucrates/dxl/operators/CDXLNode.h"
#include "naucrates/dxl/parser/CParseHandlerDXL.h"
#include "naucrates/dxl/CDXLUtils.h"
#include "naucrates/dxl/CIdGenerator.h"
#include "naucrates/exception.h"

#include "gpdbcost/CCostModelGPDB.h"
#include "gpdbcost/CCostModelGPDBLegacy.h"
83 84 85 86 87 88 89 90 91 92 93 94 95


#include "gpopt/gpdbwrappers.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
96
#define AUTO_MEM_POOL(amp) CAutoMemoryPool amp(CAutoMemoryPool::ElcExc)
97

98 99 100
// OID for Window RANK function
#define F_WINDOW_RANK_OID 7001

101
// default id for the source system
102
const CSystemId default_sysid(IMDId::EmdidGPDB, GPOS_WSZ_STR_LENGTH("GPDB"));
103 104 105 106


//---------------------------------------------------------------------------
//	@function:
107
//		SOptContext::SOptContext
108 109 110 111 112
//
//	@doc:
//		Ctor
//
//---------------------------------------------------------------------------
113
SOptContext::SOptContext()
J
Jesse Zhang 已提交
114 115 116 117 118 119 120 121 122 123
	: m_query_dxl(NULL),
	  m_query(NULL),
	  m_plan_dxl(NULL),
	  m_plan_stmt(NULL),
	  m_should_generate_plan_stmt(false),
	  m_should_serialize_plan_dxl(false),
	  m_is_unexpected_failure(false),
	  m_error_msg(NULL)
{
}
124

125 126
//---------------------------------------------------------------------------
//	@function:
127
//		SOptContext::HandleError
128 129
//
//	@doc:
H
Heikki Linnakangas 已提交
130 131
//		If there is an error, throw GPOS_EXCEPTION to abort plan generation.
//		Calling elog::ERROR would result in longjump and hence a memory leak.
132 133
//---------------------------------------------------------------------------
void
J
Jesse Zhang 已提交
134
SOptContext::HandleError(BOOL *has_unexpected_failure)
135
{
136 137
	*has_unexpected_failure = m_is_unexpected_failure;
	if (NULL != m_error_msg)
138
	{
139
		GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiOptimizerError);
140 141 142
	}
}

143 144 145

//---------------------------------------------------------------------------
//	@function:
146
//		SOptContext::Free
147 148
//
//	@doc:
149 150
//		Free all members except those pointed to by either input or
//		output
151 152 153
//
//---------------------------------------------------------------------------
void
J
Jesse Zhang 已提交
154
SOptContext::Free(SOptContext::EPin input, SOptContext::EPin output)
155
{
156
	if (NULL != m_query_dxl && epinQueryDXL != input && epinQueryDXL != output)
157
	{
158
		gpdb::GPDBFree(m_query_dxl);
159
	}
J
Jesse Zhang 已提交
160

161
	if (NULL != m_query && epinQuery != input && epinQuery != output)
162
	{
163
		gpdb::GPDBFree(m_query);
164
	}
J
Jesse Zhang 已提交
165

166
	if (NULL != m_plan_dxl && epinPlanDXL != input && epinPlanDXL != output)
167
	{
168
		gpdb::GPDBFree(m_plan_dxl);
169
	}
J
Jesse Zhang 已提交
170

171
	if (NULL != m_plan_stmt && epinPlStmt != input && epinPlStmt != output)
172
	{
173
		gpdb::GPDBFree(m_plan_stmt);
174
	}
J
Jesse Zhang 已提交
175

176
	if (NULL != m_error_msg && epinErrorMsg != input && epinErrorMsg != output)
177
	{
178
		gpdb::GPDBFree(m_error_msg);
179 180 181
	}
}

182 183 184 185 186
//---------------------------------------------------------------------------
//	@function:
//		SOptContext::CloneErrorMsg
//
//	@doc:
187
//		Clone m_error_msg to given memory context. Return NULL if there is no
188 189 190
//		error message.
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
191 192
CHAR *
SOptContext::CloneErrorMsg(MemoryContext context)
193
{
J
Jesse Zhang 已提交
194
	if (NULL == context || NULL == m_error_msg)
195 196 197
	{
		return NULL;
	}
198
	return gpdb::MemCtxtStrdup(context, m_error_msg);
199 200
}

201 202 203

//---------------------------------------------------------------------------
//	@function:
204
//		SOptContext::Cast
205 206 207 208 209
//
//	@doc:
//		Casting function
//
//---------------------------------------------------------------------------
210
SOptContext *
J
Jesse Zhang 已提交
211
SOptContext::Cast(void *ptr)
212
{
213
	GPOS_ASSERT(NULL != ptr);
214

J
Jesse Zhang 已提交
215
	return reinterpret_cast<SOptContext *>(ptr);
216 217 218 219 220 221 222 223 224 225 226
}


//---------------------------------------------------------------------------
//	@function:
//		COptTasks::SContextRelcacheToDXL::SContextRelcacheToDXL
//
//	@doc:
//		Ctor
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
227 228 229 230
COptTasks::SContextRelcacheToDXL::SContextRelcacheToDXL(List *oid_list,
														ULONG cmp_type,
														const char *filename)
	: m_oid_list(oid_list), m_cmp_type(cmp_type), m_filename(filename)
231
{
232
	GPOS_ASSERT(NULL != oid_list);
233 234 235 236
}

//---------------------------------------------------------------------------
//	@function:
237
//		COptTasks::SContextRelcacheToDXL::RelcacheConvert
238 239 240 241 242 243
//
//	@doc:
//		Casting function
//
//---------------------------------------------------------------------------
COptTasks::SContextRelcacheToDXL *
J
Jesse Zhang 已提交
244
COptTasks::SContextRelcacheToDXL::RelcacheConvert(void *ptr)
245
{
246
	GPOS_ASSERT(NULL != ptr);
247

J
Jesse Zhang 已提交
248
	return reinterpret_cast<SContextRelcacheToDXL *>(ptr);
249 250 251 252 253 254 255 256 257 258 259 260
}


//---------------------------------------------------------------------------
//	@function:
//		COptTasks::SEvalExprContext::PevalctxtConvert
//
//	@doc:
//		Casting function
//
//---------------------------------------------------------------------------
COptTasks::SEvalExprContext *
J
Jesse Zhang 已提交
261
COptTasks::SEvalExprContext::PevalctxtConvert(void *ptr)
262
{
263
	GPOS_ASSERT(NULL != ptr);
264

J
Jesse Zhang 已提交
265
	return reinterpret_cast<SEvalExprContext *>(ptr);
266 267 268 269 270 271 272 273 274 275 276 277
}


//---------------------------------------------------------------------------
//	@function:
//		COptTasks::SOptimizeMinidumpContext::PexecmdpConvert
//
//	@doc:
//		Casting function
//
//---------------------------------------------------------------------------
COptTasks::SOptimizeMinidumpContext *
J
Jesse Zhang 已提交
278
COptTasks::SOptimizeMinidumpContext::Cast(void *ptr)
279
{
280
	GPOS_ASSERT(NULL != ptr);
281

J
Jesse Zhang 已提交
282
	return reinterpret_cast<SOptimizeMinidumpContext *>(ptr);
283 284 285 286 287 288 289 290 291 292 293
}

//---------------------------------------------------------------------------
//	@function:
//		SzAllocate
//
//	@doc:
//		Allocate string buffer with protection against OOM
//
//---------------------------------------------------------------------------
CHAR *
J
Jesse Zhang 已提交
294
COptTasks::SzAllocate(CMemoryPool *pmp, ULONG ulSize)
295 296 297 298 299 300 301
{
	CHAR *sz = NULL;
	GPOS_TRY
	{
		// allocation of string buffer may happen outside gpos_exec() function,
		// we must guard against system OOM here
#ifdef FAULT_INJECTOR
302
		gpdb::InjectFaultInOptTasks(OptTaskAllocateStringBuffer);
J
Jesse Zhang 已提交
303
#endif	// FAULT_INJECTOR
304 305 306 307 308 309 310

		if (NULL == pmp)
		{
			sz = (CHAR *) gpdb::GPDBAlloc(ulSize);
		}
		else
		{
311
			sz = GPOS_NEW_ARRAY(pmp, CHAR, ulSize);
312 313 314 315
		}
	}
	GPOS_CATCH_EX(ex)
	{
316
		GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiNoAvailableMemory);
317 318 319 320 321 322 323 324 325
	}
	GPOS_CATCH_END;

	return sz;
}


//---------------------------------------------------------------------------
//	@function:
326
//		CreateMultiByteCharStringFromWCString
327 328 329 330 331 332
//
//	@doc:
//		Return regular string from wide-character string
//
//---------------------------------------------------------------------------
CHAR *
J
Jesse Zhang 已提交
333
COptTasks::CreateMultiByteCharStringFromWCString(const WCHAR *wcstr)
334
{
335
	GPOS_ASSERT(NULL != wcstr);
336

337 338 339
	const ULONG input_len = GPOS_WSZ_LENGTH(wcstr);
	const ULONG wchar_size = GPOS_SIZEOF(WCHAR);
	const ULONG max_len = (input_len + 1) * wchar_size;
340

341
	CHAR *str = SzAllocate(NULL, max_len);
342

343 344
	gpos::clib::Wcstombs(str, const_cast<WCHAR *>(wcstr), max_len);
	str[max_len - 1] = '\0';
345

346
	return str;
347 348 349 350
}

//---------------------------------------------------------------------------
//	@function:
351
//		COptTasks::ConvertToDXLFromMDCast
352 353 354 355 356
//
//	@doc:
//		Task that dumps the relcache info for a cast object into DXL
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
357 358
void *
COptTasks::ConvertToDXLFromMDCast(void *ptr)
359
{
360
	GPOS_ASSERT(NULL != ptr);
361

J
Jesse Zhang 已提交
362 363
	SContextRelcacheToDXL *relcache_ctxt =
		SContextRelcacheToDXL::RelcacheConvert(ptr);
364
	GPOS_ASSERT(NULL != relcache_ctxt);
365

366 367 368
	GPOS_ASSERT(2 == gpdb::ListLength(relcache_ctxt->m_oid_list));
	Oid src_oid = gpdb::ListNthOid(relcache_ctxt->m_oid_list, 0);
	Oid dest_oid = gpdb::ListNthOid(relcache_ctxt->m_oid_list, 1);
369 370

	CAutoMemoryPool amp(CAutoMemoryPool::ElcExc);
371
	CMemoryPool *mp = amp.Pmp();
372

J
Jesse Zhang 已提交
373 374
	IMDCacheObjectArray *mdcache_obj_array =
		GPOS_NEW(mp) IMDCacheObjectArray(mp);
375

J
Jesse Zhang 已提交
376 377
	IMDId *cast = GPOS_NEW(mp) CMDIdCast(GPOS_NEW(mp) CMDIdGPDB(src_oid),
										 GPOS_NEW(mp) CMDIdGPDB(dest_oid));
378 379

	// relcache MD provider
J
Jesse Zhang 已提交
380 381 382
	CMDProviderRelcache *relcache_provider =
		GPOS_NEW(mp) CMDProviderRelcache(mp);

383
	{
384
		CAutoMDAccessor md_accessor(mp, relcache_provider, default_sysid);
J
Jesse Zhang 已提交
385 386 387

		IMDCacheObject *md_obj = CTranslatorRelcacheToDXL::RetrieveObject(
			mp, md_accessor.Pmda(), cast);
388
		GPOS_ASSERT(NULL != md_obj);
J
Jesse Zhang 已提交
389

390 391
		mdcache_obj_array->Append(md_obj);
		cast->Release();
J
Jesse Zhang 已提交
392

393 394
		CWStringDynamic wcstr(mp);
		COstreamString oss(&wcstr);
395

J
Jesse Zhang 已提交
396 397 398
		CDXLUtils::SerializeMetadata(mp, mdcache_obj_array, oss,
									 true /*serialize_header_footer*/,
									 true /*indentation*/);
399 400
		CHAR *str = CreateMultiByteCharStringFromWCString(wcstr.GetBuffer());
		GPOS_ASSERT(NULL != str);
401

402
		relcache_ctxt->m_dxl = str;
J
Jesse Zhang 已提交
403

404
		// cleanup
405
		mdcache_obj_array->Release();
406
	}
J
Jesse Zhang 已提交
407

408 409 410 411 412
	return NULL;
}

//---------------------------------------------------------------------------
//	@function:
413
//		COptTasks::ConvertToDXLFromMDScalarCmp
414 415 416 417 418
//
//	@doc:
//		Task that dumps the relcache info for a scalar comparison object into DXL
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
419 420
void *
COptTasks::ConvertToDXLFromMDScalarCmp(void *ptr)
421
{
422
	GPOS_ASSERT(NULL != ptr);
423

J
Jesse Zhang 已提交
424 425
	SContextRelcacheToDXL *relcache_ctxt =
		SContextRelcacheToDXL::RelcacheConvert(ptr);
426
	GPOS_ASSERT(NULL != relcache_ctxt);
J
Jesse Zhang 已提交
427 428
	GPOS_ASSERT(CmptOther > relcache_ctxt->m_cmp_type &&
				"Incorrect comparison type specified");
429

430 431 432 433
	GPOS_ASSERT(2 == gpdb::ListLength(relcache_ctxt->m_oid_list));
	Oid left_oid = gpdb::ListNthOid(relcache_ctxt->m_oid_list, 0);
	Oid right_oid = gpdb::ListNthOid(relcache_ctxt->m_oid_list, 1);
	CmpType cmpt = (CmpType) relcache_ctxt->m_cmp_type;
J
Jesse Zhang 已提交
434

435
	CAutoMemoryPool amp(CAutoMemoryPool::ElcExc);
436
	CMemoryPool *mp = amp.Pmp();
437

J
Jesse Zhang 已提交
438 439
	IMDCacheObjectArray *mdcache_obj_array =
		GPOS_NEW(mp) IMDCacheObjectArray(mp);
440

J
Jesse Zhang 已提交
441 442 443
	IMDId *scalar_cmp = GPOS_NEW(mp) CMDIdScCmp(
		GPOS_NEW(mp) CMDIdGPDB(left_oid), GPOS_NEW(mp) CMDIdGPDB(right_oid),
		CTranslatorRelcacheToDXL::ParseCmpType(cmpt));
444 445

	// relcache MD provider
J
Jesse Zhang 已提交
446 447 448
	CMDProviderRelcache *relcache_provider =
		GPOS_NEW(mp) CMDProviderRelcache(mp);

449
	{
450
		CAutoMDAccessor md_accessor(mp, relcache_provider, default_sysid);
J
Jesse Zhang 已提交
451 452 453

		IMDCacheObject *md_obj = CTranslatorRelcacheToDXL::RetrieveObject(
			mp, md_accessor.Pmda(), scalar_cmp);
454
		GPOS_ASSERT(NULL != md_obj);
J
Jesse Zhang 已提交
455

456 457
		mdcache_obj_array->Append(md_obj);
		scalar_cmp->Release();
J
Jesse Zhang 已提交
458

459 460
		CWStringDynamic wcstr(mp);
		COstreamString oss(&wcstr);
461

J
Jesse Zhang 已提交
462 463 464
		CDXLUtils::SerializeMetadata(mp, mdcache_obj_array, oss,
									 true /*serialize_header_footer*/,
									 true /*indentation*/);
465 466
		CHAR *str = CreateMultiByteCharStringFromWCString(wcstr.GetBuffer());
		GPOS_ASSERT(NULL != str);
467

468
		relcache_ctxt->m_dxl = str;
J
Jesse Zhang 已提交
469

470
		// cleanup
471
		mdcache_obj_array->Release();
472
	}
J
Jesse Zhang 已提交
473

474 475 476 477 478 479 480 481 482 483 484 485 486
	return NULL;
}

//---------------------------------------------------------------------------
//	@function:
//		COptTasks::Execute
//
//	@doc:
//		Execute a task using GPOS. TODO extend gpos to provide
//		this functionality
//
//---------------------------------------------------------------------------
void
J
Jesse Zhang 已提交
487
COptTasks::Execute(void *(*func)(void *), void *func_arg)
488
{
489
	Assert(func);
490

491 492 493
	CHAR *err_buf = (CHAR *) palloc(GPOPT_ERROR_BUFFER_SIZE);
	err_buf[0] = '\0';

494 495 496 497 498
	// initialize DXL support
	InitDXL();

	bool abort_flag = false;

499
	CAutoMemoryPool amp(CAutoMemoryPool::ElcNone);
500 501

	gpos_exec_params params;
502 503
	params.func = func;
	params.arg = func_arg;
504 505 506 507 508 509
	params.stack_start = &params;
	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
510 511 512 513 514 515
	GPOS_TRY
	{
		(void) gpos_exec(&params);
	}
	GPOS_CATCH_EX(ex)
	{
516
		LogExceptionMessageAndDelete(err_buf, ex.SeverityLevel());
517 518 519
		GPOS_RETHROW(ex);
	}
	GPOS_CATCH_END;
520
	LogExceptionMessageAndDelete(err_buf);
521 522 523
}

void
J
Jesse Zhang 已提交
524
COptTasks::LogExceptionMessageAndDelete(CHAR *err_buf, ULONG severity_level)
525
{
526 527
	if ('\0' != err_buf[0])
	{
528
		int gpdb_severity_level;
529

530 531
		if (severity_level == CException::ExsevDebug1)
			gpdb_severity_level = DEBUG1;
532
		else
533
			gpdb_severity_level = LOG;
534

J
Jesse Zhang 已提交
535 536
		elog(gpdb_severity_level, "%s",
			 CreateMultiByteCharStringFromWCString((WCHAR *) err_buf));
537 538
	}

539
	pfree(err_buf);
540 541 542 543 544
}


//---------------------------------------------------------------------------
//	@function:
545
//		COptTasks::ConvertToDXLFromQueryTask
546 547 548 549 550
//
//	@doc:
//		task that does the translation from query to XML
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
551 552
void *
COptTasks::ConvertToDXLFromQueryTask(void *ptr)
553
{
554
	GPOS_ASSERT(NULL != ptr);
555

556
	SOptContext *opt_ctxt = SOptContext::Cast(ptr);
557

558 559
	GPOS_ASSERT(NULL != opt_ctxt->m_query);
	GPOS_ASSERT(NULL == opt_ctxt->m_query_dxl);
560 561

	AUTO_MEM_POOL(amp);
562
	CMemoryPool *mp = amp.Pmp();
563 564

	// ColId generator
J
Jesse Zhang 已提交
565 566 567 568
	CIdGenerator *colid_generator =
		GPOS_NEW(mp) CIdGenerator(GPDXL_COL_ID_START);
	CIdGenerator *cteid_generator =
		GPOS_NEW(mp) CIdGenerator(GPDXL_CTE_ID_START);
569 570

	// map that stores gpdb att to optimizer col mapping
571
	CMappingVarColId *var_colid_mapping = GPOS_NEW(mp) CMappingVarColId(mp);
572 573

	// relcache MD provider
J
Jesse Zhang 已提交
574 575
	CMDProviderRelcache *relcache_provider =
		GPOS_NEW(mp) CMDProviderRelcache(mp);
576 577

	{
578
		CAutoMDAccessor md_accessor(mp, relcache_provider, default_sysid);
579

580
		CAutoP<CTranslatorQueryToDXL> query_to_dxl_translator;
J
Jesse Zhang 已提交
581 582 583 584
		query_to_dxl_translator = CTranslatorQueryToDXL::QueryToDXLInstance(
			mp, md_accessor.Pmda(), colid_generator, cteid_generator,
			var_colid_mapping, (Query *) opt_ctxt->m_query, 0 /* query_level */
		);
585
		CDXLNode *query_dxl = query_to_dxl_translator->TranslateQueryToDXL();
J
Jesse Zhang 已提交
586 587
		CDXLNodeArray *query_output_dxlnode_array =
			query_to_dxl_translator->GetQueryOutputCols();
588 589
		CDXLNodeArray *cte_dxlnode_array = query_to_dxl_translator->GetCTEs();
		GPOS_ASSERT(NULL != query_output_dxlnode_array);
590

591 592
		GPOS_DELETE(colid_generator);
		GPOS_DELETE(cteid_generator);
593

594 595
		CWStringDynamic wcstr(mp);
		COstreamString oss(&wcstr);
596

J
Jesse Zhang 已提交
597 598 599 600 601 602 603
		CDXLUtils::SerializeQuery(mp, oss, query_dxl,
								  query_output_dxlnode_array, cte_dxlnode_array,
								  true,	 // serialize_header_footer
								  true	 // indentation
		);
		opt_ctxt->m_query_dxl =
			CreateMultiByteCharStringFromWCString(wcstr.GetBuffer());
604 605

		// clean up
606
		query_dxl->Release();
607 608 609 610 611 612 613 614
	}

	return NULL;
}


//---------------------------------------------------------------------------
//	@function:
615
//		COptTasks::ConvertToPlanStmtFromDXL
616 617 618 619 620 621
//
//	@doc:
//		Translate a DXL tree into a planned statement
//
//---------------------------------------------------------------------------
PlannedStmt *
J
Jesse Zhang 已提交
622 623
COptTasks::ConvertToPlanStmtFromDXL(CMemoryPool *mp, CMDAccessor *md_accessor,
									const CDXLNode *dxlnode, bool can_set_tag)
624
{
625 626
	GPOS_ASSERT(NULL != md_accessor);
	GPOS_ASSERT(NULL != dxlnode);
627

628 629 630
	CIdGenerator plan_id_generator(1 /* ulStartId */);
	CIdGenerator motion_id_generator(1 /* ulStartId */);
	CIdGenerator param_id_generator(0 /* ulStartId */);
631

632 633
	List *table_list = NULL;
	List *subplans_list = NULL;
634

J
Jesse Zhang 已提交
635 636 637 638
	CContextDXLToPlStmt dxl_to_plan_stmt_ctxt(
		mp, &plan_id_generator, &motion_id_generator, &param_id_generator,
		&table_list, &subplans_list);

639
	// translate DXL -> PlannedStmt
J
Jesse Zhang 已提交
640 641 642 643
	CTranslatorDXLToPlStmt dxl_to_plan_stmt_translator(
		mp, md_accessor, &dxl_to_plan_stmt_ctxt, gpdb::GetGPSegmentCount());
	return dxl_to_plan_stmt_translator.GetPlannedStmtFromDXL(dxlnode,
															 can_set_tag);
644 645 646 647 648
}


//---------------------------------------------------------------------------
//	@function:
649
//		COptTasks::LoadSearchStrategy
650 651 652 653 654
//
//	@doc:
//		Load search strategy from given file
//
//---------------------------------------------------------------------------
655
CSearchStageArray *
J
Jesse Zhang 已提交
656
COptTasks::LoadSearchStrategy(CMemoryPool *mp, char *path)
657
{
658 659
	CSearchStageArray *search_strategy_arr = NULL;
	CParseHandlerDXL *dxl_parse_handler = NULL;
660 661 662

	GPOS_TRY
	{
663
		if (NULL != path)
664
		{
J
Jesse Zhang 已提交
665 666
			dxl_parse_handler =
				CDXLUtils::GetParseHandlerForDXLFile(mp, path, NULL);
667
			if (NULL != dxl_parse_handler)
668
			{
669
				elog(DEBUG2, "\n[OPT]: Using search strategy in (%s)", path);
670

671 672
				search_strategy_arr = dxl_parse_handler->GetSearchStageArray();
				search_strategy_arr->AddRef();
673 674 675 676 677
			}
		}
	}
	GPOS_CATCH_EX(ex)
	{
J
Jesse Zhang 已提交
678 679
		if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError))
		{
680 681
			GPOS_RETHROW(ex);
		}
682
		elog(DEBUG2, "\n[OPT]: Using default search strategy");
683
		GPOS_RESET_EX;
684 685 686
	}
	GPOS_CATCH_END;

687
	GPOS_DELETE(dxl_parse_handler);
688

689
	return search_strategy_arr;
690 691 692 693
}

//---------------------------------------------------------------------------
//	@function:
694
//		COptTasks::CreateOptimizerConfig
695 696 697 698 699 700
//
//	@doc:
//		Create the optimizer configuration
//
//---------------------------------------------------------------------------
COptimizerConfig *
J
Jesse Zhang 已提交
701
COptTasks::CreateOptimizerConfig(CMemoryPool *mp, ICostModel *cost_model)
702 703
{
	// get chosen plan number, cost threshold
704 705 706
	ULLONG plan_id = (ULLONG) optimizer_plan_id;
	ULLONG num_samples = (ULLONG) optimizer_samples_number;
	DOUBLE cost_threshold = (DOUBLE) optimizer_cost_threshold;
707

708 709 710
	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;
711

712
	ULONG cte_inlining_cutoff = (ULONG) optimizer_cte_inlining_bound;
J
Jesse Zhang 已提交
713 714 715 716
	ULONG join_arity_for_associativity_commutativity =
		(ULONG) optimizer_join_arity_for_associativity_commutativity;
	ULONG array_expansion_threshold =
		(ULONG) optimizer_array_expansion_threshold;
717 718
	ULONG join_order_threshold = (ULONG) optimizer_join_order_threshold;
	ULONG broadcast_threshold = (ULONG) optimizer_penalize_broadcast_threshold;
719

J
Jesse Zhang 已提交
720 721 722 723 724 725 726 727 728 729 730 731 732
	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),
		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
733
								      * enforce them ourselves in the executor */
J
Jesse Zhang 已提交
734 735
				  PUSH_GROUP_BY_BELOW_SETOP_THRESHOLD),
		GPOS_NEW(mp) CWindowOids(OID(F_WINDOW_DUMMY), OID(F_WINDOW_RANK_OID)));
736 737 738 739 740 741 742 743 744 745 746
}

//---------------------------------------------------------------------------
//		@function:
//			COptTasks::SetCostModelParams
//
//      @doc:
//			Set cost model parameters
//
//---------------------------------------------------------------------------
void
J
Jesse Zhang 已提交
747
COptTasks::SetCostModelParams(ICostModel *cost_model)
748
{
749
	GPOS_ASSERT(NULL != cost_model);
750 751 752 753

	if (optimizer_nestloop_factor > 1.0)
	{
		// change NLJ cost factor
754
		ICostModelParams::SCostParam *cost_param = NULL;
J
Jesse Zhang 已提交
755 756
		if (OPTIMIZER_GPDB_CALIBRATED == optimizer_cost_model ||
			OPTIMIZER_GPDB_EXPERIMENTAL == optimizer_cost_model)
757
		{
J
Jesse Zhang 已提交
758 759
			cost_param = cost_model->GetCostModelParams()->PcpLookup(
				CCostModelParamsGPDB::EcpNLJFactor);
760 761 762
		}
		else
		{
J
Jesse Zhang 已提交
763 764
			cost_param = cost_model->GetCostModelParams()->PcpLookup(
				CCostModelParamsGPDBLegacy::EcpNLJFactor);
765
		}
766
		CDouble nlj_factor(optimizer_nestloop_factor);
J
Jesse Zhang 已提交
767 768
		cost_model->GetCostModelParams()->SetParam(
			cost_param->Id(), nlj_factor, nlj_factor - 0.5, nlj_factor + 0.5);
769
	}
770 771 772 773

	if (optimizer_sort_factor > 1.0 || optimizer_sort_factor < 1.0)
	{
		// change sort cost factor
774
		ICostModelParams::SCostParam *cost_param = NULL;
J
Jesse Zhang 已提交
775 776
		if (OPTIMIZER_GPDB_CALIBRATED == optimizer_cost_model ||
			OPTIMIZER_GPDB_EXPERIMENTAL == optimizer_cost_model)
777
		{
J
Jesse Zhang 已提交
778 779
			cost_param = cost_model->GetCostModelParams()->PcpLookup(
				CCostModelParamsGPDB::EcpSortTupWidthCostUnit);
780

781
			CDouble sort_factor(optimizer_sort_factor);
J
Jesse Zhang 已提交
782 783 784 785
			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);
786 787
		}
	}
788 789 790 791 792
}


//---------------------------------------------------------------------------
//      @function:
793
//			COptTasks::GetCostModel
794 795 796 797 798 799
//
//      @doc:
//			Generate an instance of optimizer cost model
//
//---------------------------------------------------------------------------
ICostModel *
J
Jesse Zhang 已提交
800
COptTasks::GetCostModel(CMemoryPool *mp, ULONG num_segments)
801
{
802
	ICostModel *cost_model = NULL;
J
Jesse Zhang 已提交
803 804
	if (OPTIMIZER_GPDB_CALIBRATED == optimizer_cost_model ||
		OPTIMIZER_GPDB_EXPERIMENTAL == optimizer_cost_model)
805
	{
806
		cost_model = GPOS_NEW(mp) CCostModelGPDB(mp, num_segments);
807 808 809
	}
	else
	{
810
		cost_model = GPOS_NEW(mp) CCostModelGPDBLegacy(mp, num_segments);
811 812
	}

813
	SetCostModelParams(cost_model);
814

815
	return cost_model;
816 817 818 819
}

//---------------------------------------------------------------------------
//	@function:
820
//		COptTasks::OptimizeTask
821 822 823 824 825
//
//	@doc:
//		task that does the optimizes query to physical DXL
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
826 827
void *
COptTasks::OptimizeTask(void *ptr)
828
{
829 830
	GPOS_ASSERT(NULL != ptr);
	SOptContext *opt_ctxt = SOptContext::Cast(ptr);
831

832 833 834
	GPOS_ASSERT(NULL != opt_ctxt->m_query);
	GPOS_ASSERT(NULL == opt_ctxt->m_plan_dxl);
	GPOS_ASSERT(NULL == opt_ctxt->m_plan_stmt);
835 836

	// initially assume no unexpected failure
837
	opt_ctxt->m_is_unexpected_failure = false;
838 839

	AUTO_MEM_POOL(amp);
840
	CMemoryPool *mp = amp.Pmp();
841

842 843 844
	// Does the metadatacache need to be reset?
	//
	// On the first call, before the cache has been initialized, we
845
	// don't care about the return value of MDCacheNeedsReset(). But
846 847
	// we need to call it anyway, to give it a chance to initialize
	// the invalidation mechanism.
848
	bool reset_mdcache = gpdb::MDCacheNeedsReset();
849

850
	// initialize metadata cache, or purge if needed, or change size if requested
851 852 853
	if (!CMDCache::FInitialized())
	{
		CMDCache::Init();
854
		CMDCache::SetCacheQuota(optimizer_mdcache_size * 1024L);
855
	}
856 857 858
	else if (reset_mdcache)
	{
		CMDCache::Reset();
859
		CMDCache::SetCacheQuota(optimizer_mdcache_size * 1024L);
860
	}
J
Jesse Zhang 已提交
861 862
	else if (CMDCache::ULLGetCacheQuota() !=
			 (ULLONG) optimizer_mdcache_size * 1024L)
863 864 865 866
	{
		CMDCache::SetCacheQuota(optimizer_mdcache_size * 1024L);
	}

867 868

	// load search strategy
J
Jesse Zhang 已提交
869 870
	CSearchStageArray *search_strategy_arr =
		LoadSearchStrategy(mp, optimizer_search_strategy_path);
871

872 873 874 875
	CBitSet *trace_flags = NULL;
	CBitSet *enabled_trace_flags = NULL;
	CBitSet *disabled_trace_flags = NULL;
	CDXLNode *plan_dxl = NULL;
876

877 878
	IMdIdArray *col_stats = NULL;
	MdidHashSet *rel_stats = NULL;
879 880 881 882

	GPOS_TRY
	{
		// set trace flags
J
Jesse Zhang 已提交
883 884 885 886
		trace_flags = CConfigParamMapping::PackConfigParamInBitset(
			mp, CXform::ExfSentinel);
		SetTraceflags(mp, trace_flags, &enabled_trace_flags,
					  &disabled_trace_flags);
887 888

		// set up relcache MD provider
J
Jesse Zhang 已提交
889 890
		CMDProviderRelcache *relcache_provider =
			GPOS_NEW(mp) CMDProviderRelcache(mp);
891 892 893

		{
			// scope for MD accessor
J
Jesse Zhang 已提交
894 895
			CMDAccessor mda(mp, CMDCache::Pcache(), default_sysid,
							relcache_provider);
896 897

			// ColId generator
898 899
			CIdGenerator colid_generator(GPDXL_COL_ID_START);
			CIdGenerator cteid_generator(GPDXL_CTE_ID_START);
900 901

			// map that stores gpdb att to optimizer col mapping
J
Jesse Zhang 已提交
902 903
			CMappingVarColId *var_colid_mapping =
				GPOS_NEW(mp) CMappingVarColId(mp);
904

905 906 907
			ULONG num_segments = gpdb::GetGPSegmentCount();
			ULONG num_segments_for_costing = optimizer_segments;
			if (0 == num_segments_for_costing)
908
			{
909
				num_segments_for_costing = num_segments;
910 911
			}

912
			CAutoP<CTranslatorQueryToDXL> query_to_dxl_translator;
J
Jesse Zhang 已提交
913 914 915 916
			query_to_dxl_translator = CTranslatorQueryToDXL::QueryToDXLInstance(
				mp, &mda, &colid_generator, &cteid_generator, var_colid_mapping,
				(Query *) opt_ctxt->m_query, 0 /* query_level */
			);
917

918
			ICostModel *cost_model = GetCostModel(mp, num_segments_for_costing);
J
Jesse Zhang 已提交
919 920
			COptimizerConfig *optimizer_config =
				CreateOptimizerConfig(mp, cost_model);
921 922
			CConstExprEvaluatorProxy expr_eval_proxy(mp, &mda);
			IConstExprEvaluator *expr_evaluator =
J
Jesse Zhang 已提交
923 924 925 926 927 928 929 930
				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();
931
			GPOS_ASSERT(NULL != query_output_dxlnode_array);
932

J
Jesse Zhang 已提交
933 934 935 936
			BOOL is_master_only =
				!optimizer_enable_motions ||
				(!optimizer_enable_motions_masteronly_queries &&
				 !query_to_dxl_translator->HasDistributedTables());
937
			CAutoTraceFlag atf(EopttraceDisableMotions, is_master_only);
938

J
Jesse Zhang 已提交
939 940 941 942
			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);
943

944
			if (opt_ctxt->m_should_serialize_plan_dxl)
945 946
			{
				// serialize DXL to xml
947 948
				CWStringDynamic plan_str(mp);
				COstreamString oss(&plan_str);
J
Jesse Zhang 已提交
949 950 951 952 953 954 955
				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());
956 957 958
			}

			// translate DXL->PlStmt only when needed
959
			if (opt_ctxt->m_should_generate_plan_stmt)
960
			{
961 962
				// 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
J
Jesse Zhang 已提交
963 964 965
				opt_ctxt->m_plan_stmt =
					(PlannedStmt *) gpdb::CopyObject(ConvertToPlanStmtFromDXL(
						mp, &mda, plan_dxl, opt_ctxt->m_query->canSetTag));
966 967
			}

968 969 970
			CStatisticsConfig *stats_conf = optimizer_config->GetStatsConf();
			col_stats = GPOS_NEW(mp) IMdIdArray(mp);
			stats_conf->CollectMissingStatsColumns(col_stats);
971

972 973
			rel_stats = GPOS_NEW(mp) MdidHashSet(mp);
			PrintMissingStatsWarning(mp, &mda, col_stats, rel_stats);
974

975 976
			rel_stats->Release();
			col_stats->Release();
977

978 979 980 981
			expr_evaluator->Release();
			query_dxl->Release();
			optimizer_config->Release();
			plan_dxl->Release();
982 983 984 985
		}
	}
	GPOS_CATCH_EX(ex)
	{
986 987 988 989 990 991 992
		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);
993 994 995 996
		CMDCache::Shutdown();

		if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError))
		{
J
Jesse Zhang 已提交
997 998
			elog(DEBUG1,
				 "GPDB Exception. Please check log for more information.");
999
		}
1000
		else if (ShouldErrorOut(ex))
1001
		{
1002
			IErrorContext *errctxt = CTask::Self()->GetErrCtxt();
J
Jesse Zhang 已提交
1003 1004
			opt_ctxt->m_error_msg =
				CreateMultiByteCharStringFromWCString(errctxt->GetErrorMsg());
1005 1006 1007
		}
		else
		{
H
Hans Zeller 已提交
1008
			opt_ctxt->m_is_unexpected_failure = IsLoggableFailure(ex);
1009 1010 1011 1012 1013 1014
		}
		GPOS_RETHROW(ex);
	}
	GPOS_CATCH_END;

	// cleanup
1015 1016 1017 1018
	ResetTraceflags(enabled_trace_flags, disabled_trace_flags);
	CRefCount::SafeRelease(enabled_trace_flags);
	CRefCount::SafeRelease(disabled_trace_flags);
	CRefCount::SafeRelease(trace_flags);
1019
	if (!optimizer_metadata_caching)
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
	{
		CMDCache::Shutdown();
	}

	return NULL;
}


//---------------------------------------------------------------------------
//	@function:
//		COptTasks::PrintMissingStatsWarning
//
//	@doc:
//		Print warning messages for columns with missing statistics
//
//---------------------------------------------------------------------------
void
J
Jesse Zhang 已提交
1037 1038 1039
COptTasks::PrintMissingStatsWarning(CMemoryPool *mp, CMDAccessor *md_accessor,
									IMdIdArray *col_stats,
									MdidHashSet *rel_stats)
1040
{
1041 1042 1043
	GPOS_ASSERT(NULL != md_accessor);
	GPOS_ASSERT(NULL != col_stats);
	GPOS_ASSERT(NULL != rel_stats);
1044

1045 1046
	CWStringDynamic wcstr(mp);
	COstreamString oss(&wcstr);
1047

1048 1049
	const ULONG num_missing_col_stats = col_stats->Size();
	for (ULONG ul = 0; ul < num_missing_col_stats; ul++)
1050
	{
1051 1052
		IMDId *mdid = (*col_stats)[ul];
		CMDIdColStats *mdid_col_stats = CMDIdColStats::CastMdid(mdid);
1053

1054 1055 1056
		IMDId *rel_mdid = mdid_col_stats->GetRelMdId();
		const ULONG pos = mdid_col_stats->Position();
		const IMDRelation *rel = md_accessor->RetrieveRel(rel_mdid);
1057

1058
		if (IMDRelation::ErelstorageExternal != rel->RetrieveRelStorageType())
1059
		{
1060
			if (!rel_stats->Contains(rel_mdid))
1061 1062 1063 1064 1065 1066
			{
				if (0 != ul)
				{
					oss << ", ";
				}

1067 1068 1069
				rel_mdid->AddRef();
				rel_stats->Insert(rel_mdid);
				oss << rel->Mdname().GetMDName()->GetBuffer();
1070 1071
			}

1072
			CMDName mdname = rel->GetMdCol(pos)->Mdname();
1073 1074

			char msgbuf[NAMEDATALEN * 2 + 100];
J
Jesse Zhang 已提交
1075 1076 1077 1078 1079 1080 1081
			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, NULL);
1082 1083 1084
		}
	}

1085
	if (0 < rel_stats->Size())
1086
	{
1087
		int length = NAMEDATALEN * rel_stats->Size() + 200;
1088
		char msgbuf[length];
J
Jesse Zhang 已提交
1089 1090 1091 1092 1093 1094 1095 1096 1097
		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.");
1098 1099 1100 1101 1102 1103
	}
}


//---------------------------------------------------------------------------
//	@function:
1104
//		COptTasks::OptimizeMinidumpTask
1105 1106 1107 1108 1109
//
//	@doc:
//		Task that loads and optimizes a minidump and returns the result as string-serialized DXL
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
1110 1111
void *
COptTasks::OptimizeMinidumpTask(void *ptr)
1112
{
1113
	GPOS_ASSERT(NULL != ptr);
1114

J
Jesse Zhang 已提交
1115 1116
	SOptimizeMinidumpContext *minidump_ctxt =
		SOptimizeMinidumpContext::Cast(ptr);
1117 1118
	GPOS_ASSERT(NULL != minidump_ctxt->m_szFileName);
	GPOS_ASSERT(NULL == minidump_ctxt->m_dxl_result);
1119 1120

	AUTO_MEM_POOL(amp);
1121
	CMemoryPool *mp = amp.Pmp();
1122

1123 1124 1125
	ULONG num_segments = gpdb::GetGPSegmentCount();
	ULONG num_segments_for_costing = optimizer_segments;
	if (0 == num_segments_for_costing)
1126
	{
1127
		num_segments_for_costing = num_segments;
1128 1129
	}

1130 1131 1132
	ICostModel *cost_model = GetCostModel(mp, num_segments_for_costing);
	COptimizerConfig *optimizer_config = CreateOptimizerConfig(mp, cost_model);
	CDXLNode *result_dxl = NULL;
1133 1134 1135

	GPOS_TRY
	{
J
Jesse Zhang 已提交
1136 1137 1138
		result_dxl = CMinidumperUtils::PdxlnExecuteMinidump(
			mp, minidump_ctxt->m_szFileName, num_segments, gp_session_id,
			gp_command_count, optimizer_config);
1139 1140 1141
	}
	GPOS_CATCH_EX(ex)
	{
1142 1143
		CRefCount::SafeRelease(result_dxl);
		CRefCount::SafeRelease(optimizer_config);
1144 1145 1146
		GPOS_RETHROW(ex);
	}
	GPOS_CATCH_END;
1147

1148 1149
	CWStringDynamic wcstr(mp);
	COstreamString oss(&wcstr);
J
Jesse Zhang 已提交
1150 1151 1152 1153 1154 1155 1156 1157
	CDXLUtils::SerializePlan(mp, oss, result_dxl,
							 0,		// plan_id
							 0,		// plan_space_size
							 true,	// serialize_header_footer
							 true	// indentation
	);
	minidump_ctxt->m_dxl_result =
		CreateMultiByteCharStringFromWCString(wcstr.GetBuffer());
1158 1159
	CRefCount::SafeRelease(result_dxl);
	optimizer_config->Release();
1160 1161 1162 1163 1164 1165

	return NULL;
}

//---------------------------------------------------------------------------
//	@function:
1166
//		COptTasks::ConvertToPlanStmtFromDXLTask
1167 1168
//
//	@doc:
1169
//		task that does the translation from xml to dxl to planned_stmt
1170 1171
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
1172 1173
void *
COptTasks::ConvertToPlanStmtFromDXLTask(void *ptr)
1174
{
1175
	GPOS_ASSERT(NULL != ptr);
1176

1177
	SOptContext *opt_ctxt = SOptContext::Cast(ptr);
1178

1179 1180
	GPOS_ASSERT(NULL == opt_ctxt->m_query);
	GPOS_ASSERT(NULL != opt_ctxt->m_plan_dxl);
1181 1182

	AUTO_MEM_POOL(amp);
1183
	CMemoryPool *mp = amp.Pmp();
1184

1185 1186
	CWStringDynamic wcstr(mp);
	COstreamString oss(&wcstr);
1187

1188 1189
	ULLONG plan_id = 0;
	ULLONG plan_space_size = 0;
J
Jesse Zhang 已提交
1190 1191 1192
	CDXLNode *original_plan_dxl = CDXLUtils::GetPlanDXLNode(
		mp, opt_ctxt->m_plan_dxl, NULL /*XSD location*/, &plan_id,
		&plan_space_size);
1193

1194 1195 1196
	CIdGenerator plan_id_generator(1);
	CIdGenerator motion_id_generator(1);
	CIdGenerator param_id_generator(0);
1197

1198 1199
	List *table_list = NULL;
	List *subplans_list = NULL;
1200

J
Jesse Zhang 已提交
1201 1202 1203
	CContextDXLToPlStmt dxl_to_plan_stmt_ctxt(
		mp, &plan_id_generator, &motion_id_generator, &param_id_generator,
		&table_list, &subplans_list);
1204 1205

	// relcache MD provider
J
Jesse Zhang 已提交
1206 1207
	CMDProviderRelcache *relcache_provider =
		GPOS_NEW(mp) CMDProviderRelcache(mp);
1208 1209

	{
1210
		CAutoMDAccessor md_accessor(mp, relcache_provider, default_sysid);
1211 1212

		// translate DXL -> PlannedStmt
J
Jesse Zhang 已提交
1213 1214 1215 1216 1217 1218
		CTranslatorDXLToPlStmt dxl_to_plan_stmt_translator(
			mp, md_accessor.Pmda(), &dxl_to_plan_stmt_ctxt,
			gpdb::GetGPSegmentCount());
		PlannedStmt *plan_stmt =
			dxl_to_plan_stmt_translator.GetPlannedStmtFromDXL(
				original_plan_dxl, opt_ctxt->m_query->canSetTag);
1219 1220
		if (optimizer_print_plan)
		{
1221
			elog(NOTICE, "Plstmt: %s", gpdb::NodeToString(plan_stmt));
1222 1223
		}

1224
		GPOS_ASSERT(NULL != plan_stmt);
1225 1226
		GPOS_ASSERT(NULL != CurrentMemoryContext);

1227
		opt_ctxt->m_plan_stmt = (PlannedStmt *) gpdb::CopyObject(plan_stmt);
1228 1229 1230
	}

	// cleanup
1231
	original_plan_dxl->Release();
1232 1233 1234 1235 1236 1237

	return NULL;
}

//---------------------------------------------------------------------------
//	@function:
1238
//		COptTasks::ConvertToDXLFromMDObjsTask
1239 1240 1241 1242 1243
//
//	@doc:
//		task that does dumps the relcache info for an object into DXL
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
1244 1245
void *
COptTasks::ConvertToDXLFromMDObjsTask(void *ptr)
1246
{
1247
	GPOS_ASSERT(NULL != ptr);
1248

J
Jesse Zhang 已提交
1249 1250
	SContextRelcacheToDXL *relcache_ctxt =
		SContextRelcacheToDXL::RelcacheConvert(ptr);
1251
	GPOS_ASSERT(NULL != relcache_ctxt);
1252 1253

	AUTO_MEM_POOL(amp);
1254
	CMemoryPool *mp = amp.Pmp();
1255

J
Jesse Zhang 已提交
1256 1257
	IMDCacheObjectArray *mdcache_obj_array =
		GPOS_NEW(mp) IMDCacheObjectArray(mp, 1024, 1024);
1258 1259

	// relcache MD provider
1260
	CMDProviderRelcache *md_provider = GPOS_NEW(mp) CMDProviderRelcache(mp);
1261
	{
1262 1263
		CAutoMDAccessor md_accessor(mp, md_provider, default_sysid);
		ListCell *lc = NULL;
J
Jesse Zhang 已提交
1264
		ForEach(lc, relcache_ctxt->m_oid_list)
1265
		{
1266
			Oid oid = lfirst_oid(lc);
1267
			// get object from relcache
J
Jesse Zhang 已提交
1268 1269
			CMDIdGPDB *mdid =
				GPOS_NEW(mp) CMDIdGPDB(oid, 1 /* major */, 0 /* minor */);
1270

J
Jesse Zhang 已提交
1271 1272
			IMDCacheObject *mdobj = CTranslatorRelcacheToDXL::RetrieveObject(
				mp, md_accessor.Pmda(), mdid);
1273
			GPOS_ASSERT(NULL != mdobj);
1274

1275 1276
			mdcache_obj_array->Append(mdobj);
			mdid->Release();
1277 1278
		}

1279
		if (relcache_ctxt->m_filename)
1280
		{
1281
			COstreamFile cofs(relcache_ctxt->m_filename);
1282

J
Jesse Zhang 已提交
1283 1284 1285
			CDXLUtils::SerializeMetadata(mp, mdcache_obj_array, cofs,
										 true /*serialize_header_footer*/,
										 true /*indentation*/);
1286 1287 1288
		}
		else
		{
1289 1290
			CWStringDynamic wcstr(mp);
			COstreamString oss(&wcstr);
1291

J
Jesse Zhang 已提交
1292 1293 1294
			CDXLUtils::SerializeMetadata(mp, mdcache_obj_array, oss,
										 true /*serialize_header_footer*/,
										 true /*indentation*/);
1295

J
Jesse Zhang 已提交
1296 1297
			CHAR *str =
				CreateMultiByteCharStringFromWCString(wcstr.GetBuffer());
1298

1299
			GPOS_ASSERT(NULL != str);
1300

1301
			relcache_ctxt->m_dxl = str;
1302 1303 1304
		}
	}
	// cleanup
1305
	mdcache_obj_array->Release();
1306 1307 1308 1309 1310 1311 1312

	return NULL;
}


//---------------------------------------------------------------------------
//	@function:
1313
//		COptTasks::ConvertToDXLFromRelStatsTask
1314 1315 1316 1317 1318
//
//	@doc:
//		task that dumps relstats info for a table in DXL
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
1319 1320
void *
COptTasks::ConvertToDXLFromRelStatsTask(void *ptr)
1321
{
1322
	GPOS_ASSERT(NULL != ptr);
1323

J
Jesse Zhang 已提交
1324 1325
	SContextRelcacheToDXL *relcache_ctxt =
		SContextRelcacheToDXL::RelcacheConvert(ptr);
1326
	GPOS_ASSERT(NULL != relcache_ctxt);
1327 1328

	AUTO_MEM_POOL(amp);
1329
	CMemoryPool *mp = amp.Pmp();
1330 1331

	// relcache MD provider
J
Jesse Zhang 已提交
1332 1333
	CMDProviderRelcache *relcache_provider =
		GPOS_NEW(mp) CMDProviderRelcache(mp);
1334 1335
	CAutoMDAccessor md_accessor(mp, relcache_provider, default_sysid);
	ICostModel *cost_model = GetCostModel(mp, gpdb::GetGPSegmentCount());
J
Jesse Zhang 已提交
1336 1337
	CAutoOptCtxt aoc(mp, md_accessor.Pmda(), NULL /*expr_evaluator*/,
					 cost_model);
1338

J
Jesse Zhang 已提交
1339 1340
	IMDCacheObjectArray *mdcache_obj_array =
		GPOS_NEW(mp) IMDCacheObjectArray(mp);
1341

1342
	ListCell *lc = NULL;
J
Jesse Zhang 已提交
1343
	ForEach(lc, relcache_ctxt->m_oid_list)
1344
	{
1345
		Oid relation_oid = lfirst_oid(lc);
1346 1347

		// get object from relcache
J
Jesse Zhang 已提交
1348 1349
		CMDIdGPDB *mdid =
			GPOS_NEW(mp) CMDIdGPDB(relation_oid, 1 /* major */, 0 /* minor */);
1350 1351

		// generate mdid for relstats
1352
		CMDIdRelStats *m_rel_stats_mdid = GPOS_NEW(mp) CMDIdRelStats(mdid);
J
Jesse Zhang 已提交
1353 1354 1355 1356
		IMDRelStats *mdobj_rel_stats = const_cast<IMDRelStats *>(
			md_accessor.Pmda()->Pmdrelstats(m_rel_stats_mdid));
		mdcache_obj_array->Append(
			dynamic_cast<IMDCacheObject *>(mdobj_rel_stats));
1357 1358

		// extract out column stats for this relation
1359 1360
		Relation rel = gpdb::GetRelation(relation_oid);
		ULONG pos_counter = 0;
1361 1362 1363 1364
		for (ULONG ul = 0; ul < ULONG(rel->rd_att->natts); ul++)
		{
			if (!rel->rd_att->attrs[ul]->attisdropped)
			{
1365
				mdid->AddRef();
J
Jesse Zhang 已提交
1366 1367
				CMDIdColStats *mdid_col_stats =
					GPOS_NEW(mp) CMDIdColStats(mdid, pos_counter);
1368
				pos_counter++;
J
Jesse Zhang 已提交
1369 1370 1371 1372
				IMDColStats *mdobj_col_stats = const_cast<IMDColStats *>(
					md_accessor.Pmda()->Pmdcolstats(mdid_col_stats));
				mdcache_obj_array->Append(
					dynamic_cast<IMDCacheObject *>(mdobj_col_stats));
1373
				mdid_col_stats->Release();
1374 1375 1376
			}
		}
		gpdb::CloseRelation(rel);
1377
		m_rel_stats_mdid->Release();
1378 1379
	}

1380
	if (relcache_ctxt->m_filename)
1381
	{
1382
		COstreamFile cofs(relcache_ctxt->m_filename);
1383

J
Jesse Zhang 已提交
1384 1385 1386
		CDXLUtils::SerializeMetadata(mp, mdcache_obj_array, cofs,
									 true /*serialize_header_footer*/,
									 true /*indentation*/);
1387 1388 1389
	}
	else
	{
1390 1391
		CWStringDynamic wcstr(mp);
		COstreamString oss(&wcstr);
1392

J
Jesse Zhang 已提交
1393 1394 1395
		CDXLUtils::SerializeMetadata(mp, mdcache_obj_array, oss,
									 true /*serialize_header_footer*/,
									 true /*indentation*/);
1396

1397
		CHAR *str = CreateMultiByteCharStringFromWCString(wcstr.GetBuffer());
1398

1399
		GPOS_ASSERT(NULL != str);
1400

1401
		relcache_ctxt->m_dxl = str;
1402 1403 1404
	}

	// cleanup
1405
	mdcache_obj_array->Release();
1406 1407 1408 1409 1410 1411 1412

	return NULL;
}


//---------------------------------------------------------------------------
//	@function:
1413
//		COptTasks::EvalExprFromDXLTask
1414 1415 1416 1417 1418 1419
//
//	@doc:
//		Task that parses an XML representation of a DXL constant expression,
//		evaluates it and returns the result as a serialized DXL document.
//
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
1420 1421
void *
COptTasks::EvalExprFromDXLTask(void *ptr)
1422
{
1423 1424
	GPOS_ASSERT(NULL != ptr);
	SEvalExprContext *eval_expr_ctxt = SEvalExprContext::PevalctxtConvert(ptr);
1425

1426 1427
	GPOS_ASSERT(NULL != eval_expr_ctxt->m_dxl);
	GPOS_ASSERT(NULL == eval_expr_ctxt->m_dxl_result);
1428 1429

	AUTO_MEM_POOL(amp);
1430
	CMemoryPool *mp = amp.Pmp();
1431

J
Jesse Zhang 已提交
1432 1433
	CDXLNode *input_dxl = CDXLUtils::ParseDXLToScalarExprDXLNode(
		mp, eval_expr_ctxt->m_dxl, NULL /*xsd_file_path*/);
1434
	GPOS_ASSERT(NULL != input_dxl);
1435

1436 1437
	CDXLNode *result_dxl = NULL;
	BOOL should_release_cache = false;
1438 1439 1440 1441

	// Does the metadatacache need to be reset?
	//
	// On the first call, before the cache has been initialized, we
1442
	// don't care about the return value of MDCacheNeedsReset(). But
1443 1444
	// we need to call it anyway, to give it a chance to initialize
	// the invalidation mechanism.
1445
	bool reset_mdcache = gpdb::MDCacheNeedsReset();
1446 1447

	// initialize metadata cache, or purge if needed, or change size if requested
1448 1449 1450
	if (!CMDCache::FInitialized())
	{
		CMDCache::Init();
1451
		CMDCache::SetCacheQuota(optimizer_mdcache_size * 1024L);
1452
		should_release_cache = true;
1453
	}
1454 1455 1456 1457 1458
	else if (reset_mdcache)
	{
		CMDCache::Reset();
		CMDCache::SetCacheQuota(optimizer_mdcache_size * 1024L);
	}
J
Jesse Zhang 已提交
1459 1460
	else if (CMDCache::ULLGetCacheQuota() !=
			 (ULLONG) optimizer_mdcache_size * 1024L)
1461 1462 1463
	{
		CMDCache::SetCacheQuota(optimizer_mdcache_size * 1024L);
	}
1464 1465 1466 1467

	GPOS_TRY
	{
		// set up relcache MD provider
J
Jesse Zhang 已提交
1468 1469
		CMDProviderRelcache *relcache_provider =
			GPOS_NEW(mp) CMDProviderRelcache(mp);
1470 1471
		{
			// scope for MD accessor
J
Jesse Zhang 已提交
1472 1473
			CMDAccessor mda(mp, CMDCache::Pcache(), default_sysid,
							relcache_provider);
1474

1475 1476
			CConstExprEvaluatorProxy expr_eval_proxy(mp, &mda);
			result_dxl = expr_eval_proxy.EvaluateExpr(input_dxl);
1477 1478 1479 1480
		}
	}
	GPOS_CATCH_EX(ex)
	{
1481 1482 1483
		CRefCount::SafeRelease(result_dxl);
		CRefCount::SafeRelease(input_dxl);
		if (should_release_cache)
1484 1485 1486
		{
			CMDCache::Shutdown();
		}
1487
		if (ShouldErrorOut(ex))
1488
		{
1489
			IErrorContext *errctxt = CTask::Self()->GetErrCtxt();
J
Jesse Zhang 已提交
1490 1491
			char *serialized_error_msg =
				CreateMultiByteCharStringFromWCString(errctxt->GetErrorMsg());
1492 1493
			elog(DEBUG1, "%s", serialized_error_msg);
			gpdb::GPDBFree(serialized_error_msg);
1494 1495 1496 1497 1498
		}
		GPOS_RETHROW(ex);
	}
	GPOS_CATCH_END;

1499
	CWStringDynamic *dxl_string =
J
Jesse Zhang 已提交
1500 1501 1502 1503 1504 1505
		CDXLUtils::SerializeScalarExpr(mp, result_dxl,
									   true,  // serialize_header_footer
									   true	  // indentation
		);
	eval_expr_ctxt->m_dxl_result =
		CreateMultiByteCharStringFromWCString(dxl_string->GetBuffer());
1506 1507 1508
	GPOS_DELETE(dxl_string);
	CRefCount::SafeRelease(result_dxl);
	input_dxl->Release();
1509

1510
	if (should_release_cache)
1511 1512 1513 1514 1515 1516 1517 1518 1519 1520
	{
		CMDCache::Shutdown();
	}

	return NULL;
}


//---------------------------------------------------------------------------
//	@function:
1521
//		COptTasks::Optimize
1522 1523 1524 1525 1526 1527
//
//	@doc:
//		optimizes a query to physical DXL
//
//---------------------------------------------------------------------------
char *
J
Jesse Zhang 已提交
1528
COptTasks::Optimize(Query *query)
1529
{
1530
	Assert(query);
1531

1532 1533 1534 1535
	SOptContext gpopt_context;
	gpopt_context.m_query = query;
	gpopt_context.m_should_serialize_plan_dxl = true;
	Execute(&OptimizeTask, &gpopt_context);
1536 1537

	// clean up context
1538
	gpopt_context.Free(gpopt_context.epinQuery, gpopt_context.epinPlanDXL);
1539

1540
	return gpopt_context.m_plan_dxl;
1541 1542 1543 1544 1545
}


//---------------------------------------------------------------------------
//	@function:
1546
//		COptTasks::GPOPTOptimizedPlan
1547 1548 1549 1550 1551 1552
//
//	@doc:
//		optimizes a query to plannedstmt
//
//---------------------------------------------------------------------------
PlannedStmt *
J
Jesse Zhang 已提交
1553 1554 1555 1556 1557
COptTasks::GPOPTOptimizedPlan(
	Query *query, SOptContext *gpopt_context,
	BOOL *
		has_unexpected_failure	// output : set to true if optimizer unexpectedly failed to produce plan
)
1558
{
1559 1560
	Assert(query);
	Assert(gpopt_context);
1561

1562
	gpopt_context->m_query = query;
J
Jesse Zhang 已提交
1563
	gpopt_context->m_should_generate_plan_stmt = true;
1564
	GPOS_TRY
1565
	{
1566
		Execute(&OptimizeTask, gpopt_context);
1567
	}
1568 1569
	GPOS_CATCH_EX(ex)
	{
1570
		*has_unexpected_failure = gpopt_context->m_is_unexpected_failure;
1571 1572 1573
		GPOS_RETHROW(ex);
	}
	GPOS_CATCH_END;
1574 1575
	gpopt_context->HandleError(has_unexpected_failure);
	return gpopt_context->m_plan_stmt;
1576 1577 1578 1579 1580
}


//---------------------------------------------------------------------------
//	@function:
1581
//		COptTasks::ConvertQueryToDXL
1582 1583 1584 1585 1586 1587
//
//	@doc:
//		serializes query to DXL
//
//---------------------------------------------------------------------------
char *
J
Jesse Zhang 已提交
1588
COptTasks::ConvertQueryToDXL(Query *query)
1589
{
1590
	Assert(query);
1591

1592 1593 1594
	SOptContext gpopt_context;
	gpopt_context.m_query = query;
	Execute(&ConvertToDXLFromQueryTask, &gpopt_context);
1595 1596

	// clean up context
1597
	gpopt_context.Free(gpopt_context.epinQuery, gpopt_context.epinQueryDXL);
1598

1599
	return gpopt_context.m_query_dxl;
1600 1601 1602 1603 1604
}


//---------------------------------------------------------------------------
//	@function:
1605
//		COptTasks::ConvertToiPlanStmtFromXML
1606 1607 1608 1609 1610 1611
//
//	@doc:
//		deserializes planned stmt from DXL
//
//---------------------------------------------------------------------------
PlannedStmt *
J
Jesse Zhang 已提交
1612
COptTasks::ConvertToiPlanStmtFromXML(char *dxl_string)
1613
{
1614
	Assert(NULL != dxl_string);
1615

1616 1617 1618
	SOptContext gpopt_context;
	gpopt_context.m_plan_dxl = dxl_string;
	Execute(&ConvertToPlanStmtFromDXLTask, &gpopt_context);
1619 1620

	// clean up context
1621
	gpopt_context.Free(gpopt_context.epinPlanDXL, gpopt_context.epinPlStmt);
1622

1623
	return gpopt_context.m_plan_stmt;
1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635
}


//---------------------------------------------------------------------------
//	@function:
//		COptTasks::DumpMDObjs
//
//	@doc:
//		Dump relcache objects into DXL file
//
//---------------------------------------------------------------------------
void
J
Jesse Zhang 已提交
1636
COptTasks::DumpMDObjs(List *oid_list, const char *filename)
1637
{
J
Jesse Zhang 已提交
1638 1639
	SContextRelcacheToDXL relcache_ctxt(oid_list, gpos::ulong_max /*cmp_type*/,
										filename);
1640
	Execute(&ConvertToDXLFromMDObjsTask, &relcache_ctxt);
1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652
}


//---------------------------------------------------------------------------
//	@function:
//		COptTasks::SzMDObjs
//
//	@doc:
//		Dump relcache objects into DXL string
//
//---------------------------------------------------------------------------
char *
J
Jesse Zhang 已提交
1653
COptTasks::SzMDObjs(List *oid_list)
1654
{
J
Jesse Zhang 已提交
1655 1656
	SContextRelcacheToDXL relcache_ctxt(oid_list, gpos::ulong_max /*cmp_type*/,
										NULL /*filename*/);
1657
	Execute(&ConvertToDXLFromMDObjsTask, &relcache_ctxt);
1658

1659
	return relcache_ctxt.m_dxl;
1660 1661 1662 1663
}

//---------------------------------------------------------------------------
//	@function:
1664
//		COptTasks::DumpMDCast
1665 1666 1667 1668 1669 1670
//
//	@doc:
//		Dump cast object into DXL string
//
//---------------------------------------------------------------------------
char *
J
Jesse Zhang 已提交
1671
COptTasks::DumpMDCast(List *oid_list)
1672
{
J
Jesse Zhang 已提交
1673 1674
	SContextRelcacheToDXL relcache_ctxt(oid_list, gpos::ulong_max /*cmp_type*/,
										NULL /*filename*/);
1675
	Execute(&ConvertToDXLFromMDCast, &relcache_ctxt);
1676

1677
	return relcache_ctxt.m_dxl;
1678 1679 1680 1681
}

//---------------------------------------------------------------------------
//	@function:
1682
//		COptTasks::DumpMDScalarCmp
1683 1684 1685 1686 1687 1688
//
//	@doc:
//		Dump scalar comparison object into DXL string
//
//---------------------------------------------------------------------------
char *
J
Jesse Zhang 已提交
1689
COptTasks::DumpMDScalarCmp(List *oid_list, char *cmp_type)
1690
{
J
Jesse Zhang 已提交
1691 1692
	SContextRelcacheToDXL relcache_ctxt(oid_list, GetComparisonType(cmp_type),
										NULL /*filename*/);
1693
	Execute(&ConvertToDXLFromMDScalarCmp, &relcache_ctxt);
1694

1695
	return relcache_ctxt.m_dxl;
1696 1697 1698 1699 1700
}


//---------------------------------------------------------------------------
//	@function:
1701
//		COptTasks::DumpRelStats
1702 1703 1704 1705 1706 1707
//
//	@doc:
//		Dump statistics objects into DXL string
//
//---------------------------------------------------------------------------
char *
J
Jesse Zhang 已提交
1708
COptTasks::DumpRelStats(List *oid_list)
1709
{
J
Jesse Zhang 已提交
1710 1711
	SContextRelcacheToDXL relcache_ctxt(oid_list, gpos::ulong_max /*cmp_type*/,
										NULL /*filename*/);
1712
	Execute(&ConvertToDXLFromRelStatsTask, &relcache_ctxt);
1713

1714
	return relcache_ctxt.m_dxl;
1715 1716 1717 1718
}

//---------------------------------------------------------------------------
//	@function:
1719
//		COptTasks::SetXform
1720 1721 1722 1723 1724 1725
//
//	@doc:
//		Enable/Disable a given xform
//
//---------------------------------------------------------------------------
bool
J
Jesse Zhang 已提交
1726
COptTasks::SetXform(char *xform_str, bool should_disable)
1727
{
1728 1729
	CXform *xform = CXformFactory::Pxff()->Pxf(xform_str);
	if (NULL != xform)
1730
	{
1731
		optimizer_xforms[xform->Exfid()] = should_disable;
1732 1733 1734 1735 1736 1737 1738 1739 1740

		return true;
	}

	return false;
}

//---------------------------------------------------------------------------
//	@function:
1741
//		COptTasks::GetComparisonType
1742 1743 1744 1745 1746 1747
//
//	@doc:
//		Find the comparison type code given its string representation
//
//---------------------------------------------------------------------------
ULONG
J
Jesse Zhang 已提交
1748
COptTasks::GetComparisonType(char *cmp_type)
1749
{
1750
	const ULONG num_cmp_types = 6;
J
Jesse Zhang 已提交
1751 1752
	const CmpType cmp_types[] = {CmptEq, CmptNEq, CmptLT,
								 CmptGT, CmptLEq, CmptGEq};
1753
	const CHAR *cmp_types_str_arr[] = {"Eq", "NEq", "LT", "GT", "LEq", "GEq"};
J
Jesse Zhang 已提交
1754

1755
	for (ULONG ul = 0; ul < num_cmp_types; ul++)
J
Jesse Zhang 已提交
1756
	{
1757
		if (0 == strcasecmp(cmp_type, cmp_types_str_arr[ul]))
1758
		{
1759
			return cmp_types[ul];
1760 1761
		}
	}
1762

1763
	GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiInvalidComparisonTypeCode);
1764 1765 1766 1767 1768 1769
	return CmptOther;
}


//---------------------------------------------------------------------------
//	@function:
1770
//		COptTasks::EvalExprFromXML
1771 1772 1773
//
//	@doc:
//		Converts XML string to DXL and evaluates the expression. Caller keeps
1774
//		ownership of 'xml_string' and takes ownership of the returned result.
1775 1776 1777
//
//---------------------------------------------------------------------------
char *
J
Jesse Zhang 已提交
1778
COptTasks::EvalExprFromXML(char *xml_string)
1779
{
1780
	GPOS_ASSERT(NULL != xml_string);
1781 1782

	SEvalExprContext evalctxt;
1783 1784
	evalctxt.m_dxl = xml_string;
	evalctxt.m_dxl_result = NULL;
1785

1786 1787
	Execute(&EvalExprFromDXLTask, &evalctxt);
	return evalctxt.m_dxl_result;
1788 1789 1790 1791 1792
}


//---------------------------------------------------------------------------
//	@function:
1793
//		COptTasks::OptimizeMinidumpFromFile
1794 1795 1796 1797 1798 1799 1800
//
//	@doc:
//		Loads a minidump from the given file path, optimizes it and returns
//		the serialized representation of the result as DXL.
//
//---------------------------------------------------------------------------
char *
J
Jesse Zhang 已提交
1801
COptTasks::OptimizeMinidumpFromFile(char *file_name)
1802
{
1803
	GPOS_ASSERT(NULL != file_name);
1804
	SOptimizeMinidumpContext optmdpctxt;
1805 1806
	optmdpctxt.m_szFileName = file_name;
	optmdpctxt.m_dxl_result = NULL;
1807

1808 1809
	Execute(&OptimizeMinidumpTask, &optmdpctxt);
	return optmdpctxt.m_dxl_result;
1810 1811 1812
}

// EOF