Esempio n. 1
0
//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::OsPrint
//
//	@doc:
//		Debug print
//
//---------------------------------------------------------------------------
IOstream &
CPartInfo::OsPrint
	(
	IOstream &os
	)
	const
{
	const ULONG ulLength = m_pdrgppartentries->UlLength();
	os << "Part Consumers: ";
	for (ULONG ul = 0; ul < ulLength; ul++)
	{
		CPartInfoEntry *ppartinfoentry = (*m_pdrgppartentries)[ul];
		ppartinfoentry->OsPrint(os);

		// separator
		os << (ul == ulLength - 1 ? "" : ", ");
	}

	os << ", Part Keys: ";
	for (ULONG ulCons = 0; ulCons < ulLength; ulCons++)
	{
		DrgPpartkeys *pdrgppartkeys = Pdrgppartkeys(ulCons);
		os << "(";
		const ULONG ulPartKeys = pdrgppartkeys->UlLength();;
		for (ULONG ulPartKey = 0; ulPartKey < ulPartKeys; ulPartKey++)
		{
			os << *(*pdrgppartkeys)[ulPartKey];
			os << (ulPartKey == ulPartKeys - 1 ? "" : ", ");
		}
		os << ")";
		os << (ulCons == ulLength - 1 ? "" : ", ");
	}

	return os;
}
Esempio n. 2
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalJoin::PexprJoinPredOnPartKeys
//
//	@doc:
//		Helper to find join predicates on part keys. Returns NULL if not found
//
//---------------------------------------------------------------------------
CExpression *
CPhysicalJoin::PexprJoinPredOnPartKeys
	(
	IMemoryPool *pmp,
	CExpression *pexprScalar,
	CPartIndexMap *ppimSource,
	ULONG ulPartIndexId,
	CColRefSet *pcrsAllowedRefs
	)
{
	GPOS_ASSERT(NULL != pcrsAllowedRefs);

	CExpression *pexprPred = NULL;
	DrgPpartkeys *pdrgppartkeys = ppimSource->Pdrgppartkeys(ulPartIndexId);
	const ULONG ulKeysets = pdrgppartkeys->UlLength();
	for (ULONG ulKey = 0; NULL == pexprPred && ulKey < ulKeysets; ulKey++)
	{
		// get partition key
		DrgDrgPcr *pdrgpdrgpcrPartKeys = (*pdrgppartkeys)[ulKey]->Pdrgpdrgpcr();

		// try to generate a request with dynamic partition selection
		pexprPred = CPredicateUtils::PexprExtractPredicatesOnPartKeys
										(
										pmp,
										pexprScalar,
										pdrgpdrgpcrPartKeys,
										pcrsAllowedRefs,
										true // fUseConstraints
										);
	}

	return pexprPred;
}
Esempio n. 3
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalSelect::PexprPartPred
//
//	@doc:
//		Compute partition predicate to pass down to n-th child
//
//---------------------------------------------------------------------------
CExpression *
CLogicalSelect::PexprPartPred
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CExpression *, //pexprInput
	ULONG
#ifdef GPOS_DEBUG
	ulChildIndex
#endif //GPOS_DEBUG
	)
	const
{
	GPOS_ASSERT(0 == ulChildIndex);

	// in case of subquery in select predicate, we cannot extract the whole
	// predicate, and it would not be helpful anyway, so return NULL
	if (exprhdl.Pdpscalar(1 /*ulChildIndex*/)->FHasSubquery())
	{
		return NULL;
	}

	CExpression *pexprScalar = exprhdl.PexprScalarChild(1 /*ulChildIndex*/);
	GPOS_ASSERT(NULL != pexprScalar);

	// get partition keys
	CPartInfo *ppartinfo = exprhdl.Pdprel()->Ppartinfo();
	GPOS_ASSERT(NULL != ppartinfo);

	// we assume that the select is right on top of the dynamic get, so there
	// should be only one part consumer. If there is more, then we are higher up so
	// we do not push down any predicates
	if (1 != ppartinfo->UlConsumers())
	{
		return NULL;
	}

	CExpression *pexprPredOnPartKey = NULL;

	DrgPpartkeys *pdrgppartkeys = ppartinfo->Pdrgppartkeys(0 /*ulPos*/);
	const ULONG ulKeySets = pdrgppartkeys->UlLength();
	for (ULONG ul = 0; NULL == pexprPredOnPartKey && ul < ulKeySets; ul++)
	{
		pexprPredOnPartKey = CPredicateUtils::PexprExtractPredicatesOnPartKeys
												(
												pmp,
												pexprScalar,
												(*pdrgppartkeys)[ul]->Pdrgpdrgpcr(),
												NULL, //pcrsAllowedRefs
												true //fUseConstraints
												);
	}

	return pexprPredOnPartKey;
}
Esempio n. 4
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();
}