//---------------------------------------------------------------------------
//	@function:
//		CJobTransformation::EevtTransform
//
//	@doc:
//		Apply transformation action
//
//---------------------------------------------------------------------------
CJobTransformation::EEvent
CJobTransformation::EevtTransform
	(
	CSchedulerContext *psc,
	CJob *pjOwner
	)
{
	// get a job pointer
	CJobTransformation *pjt = PjConvert(pjOwner);
	IMemoryPool *pmpGlobal = psc->PmpGlobal();
	IMemoryPool *pmpLocal = psc->PmpLocal();
	CGroupExpression *pgexpr = pjt->m_pgexpr;
	CXform *pxform = pjt->m_pxform;

	// insert transformation results to memo
	CXformResult *pxfres = GPOS_NEW(pmpGlobal) CXformResult(pmpGlobal);
	ULONG ulElapsedTime = 0;
	pgexpr->Transform(pmpGlobal, pmpLocal, pxform, pxfres, &ulElapsedTime);
	psc->Peng()->InsertXformResult(pgexpr->Pgroup(), pxfres, pxform->Exfid(), pgexpr, ulElapsedTime);
	pxfres->Release();

	return eevCompleted;
}
//---------------------------------------------------------------------------
//	@function:
//		CExpressionHandle::PexprScalarChild
//
//	@doc:
//		Get the scalar child at given index
//
//---------------------------------------------------------------------------
CExpression *
CExpressionHandle::PexprScalarChild
	(
	ULONG ulChildIndex
	)
	const
{
	GPOS_ASSERT(ulChildIndex < UlArity());

	if (NULL != m_pgexpr)
	{
		// access scalar expression cached on the child scalar group
		GPOS_ASSERT((*m_pgexpr)[ulChildIndex]->FScalar());

		CExpression *pexprScalar = (*m_pgexpr)[ulChildIndex]->PexprScalar();
		GPOS_ASSERT_IMP(NULL == pexprScalar, CDrvdPropScalar::Pdpscalar((*m_pgexpr)[ulChildIndex]->Pdp())->FHasSubquery());

		return pexprScalar;
	}

	if (NULL != m_pexpr && NULL != (*m_pexpr)[ulChildIndex]->Pgexpr())
	{
		// if the expression does not come from a group, but its child does then
		// get the scalar child from that group
		CGroupExpression *pgexpr = (*m_pexpr)[ulChildIndex]->Pgexpr();
		CExpression *pexprScalar = pgexpr->Pgroup()->PexprScalar();
		GPOS_ASSERT_IMP(NULL == pexprScalar, CDrvdPropScalar::Pdpscalar((*m_pexpr)[ulChildIndex]->PdpDerive())->FHasSubquery());

		return pexprScalar;
	}

	// access scalar expression from the child expression node
	GPOS_ASSERT((*m_pexpr)[ulChildIndex]->Pop()->FScalar());

	return (*m_pexpr)[ulChildIndex];
}