Ejemplo n.º 1
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalInnerIndexApply::PstatsDerive
//
//	@doc:
//		Derive statistics
//
//---------------------------------------------------------------------------
IStatistics *
CLogicalInnerIndexApply::PstatsDerive
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	DrgPstat* // pdrgpstatCtxt
	)
	const
{
	GPOS_ASSERT(EspNone < Esp(exprhdl));

	IStatistics *pstatsOuter = exprhdl.Pstats(0);
	IStatistics *pstatsInner = exprhdl.Pstats(1);
	CExpression *pexprScalar = exprhdl.PexprScalarChild(2 /*ulChildIndex*/);

	// join stats of the children
	DrgPstat *pdrgpstat = GPOS_NEW(pmp) DrgPstat(pmp);
	pstatsOuter->AddRef();
	pdrgpstat->Append(pstatsOuter);
	pstatsInner->AddRef();
	pdrgpstat->Append(pstatsInner);
	IStatistics *pstats = CStatisticsUtils::PstatsJoinArray(pmp, false /*fOuterJoin*/, pdrgpstat, pexprScalar);
	pdrgpstat->Release();

	return pstats;
}
Ejemplo n.º 2
0
//---------------------------------------------------------------------------
//	@function:
//		CExpressionHandle::CopyStats
//
//	@doc:
//		Copy stats from attached expression/group expression to local stats
//		members
//
//---------------------------------------------------------------------------
void
CExpressionHandle::CopyStats()
{
	if (!FStatsDerived())
	{
		// stats of attached expression (or its children) have not been derived yet
		return;
	}

	IStatistics *pstats = NULL;
	if (NULL != m_pexpr)
	{
		pstats = const_cast<IStatistics *>(m_pexpr->Pstats());
	}
	else
	{
		GPOS_ASSERT(NULL != m_pgexpr);
		pstats = m_pgexpr->Pgroup()->Pstats();
	}
	GPOS_ASSERT(NULL != pstats);

	// attach stats
	pstats->AddRef();
	GPOS_ASSERT(NULL == m_pstats);
	m_pstats = pstats;

	// attach child stats
	GPOS_ASSERT(NULL == m_pdrgpstat);
	m_pdrgpstat = GPOS_NEW(m_pmp) DrgPstat(m_pmp);
	const ULONG ulArity = UlArity();
	for (ULONG ul = 0; ul < ulArity; ul++)
	{
		IStatistics *pstatsChild = NULL;
		if (NULL != m_pexpr)
		{
			pstatsChild = const_cast<IStatistics *>((*m_pexpr)[ul]->Pstats());
		}
		else
		{
			pstatsChild = (*m_pgexpr)[ul]->Pstats();
		}

		if (NULL != pstatsChild)
		{
			pstatsChild->AddRef();
		}
		else
		{
			GPOS_ASSERT(FScalarChild(ul));

			// create dummy stats for missing scalar children
			pstatsChild = CStatistics::PstatsEmpty(m_pmp);
		}

		m_pdrgpstat->Append(pstatsChild);
	}
}
Ejemplo n.º 3
0
//---------------------------------------------------------------------------
//	@function:
//		CExpressionHandle::DeriveRootStats
//
//	@doc:
//		Stat derivation at root operator where handle is attached
//
//---------------------------------------------------------------------------
void
CExpressionHandle::DeriveRootStats
	(
	DrgPstat *pdrgpstatCtxt
	)
{
	GPOS_ASSERT(NULL == m_pstats);

	CLogical *popLogical = CLogical::PopConvert(Pop());
	IStatistics *pstatsRoot = NULL;
	if (FAttachedToLeafPattern())
	{
		// for leaf patterns extracted from memo, trigger state derivation on origin group
		GPOS_ASSERT(NULL != m_pexpr);
		GPOS_ASSERT(NULL != m_pexpr->Pgexpr());

		pstatsRoot = m_pexpr->Pgexpr()->Pgroup()->PstatsRecursiveDerive(m_pmp, m_pmp, CReqdPropRelational::Prprel(m_prp), pdrgpstatCtxt);
		pstatsRoot->AddRef();
	}
	else
	{
		// otherwise, derive stats using root operator
		pstatsRoot = popLogical->PstatsDerive(m_pmp, *this, pdrgpstatCtxt);
	}
	GPOS_ASSERT(NULL != pstatsRoot);

	m_pstats = pstatsRoot;
}
Ejemplo n.º 4
0
//---------------------------------------------------------------------------
//	@function:
//		CGroupExpression::PstatsRecursiveDerive
//
//	@doc:
//		Derive stats recursively on group expression
//
//---------------------------------------------------------------------------
IStatistics *
CGroupExpression::PstatsRecursiveDerive
	(
	IMemoryPool *, // pmpLocal
	IMemoryPool *pmpGlobal,
	CReqdPropRelational *prprel,
	DrgPstat *pdrgpstatCtxt,
	BOOL fComputeRootStats
	)
{
	GPOS_ASSERT(!Pgroup()->FScalar());
	GPOS_ASSERT(!Pgroup()->FImplemented());
	GPOS_ASSERT(NULL != pdrgpstatCtxt);
	GPOS_CHECK_ABORT;

	// trigger recursive property derivation
	CExpressionHandle exprhdl(pmpGlobal);
	exprhdl.Attach(this);
	exprhdl.DeriveProps(NULL /*pdpctxt*/);

	// compute required relational properties on child groups
	exprhdl.ComputeReqdProps(prprel, 0 /*ulOptReq*/);

	// trigger recursive stat derivation
	exprhdl.DeriveStats(pdrgpstatCtxt, fComputeRootStats);
	IStatistics *pstats = exprhdl.Pstats();
	if (NULL != pstats)
	{
		pstats->AddRef();
	}

	return pstats;
}
Ejemplo n.º 5
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PstatsPassThruOuter
//
//	@doc:
//		Helper for common case of passing through derived stats
//
//---------------------------------------------------------------------------
IStatistics *
CLogical::PstatsPassThruOuter
	(
	CExpressionHandle &exprhdl
	)
{
	GPOS_CHECK_ABORT;

	IStatistics *pstats = exprhdl.Pstats(0);
	pstats->AddRef();

	return pstats;
}
Ejemplo n.º 6
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalPartitionSelector::PpfmDerive
//
//	@doc:
//		Derive partition filter map
//
//---------------------------------------------------------------------------
CPartFilterMap *
CPhysicalPartitionSelector::PpfmDerive
	(
	IMemoryPool *mp,
	CExpressionHandle &exprhdl
	)
	const
{
	if (!FHasFilter())
	{
		return PpfmPassThruOuter(exprhdl);
	}

	CPartFilterMap *ppfm = PpfmDeriveCombineRelational(mp, exprhdl);
	IStatistics *stats = exprhdl.Pstats();
	GPOS_ASSERT(NULL != stats);
	m_pexprCombinedPredicate->AddRef();
	stats->AddRef();
	ppfm->AddPartFilter(mp, m_scan_id, m_pexprCombinedPredicate, stats);
	return ppfm;
}
Ejemplo n.º 7
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalSelect::PstatsDerive
//
//	@doc:
//		Derive statistics based on filter predicates
//
//---------------------------------------------------------------------------
IStatistics *
CLogicalSelect::PstatsDerive
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	DrgPstat *pdrgpstatCtxt
	)
	const
{
	GPOS_ASSERT(Esp(exprhdl) > EspNone);
	IStatistics *pstatsChild = exprhdl.Pstats(0);

	if (exprhdl.Pdpscalar(1 /*ulChildIndex*/)->FHasSubquery())
	{
		// in case of subquery in select predicate, we return child stats
		pstatsChild->AddRef();
		return pstatsChild;
	}

	// remove implied predicates from selection condition to avoid cardinality under-estimation
	CExpression *pexprScalar = exprhdl.PexprScalarChild(1 /*ulChildIndex*/);
	CExpression *pexprPredicate = CPredicateUtils::PexprRemoveImpliedConjuncts(pmp, pexprScalar, exprhdl);


	// split selection predicate into local predicate and predicate involving outer references
	CExpression *pexprLocal = NULL;
	CExpression *pexprOuterRefs = NULL;

	// get outer references from expression handle
	CColRefSet *pcrsOuter = exprhdl.Pdprel()->PcrsOuter();

	CPredicateUtils::SeparateOuterRefs(pmp, pexprPredicate, pcrsOuter, &pexprLocal, &pexprOuterRefs);
	pexprPredicate->Release();

	IStatistics *pstats = CStatisticsUtils::PstatsFilter(pmp, exprhdl, pstatsChild, pexprLocal, pexprOuterRefs, pdrgpstatCtxt);
	pexprLocal->Release();
	pexprOuterRefs->Release();

	return pstats;
}
Ejemplo n.º 8
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalLimit::PstatsDerive
//
//	@doc:
//		Derive statistics based on limit
//
//---------------------------------------------------------------------------
IStatistics *
CLogicalLimit::PstatsDerive
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	DrgPstat * // not used
	)
	const
{
	GPOS_ASSERT(Esp(exprhdl) > EspNone);
	IStatistics *pstatsChild = exprhdl.Pstats(0);
	CMaxCard maxcard = this->Maxcard(pmp, exprhdl);
	CDouble dRowsMax = CDouble(maxcard.Ull());

	if (pstatsChild->DRows() <= dRowsMax)
	{
		pstatsChild->AddRef();
		return pstatsChild;
	}

	return pstatsChild->PstatsLimit(pmp, dRowsMax);
}
Ejemplo n.º 9
0
//---------------------------------------------------------------------------
//	@function:
//		CExpressionHandle::DeriveCostContextStats
//
//	@doc:
//		Stats derivation based on required plan properties
//
//---------------------------------------------------------------------------
void
CExpressionHandle::DeriveCostContextStats()
{
	GPOS_ASSERT(NULL != m_pcc);
	GPOS_ASSERT(NULL == m_pcc->Pstats());

	// copy group properties and stats
	CopyGroupProps();
	CopyStats();

	if (NULL != m_pstats && !m_pcc->FNeedsNewStats())
	{
		// there is no need to derive stats,
		// stats are copied from owner group

		return;
	}

	CEnfdPartitionPropagation *pepp = m_pcc->Poc()->Prpp()->Pepp();
	COperator *pop = Pop();
	if (CUtils::FPhysicalScan(pop) &&
		CPhysicalScan::PopConvert(pop)->FDynamicScan() &&
		!pepp->PpfmDerived()->FEmpty())
	{
		// derive stats on dynamic table scan using stats of part selector
		CPhysicalScan *popScan = CPhysicalScan::PopConvert(m_pgexpr->Pop());
		IStatistics *pstatsDS = popScan->PstatsDerive(m_pmp, *this, m_pcc->Poc()->Prpp(), m_pcc->Poc()->Pdrgpstat());

		CRefCount::SafeRelease(m_pstats);
		m_pstats = pstatsDS;

		return;
	}

	// release current stats since we will derive new stats
	CRefCount::SafeRelease(m_pstats);
	m_pstats = NULL;

	// load stats from child cost context -- these may be different from child groups stats
	CRefCount::SafeRelease(m_pdrgpstat);
	m_pdrgpstat = NULL;

	m_pdrgpstat = GPOS_NEW(m_pmp) DrgPstat(m_pmp);
	const ULONG ulArity = m_pcc->Pdrgpoc()->UlLength();
	for (ULONG ul = 0; ul < ulArity; ul++)
	{
		COptimizationContext *pocChild = (*m_pcc->Pdrgpoc())[ul];
		CCostContext *pccChild = pocChild->PccBest();
		GPOS_ASSERT(NULL != pccChild);
		GPOS_ASSERT(NULL != pccChild->Pstats());

		pccChild->Pstats()->AddRef();
		m_pdrgpstat->Append(pccChild->Pstats());
	}

	if (CPhysical::PopConvert(m_pgexpr->Pop())->FPassThruStats())
	{
		GPOS_ASSERT(1 == m_pdrgpstat->UlLength());

		// copy stats from first child
		(*m_pdrgpstat)[0]->AddRef();
		m_pstats = (*m_pdrgpstat)[0];

		return;
	}

	// derive stats using the best logical expression with the same children as attached physical operator
	CGroupExpression *pgexprForStats = m_pcc->PgexprForStats();
	GPOS_ASSERT(NULL != pgexprForStats);

	CExpressionHandle exprhdl(m_pmp);
	exprhdl.Attach(pgexprForStats);
	exprhdl.DeriveProps(NULL /*pdpctxt*/);
	m_pdrgpstat->AddRef();
	exprhdl.m_pdrgpstat = m_pdrgpstat;
	exprhdl.ComputeReqdProps(m_pcc->Poc()->Prprel(), 0 /*ulOptReq*/);

	GPOS_ASSERT(NULL == exprhdl.m_pstats);
	IStatistics *pstats = m_pgexpr->Pgroup()->PstatsCompute(m_pcc->Poc(), exprhdl, pgexprForStats);

	// copy stats to main handle
	GPOS_ASSERT(NULL == m_pstats);
	GPOS_ASSERT(NULL != pstats);

	pstats->AddRef();
	m_pstats = pstats;

	GPOS_ASSERT(m_pstats != NULL);
}
Ejemplo n.º 10
0
//---------------------------------------------------------------------------
//	@function:
//		CExpressionHandle::DeriveStats
//
//	@doc:
//		Recursive stat derivation
//
//---------------------------------------------------------------------------
void
CExpressionHandle::DeriveStats
	(
	DrgPstat *pdrgpstatCtxt,
	BOOL fComputeRootStats
	)
{
	GPOS_ASSERT(NULL != pdrgpstatCtxt);
	GPOS_ASSERT(NULL == m_pdrgpstat);
	GPOS_ASSERT(NULL == m_pstats);
	GPOS_ASSERT(NULL != m_pdrgprp);

	// copy input context
	DrgPstat *pdrgpstatCurrentCtxt = GPOS_NEW(m_pmp) DrgPstat(m_pmp);
	CUtils::AddRefAppend<IStatistics, CleanupStats>(pdrgpstatCurrentCtxt, pdrgpstatCtxt);

	// create array of children stats
	m_pdrgpstat = GPOS_NEW(m_pmp) DrgPstat(m_pmp);
	ULONG ulMaxChildRisk = 1;
	const ULONG ulArity = UlArity();
	for (ULONG ul = 0; ul < ulArity; ul++)
	{
		// create a new context for outer references used by current child
		DrgPstat *pdrgpstatChildCtxt = PdrgpstatOuterRefs(pdrgpstatCurrentCtxt, ul);

		IStatistics *pstats = NULL;
		if (NULL != Pexpr())
		{
			// derive stats recursively on child expression
			pstats = (*Pexpr())[ul]->PstatsDerive(Prprel(ul), pdrgpstatChildCtxt);
		}
		else
		{
			// derive stats recursively on child group
			pstats = (*Pgexpr())[ul]->PstatsRecursiveDerive(m_pmp, m_pmp, Prprel(ul), pdrgpstatChildCtxt);
		}
		GPOS_ASSERT(NULL != pstats);

		// add child stat to current context
		pstats->AddRef();
		pdrgpstatCurrentCtxt->Append(pstats);
		pdrgpstatChildCtxt->Release();

		// add child stat to children stat array
		pstats->AddRef();
		m_pdrgpstat->Append(pstats);
		if (pstats->UlStatsEstimationRisk() > ulMaxChildRisk)
		{
			ulMaxChildRisk = pstats->UlStatsEstimationRisk();
		}
	}

	if (fComputeRootStats)
	{
		// call stat derivation on operator to compute local stats
		GPOS_ASSERT(NULL == m_pstats);

		DeriveRootStats(pdrgpstatCtxt);
		GPOS_ASSERT(NULL != m_pstats);

		CLogical *popLogical = CLogical::PopConvert(Pop());
		ULONG ulRisk = ulMaxChildRisk;
		if (CStatisticsUtils::FIncreasesRisk(popLogical))
		{
			++ulRisk;
		}
		m_pstats->SetStatsEstimationRisk(ulRisk);
	}

	// clean up current stat context
	pdrgpstatCurrentCtxt->Release();
}