CTranslatorDXLToScalar.cpp 66.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 29 30 31
//---------------------------------------------------------------------------
//	Greenplum Database
//	Copyright (C) 2011 EMC Corp.
//
//	@filename:
//		CTranslatorDXLToScalar.cpp
//
//	@doc:
//		Implementation of the methods used to translate DXL Scalar Node into
//		GPDB's Expr.
//
//	@test:
//---------------------------------------------------------------------------

#include "postgres.h"
#include "nodes/plannodes.h"
#include "nodes/parsenodes.h"
#include "nodes/primnodes.h"
#include "nodes/makefuncs.h"
#include "utils/datum.h"

#include "gpos/base.h"

#include "gpopt/mdcache/CMDAccessor.h"
#include "gpopt/mdcache/CMDAccessorUtils.h"
#include "gpopt/base/COptCtxt.h"
#include "gpopt/translate/CTranslatorDXLToScalar.h"
#include "gpopt/translate/CTranslatorDXLToPlStmt.h"
#include "gpopt/translate/CTranslatorUtils.h"
#include "gpopt/translate/CMappingColIdVarPlStmt.h"

32 33 34 35 36 37 38 39 40 41 42 43 44
#include "naucrates/dxl/CDXLUtils.h"
#include "naucrates/dxl/operators/CDXLDatumBool.h"
#include "naucrates/dxl/operators/CDXLDatumInt2.h"
#include "naucrates/dxl/operators/CDXLDatumInt4.h"
#include "naucrates/dxl/operators/CDXLDatumInt8.h"
#include "naucrates/dxl/operators/CDXLDatumGeneric.h"
#include "naucrates/dxl/operators/CDXLDatumOid.h"
#include "naucrates/dxl/xml/dxltokens.h"

#include "naucrates/md/IMDAggregate.h"
#include "naucrates/md/IMDFunction.h"
#include "naucrates/md/IMDScalarOp.h"
#include "naucrates/md/IMDTypeBool.h"
45 46 47 48 49 50 51

#include "gpopt/gpdbwrappers.h"

using namespace gpdxl;
using namespace gpos;
using namespace gpopt;

52

53 54 55 56 57 58 59
//---------------------------------------------------------------------------
//	@function:
//		CTranslatorDXLToScalar::CTranslatorDXLToScalar
//
//	@doc:
//		Constructor
//---------------------------------------------------------------------------
J
Jesse Zhang 已提交
60 61 62 63 64 65 66
CTranslatorDXLToScalar::CTranslatorDXLToScalar(CMemoryPool *mp,
											   CMDAccessor *md_accessor,
											   ULONG num_segments)
	: m_mp(mp),
	  m_md_accessor(md_accessor),
	  m_has_subqueries(false),
	  m_num_of_segments(num_segments)
67 68 69 70 71
{
}

//---------------------------------------------------------------------------
//	@function:
72
//		CTranslatorDXLToScalar::TranslateDXLToScalar
73 74 75 76 77
//
//	@doc:
//		Translates a DXL scalar expression into a GPDB Expression node
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
78 79
CTranslatorDXLToScalar::TranslateDXLToScalar(const CDXLNode *dxlnode,
											 CMappingColIdVar *colid_var)
80
{
J
Jesse Zhang 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
	static const STranslatorElem translators[] = {
		{EdxlopScalarIdent,
		 &CTranslatorDXLToScalar::TranslateDXLScalarIdentToScalar},
		{EdxlopScalarCmp,
		 &CTranslatorDXLToScalar::TranslateDXLScalarCmpToScalar},
		{EdxlopScalarDistinct,
		 &CTranslatorDXLToScalar::TranslateDXLScalarDistinctToScalar},
		{EdxlopScalarOpExpr,
		 &CTranslatorDXLToScalar::TranslateDXLScalarOpExprToScalar},
		{EdxlopScalarArrayComp,
		 &CTranslatorDXLToScalar::TranslateDXLScalarArrayCompToScalar},
		{EdxlopScalarCoalesce,
		 &CTranslatorDXLToScalar::TranslateDXLScalarCoalesceToScalar},
		{EdxlopScalarMinMax,
		 &CTranslatorDXLToScalar::TranslateDXLScalarMinMaxToScalar},
		{EdxlopScalarConstValue,
		 &CTranslatorDXLToScalar::TranslateDXLScalarConstToScalar},
		{EdxlopScalarBoolExpr,
		 &CTranslatorDXLToScalar::TranslateDXLScalarBoolExprToScalar},
		{EdxlopScalarBooleanTest,
		 &CTranslatorDXLToScalar::TranslateDXLScalarBooleanTestToScalar},
		{EdxlopScalarNullTest,
		 &CTranslatorDXLToScalar::TranslateDXLScalarNullTestToScalar},
		{EdxlopScalarNullIf,
		 &CTranslatorDXLToScalar::TranslateDXLScalarNullIfToScalar},
		{EdxlopScalarIfStmt,
		 &CTranslatorDXLToScalar::TranslateDXLScalarIfStmtToScalar},
		{EdxlopScalarSwitch,
		 &CTranslatorDXLToScalar::TranslateDXLScalarSwitchToScalar},
		{EdxlopScalarCaseTest,
		 &CTranslatorDXLToScalar::TranslateDXLScalarCaseTestToScalar},
		{EdxlopScalarFuncExpr,
		 &CTranslatorDXLToScalar::TranslateDXLScalarFuncExprToScalar},
		{EdxlopScalarAggref,
		 &CTranslatorDXLToScalar::TranslateDXLScalarAggrefToScalar},
		{EdxlopScalarWindowRef,
		 &CTranslatorDXLToScalar::TranslateDXLScalarWindowRefToScalar},
		{EdxlopScalarCast,
		 &CTranslatorDXLToScalar::TranslateDXLScalarCastToScalar},
		{EdxlopScalarCoerceToDomain,
		 &CTranslatorDXLToScalar::TranslateDXLScalarCoerceToDomainToScalar},
		{EdxlopScalarCoerceViaIO,
		 &CTranslatorDXLToScalar::TranslateDXLScalarCoerceViaIOToScalar},
		{EdxlopScalarArrayCoerceExpr,
		 &CTranslatorDXLToScalar::TranslateDXLScalarArrayCoerceExprToScalar},
		{EdxlopScalarSubPlan,
		 &CTranslatorDXLToScalar::TranslateDXLScalarSubplanToScalar},
		{EdxlopScalarArray,
		 &CTranslatorDXLToScalar::TranslateDXLScalarArrayToScalar},
		{EdxlopScalarArrayRef,
		 &CTranslatorDXLToScalar::TranslateDXLScalarArrayRefToScalar},
		{EdxlopScalarDMLAction,
		 &CTranslatorDXLToScalar::TranslateDXLScalarDMLActionToScalar},
		{EdxlopScalarPartDefault,
		 &CTranslatorDXLToScalar::TranslateDXLScalarPartDefaultToScalar},
		{EdxlopScalarPartBound,
		 &CTranslatorDXLToScalar::TranslateDXLScalarPartBoundToScalar},
		{EdxlopScalarPartBoundInclusion,
		 &CTranslatorDXLToScalar::TranslateDXLScalarPartBoundInclusionToScalar},
		{EdxlopScalarPartBoundOpen,
		 &CTranslatorDXLToScalar::TranslateDXLScalarPartBoundOpenToScalar},
		{EdxlopScalarPartListValues,
		 &CTranslatorDXLToScalar::TranslateDXLScalarPartListValuesToScalar},
		{EdxlopScalarPartListNullTest,
		 &CTranslatorDXLToScalar::TranslateDXLScalarPartListNullTestToScalar},
146 147
	};

148
	const ULONG num_translators = GPOS_ARRAY_SIZE(translators);
149

150 151
	GPOS_ASSERT(NULL != dxlnode);
	Edxlopid eopid = dxlnode->GetOperator()->GetDXLOperator();
152 153

	// find translator for the node type
154 155
	expr_func_ptr translate_func = NULL;
	for (ULONG ul = 0; ul < num_translators; ul++)
156
	{
157
		STranslatorElem elem = translators[ul];
158 159
		if (eopid == elem.eopid)
		{
160
			translate_func = elem.translate_func;
161 162 163 164
			break;
		}
	}

165
	if (NULL == translate_func)
166
	{
J
Jesse Zhang 已提交
167 168
		GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXL2PlStmtConversion,
				   dxlnode->GetOperator()->GetOpNameStr()->GetBuffer());
169 170
	}

171
	return (this->*translate_func)(dxlnode, colid_var);
172 173 174 175
}

//---------------------------------------------------------------------------
//	@function:
176
//		CTranslatorDXLToScalar::TranslateDXLScalarIfStmtToScalar
177 178 179 180 181
//
//	@doc:
//		Translates a DXL scalar if stmt into a GPDB CaseExpr node
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
182 183
CTranslatorDXLToScalar::TranslateDXLScalarIfStmtToScalar(
	const CDXLNode *scalar_if_stmt_node, CMappingColIdVar *colid_var)
184
{
185
	GPOS_ASSERT(NULL != scalar_if_stmt_node);
J
Jesse Zhang 已提交
186 187
	CDXLScalarIfStmt *scalar_if_stmt_dxl =
		CDXLScalarIfStmt::Cast(scalar_if_stmt_node->GetOperator());
188

189
	CaseExpr *case_expr = MakeNode(CaseExpr);
J
Jesse Zhang 已提交
190 191
	case_expr->casetype =
		CMDIdGPDB::CastMdid(scalar_if_stmt_dxl->GetResultTypeMdId())->Oid();
192

J
Jesse Zhang 已提交
193
	CDXLNode *curr_node = const_cast<CDXLNode *>(scalar_if_stmt_node);
194
	Expr *else_expr = NULL;
195

D
Daniel Gustafsson 已提交
196 197
	// An If statement is of the format: IF <condition> <then> <else>
	// The leaf else statement is the def result of the case statement
198
	BOOL is_leaf_else_stmt = false;
199

200
	while (!is_leaf_else_stmt)
201
	{
202
		if (3 != curr_node->Arity())
203
		{
J
Jesse Zhang 已提交
204
			GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXLIncorrectNumberOfChildren);
205 206 207
			return NULL;
		}

208 209
		Expr *when_expr = TranslateDXLToScalar((*curr_node)[0], colid_var);
		Expr *then_expr = TranslateDXLToScalar((*curr_node)[1], colid_var);
210

211 212 213
		CaseWhen *case_when = MakeNode(CaseWhen);
		case_when->expr = when_expr;
		case_when->result = then_expr;
J
Jesse Zhang 已提交
214
		case_expr->args = gpdb::LAppend(case_expr->args, case_when);
215

J
Jesse Zhang 已提交
216 217
		if (EdxlopScalarIfStmt ==
			(*curr_node)[2]->GetOperator()->GetDXLOperator())
218
		{
219
			curr_node = (*curr_node)[2];
220 221 222
		}
		else
		{
223 224
			is_leaf_else_stmt = true;
			else_expr = TranslateDXLToScalar((*curr_node)[2], colid_var);
225 226 227
		}
	}

228
	case_expr->defresult = else_expr;
229

J
Jesse Zhang 已提交
230
	return (Expr *) case_expr;
231 232 233 234
}

//---------------------------------------------------------------------------
//	@function:
235
//		CTranslatorDXLToScalar::TranslateDXLScalarSwitchToScalar
236 237 238 239 240
//
//	@doc:
//		Translates a DXL scalar switch into a GPDB CaseExpr node
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
241 242
CTranslatorDXLToScalar::TranslateDXLScalarSwitchToScalar(
	const CDXLNode *scalar_switch_node, CMappingColIdVar *colid_var)
243
{
244
	GPOS_ASSERT(NULL != scalar_switch_node);
J
Jesse Zhang 已提交
245 246
	CDXLScalarSwitch *dxlop =
		CDXLScalarSwitch::Cast(scalar_switch_node->GetOperator());
247

248 249
	CaseExpr *case_expr = MakeNode(CaseExpr);
	case_expr->casetype = CMDIdGPDB::CastMdid(dxlop->MdidType())->Oid();
250 251

	// translate arg child
252 253
	case_expr->arg = TranslateDXLToScalar((*scalar_switch_node)[0], colid_var);
	GPOS_ASSERT(NULL != case_expr->arg);
254

255 256 257
	const ULONG arity = scalar_switch_node->Arity();
	GPOS_ASSERT(1 < arity);
	for (ULONG ul = 1; ul < arity; ul++)
258
	{
259
		const CDXLNode *child_dxl = (*scalar_switch_node)[ul];
260

J
Jesse Zhang 已提交
261 262
		if (EdxlopScalarSwitchCase ==
			child_dxl->GetOperator()->GetDXLOperator())
263
		{
264 265
			CaseWhen *case_when = MakeNode(CaseWhen);
			case_when->expr = TranslateDXLToScalar((*child_dxl)[0], colid_var);
J
Jesse Zhang 已提交
266 267
			case_when->result =
				TranslateDXLToScalar((*child_dxl)[1], colid_var);
268
			case_expr->args = gpdb::LAppend(case_expr->args, case_when);
269 270 271 272
		}
		else
		{
			// default return value
273
			GPOS_ASSERT(ul == arity - 1);
J
Jesse Zhang 已提交
274 275
			case_expr->defresult =
				TranslateDXLToScalar((*scalar_switch_node)[ul], colid_var);
276 277 278
		}
	}

J
Jesse Zhang 已提交
279
	return (Expr *) case_expr;
280 281 282 283
}

