Beispiel #1
0
//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::CPartInfoEntry::PpartinfoentryAddRemappedKeys
//
//	@doc:
//		Create a copy of the current object, and add a set of remapped
//		part keys to this entry, using the existing keys and the given hashmap
//
//---------------------------------------------------------------------------
CPartInfo::CPartInfoEntry *
CPartInfo::CPartInfoEntry::PpartinfoentryAddRemappedKeys
	(
	IMemoryPool *pmp,
	CColRefSet *pcrs,
	HMUlCr *phmulcr
	)
{
	GPOS_ASSERT(NULL != pcrs);
	GPOS_ASSERT(NULL != phmulcr);

    DrgPpartkeys *pdrgppartkeys = CPartKeys::PdrgppartkeysCopy(pmp, m_pdrgppartkeys);

	const ULONG ulSize = m_pdrgppartkeys->UlLength();
	for (ULONG ul = 0; ul < ulSize; ul++)
	{
		CPartKeys *ppartkeys = (*m_pdrgppartkeys)[ul];

		if (ppartkeys->FOverlap(pcrs))
		{
			pdrgppartkeys->Append(ppartkeys->PpartkeysRemap(pmp, phmulcr));
			break;
		}
	}

	m_pmdid->AddRef();
	CPartConstraint *ppartcnstrRel = m_ppartcnstrRel->PpartcnstrCopyWithRemappedColumns(pmp, phmulcr, false /*fMustExist*/);

	return GPOS_NEW(pmp) CPartInfoEntry(m_ulScanId, m_pmdid, pdrgppartkeys, ppartcnstrRel);
}
//---------------------------------------------------------------------------
//	@function:
//		CPartitionPropagationSpec::AppendEnforcers
//
//	@doc:
//		Add required enforcers to dynamic array
//
//---------------------------------------------------------------------------
void
CPartitionPropagationSpec::AppendEnforcers
	(
	IMemoryPool *mp,
	CExpressionHandle &exprhdl,
	CReqdPropPlan *
#ifdef GPOS_DEBUG
	prpp
#endif // GPOS_DEBUG
	,
	CExpressionArray *pdrgpexpr, 
	CExpression *pexpr
	)
{
	GPOS_ASSERT(NULL != prpp);
	GPOS_ASSERT(NULL != mp);
	GPOS_ASSERT(NULL != pdrgpexpr);
	GPOS_ASSERT(NULL != pexpr);
	
	ULongPtrArray *pdrgpul = m_ppim->PdrgpulScanIds(mp);
	const ULONG size = pdrgpul->Size();
	
	for (ULONG ul = 0; ul < size; ul++)
	{
		ULONG scan_id = *((*pdrgpul)[ul]);
		GPOS_ASSERT(m_ppim->Contains(scan_id));
		
		if (CPartIndexMap::EpimConsumer != m_ppim->Epim(scan_id) || 0 < m_ppim->UlExpectedPropagators(scan_id))
		{
			continue;
		}
		
		if (!FRequiresPartitionPropagation(mp, pexpr, exprhdl, scan_id))
		{
			continue;
		}
		
		CExpression *pexprResolver = NULL;

		IMDId *mdid = m_ppim->GetRelMdId(scan_id);
		CColRef2dArray *pdrgpdrgpcrKeys = NULL;
		CPartKeysArray *pdrgppartkeys = m_ppim->Pdrgppartkeys(scan_id);
		CPartConstraint *ppartcnstr = m_ppim->PpartcnstrRel(scan_id);
		UlongToPartConstraintMap *ppartcnstrmap = m_ppim->Ppartcnstrmap(scan_id);
		mdid->AddRef();
		ppartcnstr->AddRef();
		ppartcnstrmap->AddRef();
		pexpr->AddRef();
		
		// check if there is a predicate on this part index id
		UlongToExprMap *phmulexprEqFilter = GPOS_NEW(mp) UlongToExprMap(mp);
		UlongToExprMap *phmulexprFilter = GPOS_NEW(mp) UlongToExprMap(mp);
		CExpression *pexprResidual = NULL;
		if (m_ppfm->FContainsScanId(scan_id))
		{
			CExpression *pexprScalar = PexprFilter(mp, scan_id);
			
			// 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::GetDrvdScalarProps(pexprScalar->PdpDerive())->PcrsUsed();
			const ULONG ulKeysets = pdrgppartkeys->Size();
			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(mp, 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->Size());
			pdrgpdrgpcrKeys = (*pdrgppartkeys)[0]->Pdrgpdrgpcr();
			pdrgpdrgpcrKeys->AddRef();
		}

		pexprResolver = GPOS_NEW(mp) CExpression
									(
									mp,
									GPOS_NEW(mp) CPhysicalPartitionSelector
												(
												mp,
												scan_id,
												mdid,
												pdrgpdrgpcrKeys,
												ppartcnstrmap,
												ppartcnstr,
												phmulexprEqFilter,
												phmulexprFilter,
												pexprResidual
												),
									pexpr
									);
		
		pdrgpexpr->Append(pexprResolver);
	}
	pdrgpul->Release();
}