コード例 #1
0
ファイル: CLogical.cpp プロジェクト: HanumathRao/gporca
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PpcDeriveConstraintRestrict
//
//	@doc:
//		Derive constraint property only on the given columns
//
//---------------------------------------------------------------------------
CPropConstraint *
CLogical::PpcDeriveConstraintRestrict
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CColRefSet *pcrsOutput
	)
{
	// constraint property from relational child
	CPropConstraint *ppc = exprhdl.Pdprel(0)->Ppc();
	DrgPcrs *pdrgpcrs = ppc->PdrgpcrsEquivClasses();

	// construct new array of equivalence classes
	DrgPcrs *pdrgpcrsNew = GPOS_NEW(pmp) DrgPcrs(pmp);

	const ULONG ulLen = pdrgpcrs->UlLength();
	for (ULONG ul = 0; ul < ulLen; ul++)
	{
		CColRefSet *pcrsEquiv = GPOS_NEW(pmp) CColRefSet(pmp);
		pcrsEquiv->Include((*pdrgpcrs)[ul]);
		pcrsEquiv->Intersection(pcrsOutput);

		if (0 < pcrsEquiv->CElements())
		{
			pdrgpcrsNew->Append(pcrsEquiv);
		}
		else
		{
			pcrsEquiv->Release();
		}
	}

	CConstraint *pcnstrChild = ppc->Pcnstr();
	if (NULL == pcnstrChild)
	{
		return GPOS_NEW(pmp) CPropConstraint(pmp, pdrgpcrsNew, NULL);
	}

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

	// include only constraints on given columns
	CColRefSetIter crsi(*pcrsOutput);
	while (crsi.FAdvance())
	{
		CColRef *pcr = crsi.Pcr();
		CConstraint *pcnstrCol = pcnstrChild->Pcnstr(pmp, pcr);
		if (NULL == pcnstrCol)
		{
			continue;
		}

		if (pcnstrCol->FUnbounded())
		{
			pcnstrCol->Release();
			continue;
		}

		pdrgpcnstr->Append(pcnstrCol);
	}

	CConstraint *pcnstr = CConstraint::PcnstrConjunction(pmp, pdrgpcnstr);

	return GPOS_NEW(pmp) CPropConstraint(pmp, pdrgpcrsNew, pcnstr);
}
コード例 #2
0
ファイル: CConstraint.cpp プロジェクト: hsyuan/gporca
//---------------------------------------------------------------------------
//	@function:
//		CConstraint::PcnstrFromScalarBoolOp
//
//	@doc:
//		Create constraint from scalar boolean expression
//
//---------------------------------------------------------------------------
CConstraint *
CConstraint::PcnstrFromScalarBoolOp
(
    IMemoryPool *pmp,
    CExpression *pexpr,
    DrgPcrs **ppdrgpcrs // output equivalence classes
)
{
    GPOS_ASSERT(NULL != pexpr);
    GPOS_ASSERT(CUtils::FScalarBoolOp(pexpr));
    GPOS_ASSERT(NULL != ppdrgpcrs);
    GPOS_ASSERT(NULL == *ppdrgpcrs);

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

    const ULONG ulArity= pexpr->UlArity();
    for (ULONG ul = 0; ul < ulArity; ul++)
    {
        DrgPcrs *pdrgpcrsChild = NULL;
        CConstraint *pcnstrChild = PcnstrFromScalarExpr(pmp, (*pexpr)[ul], &pdrgpcrsChild);
        if (NULL == pcnstrChild || pcnstrChild->FUnbounded())
        {
            CRefCount::SafeRelease(pcnstrChild);
            CRefCount::SafeRelease(pdrgpcrsChild);
            if (CPredicateUtils::FOr(pexpr))
            {
                pdrgpcnstr->Release();
                return NULL;
            }
            continue;
        }
        GPOS_ASSERT(NULL != pdrgpcrsChild);

        pdrgpcnstr->Append(pcnstrChild);
        DrgPcrs *pdrgpcrsMerged = PdrgpcrsMergeFromBoolOp(pmp, pexpr, *ppdrgpcrs, pdrgpcrsChild);

        (*ppdrgpcrs)->Release();
        *ppdrgpcrs = pdrgpcrsMerged;
        pdrgpcrsChild->Release();
    }

    const ULONG ulLen = pdrgpcnstr->UlLength();
    if (0 == ulLen)
    {
        pdrgpcnstr->Release();
        return NULL;
    }

    if (1 == ulLen)
    {
        CConstraint *pcnstrChild = (*pdrgpcnstr)[0];
        pcnstrChild->AddRef();
        pdrgpcnstr->Release();

        if (CPredicateUtils::FNot(pexpr))
        {
            return GPOS_NEW(pmp) CConstraintNegation(pmp, pcnstrChild);
        }

        return pcnstrChild;
    }

    // we know we have more than one child
    if (CPredicateUtils::FAnd(pexpr))
    {
        return GPOS_NEW(pmp) CConstraintConjunction(pmp, pdrgpcnstr);
    }

    if (CPredicateUtils::FOr(pexpr))
    {
        return GPOS_NEW(pmp) CConstraintDisjunction(pmp, pdrgpcnstr);
    }

    return NULL;
}
コード例 #3
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalDynamicGetBase::PstatsDeriveFilter
//
//	@doc:
//		Derive stats from base table using filters on partition and/or index columns
//
//---------------------------------------------------------------------------
IStatistics *
CLogicalDynamicGetBase::PstatsDeriveFilter
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CExpression *pexprFilter
	)
	const
{
	CExpression *pexprFilterNew = NULL;
	CConstraint *pcnstr = m_ppartcnstr->PcnstrCombined();
	if (m_fPartial && NULL != pcnstr && !pcnstr->FUnbounded())
	{
		if (NULL == pexprFilter)
		{
			pexprFilterNew = pcnstr->PexprScalar(pmp);
			pexprFilterNew->AddRef();
		}
		else
		{
			pexprFilterNew = CPredicateUtils::PexprConjunction(pmp, pexprFilter, pcnstr->PexprScalar(pmp));
		}
	}
	else if (NULL != pexprFilter)
	{
		pexprFilterNew = pexprFilter;
		pexprFilterNew->AddRef();
	}

	CColRefSet *pcrsStat = GPOS_NEW(pmp) CColRefSet(pmp);
	CDrvdPropScalar *pdpscalar = NULL;

	if (NULL != pexprFilterNew)
	{
		pdpscalar = CDrvdPropScalar::Pdpscalar(pexprFilterNew->PdpDerive());
		pcrsStat->Include(pdpscalar->PcrsUsed());
	}

	// requesting statistics on distribution columns to estimate data skew
	if (NULL != m_pcrsDist)
	{
		pcrsStat->Include(m_pcrsDist);
	}


	IStatistics *pstatsFullTable = PstatsBaseTable(pmp, exprhdl, m_ptabdesc, pcrsStat);
	
	pcrsStat->Release();
	
	if (NULL == pexprFilterNew || pdpscalar->FHasSubquery())
	{
		return pstatsFullTable;
	}

	CStatsPred *pstatspred =  CStatsPredUtils::PstatspredExtract
												(
												pmp, 
												pexprFilterNew, 
												NULL /*pcrsOuterRefs*/
												);
	pexprFilterNew->Release();

	IStatistics *pstatsResult = pstatsFullTable->PstatsFilter
													(
													pmp, 
													pstatspred, 
													true /* fCapNdvs */ 
													);
	pstatspred->Release();
	pstatsFullTable->Release();

	return pstatsResult;
}