//---------------------------------------------------------------------------
//	@function:
284
//		CTranslatorDXLToScalar::TranslateDXLScalarCaseTestToScalar
285 286 287 288 289
//
//	@doc:
//		Translates a DXL scalar case test into a GPDB CaseTestExpr node
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
290
CTranslatorDXLToScalar::TranslateDXLScalarCaseTestToScalar(
291
	const CDXLNode *scalar_case_test_node,
J
Jesse Zhang 已提交
292 293
	CMappingColIdVar *	//colid_var
)
294
{
295
	GPOS_ASSERT(NULL != scalar_case_test_node);
J
Jesse Zhang 已提交
296 297
	CDXLScalarCaseTest *dxlop =
		CDXLScalarCaseTest::Cast(scalar_case_test_node->GetOperator());
298

299 300 301
	CaseTestExpr *case_test_expr = MakeNode(CaseTestExpr);
	case_test_expr->typeId = CMDIdGPDB::CastMdid(dxlop->MdidType())->Oid();
	case_test_expr->typeMod = -1;
302

J
Jesse Zhang 已提交
303
	return (Expr *) case_test_expr;
304 305 306 307
}

//---------------------------------------------------------------------------
//	@function:
308
//		CTranslatorDXLToScalar::TranslateDXLScalarOpExprToScalar
309 310 311 312 313
//
//	@doc:
//		Translates a DXL scalar opexpr into a GPDB OpExpr node
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
314 315
CTranslatorDXLToScalar::TranslateDXLScalarOpExprToScalar(
	const CDXLNode *scalar_op_expr_node, CMappingColIdVar *colid_var)
316
{
317
	GPOS_ASSERT(NULL != scalar_op_expr_node);
J
Jesse Zhang 已提交
318 319
	CDXLScalarOpExpr *scalar_op_expr_dxl =
		CDXLScalarOpExpr::Cast(scalar_op_expr_node->GetOperator());
320

321 322
	OpExpr *op_expr = MakeNode(OpExpr);
	op_expr->opno = CMDIdGPDB::CastMdid(scalar_op_expr_dxl->MDId())->Oid();
323

J
Jesse Zhang 已提交
324 325
	const IMDScalarOp *md_scalar_op =
		m_md_accessor->RetrieveScOp(scalar_op_expr_dxl->MDId());
326 327 328 329
	op_expr->opfuncid = CMDIdGPDB::CastMdid(md_scalar_op->FuncMdId())->Oid();

	IMDId *return_type_mdid = scalar_op_expr_dxl->GetReturnTypeMdId();
	if (NULL != return_type_mdid)
330
	{
331
		op_expr->opresulttype = CMDIdGPDB::CastMdid(return_type_mdid)->Oid();
332
	}
J
Jesse Zhang 已提交
333
	else
334
	{
J
Jesse Zhang 已提交
335 336
		op_expr->opresulttype =
			GetFunctionReturnTypeOid(md_scalar_op->FuncMdId());
337 338
	}

J
Jesse Zhang 已提交
339 340
	const IMDFunction *md_func =
		m_md_accessor->RetrieveFunc(md_scalar_op->FuncMdId());
341
	op_expr->opretset = md_func->ReturnsSet();
342

J
Jesse Zhang 已提交
343 344
	GPOS_ASSERT(1 == scalar_op_expr_node->Arity() ||
				2 == scalar_op_expr_node->Arity());
345 346

	// translate children
J
Jesse Zhang 已提交
347 348
	op_expr->args =
		TranslateScalarChildren(op_expr->args, scalar_op_expr_node, colid_var);
349

J
Jesse Zhang 已提交
350
	return (Expr *) op_expr;
351 352 353 354
}

//---------------------------------------------------------------------------
//	@function:
355
//		CTranslatorDXLToScalar::TranslateDXLScalarArrayCompToScalar
356 357 358 359 360 361
//
//	@doc:
//		Translates a CDXLScalarArrayComp into a GPDB ScalarArrayOpExpr
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
362 363
CTranslatorDXLToScalar::TranslateDXLScalarArrayCompToScalar(
	const CDXLNode *scalar_array_comp_node, CMappingColIdVar *colid_var)
364
{
365
	GPOS_ASSERT(NULL != scalar_array_comp_node);
J
Jesse Zhang 已提交
366 367
	CDXLScalarArrayComp *array_comp_dxl =
		CDXLScalarArrayComp::Cast(scalar_array_comp_node->GetOperator());
368

369 370
	ScalarArrayOpExpr *array_op_expr = MakeNode(ScalarArrayOpExpr);
	array_op_expr->opno = CMDIdGPDB::CastMdid(array_comp_dxl->MDId())->Oid();
J
Jesse Zhang 已提交
371 372 373 374
	const IMDScalarOp *md_scalar_op =
		m_md_accessor->RetrieveScOp(array_comp_dxl->MDId());
	array_op_expr->opfuncid =
		CMDIdGPDB::CastMdid(md_scalar_op->FuncMdId())->Oid();
375

J
Jesse Zhang 已提交
376
	switch (array_comp_dxl->GetDXLArrayCmpType())
377 378
	{
		case Edxlarraycomptypeany:
J
Jesse Zhang 已提交
379 380
			array_op_expr->useOr = true;
			break;
381 382

		case Edxlarraycomptypeall:
J
Jesse Zhang 已提交
383 384
			array_op_expr->useOr = false;
			break;
385 386

		default:
J
Jesse Zhang 已提交
387 388 389 390
			GPOS_RAISE(
				gpdxl::ExmaDXL, gpdxl::ExmiPlStmt2DXLConversion,
				GPOS_WSZ_LIT(
					"Scalar Array Comparison: Specified operator type is invalid"));
391 392 393 394
	}

	// translate left and right child

395
	GPOS_ASSERT(2 == scalar_array_comp_node->Arity());
396

397 398
	CDXLNode *left_node = (*scalar_array_comp_node)[EdxlsccmpIndexLeft];
	CDXLNode *right_node = (*scalar_array_comp_node)[EdxlsccmpIndexRight];
399

400 401
	Expr *left_expr = TranslateDXLToScalar(left_node, colid_var);
	Expr *right_expr = TranslateDXLToScalar(right_node, colid_var);
402

403
	array_op_expr->args = ListMake2(left_expr, right_expr);
404

J
Jesse Zhang 已提交
405
	return (Expr *) array_op_expr;
406 407 408 409
}

//---------------------------------------------------------------------------
//	@function:
410
//		CTranslatorDXLToScalar::TranslateDXLScalarDistinctToScalar
411 412 413 414 415 416
//
//	@doc:
//		Translates a DXL scalar distinct comparison into a GPDB DistinctExpr node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
417 418
CTranslatorDXLToScalar::TranslateDXLScalarDistinctToScalar(
	const CDXLNode *scalar_distinct_cmp_node, CMappingColIdVar *colid_var)
419
{
420
	GPOS_ASSERT(NULL != scalar_distinct_cmp_node);
J
Jesse Zhang 已提交
421 422
	CDXLScalarDistinctComp *dxlop =
		CDXLScalarDistinctComp::Cast(scalar_distinct_cmp_node->GetOperator());
423

424 425
	DistinctExpr *dist_expr = MakeNode(DistinctExpr);
	dist_expr->opno = CMDIdGPDB::CastMdid(dxlop->MDId())->Oid();
426

J
Jesse Zhang 已提交
427 428
	const IMDScalarOp *md_scalar_op =
		m_md_accessor->RetrieveScOp(dxlop->MDId());
429

430
	dist_expr->opfuncid = CMDIdGPDB::CastMdid(md_scalar_op->FuncMdId())->Oid();
J
Jesse Zhang 已提交
431 432
	dist_expr->opresulttype =
		GetFunctionReturnTypeOid(md_scalar_op->FuncMdId());
433 434

	// translate left and right child
435 436 437
	GPOS_ASSERT(2 == scalar_distinct_cmp_node->Arity());
	CDXLNode *left_node = (*scalar_distinct_cmp_node)[EdxlscdistcmpIndexLeft];
	CDXLNode *right_node = (*scalar_distinct_cmp_node)[EdxlscdistcmpIndexRight];
438

439 440
	Expr *left_expr = TranslateDXLToScalar(left_node, colid_var);
	Expr *right_expr = TranslateDXLToScalar(right_node, colid_var);
441

442
	dist_expr->args = ListMake2(left_expr, right_expr);
443

J
Jesse Zhang 已提交
444
	return (Expr *) dist_expr;
445 446 447 448
}

//---------------------------------------------------------------------------
//	@function:
449
//		CTranslatorDXLToScalar::TranslateDXLScalarAggrefToScalar
450 451
//
//	@doc:
452
//		Translates a DXL scalar aggref_node into a GPDB Aggref node
453 454 455
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
456 457
CTranslatorDXLToScalar::TranslateDXLScalarAggrefToScalar(
	const CDXLNode *aggref_node, CMappingColIdVar *colid_var)
458
{
459
	GPOS_ASSERT(NULL != aggref_node);
J
Jesse Zhang 已提交
460 461
	CDXLScalarAggref *dxlop =
		CDXLScalarAggref::Cast(aggref_node->GetOperator());
462

463 464 465 466 467
	Aggref *aggref = MakeNode(Aggref);
	aggref->aggfnoid = CMDIdGPDB::CastMdid(dxlop->GetDXLAggFuncMDid())->Oid();
	aggref->aggdistinct = dxlop->IsDistinct();
	aggref->agglevelsup = 0;
	aggref->location = -1;
468

469 470 471
	CMDIdGPDB *agg_mdid = GPOS_NEW(m_mp) CMDIdGPDB(aggref->aggfnoid);
	const IMDAggregate *pmdagg = m_md_accessor->RetrieveAgg(agg_mdid);
	agg_mdid->Release();
472

473 474
	EdxlAggrefStage edxlaggstage = dxlop->GetDXLAggStage();
	if (NULL != dxlop->GetDXLResolvedRetTypeMDid())
475 476
	{
		// use resolved type
J
Jesse Zhang 已提交
477 478
		aggref->aggtype =
			CMDIdGPDB::CastMdid(dxlop->GetDXLResolvedRetTypeMDid())->Oid();
479
	}
J
Jesse Zhang 已提交
480 481
	else if (EdxlaggstageIntermediate == edxlaggstage ||
			 EdxlaggstagePartial == edxlaggstage)
482
	{
J
Jesse Zhang 已提交
483 484
		aggref->aggtype =
			CMDIdGPDB::CastMdid(pmdagg->GetIntermediateResultTypeMdid())->Oid();
485 486 487
	}
	else
	{
J
Jesse Zhang 已提交
488 489
		aggref->aggtype =
			CMDIdGPDB::CastMdid(pmdagg->GetResultTypeMdid())->Oid();
490 491
	}

J
Jesse Zhang 已提交
492
	switch (dxlop->GetDXLAggStage())
493 494
	{
		case EdxlaggstageNormal:
J
Jesse Zhang 已提交
495 496
			aggref->aggstage = AGGSTAGE_NORMAL;
			break;
497
		case EdxlaggstagePartial:
J
Jesse Zhang 已提交
498 499
			aggref->aggstage = AGGSTAGE_PARTIAL;
			break;
500
		case EdxlaggstageIntermediate:
J
Jesse Zhang 已提交
501 502
			aggref->aggstage = AGGSTAGE_INTERMEDIATE;
			break;
503
		case EdxlaggstageFinal:
J
Jesse Zhang 已提交
504 505
			aggref->aggstage = AGGSTAGE_FINAL;
			break;
506
		default:
J
Jesse Zhang 已提交
507 508 509
			GPOS_RAISE(
				gpdxl::ExmaDXL, gpdxl::ExmiPlStmt2DXLConversion,
				GPOS_WSZ_LIT("AGGREF: Specified AggStage value is invalid"));
510 511 512
	}

	// translate each DXL argument
J
Jesse Zhang 已提交
513 514
	aggref->args =
		TranslateScalarChildren(aggref->args, aggref_node, colid_var);
515

J
Jesse Zhang 已提交
516
	return (Expr *) aggref;
517 518 519 520
}

