Example #1
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalAgg::PdsRequiredIntermediateAgg
//
//	@doc:
//		Compute required distribution of the n-th child of an intermediate 
//		aggregate operator
//
//---------------------------------------------------------------------------
CDistributionSpec *
CPhysicalAgg::PdsRequiredIntermediateAgg
	(
	IMemoryPool *pmp,
	ULONG  ulOptReq
	)
	const
{
	GPOS_ASSERT(COperator::EgbaggtypeIntermediate == m_egbaggtype);

	if (0 == ulOptReq)
	{
		return PdsMaximalHashed(pmp, m_pdrgpcr);
	}

	DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);
	const ULONG ulLen = m_pdrgpcr->UlLength() - m_pdrgpcrArgDQA->UlLength();
	for (ULONG ul = 0; ul < ulLen; ul++)
	{
		CColRef *pcr = (*m_pdrgpcr)[ul];
		pdrgpcr->Append(pcr);
	}

	CDistributionSpec *pds = PdsMaximalHashed(pmp, pdrgpcr);
	pdrgpcr->Release();

	return pds;
}
Example #2
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PdrgpdrgpcrCreatePartCols
//
//	@doc:
//		Initialize array of partition columns from the array with their indexes
//
//---------------------------------------------------------------------------
DrgDrgPcr *
CLogical::PdrgpdrgpcrCreatePartCols
	(
	IMemoryPool *pmp,
	DrgPcr *pdrgpcr,
	const DrgPul *pdrgpulPart
	)
{
	GPOS_ASSERT(NULL != pdrgpcr && "Output columns cannot be NULL");
	GPOS_ASSERT(NULL != pdrgpulPart);
	
	DrgDrgPcr *pdrgpdrgpcrPart = GPOS_NEW(pmp) DrgDrgPcr(pmp);
	
	const ULONG ulPartCols = pdrgpulPart->UlLength();
	GPOS_ASSERT(0 < ulPartCols);
	
	for (ULONG ul = 0; ul < ulPartCols; ul++)
	{
		ULONG ulCol = *((*pdrgpulPart)[ul]);
		
		CColRef *pcr = (*pdrgpcr)[ulCol];
		DrgPcr * pdrgpcrCurr = GPOS_NEW(pmp) DrgPcr(pmp);
		pdrgpcrCurr->Append(pcr);
		pdrgpdrgpcrPart->Append(pdrgpcrCurr);
	}
	
	return pdrgpdrgpcrPart;
}
//---------------------------------------------------------------------------
//	@function:
//		CXformImplementDynamicBitmapTableGet::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformImplementDynamicBitmapTableGet::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	IMemoryPool *pmp = pxfctxt->Pmp();
	CLogicalDynamicBitmapTableGet *popLogical = CLogicalDynamicBitmapTableGet::PopConvert(pexpr->Pop());

	CTableDescriptor *ptabdesc = popLogical->Ptabdesc();
	ptabdesc->AddRef();

	CName *pname = GPOS_NEW(pmp) CName(pmp, popLogical->Name());

	DrgPcr *pdrgpcrOutput = popLogical->PdrgpcrOutput();

	GPOS_ASSERT(NULL != pdrgpcrOutput);
	pdrgpcrOutput->AddRef();

	DrgDrgPcr *pdrgpdrgpcrPart = popLogical->PdrgpdrgpcrPart();
	pdrgpdrgpcrPart->AddRef();

	CPartConstraint *ppartcnstr = popLogical->Ppartcnstr();
	ppartcnstr->AddRef();

	CPartConstraint *ppartcnstrRel = popLogical->PpartcnstrRel();
	ppartcnstrRel->AddRef();

	CPhysicalDynamicBitmapTableScan *popPhysical =
			GPOS_NEW(pmp) CPhysicalDynamicBitmapTableScan
					(
					pmp,
					popLogical->FPartial(),
					ptabdesc,
					pexpr->Pop()->UlOpId(),
					pname,
					popLogical->UlScanId(),
					pdrgpcrOutput,
					pdrgpdrgpcrPart,
					popLogical->UlSecondaryScanId(),
					ppartcnstr,
					ppartcnstrRel
					);

	CExpression *pexprCondition = (*pexpr)[0];
	CExpression *pexprIndexPath = (*pexpr)[1];
	pexprCondition->AddRef();
	pexprIndexPath->AddRef();

	CExpression *pexprPhysical =
			GPOS_NEW(pmp) CExpression(pmp, popPhysical, pexprCondition, pexprIndexPath);
	pxfres->Add(pexprPhysical);
}
Example #4
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalSetOp::PpartinfoDerive
//
//	@doc:
//		Derive partition consumer info
//
//---------------------------------------------------------------------------
CPartInfo *
CLogicalSetOp::PpartinfoDerive
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl
	)
	const
{
	const ULONG ulArity = exprhdl.UlArity();
	GPOS_ASSERT(0 < ulArity);

	// start with the part info of the first child
	CPartInfo *ppartinfo = exprhdl.Pdprel(0 /*ulChildIndex*/)->Ppartinfo();
	ppartinfo->AddRef();

	for (ULONG ul = 1; ul < ulArity; ul++)
	{
		CPartInfo *ppartinfoChild = exprhdl.Pdprel(ul)->Ppartinfo();
		GPOS_ASSERT(NULL != ppartinfoChild);

		DrgPcr *pdrgpcrInput = (*m_pdrgpdrgpcrInput)[ul];
		GPOS_ASSERT(pdrgpcrInput->UlLength() == m_pdrgpcrOutput->UlLength());

		CPartInfo *ppartinfoRemapped = ppartinfoChild->PpartinfoWithRemappedKeys(pmp, pdrgpcrInput, m_pdrgpcrOutput);
		CPartInfo *ppartinfoCombined = CPartInfo::PpartinfoCombine(pmp, ppartinfo, ppartinfoRemapped);
		ppartinfoRemapped->Release();

		ppartinfo->Release();
		ppartinfo = ppartinfoCombined;
	}

	return ppartinfo;
}
Example #5
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PkcCombineKeys
//
//	@doc:
//		Common case of combining keys from first n - 1 children
//
//---------------------------------------------------------------------------
CKeyCollection *
CLogical::PkcCombineKeys
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl
	)
{
	CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp);
	const ULONG ulArity = exprhdl.UlArity();
	for (ULONG ul = 0; ul < ulArity - 1; ul++)
	{
		CKeyCollection *pkc = exprhdl.Pdprel(ul)->Pkc();
		if (NULL == pkc)
		{
			// if a child has no key, the operator has no key
			pcrs->Release();
			return NULL;
		}

		DrgPcr *pdrgpcr = pkc->PdrgpcrKey(pmp);
		pcrs->Include(pdrgpcr);
		pdrgpcr->Release();
	}

	return GPOS_NEW(pmp) CKeyCollection(pmp, pcrs);
}
Example #6
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PdrgpcrCreateMapping
//
//	@doc:
//		Create output column mapping given a list of column descriptors and
//		a pointer to the operator creating that column
//
//---------------------------------------------------------------------------
DrgPcr *
CLogical::PdrgpcrCreateMapping
	(
	IMemoryPool *pmp,
	const DrgPcoldesc *pdrgpcoldesc,
	ULONG ulOpSourceId
	)
	const
{
	// get column factory from optimizer context object
	CColumnFactory *pcf = COptCtxt::PoctxtFromTLS()->Pcf();
	
	ULONG ulCols = pdrgpcoldesc->UlLength();
	
	DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp, ulCols);
	for(ULONG ul = 0; ul < ulCols; ul++)
	{
		CColumnDescriptor *pcoldesc = (*pdrgpcoldesc)[ul];
		CName name(pmp, pcoldesc->Name());
		
		CColRef *pcr = pcf->PcrCreate(pcoldesc, name, ulOpSourceId);
		pdrgpcr->Append(pcr);
	}
	
	return pdrgpcr;
}
//---------------------------------------------------------------------------
//	@function:
//		CXformDifferenceAll2LeftAntiSemiJoin::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformDifferenceAll2LeftAntiSemiJoin::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	IMemoryPool *pmp = pxfctxt->Pmp();

	// TODO: , Jan 8th 2013, we currently only handle difference all
	//  operators with two children
	GPOS_ASSERT(2 == pexpr->UlArity());

	// extract components
	CExpression *pexprLeftChild = (*pexpr)[0];
	CExpression *pexprRightChild = (*pexpr)[1];

	CLogicalDifferenceAll *popDifferenceAll = CLogicalDifferenceAll::PopConvert(pexpr->Pop());
	DrgDrgPcr *pdrgpdrgpcrInput = popDifferenceAll->PdrgpdrgpcrInput();

	CExpression *pexprLeftWindow = CXformUtils::PexprWindowWithRowNumber(pmp, pexprLeftChild, (*pdrgpdrgpcrInput)[0]);
	CExpression *pexprRightWindow = CXformUtils::PexprWindowWithRowNumber(pmp, pexprRightChild, (*pdrgpdrgpcrInput)[1]);

	DrgDrgPcr *pdrgpdrgpcrInputNew = GPOS_NEW(pmp) DrgDrgPcr(pmp);
	DrgPcr *pdrgpcrLeftNew = CUtils::PdrgpcrExactCopy(pmp, (*pdrgpdrgpcrInput)[0]);
	pdrgpcrLeftNew->Append(CXformUtils::PcrProjectElement(pexprLeftWindow, 0 /* row_number window function*/));

	DrgPcr *pdrgpcrRightNew = CUtils::PdrgpcrExactCopy(pmp, (*pdrgpdrgpcrInput)[1]);
	pdrgpcrRightNew->Append(CXformUtils::PcrProjectElement(pexprRightWindow, 0 /* row_number window function*/));

	pdrgpdrgpcrInputNew->Append(pdrgpcrLeftNew);
	pdrgpdrgpcrInputNew->Append(pdrgpcrRightNew);

	// generate the scalar condition for the left anti-semi join
	CExpression *pexprScCond = CUtils::PexprConjINDFCond(pmp, pdrgpdrgpcrInputNew);

	// assemble the new left anti-semi join logical operator
	CExpression *pexprLASJ = GPOS_NEW(pmp) CExpression
										(
										pmp,
										GPOS_NEW(pmp) CLogicalLeftAntiSemiJoin(pmp),
										pexprLeftWindow,
										pexprRightWindow,
										pexprScCond
										);

	// clean up
	pdrgpdrgpcrInputNew->Release();

	// add alternative to results
	pxfres->Add(pexprLASJ);
}
//---------------------------------------------------------------------------
//	@function:
//		CXformDynamicGet2DynamicTableScan::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformDynamicGet2DynamicTableScan::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	CLogicalDynamicGet *popGet = CLogicalDynamicGet::PopConvert(pexpr->Pop());
	IMemoryPool *pmp = pxfctxt->Pmp();

	// create/extract components for alternative
	CName *pname = GPOS_NEW(pmp) CName(pmp, popGet->Name());
	
	CTableDescriptor *ptabdesc = popGet->Ptabdesc();
	ptabdesc->AddRef();
	
	DrgPcr *pdrgpcrOutput = popGet->PdrgpcrOutput();
	GPOS_ASSERT(NULL != pdrgpcrOutput);

	pdrgpcrOutput->AddRef();
	
	DrgDrgPcr *pdrgpdrgpcrPart = popGet->PdrgpdrgpcrPart();
	pdrgpdrgpcrPart->AddRef();
	
	popGet->Ppartcnstr()->AddRef();
	popGet->PpartcnstrRel()->AddRef();
	
	// create alternative expression
	CExpression *pexprAlt = 
		GPOS_NEW(pmp) CExpression
			(
			pmp,
			GPOS_NEW(pmp) CPhysicalDynamicTableScan
						(
						pmp,
						popGet->FPartial(),
						pname, 
						ptabdesc,
						popGet->UlOpId(),
						popGet->UlScanId(), 
						pdrgpcrOutput,
						pdrgpdrgpcrPart,
						popGet->UlSecondaryScanId(),
						popGet->Ppartcnstr(),
						popGet->PpartcnstrRel()
						)
			);
	// add alternative to transformation result
	pxfres->Add(pexprAlt);
}
Example #9
0
//---------------------------------------------------------------------------
//	@function:
//		CXformGbAgg2StreamAgg::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformGbAgg2StreamAgg::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));
	CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(pexpr->Pop());
	IMemoryPool *pmp = pxfctxt->Pmp();
	DrgPcr *pdrgpcr = popAgg->Pdrgpcr();
	pdrgpcr->AddRef();
	
	// extract components
	CExpression *pexprRel = (*pexpr)[0];
	CExpression *pexprScalar = (*pexpr)[1];

	// addref children
	pexprRel->AddRef();
	pexprScalar->AddRef();

	DrgPcr *pdrgpcrArgDQA = popAgg->PdrgpcrArgDQA();
	if (0 != pdrgpcrArgDQA->UlSafeLength())
	{
		GPOS_ASSERT(NULL != pdrgpcrArgDQA);
		pdrgpcrArgDQA->AddRef();
	}

	// create alternative expression
	CExpression *pexprAlt = 
		GPOS_NEW(pmp) CExpression
			(
			pmp,
			GPOS_NEW(pmp) CPhysicalStreamAgg
						(
						pmp,
						pdrgpcr,
						popAgg->PdrgpcrMinimal(),
						popAgg->Egbaggtype(),
						popAgg->FGeneratesDuplicates(),
						pdrgpcrArgDQA,
						CXformUtils::FMultiStageAgg(pexpr)
						),
			pexprRel,
			pexprScalar
			);

	// add alternative to transformation result
	pxfres->Add(pexprAlt);
}
//---------------------------------------------------------------------------
//	@function:
//		CXformGbAggDedup2HashAggDedup::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformGbAggDedup2HashAggDedup::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	IMemoryPool *pmp = pxfctxt->Pmp();
	CLogicalGbAggDeduplicate *popAggDedup = CLogicalGbAggDeduplicate::PopConvert(pexpr->Pop());
	DrgPcr *pdrgpcr = popAggDedup->Pdrgpcr();
	pdrgpcr->AddRef();

	DrgPcr *pdrgpcrKeys = popAggDedup->PdrgpcrKeys();
	pdrgpcrKeys->AddRef();

	// extract components
	CExpression *pexprRel = (*pexpr)[0];
	CExpression *pexprScalar = (*pexpr)[1];
	GPOS_ASSERT(0 == pexprScalar->UlArity());

	// addref children
	pexprRel->AddRef();
	pexprScalar->AddRef();

	// create alternative expression
	CExpression *pexprAlt =
		GPOS_NEW(pmp) CExpression
			(
			pmp,
			GPOS_NEW(pmp) CPhysicalHashAggDeduplicate
						(
						pmp,
						pdrgpcr,
						popAggDedup->PdrgpcrMinimal(),
						popAggDedup->Egbaggtype(),
						pdrgpcrKeys,
						popAggDedup->FGeneratesDuplicates(),
						CXformUtils::FMultiStageAgg(pexpr)
						),
			pexprRel,
			pexprScalar
			);

	// add alternative to transformation result
	pxfres->Add(pexprAlt);
}
Example #11
0
//---------------------------------------------------------------------------
//	@function:
//		CXformSimplifyGbAgg::FDropGbAgg
//
//	@doc:
//		Return true if GbAgg operator can be dropped because grouping
//		columns include a key
//
//---------------------------------------------------------------------------
BOOL
CXformSimplifyGbAgg::FDropGbAgg
	(
	IMemoryPool *pmp,
	CExpression *pexpr,
	CXformResult *pxfres
	)
{
	CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(pexpr->Pop());
	CExpression *pexprRelational = (*pexpr)[0];
	CExpression *pexprProjectList = (*pexpr)[1];

	if (0 < pexprProjectList->UlArity())
	{
		// GbAgg cannot be dropped if Agg functions are computed
		return false;
	}

	CKeyCollection *pkc = CDrvdPropRelational::Pdprel(pexprRelational->PdpDerive())->Pkc();
	if (NULL == pkc)
	{
		// relational child does not have key
		return false;
	}

	const ULONG ulKeys = pkc->UlKeys();
	BOOL fDrop = false;
	for (ULONG ul = 0; !fDrop && ul < ulKeys; ul++)
	{
		DrgPcr *pdrgpcrKey = pkc->PdrgpcrKey(pmp, ul);
		CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp, pdrgpcrKey);
		pdrgpcrKey->Release();

		CColRefSet *pcrsGrpCols = GPOS_NEW(pmp) CColRefSet(pmp);
		pcrsGrpCols->Include(popAgg->Pdrgpcr());
		BOOL fGrpColsHasKey = pcrsGrpCols->FSubset(pcrs);

		pcrs->Release();
		pcrsGrpCols->Release();
		if (fGrpColsHasKey)
		{
			// Gb operator can be dropped
			pexprRelational->AddRef();
			CExpression *pexprResult =
				CUtils::PexprLogicalSelect(pmp, pexprRelational, CPredicateUtils::PexprConjunction(pmp, NULL));
			pxfres->Add(pexprResult);
			fDrop = true;
		}
	}

	return fDrop;
}
Example #12
0
//---------------------------------------------------------------------------
//	@function:
//		CXformDelete2DML::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformDelete2DML::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	CLogicalDelete *popDelete = CLogicalDelete::PopConvert(pexpr->Pop());
	IMemoryPool *pmp = pxfctxt->Pmp();

	// extract components for alternative

	CTableDescriptor *ptabdesc = popDelete->Ptabdesc();
	ptabdesc->AddRef();

	DrgPcr *pdrgpcr = popDelete->Pdrgpcr();
	pdrgpcr->AddRef();

	CColRef *pcrCtid = popDelete->PcrCtid();

	CColRef *pcrSegmentId = popDelete->PcrSegmentId();

	// child of delete operator
	CExpression *pexprChild = (*pexpr)[0];
	pexprChild->AddRef();

	// create logical DML
	CExpression *pexprAlt =
		CXformUtils::PexprLogicalDMLOverProject
						(
						pmp,
						pexprChild,
						CLogicalDML::EdmlDelete,
						ptabdesc,
						pdrgpcr,
						pcrCtid,
						pcrSegmentId
						);

	// add alternative to transformation result
	pxfres->Add(pexprAlt);
}
Example #13
0
//---------------------------------------------------------------------------
//	@function:
//		CColRefSet::Pdrgpcr
//
//	@doc:
//		Convert set into array
//
//---------------------------------------------------------------------------
DrgPcr *
CColRefSet::Pdrgpcr
	(
	IMemoryPool *pmp
	)
	const
{
	DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);
	
	CColRefSetIter crsi(*this);
	while(crsi.FAdvance())
	{
		pdrgpcr->Append(crsi.Pcr());
	}
	
	return pdrgpcr;
}
//---------------------------------------------------------------------------
//	@function:
//		CXformImplementSplit::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformImplementSplit::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	CLogicalSplit *popSplit = CLogicalSplit::PopConvert(pexpr->Pop());
	IMemoryPool *pmp = pxfctxt->Pmp();

	// extract components for alternative
	DrgPcr *pdrgpcrDelete = popSplit->PdrgpcrDelete();
	pdrgpcrDelete->AddRef();

	DrgPcr *pdrgpcrInsert = popSplit->PdrgpcrInsert();
	pdrgpcrInsert->AddRef();

	CColRef *pcrAction = popSplit->PcrAction();
	CColRef *pcrCtid = popSplit->PcrCtid();
	CColRef *pcrSegmentId = popSplit->PcrSegmentId();
	CColRef *pcrTupleOid = popSplit->PcrTupleOid();

	// child of Split operator
	CExpression *pexprChild = (*pexpr)[0];
	CExpression *pexprProjList = (*pexpr)[1];
	pexprChild->AddRef();
	pexprProjList->AddRef();

	// create physical Split
	CExpression *pexprAlt =
		GPOS_NEW(pmp) CExpression
			(
			pmp,
			GPOS_NEW(pmp) CPhysicalSplit(pmp, pdrgpcrDelete, pdrgpcrInsert, pcrCtid, pcrSegmentId, pcrAction, pcrTupleOid),
			pexprChild,
			pexprProjList
			);
	// add alternative to transformation result
	pxfres->Add(pexprAlt);
}
//---------------------------------------------------------------------------
//	@function:
//		CXformImplementInnerIndexApply::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformImplementInnerIndexApply::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	IMemoryPool *pmp = pxfctxt->Pmp();

	// extract components
	CExpression *pexprOuter = (*pexpr)[0];
	CExpression *pexprInner = (*pexpr)[1];
	CExpression *pexprScalar = (*pexpr)[2];
	DrgPcr *pdrgpcr = CLogicalInnerIndexApply::PopConvert(pexpr->Pop())->PdrgPcrOuterRefs();
	pdrgpcr->AddRef();

	// addref all components
	pexprOuter->AddRef();
	pexprInner->AddRef();
	pexprScalar->AddRef();

	// assemble physical operator
	CExpression *pexprResult =
		GPOS_NEW(pmp) CExpression
					(
					pmp,
					GPOS_NEW(pmp) CPhysicalInnerIndexNLJoin(pmp, pdrgpcr),
					pexprOuter,
					pexprInner,
					pexprScalar
					);

	// add alternative to results
	pxfres->Add(pexprResult);
}
Example #16
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalUnionAll::PdrgpulMap
//
//	@doc:
//		Map given array of scalar identifier expressions to positions of
//		UnionAll input columns in the given child;
//		the function returns NULL if no mapping could be constructed
//
//---------------------------------------------------------------------------
DrgPul *
CPhysicalUnionAll::PdrgpulMap
	(
	IMemoryPool *pmp,
	DrgPexpr *pdrgpexpr,
	ULONG ulChildIndex
	)
	const
{
	GPOS_ASSERT(NULL != pdrgpexpr);

	DrgPcr *pdrgpcr = (*m_pdrgpdrgpcrInput)[ulChildIndex];
	const ULONG ulExprs = pdrgpexpr->UlLength();
	const ULONG ulCols = pdrgpcr->UlLength();
	DrgPul *pdrgpul = GPOS_NEW(pmp) DrgPul(pmp);
	for (ULONG ulExpr = 0; ulExpr < ulExprs; ulExpr++)
	{
		CExpression *pexpr = (*pdrgpexpr)[ulExpr];
		if (COperator::EopScalarIdent != pexpr->Pop()->Eopid())
		{
			continue;
		}
		const CColRef *pcr = CScalarIdent::PopConvert(pexpr->Pop())->Pcr();
		for (ULONG ulCol = 0; ulCol < ulCols; ulCol++)
		{
			if ((*pdrgpcr)[ulCol] == pcr)
			{
				pdrgpul->Append(GPOS_NEW(pmp) ULONG(ulCol));
			}
		}
	}

	if (0 == pdrgpul->UlLength())
	{
		// mapping failed
		pdrgpul->Release();
		pdrgpul = NULL;
	}

	return pdrgpul;
}
Example #17
0
//---------------------------------------------------------------------------
//	@function:
//		CKeyCollection::PdrgpcrHashableKey
//
//	@doc:
//		Extract a hashable key
//
//---------------------------------------------------------------------------
DrgPcr *
CKeyCollection::PdrgpcrHashableKey
	(
	IMemoryPool *pmp
	)
	const
{
	const ULONG ulSets = m_pdrgpcrs->UlLength();
	for(ULONG ul = 0; ul < ulSets; ul++)
	{
		DrgPcr *pdrgpcrKey = (*m_pdrgpcrs)[ul]->Pdrgpcr(pmp);
		if (CUtils::FHashable(pdrgpcrKey))
		{
			return pdrgpcrKey;
		}
		pdrgpcrKey->Release();
	}

	// no hashable key is found
	return NULL;
}
//---------------------------------------------------------------------------
//	@function:
//		CDistributionSpecHashed::PdshashedMaximal
//
//	@doc:
//		Return a hashed distribution on the maximal hashable subset of
//		given columns,
//		if all columns are not hashable, return NULL
//
//---------------------------------------------------------------------------
CDistributionSpecHashed *
CDistributionSpecHashed::PdshashedMaximal
	(
	IMemoryPool *pmp,
	DrgPcr *pdrgpcr,
	BOOL fNullsColocated
	)
{
	GPOS_ASSERT(NULL != pdrgpcr);
	GPOS_ASSERT(0 < pdrgpcr->UlLength());

	DrgPcr *pdrgpcrHashable = CUtils::PdrgpcrHashableSubset(pmp, pdrgpcr);
	CDistributionSpecHashed *pdshashed = NULL;
	if (0 < pdrgpcrHashable->UlLength())
	{
		DrgPexpr *pdrgpexpr = CUtils::PdrgpexprScalarIdents(pmp, pdrgpcrHashable);
		pdshashed = GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, fNullsColocated);
	}
	pdrgpcrHashable->Release();

	return pdshashed;
}
Example #19
0
//---------------------------------------------------------------------------
//	@function:
//		CPartKeys::PpartkeysCopy
//
//	@doc:
//		Copy part key into the given memory pool
//
//---------------------------------------------------------------------------
CPartKeys *
CPartKeys::PpartkeysCopy
	(
	IMemoryPool *pmp
	)
{
	DrgDrgPcr *pdrgpdrgpcrCopy = GPOS_NEW(pmp) DrgDrgPcr(pmp);

	const ULONG ulLength = m_pdrgpdrgpcr->UlLength();
	for (ULONG ul = 0; ul < ulLength; ul++)
	{
		DrgPcr *pdrgpcr = (*m_pdrgpdrgpcr)[ul];
		DrgPcr *pdrgpcrCopy = GPOS_NEW(pmp) DrgPcr(pmp);
		const ULONG ulCols = pdrgpcr->UlLength();
		for (ULONG ulCol = 0; ulCol < ulCols; ulCol++)
		{
			pdrgpcrCopy->Append((*pdrgpcr)[ulCol]);
		}
		pdrgpdrgpcrCopy->Append(pdrgpcrCopy);
	}

	return GPOS_NEW(pmp) CPartKeys(pdrgpdrgpcrCopy);
}
//---------------------------------------------------------------------------
//	@function:
//		CTranslatorDXLToExprUtils::Pdrgpcr
//
//	@doc:
// 		Construct a dynamic array of column references corresponding to the
//		given col ids
//
//---------------------------------------------------------------------------
DrgPcr *
CTranslatorDXLToExprUtils::Pdrgpcr
	(
	IMemoryPool *pmp,
	HMUlCr *phmulcr,
	const DrgPul *pdrgpulColIds
	)
{
	GPOS_ASSERT(NULL != pdrgpulColIds);

	DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);

	for (ULONG ul = 0; ul < pdrgpulColIds->UlLength(); ul++)
	{
		ULONG *pulColId = (*pdrgpulColIds)[ul];
		const CColRef *pcr = phmulcr->PtLookup(pulColId);
		GPOS_ASSERT(NULL != pcr);

		pdrgpcr->Append(const_cast<CColRef*>(pcr));
	}

	return pdrgpcr;
}
Example #21
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalUnion::CLogicalUnion
//
//	@doc:
//		Ctor
//
//---------------------------------------------------------------------------
CLogicalUnion::CLogicalUnion
	(
	IMemoryPool *pmp,
	DrgPcr *pdrgpcrOutput,
	DrgDrgPcr *pdrgpdrgpcrInput
	)
	:
	CLogicalSetOp(pmp, pdrgpcrOutput, pdrgpdrgpcrInput)
{

#ifdef GPOS_DEBUG
	DrgPcr *pdrgpcrInput = (*pdrgpdrgpcrInput)[0];
	const ULONG ulCols = pdrgpcrOutput->UlLength();
	GPOS_ASSERT(ulCols == pdrgpcrInput->UlLength());

	// Ensure that the output columns are the same as first input
	for(ULONG ul = 0; ul < ulCols; ul++)
	{
		GPOS_ASSERT( (*pdrgpcrOutput)[ul] == (*pdrgpcrInput)[ul]);
	}

#endif // GPOS_DEBUG
}
Example #22
0
//---------------------------------------------------------------------------
//	@function:
//		CPartKeys::PpartkeysRemap
//
//	@doc:
//		Create a new PartKeys object from the current one by remapping the
//		keys using the given hashmap
//
//---------------------------------------------------------------------------
CPartKeys *
CPartKeys::PpartkeysRemap
	(
	IMemoryPool *pmp,
	HMUlCr *phmulcr
	)
	const
{
	GPOS_ASSERT(NULL != phmulcr);
	DrgDrgPcr *pdrgpdrgpcr = GPOS_NEW(pmp) DrgDrgPcr(pmp);

	for (ULONG ul = 0; ul < m_ulLevels; ul++)
	{
		CColRef *pcr = CUtils::PcrRemap(PcrKey(ul), phmulcr, false /*fMustExist*/);

		DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);
		pdrgpcr->Append(pcr);

		pdrgpdrgpcr->Append(pdrgpcr);
	}

	return GPOS_NEW(pmp) CPartKeys(pdrgpdrgpcr);
}
//---------------------------------------------------------------------------
//	@function:
//		CXformImplementConstTableGet::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformImplementConstTableGet::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	CLogicalConstTableGet *popConstTableGet = CLogicalConstTableGet::PopConvert(pexpr->Pop());
	IMemoryPool *pmp = pxfctxt->Pmp();

	// create/extract components for alternative
	DrgPcoldesc *pdrgpcoldesc = popConstTableGet->Pdrgpcoldesc();
	pdrgpcoldesc->AddRef();
	
	DrgPdrgPdatum *pdrgpdrgpdatum = popConstTableGet->Pdrgpdrgpdatum();
	pdrgpdrgpdatum->AddRef();
	
	DrgPcr *pdrgpcrOutput = popConstTableGet->PdrgpcrOutput();
	pdrgpcrOutput->AddRef();
		
	// create alternative expression
	CExpression *pexprAlt = 
		GPOS_NEW(pmp) CExpression
			(
			pmp,
			GPOS_NEW(pmp) CPhysicalConstTableGet(pmp, pdrgpcoldesc, pdrgpdrgpdatum, pdrgpcrOutput)
			);
	
	// add alternative to transformation result
	pxfres->Add(pexprAlt);
}
//---------------------------------------------------------------------------
//	@function:
//		CXformSelect2PartialDynamicIndexGet::CreatePartialIndexGetPlan
//
//	@doc:
//		Create a plan as a union of the given partial index get candidates and 
//		possibly a dynamic table scan
//
//---------------------------------------------------------------------------
void
CXformSelect2PartialDynamicIndexGet::CreatePartialIndexGetPlan
	(
	IMemoryPool *pmp,
	CExpression *pexpr,
	DrgPpartdig *pdrgppartdig,
	const IMDRelation *pmdrel,
	CXformResult *pxfres
	)
	const
{ 
	CExpression *pexprRelational = (*pexpr)[0];
	CExpression *pexprScalar = (*pexpr)[1];

	CLogicalDynamicGet *popGet = CLogicalDynamicGet::PopConvert(pexprRelational->Pop());
	DrgPcr *pdrgpcrGet = popGet->PdrgpcrOutput();
	
	const ULONG ulPartialIndexes = pdrgppartdig->UlLength();
	
	DrgDrgPcr *pdrgpdrgpcrInput = GPOS_NEW(pmp) DrgDrgPcr(pmp);
	DrgPexpr *pdrgpexprInput = GPOS_NEW(pmp) DrgPexpr(pmp);
	for (ULONG ul = 0; ul < ulPartialIndexes; ul++)
	{
		SPartDynamicIndexGetInfo *ppartdig = (*pdrgppartdig)[ul];

		const IMDIndex *pmdindex = ppartdig->m_pmdindex;
		CPartConstraint *ppartcnstr = ppartdig->m_ppartcnstr;
		DrgPexpr *pdrgpexprIndex = ppartdig->m_pdrgpexprIndex;
		DrgPexpr *pdrgpexprResidual = ppartdig->m_pdrgpexprResidual;
		
		DrgPcr *pdrgpcrNew = pdrgpcrGet;

		if (0 < ul)
		{
			pdrgpcrNew = CUtils::PdrgpcrCopy(pmp, pdrgpcrGet);
		}
		else
		{
			pdrgpcrNew->AddRef();
		}

		CExpression *pexprDynamicScan = NULL;
		if (NULL != pmdindex)
		{
			pexprDynamicScan = CXformUtils::PexprPartialDynamicIndexGet
								(
								pmp,
								popGet,
								pexpr->Pop()->UlOpId(),
								pdrgpexprIndex,
								pdrgpexprResidual,
								pdrgpcrNew,
								pmdindex,
								pmdrel,
								ppartcnstr,
								NULL, // pcrsAcceptedOuterRefs
								NULL, // pdrgpcrOuter
								NULL // pdrgpcrNewOuter
								);
		}
		else
		{
			pexprDynamicScan = PexprSelectOverDynamicGet
								(
								pmp,
								popGet,
								pexprScalar,
								pdrgpcrNew,
								ppartcnstr
								);
		}
		GPOS_ASSERT(NULL != pexprDynamicScan);

		pdrgpdrgpcrInput->Append(pdrgpcrNew);
		pdrgpexprInput->Append(pexprDynamicScan);
	}

	ULONG ulInput = pdrgpexprInput->UlLength();
	if (0 < ulInput)
	{
		CExpression *pexprResult = NULL;
		if (1 < ulInput)
		{
			pdrgpcrGet->AddRef();
			DrgPcr *pdrgpcrOuter = pdrgpcrGet;

			// construct a new union all operator
			pexprResult = GPOS_NEW(pmp) CExpression
							(
							pmp,
							GPOS_NEW(pmp) CLogicalUnionAll(pmp, pdrgpcrOuter, pdrgpdrgpcrInput, popGet->UlScanId()),
							pdrgpexprInput
							);
		}
		else
		{
			pexprResult = (*pdrgpexprInput)[0];
			pexprResult->AddRef();

			// clean up
			pdrgpexprInput->Release();
			pdrgpdrgpcrInput->Release();
		}

		// if scalar expression involves the partitioning key, keep a SELECT node
		// on top for the purposes of partition selection
		DrgDrgPcr *pdrgpdrgpcrPartKeys = popGet->PdrgpdrgpcrPart();
		CExpression *pexprPredOnPartKey = CPredicateUtils::PexprExtractPredicatesOnPartKeys
											(
											pmp,
											pexprScalar,
											pdrgpdrgpcrPartKeys,
											NULL, /*pcrsAllowedRefs*/
											true /*fUseConstraints*/
											);
		
		if (NULL != pexprPredOnPartKey)
		{
			pexprResult = GPOS_NEW(pmp) CExpression(pmp, GPOS_NEW(pmp) CLogicalSelect(pmp), pexprResult, pexprPredOnPartKey);
		}
		
		pxfres->Add(pexprResult);

		return;
	}

	// clean up
	pdrgpdrgpcrInput->Release();
	pdrgpexprInput->Release();
}
Example #25
0
//---------------------------------------------------------------------------
//	@function:
//		CXformSimplifyGbAgg::Transform
//
//	@doc:
//		Actual transformation to simplify a aggregate expression
//
//---------------------------------------------------------------------------
void
CXformSimplifyGbAgg::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(NULL != pxfres);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	IMemoryPool *pmp = pxfctxt->Pmp();

	if (FDropGbAgg(pmp, pexpr,pxfres))
	{
		 // grouping columns could be dropped, GbAgg is transformed to a Select
		return;
	}

	// extract components
	CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(pexpr->Pop());
	CExpression *pexprRelational = (*pexpr)[0];
	CExpression *pexprProjectList = (*pexpr)[1];

	DrgPcr *pdrgpcr = popAgg->Pdrgpcr();
	CColRefSet *pcrsGrpCols = GPOS_NEW(pmp) CColRefSet(pmp);
	pcrsGrpCols->Include(pdrgpcr);

	CColRefSet *pcrsCovered = GPOS_NEW(pmp) CColRefSet(pmp);	// set of grouping columns covered by FD's
	CColRefSet *pcrsMinimal = GPOS_NEW(pmp) CColRefSet(pmp); // a set of minimal grouping columns based on FD's
	DrgPfd *pdrgpfd = CDrvdPropRelational::Pdprel(pexpr->PdpDerive())->Pdrgpfd();

	// collect grouping columns FD's
	const ULONG ulSize = pdrgpfd->UlSafeLength();
	for (ULONG ul = 0; ul < ulSize; ul++)
	{
		CFunctionalDependency *pfd = (*pdrgpfd)[ul];
		if (pfd->FIncluded(pcrsGrpCols))
		{
			pcrsCovered->Include(pfd->PcrsDetermined());
			pcrsCovered->Include(pfd->PcrsKey());
			pcrsMinimal->Include(pfd->PcrsKey());
		}
	}
	BOOL fCovered = pcrsCovered->FEqual(pcrsGrpCols);
	pcrsGrpCols->Release();
	pcrsCovered->Release();

	if (!fCovered)
	{
		// the union of RHS of collected FD's does not cover all grouping columns
		pcrsMinimal->Release();
		return;
	}

	// create a new Agg with minimal grouping columns
	pdrgpcr->AddRef();

	CLogicalGbAgg *popAggNew = GPOS_NEW(pmp) CLogicalGbAgg(pmp, pdrgpcr, pcrsMinimal->Pdrgpcr(pmp), popAgg->Egbaggtype());
	pcrsMinimal->Release();
	GPOS_ASSERT(!popAgg->FMatch(popAggNew) && "Simplified aggregate matches original aggregate");

	pexprRelational->AddRef();
	pexprProjectList->AddRef();
	CExpression *pexprResult = GPOS_NEW(pmp) CExpression(pmp, popAggNew, pexprRelational, pexprProjectList);
	pxfres->Add(pexprResult);
}
//---------------------------------------------------------------------------
//	@function:
//		CXformInnerApplyWithOuterKey2InnerJoin::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformInnerApplyWithOuterKey2InnerJoin::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	IMemoryPool *pmp = pxfctxt->Pmp();

	// extract components
	CExpression *pexprOuter = (*pexpr)[0];
	CExpression *pexprGb = (*pexpr)[1];
	CExpression *pexprScalar = (*pexpr)[2];

	if (0 < CLogicalGbAgg::PopConvert(pexprGb->Pop())->Pdrgpcr()->UlLength())
	{
		// xform is not applicable if inner Gb has grouping columns
		return;
	}

	if (CUtils::FHasSubqueryOrApply((*pexprGb)[0]))
	{
		// Subquery/Apply must be unnested before reaching here
		return;
	}

	// decorrelate Gb's relational child
	(*pexprGb)[0]->ResetDerivedProperties();
	CExpression *pexprInner = NULL;
	DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
	if (!CDecorrelator::FProcess(pmp, (*pexprGb)[0], false /*fEqualityOnly*/, &pexprInner, pdrgpexpr))
	{
		pdrgpexpr->Release();
		return;
	}

	GPOS_ASSERT(NULL != pexprInner);
	CExpression *pexprPredicate = CPredicateUtils::PexprConjunction(pmp, pdrgpexpr);

	// join outer child with Gb's decorrelated child
	pexprOuter->AddRef();
	CExpression *pexprInnerJoin =
		GPOS_NEW(pmp) CExpression
			(
			pmp,
			GPOS_NEW(pmp) CLogicalInnerJoin(pmp),
			pexprOuter,
			pexprInner,
			pexprPredicate
			);

	// create grouping columns from the output of outer child
	DrgPcr *pdrgpcrKey = NULL;
	DrgPcr *pdrgpcr = CUtils::PdrgpcrGroupingKey(pmp, pexprOuter, &pdrgpcrKey);
	pdrgpcrKey->Release();  // key is not used here

	CLogicalGbAgg *popGbAgg = GPOS_NEW(pmp) CLogicalGbAgg(pmp, pdrgpcr, COperator::EgbaggtypeGlobal /*egbaggtype*/);
	CExpression *pexprPrjList = (*pexprGb)[1];
	pexprPrjList->AddRef();
	CExpression *pexprNewGb = GPOS_NEW(pmp) CExpression (pmp, popGbAgg, pexprInnerJoin, pexprPrjList);

	// add Apply predicate in a top Select node
	pexprScalar->AddRef();
	CExpression *pexprSelect = CUtils::PexprLogicalSelect(pmp, pexprNewGb, pexprScalar);

	pxfres->Add(pexprSelect);
}
Example #27
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PpcDeriveConstraintFromTable
//
//	@doc:
//		Derive constraint property from a table/index get
//
//---------------------------------------------------------------------------
CPropConstraint *
CLogical::PpcDeriveConstraintFromTable
	(
	IMemoryPool *pmp,
	const CTableDescriptor *ptabdesc,
	const DrgPcr *pdrgpcrOutput
	)
{
	DrgPcrs *pdrgpcrs = GPOS_NEW(pmp) DrgPcrs(pmp);

	DrgPcnstr *pdrgpcnstr = GPOS_NEW(pmp) DrgPcnstr(pmp);

	const DrgPcoldesc *pdrgpcoldesc = ptabdesc->Pdrgpcoldesc();
	const ULONG ulCols = pdrgpcoldesc->UlLength();

	DrgPcr *pdrgpcrNonSystem = GPOS_NEW(pmp) DrgPcr(pmp);

	for (ULONG ul = 0; ul < ulCols; ul++)
	{
		CColumnDescriptor *pcoldesc = (*pdrgpcoldesc)[ul];
		CColRef *pcr = (*pdrgpcrOutput)[ul];
		// we are only interested in non-system columns that are defined as
		// being NOT NULL

		if (pcoldesc->FSystemColumn())
		{
			continue;
		}

		pdrgpcrNonSystem->Append(pcr);

		if (pcoldesc->FNullable())
		{
			continue;
		}

		// add a "not null" constraint and an equivalence class
		CConstraint * pcnstr = CConstraintInterval::PciUnbounded(pmp, pcr, false /*fIncludesNull*/);

		if (pcnstr == NULL)
		{
			continue;
		}
		pdrgpcnstr->Append(pcnstr);

		CColRefSet *pcrsEquiv = GPOS_NEW(pmp) CColRefSet(pmp);
		pcrsEquiv->Include(pcr);
		pdrgpcrs->Append(pcrsEquiv);
	}

	CMDAccessor *pmda = COptCtxt::PoctxtFromTLS()->Pmda();
	const IMDRelation *pmdrel = pmda->Pmdrel(ptabdesc->Pmdid());

	const ULONG ulCheckConstraint = pmdrel->UlCheckConstraints();
	for (ULONG ul = 0; ul < ulCheckConstraint; ul++)
	{
		IMDId *pmdidCheckConstraint = pmdrel->PmdidCheckConstraint(ul);

		const IMDCheckConstraint *pmdCheckConstraint = pmda->Pmdcheckconstraint(pmdidCheckConstraint);

		// extract the check constraint expression
		CExpression *pexprCheckConstraint = pmdCheckConstraint->Pexpr(pmp, pmda, pdrgpcrNonSystem);
		GPOS_ASSERT(NULL != pexprCheckConstraint);
		GPOS_ASSERT(CUtils::FPredicate(pexprCheckConstraint));

		DrgPcrs *pdrgpcrsChild = NULL;
		CConstraint *pcnstr = CConstraint::PcnstrFromScalarExpr(pmp, pexprCheckConstraint, &pdrgpcrsChild);
		if (NULL != pcnstr)
		{
			pdrgpcnstr->Append(pcnstr);

			// merge with the equivalence classes we have so far
			DrgPcrs *pdrgpcrsMerged = CUtils::PdrgpcrsMergeEquivClasses(pmp, pdrgpcrs, pdrgpcrsChild);
			pdrgpcrs->Release();
			pdrgpcrs = pdrgpcrsMerged;
		}
		CRefCount::SafeRelease(pdrgpcrsChild);
		pexprCheckConstraint->Release();
	}

	pdrgpcrNonSystem->Release();

	return GPOS_NEW(pmp) CPropConstraint(pmp, pdrgpcrs, CConstraint::PcnstrConjunction(pmp, pdrgpcnstr));
}
Example #28
0
//---------------------------------------------------------------------------
//	@function:
//		CQueryContext::PqcGenerate
//
//	@doc:
// 		Generate the query context for the given expression and array of
//		output column ref ids
//
//---------------------------------------------------------------------------
CQueryContext *
CQueryContext::PqcGenerate
(
    IMemoryPool *pmp,
    CExpression * pexpr,
    DrgPul *pdrgpulQueryOutputColRefId,
    DrgPmdname *pdrgpmdname,
    BOOL fDeriveStats
)
{
    GPOS_ASSERT(NULL != pexpr && NULL != pdrgpulQueryOutputColRefId);

    CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp);
    DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);

    COptCtxt *poptctxt = COptCtxt::PoctxtFromTLS();
    CColumnFactory *pcf = poptctxt->Pcf();
    GPOS_ASSERT(NULL != pcf);

    const ULONG ulLen = pdrgpulQueryOutputColRefId->UlLength();
    for (ULONG ul = 0; ul < ulLen; ul++)
    {
        ULONG *pul = (*pdrgpulQueryOutputColRefId)[ul];
        GPOS_ASSERT(NULL != pul);

        CColRef *pcr = pcf->PcrLookup(*pul);
        GPOS_ASSERT(NULL != pcr);

        pcrs->Include(pcr);
        pdrgpcr->Append(pcr);
    }

    COrderSpec *pos = NULL;
    CExpression *pexprResult = pexpr;
    COperator *popTop = PopTop(pexpr);
    if (COperator::EopLogicalLimit == popTop->Eopid())
    {
        // top level operator is a limit, copy order spec to query context
        pos = CLogicalLimit::PopConvert(popTop)->Pos();
        pos->AddRef();
    }
    else
    {
        // no order required
        pos = GPOS_NEW(pmp) COrderSpec(pmp);
    }

    CDistributionSpec *pds = NULL;

    BOOL fDML = CUtils::FLogicalDML(pexpr->Pop());
    poptctxt->MarkDMLQuery(fDML);

    if (fDML)
    {
        pds = GPOS_NEW(pmp) CDistributionSpecAny(COperator::EopSentinel);
    }
    else
    {
        pds = GPOS_NEW(pmp) CDistributionSpecSingleton(CDistributionSpecSingleton::EstMaster);
    }

    CRewindabilitySpec *prs = GPOS_NEW(pmp) CRewindabilitySpec(CRewindabilitySpec::ErtNone /*ert*/);

    CEnfdOrder *peo = GPOS_NEW(pmp) CEnfdOrder(pos, CEnfdOrder::EomSatisfy);

    // we require satisfy matching on distribution since final query results must be sent to master
    CEnfdDistribution *ped = GPOS_NEW(pmp) CEnfdDistribution(pds, CEnfdDistribution::EdmSatisfy);

    CEnfdRewindability *per = GPOS_NEW(pmp) CEnfdRewindability(prs, CEnfdRewindability::ErmSatisfy);

    CCTEReq *pcter = poptctxt->Pcteinfo()->PcterProducers(pmp);

    CReqdPropPlan *prpp = GPOS_NEW(pmp) CReqdPropPlan(pcrs, peo, ped, per, pcter);

    pdrgpmdname->AddRef();
    return GPOS_NEW(pmp) CQueryContext(pmp, pexprResult, prpp, pdrgpcr, pdrgpmdname, fDeriveStats);
}
//---------------------------------------------------------------------------
//	@function:
//		CXformSplitGbAggDedup::Transform
//
//	@doc:
//		Actual transformation to expand a global aggregate into a pair of
//		local and global aggregate
//
//---------------------------------------------------------------------------
void
CXformSplitGbAggDedup::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(NULL != pxfres);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	IMemoryPool *pmp = pxfctxt->Pmp();
	CLogicalGbAggDeduplicate *popAggDedup = CLogicalGbAggDeduplicate::PopConvert(pexpr->Pop());

	// extract components
	CExpression *pexprRelational = (*pexpr)[0];
	CExpression *pexprProjectList = (*pexpr)[1];

	// check if the transformation is applicable
	if (!FApplicable(pexprProjectList))
	{
		return;
	}

	pexprRelational->AddRef();

	CExpression *pexprProjectListLocal = NULL;
	CExpression *pexprProjectListGlobal = NULL;

	(void) PopulateLocalGlobalProjectList(pmp, pexprProjectList, &pexprProjectListLocal, &pexprProjectListGlobal);
	GPOS_ASSERT(NULL != pexprProjectListLocal && NULL != pexprProjectListLocal);

	DrgPcr *pdrgpcr = popAggDedup->Pdrgpcr();
	pdrgpcr->AddRef();
	pdrgpcr->AddRef();

	DrgPcr *pdrgpcrMinimal = popAggDedup->PdrgpcrMinimal();
	if (NULL != pdrgpcrMinimal)
	{
		pdrgpcrMinimal->AddRef();
		pdrgpcrMinimal->AddRef();
	}

	DrgPcr *pdrgpcrKeys = popAggDedup->PdrgpcrKeys();
	pdrgpcrKeys->AddRef();
	pdrgpcrKeys->AddRef();

	CExpression *pexprLocal =
			GPOS_NEW(pmp) CExpression
						(
						pmp,
						GPOS_NEW(pmp) CLogicalGbAggDeduplicate(pmp, pdrgpcr, pdrgpcrMinimal, COperator::EgbaggtypeLocal /*egbaggtype*/, pdrgpcrKeys),
						pexprRelational,
						pexprProjectListLocal
						);

	CExpression *pexprGlobal =
			GPOS_NEW(pmp) CExpression
						(
						pmp,
						GPOS_NEW(pmp) CLogicalGbAggDeduplicate(pmp, pdrgpcr, pdrgpcrMinimal, COperator::EgbaggtypeGlobal /*egbaggtype*/, pdrgpcrKeys),
						pexprLocal,
						pexprProjectListGlobal
						);

	pxfres->Add(pexprGlobal);
}