//---------------------------------------------------------------------------
//	@function:
//		CXformDifferenceAll2LeftAntiSemiJoin::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformDifferenceAll2LeftAntiSemiJoin::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	IMemoryPool *pmp = pxfctxt->Pmp();

	// TODO: , Jan 8th 2013, we currently only handle difference all
	//  operators with two children
	GPOS_ASSERT(2 == pexpr->UlArity());

	// extract components
	CExpression *pexprLeftChild = (*pexpr)[0];
	CExpression *pexprRightChild = (*pexpr)[1];

	CLogicalDifferenceAll *popDifferenceAll = CLogicalDifferenceAll::PopConvert(pexpr->Pop());
	DrgDrgPcr *pdrgpdrgpcrInput = popDifferenceAll->PdrgpdrgpcrInput();

	CExpression *pexprLeftWindow = CXformUtils::PexprWindowWithRowNumber(pmp, pexprLeftChild, (*pdrgpdrgpcrInput)[0]);
	CExpression *pexprRightWindow = CXformUtils::PexprWindowWithRowNumber(pmp, pexprRightChild, (*pdrgpdrgpcrInput)[1]);

	DrgDrgPcr *pdrgpdrgpcrInputNew = GPOS_NEW(pmp) DrgDrgPcr(pmp);
	DrgPcr *pdrgpcrLeftNew = CUtils::PdrgpcrExactCopy(pmp, (*pdrgpdrgpcrInput)[0]);
	pdrgpcrLeftNew->Append(CXformUtils::PcrProjectElement(pexprLeftWindow, 0 /* row_number window function*/));

	DrgPcr *pdrgpcrRightNew = CUtils::PdrgpcrExactCopy(pmp, (*pdrgpdrgpcrInput)[1]);
	pdrgpcrRightNew->Append(CXformUtils::PcrProjectElement(pexprRightWindow, 0 /* row_number window function*/));

	pdrgpdrgpcrInputNew->Append(pdrgpcrLeftNew);
	pdrgpdrgpcrInputNew->Append(pdrgpcrRightNew);

	// generate the scalar condition for the left anti-semi join
	CExpression *pexprScCond = CUtils::PexprConjINDFCond(pmp, pdrgpdrgpcrInputNew);

	// assemble the new left anti-semi join logical operator
	CExpression *pexprLASJ = GPOS_NEW(pmp) CExpression
										(
										pmp,
										GPOS_NEW(pmp) CLogicalLeftAntiSemiJoin(pmp),
										pexprLeftWindow,
										pexprRightWindow,
										pexprScCond
										);

	// clean up
	pdrgpdrgpcrInputNew->Release();

	// add alternative to results
	pxfres->Add(pexprLASJ);
}
Beispiel #2
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PdrgpcrCreateMapping
//
//	@doc:
//		Create output column mapping given a list of column descriptors and
//		a pointer to the operator creating that column
//
//---------------------------------------------------------------------------
DrgPcr *
CLogical::PdrgpcrCreateMapping
	(
	IMemoryPool *pmp,
	const DrgPcoldesc *pdrgpcoldesc,
	ULONG ulOpSourceId
	)
	const
{
	// get column factory from optimizer context object
	CColumnFactory *pcf = COptCtxt::PoctxtFromTLS()->Pcf();
	
	ULONG ulCols = pdrgpcoldesc->UlLength();
	
	DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp, ulCols);
	for(ULONG ul = 0; ul < ulCols; ul++)
	{
		CColumnDescriptor *pcoldesc = (*pdrgpcoldesc)[ul];
		CName name(pmp, pcoldesc->Name());
		
		CColRef *pcr = pcf->PcrCreate(pcoldesc, name, ulOpSourceId);
		pdrgpcr->Append(pcr);
	}
	
	return pdrgpcr;
}
Beispiel #3
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PdrgpdrgpcrCreatePartCols
//
//	@doc:
//		Initialize array of partition columns from the array with their indexes
//
//---------------------------------------------------------------------------
DrgDrgPcr *
CLogical::PdrgpdrgpcrCreatePartCols
	(
	IMemoryPool *pmp,
	DrgPcr *pdrgpcr,
	const DrgPul *pdrgpulPart
	)
{
	GPOS_ASSERT(NULL != pdrgpcr && "Output columns cannot be NULL");
	GPOS_ASSERT(NULL != pdrgpulPart);
	
	DrgDrgPcr *pdrgpdrgpcrPart = GPOS_NEW(pmp) DrgDrgPcr(pmp);
	
	const ULONG ulPartCols = pdrgpulPart->UlLength();
	GPOS_ASSERT(0 < ulPartCols);
	
	for (ULONG ul = 0; ul < ulPartCols; ul++)
	{
		ULONG ulCol = *((*pdrgpulPart)[ul]);
		
		CColRef *pcr = (*pdrgpcr)[ulCol];
		DrgPcr * pdrgpcrCurr = GPOS_NEW(pmp) DrgPcr(pmp);
		pdrgpcrCurr->Append(pcr);
		pdrgpdrgpcrPart->Append(pdrgpcrCurr);
	}
	
	return pdrgpdrgpcrPart;
}
Beispiel #4
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalAgg::PdsRequiredIntermediateAgg
//
//	@doc:
//		Compute required distribution of the n-th child of an intermediate 
//		aggregate operator
//
//---------------------------------------------------------------------------
CDistributionSpec *
CPhysicalAgg::PdsRequiredIntermediateAgg
	(
	IMemoryPool *pmp,
	ULONG  ulOptReq
	)
	const
{
	GPOS_ASSERT(COperator::EgbaggtypeIntermediate == m_egbaggtype);

	if (0 == ulOptReq)
	{
		return PdsMaximalHashed(pmp, m_pdrgpcr);
	}

	DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);
	const ULONG ulLen = m_pdrgpcr->UlLength() - m_pdrgpcrArgDQA->UlLength();
	for (ULONG ul = 0; ul < ulLen; ul++)
	{
		CColRef *pcr = (*m_pdrgpcr)[ul];
		pdrgpcr->Append(pcr);
	}

	CDistributionSpec *pds = PdsMaximalHashed(pmp, pdrgpcr);
	pdrgpcr->Release();

	return pds;
}
Beispiel #5
0
//---------------------------------------------------------------------------
//	@function:
//		CColRefSet::Pdrgpcr
//
//	@doc:
//		Convert set into array
//
//---------------------------------------------------------------------------
DrgPcr *
CColRefSet::Pdrgpcr
	(
	IMemoryPool *pmp
	)
	const
{
	DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);
	
	CColRefSetIter crsi(*this);
	while(crsi.FAdvance())
	{
		pdrgpcr->Append(crsi.Pcr());
	}
	
	return pdrgpcr;
}
Beispiel #6
0
//---------------------------------------------------------------------------
//	@function:
//		CPartKeys::PpartkeysRemap
//
//	@doc:
//		Create a new PartKeys object from the current one by remapping the
//		keys using the given hashmap
//
//---------------------------------------------------------------------------
CPartKeys *
CPartKeys::PpartkeysRemap
	(
	IMemoryPool *pmp,
	HMUlCr *phmulcr
	)
	const
{
	GPOS_ASSERT(NULL != phmulcr);
	DrgDrgPcr *pdrgpdrgpcr = GPOS_NEW(pmp) DrgDrgPcr(pmp);

	for (ULONG ul = 0; ul < m_ulLevels; ul++)
	{
		CColRef *pcr = CUtils::PcrRemap(PcrKey(ul), phmulcr, false /*fMustExist*/);

		DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);
		pdrgpcr->Append(pcr);

		pdrgpdrgpcr->Append(pdrgpcr);
	}

	return GPOS_NEW(pmp) CPartKeys(pdrgpdrgpcr);
}
Beispiel #7
0
//---------------------------------------------------------------------------
//	@function:
//		CPartKeys::PpartkeysCopy
//
//	@doc:
//		Copy part key into the given memory pool
//
//---------------------------------------------------------------------------
CPartKeys *
CPartKeys::PpartkeysCopy
	(
	IMemoryPool *pmp
	)
{
	DrgDrgPcr *pdrgpdrgpcrCopy = GPOS_NEW(pmp) DrgDrgPcr(pmp);

	const ULONG ulLength = m_pdrgpdrgpcr->UlLength();
	for (ULONG ul = 0; ul < ulLength; ul++)
	{
		DrgPcr *pdrgpcr = (*m_pdrgpdrgpcr)[ul];
		DrgPcr *pdrgpcrCopy = GPOS_NEW(pmp) DrgPcr(pmp);
		const ULONG ulCols = pdrgpcr->UlLength();
		for (ULONG ulCol = 0; ulCol < ulCols; ulCol++)
		{
			pdrgpcrCopy->Append((*pdrgpcr)[ulCol]);
		}
		pdrgpdrgpcrCopy->Append(pdrgpcrCopy);
	}

	return GPOS_NEW(pmp) CPartKeys(pdrgpdrgpcrCopy);
}
//---------------------------------------------------------------------------
//	@function:
//		CTranslatorDXLToExprUtils::Pdrgpcr
//
//	@doc:
// 		Construct a dynamic array of column references corresponding to the
//		given col ids
//
//---------------------------------------------------------------------------
DrgPcr *
CTranslatorDXLToExprUtils::Pdrgpcr
	(
	IMemoryPool *pmp,
	HMUlCr *phmulcr,
	const DrgPul *pdrgpulColIds
	)
{
	GPOS_ASSERT(NULL != pdrgpulColIds);

	DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);

	for (ULONG ul = 0; ul < pdrgpulColIds->UlLength(); ul++)
	{
		ULONG *pulColId = (*pdrgpulColIds)[ul];
		const CColRef *pcr = phmulcr->PtLookup(pulColId);
		GPOS_ASSERT(NULL != pcr);

		pdrgpcr->Append(const_cast<CColRef*>(pcr));
	}

	return pdrgpcr;
}
Beispiel #9
0
//---------------------------------------------------------------------------
//	@function:
//		CQueryContext::PqcGenerate
//
//	@doc:
// 		Generate the query context for the given expression and array of
//		output column ref ids
//
//---------------------------------------------------------------------------
CQueryContext *
CQueryContext::PqcGenerate
(
    IMemoryPool *pmp,
    CExpression * pexpr,
    DrgPul *pdrgpulQueryOutputColRefId,
    DrgPmdname *pdrgpmdname,
    BOOL fDeriveStats
)
{
    GPOS_ASSERT(NULL != pexpr && NULL != pdrgpulQueryOutputColRefId);

    CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp);
    DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);

    COptCtxt *poptctxt = COptCtxt::PoctxtFromTLS();
    CColumnFactory *pcf = poptctxt->Pcf();
    GPOS_ASSERT(NULL != pcf);

    const ULONG ulLen = pdrgpulQueryOutputColRefId->UlLength();
    for (ULONG ul = 0; ul < ulLen; ul++)
    {
        ULONG *pul = (*pdrgpulQueryOutputColRefId)[ul];
        GPOS_ASSERT(NULL != pul);

        CColRef *pcr = pcf->PcrLookup(*pul);
        GPOS_ASSERT(NULL != pcr);

        pcrs->Include(pcr);
        pdrgpcr->Append(pcr);
    }

    COrderSpec *pos = NULL;
    CExpression *pexprResult = pexpr;
    COperator *popTop = PopTop(pexpr);
    if (COperator::EopLogicalLimit == popTop->Eopid())
    {
        // top level operator is a limit, copy order spec to query context
        pos = CLogicalLimit::PopConvert(popTop)->Pos();
        pos->AddRef();
    }
    else
    {
        // no order required
        pos = GPOS_NEW(pmp) COrderSpec(pmp);
    }

    CDistributionSpec *pds = NULL;

    BOOL fDML = CUtils::FLogicalDML(pexpr->Pop());
    poptctxt->MarkDMLQuery(fDML);

    if (fDML)
    {
        pds = GPOS_NEW(pmp) CDistributionSpecAny(COperator::EopSentinel);
    }
    else
    {
        pds = GPOS_NEW(pmp) CDistributionSpecSingleton(CDistributionSpecSingleton::EstMaster);
    }

    CRewindabilitySpec *prs = GPOS_NEW(pmp) CRewindabilitySpec(CRewindabilitySpec::ErtNone /*ert*/);

    CEnfdOrder *peo = GPOS_NEW(pmp) CEnfdOrder(pos, CEnfdOrder::EomSatisfy);

    // we require satisfy matching on distribution since final query results must be sent to master
    CEnfdDistribution *ped = GPOS_NEW(pmp) CEnfdDistribution(pds, CEnfdDistribution::EdmSatisfy);

    CEnfdRewindability *per = GPOS_NEW(pmp) CEnfdRewindability(prs, CEnfdRewindability::ErmSatisfy);

    CCTEReq *pcter = poptctxt->Pcteinfo()->PcterProducers(pmp);

    CReqdPropPlan *prpp = GPOS_NEW(pmp) CReqdPropPlan(pcrs, peo, ped, per, pcter);

    pdrgpmdname->AddRef();
    return GPOS_NEW(pmp) CQueryContext(pmp, pexprResult, prpp, pdrgpcr, pdrgpmdname, fDeriveStats);
}
Beispiel #10
0
//---------------------------------------------------------------------------
//	@function:
//		CLogical::PpcDeriveConstraintFromTable
//
//	@doc:
//		Derive constraint property from a table/index get
//
//---------------------------------------------------------------------------
CPropConstraint *
CLogical::PpcDeriveConstraintFromTable
	(
	IMemoryPool *pmp,
	const CTableDescriptor *ptabdesc,
	const DrgPcr *pdrgpcrOutput
	)
{
	DrgPcrs *pdrgpcrs = GPOS_NEW(pmp) DrgPcrs(pmp);

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

	const DrgPcoldesc *pdrgpcoldesc = ptabdesc->Pdrgpcoldesc();
	const ULONG ulCols = pdrgpcoldesc->UlLength();

	DrgPcr *pdrgpcrNonSystem = GPOS_NEW(pmp) DrgPcr(pmp);

	for (ULONG ul = 0; ul < ulCols; ul++)
	{
		CColumnDescriptor *pcoldesc = (*pdrgpcoldesc)[ul];
		CColRef *pcr = (*pdrgpcrOutput)[ul];
		// we are only interested in non-system columns that are defined as
		// being NOT NULL

		if (pcoldesc->FSystemColumn())
		{
			continue;
		}

		pdrgpcrNonSystem->Append(pcr);

		if (pcoldesc->FNullable())
		{
			continue;
		}

		// add a "not null" constraint and an equivalence class
		CConstraint * pcnstr = CConstraintInterval::PciUnbounded(pmp, pcr, false /*fIncludesNull*/);

		if (pcnstr == NULL)
		{
			continue;
		}
		pdrgpcnstr->Append(pcnstr);

		CColRefSet *pcrsEquiv = GPOS_NEW(pmp) CColRefSet(pmp);
		pcrsEquiv->Include(pcr);
		pdrgpcrs->Append(pcrsEquiv);
	}

	CMDAccessor *pmda = COptCtxt::PoctxtFromTLS()->Pmda();
	const IMDRelation *pmdrel = pmda->Pmdrel(ptabdesc->Pmdid());

	const ULONG ulCheckConstraint = pmdrel->UlCheckConstraints();
	for (ULONG ul = 0; ul < ulCheckConstraint; ul++)
	{
		IMDId *pmdidCheckConstraint = pmdrel->PmdidCheckConstraint(ul);

		const IMDCheckConstraint *pmdCheckConstraint = pmda->Pmdcheckconstraint(pmdidCheckConstraint);

		// extract the check constraint expression
		CExpression *pexprCheckConstraint = pmdCheckConstraint->Pexpr(pmp, pmda, pdrgpcrNonSystem);
		GPOS_ASSERT(NULL != pexprCheckConstraint);
		GPOS_ASSERT(CUtils::FPredicate(pexprCheckConstraint));

		DrgPcrs *pdrgpcrsChild = NULL;
		CConstraint *pcnstr = CConstraint::PcnstrFromScalarExpr(pmp, pexprCheckConstraint, &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);
		pexprCheckConstraint->Release();
	}

	pdrgpcrNonSystem->Release();

	return GPOS_NEW(pmp) CPropConstraint(pmp, pdrgpcrs, CConstraint::PcnstrConjunction(pmp, pdrgpcnstr));
}