//---------------------------------------------------------------------------
//	@function:
521
//		CTranslatorDXLToScalar::TranslateDXLScalarWindowRefToScalar
522 523 524 525 526 527
//
//	@doc:
//		Translate a DXL scalar window ref into a GPDB WindowRef node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
528 529
CTranslatorDXLToScalar::TranslateDXLScalarWindowRefToScalar(
	const CDXLNode *scalar_winref_node, CMappingColIdVar *colid_var)
530
{
531
	GPOS_ASSERT(NULL != scalar_winref_node);
J
Jesse Zhang 已提交
532 533
	CDXLScalarWindowRef *dxlop =
		CDXLScalarWindowRef::Cast(scalar_winref_node->GetOperator());
534 535

	WindowRef *pwindowref = MakeNode(WindowRef);
536 537
	pwindowref->winfnoid = CMDIdGPDB::CastMdid(dxlop->FuncMdId())->Oid();
	pwindowref->windistinct = dxlop->IsDistinct();
538 539
	pwindowref->location = -1;
	pwindowref->winlevel = 0;
540 541
	pwindowref->winspec = dxlop->GetWindSpecPos();
	pwindowref->restype = CMDIdGPDB::CastMdid(dxlop->ReturnTypeMdId())->Oid();
542

543 544
	EdxlWinStage dxl_win_stage = dxlop->GetDxlWinStage();
	GPOS_ASSERT(dxl_win_stage != EdxlwinstageSentinel);
545

J
Jesse Zhang 已提交
546 547 548 549 550
	ULONG mapping[][2] = {
		{WINSTAGE_IMMEDIATE, EdxlwinstageImmediate},
		{WINSTAGE_PRELIMINARY, EdxlwinstagePreliminary},
		{WINSTAGE_ROWKEY, EdxlwinstageRowKey},
	};
551

552 553
	const ULONG arity = GPOS_ARRAY_SIZE(mapping);
	for (ULONG ul = 0; ul < arity; ul++)
554
	{
555 556
		ULONG *elem = mapping[ul];
		if ((ULONG) dxl_win_stage == elem[1])
557
		{
558
			pwindowref->winstage = (WinStage) elem[0];
559 560 561 562 563
			break;
		}
	}

	// translate the arguments of the window function
J
Jesse Zhang 已提交
564 565
	pwindowref->args = TranslateScalarChildren(pwindowref->args,
											   scalar_winref_node, colid_var);
566 567 568 569 570 571

	return (Expr *) pwindowref;
}

//---------------------------------------------------------------------------
//	@function:
572
//		CTranslatorDXLToScalar::TranslateDXLScalarFuncExprToScalar
573 574 575 576 577 578
//
//	@doc:
//		Translates a DXL scalar opexpr into a GPDB FuncExpr node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
579 580
CTranslatorDXLToScalar::TranslateDXLScalarFuncExprToScalar(
	const CDXLNode *scalar_func_expr_node, CMappingColIdVar *colid_var)
581
{
582
	GPOS_ASSERT(NULL != scalar_func_expr_node);
J
Jesse Zhang 已提交
583 584
	CDXLScalarFuncExpr *dxlop =
		CDXLScalarFuncExpr::Cast(scalar_func_expr_node->GetOperator());
585

586 587 588 589
	FuncExpr *func_expr = MakeNode(FuncExpr);
	func_expr->funcid = CMDIdGPDB::CastMdid(dxlop->FuncMdId())->Oid();
	func_expr->funcretset = dxlop->ReturnsSet();
	func_expr->funcformat = COERCE_DONTCARE;
J
Jesse Zhang 已提交
590 591 592 593
	func_expr->funcresulttype =
		CMDIdGPDB::CastMdid(dxlop->ReturnTypeMdId())->Oid();
	func_expr->args = TranslateScalarChildren(func_expr->args,
											  scalar_func_expr_node, colid_var);
594

595
	return (Expr *) func_expr;
596 597 598 599
}

//---------------------------------------------------------------------------
//	@function:
600
//		CTranslatorDXLToScalar::TranslateDXLScalarSubplanToScalar
601 602 603 604 605 606
//
//	@doc:
//		Translates a DXL scalar SubPlan into a GPDB SubPlan node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
607 608
CTranslatorDXLToScalar::TranslateDXLScalarSubplanToScalar(
	const CDXLNode *scalar_subplan_node, CMappingColIdVar *colid_var)
609
{
J
Jesse Zhang 已提交
610 611
	CDXLTranslateContext *output_context =
		(dynamic_cast<CMappingColIdVarPlStmt *>(colid_var))->GetOutputContext();
612

J
Jesse Zhang 已提交
613 614 615
	CContextDXLToPlStmt *dxl_to_plstmt_ctxt =
		(dynamic_cast<CMappingColIdVarPlStmt *>(colid_var))
			->GetDXLToPlStmtContext();
616

J
Jesse Zhang 已提交
617 618
	CDXLScalarSubPlan *dxlop =
		CDXLScalarSubPlan::Cast(scalar_subplan_node->GetOperator());
619

620
	// translate subplan test expression
621
	List *param_ids = NIL;
622

J
Jesse Zhang 已提交
623 624 625 626
	SubLinkType slink = CTranslatorUtils::MapDXLSubplanToSublinkType(
		dxlop->GetDxlSubplanType());
	Expr *test_expr = TranslateDXLSubplanTestExprToScalar(
		dxlop->GetDxlTestExpr(), slink, colid_var, &param_ids);
627

J
Jesse Zhang 已提交
628
	const CDXLColRefArray *outer_refs = dxlop->GetDxlOuterColRefsArray();
629

630
	const ULONG len = outer_refs->Size();
631

632
	// Translate a copy of the translate context: the param mappings from the outer scope get copied in the constructor
J
Jesse Zhang 已提交
633 634 635
	CDXLTranslateContext subplan_translate_ctxt(
		m_mp, output_context->IsParentAggNode(),
		output_context->GetColIdToParamIdMap());
636

637
	// insert new outer ref mappings in the subplan translate context
638
	for (ULONG ul = 0; ul < len; ul++)
639
	{
640 641 642 643
		CDXLColRef *dxl_colref = (*outer_refs)[ul];
		IMDId *mdid = dxl_colref->MdidType();
		ULONG colid = dxl_colref->Id();
		INT type_modifier = dxl_colref->TypeModifier();
644

645
		if (NULL == subplan_translate_ctxt.GetParamIdMappingElement(colid))
646 647
		{
			// keep outer reference mapping to the original column for subsequent subplans
J
Jesse Zhang 已提交
648 649 650 651
			CMappingElementColIdParamId *colid_to_param_id_map =
				GPOS_NEW(m_mp) CMappingElementColIdParamId(
					colid, dxl_to_plstmt_ctxt->GetNextParamId(), mdid,
					type_modifier);
652

653
#ifdef GPOS_DEBUG
654
			BOOL is_inserted =
655
#endif
J
Jesse Zhang 已提交
656 657
				subplan_translate_ctxt.FInsertParamMapping(
					colid, colid_to_param_id_map);
658
			GPOS_ASSERT(is_inserted);
659 660 661
		}
	}

662
	CDXLNode *child_dxl = (*scalar_subplan_node)[0];
J
Jesse Zhang 已提交
663 664
	GPOS_ASSERT(EdxloptypePhysical ==
				child_dxl->GetOperator()->GetDXLOperatorType());
665

666
	GPOS_ASSERT(NULL != scalar_subplan_node);
J
Jesse Zhang 已提交
667 668
	GPOS_ASSERT(EdxlopScalarSubPlan ==
				scalar_subplan_node->GetOperator()->GetDXLOperator());
669
	GPOS_ASSERT(1 == scalar_subplan_node->Arity());
670 671

	// generate the child plan,
672
	// Translate DXL->PlStmt translator to handle subplan's relational children
J
Jesse Zhang 已提交
673 674 675 676 677 678 679 680 681
	CTranslatorDXLToPlStmt dxl_to_plstmt_translator(
		m_mp, m_md_accessor,
		(dynamic_cast<CMappingColIdVarPlStmt *>(colid_var))
			->GetDXLToPlStmtContext(),
		m_num_of_segments);
	CDXLTranslationContextArray *prev_siblings_ctxt_arr =
		GPOS_NEW(m_mp) CDXLTranslationContextArray(m_mp);
	Plan *plan_child = dxl_to_plstmt_translator.TranslateDXLOperatorToPlan(
		child_dxl, &subplan_translate_ctxt, prev_siblings_ctxt_arr);
682
	prev_siblings_ctxt_arr->Release();
683

J
Jesse Zhang 已提交
684 685
	GPOS_ASSERT(NULL != plan_child->targetlist &&
				1 <= gpdb::ListLength(plan_child->targetlist));
686 687

	// translate subplan and set test expression
J
Jesse Zhang 已提交
688 689
	SubPlan *subplan =
		TranslateSubplanFromChildPlan(plan_child, slink, dxl_to_plstmt_ctxt);
690 691
	subplan->testexpr = (Node *) test_expr;
	subplan->paramIds = param_ids;
692 693

	// translate other subplan params
J
Jesse Zhang 已提交
694 695
	TranslateSubplanParams(subplan, &subplan_translate_ctxt, outer_refs,
						   colid_var);
696

J
Jesse Zhang 已提交
697
	return (Expr *) subplan;
698 699
}

J
Jesse Zhang 已提交
700 701
inline BOOL
FDXLCastedId(CDXLNode *dxl_node)
702
{
703
	return EdxlopScalarCast == dxl_node->GetOperator()->GetDXLOperator() &&
J
Jesse Zhang 已提交
704 705
		   dxl_node->Arity() > 0 &&
		   EdxlopScalarIdent == (*dxl_node)[0]->GetOperator()->GetDXLOperator();
706 707
}

J
Jesse Zhang 已提交
708 709
inline CTranslatorDXLToScalar::STypeOidAndTypeModifier
OidParamOidFromDXLIdentOrDXLCastIdent(CDXLNode *ident_or_cast_ident_node)
710
{
J
Jesse Zhang 已提交
711 712 713
	GPOS_ASSERT(EdxlopScalarIdent ==
					ident_or_cast_ident_node->GetOperator()->GetDXLOperator() ||
				FDXLCastedId(ident_or_cast_ident_node));
714

715
	CDXLScalarIdent *inner_ident;
J
Jesse Zhang 已提交
716 717
	if (EdxlopScalarIdent ==
		ident_or_cast_ident_node->GetOperator()->GetDXLOperator())
718
	{
J
Jesse Zhang 已提交
719 720
		inner_ident =
			CDXLScalarIdent::Cast(ident_or_cast_ident_node->GetOperator());
721 722 723
	}
	else
	{
J
Jesse Zhang 已提交
724 725
		inner_ident = CDXLScalarIdent::Cast(
			(*ident_or_cast_ident_node)[0]->GetOperator());
726
	}
727 728
	Oid inner_type_oid = CMDIdGPDB::CastMdid(inner_ident->MdidType())->Oid();
	INT type_modifier = inner_ident->TypeModifier();
729

J
Jesse Zhang 已提交
730 731
	CTranslatorDXLToScalar::STypeOidAndTypeModifier modifier = {inner_type_oid,
																type_modifier};
732
	return modifier;
733
}
734 735 736

//---------------------------------------------------------------------------
//      @function:
737
//              CTranslatorDXLToScalar::TranslateDXLSubplanTestExprToScalar
738 739 740 741 742 743
//
//      @doc:
//              Translate subplan test expression
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
744 745 746
CTranslatorDXLToScalar::TranslateDXLSubplanTestExprToScalar(
	CDXLNode *test_expr_node, SubLinkType slink, CMappingColIdVar *colid_var,
	List **param_ids)
747
{
J
Jesse Zhang 已提交
748 749
	if (EXPR_SUBLINK == slink || EXISTS_SUBLINK == slink ||
		NOT_EXISTS_SUBLINK == slink)
750 751 752 753
	{
		// expr/exists/not-exists sublinks have no test expression
		return NULL;
	}
754
	GPOS_ASSERT(NULL != test_expr_node);
755

756
	if (HasConstTrue(test_expr_node, m_md_accessor))
757 758
	{
		// dummy test expression
759
		return (Expr *) TranslateDXLScalarConstToScalar(test_expr_node, NULL);
760 761
	}

762
	if (EdxlopScalarCmp != test_expr_node->GetOperator()->GetDXLOperator())
763 764
	{
		// test expression is expected to be a comparison
J
Jesse Zhang 已提交
765 766
		GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXL2PlStmtConversion,
				   GPOS_WSZ_LIT("Unexpected subplan test expression"));
767 768
	}

769
	GPOS_ASSERT(2 == test_expr_node->Arity());
770 771
	GPOS_ASSERT(ANY_SUBLINK == slink || ALL_SUBLINK == slink);

772 773
	CDXLNode *outer_child_node = (*test_expr_node)[0];
	CDXLNode *inner_child_node = (*test_expr_node)[1];
774

J
Jesse Zhang 已提交
775 776 777
	if (EdxlopScalarIdent !=
			inner_child_node->GetOperator()->GetDXLOperator() &&
		!FDXLCastedId(inner_child_node))
