Example #1
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalUnionAll::AssertValidChildDistributions
//
//	@doc:
//		Helper to validate child distributions
//
//---------------------------------------------------------------------------
void
CPhysicalUnionAll::AssertValidChildDistributions
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CDistributionSpec::EDistributionType *pedt, // array of distribution types to check
	ULONG ulDistrs, // number of distribution types to check
	const CHAR *szAssertMsg
	)
{
	const ULONG ulArity = exprhdl.UlArity();
	for (ULONG ulChild = 0; ulChild < ulArity; ulChild++)
	{
		CDistributionSpec *pdsChild = exprhdl.Pdpplan(ulChild)->Pds();
		CDistributionSpec::EDistributionType edtChild = pdsChild->Edt();
		BOOL fMatch = false;
		for (ULONG ulDistr = 0; !fMatch && ulDistr < ulDistrs; ulDistr++)
		{
			fMatch = (pedt[ulDistr] == edtChild);
		}

		if (!fMatch)
		{
			CAutoTrace at(pmp);
			at.Os() << szAssertMsg;
		}
		GPOS_ASSERT(fMatch);
	}
}
Example #2
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalAgg::EpetDistribution
//
//	@doc:
//		Return the enforcing type for distribution property based on this operator
//
//---------------------------------------------------------------------------
CEnfdProp::EPropEnforcingType
CPhysicalAgg::EpetDistribution
	(
	CExpressionHandle &exprhdl,
	const CEnfdDistribution *ped
	)
	const
{
	GPOS_ASSERT(NULL != ped);

	// get distribution delivered by the aggregate node
	CDistributionSpec *pds = CDrvdPropPlan::Pdpplan(exprhdl.Pdp())->Pds();

	if (ped->FCompatible(pds))
	{
		if (COperator::EgbaggtypeLocal != Egbaggtype())
		{
			return CEnfdProp::EpetUnnecessary;
		}

		// prohibit the plan if local aggregate already delivers the enforced distribution, since
		// otherwise we would create two aggregates with no intermediate motion operators
		return CEnfdProp::EpetProhibited;

	}

	// if there are outer refs, we cannot have a motion on top
	if (exprhdl.FHasOuterRefs())
	{
		return CEnfdProp::EpetProhibited;
	}

	// required distribution will be enforced on Agg's output
	return CEnfdProp::EpetRequired;
}
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalPartitionSelectorDML::EpetDistribution
//
//	@doc:
//		Return the enforcing type for distribution property based on this operator
//
//---------------------------------------------------------------------------
CEnfdProp::EPropEnforcingType
CPhysicalPartitionSelectorDML::EpetDistribution
	(
	CExpressionHandle &exprhdl,
	const CEnfdDistribution *ped
	)
	const
{
	GPOS_ASSERT(NULL != ped);

	// get distribution delivered by the filter node
	CDistributionSpec *pds = CDrvdPropPlan::Pdpplan(exprhdl.Pdp())->Pds();
	if (ped->FCompatible(pds))
	{
		 // required distribution is already provided
		 return CEnfdProp::EpetUnnecessary;
	}

	if (exprhdl.HasOuterRefs())
	{
		return CEnfdProp::EpetProhibited;
	}

	return CEnfdProp::EpetRequired;
}
Example #4
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalJoin::FProvidesReqdCols
//
//	@doc:
//		Helper for checking if required columns are included in output columns
//
//---------------------------------------------------------------------------
BOOL
CPhysicalJoin::FProvidesReqdCols
	(
	CExpressionHandle &exprhdl,
	CColRefSet *pcrsRequired,
	ULONG // ulOptReq
	)
	const
{
	GPOS_ASSERT(NULL != pcrsRequired);
	GPOS_ASSERT(3 == exprhdl.UlArity());

	// union columns from relational children
	CColRefSet *pcrs = GPOS_NEW(m_pmp) CColRefSet(m_pmp);
	ULONG ulArity = exprhdl.UlArity();
	for (ULONG i = 0; i < ulArity - 1; i++)
	{
		CColRefSet *pcrsChild = exprhdl.Pdprel(i)->PcrsOutput();
		pcrs->Union(pcrsChild);
	}

	BOOL fProvidesCols = pcrs->FSubset(pcrsRequired);
	pcrs->Release();

	return fProvidesCols;
}
Example #5
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalSequence::Maxcard
//
//	@doc:
//		Derive max card
//
//---------------------------------------------------------------------------
CMaxCard
CLogicalSequence::Maxcard
	(
	IMemoryPool *, // mp
	CExpressionHandle &exprhdl
	)
	const
{
	// pass on max card of last child
	return exprhdl.GetRelationalProperties(exprhdl.Arity() - 1)->Maxcard();
}
//---------------------------------------------------------------------------
//	@function:
//		CLogicalSequenceProject::FHasLocalOuterRefs
//
//	@doc:
//		Return true if outer references are included in Partition/Order,
//		or window frame edges
//
//---------------------------------------------------------------------------
BOOL
CLogicalSequenceProject::FHasLocalOuterRefs
	(
	CExpressionHandle &exprhdl
	)
	const
{
	GPOS_ASSERT(this == exprhdl.Pop());

	CColRefSet *outer_refs = CDrvdPropRelational::GetRelationalProperties(exprhdl.Pdp())->PcrsOuter();

	return !(outer_refs->IsDisjoint(m_pcrsLocalUsed));
}
Example #7
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalJoin::FOuterProvidesReqdCols
//
//	@doc:
//		Helper for checking if the outer input of a binary join operator
//		includes the required columns
//
//---------------------------------------------------------------------------
BOOL
CPhysicalJoin::FOuterProvidesReqdCols
	(
	CExpressionHandle &exprhdl,
	CColRefSet *pcrsRequired
	)
{
	GPOS_ASSERT(NULL != pcrsRequired);
	GPOS_ASSERT(3 == exprhdl.UlArity() && "expected binary join");

	CColRefSet *pcrsOutput = exprhdl.Pdprel(0 /*ulChildIndex*/)->PcrsOutput();

	return pcrsOutput->FSubset(pcrsRequired);
}
Example #8
0
//---------------------------------------------------------------------------
//	@function:
//		CXformSubqJoin2Apply::Exfp
//
//	@doc:
//		Compute xform promise for a given expression handle;
// 		if subqueries exist in the scalar predicate, we must have an
// 		equivalent logical Apply expression created during exploration;
// 		no need for generating a Join expression here
//
//---------------------------------------------------------------------------
CXform::EXformPromise
CXformSubqJoin2Apply::Exfp
	(
	CExpressionHandle &exprhdl
	)
	const
{
	if (exprhdl.GetDrvdScalarProps(exprhdl.Arity() - 1)->FHasSubquery())
	{
		return CXform::ExfpHigh;
	}

	return CXform::ExfpNone;
}
Example #9
0
//---------------------------------------------------------------------------
//	@function:
//		CXformGbAgg2Apply::Exfp
//
//	@doc:
//		Compute xform promise for a given expression handle;
//		scalar child must have subquery
//
//---------------------------------------------------------------------------
CXform::EXformPromise
CXformGbAgg2Apply::Exfp
	(
	CExpressionHandle &exprhdl
	)
	const
{
	CLogicalGbAgg *popGbAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop());
	if (popGbAgg->FGlobal() && exprhdl.Pdpscalar(1)->FHasSubquery())
	{
		return CXform::ExfpHigh;
	}

	return CXform::ExfpNone;
}
Example #10
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalUnionAll::FProvidesReqdCols
//
//	@doc:
//		Check if required columns are included in output columns
//
//---------------------------------------------------------------------------
BOOL
CPhysicalUnionAll::FProvidesReqdCols
	(
	CExpressionHandle &
#ifdef GPOS_DEBUG
	exprhdl
#endif // GPOS_DEBUG
	,
	CColRefSet *pcrsRequired,
	ULONG // ulOptReq
	)
	const
{
	GPOS_ASSERT(NULL != pcrsRequired);
	GPOS_ASSERT(m_pdrgpdrgpcrInput->UlLength() == exprhdl.UlArity());

	CColRefSet *pcrs = GPOS_NEW(m_pmp) CColRefSet(m_pmp);

	// include output columns
	pcrs->Include(m_pdrgpcrOutput);
	BOOL fProvidesCols = pcrs->FSubset(pcrsRequired);
	pcrs->Release();

	return fProvidesCols;
}
void
CDistributionSpecHashedNoOp::AppendEnforcers
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CReqdPropPlan *,
	DrgPexpr *pdrgpexpr,
	CExpression *pexpr
	)
{
	CDrvdProp *pdp = exprhdl.Pdp();
	CDistributionSpec *pdsChild = CDrvdPropPlan::Pdpplan(pdp)->Pds();
	CDistributionSpecHashed *pdsChildHashed = dynamic_cast<CDistributionSpecHashed *>(pdsChild);
	if (NULL == pdsChildHashed)
	{
		return;
	}
	
	DrgPexpr *pdrgpexprNoOpRedistributionColumns = pdsChildHashed->Pdrgpexpr();
	pdrgpexprNoOpRedistributionColumns->AddRef();
	CDistributionSpecHashedNoOp* pdsNoOp = GPOS_NEW(pmp) CDistributionSpecHashedNoOp(pdrgpexprNoOpRedistributionColumns);
	pexpr->AddRef();
	CExpression *pexprMotion = GPOS_NEW(pmp) CExpression
			(
					pmp,
					GPOS_NEW(pmp) CPhysicalMotionHashDistribute(pmp, pdsNoOp),
					pexpr
			);
	pdrgpexpr->Append(pexprMotion);
}
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalPartitionSelectorDML::EpetOrder
//
//	@doc:
//		Return the enforcing type for order property based on this operator
//
//---------------------------------------------------------------------------
CEnfdProp::EPropEnforcingType
CPhysicalPartitionSelectorDML::EpetOrder
	(
	CExpressionHandle &exprhdl,
	const CEnfdOrder *peo
	)
	const
{
	GPOS_ASSERT(NULL != peo);
	GPOS_ASSERT(!peo->PosRequired()->IsEmpty());

	COrderSpec *pos = CDrvdPropPlan::Pdpplan(exprhdl.Pdp())->Pos();
	if (peo->FCompatible(pos))
	{
		return  CEnfdProp::EpetUnnecessary;
	}

	// Sort has to go above if sort columns use any column
	// defined here, otherwise, Sort can either go above or below
	CColRefSet *pcrsSort = peo->PosRequired()->PcrsUsed(m_mp);
	BOOL fUsesDefinedCols = pcrsSort->FMember(m_pcrOid);
	pcrsSort->Release();
	if (fUsesDefinedCols)
	{
		return CEnfdProp::EpetRequired;
	}

	return CEnfdProp::EpetOptional;
}
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalComputeScalar::EpetOrder
//
//	@doc:
//		Return the enforcing type for order property based on this operator
//
//---------------------------------------------------------------------------
CEnfdProp::EPropEnforcingType
CPhysicalComputeScalar::EpetOrder
	(
	CExpressionHandle &exprhdl,
	const CEnfdOrder *peo
	)
	const
{
	GPOS_ASSERT(NULL != peo);
	GPOS_ASSERT(!peo->PosRequired()->FEmpty());
	
	COrderSpec *pos = CDrvdPropPlan::Pdpplan(exprhdl.Pdp())->Pos();
	if (peo->FCompatible(pos))
	{
		return  CEnfdProp::EpetUnnecessary;
	}

	// Sort has to go above ComputeScalar if sort columns use any column
	// defined by ComputeScalar, otherwise, Sort can either go above or below ComputeScalar
	CColRefSet *pcrsSort = peo->PosRequired()->PcrsUsed(m_pmp);
	BOOL fUsesDefinedCols = FUnaryUsesDefinedColumns(pcrsSort, exprhdl);
	pcrsSort->Release();
	if (fUsesDefinedCols)
	{
		return CEnfdProp::EpetRequired;
	}

	return CEnfdProp::EpetOptional;
}
//---------------------------------------------------------------------------
//	@function:
//		CXformInnerApplyWithOuterKey2InnerJoin::Exfp
//
//	@doc:
//		Compute xform promise for a given expression handle;
//
//---------------------------------------------------------------------------
CXform::EXformPromise
CXformInnerApplyWithOuterKey2InnerJoin::Exfp
	(
	CExpressionHandle &exprhdl
	)
	const
{
	// check if outer child has key and inner child has outer references
	if (NULL == exprhdl.Pdprel(0)->Pkc() ||
		0 == exprhdl.Pdprel(1)->PcrsOuter()->CElements())
	{
		return ExfpNone;
	}

	return ExfpHigh;
}
Example #15
0
//---------------------------------------------------------------------------
//	@function:
//		CDrvdPropPlan::Derive
//
//	@doc:
//		Derive plan props
//
//---------------------------------------------------------------------------
void
CDrvdPropPlan::Derive
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CDrvdPropCtxt *pdpctxt
	)
{
	CPhysical *popPhysical = CPhysical::PopConvert(exprhdl.Pop());
	if (NULL != pdpctxt && COperator::EopPhysicalCTEConsumer == popPhysical->Eopid())
	{
		CopyCTEProducerPlanProps(pmp, pdpctxt, popPhysical);
	}
	else
	{
		// call property derivation functions on the operator
		m_pos = popPhysical->PosDerive(pmp, exprhdl);
		m_pds = popPhysical->PdsDerive(pmp, exprhdl);
		m_prs = popPhysical->PrsDerive(pmp, exprhdl);
		m_ppim = popPhysical->PpimDerive(pmp, exprhdl, pdpctxt);
		m_ppfm = popPhysical->PpfmDerive(pmp, exprhdl);

		GPOS_ASSERT(NULL != m_ppim);
		GPOS_ASSERT(CDistributionSpec::EdtAny != m_pds->Edt() && "CDistributionAny is a require-only, cannot be derived");
	}

	m_pcm = popPhysical->PcmDerive(pmp, exprhdl);
}
Example #16
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalDifferenceAll::Maxcard
//
//	@doc:
//		Derive max card
//
//---------------------------------------------------------------------------
CMaxCard
CLogicalDifferenceAll::Maxcard
	(
	IMemoryPool *, // pmp
	CExpressionHandle &exprhdl
	)
	const
{
	// contradictions produce no rows
	if (CDrvdPropRelational::Pdprel(exprhdl.Pdp())->Ppc()->FContradiction())
	{
		return CMaxCard(0 /*ull*/);
	}

	return exprhdl.Pdprel(0)->Maxcard();
}
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalPartitionSelector::EpetDistribution
//
//	@doc:
//		Return the enforcing type for distribution property based on this operator
//
//---------------------------------------------------------------------------
CEnfdProp::EPropEnforcingType
CPhysicalPartitionSelector::EpetDistribution
	(
	CExpressionHandle &exprhdl,
	const CEnfdDistribution *ped
	)
	const
{
	CDrvdPropPlan *pdpplan = exprhdl.Pdpplan(0 /* child_index */);

	if (ped->FCompatible(pdpplan->Pds()))
	{
		// required distribution established by the operator
		return CEnfdProp::EpetUnnecessary;
	}

	CPartIndexMap *ppimDrvd = pdpplan->Ppim();
	if (!ppimDrvd->Contains(m_scan_id))
	{
		// part consumer is defined above: prohibit adding a motion on top of the
		// part resolver as this will create two slices
		return CEnfdProp::EpetProhibited;
	}

	GPOS_ASSERT(CPartIndexMap::EpimConsumer == ppimDrvd->Epim(m_scan_id));

	// part consumer found below: enforce distribution on top of part resolver
	return CEnfdProp::EpetRequired;
}
Example #18
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysical::FUnaryUsesDefinedColumns
//
//	@doc:
//		Return true if the given column set includes any of the columns defined
//		by the unary node, as given by the handle
//
//---------------------------------------------------------------------------
BOOL
CPhysical::FUnaryUsesDefinedColumns
	(
	CColRefSet *pcrs,
	CExpressionHandle &exprhdl
	)
{
	GPOS_ASSERT(NULL != pcrs);
	GPOS_ASSERT(2 == exprhdl.Arity() && "Not a unary operator");
	
	if (0 == pcrs->Size())
	{
		return false;
	}

	return !pcrs->IsDisjoint(exprhdl.GetDrvdScalarProps(1)->PcrsDefined());
}
Example #19
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalUnion::Maxcard
//
//	@doc:
//		Derive max card
//
//---------------------------------------------------------------------------
CMaxCard
CLogicalUnion::Maxcard
	(
	IMemoryPool *, // mp
	CExpressionHandle &exprhdl
	)
	const
{
	const ULONG arity = exprhdl.Arity();
	
	CMaxCard maxcard = exprhdl.GetRelationalProperties(0)->Maxcard();
	for (ULONG ul = 1; ul < arity; ul++)
	{
		maxcard += exprhdl.GetRelationalProperties(ul)->Maxcard();
	}
	
	return maxcard;
}
Example #20
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalUnion::Maxcard
//
//	@doc:
//		Derive max card
//
//---------------------------------------------------------------------------
CMaxCard
CLogicalUnion::Maxcard
	(
	IMemoryPool *, // pmp
	CExpressionHandle &exprhdl
	)
	const
{
	const ULONG ulArity = exprhdl.UlArity();
	
	CMaxCard maxcard = exprhdl.Pdprel(0)->Maxcard();
	for (ULONG ul = 1; ul < ulArity; ul++)
	{
		maxcard += exprhdl.Pdprel(ul)->Maxcard();
	}
	
	return maxcard;
}
Example #21
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysical::FChildrenHaveCompatibleDistributions
//
//	@doc:
//		Returns true iff the delivered distributions of the children are
//		compatible among themselves.
//
//---------------------------------------------------------------------------
BOOL
CPhysical::FCompatibleChildrenDistributions
	(
	const CExpressionHandle &exprhdl
	)
	const
{
	GPOS_ASSERT(exprhdl.Pop() == this);
	BOOL fSingletonOrUniversalChild = false;
	BOOL fNotSingletonOrUniversalDistributedChild = false;
	const ULONG arity = exprhdl.Arity();
	for (ULONG ul = 0; ul < arity; ul++)
	{
		if (!exprhdl.FScalarChild(ul))
		{
			CDrvdPropPlan *pdpplanChild = exprhdl.Pdpplan(ul);

			// an operator cannot have a singleton or universal distributed child
			// and one distributed on multiple nodes
			// this assumption is safe for all current operators, but it can be
			// too conservative: we could allow for instance the following cases
			// * LeftOuterJoin (universal, distributed)
			// * AntiSemiJoin  (universal, distributed)
			// These cases can be enabled if considered necessary by overriding
			// this function.
			if (CDistributionSpec::EdtUniversal == pdpplanChild->Pds()->Edt() ||
				pdpplanChild->Pds()->FSingletonOrStrictSingleton())
			{
				fSingletonOrUniversalChild = true;
			}
			else
			{
				fNotSingletonOrUniversalDistributedChild = true;
			}
			if (fSingletonOrUniversalChild && fNotSingletonOrUniversalDistributedChild)
			{

				return false;
			}
		}
	}

	return true;
}
Example #22
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalSequence::FProvidesReqdCols
//
//	@doc:
//		Helper for checking if required columns are included in output columns
//
//---------------------------------------------------------------------------
BOOL
CPhysicalSequence::FProvidesReqdCols
	(
	CExpressionHandle &exprhdl,
	CColRefSet *pcrsRequired,
	ULONG // ulOptReq
	)
	const
{
	GPOS_ASSERT(NULL != pcrsRequired);

	// last child must provide required columns
	ULONG ulArity = exprhdl.UlArity();
	GPOS_ASSERT(0 < ulArity);
	
	CColRefSet *pcrsChild = exprhdl.Pdprel(ulArity - 1)->PcrsOutput();

	return pcrsChild->FSubset(pcrsRequired);
}
Example #23
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalLeftSemiApply::Maxcard
//
//	@doc:
//		Derive max card
//
//---------------------------------------------------------------------------
CMaxCard
CLogicalLeftSemiApply::Maxcard
	(
	IMemoryPool *, // mp
	CExpressionHandle &exprhdl
	)
	const
{
	return CLogical::Maxcard(exprhdl, 2 /*ulScalarIndex*/, exprhdl.GetRelationalProperties(0)->Maxcard());
}
//---------------------------------------------------------------------------
//	@function:
//		CXformGbAgg2StreamAgg::Exfp
//
//	@doc:
//		Compute xform promise for a given expression handle;
//		grouping columns must be non-empty
//
//---------------------------------------------------------------------------
CXform::EXformPromise
CXformGbAgg2StreamAgg::Exfp
	(
	CExpressionHandle &exprhdl
	)
	const
{
	CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop());
	if (0 == popAgg->Pdrgpcr()->UlLength() ||
		!CUtils::FComparisonPossible(popAgg->Pdrgpcr(), IMDType::EcmptL) ||
		exprhdl.Pdpscalar(1 /*ulChildIndex*/)->FHasSubquery())
	{
		// no grouping columns, or no sort operators are available for grouping columns, or
		// agg functions use subquery arguments
		return CXform::ExfpNone;
	}

	return CXform::ExfpHigh;
}
//---------------------------------------------------------------------------
//	@function:
//		CLogicalLeftSemiApply::Maxcard
//
//	@doc:
//		Derive max card
//
//---------------------------------------------------------------------------
CMaxCard
CLogicalLeftSemiApply::Maxcard
	(
	IMemoryPool *, // pmp
	CExpressionHandle &exprhdl
	)
	const
{
	return CLogical::Maxcard(exprhdl, 2 /*ulScalarIndex*/, exprhdl.Pdprel(0)->Maxcard());
}
Example #26
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalSelect::Maxcard
//
//	@doc:
//		Derive max card
//
//---------------------------------------------------------------------------
CMaxCard
CLogicalSelect::Maxcard
	(
	IMemoryPool *, // pmp
	CExpressionHandle &exprhdl
	)
	const
{
	// in case of a false condition or a contradiction, maxcard should be zero
	CExpression *pexprScalar = exprhdl.PexprScalarChild(1);
	if ((NULL != pexprScalar && CUtils::FScalarConstFalse(pexprScalar)) ||
		CDrvdPropRelational::Pdprel(exprhdl.Pdp())->Ppc()->FContradiction())
	{
		return CMaxCard(0 /*ull*/);
	}

	// pass on max card of first child
	return exprhdl.Pdprel(0)->Maxcard();
}
Example #27
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::MaxcardDef
//
//	@doc:
//		Default max card for join and apply operators
//
//---------------------------------------------------------------------------
CMaxCard
CLogical::MaxcardDef
	(
	CExpressionHandle &exprhdl
	)
{
	const ULONG ulArity = exprhdl.UlArity();

	CMaxCard maxcard = exprhdl.Pdprel(0)->Maxcard();
	for (ULONG ul = 1; ul < ulArity - 1; ul++)
	{
		if (!exprhdl.FScalarChild(ul))
		{
			maxcard *= exprhdl.Pdprel(ul)->Maxcard();
		}
	}

	return maxcard;
}
//---------------------------------------------------------------------------
//	@function:
//		CXformGbAggWithMDQA2Join::Exfp
//
//	@doc:
//		Compute xform promise for a given expression handle;
//
//---------------------------------------------------------------------------
CXform::EXformPromise
CXformGbAggWithMDQA2Join::Exfp
	(
	CExpressionHandle &exprhdl
	)
	const
{
	CAutoMemoryPool amp;

	CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop());

	if (COperator::EgbaggtypeGlobal == popAgg->Egbaggtype() &&
		exprhdl.Pdpscalar(1 /*ulChildIndex*/)->FHasMultipleDistinctAggs())
	{
		return CXform::ExfpHigh;
	}

	return CXform::ExfpNone;
}
Example #29
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalCTEAnchor::Maxcard
//
//	@doc:
//		Derive max card
//
//---------------------------------------------------------------------------
CMaxCard
CLogicalCTEAnchor::Maxcard
	(
	IMemoryPool *, // pmp
	CExpressionHandle &exprhdl
	)
	const
{
	// pass on max card of first child
	return exprhdl.Pdprel(0)->Maxcard();
}
Example #30
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalLimit::Maxcard
//
//	@doc:
//		Derive max card
//
//---------------------------------------------------------------------------
CMaxCard
CLogicalLimit::Maxcard
	(
	IMemoryPool *, // pmp
	CExpressionHandle &exprhdl
	)
	const
{
	CExpression *pexprCount = exprhdl.PexprScalarChild(2 /*ulChildIndex*/);
	if (CUtils::FScalarConstInt<IMDTypeInt8>(pexprCount))
	{
		CScalarConst *popScalarConst = CScalarConst::PopConvert(pexprCount->Pop());
		IDatumInt8 *pdatumInt8 = dynamic_cast<IDatumInt8 *>(popScalarConst->Pdatum());

		return CMaxCard(pdatumInt8->LValue());
	}

	// pass on max card of first child
	return exprhdl.Pdprel(0)->Maxcard();
}