示例#1
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);
}
示例#3
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalSetOp::FMatch
//
//	@doc:
//		Match function on operator level
//
//---------------------------------------------------------------------------
BOOL
CLogicalSetOp::FMatch
	(
	COperator *pop
	)
	const
{
	if (pop->Eopid() != Eopid())
	{
		return false;
	}

	CLogicalSetOp *popSetOp = CLogicalSetOp::PopConvert(pop);
	DrgDrgPcr *pdrgpdrgpcrInput = popSetOp->PdrgpdrgpcrInput();
	const ULONG ulArity = pdrgpdrgpcrInput->UlLength();

	if (ulArity != m_pdrgpdrgpcrInput->UlLength() ||
		!m_pdrgpcrOutput->FEqual(popSetOp->PdrgpcrOutput()))
	{
		return false;
	}

	for (ULONG ul = 0; ul < ulArity; ul++)
	{
		if (!(*m_pdrgpdrgpcrInput)[ul]->FEqual((*pdrgpdrgpcrInput)[ul]))
		{
			return false;
		}
	}

	return true;
}
//---------------------------------------------------------------------------
//	@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);
}
示例#6
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);
}
示例#7
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:
//		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();
}
示例#9
0
//---------------------------------------------------------------------------
//	@function:
//		CPartitionPropagationSpec::AppendEnforcers
//
//	@doc:
//		Add required enforcers to dynamic array
//
//---------------------------------------------------------------------------
void
CPartitionPropagationSpec::AppendEnforcers
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CReqdPropPlan *
#ifdef GPOS_DEBUG
	prpp
#endif // GPOS_DEBUG
	,
	DrgPexpr *pdrgpexpr, 
	CExpression *pexpr
	)
{
	GPOS_ASSERT(NULL != prpp);
	GPOS_ASSERT(NULL != pmp);
	GPOS_ASSERT(NULL != pdrgpexpr);
	GPOS_ASSERT(NULL != pexpr);
	
	DrgPul *pdrgpul = m_ppim->PdrgpulScanIds(pmp);
	const ULONG ulSize = pdrgpul->UlLength();
	
	for (ULONG ul = 0; ul < ulSize; ul++)
	{
		ULONG ulScanId = *((*pdrgpul)[ul]);
		GPOS_ASSERT(m_ppim->FContains(ulScanId));
		
		if (CPartIndexMap::EpimConsumer != m_ppim->Epim(ulScanId) || 0 < m_ppim->UlExpectedPropagators(ulScanId))
		{
			continue;
		}
		
		if (!FRequiresPartitionPropagation(pmp, pexpr, exprhdl, ulScanId))
		{
			continue;
		}
		
		CExpression *pexprResolver = NULL;

		IMDId *pmdid = m_ppim->PmdidRel(ulScanId);
		DrgDrgPcr *pdrgpdrgpcrKeys = NULL;
		DrgPpartkeys *pdrgppartkeys = m_ppim->Pdrgppartkeys(ulScanId);
		CPartConstraint *ppartcnstr = m_ppim->PpartcnstrRel(ulScanId);
		PartCnstrMap *ppartcnstrmap = m_ppim->Ppartcnstrmap(ulScanId);
		pmdid->AddRef();
		ppartcnstr->AddRef();
		ppartcnstrmap->AddRef();
		pexpr->AddRef();
		
		// check if there is a predicate on this part index id
		HMUlExpr *phmulexprEqFilter = GPOS_NEW(pmp) HMUlExpr(pmp);
		HMUlExpr *phmulexprFilter = GPOS_NEW(pmp) HMUlExpr(pmp);
		CExpression *pexprResidual = NULL;
		if (m_ppfm->FContainsScanId(ulScanId))
		{
			CExpression *pexprScalar = PexprFilter(pmp, ulScanId);
			
			// find out which keys are used in the predicate, in case there are multiple
			// keys at this point (e.g. from a union of multiple CTE consumers)
			CColRefSet *pcrsUsed = CDrvdPropScalar::Pdpscalar(pexprScalar->PdpDerive())->PcrsUsed();
			const ULONG ulKeysets = pdrgppartkeys->UlLength();
			for (ULONG ulKey = 0; NULL == pdrgpdrgpcrKeys && ulKey < ulKeysets; ulKey++)
			{
				// get partition key
				CPartKeys *ppartkeys = (*pdrgppartkeys)[ulKey];
				if (ppartkeys->FOverlap(pcrsUsed))
				{
					pdrgpdrgpcrKeys = ppartkeys->Pdrgpdrgpcr();
				}
			}
			
                        // if we cannot find partition keys mapping the partition predicates, fall back to planner
                        if (NULL == pdrgpdrgpcrKeys)
                        {
                            GPOS_RAISE(gpopt::ExmaGPOPT, gpopt::ExmiUnsatisfiedRequiredProperties);
                        }

			pdrgpdrgpcrKeys->AddRef();

			// split predicates and put them in the appropriate hashmaps
			SplitPartPredicates(pmp, pexprScalar, pdrgpdrgpcrKeys, phmulexprEqFilter, phmulexprFilter, &pexprResidual);
			pexprScalar->Release();
		}
		else
		{
			// doesn't matter which keys we use here since there is no filter
			GPOS_ASSERT(1 <= pdrgppartkeys->UlLength());
			pdrgpdrgpcrKeys = (*pdrgppartkeys)[0]->Pdrgpdrgpcr();
			pdrgpdrgpcrKeys->AddRef();
		}

		pexprResolver = GPOS_NEW(pmp) CExpression
									(
									pmp,
									GPOS_NEW(pmp) CPhysicalPartitionSelector
												(
												pmp,
												ulScanId,
												pmdid,
												pdrgpdrgpcrKeys,
												ppartcnstrmap,
												ppartcnstr,
												phmulexprEqFilter,
												phmulexprFilter,
												pexprResidual
												),
									pexpr
									);
		
		pdrgpexpr->Append(pexprResolver);
	}
	pdrgpul->Release();
}