778
	{
J
Jesse Zhang 已提交
779
		// test expression is expected to be a comparison between an outer expression
780
		// and a scalar identifier from subplan child
781 782
		// ORCA currently only supports PARAMs on the inner side of the form id or cast(id)
		// The outer side may be any non-param thing.
J
Jesse Zhang 已提交
783 784
		GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXL2PlStmtConversion,
				   GPOS_WSZ_LIT("Unsupported subplan test expression"));
785 786 787
	}

	// extract type of inner column
J
Jesse Zhang 已提交
788 789
	CDXLScalarComp *scalar_cmp_dxl =
		CDXLScalarComp::Cast(test_expr_node->GetOperator());
790

J
Jesse Zhang 已提交
791 792 793 794 795 796 797 798 799 800
	// create an OpExpr for subplan test expression
	OpExpr *op_expr = MakeNode(OpExpr);
	op_expr->opno = CMDIdGPDB::CastMdid(scalar_cmp_dxl->MDId())->Oid();
	const IMDScalarOp *md_scalar_op =
		m_md_accessor->RetrieveScOp(scalar_cmp_dxl->MDId());
	op_expr->opfuncid = CMDIdGPDB::CastMdid(md_scalar_op->FuncMdId())->Oid();
	op_expr->opresulttype =
		CMDIdGPDB::CastMdid(m_md_accessor->PtMDType<IMDTypeBool>()->MDId())
			->Oid();
	op_expr->opretset = false;
801

J
Jesse Zhang 已提交
802 803
	// translate outer expression (can be a deep scalar tree)
	Expr *outer_arg_expr = TranslateDXLToScalar(outer_child_node, colid_var);
804

J
Jesse Zhang 已提交
805 806 807
	// add translated outer expression as first arg of OpExpr
	List *args = NIL;
	args = gpdb::LAppend(args, outer_arg_expr);
808 809

	// second arg must be an EXEC param which is replaced during query execution with subplan output
810 811
	Param *param = MakeNode(Param);
	param->paramkind = PARAM_EXEC;
J
Jesse Zhang 已提交
812 813 814
	CContextDXLToPlStmt *dxl_to_plstmt_ctxt =
		(dynamic_cast<CMappingColIdVarPlStmt *>(colid_var))
			->GetDXLToPlStmtContext();
815
	param->paramid = dxl_to_plstmt_ctxt->GetNextParamId();
J
Jesse Zhang 已提交
816 817
	CTranslatorDXLToScalar::STypeOidAndTypeModifier oidAndTypeModifier =
		OidParamOidFromDXLIdentOrDXLCastIdent(inner_child_node);
818 819
	param->paramtype = oidAndTypeModifier.oid_type;
	param->paramtypmod = oidAndTypeModifier.type_modifier;
820 821 822 823

	// test expression is used for non-scalar subplan,
	// second arg of test expression must be an EXEC param referring to subplan output,
	// we add this param to subplan param ids before translating other params
824

825
	*param_ids = gpdb::LAppendInt(*param_ids, param->paramid);
826

827
	if (EdxlopScalarIdent == inner_child_node->GetOperator()->GetDXLOperator())
828
	{
829
		args = gpdb::LAppend(args, param);
830
	}
J
Jesse Zhang 已提交
831
	else  // we have a cast
832
	{
J
Jesse Zhang 已提交
833 834 835 836
		CDXLScalarCast *scalar_cast =
			CDXLScalarCast::Cast(inner_child_node->GetOperator());
		Expr *pexprCastParam =
			TranslateRelabelTypeOrFuncExprFromDXL(scalar_cast, (Expr *) param);
837
		args = gpdb::LAppend(args, pexprCastParam);
838
	}
839
	op_expr->args = args;
840

841
	return (Expr *) op_expr;
842 843 844 845 846 847 848 849 850 851 852 853
}


//---------------------------------------------------------------------------
//      @function:
//              CTranslatorDXLToScalar::TranslateSubplanParams
//
//      @doc:
//              Translate subplan parameters
//
//---------------------------------------------------------------------------
void
J
Jesse Zhang 已提交
854 855 856
CTranslatorDXLToScalar::TranslateSubplanParams(
	SubPlan *subplan, CDXLTranslateContext *dxl_translator_ctxt,
	const CDXLColRefArray *outer_refs, CMappingColIdVar *colid_var)
857
{
858 859 860 861
	GPOS_ASSERT(NULL != subplan);
	GPOS_ASSERT(NULL != dxl_translator_ctxt);
	GPOS_ASSERT(NULL != outer_refs);
	GPOS_ASSERT(NULL != colid_var);
862 863

	// Create the PARAM and ARG nodes
864 865
	const ULONG size = outer_refs->Size();
	for (ULONG ul = 0; ul < size; ul++)
866
	{
867 868
		CDXLColRef *dxl_colref = (*outer_refs)[ul];
		dxl_colref->AddRef();
J
Jesse Zhang 已提交
869 870
		const CMappingElementColIdParamId *colid_to_param_id_map =
			dxl_translator_ctxt->GetParamIdMappingElement(dxl_colref->Id());
871

872 873 874
		// TODO: eliminate param, it's not *really* used, and it's (short-term) leaked
		Param *param = TranslateParamFromMapping(colid_to_param_id_map);
		subplan->parParam = gpdb::LAppendInt(subplan->parParam, param->paramid);
875

J
Jesse Zhang 已提交
876 877
		GPOS_ASSERT(
			colid_to_param_id_map->MdidType()->Equals(dxl_colref->MdidType()));
878

J
Jesse Zhang 已提交
879 880
		CDXLScalarIdent *scalar_ident_dxl =
			GPOS_NEW(m_mp) CDXLScalarIdent(m_mp, dxl_colref);
881
		Expr *arg = (Expr *) colid_var->VarFromDXLNodeScId(scalar_ident_dxl);
882 883

		// not found in mapping, it must be an external parameter
884
		if (NULL == arg)
885
		{
J
Jesse Zhang 已提交
886
			arg = (Expr *) TranslateParamFromMapping(colid_to_param_id_map);
887
			GPOS_ASSERT(NULL != arg);
888 889
		}

890 891
		scalar_ident_dxl->Release();
		subplan->args = gpdb::LAppend(subplan->args, arg);
892
	}
893 894 895 896
}

//---------------------------------------------------------------------------
//	@function:
897
//		CTranslatorDXLToScalar::TranslateSubplanFromChildPlan
898 899 900 901 902 903
//
//	@doc:
//		add child plan to translation context, and build a subplan from it
//
//---------------------------------------------------------------------------
SubPlan *
J
Jesse Zhang 已提交
904 905
CTranslatorDXLToScalar::TranslateSubplanFromChildPlan(
	Plan *plan, SubLinkType slink, CContextDXLToPlStmt *dxl_to_plstmt_ctxt)
906
{
907 908 909
	dxl_to_plstmt_ctxt->AddSubplan(plan);

	SubPlan *subplan = MakeNode(SubPlan);
J
Jesse Zhang 已提交
910 911
	subplan->plan_id =
		gpdb::ListLength(dxl_to_plstmt_ctxt->GetSubplanEntriesList());
912 913
	subplan->plan_name = GetSubplanAlias(subplan->plan_id);
	subplan->is_initplan = false;
J
Jesse Zhang 已提交
914 915
	subplan->firstColType = gpdb::ExprType(
		(Node *) ((TargetEntry *) gpdb::ListNth(plan->targetlist, 0))->expr);
916 917 918 919 920 921
	subplan->firstColTypmod = -1;
	subplan->subLinkType = slink;
	subplan->is_multirow = false;
	subplan->unknownEqFalse = false;

	return subplan;
922 923 924 925
}

//---------------------------------------------------------------------------
//	@function:
926
//		CTranslatorDXLToScalar::GetSubplanAlias
927 928 929 930 931 932
//
//	@doc:
//		build plan name, for explain purposes
//
//---------------------------------------------------------------------------
CHAR *
J
Jesse Zhang 已提交
933
CTranslatorDXLToScalar::GetSubplanAlias(ULONG plan_id)
934
{
935 936 937
	CWStringDynamic *plan_name = GPOS_NEW(m_mp) CWStringDynamic(m_mp);
	plan_name->AppendFormat(GPOS_WSZ_LIT("SubPlan %d"), plan_id);
	const WCHAR *buf = plan_name->GetBuffer();
938

939 940
	ULONG max_length = (GPOS_WSZ_LENGTH(buf) + 1) * GPOS_SIZEOF(WCHAR);
	CHAR *result_plan_name = (CHAR *) gpdb::GPDBAlloc(max_length);
J
Jesse Zhang 已提交
941 942
	gpos::clib::Wcstombs(result_plan_name, const_cast<WCHAR *>(buf),
						 max_length);
943 944
	result_plan_name[max_length - 1] = '\0';
	GPOS_DELETE(plan_name);
945

946
	return result_plan_name;
947 948 949 950
}

//---------------------------------------------------------------------------
//	@function:
951
//		CTranslatorDXLToScalar::TranslateParamFromMapping
952 953
//
//	@doc:
954
//		Translates a GPDB param from the given mapping
955 956 957
//
//---------------------------------------------------------------------------
Param *
J
Jesse Zhang 已提交
958 959
CTranslatorDXLToScalar::TranslateParamFromMapping(
	const CMappingElementColIdParamId *colid_to_param_id_map)
960
{
961 962 963
	Param *param = MakeNode(Param);
	param->paramid = colid_to_param_id_map->ParamId();
	param->paramkind = PARAM_EXEC;
J
Jesse Zhang 已提交
964 965
	param->paramtype =
		CMDIdGPDB::CastMdid(colid_to_param_id_map->MdidType())->Oid();
966
	param->paramtypmod = colid_to_param_id_map->TypeModifier();
967

968
	return param;
969 970 971 972 973
}


//---------------------------------------------------------------------------
//	@function:
974
//		CTranslatorDXLToScalar::TranslateDXLScalarBoolExprToScalar
975 976 977 978 979 980
//
//	@doc:
//		Translates a DXL scalar BoolExpr into a GPDB OpExpr node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
981 982
CTranslatorDXLToScalar::TranslateDXLScalarBoolExprToScalar(
	const CDXLNode *scalar_bool_expr_node, CMappingColIdVar *colid_var)
983
{
984
	GPOS_ASSERT(NULL != scalar_bool_expr_node);
J
Jesse Zhang 已提交
985 986
	CDXLScalarBoolExpr *dxlop =
		CDXLScalarBoolExpr::Cast(scalar_bool_expr_node->GetOperator());
987
	BoolExpr *scalar_bool_expr = MakeNode(BoolExpr);
988

989 990
	GPOS_ASSERT(1 <= scalar_bool_expr_node->Arity());
	switch (dxlop->GetDxlBoolTypeStr())
991 992 993
	{
		case Edxlnot:
		{
994 995
			GPOS_ASSERT(1 == scalar_bool_expr_node->Arity());
			scalar_bool_expr->boolop = NOT_EXPR;
996 997 998 999
			break;
		}
		case Edxland:
		{
1000 1001
			GPOS_ASSERT(2 <= scalar_bool_expr_node->Arity());
			scalar_bool_expr->boolop = AND_EXPR;
1002 1003 1004 1005
			break;
		}
		case Edxlor:
		{
1006 1007
			GPOS_ASSERT(2 <= scalar_bool_expr_node->Arity());
			scalar_bool_expr->boolop = OR_EXPR;
1008 1009 1010 1011 1012 1013 1014 1015 1016
			break;
		}
		default:
		{
			GPOS_ASSERT(!"Boolean Operation: Must be either or/ and / not");
			return NULL;
		}
	}

J
Jesse Zhang 已提交
1017 1018
	scalar_bool_expr->args = TranslateScalarChildren(
		scalar_bool_expr->args, scalar_bool_expr_node, colid_var);
1019
	scalar_bool_expr->location = -1;
1020

J
Jesse Zhang 已提交
1021
	return (Expr *) scalar_bool_expr;
1022 1023 1024 1025
}

//---------------------------------------------------------------------------
//	@function:
1026
//		CTranslatorDXLToScalar::TranslateDXLScalarBooleanTestToScalar
1027 1028 1029 1030 1031 1032
//
//	@doc:
//		Translates a DXL scalar BooleanTest into a GPDB OpExpr node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1033 1034
CTranslatorDXLToScalar::TranslateDXLScalarBooleanTestToScalar(
	const CDXLNode *scalar_boolean_test_node, CMappingColIdVar *colid_var)
