예제 #1
0
//---------------------------------------------------------------------------
//	@function:
//		CDrvdPropPlan::CopyCTEProducerPlanProps
//
//	@doc:
//		Copy CTE producer plan properties from given context to current object
//
//---------------------------------------------------------------------------
void
CDrvdPropPlan::CopyCTEProducerPlanProps
	(
	IMemoryPool *pmp,
	CDrvdPropCtxt *pdpctxt,
	COperator *pop
	)
{
	CDrvdPropCtxtPlan *pdpctxtplan = CDrvdPropCtxtPlan::PdpctxtplanConvert(pdpctxt);
	CPhysicalCTEConsumer *popCTEConsumer = CPhysicalCTEConsumer::PopConvert(pop);
	ULONG ulCTEId = popCTEConsumer->UlCTEId();
	HMUlCr *phmulcr = popCTEConsumer->Phmulcr();
	CDrvdPropPlan *pdpplan = pdpctxtplan->PdpplanCTEProducer(ulCTEId);
	if (NULL != pdpplan)
	{
		// copy producer plan properties after remapping columns
		m_pos = pdpplan->Pos()->PosCopyWithRemappedColumns(pmp, phmulcr, true /*fMustExist*/);
		m_pds = pdpplan->Pds()->PdsCopyWithRemappedColumns(pmp, phmulcr, true /*fMustExist*/);

		// rewindability and partition filter map do not need column remapping,
		// we add-ref producer's properties directly
		pdpplan->Prs()->AddRef();
		m_prs = pdpplan->Prs();

		pdpplan->Ppfm()->AddRef();
		m_ppfm = pdpplan->Ppfm();

		// no need to copy the part index map. return an empty one. This is to
		// distinguish between a CTE consumer and the inlined expression
		m_ppim = GPOS_NEW(pmp) CPartIndexMap(pmp);

		GPOS_ASSERT(CDistributionSpec::EdtAny != m_pds->Edt() && "CDistributionAny is a require-only, cannot be derived");
	}
}
예제 #2
0
BOOL
CPhysicalSpool::FValidContext
	(
	IMemoryPool *,
	COptimizationContext *poc,
	COptimizationContextArray *pdrgpocChild
	)
	const
{
	GPOS_ASSERT(NULL != pdrgpocChild);
	GPOS_ASSERT(1 == pdrgpocChild->Size());

	COptimizationContext *pocChild = (*pdrgpocChild)[0];
	CCostContext *pccBest = pocChild->PccBest();
	GPOS_ASSERT(NULL != pccBest);

	// partition selections that happen outside of a physical spool does not do
	// any good on rescan: a physical spool blocks the rescan from the entire
	// subtree (in particular, any dynamic scan) underneath it. That means when
	// we have a dynamic scan under a spool, and a corresponding partition
	// selector outside the spool, we run the risk of materializing the wrong
	// results.

	// For example, the following plan is invalid because the partition selector
	// won't be able to influence inner side of the nested loop join as intended
	// ("blocked" by the spool):

	// +--CPhysicalMotionGather(master)
	//    +--CPhysicalInnerNLJoin
	//       |--CPhysicalPartitionSelector
	//       |  +--CPhysicalMotionBroadcast
	//       |     +--CPhysicalTableScan "foo" ("foo")
	//       |--CPhysicalSpool
	//       |  +--CPhysicalLeftOuterHashJoin
	//       |     |--CPhysicalDynamicTableScan "pt" ("pt")
	//       |     |--CPhysicalMotionHashDistribute
	//       |     |  +--CPhysicalTableScan "bar" ("bar")
	//       |     +--CScalarCmp (=)
	//       |        |--CScalarIdent "d" (19)
	//       |        +--CScalarIdent "dk" (9)
	//       +--CScalarCmp (<)
	//          |--CScalarIdent "a" (0)
	//          +--CScalarIdent "partkey" (10)

	CDrvdPropPlan *pdpplanChild = pccBest->Pdpplan();
	if (pdpplanChild->Ppim()->FContainsUnresolved())
	{
		return false;
	}

	// Discard any context that is requesting for rewindability with motion hazard handling and
	// the physical spool is streaming with a motion underneath it.
	// We do not want to add a blocking spool over a spool as spooling twice will be expensive,
	// hence invalidate this context.
	CEnfdRewindability *per = poc->Prpp()->Per();
	if(per->PrsRequired()->HasMotionHazard() &&
	   pdpplanChild->Prs()->HasMotionHazard())
	{
		return FEager();
	}

	return true;
}