Beispiel #1
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PcrsDeriveCorrelatedApply
//
//	@doc:
//		Derive columns from the inner child of a correlated-apply expression
//		that can be used above the apply expression
//
//---------------------------------------------------------------------------
CColRefSet *
CLogical::PcrsDeriveCorrelatedApply
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl
	)
	const
{
	GPOS_ASSERT(this == exprhdl.Pop());

	ULONG ulArity = exprhdl.UlArity();
	CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp);

	if (CUtils::FCorrelatedApply(exprhdl.Pop()))
	{
		// add inner columns of correlated-apply expression
		pcrs->Include(CLogicalApply::PopConvert(exprhdl.Pop())->PdrgPcrInner());
	}

	// combine correlated-apply columns from logical children
	for (ULONG ul = 0; ul < ulArity; ul++)
	{
		if (!exprhdl.FScalarChild(ul))
		{
			CDrvdPropRelational *pdprel = exprhdl.Pdprel(ul);
			pcrs->Union(pdprel->PcrsCorrelatedApply());
		}
	}

	return pcrs;
}
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalPartitionSelector::PdsRequired
//
//	@doc:
//		Compute required distribution of the n-th child
//
//---------------------------------------------------------------------------
CDistributionSpec *
CPhysicalPartitionSelector::PdsRequired
	(
	IMemoryPool *mp,
	CExpressionHandle &exprhdl,
	CDistributionSpec *pdsInput,
	ULONG child_index,
	CDrvdProp2dArray *, // pdrgpdpCtxt
	ULONG // ulOptReq
	)
	const
{
	GPOS_ASSERT(0 == child_index);

	CDrvdPropRelational *pdprelDrvd = exprhdl.GetRelationalProperties();
	CPartInfo *ppartinfo = pdprelDrvd->Ppartinfo();
	BOOL fCovered = ppartinfo->FContainsScanId(m_scan_id);

	if (fCovered)
	{
		// if partition consumer is defined below, do not pass distribution
		// requirements down as this will cause the consumer and enforcer to be
		// in separate slices
		return GPOS_NEW(mp) CDistributionSpecAny(this->Eopid());
	}

	return PdsPassThru(mp, exprhdl, pdsInput, child_index);
}
Beispiel #3
0
//---------------------------------------------------------------------------
//	@function:
//		CXformTest::PexprStarJoinTree
//
//	@doc:
//		Generate a randomized star join tree
//
//---------------------------------------------------------------------------
CExpression *
CXformTest::PexprStarJoinTree
	(
	IMemoryPool *pmp,
	ULONG ulTabs
	)
{
	
	CExpression *pexprLeft = CTestUtils::PexprLogicalGet(pmp);
	
	for (ULONG ul = 1; ul < ulTabs; ul++)
	{
		CDrvdPropRelational *pdprelLeft = CDrvdPropRelational::Pdprel(pexprLeft->PdpDerive());
		CColRef *pcrLeft = pdprelLeft->PcrsOutput()->PcrAny();
	
		CExpression *pexprRight = CTestUtils::PexprLogicalGet(pmp);

		CDrvdPropRelational *pdprelRight = CDrvdPropRelational::Pdprel(pexprRight->PdpDerive());
		CColRef *pcrRight = pdprelRight->PcrsOutput()->PcrAny();
		
		CExpression *pexprPred = CUtils::PexprScalarEqCmp(pmp, pcrLeft, pcrRight);
		
		pexprLeft = CUtils::PexprLogicalJoin<CLogicalInnerJoin>(pmp, pexprLeft, pexprRight, pexprPred);
	}
	
	return pexprLeft;	
}
Beispiel #4
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PcrsDeriveOuter
//
//	@doc:
//		Derive outer references
//
//---------------------------------------------------------------------------
CColRefSet *
CLogical::PcrsDeriveOuter
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CColRefSet *pcrsUsedAdditional
	)
{
	ULONG ulArity = exprhdl.UlArity();
	CColRefSet *pcrsOuter = GPOS_NEW(pmp) CColRefSet(pmp);

	// collect output columns from relational children
	// and used columns from scalar children
	CColRefSet *pcrsOutput = GPOS_NEW(pmp) CColRefSet(pmp);

	CColRefSet *pcrsUsed = GPOS_NEW(pmp) CColRefSet(pmp);
	for (ULONG i = 0; i < ulArity; i++)
	{
		if (exprhdl.FScalarChild(i))
		{
			CDrvdPropScalar *pdpscalar = exprhdl.Pdpscalar(i);
			pcrsUsed->Union(pdpscalar->PcrsUsed());
		}
		else
		{
			CDrvdPropRelational *pdprel = exprhdl.Pdprel(i);
			pcrsOutput->Union(pdprel->PcrsOutput());

			// add outer references from relational children
			pcrsOuter->Union(pdprel->PcrsOuter());
		}
	}

	if (NULL != pcrsUsedAdditional)
	{
		pcrsUsed->Include(pcrsUsedAdditional);
	}

	// outer references are columns used by scalar child
	// but are not included in the output columns of relational children
	pcrsOuter->Union(pcrsUsed);
	pcrsOuter->Exclude(pcrsOutput);

	pcrsOutput->Release();
	pcrsUsed->Release();
	return pcrsOuter;
}
Beispiel #5
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PstatsBaseTable
//
//	@doc:
//		Helper for deriving statistics on a base table
//
//---------------------------------------------------------------------------
IStatistics *
CLogical::PstatsBaseTable
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CTableDescriptor *ptabdesc,
	CColRefSet *pcrsHistExtra   // additional columns required for stats, not required by parent
	)
{
	CReqdPropRelational *prprel = CReqdPropRelational::Prprel(exprhdl.Prp());
	CColRefSet *pcrsHist = GPOS_NEW(pmp) CColRefSet(pmp);
	pcrsHist->Include(prprel->PcrsStat());
	if (NULL != pcrsHistExtra)
	{
		pcrsHist->Include(pcrsHistExtra);
	}

	CDrvdPropRelational *pdprel = exprhdl.Pdprel();
	CColRefSet *pcrsOutput = pdprel->PcrsOutput();
	CColRefSet *pcrsWidth = GPOS_NEW(pmp) CColRefSet(pmp);
	pcrsWidth->Include(pcrsOutput);
	pcrsWidth->Exclude(pcrsHist);

	const COptCtxt *poctxt = COptCtxt::PoctxtFromTLS();
	CMDAccessor *pmda = poctxt->Pmda();
	CStatisticsConfig *pstatsconf = poctxt->Poconf()->Pstatsconf();

	IStatistics *pstats = pmda->Pstats
								(
								pmp,
								ptabdesc->Pmdid(),
								pcrsHist,
								pcrsWidth,
								pstatsconf
								);

	// clean up
	pcrsWidth->Release();
	pcrsHist->Release();

	return pstats;
}
Beispiel #6
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PstatsBaseTable
//
//	@doc:
//		Helper for deriving statistics on a base table
//
//---------------------------------------------------------------------------
IStatistics *
CLogical::PstatsBaseTable
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CTableDescriptor *ptabdesc,
	CColRefSet *pcrsStatExtra   // additional columns required for stats, not required by parent
	)
{
	// extract colids and attribute for which detailed stats are necessary
	CReqdPropRelational *prprel = CReqdPropRelational::Prprel(exprhdl.Prp());
	CColRefSet *pcrsStat = GPOS_NEW(pmp) CColRefSet(pmp);
	pcrsStat->Include(prprel->PcrsStat());
	if (NULL != pcrsStatExtra)
	{
		pcrsStat->Include(pcrsStatExtra);
	}

	DrgPul *pdrgpulHistColIds = GPOS_NEW(pmp) DrgPul(pmp);
	DrgPul *pdrgpulHistPos = GPOS_NEW(pmp) DrgPul(pmp);
	CUtils::ExtractColIdsAttno(pmp, ptabdesc, pcrsStat, pdrgpulHistColIds, pdrgpulHistPos);

	// extract colids and attribute for which widths are necessary
	CDrvdPropRelational *pdprel = exprhdl.Pdprel();
	CColRefSet *pcrsWidth = pdprel->PcrsOutput();
	DrgPul *pdrgpulWidthColIds = GPOS_NEW(pmp) DrgPul(pmp);
	DrgPul *pdrgpulWidthPos = GPOS_NEW(pmp) DrgPul(pmp);
	CUtils::ExtractColIdsAttno(pmp, ptabdesc, pcrsWidth, pdrgpulWidthColIds, pdrgpulWidthPos);

	CMDAccessor *pmda = COptCtxt::PoctxtFromTLS()->Pmda();
	IStatistics *pstats = pmda->Pstats(pmp, ptabdesc->Pmdid(), pdrgpulHistPos, pdrgpulHistColIds, pdrgpulWidthPos, pdrgpulWidthColIds);

	if (!GPOS_FTRACE(EopttraceDonotCollectMissingStatsCols) && !pstats->FEmpty())
	{
		CStatisticsUtils::RecordMissingStatisticsColumns(pmp, ptabdesc, pcrsStat, pstats);
	}

	pcrsStat->Release();

	return pstats;
}
Beispiel #7
0
//---------------------------------------------------------------------------
//	@function:
//		CDecorrelator::FProcess
//
//	@doc:
//		Main driver for decorrelation of expression
//
//---------------------------------------------------------------------------
BOOL
CDecorrelator::FProcess
	(
	IMemoryPool *pmp,
	CExpression *pexpr,
	BOOL fEqualityOnly,
	CExpression **ppexprDecorrelated,
	DrgPexpr *pdrgpexprCorrelations
	)
{
	GPOS_CHECK_STACK_SIZE;

	// only correlated Apply can be encountered here
	GPOS_ASSERT_IMP(CUtils::FApply(pexpr->Pop()), CUtils::FCorrelatedApply(pexpr->Pop()) &&
			"Apply expression is encountered by decorrelator");

	CDrvdPropRelational *pdprel = CDrvdPropRelational::Pdprel(pexpr->PdpDerive());

	// no outer references?
	if (0 == pdprel->PcrsOuter()->CElements())
	{
		pexpr->AddRef();
		*ppexprDecorrelated = pexpr;
		return true;
	}
	
	BOOL fSuccess = FProcessOperator(pmp, pexpr, fEqualityOnly, ppexprDecorrelated, pdrgpexprCorrelations);

	// in case of success make sure there are no outer references left
	GPOS_ASSERT_IMP
		(
		fSuccess,
		0 == CDrvdPropRelational::Pdprel((*ppexprDecorrelated)->PdpDerive())->PcrsOuter()->CElements()
		);

	return fSuccess;
}	
Beispiel #8
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PpcDeriveConstraintFromPredicates
//
//	@doc:
//		Derive constraint property when expression has relational children and
//		scalar children (predicates)
//
//---------------------------------------------------------------------------
CPropConstraint *
CLogical::PpcDeriveConstraintFromPredicates
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl
	)
{
	DrgPcrs *pdrgpcrs = GPOS_NEW(pmp) DrgPcrs(pmp);

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

	// collect constraint properties from relational children
	// and predicates from scalar children
	const ULONG ulArity = exprhdl.UlArity();
	for (ULONG ul = 0; ul < ulArity; ul++)
	{
		if (exprhdl.FScalarChild(ul))
		{
			CExpression *pexprScalar = exprhdl.PexprScalarChild(ul);

			// make sure it is a predicate... boolop, cmp, nulltest
			if (NULL == pexprScalar || !CUtils::FPredicate(pexprScalar))
			{
				continue;
			}

			DrgPcrs *pdrgpcrsChild = NULL;
			CConstraint *pcnstr = CConstraint::PcnstrFromScalarExpr(pmp, pexprScalar, &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);
		}
		else
		{
			CDrvdPropRelational *pdprel = exprhdl.Pdprel(ul);
			CPropConstraint *ppc = pdprel->Ppc();

			// equivalence classes coming from child
			DrgPcrs *pdrgpcrsChild = ppc->PdrgpcrsEquivClasses();

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

			// constraint coming from child
			CConstraint *pcnstr = ppc->Pcnstr();
			if (NULL != pcnstr)
			{
				pcnstr->AddRef();
				pdrgpcnstr->Append(pcnstr);
			}
		}
	}

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

	return GPOS_NEW(pmp) CPropConstraint(pmp, pdrgpcrs, pcnstrNew);
}
Beispiel #9
0
//---------------------------------------------------------------------------
//     @function:
//             CNormalizer::FLocalColsSubsetOfInputCols
//
//     @doc:
//             Check if the columns used by the operator are a subset of its input columns
//
//---------------------------------------------------------------------------
BOOL
CNormalizer::FLocalColsSubsetOfInputCols
	(
	IMemoryPool *pmp,
	CExpression *pexpr
	)
{
	GPOS_ASSERT(NULL != pexpr);
	GPOS_CHECK_STACK_SIZE;

	CExpressionHandle exprhdl(pmp);
	if (NULL != pexpr->Pgexpr())
	{
		exprhdl.Attach(pexpr->Pgexpr());
	}
	else
	{
		exprhdl.Attach(pexpr);
	}
	exprhdl.DeriveProps(NULL /*pdpctxt*/);

	BOOL fValid = true;
	if (pexpr->Pop()->FLogical())
	{
		if (0 == exprhdl.UlNonScalarChildren())
		{
			return true;
		}

		CColRefSet *pcrsInput = GPOS_NEW(pmp) CColRefSet(pmp);

		const ULONG ulArity = exprhdl.UlArity();
		for (ULONG ul = 0; ul < ulArity; ul++)
		{
			if (!exprhdl.FScalarChild(ul))
			{
				CDrvdPropRelational *pdprelChild = exprhdl.Pdprel(ul);
				pcrsInput->Include(pdprelChild->PcrsOutput());
			}
		}

		// check if the operator's locally used columns are a subset of the input columns
		CColRefSet *pcrsUsedOp = exprhdl.PcrsUsedColumns(pmp);
		pcrsUsedOp->Exclude(exprhdl.Pdprel()->PcrsOuter());

		fValid = pcrsInput->FSubset(pcrsUsedOp);

		// release
		pcrsInput->Release();
		pcrsUsedOp->Release();
	}

	// check if its children are valid
	const ULONG ulExprArity = pexpr->UlArity();
	for (ULONG ulChildIdx = 0; ulChildIdx < ulExprArity && fValid; ulChildIdx++)
	{
		CExpression *pexprChild = (*pexpr)[ulChildIdx];
		fValid = FLocalColsSubsetOfInputCols(pmp, pexprChild);
	}

	return fValid;
}