1035
{
1036
	GPOS_ASSERT(NULL != scalar_boolean_test_node);
J
Jesse Zhang 已提交
1037 1038
	CDXLScalarBooleanTest *dxlop =
		CDXLScalarBooleanTest::Cast(scalar_boolean_test_node->GetOperator());
1039
	BooleanTest *scalar_boolean_test = MakeNode(BooleanTest);
1040

1041
	switch (dxlop->GetDxlBoolTypeStr())
1042 1043
	{
		case EdxlbooleantestIsTrue:
J
Jesse Zhang 已提交
1044 1045
			scalar_boolean_test->booltesttype = IS_TRUE;
			break;
1046
		case EdxlbooleantestIsNotTrue:
J
Jesse Zhang 已提交
1047 1048
			scalar_boolean_test->booltesttype = IS_NOT_TRUE;
			break;
1049
		case EdxlbooleantestIsFalse:
J
Jesse Zhang 已提交
1050 1051
			scalar_boolean_test->booltesttype = IS_FALSE;
			break;
1052
		case EdxlbooleantestIsNotFalse:
J
Jesse Zhang 已提交
1053 1054
			scalar_boolean_test->booltesttype = IS_NOT_FALSE;
			break;
1055
		case EdxlbooleantestIsUnknown:
J
Jesse Zhang 已提交
1056 1057
			scalar_boolean_test->booltesttype = IS_UNKNOWN;
			break;
1058
		case EdxlbooleantestIsNotUnknown:
J
Jesse Zhang 已提交
1059 1060
			scalar_boolean_test->booltesttype = IS_NOT_UNKNOWN;
			break;
1061
		default:
J
Jesse Zhang 已提交
1062 1063 1064 1065
		{
			GPOS_ASSERT(!"Invalid Boolean Test Operation");
			return NULL;
		}
1066 1067
	}

1068 1069
	GPOS_ASSERT(1 == scalar_boolean_test_node->Arity());
	CDXLNode *dxlnode_arg = (*scalar_boolean_test_node)[0];
1070

1071 1072
	Expr *arg_expr = TranslateDXLToScalar(dxlnode_arg, colid_var);
	scalar_boolean_test->arg = arg_expr;
1073

J
Jesse Zhang 已提交
1074
	return (Expr *) scalar_boolean_test;
1075 1076 1077 1078
}

//---------------------------------------------------------------------------
//	@function:
1079
//		CTranslatorDXLToScalar::TranslateDXLScalarNullTestToScalar
1080 1081 1082 1083 1084 1085
//
//	@doc:
//		Translates a DXL scalar NullTest into a GPDB NullTest node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1086 1087
CTranslatorDXLToScalar::TranslateDXLScalarNullTestToScalar(
	const CDXLNode *scalar_null_test_node, CMappingColIdVar *colid_var)
1088
{
1089
	GPOS_ASSERT(NULL != scalar_null_test_node);
J
Jesse Zhang 已提交
1090 1091
	CDXLScalarNullTest *dxlop =
		CDXLScalarNullTest::Cast(scalar_null_test_node->GetOperator());
1092
	NullTest *null_test = MakeNode(NullTest);
1093

1094 1095 1096
	GPOS_ASSERT(1 == scalar_null_test_node->Arity());
	CDXLNode *child_dxl = (*scalar_null_test_node)[0];
	Expr *child_expr = TranslateDXLToScalar(child_dxl, colid_var);
1097

1098
	if (dxlop->IsNullTest())
1099
	{
1100
		null_test->nulltesttype = IS_NULL;
1101 1102 1103
	}
	else
	{
1104
		null_test->nulltesttype = IS_NOT_NULL;
1105 1106
	}

1107
	null_test->arg = child_expr;
J
Jesse Zhang 已提交
1108
	return (Expr *) null_test;
1109 1110 1111 1112
}

//---------------------------------------------------------------------------
//	@function:
1113
//		CTranslatorDXLToScalar::TranslateDXLScalarNullIfToScalar
1114 1115 1116 1117 1118 1119
//
//	@doc:
//		Translates a DXL scalar nullif into a GPDB NullIfExpr node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1120 1121
CTranslatorDXLToScalar::TranslateDXLScalarNullIfToScalar(
	const CDXLNode *scalar_null_if_node, CMappingColIdVar *colid_var)
1122
{
1123
	GPOS_ASSERT(NULL != scalar_null_if_node);
J
Jesse Zhang 已提交
1124 1125
	CDXLScalarNullIf *dxlop =
		CDXLScalarNullIf::Cast(scalar_null_if_node->GetOperator());
1126

1127 1128
	NullIfExpr *scalar_null_if_expr = MakeNode(NullIfExpr);
	scalar_null_if_expr->opno = CMDIdGPDB::CastMdid(dxlop->MdIdOp())->Oid();
1129

J
Jesse Zhang 已提交
1130 1131
	const IMDScalarOp *md_scalar_op =
		m_md_accessor->RetrieveScOp(dxlop->MdIdOp());
1132

J
Jesse Zhang 已提交
1133 1134 1135 1136
	scalar_null_if_expr->opfuncid =
		CMDIdGPDB::CastMdid(md_scalar_op->FuncMdId())->Oid();
	scalar_null_if_expr->opresulttype =
		GetFunctionReturnTypeOid(md_scalar_op->FuncMdId());
1137
	scalar_null_if_expr->opretset = false;
1138 1139

	// translate children
1140
	GPOS_ASSERT(2 == scalar_null_if_node->Arity());
J
Jesse Zhang 已提交
1141 1142
	scalar_null_if_expr->args = TranslateScalarChildren(
		scalar_null_if_expr->args, scalar_null_if_node, colid_var);
1143

1144
	return (Expr *) scalar_null_if_expr;
1145 1146 1147
}

Expr *
J
Jesse Zhang 已提交
1148 1149
CTranslatorDXLToScalar::TranslateRelabelTypeOrFuncExprFromDXL(
	const CDXLScalarCast *scalar_cast, Expr *child_expr)
1150
{
1151
	if (IMDId::IsValid(scalar_cast->FuncMdId()))
1152
	{
1153 1154
		FuncExpr *func_expr = MakeNode(FuncExpr);
		func_expr->funcid = CMDIdGPDB::CastMdid(scalar_cast->FuncMdId())->Oid();
1155

J
Jesse Zhang 已提交
1156 1157 1158 1159
		const IMDFunction *pmdfunc =
			m_md_accessor->RetrieveFunc(scalar_cast->FuncMdId());
		func_expr->funcretset = pmdfunc->ReturnsSet();
		;
1160

1161
		func_expr->funcformat = COERCE_IMPLICIT_CAST;
J
Jesse Zhang 已提交
1162 1163
		func_expr->funcresulttype =
			CMDIdGPDB::CastMdid(scalar_cast->MdidType())->Oid();
1164

1165 1166
		func_expr->args = NIL;
		func_expr->args = gpdb::LAppend(func_expr->args, child_expr);
1167

1168
		return (Expr *) func_expr;
1169 1170
	}

1171
	RelabelType *relabel_type = MakeNode(RelabelType);
1172

J
Jesse Zhang 已提交
1173 1174
	relabel_type->resulttype =
		CMDIdGPDB::CastMdid(scalar_cast->MdidType())->Oid();
1175 1176 1177 1178
	relabel_type->arg = child_expr;
	relabel_type->resulttypmod = -1;
	relabel_type->location = -1;
	relabel_type->relabelformat = COERCE_DONTCARE;
1179

1180
	return (Expr *) relabel_type;
1181 1182
}

1183 1184
// Translates a DXL scalar cast into a GPDB RelabelType / FuncExpr node
Expr *
J
Jesse Zhang 已提交
1185 1186
CTranslatorDXLToScalar::TranslateDXLScalarCastToScalar(
	const CDXLNode *scalar_cast_node, CMappingColIdVar *colid_var)
1187
{
1188
	GPOS_ASSERT(NULL != scalar_cast_node);
J
Jesse Zhang 已提交
1189 1190
	const CDXLScalarCast *dxlop =
		CDXLScalarCast::Cast(scalar_cast_node->GetOperator());
1191

1192 1193
	GPOS_ASSERT(1 == scalar_cast_node->Arity());
	CDXLNode *child_dxl = (*scalar_cast_node)[0];
1194

1195
	Expr *child_expr = TranslateDXLToScalar(child_dxl, colid_var);
1196

1197
	return TranslateRelabelTypeOrFuncExprFromDXL(dxlop, child_expr);
1198 1199
}

1200 1201 1202

//---------------------------------------------------------------------------
//      @function:
1203
//              CTranslatorDXLToScalar::TranslateDXLScalarCoerceToDomainToScalar
1204 1205
//
//      @doc:
1206
//              Translates a DXL scalar coerce into a GPDB coercetodomain node
1207 1208 1209
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1210 1211
CTranslatorDXLToScalar::TranslateDXLScalarCoerceToDomainToScalar(
	const CDXLNode *scalar_coerce_node, CMappingColIdVar *colid_var)
1212
{
J
Jesse Zhang 已提交
1213 1214 1215
	GPOS_ASSERT(NULL != scalar_coerce_node);
	CDXLScalarCoerceToDomain *dxlop =
		CDXLScalarCoerceToDomain::Cast(scalar_coerce_node->GetOperator());
1216

J
Jesse Zhang 已提交
1217 1218
	GPOS_ASSERT(1 == scalar_coerce_node->Arity());
	CDXLNode *child_dxl = (*scalar_coerce_node)[0];
1219

J
Jesse Zhang 已提交
1220
	Expr *child_expr = TranslateDXLToScalar(child_dxl, colid_var);
1221 1222


J
Jesse Zhang 已提交
1223
	CoerceToDomain *coerce = MakeNode(CoerceToDomain);
1224

1225 1226 1227 1228
	coerce->resulttype = CMDIdGPDB::CastMdid(dxlop->GetResultTypeMdId())->Oid();
	coerce->arg = child_expr;
	coerce->resulttypmod = dxlop->TypeModifier();
	coerce->location = dxlop->GetLocation();
J
Jesse Zhang 已提交
1229
	coerce->coercionformat = (CoercionForm) dxlop->GetDXLCoercionForm();
1230

J
Jesse Zhang 已提交
1231
	return (Expr *) coerce;
1232 1233
}

1234 1235
//---------------------------------------------------------------------------
//      @function:
1236
//              CTranslatorDXLToScalar::TranslateDXLScalarCoerceViaIOToScalar
1237 1238 1239 1240 1241 1242
//
//      @doc:
//              Translates a DXL scalar coerce into a GPDB coerceviaio node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1243 1244
CTranslatorDXLToScalar::TranslateDXLScalarCoerceViaIOToScalar(
	const CDXLNode *scalar_coerce_node, CMappingColIdVar *colid_var)
1245
{
J
Jesse Zhang 已提交
1246 1247 1248
	GPOS_ASSERT(NULL != scalar_coerce_node);
	CDXLScalarCoerceViaIO *dxlop =
		CDXLScalarCoerceViaIO::Cast(scalar_coerce_node->GetOperator());
1249

J
Jesse Zhang 已提交
1250 1251
	GPOS_ASSERT(1 == scalar_coerce_node->Arity());
	CDXLNode *child_dxl = (*scalar_coerce_node)[0];
1252

J
Jesse Zhang 已提交
1253
	Expr *child_expr = TranslateDXLToScalar(child_dxl, colid_var);
1254

J
Jesse Zhang 已提交
1255
	CoerceViaIO *coerce = MakeNode(CoerceViaIO);
1256

1257 1258 1259
	coerce->resulttype = CMDIdGPDB::CastMdid(dxlop->GetResultTypeMdId())->Oid();
	coerce->arg = child_expr;
	coerce->location = dxlop->GetLocation();
J
Jesse Zhang 已提交
1260
	coerce->coerceformat = (CoercionForm) dxlop->GetDXLCoercionForm();
1261

J
Jesse Zhang 已提交
1262
	return (Expr *) coerce;
1263 1264
}

1265 1266
//---------------------------------------------------------------------------
//      @function:
1267
//              CTranslatorDXLToScalar::TranslateDXLScalarArrayCoerceExprToScalar
1268 1269 1270 1271 1272 1273
//
//      @doc:
//              Translates a DXL scalar array coerce expr into a GPDB T_ArrayCoerceExpr node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1274 1275
CTranslatorDXLToScalar::TranslateDXLScalarArrayCoerceExprToScalar(
	const CDXLNode *scalar_coerce_node, CMappingColIdVar *colid_var)
1276
{
J
Jesse Zhang 已提交
1277 1278 1279
	GPOS_ASSERT(NULL != scalar_coerce_node);
	CDXLScalarArrayCoerceExpr *dxlop =
		CDXLScalarArrayCoerceExpr::Cast(scalar_coerce_node->GetOperator());
1280

J
Jesse Zhang 已提交
1281 1282
	GPOS_ASSERT(1 == scalar_coerce_node->Arity());
	CDXLNode *child_dxl = (*scalar_coerce_node)[0];
1283

J
Jesse Zhang 已提交
1284
	Expr *child_expr = TranslateDXLToScalar(child_dxl, colid_var);
1285

J
Jesse Zhang 已提交
1286
	ArrayCoerceExpr *coerce = MakeNode(ArrayCoerceExpr);
1287

1288 1289 1290 1291 1292
	coerce->arg = child_expr;
	coerce->elemfuncid = CMDIdGPDB::CastMdid(dxlop->GetCoerceFuncMDid())->Oid();
	coerce->resulttype = CMDIdGPDB::CastMdid(dxlop->GetResultTypeMdId())->Oid();
	coerce->resulttypmod = dxlop->TypeModifier();
	coerce->isExplicit = dxlop->IsExplicit();
J
Jesse Zhang 已提交
1293
	coerce->coerceformat = (CoercionForm) dxlop->GetDXLCoercionForm();
1294
	coerce->location = dxlop->GetLocation();
1295

J
Jesse Zhang 已提交
1296
	return (Expr *) coerce;
1297 1298
}

1299 1300
//---------------------------------------------------------------------------
//	@function:
1301
//		CTranslatorDXLToScalar::TranslateDXLScalarCoalesceToScalar
1302 1303 1304 1305 1306 1307
//
//	@doc:
//		Translates a DXL scalar coalesce operator into a GPDB coalesce node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1308 1309
CTranslatorDXLToScalar::TranslateDXLScalarCoalesceToScalar(
	const CDXLNode *scalar_coalesce_node, CMappingColIdVar *colid_var)
1310
{
1311
	GPOS_ASSERT(NULL != scalar_coalesce_node);
J
Jesse Zhang 已提交
1312 1313
	CDXLScalarCoalesce *dxlop =
		CDXLScalarCoalesce::Cast(scalar_coalesce_node->GetOperator());
1314
	CoalesceExpr *coalesce = MakeNode(CoalesceExpr);
1315

1316
	coalesce->coalescetype = CMDIdGPDB::CastMdid(dxlop->MdidType())->Oid();
J
Jesse Zhang 已提交
1317 1318
	coalesce->args = TranslateScalarChildren(coalesce->args,
											 scalar_coalesce_node, colid_var);
1319
	coalesce->location = -1;
1320

1321
	return (Expr *) coalesce;
1322 1323 1324 1325
}

//---------------------------------------------------------------------------
//	@function:
1326
//		CTranslatorDXLToScalar::TranslateDXLScalarMinMaxToScalar
1327 1328 1329 1330 1331 1332
//
//	@doc:
//		Translates a DXL scalar minmax operator into a GPDB minmax node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1333 1334
CTranslatorDXLToScalar::TranslateDXLScalarMinMaxToScalar(
	const CDXLNode *scalar_min_max_node, CMappingColIdVar *colid_var)
1335
{
1336
	GPOS_ASSERT(NULL != scalar_min_max_node);
J
Jesse Zhang 已提交
1337 1338
	CDXLScalarMinMax *dxlop =
		CDXLScalarMinMax::Cast(scalar_min_max_node->GetOperator());
1339
	MinMaxExpr *min_max_expr = MakeNode(MinMaxExpr);
1340

1341
	min_max_expr->minmaxtype = CMDIdGPDB::CastMdid(dxlop->MdidType())->Oid();
J
Jesse Zhang 已提交
1342 1343
	min_max_expr->args = TranslateScalarChildren(
		min_max_expr->args, scalar_min_max_node, colid_var);
1344
	min_max_expr->location = -1;
1345

1346 1347
	CDXLScalarMinMax::EdxlMinMaxType min_max_type = dxlop->GetMinMaxType();
	if (CDXLScalarMinMax::EmmtMax == min_max_type)
1348
	{
1349
		min_max_expr->op = IS_GREATEST;
1350 1351 1352
	}
	else
	{
1353 1354
		GPOS_ASSERT(CDXLScalarMinMax::EmmtMin == min_max_type);
		min_max_expr->op = IS_LEAST;
1355 1356
	}

1357
	return (Expr *) min_max_expr;
1358 1359 1360 1361
}

//---------------------------------------------------------------------------
//	@function:
1362
//		CTranslatorDXLToScalar::TranslateScalarChildren
1363 1364 1365 1366 1367 1368
//
//	@doc:
//		Translate children of DXL node, and add them to list
//
//---------------------------------------------------------------------------
List *
J
Jesse Zhang 已提交
1369 1370 1371
CTranslatorDXLToScalar::TranslateScalarChildren(List *list,
												const CDXLNode *dxlnode,
												CMappingColIdVar *colid_var)
1372
{
1373
	List *new_list = list;
1374

1375 1376
	const ULONG arity = dxlnode->Arity();
	for (ULONG ul = 0; ul < arity; ul++)
1377
	{
1378 1379 1380
		CDXLNode *child_dxl = (*dxlnode)[ul];
		Expr *child_expr = TranslateDXLToScalar(child_dxl, colid_var);
		new_list = gpdb::LAppend(new_list, child_expr);
1381 1382
	}

1383
	return new_list;
1384 1385 1386 1387
}

//---------------------------------------------------------------------------
//	@function:
1388
//		CTranslatorDXLToScalar::TranslateDXLScalarConstToScalar
1389 1390 1391 1392 1393 1394
//
//	@doc:
//		Translates a DXL scalar constant operator into a GPDB scalar const node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1395
CTranslatorDXLToScalar::TranslateDXLScalarConstToScalar(
1396
	const CDXLNode *const_node,
J
Jesse Zhang 已提交
1397 1398
	CMappingColIdVar *	//colid_var
)
1399
{
1400
	GPOS_ASSERT(NULL != const_node);
J
Jesse Zhang 已提交
1401 1402 1403
	CDXLScalarConstValue *dxlop =
		CDXLScalarConstValue::Cast(const_node->GetOperator());
	CDXLDatum *datum_dxl = const_cast<CDXLDatum *>(dxlop->GetDatumVal());
1404

1405
	return TranslateDXLDatumToScalar(datum_dxl);
1406 1407 1408 1409
}

//---------------------------------------------------------------------------
//	@function:
1410
//		CTranslatorDXLToScalar::TranslateDXLDatumToScalar
1411 1412 1413 1414 1415 1416
//
//	@doc:
//		Translates a DXL datum into a GPDB scalar const node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1417
CTranslatorDXLToScalar::TranslateDXLDatumToScalar(CDXLDatum *datum_dxl)
1418
{
1419 1420
	GPOS_ASSERT(NULL != datum_dxl);

J
Jesse Zhang 已提交
1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437
	static const SDatumTranslatorElem translators[] = {
		{CDXLDatum::EdxldatumInt2,
		 &CTranslatorDXLToScalar::ConvertDXLDatumToConstInt2},
		{CDXLDatum::EdxldatumInt4,
		 &CTranslatorDXLToScalar::ConvertDXLDatumToConstInt4},
		{CDXLDatum::EdxldatumInt8,
		 &CTranslatorDXLToScalar::ConvertDXLDatumToConstInt8},
		{CDXLDatum::EdxldatumBool,
		 &CTranslatorDXLToScalar::ConvertDXLDatumToConstBool},
		{CDXLDatum::EdxldatumOid,
		 &CTranslatorDXLToScalar::ConvertDXLDatumToConstOid},
		{CDXLDatum::EdxldatumGeneric,
		 &CTranslatorDXLToScalar::TranslateDXLDatumGenericToScalar},
		{CDXLDatum::EdxldatumStatsDoubleMappable,
		 &CTranslatorDXLToScalar::TranslateDXLDatumGenericToScalar},
		{CDXLDatum::EdxldatumStatsLintMappable,
		 &CTranslatorDXLToScalar::TranslateDXLDatumGenericToScalar}};
1438

1439 1440
	const ULONG num_translators = GPOS_ARRAY_SIZE(translators);
	CDXLDatum::EdxldatumType edxldatumtype = datum_dxl->GetDatumType();
1441 1442

	// find translator for the node type
1443 1444
	const_func_ptr translate_func = NULL;
	for (ULONG i = 0; i < num_translators; i++)
1445
	{
1446
		SDatumTranslatorElem elem = translators[i];
1447 1448
		if (edxldatumtype == elem.edxldt)
		{
1449
			translate_func = elem.translate_func;
1450 1451 1452 1453
			break;
		}
	}

1454
	if (NULL == translate_func)
1455
	{
J
Jesse Zhang 已提交
1456 1457 1458
		GPOS_RAISE(
			gpdxl::ExmaDXL, gpdxl::ExmiDXL2PlStmtConversion,
			CDXLTokens::GetDXLTokenStr(EdxltokenScalarConstValue)->GetBuffer());
1459 1460
	}

J
Jesse Zhang 已提交
1461
	return (Expr *) (this->*translate_func)(datum_dxl);
1462 1463 1464 1465
}

//---------------------------------------------------------------------------
//	@function:
1466
//		CTranslatorDXLToScalar::ConvertDXLDatumToConstOid
1467 1468 1469 1470 1471 1472
//
//	@doc:
//		Translates an oid datum into a constant
//
//---------------------------------------------------------------------------
Const *
J
Jesse Zhang 已提交
1473
CTranslatorDXLToScalar::ConvertDXLDatumToConstOid(CDXLDatum *datum_dxl)
1474
{
1475
	CDXLDatumOid *oid_datum_dxl = CDXLDatumOid::Cast(datum_dxl);
1476

1477 1478 1479
	Const *constant = MakeNode(Const);
	constant->consttype = CMDIdGPDB::CastMdid(oid_datum_dxl->MDId())->Oid();
	constant->consttypmod = -1;
1480
	constant->constbyval = true;
1481
	constant->constisnull = oid_datum_dxl->IsNull();
1482
	constant->constlen = sizeof(Oid);
1483

1484
	if (constant->constisnull)
1485
	{
1486
		constant->constvalue = (Datum) 0;
1487 1488 1489
	}
	else
	{
1490
		constant->constvalue = gpdb::DatumFromInt32(oid_datum_dxl->OidValue());
1491 1492
	}

1493
	return constant;
1494 1495 1496 1497 1498
}


//---------------------------------------------------------------------------
//	@function:
1499
//		CTranslatorDXLToScalar::ConvertDXLDatumToConstInt2
1500 1501 1502 1503 1504 1505
//
//	@doc:
//		Translates an int2 datum into a constant
//
//---------------------------------------------------------------------------
Const *
J
Jesse Zhang 已提交
1506
CTranslatorDXLToScalar::ConvertDXLDatumToConstInt2(CDXLDatum *datum_dxl)
1507
{
1508
	CDXLDatumInt2 *datum_int2_dxl = CDXLDatumInt2::Cast(datum_dxl);
1509

1510 1511 1512
	Const *constant = MakeNode(Const);
	constant->consttype = CMDIdGPDB::CastMdid(datum_int2_dxl->MDId())->Oid();
	constant->consttypmod = -1;
1513
	constant->constbyval = true;
1514
	constant->constisnull = datum_int2_dxl->IsNull();
1515
	constant->constlen = sizeof(int16);
1516

1517
	if (constant->constisnull)
1518
	{
1519
		constant->constvalue = (Datum) 0;
1520 1521 1522
	}
	else
	{
1523
		constant->constvalue = gpdb::DatumFromInt16(datum_int2_dxl->Value());
1524 1525
	}

1526
	return constant;
1527 1528 1529 1530 1531
}


//---------------------------------------------------------------------------
//	@function:
1532
//		CTranslatorDXLToScalar::ConvertDXLDatumToConstInt4
1533 1534 1535 1536 1537 1538
//
//	@doc:
//		Translates an int4 datum into a constant
//
//---------------------------------------------------------------------------
Const *
J
Jesse Zhang 已提交
1539
CTranslatorDXLToScalar::ConvertDXLDatumToConstInt4(CDXLDatum *datum_dxl)
1540
{
1541
	CDXLDatumInt4 *datum_int4_dxl = CDXLDatumInt4::Cast(datum_dxl);
1542

1543 1544 1545
	Const *constant = MakeNode(Const);
	constant->consttype = CMDIdGPDB::CastMdid(datum_int4_dxl->MDId())->Oid();
	constant->consttypmod = -1;
1546
	constant->constbyval = true;
1547
	constant->constisnull = datum_int4_dxl->IsNull();
1548
	constant->constlen = sizeof(int32);
1549

1550
	if (constant->constisnull)
1551
	{
1552
		constant->constvalue = (Datum) 0;
1553 1554 1555
	}
	else
	{
1556
		constant->constvalue = gpdb::DatumFromInt32(datum_int4_dxl->Value());
1557 1558
	}

1559
	return constant;
1560 1561 1562 1563
}

//---------------------------------------------------------------------------
//	@function:
1564
//		CTranslatorDXLToScalar::ConvertDXLDatumToConstInt8
1565 1566 1567 1568 1569 1570
//
//	@doc:
//		Translates an int8 datum into a constant
//
//---------------------------------------------------------------------------
Const *
J
Jesse Zhang 已提交
1571
CTranslatorDXLToScalar::ConvertDXLDatumToConstInt8(CDXLDatum *datum_dxl)
1572
{
1573
	CDXLDatumInt8 *datum_int8_dxl = CDXLDatumInt8::Cast(datum_dxl);
1574

1575 1576 1577
	Const *constant = MakeNode(Const);
	constant->consttype = CMDIdGPDB::CastMdid(datum_int8_dxl->MDId())->Oid();
	constant->consttypmod = -1;
1578
	constant->constbyval = FLOAT8PASSBYVAL;
1579
	constant->constisnull = datum_int8_dxl->IsNull();
1580
	constant->constlen = sizeof(int64);
1581

1582
	if (constant->constisnull)
1583
	{
1584
		constant->constvalue = (Datum) 0;
1585 1586 1587
	}
	else
	{
1588
		constant->constvalue = gpdb::DatumFromInt64(datum_int8_dxl->Value());
1589 1590
	}

1591
	return constant;
1592 1593 1594 1595
}

//---------------------------------------------------------------------------
//	@function:
1596
//		CTranslatorDXLToScalar::ConvertDXLDatumToConstBool
1597 1598 1599 1600 1601 1602
//
//	@doc:
//		Translates a boolean datum into a constant
//
//---------------------------------------------------------------------------
Const *
J
Jesse Zhang 已提交
1603
CTranslatorDXLToScalar::ConvertDXLDatumToConstBool(CDXLDatum *datum_dxl)
1604
{
1605
	CDXLDatumBool *datum_bool_dxl = CDXLDatumBool::Cast(datum_dxl);
1606

1607 1608 1609
	Const *constant = MakeNode(Const);
	constant->consttype = CMDIdGPDB::CastMdid(datum_bool_dxl->MDId())->Oid();
	constant->consttypmod = -1;
1610
	constant->constbyval = true;
1611
	constant->constisnull = datum_bool_dxl->IsNull();
1612
	constant->constlen = sizeof(bool);
1613

1614
	if (constant->constisnull)
1615
	{
1616
		constant->constvalue = (Datum) 0;
1617 1618 1619
	}
	else
	{
1620
		constant->constvalue = gpdb::DatumFromBool(datum_bool_dxl->GetValue());
1621 1622 1623
	}


1624
	return constant;
1625 1626 1627 1628
}

//---------------------------------------------------------------------------
//	@function:
1629
//		CTranslatorDXLToScalar::TranslateDXLDatumGenericToScalar
1630 1631 1632 1633 1634 1635
//
//	@doc:
//		Translates a datum of generic type into a constant
//
//---------------------------------------------------------------------------
Const *
J
Jesse Zhang 已提交
1636
CTranslatorDXLToScalar::TranslateDXLDatumGenericToScalar(CDXLDatum *datum_dxl)
1637
{
1638
	CDXLDatumGeneric *datum_generic_dxl = CDXLDatumGeneric::Cast(datum_dxl);
J
Jesse Zhang 已提交
1639 1640
	const IMDType *type =
		m_md_accessor->RetrieveType(datum_generic_dxl->MDId());
1641

1642 1643 1644
	Const *constant = MakeNode(Const);
	constant->consttype = CMDIdGPDB::CastMdid(datum_generic_dxl->MDId())->Oid();
	constant->consttypmod = datum_generic_dxl->TypeModifier();
1645 1646
	constant->constbyval = type->IsPassedByValue();
	constant->constlen = type->Length();
1647

1648
	constant->constisnull = datum_generic_dxl->IsNull();
1649
	if (constant->constisnull)
1650
	{
1651
		constant->constvalue = (Datum) 0;
1652
	}
1653
	else if (constant->constbyval)
1654 1655
	{
		// if it is a by-value constant, the value is stored in the datum.
1656 1657
		GPOS_ASSERT(constant->constlen >= 0);
		GPOS_ASSERT((ULONG) constant->constlen <= sizeof(Datum));
J
Jesse Zhang 已提交
1658 1659
		memcpy(&constant->constvalue, datum_generic_dxl->GetByteArray(),
			   sizeof(Datum));
1660 1661 1662
	}
	else
	{
1663 1664
		Datum val = gpdb::DatumFromPointer(datum_generic_dxl->GetByteArray());
		ULONG length = (ULONG) gpdb::DatumSize(val, false, constant->constlen);
1665

1666 1667 1668 1669
		CHAR *str = (CHAR *) gpdb::GPDBAlloc(length + 1);
		memcpy(str, datum_generic_dxl->GetByteArray(), length);
		str[length] = '\0';
		constant->constvalue = gpdb::DatumFromPointer(str);
1670 1671
	}

1672
	return constant;
1673 1674 1675 1676
}

//---------------------------------------------------------------------------
//	@function:
1677
//		CTranslatorDXLToScalar::TranslateDXLScalarPartDefaultToScalar
1678 1679 1680 1681 1682 1683
//
//	@doc:
//		Translates a DXL part default into a GPDB part default
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1684
CTranslatorDXLToScalar::TranslateDXLScalarPartDefaultToScalar(
1685
	const CDXLNode *part_default_node,
J
Jesse Zhang 已提交
1686 1687
	CMappingColIdVar *	//colid_var
)
1688
{
J
Jesse Zhang 已提交
1689 1690
	CDXLScalarPartDefault *dxlop =
		CDXLScalarPartDefault::Cast(part_default_node->GetOperator());
1691

1692 1693
	PartDefaultExpr *expr = MakeNode(PartDefaultExpr);
	expr->level = dxlop->GetPartitioningLevel();
1694

1695
	return (Expr *) expr;
1696 1697 1698 1699
}

//---------------------------------------------------------------------------
//	@function:
1700
//		CTranslatorDXLToScalar::TranslateDXLScalarPartBoundToScalar
1701 1702 1703 1704 1705 1706
//
//	@doc:
//		Translates a DXL part bound into a GPDB part bound
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1707
CTranslatorDXLToScalar::TranslateDXLScalarPartBoundToScalar(
1708
	const CDXLNode *part_bound_node,
J
Jesse Zhang 已提交
1709 1710
	CMappingColIdVar *	//colid_var
)
1711
{
J
Jesse Zhang 已提交
1712 1713
	CDXLScalarPartBound *dxlop =
		CDXLScalarPartBound::Cast(part_bound_node->GetOperator());
1714

1715 1716 1717 1718
	PartBoundExpr *expr = MakeNode(PartBoundExpr);
	expr->level = dxlop->GetPartitioningLevel();
	expr->boundType = CMDIdGPDB::CastMdid(dxlop->MdidType())->Oid();
	expr->isLowerBound = dxlop->IsLowerBound();
1719

1720
	return (Expr *) expr;
1721 1722 1723 1724
}

//---------------------------------------------------------------------------
//	@function:
1725
//		CTranslatorDXLToScalar::TranslateDXLScalarPartBoundInclusionToScalar
1726 1727 1728 1729 1730 1731
//
//	@doc:
//		Translates a DXL part bound inclusion into a GPDB part bound inclusion
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1732
CTranslatorDXLToScalar::TranslateDXLScalarPartBoundInclusionToScalar(
1733
	const CDXLNode *part_bound_incl_node,
J
Jesse Zhang 已提交
1734 1735
	CMappingColIdVar *	//colid_var
)
1736
{
J
Jesse Zhang 已提交
1737 1738
	CDXLScalarPartBoundInclusion *dxlop =
		CDXLScalarPartBoundInclusion::Cast(part_bound_incl_node->GetOperator());
1739

1740 1741 1742
	PartBoundInclusionExpr *expr = MakeNode(PartBoundInclusionExpr);
	expr->level = dxlop->GetPartitioningLevel();
	expr->isLowerBound = dxlop->IsLowerBound();
1743

1744
	return (Expr *) expr;
1745 1746 1747 1748
}

//---------------------------------------------------------------------------
//	@function:
1749
//		CTranslatorDXLToScalar::TranslateDXLScalarPartBoundOpenToScalar
1750 1751 1752 1753 1754 1755
//
//	@doc:
//		Translates a DXL part bound openness into a GPDB part bound openness
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1756
CTranslatorDXLToScalar::TranslateDXLScalarPartBoundOpenToScalar(
1757
	const CDXLNode *part_bound_open_node,
J
Jesse Zhang 已提交
1758 1759
	CMappingColIdVar *	//colid_var
)
1760
{
J
Jesse Zhang 已提交
1761 1762
	CDXLScalarPartBoundOpen *dxlop =
		CDXLScalarPartBoundOpen::Cast(part_bound_open_node->GetOperator());
1763

1764 1765 1766
	PartBoundOpenExpr *expr = MakeNode(PartBoundOpenExpr);
	expr->level = dxlop->GetPartitioningLevel();
	expr->isLowerBound = dxlop->IsLowerBound();
1767

1768
	return (Expr *) expr;
1769 1770
}

1771 1772
//---------------------------------------------------------------------------
//	@function:
1773
//		CTranslatorDXLToScalar::TranslateDXLScalarPartListValuesToScalar
1774 1775 1776 1777 1778 1779
//
//	@doc:
//		Translates a DXL part list values into a GPDB part list values
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1780
CTranslatorDXLToScalar::TranslateDXLScalarPartListValuesToScalar(
1781
	const CDXLNode *part_list_values_node,
J
Jesse Zhang 已提交
1782 1783
	CMappingColIdVar *	//colid_var
)
1784
{
J
Jesse Zhang 已提交
1785 1786
	CDXLScalarPartListValues *dxlop =
		CDXLScalarPartListValues::Cast(part_list_values_node->GetOperator());
1787

1788 1789 1790 1791
	PartListRuleExpr *expr = MakeNode(PartListRuleExpr);
	expr->level = dxlop->GetPartitioningLevel();
	expr->resulttype = CMDIdGPDB::CastMdid(dxlop->GetResultTypeMdId())->Oid();
	expr->elementtype = CMDIdGPDB::CastMdid(dxlop->GetElemTypeMdId())->Oid();
1792

1793
	return (Expr *) expr;
1794 1795 1796 1797
}

//---------------------------------------------------------------------------
//	@function:
1798
//		CTranslatorDXLToScalar::TranslateDXLScalarPartListNullTestToScalar
1799 1800 1801 1802 1803 1804
//
//	@doc:
//		Translates a DXL part list values into a GPDB part list null test
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1805
CTranslatorDXLToScalar::TranslateDXLScalarPartListNullTestToScalar(
1806
	const CDXLNode *part_list_null_test_node,
J
Jesse Zhang 已提交
1807 1808
	CMappingColIdVar *	//colid_var
)
1809
{
J
Jesse Zhang 已提交
1810 1811
	CDXLScalarPartListNullTest *dxlop = CDXLScalarPartListNullTest::Cast(
		part_list_null_test_node->GetOperator());
1812

1813 1814 1815
	PartListNullTestExpr *expr = MakeNode(PartListNullTestExpr);
	expr->level = dxlop->GetPartitioningLevel();
	expr->nulltesttype = dxlop->IsNull() ? IS_NULL : IS_NOT_NULL;
1816

1817
	return (Expr *) expr;
1818 1819
}

1820 1821
//---------------------------------------------------------------------------
//	@function:
1822
//		CTranslatorDXLToScalar::TranslateDXLScalarIdentToScalar
1823 1824 1825 1826 1827 1828
//
//	@doc:
//		Translates a DXL scalar ident into a GPDB Expr node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1829 1830
CTranslatorDXLToScalar::TranslateDXLScalarIdentToScalar(
	const CDXLNode *scalar_id_node, CMappingColIdVar *colid_var)
1831
{
J
Jesse Zhang 已提交
1832 1833
	CMappingColIdVarPlStmt *colid_var_plstmt_map =
		dynamic_cast<CMappingColIdVarPlStmt *>(colid_var);
1834 1835

	// scalar identifier
J
Jesse Zhang 已提交
1836 1837
	CDXLScalarIdent *dxlop =
		CDXLScalarIdent::Cast(scalar_id_node->GetOperator());
1838
	Expr *result_expr = NULL;
J
Jesse Zhang 已提交
1839 1840 1841 1842
	if (NULL == colid_var_plstmt_map ||
		NULL ==
			colid_var_plstmt_map->GetOutputContext()->GetParamIdMappingElement(
				dxlop->GetDXLColRef()->Id()))
1843
	{
1844 1845
		// not an outer ref -> Translate var node
		result_expr = (Expr *) colid_var->VarFromDXLNodeScId(dxlop);
1846 1847 1848
	}
	else
	{
1849
		// outer ref -> Translate param node
J
Jesse Zhang 已提交
1850 1851
		result_expr =
			(Expr *) colid_var_plstmt_map->ParamFromDXLNodeScId(dxlop);
1852 1853
	}

J
Jesse Zhang 已提交
1854
	if (NULL == result_expr)
1855
	{
J
Jesse Zhang 已提交
1856 1857
		GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXL2PlStmtAttributeNotFound,
				   dxlop->GetDXLColRef()->Id());
1858
	}
1859
	return result_expr;
1860 1861 1862 1863
}

//---------------------------------------------------------------------------
//	@function:
1864
//		CTranslatorDXLToScalar::TranslateDXLScalarCmpToScalar
1865 1866 1867 1868 1869 1870
//
//	@doc:
//		Translates a DXL scalar comparison operator or a scalar distinct comparison into a GPDB OpExpr node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1871 1872
CTranslatorDXLToScalar::TranslateDXLScalarCmpToScalar(
	const CDXLNode *scalar_cmp_node, CMappingColIdVar *colid_var)
1873
{
1874
	GPOS_ASSERT(NULL != scalar_cmp_node);
J
Jesse Zhang 已提交
1875 1876
	CDXLScalarComp *dxlop =
		CDXLScalarComp::Cast(scalar_cmp_node->GetOperator());
1877

1878 1879
	OpExpr *op_expr = MakeNode(OpExpr);
	op_expr->opno = CMDIdGPDB::CastMdid(dxlop->MDId())->Oid();
1880

J
Jesse Zhang 已提交
1881 1882
	const IMDScalarOp *md_scalar_op =
		m_md_accessor->RetrieveScOp(dxlop->MDId());
1883

1884
	op_expr->opfuncid = CMDIdGPDB::CastMdid(md_scalar_op->FuncMdId())->Oid();
J
Jesse Zhang 已提交
1885 1886 1887
	op_expr->opresulttype =
		CMDIdGPDB::CastMdid(m_md_accessor->PtMDType<IMDTypeBool>()->MDId())
			->Oid();
1888
	op_expr->opretset = false;
1889 1890

	// translate left and right child
1891
	GPOS_ASSERT(2 == scalar_cmp_node->Arity());
1892

1893 1894
	CDXLNode *left_node = (*scalar_cmp_node)[EdxlsccmpIndexLeft];
	CDXLNode *right_node = (*scalar_cmp_node)[EdxlsccmpIndexRight];
1895

1896 1897
	Expr *left_expr = TranslateDXLToScalar(left_node, colid_var);
	Expr *right_expr = TranslateDXLToScalar(right_node, colid_var);
1898

1899
	op_expr->args = ListMake2(left_expr, right_expr);
1900

1901
	return (Expr *) op_expr;
1902 1903 1904 1905
}

//---------------------------------------------------------------------------
//	@function:
1906
//		CTranslatorDXLToScalar::TranslateDXLScalarArrayToScalar
1907 1908 1909 1910 1911 1912
//
//	@doc:
//		Translates a DXL scalar array into a GPDB ArrayExpr node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1913 1914
CTranslatorDXLToScalar::TranslateDXLScalarArrayToScalar(
	const CDXLNode *scalar_array_node, CMappingColIdVar *colid_var)
1915
{
1916
	GPOS_ASSERT(NULL != scalar_array_node);
J
Jesse Zhang 已提交
1917 1918
	CDXLScalarArray *dxlop =
		CDXLScalarArray::Cast(scalar_array_node->GetOperator());
1919

1920 1921 1922 1923
	ArrayExpr *expr = MakeNode(ArrayExpr);
	expr->element_typeid = CMDIdGPDB::CastMdid(dxlop->ElementTypeMDid())->Oid();
	expr->array_typeid = CMDIdGPDB::CastMdid(dxlop->ArrayTypeMDid())->Oid();
	expr->multidims = dxlop->IsMultiDimensional();
J
Jesse Zhang 已提交
1924 1925
	expr->elements =
		TranslateScalarChildren(expr->elements, scalar_array_node, colid_var);
1926

1927 1928 1929 1930 1931 1932 1933 1934
	/*
	 * ORCA doesn't know how to construct array constants, so it will
	 * return any arrays as ArrayExprs. Convert them to array constants,
	 * for more efficient evaluation at runtime. (This will try to further
	 * simplify the elements, too, but that is most likely futile, as the
	 * expressions were already simplified as much as we could before they
	 * were passed to ORCA. But there's little harm in trying).
	 */
1935
	return (Expr *) gpdb::EvalConstExpressions((Node *) expr);
1936 1937 1938 1939
}

//---------------------------------------------------------------------------
//	@function:
1940
//		CTranslatorDXLToScalar::TranslateDXLScalarArrayRefToScalar
1941 1942 1943 1944 1945 1946
//
//	@doc:
//		Translates a DXL scalar arrayref into a GPDB ArrayRef node
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
1947 1948
CTranslatorDXLToScalar::TranslateDXLScalarArrayRefToScalar(
	const CDXLNode *scalar_array_ref_node, CMappingColIdVar *colid_var)
1949
{
1950
	GPOS_ASSERT(NULL != scalar_array_ref_node);
J
Jesse Zhang 已提交
1951 1952
	CDXLScalarArrayRef *dxlop =
		CDXLScalarArrayRef::Cast(scalar_array_ref_node->GetOperator());
1953

1954
	ArrayRef *array_ref = MakeNode(ArrayRef);
J
Jesse Zhang 已提交
1955 1956 1957 1958
	array_ref->refarraytype =
		CMDIdGPDB::CastMdid(dxlop->ArrayTypeMDid())->Oid();
	array_ref->refelemtype =
		CMDIdGPDB::CastMdid(dxlop->ElementTypeMDid())->Oid();
1959
	array_ref->reftypmod = dxlop->TypeModifier();
1960

1961 1962
	const ULONG arity = scalar_array_ref_node->Arity();
	GPOS_ASSERT(3 == arity || 4 == arity);
1963

J
Jesse Zhang 已提交
1964 1965 1966 1967 1968 1969
	array_ref->reflowerindexpr = TranslateDXLArrayRefIndexListToScalar(
		(*scalar_array_ref_node)[0], CDXLScalarArrayRefIndexList::EilbLower,
		colid_var);
	array_ref->refupperindexpr = TranslateDXLArrayRefIndexListToScalar(
		(*scalar_array_ref_node)[1], CDXLScalarArrayRefIndexList::EilbUpper,
		colid_var);
1970

J
Jesse Zhang 已提交
1971 1972
	array_ref->refexpr =
		TranslateDXLToScalar((*scalar_array_ref_node)[2], colid_var);
1973 1974
	array_ref->refassgnexpr = NULL;
	if (4 == arity)
1975
	{
J
Jesse Zhang 已提交
1976 1977
		array_ref->refassgnexpr =
			TranslateDXLToScalar((*scalar_array_ref_node)[3], colid_var);
1978 1979
	}

1980
	return (Expr *) array_ref;
1981 1982 1983 1984
}

//---------------------------------------------------------------------------
//	@function:
1985
//		CTranslatorDXLToScalar::TranslateDXLArrayRefIndexListToScalar
1986 1987 1988 1989 1990 1991
//
//	@doc:
//		Translates a DXL arrayref index list
//
//---------------------------------------------------------------------------
List *
J
Jesse Zhang 已提交
1992
CTranslatorDXLToScalar::TranslateDXLArrayRefIndexListToScalar(
1993
	const CDXLNode *index_list_node,
1994 1995
	CDXLScalarArrayRefIndexList::EIndexListBound
#ifdef GPOS_DEBUG
J
Jesse Zhang 已提交
1996 1997
		index_list_bound
#endif	//GPOS_DEBUG
1998
	,
J
Jesse Zhang 已提交
1999
	CMappingColIdVar *colid_var)
2000
{
2001
	GPOS_ASSERT(NULL != index_list_node);
J
Jesse Zhang 已提交
2002 2003 2004
	GPOS_ASSERT(index_list_bound == CDXLScalarArrayRefIndexList::Cast(
										index_list_node->GetOperator())
										->GetDXLIndexListBound());
2005

2006 2007
	List *children = NIL;
	children = TranslateScalarChildren(children, index_list_node, colid_var);
2008

2009
	return children;
2010 2011 2012 2013
}

//---------------------------------------------------------------------------
//	@function:
2014
//		CTranslatorDXLToScalar::TranslateDXLScalarDMLActionToScalar
2015 2016
//
//	@doc:
J
Jesse Zhang 已提交
2017
//		Translates a DML action expression
2018 2019 2020
//
//---------------------------------------------------------------------------
Expr *
J
Jesse Zhang 已提交
2021
CTranslatorDXLToScalar::TranslateDXLScalarDMLActionToScalar(
2022 2023
	const CDXLNode *
#ifdef GPOS_DEBUG
J
Jesse Zhang 已提交
2024
		dml_action_node
2025 2026
#endif
	,
J
Jesse Zhang 已提交
2027 2028
	CMappingColIdVar *	// colid_var
)
2029
{
2030
	GPOS_ASSERT(NULL != dml_action_node);
J
Jesse Zhang 已提交
2031 2032
	GPOS_ASSERT(EdxlopScalarDMLAction ==
				dml_action_node->GetOperator()->GetDXLOperator());
2033

2034
	DMLActionExpr *expr = MakeNode(DMLActionExpr);
2035

2036
	return (Expr *) expr;
2037 2038 2039 2040 2041 2042
}



//---------------------------------------------------------------------------
//	@function:
2043
//		CTranslatorDXLToScalar::GetFunctionReturnTypeOid
2044 2045 2046 2047 2048 2049
//
//	@doc:
//		Returns the operator return type oid for the operator funcid from the translation context
//
//---------------------------------------------------------------------------
Oid
J
Jesse Zhang 已提交
2050
CTranslatorDXLToScalar::GetFunctionReturnTypeOid(IMDId *mdid) const
2051
{
J
Jesse Zhang 已提交
2052 2053 2054
	return CMDIdGPDB::CastMdid(
			   m_md_accessor->RetrieveFunc(mdid)->GetResultTypeMdid())
		->Oid();
2055 2056 2057 2058
}

//---------------------------------------------------------------------------
//	@function:
2059
//		CTranslatorDXLToScalar::HasBoolResult
2060 2061 2062 2063 2064 2065
//
//	@doc:
//		Check to see if the operator returns a boolean result
//
//---------------------------------------------------------------------------
BOOL
J
Jesse Zhang 已提交
2066 2067
CTranslatorDXLToScalar::HasBoolResult(CDXLNode *dxlnode,
									  CMDAccessor *md_accessor)
2068
{
2069
	GPOS_ASSERT(NULL != dxlnode);
2070

J
Jesse Zhang 已提交
2071
	if (EdxloptypeScalar != dxlnode->GetOperator()->GetDXLOperatorType())
2072 2073 2074 2075
	{
		return false;
	}

J
Jesse Zhang 已提交
2076
	CDXLScalar *dxlop = dynamic_cast<CDXLScalar *>(dxlnode->GetOperator());
2077

2078
	return dxlop->HasBoolResult(md_accessor);
2079 2080 2081 2082
}

//---------------------------------------------------------------------------
//	@function:
2083
//		CTranslatorDXLToScalar::HasConstTrue
2084 2085 2086 2087 2088 2089
//
//	@doc:
//		Check if the operator is a "true" bool constant
//
//---------------------------------------------------------------------------
BOOL
J
Jesse Zhang 已提交
2090 2091
CTranslatorDXLToScalar::HasConstTrue(CDXLNode *dxlnode,
									 CMDAccessor *md_accessor)
2092
{
2093
	GPOS_ASSERT(NULL != dxlnode);
J
Jesse Zhang 已提交
2094 2095
	if (!HasBoolResult(dxlnode, md_accessor) ||
		EdxlopScalarConstValue != dxlnode->GetOperator()->GetDXLOperator())
2096 2097 2098 2099
	{
		return false;
	}

J
Jesse Zhang 已提交
2100 2101 2102 2103
	CDXLScalarConstValue *dxlop =
		CDXLScalarConstValue::Cast(dxlnode->GetOperator());
	CDXLDatumBool *datum_bool_dxl =
		CDXLDatumBool::Cast(const_cast<CDXLDatum *>(dxlop->GetDatumVal()));
2104

2105
	return datum_bool_dxl->GetValue();
2106 2107 2108 2109
}

//---------------------------------------------------------------------------
//	@function:
2110
//		CTranslatorDXLToScalar::HasConstNull
2111 2112 2113 2114 2115 2116
//
//	@doc:
//		Check if the operator is a NULL constant
//
//---------------------------------------------------------------------------
BOOL
J
Jesse Zhang 已提交
2117
CTranslatorDXLToScalar::HasConstNull(CDXLNode *dxlnode)
2118
{
2119 2120
	GPOS_ASSERT(NULL != dxlnode);
	if (EdxlopScalarConstValue != dxlnode->GetOperator()->GetDXLOperator())
2121 2122 2123 2124
	{
		return false;
	}

J
Jesse Zhang 已提交
2125 2126
	CDXLScalarConstValue *dxlop =
		CDXLScalarConstValue::Cast(dxlnode->GetOperator());
2127

2128
	return dxlop->GetDatumVal()->IsNull();
2129 2130 2131
}

// EOF