Exemple #1
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::PexprExpand
//
//	@doc:
//		Create join order
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprExpand()
{
	CBitSet *pbs = GPOS_NEW(m_pmp) CBitSet(m_pmp);
	for (ULONG ul = 0; ul < m_ulComps; ul++)
	{
		(void) pbs->FExchangeSet(ul);
	}

	if (GPOPT_DP_JOIN_ORDERING_SIZE_THRESHOLD < m_ulComps &&
		GPOPT_DP_JOIN_ORDERING_CONNECTEDNESS_THRESHOLD < DMaxConnectedness(pbs))
	{
		// terminate early if computation cost is expected to be large
		pbs->Release();

		return NULL;
	}

	CExpression *pexprResult = PexprBestJoinOrder(pbs);
	if (NULL != pexprResult)
	{
		pexprResult->AddRef();
	}
	pbs->Release();

	return pexprResult;
}
//---------------------------------------------------------------------------
//	@function:
//		CLogicalGbAggDeduplicate::PstatsDerive
//
//	@doc:
//		Derive statistics
//
//---------------------------------------------------------------------------
IStatistics *
CLogicalGbAggDeduplicate::PstatsDerive
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	DrgPstat * // not used
	)
	const
{
	GPOS_ASSERT(Esp(exprhdl) > EspNone);
	IStatistics *pstatsChild = exprhdl.Pstats(0);

	// extract computed columns
	DrgPul *pdrgpulComputedCols = GPOS_NEW(pmp) DrgPul(pmp);
	exprhdl.Pdpscalar(1 /*ulChildIndex*/)->PcrsDefined()->ExtractColIds(pmp, pdrgpulComputedCols);

	// construct bitset with keys of join child
	CBitSet *pbsKeys = GPOS_NEW(pmp) CBitSet(pmp);
	const ULONG ulKeys = m_pdrgpcrKeys->UlLength();
	for (ULONG ul = 0; ul < ulKeys; ul++)
	{
		CColRef *pcr = (*m_pdrgpcrKeys)[ul];
		pbsKeys->FExchangeSet(pcr->UlId());
	}

	IStatistics *pstats = CLogicalGbAgg::PstatsDerive(pmp, pstatsChild, Pdrgpcr(), pdrgpulComputedCols, pbsKeys);
	pbsKeys->Release();
	pdrgpulComputedCols->Release();

	return pstats;
}
//---------------------------------------------------------------------------
//	@function:
//		CTranslatorDXLToExprUtils::AddKeySets
//
//	@doc:
// 		Add key sets info from the MD relation to the table descriptor
//
//---------------------------------------------------------------------------
void
CTranslatorDXLToExprUtils::AddKeySets
	(
	IMemoryPool *pmp,
	CTableDescriptor *ptabdesc,
	const IMDRelation *pmdrel,
	HMUlUl *phmululColMapping
	)
{
	GPOS_ASSERT(NULL != ptabdesc);
	GPOS_ASSERT(NULL != pmdrel);

	const ULONG ulKeySets = pmdrel->UlKeySets();
	for (ULONG ul = 0; ul < ulKeySets; ul++)
	{
		CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, ptabdesc->UlColumns());
		const DrgPul *pdrgpulKeys = pmdrel->PdrgpulKeyset(ul);
		const ULONG ulKeys = pdrgpulKeys->UlLength();

		for (ULONG ulKey = 0; ulKey < ulKeys; ulKey++)
		{
			// populate current keyset
			ULONG ulOriginalKey = *((*pdrgpulKeys)[ulKey]);
			ULONG *pulRemappedKey = phmululColMapping->PtLookup(&ulOriginalKey);
			GPOS_ASSERT(NULL != pulRemappedKey);
			
			pbs->FExchangeSet(*pulRemappedKey);
		}

		if (!ptabdesc->FAddKeySet(pbs))
		{
			pbs->Release();
		}
	}
}
Exemple #4
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::GenerateSubsets
//
//	@doc:
//		Generate all subsets of given array of elements
//
//---------------------------------------------------------------------------
void
CJoinOrderDP::GenerateSubsets
	(
	IMemoryPool *mp,
	CBitSet *pbsCurrent,
	ULONG *pulElems,
	ULONG size,
	ULONG ulIndex,
	CBitSetArray *pdrgpbsSubsets
	)
{
	GPOS_CHECK_STACK_SIZE;
	GPOS_CHECK_ABORT;

	GPOS_ASSERT(ulIndex <= size);
	GPOS_ASSERT(NULL != pbsCurrent);
	GPOS_ASSERT(NULL != pulElems);
	GPOS_ASSERT(NULL != pdrgpbsSubsets);

	if (ulIndex == size)
	{
		pdrgpbsSubsets->Append(pbsCurrent);
		return;
	}

	CBitSet *pbsCopy = GPOS_NEW(mp) CBitSet(mp, *pbsCurrent);
#ifdef GPOS_DEBUG
	BOOL fSet =
#endif // GPOS_DEBUG
		pbsCopy->ExchangeSet(pulElems[ulIndex]);
	GPOS_ASSERT(!fSet);

	GenerateSubsets(mp, pbsCopy, pulElems, size, ulIndex + 1, pdrgpbsSubsets);
	GenerateSubsets(mp, pbsCurrent, pulElems, size, ulIndex + 1, pdrgpbsSubsets);
}
Exemple #5
0
// ***************************************************************************
CBitSet	CBitSet::operator~() const
{
	CBitSet	ret;

	ret= *this;
	ret.flip();
	return ret;
}
Exemple #6
0
//---------------------------------------------------------------------------
//	@function:
//		CPartConstraint::PpartcnstrRemaining
//
//	@doc:
//		Return what remains of the current part constraint after taking out
//		the given part constraint. Returns NULL is the difference cannot be
//		performed
//
//---------------------------------------------------------------------------
CPartConstraint *
CPartConstraint::PpartcnstrRemaining
	(
	IMemoryPool *mp,
	CPartConstraint *ppartcnstr
	)
{
	GPOS_ASSERT(!m_fUninterpreted && "Calling PpartcnstrRemaining on uninterpreted partition constraint");
	GPOS_ASSERT(NULL != ppartcnstr);

	if (m_num_of_part_levels != ppartcnstr->m_num_of_part_levels || !ppartcnstr->FCanNegate())
	{
		return NULL;
	}

	UlongToConstraintMap *phmulcnstr = GPOS_NEW(mp) UlongToConstraintMap(mp);
	CBitSet *pbsDefaultParts = GPOS_NEW(mp) CBitSet(mp);

	// constraint on first level
	CConstraint *pcnstrCurrent = Pcnstr(0 /*ulLevel*/);
	CConstraint *pcnstrOther = ppartcnstr->Pcnstr(0 /*ulLevel*/);

	CConstraint *pcnstrRemaining = PcnstrRemaining(mp, pcnstrCurrent, pcnstrOther);

#ifdef GPOS_DEBUG
	BOOL result =
#endif // GPOS_DEBUG
	phmulcnstr->Insert(GPOS_NEW(mp) ULONG(0), pcnstrRemaining);
	GPOS_ASSERT(result);

	if (IsDefaultPartition(0 /*ulLevel*/) && !ppartcnstr->IsDefaultPartition(0 /*ulLevel*/))
	{
		pbsDefaultParts->ExchangeSet(0 /*ulBit*/);
	}

	// copy the remaining constraints and default partition flags
	for (ULONG ul = 1; ul < m_num_of_part_levels; ul++)
	{
		CConstraint *pcnstrLevel = Pcnstr(ul);
		if (NULL != pcnstrLevel)
		{
			pcnstrLevel->AddRef();
#ifdef GPOS_DEBUG
			BOOL result =
#endif // GPOS_DEBUG
			phmulcnstr->Insert(GPOS_NEW(mp) ULONG(ul), pcnstrLevel);
			GPOS_ASSERT(result);
		}

		if (IsDefaultPartition(ul))
		{
			pbsDefaultParts->ExchangeSet(ul);
		}
	}

	m_pdrgpdrgpcr->AddRef();
	return GPOS_NEW(mp) CPartConstraint(mp, phmulcnstr, pbsDefaultParts, false /*is_unbounded*/, m_pdrgpdrgpcr);
}
Exemple #7
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalGet::OsPrint
//
//	@doc:
//		debug print
//
//---------------------------------------------------------------------------
IOstream &
CLogicalGet::OsPrint
	(
	IOstream &os
	)
	const
{
	if (m_fPattern)
	{
		return COperator::OsPrint(os);
	}
	else
	{
		os << SzId() << " ";
		// alias of table as referenced in the query
		m_pnameAlias->OsPrint(os);

		// actual name of table in catalog and columns
		os << " (";
		m_ptabdesc->Name().OsPrint(os);
		os << "), Columns: [";
		CUtils::OsPrintDrgPcr(os, m_pdrgpcrOutput);
		os << "] Key sets: {";
		
		const ULONG ulColumns = m_pdrgpcrOutput->Size();
		const CBitSetArray *pdrgpbsKeys = m_ptabdesc->PdrgpbsKeys();
		for (ULONG ul = 0; ul < pdrgpbsKeys->Size(); ul++)
		{
			CBitSet *pbs = (*pdrgpbsKeys)[ul];
			if (0 < ul)
			{
				os << ", ";
			}
			os << "[";
			ULONG ulPrintedKeys = 0;
			for (ULONG ulKey = 0; ulKey < ulColumns; ulKey++)
			{
				if (pbs->Get(ulKey))
				{
					if (0 < ulPrintedKeys)
					{
						os << ",";
					}
					os << ulKey;
					ulPrintedKeys++;
				}
			}
			os << "]";
		}
		os << "}";
		
	}
		
	return os;
}
Exemple #8
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalDML::PosComputeRequired
//
//	@doc:
//		Compute required sort order based on the key information in the table 
//		descriptor:
//		1. If a table has no keys, no sort order is necessary.
//
//		2. If a table has keys, but they are not modified in the update, no sort
//		order is necessary. This relies on the fact that Split always produces
//		Delete tuples before Insert tuples, so we cannot have two versions of the
//		same tuple on the same time. Consider for example tuple (A: 1, B: 2), where
//		A is key and an update "set B=B+1". Since there cannot be any other tuple 
//		with A=1, and the tuple (1,2) is deleted before tuple (1,3) gets inserted,
//		we don't need to enforce specific order of deletes and inserts.
//
//		3. If the update changes a key column, enforce order on the Action column
//		to deliver Delete tuples before Insert tuples. This is done to avoid a
//		conflict between a newly inserted tuple and an old tuple that is about to be
//		deleted. Consider table with tuples (A: 1),(A: 2), where A is key, and 
//		update "set A=A+1". Split will generate tuples (1,"D"), (2,"I"), (2,"D"), (3,"I").
//		If (2,"I") happens before (2,"D") we will have a violation of the key constraint.
//		Therefore we need to enforce sort order on Action to get all old tuples
//		tuples deleted before the new ones are inserted.
//
//---------------------------------------------------------------------------
COrderSpec *
CPhysicalDML::PosComputeRequired
	(
	IMemoryPool *pmp,
	CTableDescriptor *ptabdesc
	)
{
	COrderSpec *pos = GPOS_NEW(pmp) COrderSpec(pmp);

	const DrgPbs *pdrgpbsKeys = ptabdesc->PdrgpbsKeys();
	if (1 < pdrgpbsKeys->UlLength() && CLogicalDML::EdmlUpdate == m_edmlop)
	{
		// if this is an update on the target table's keys, enforce order on 
		// the action column, see explanation in function's comment		
		const ULONG ulKeySets = pdrgpbsKeys->UlLength();
		BOOL fNeedsSort = false;
		for (ULONG ul = 0; ul < ulKeySets && !fNeedsSort; ul++)
		{
			CBitSet *pbs = (*pdrgpbsKeys)[ul];
			if (!pbs->FDisjoint(m_pbsModified))
			{
				fNeedsSort = true;
				break;
			}
		}
		
		if (fNeedsSort)
		{
			IMDId *pmdid = m_pcrAction->Pmdtype()->PmdidCmp(IMDType::EcmptL);
			pmdid->AddRef();
			pos->Append(pmdid, m_pcrAction, COrderSpec::EntAuto);
		}
	}
	else if (m_ptabdesc->FPartitioned())
	{
		COptimizerConfig *poconf = COptCtxt::PoctxtFromTLS()->Poconf();

		BOOL fInsertSortOnParquet = FInsertSortOnParquet();
		BOOL fInsertSortOnRows = FInsertSortOnRows(poconf);

		if (fInsertSortOnParquet || fInsertSortOnRows)
		{
			GPOS_ASSERT(CLogicalDML::EdmlInsert == m_edmlop);
			m_fInputSorted = true;
			// if this is an INSERT over a partitioned Parquet or Row-oriented table,
			// sort tuples by their table oid
			IMDId *pmdid = m_pcrTableOid->Pmdtype()->PmdidCmp(IMDType::EcmptL);
			pmdid->AddRef();
			pos->Append(pmdid, m_pcrTableOid, COrderSpec::EntAuto);
		}
	}
	
	return pos;
}
//---------------------------------------------------------------------------
//	@function:
//		CSerializableOptimizerConfig::Serialize
//
//	@doc:
//		Serialize contents into provided stream
//
//---------------------------------------------------------------------------
void
CSerializableOptimizerConfig::Serialize
	(
	COstream &oos
	)
{
	CXMLSerializer xml_serializer(m_mp, oos, false /*Indent*/);

	// Copy traceflags from global state
	CBitSet *pbs = CTask::Self()->GetTaskCtxt()->copy_trace_flags(m_mp);
	m_optimizer_config->Serialize(m_mp, &xml_serializer, pbs);
	pbs->Release();
}
Exemple #10
0
//---------------------------------------------------------------------------
//	@function:
//		CXformImplementDML::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformImplementDML::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	CLogicalDML *popDML = CLogicalDML::PopConvert(pexpr->Pop());
	IMemoryPool *mp = pxfctxt->Pmp();

	// extract components for alternative

	CLogicalDML::EDMLOperator edmlop = popDML->Edmlop();

	CTableDescriptor *ptabdesc = popDML->Ptabdesc();
	ptabdesc->AddRef();
	
	CColRefArray *pdrgpcrSource = popDML->PdrgpcrSource();
	pdrgpcrSource->AddRef();
	CBitSet *pbsModified = popDML->PbsModified();
	pbsModified->AddRef();

	CColRef *pcrAction = popDML->PcrAction();
	CColRef *pcrTableOid = popDML->PcrTableOid();
	CColRef *pcrCtid = popDML->PcrCtid();
	CColRef *pcrSegmentId = popDML->PcrSegmentId();
	CColRef *pcrTupleOid = popDML->PcrTupleOid();

	// child of DML operator
	CExpression *pexprChild = (*pexpr)[0];
	pexprChild->AddRef();

	// create physical DML
	CExpression *pexprAlt = 
		GPOS_NEW(mp) CExpression
			(
			mp,
			GPOS_NEW(mp) CPhysicalDML(mp, edmlop, ptabdesc, pdrgpcrSource, pbsModified, pcrAction, pcrTableOid, pcrCtid, pcrSegmentId, pcrTupleOid),
			pexprChild
			);
	// add alternative to transformation result
	pxfres->Add(pexprAlt);
}
Exemple #11
0
//---------------------------------------------------------------------------
//	@function:
//		CBitSetTest::EresUnittest_Basics
//
//	@doc:
//		Testing ctors/dtor
//
//---------------------------------------------------------------------------
GPOS_RESULT
CBitSetTest::EresUnittest_Basics()
{
	// create memory pool
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	ULONG cSizeBits = 32;
	CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);

	ULONG cInserts = 10;
	for (ULONG i = 0; i < cInserts; i += 2)
	{
		// forces addition of new link
		pbs->FExchangeSet(i * cSizeBits);
	}
	GPOS_ASSERT(cInserts / 2 == pbs->CElements());

	for (ULONG i = 1; i < cInserts; i += 2)
	{
		// new link between existing links
		pbs->FExchangeSet(i * cSizeBits);
	}
	GPOS_ASSERT(cInserts == pbs->CElements());

	CBitSet *pbsCopy = GPOS_NEW(pmp) CBitSet(pmp, *pbs);
	GPOS_ASSERT(pbsCopy->FEqual(pbs));

	// delete old bitset to make sure we're not accidentally
	// using any of its memory
	pbs->Release();

	for (ULONG i = 0; i < cInserts; i++)
	{
		GPOS_ASSERT(pbsCopy->FBit(i * cSizeBits));
	}

	CWStringDynamic str(pmp);
	COstreamString os(&str);
	
	os << *pbsCopy << std::endl;
	GPOS_TRACE(str.Wsz());
	
	pbsCopy->Release();

	return GPOS_OK;
}
//---------------------------------------------------------------------------
//	@function:
//		CTranslatorDXLToQuery::MarkUnusedColumns
//
//	@doc:
//		Mark unused target list entries in the setop child
//
//---------------------------------------------------------------------------
void
CTranslatorDXLToQuery::MarkUnusedColumns
	(
	Query *pquery,
	RangeTblRef *prtref,
	CStateDXLToQuery *pstatedxltoquery,
	const DrgPul *pdrgpulColids
	)
{
	const ULONG ulRTIndex = prtref->rtindex;
	RangeTblEntry *prte = (RangeTblEntry*) gpdb::PvListNth(pquery->rtable, ulRTIndex -1);

	GPOS_ASSERT(RTE_SUBQUERY == prte->rtekind);
	Query *pqueryDerTbl = prte->subquery;

	// maintain the list of used columns in a bit set
	CBitSet *pds = New(m_pmp) CBitSet(m_pmp);
	const ULONG ulLen = pdrgpulColids->UlLength();
	for (ULONG ul = 0; ul < ulLen; ul++)
	{
		ULONG ulValue = *((*pdrgpulColids)[ul]);
		(void) pds->FExchangeSet(ulValue);
	}

	// Mark all columns that are not in the list of required input columns as being unused
	const ULONG ulSize = pstatedxltoquery->UlLength();
	for (ULONG ul = 0; ul < ulSize; ul++)
	{
		ULONG ulColId = pstatedxltoquery->UlColId(ul);
		BOOL fSet = pds->FBit(ulColId);

		if (!fSet)
		{
			// mark the column as unused in the query
			TargetEntry *pte2 = (TargetEntry*) gpdb::PvListNth(pqueryDerTbl->targetList, ul);
			pte2->resjunk = true;

			// mark the column as unused in the state
			TargetEntry *pte = pstatedxltoquery->PteColumn(ul);
			pte->resjunk = true;
		}
	}

	pds->Release();
}
Exemple #13
0
//---------------------------------------------------------------------------
//	@function:
//		CBitSetTest::EresUnittest_Performance
//
//	@doc:
//		Simple perf test -- simulates xform candidate sets
//
//---------------------------------------------------------------------------
GPOS_RESULT
CBitSetTest::EresUnittest_Performance()
{
	// create memory pool
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();
	
	ULONG cSizeBits = 512;
	CBitSet *pbsBase = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);
	for (ULONG i = 0; i < cSizeBits; i++)
		{
			(void) pbsBase->FExchangeSet(i);
		}

	CBitSet *pbsTest = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);
	for (ULONG j = 0; j < 100000; j++)
	{
		ULONG cRandomBits = 16;
		for (ULONG i = 0; i < cRandomBits; i += ((cSizeBits - 1) / cRandomBits))
		{
			(void) pbsTest->FExchangeSet(i);
		}
			
		pbsTest->Intersection(pbsBase);		
	}	
	
	pbsTest->Release();
	pbsBase->Release();
	
	return GPOS_OK;
}	
Exemple #14
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::PexprExpand
//
//	@doc:
//		Create join order
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprExpand()
{
	CBitSet *pbs = GPOS_NEW(m_mp) CBitSet(m_mp);
	for (ULONG ul = 0; ul < m_ulComps; ul++)
	{
		(void) pbs->ExchangeSet(ul);
	}

	CExpression *pexprResult = PexprBestJoinOrder(pbs);
	if (NULL != pexprResult)
	{
		pexprResult->AddRef();
	}
	pbs->Release();

	return pexprResult;
}
Exemple #15
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::PbsCovered
//
//	@doc:
//		Return a subset of the given set covered by one or more edges
//
//---------------------------------------------------------------------------
CBitSet *
CJoinOrderDP::PbsCovered
	(
	CBitSet *pbsInput
	)
{
	GPOS_ASSERT(NULL != pbsInput);
	CBitSet *pbs = GPOS_NEW(m_mp) CBitSet(m_mp);

	for (ULONG ul = 0; ul < m_ulEdges; ul++)
	{
		SEdge *pedge = m_rgpedge[ul];
		if (pbsInput->ContainsAll(pedge->m_pbs))
		{
			pbs->Union(pedge->m_pbs);
		}
	}

	return pbs;
}
Exemple #16
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::DConnectedness
//
//	@doc:
//		 Return connectedness measure of given component
//
//---------------------------------------------------------------------------
CDouble
CJoinOrderDP::DConnectedness
	(
	ULONG ulComp
	)
{
	CBitSet *pbsConnected = GPOS_NEW(m_pmp) CBitSet(m_pmp);
	for (ULONG ul = 0; ul < m_ulEdges; ul++)
	{
		SEdge *pedge = m_rgpedge[ul];
		if (pedge->m_pbs->FBit(ulComp))
		{
			pbsConnected->Union(pedge->m_pbs);
		}
	}
	(void) pbsConnected->FExchangeClear(ulComp);
	DOUBLE dConnectedness = (DOUBLE) pbsConnected->CElements() / m_ulComps;
	pbsConnected->Release();

	return CDouble(dConnectedness);
}
Exemple #17
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::PexprBuildPred
//
//	@doc:
//		Build predicate connecting the two given sets
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprBuildPred
	(
	CBitSet *pbsFst,
	CBitSet *pbsSnd
	)
{
	// collect edges connecting the given sets
	CBitSet *pbsEdges = GPOS_NEW(m_mp) CBitSet(m_mp);
	CBitSet *pbs = GPOS_NEW(m_mp) CBitSet(m_mp, *pbsFst);
	pbs->Union(pbsSnd);

	for (ULONG ul = 0; ul < m_ulEdges; ul++)
	{
		SEdge *pedge = m_rgpedge[ul];
		if (
			pbs->ContainsAll(pedge->m_pbs) &&
			!pbsFst->IsDisjoint(pedge->m_pbs) &&
			!pbsSnd->IsDisjoint(pedge->m_pbs)
			)
		{
#ifdef GPOS_DEBUG
		BOOL fSet =
#endif // GPOS_DEBUG
			pbsEdges->ExchangeSet(ul);
			GPOS_ASSERT(!fSet);
		}
	}
	pbs->Release();

	CExpression *pexprPred = NULL;
	if (0 < pbsEdges->Size())
	{
		CExpressionArray *pdrgpexpr = GPOS_NEW(m_mp) CExpressionArray(m_mp);
		CBitSetIter bsi(*pbsEdges);
		while (bsi.Advance())
		{
			ULONG ul = bsi.Bit();
			SEdge *pedge = m_rgpedge[ul];
			pedge->m_pexpr->AddRef();
			pdrgpexpr->Append(pedge->m_pexpr);
		}

		pexprPred = CPredicateUtils::PexprConjunction(m_mp, pdrgpexpr);
	}

	pbsEdges->Release();
	return pexprPred;
}
Exemple #18
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::PexprJoin
//
//	@doc:
//		Join expressions in the given set
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprJoin
	(
	CBitSet *pbs
	)
{
	GPOS_ASSERT(2 == pbs->Size());

	CBitSetIter bsi(*pbs);
	(void) bsi.Advance();
	ULONG ulCompFst = bsi.Bit();
	(void) bsi.Advance();
	ULONG ulCompSnd = bsi.Bit();
	GPOS_ASSERT(!bsi.Advance());

	CBitSet *pbsFst = GPOS_NEW(m_mp) CBitSet(m_mp);
	(void) pbsFst->ExchangeSet(ulCompFst);
	CBitSet *pbsSnd = GPOS_NEW(m_mp) CBitSet(m_mp);
	(void) pbsSnd->ExchangeSet(ulCompSnd);
	CExpression *pexprScalar = PexprPred(pbsFst, pbsSnd);
	pbsFst->Release();
	pbsSnd->Release();

	if (NULL == pexprScalar)
	{
		return NULL;
	}

	CExpression *pexprLeft = m_rgpcomp[ulCompFst]->m_pexpr;
	CExpression *pexprRight = m_rgpcomp[ulCompSnd]->m_pexpr;
	pexprLeft->AddRef();
	pexprRight->AddRef();
	pexprScalar->AddRef();
	CExpression *pexprJoin =
		CUtils::PexprLogicalJoin<CLogicalInnerJoin>(m_mp, pexprLeft, pexprRight, pexprScalar);

	DeriveStats(pexprJoin);
	// store solution in DP table
	pbs->AddRef();
#ifdef GPOS_DEBUG
	BOOL fInserted =
#endif // GPOS_DEBUG
		m_phmbsexpr->Insert(pbs, pexprJoin);
	GPOS_ASSERT(fInserted);

	return pexprJoin;
}
Exemple #19
0
//---------------------------------------------------------------------------
//	@function:
//		CBitSetTest::EresUnittest_SetOps
//
//	@doc:
//		Test for set operations
//
//---------------------------------------------------------------------------
GPOS_RESULT
CBitSetTest::EresUnittest_SetOps()
{
	// create memory pool
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	ULONG cSizeBits = 32;
	ULONG cInserts = 10;

	CBitSet *pbs1 = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);
	for (ULONG i = 0; i < cInserts; i += 2)
	{
		pbs1->FExchangeSet(i * cSizeBits);
	}

	CBitSet *pbs2 = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);
	for (ULONG i = 1; i < cInserts; i += 2)
	{
		pbs2->FExchangeSet(i * cSizeBits);
	}
	CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);

	pbs->Union(pbs1);
	GPOS_ASSERT(pbs->FEqual(pbs1));

	pbs->Intersection(pbs1);
	GPOS_ASSERT(pbs->FEqual(pbs1));
	GPOS_ASSERT(pbs->FEqual(pbs));
	GPOS_ASSERT(pbs1->FEqual(pbs1));

	pbs->Union(pbs2);
	GPOS_ASSERT(!pbs->FEqual(pbs1) && !pbs->FEqual(pbs2));
	GPOS_ASSERT(pbs->FSubset(pbs1) && pbs->FSubset(pbs2));
	
	pbs->Difference(pbs2);
	GPOS_ASSERT(pbs->FEqual(pbs1));

	pbs1->Release();

	pbs->Union(pbs2);
	pbs->Intersection(pbs2);
	GPOS_ASSERT(pbs->FEqual(pbs2));
	GPOS_ASSERT(pbs->FSubset(pbs2));

	GPOS_ASSERT(pbs->CElements() == pbs2->CElements());

	pbs2->Release();

	pbs->Release();

	return GPOS_OK;
}
Exemple #20
0
//---------------------------------------------------------------------------
//	@function:
//		CBitSetTest::EresUnittest_Removal
//
//	@doc:
//		Cleanup test
//
//---------------------------------------------------------------------------
GPOS_RESULT
CBitSetTest::EresUnittest_Removal()
{
	// create memory pool
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	ULONG cSizeBits = 32;
	CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);
	CBitSet *pbsEmpty = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);

	GPOS_ASSERT(pbs->FEqual(pbsEmpty));
	GPOS_ASSERT(pbsEmpty->FEqual(pbs));

	ULONG cInserts = 10;
	for (ULONG i = 0; i < cInserts; i++)
	{
		pbs->FExchangeSet(i * cSizeBits);

		GPOS_ASSERT(i + 1 == pbs->CElements());
	}

	for (ULONG i = 0; i < cInserts; i++)
	{
		// cleans up empty links
		pbs->FExchangeClear(i * cSizeBits);

		GPOS_ASSERT(cInserts - i - 1 == pbs->CElements());
	}

	GPOS_ASSERT(pbs->FEqual(pbsEmpty));
	GPOS_ASSERT(pbsEmpty->FEqual(pbs));

	pbs->Release();
	pbsEmpty->Release();

	return GPOS_OK;
}
Exemple #21
0
//---------------------------------------------------------------------------
//	@function:
//		CPhysical::PppsRequiredPushThruNAry
//
//	@doc:
//		Helper for pushing required partition propagation to the children of
//		an n-ary operator
//
//---------------------------------------------------------------------------
CPartitionPropagationSpec *
CPhysical::PppsRequiredPushThruNAry
	(
	IMemoryPool *mp,
	CExpressionHandle &exprhdl,
	CPartitionPropagationSpec *pppsReqd,
	ULONG child_index
	)
{
	GPOS_ASSERT(NULL != pppsReqd);


	CPartIndexMap *ppimReqd = pppsReqd->Ppim();
	CPartFilterMap *ppfmReqd = pppsReqd->Ppfm();

	ULongPtrArray *pdrgpul = ppimReqd->PdrgpulScanIds(mp);

	CPartIndexMap *ppimResult = GPOS_NEW(mp) CPartIndexMap(mp);
	CPartFilterMap *ppfmResult = GPOS_NEW(mp) CPartFilterMap(mp);

	const ULONG ulPartIndexIds = pdrgpul->Size();
	const ULONG arity = exprhdl.UlNonScalarChildren();

	// iterate over required part index ids and decide which ones to push to the outer
	// and which to the inner side of the n-ary op
	for (ULONG ul = 0; ul < ulPartIndexIds; ul++)
	{
		ULONG part_idx_id = *((*pdrgpul)[ul]);
		GPOS_ASSERT(ppimReqd->Contains(part_idx_id));

		CBitSet *pbsPartConsumer = GPOS_NEW(mp) CBitSet(mp);
		for (ULONG ulChildIdx = 0; ulChildIdx < arity; ulChildIdx++)
		{
			if (exprhdl.GetRelationalProperties(ulChildIdx)->Ppartinfo()->FContainsScanId(part_idx_id))
			{
				(void) pbsPartConsumer->ExchangeSet(ulChildIdx);
			}
		}

		if (arity == pbsPartConsumer->Size() &&
			COperator::EopPhysicalSequence == exprhdl.Pop()->Eopid() &&
			(*(exprhdl.Pgexpr()))[0]->FHasCTEProducer())
		{
			GPOS_ASSERT(2 == arity);

			// this is a part index id that comes from both sides of a sequence
			// with a CTE producer on the outer side, so pretend that part index
			// id is not defined the inner sides
			pbsPartConsumer->ExchangeClear(1);
		}

		if (!FCanPushPartReqToChild(pbsPartConsumer, child_index))
		{
			// clean up
			pbsPartConsumer->Release();

			continue;
		}

		// clean up
		pbsPartConsumer->Release();

		CPartKeysArray *pdrgppartkeys = exprhdl.GetRelationalProperties(child_index)->Ppartinfo()->PdrgppartkeysByScanId(part_idx_id);
		GPOS_ASSERT(NULL != pdrgppartkeys);
		pdrgppartkeys->AddRef();

		// push requirements to child node
		ppimResult->AddRequiredPartPropagation(ppimReqd, part_idx_id, CPartIndexMap::EppraPreservePropagators, pdrgppartkeys);

		// check if there is a filter on the part index id and propagate that further down
		if (ppfmReqd->FContainsScanId(part_idx_id))
		{
			CExpression *pexpr = ppfmReqd->Pexpr(part_idx_id);
			// if the current child is inner child and the predicate is IsNull check and the parent is outer join,
			// don't push IsNull check predicate to the partition filter.
			// for all the other cases, push the filter down.
			if (!(1 == child_index &&
				CUtils::FScalarNullTest(pexpr) &&
				CUtils::FPhysicalOuterJoin(exprhdl.Pop()))
				)
			{
				pexpr->AddRef();
				ppfmResult->AddPartFilter(mp, part_idx_id, pexpr, NULL /*stats */);
			}
		}
	}

	pdrgpul->Release();

	return GPOS_NEW(mp) CPartitionPropagationSpec(ppimResult, ppfmResult);
}
//---------------------------------------------------------------------------
//      @function:
//		CPartitionPropagationSpec::SplitPartPredicates
//
//	@doc:
//		Split the partition elimination predicates over the various levels
//		as well as the residual predicate and add them to the appropriate
//		hashmaps. These are to be used when creating the partition selector
//
//---------------------------------------------------------------------------
void
CPartitionPropagationSpec::SplitPartPredicates
	(
	IMemoryPool *pmp,
	CExpression *pexprScalar,
	DrgDrgPcr *pdrgpdrgpcrKeys,
	HMUlExpr *phmulexprEqFilter,	// output
	HMUlExpr *phmulexprFilter,		// output
	CExpression **ppexprResidual	// output
	)
{
	GPOS_ASSERT(NULL != pexprScalar);
	GPOS_ASSERT(NULL != pdrgpdrgpcrKeys);
	GPOS_ASSERT(NULL != phmulexprEqFilter);
	GPOS_ASSERT(NULL != phmulexprFilter);
	GPOS_ASSERT(NULL != ppexprResidual);
	GPOS_ASSERT(NULL == *ppexprResidual);

	DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprScalar);
	CBitSet *pbsUsed = GPOS_NEW(pmp) CBitSet(pmp);
	CColRefSet *pcrsKeys = PcrsKeys(pmp, pdrgpdrgpcrKeys);

	const ULONG ulLevels = pdrgpdrgpcrKeys->UlLength();
	for (ULONG ul = 0; ul < ulLevels; ul++)
	{
		CColRef *pcr = CUtils::PcrExtractPartKey(pdrgpdrgpcrKeys, ul);
		// find conjuncts for this key and mark their positions
		DrgPexpr *pdrgpexprKey = PdrgpexprPredicatesOnKey(pmp, pdrgpexprConjuncts, pcr, pcrsKeys, &pbsUsed);
		const ULONG ulLen = pdrgpexprKey->UlLength();
		if (0 == ulLen)
		{
			// no predicates on this key
			pdrgpexprKey->Release();
			continue;
		}

		if (1 < ulLen || (!CPredicateUtils::FEquality((*pdrgpexprKey)[0])))
		{
			// more than one predicate on this key or one non-equality predicate
#ifdef GPOS_DEBUG
			BOOL fResult =
#endif // GPOS_DEBUG
			phmulexprFilter->FInsert(GPOS_NEW(pmp) ULONG(ul), CPredicateUtils::PexprConjunction(pmp, pdrgpexprKey));
			GPOS_ASSERT(fResult);
			continue;
		}

		// one equality predicate (key = expr); take out the expression
		// and add it to the equality filters map
		CExpression *pexprPartKey = NULL;
		CExpression *pexprOther = NULL;
		IMDType::ECmpType ecmpt = IMDType::EcmptOther;

		CPredicateUtils::ExtractComponents((*pdrgpexprKey)[0], pcr, &pexprPartKey, &pexprOther, &ecmpt);
		GPOS_ASSERT(NULL != pexprOther);
		pexprOther->AddRef();
#ifdef GPOS_DEBUG
		BOOL fResult =
#endif // GPOS_DEBUG
		phmulexprEqFilter->FInsert(GPOS_NEW(pmp) ULONG(ul), pexprOther);
		GPOS_ASSERT(fResult);
		pdrgpexprKey->Release();
	}

	(*ppexprResidual) = PexprResidualFilter(pmp, pdrgpexprConjuncts, pbsUsed);

	pcrsKeys->Release();
	pdrgpexprConjuncts->Release();
	pbsUsed->Release();
}
//---------------------------------------------------------------------------
//	@function:
//		CConfigParamMapping::PbsPack
//
//	@doc:
//		Pack the GPDB config params into a bitset
//
//---------------------------------------------------------------------------
CBitSet *
CConfigParamMapping::PbsPack
	(
	IMemoryPool *pmp,
	ULONG ulXforms // number of available xforms
	)
{
	CBitSet *pbs = New(pmp) CBitSet(pmp, EopttraceSentinel);

	for (ULONG ul = 0; ul < GPOS_ARRAY_SIZE(m_elem); ul++)
	{
		SConfigMappingElem elem = m_elem[ul];
		GPOS_ASSERT(!pbs->FBit((ULONG) elem.m_etf) &&
					"trace flag already set");

		BOOL fVal = *elem.m_pfParam;
		if (elem.m_fNegate)
		{
			// negate the value of config param
			fVal = !fVal;
		}

		if (fVal)
		{
#ifdef GPOS_DEBUG
			BOOL fSet =
#endif // GPOS_DEBUG
				pbs->FExchangeSet((ULONG) elem.m_etf);
			GPOS_ASSERT(!fSet);
		}
	}

	// pack disable flags of xforms
	for (ULONG ul = 0; ul < ulXforms; ul++)
	{
		GPOS_ASSERT(!pbs->FBit(EopttraceDisableXformBase + ul) &&
					"xform trace flag already set");

		if (optimizer_xforms[ul])
		{
#ifdef GPOS_DEBUG
			BOOL fSet =
#endif // GPOS_DEBUG
				pbs->FExchangeSet(EopttraceDisableXformBase + ul);
			GPOS_ASSERT(!fSet);
		}
	}

	// disable index-join if the corresponding GUC is turned off
	if (!optimizer_enable_indexjoin)
	{
		CBitSet *pbsIndexJoin = CXform::PbsIndexJoinXforms(pmp);
		pbs->Union(pbsIndexJoin);
		pbsIndexJoin->Release();
	}

	// disable bitmap scan if the corresponding GUC is turned off
	if (!optimizer_enable_bitmapscan)
	{
		CBitSet *pbsBitmapScan = CXform::PbsBitmapIndexXforms(pmp);
		pbs->Union(pbsBitmapScan);
		pbsBitmapScan->Release();
	}

	// disable outerjoin to unionall transformation if GUC is turned off
	if (!optimizer_enable_outerjoin_to_unionall_rewrite)
	{
		 pbs->FExchangeSet(GPOPT_DISABLE_XFORM_TF(CXform::ExfLeftOuter2InnerUnionAllLeftAntiSemiJoin));
	}

	// disable Assert MaxOneRow plans if GUC is turned off
	if (!optimizer_enable_assert_maxonerow)
	{
		 pbs->FExchangeSet(GPOPT_DISABLE_XFORM_TF(CXform::ExfMaxOneRow2Assert));
	}

	if (!optimizer_enable_partial_index)
	{
		CBitSet *pbsHeterogeneousIndex = CXform::PbsHeterogeneousIndexXforms(pmp);
		pbs->Union(pbsHeterogeneousIndex);
		pbsHeterogeneousIndex->Release();
	}

	return pbs;
}
Exemple #24
0
void DecodeISDNMessage(ofstream f, CString message )
{
	sGlobalDefs gvars;
	gvars.GlobalCallReference = false;
	bool decodeOk = true;
	int bi=0;

	message.TrimLeft(); message.TrimRight();
	BYTE Protocol=0;
	try {
		Protocol=GetByte(message,bi++);
		SetFont(f,ElementType(0,IE_PROTOCOL_DISCRIMINATOR));
		decodeOk=DecodeProtocol(f,INDENT_SIZE,Protocol);
		f<<eFont;
		f<<Break<<endl;
	} catch (CPException se) {
		decodeOk=false;
	}

	
	BYTE crefl;
	if ( decodeOk ) {
		try {
			crefl = GetByte(message,bi++);
		} catch (CPException se) {
			decodeOk=false;
		}
	}
	if ( decodeOk ) {
		SetFont(f,ElementType(0,IE_CALL_REFERENCE));
		decodeOk=DecodeCallReferenceLength(f,3,crefl);
		if (decodeOk) {
			int callRefLen = (crefl & 0x0f);  // should be one or two only
			if ( callRefLen != 0 )
			{
				BYTE CallRef[2] = { 0,0 };
				for (int j=0; j<crefl; j++)
				try {
					CallRef[j]=GetByte(message,bi++);
				}
				catch (CPException se) {
					f<<"**Not enough Call Reference data**"<<Break<<endl;
					decodeOk = false;
				}
				if ( decodeOk ) 
					DecodeCallReference(f,INDENT_SIZE,crefl,CallRef[0],CallRef[1]);
			}
		}
		f<<eFont;
		f<<Break<<endl;
	}

    BYTE MessageType;
    if ( decodeOk ) {
		try {
			MessageType = GetByte(message,bi++);
		} catch (CPException se) {
			decodeOk=false;
		}
	}

	CBitSet elements;
	if ( decodeOk ) {
		SetFont(f,ElementType(MessageType,IE_MESSAGE_TYPE));
		DecodeMessageType(f,INDENT_SIZE,Protocol,MessageType);
		f<<eFont<<endl;
    }

	gvars.ActiveCodeSet = 0;
    int LastActiveCodeSet=0;
	bool decodeDone=false;
    while ( decodeOk && !decodeDone) {
		int ie;
		try {
			ie = GetByte(message,bi++);
		} catch (CPException se) {
			decodeDone=true;
			continue;
		}
		f << Break << endl;
		if ( (ie & 0x80) == 0x80 ) {
			// single octet Information Element
			SetFont(f,ElementType(MessageType,ie));
			if (ie==IE_SENDING_COMPLETE) {
				f << "ie=" << HexOutput(ie) << Break << "IE="<<IEname(MAKE_FULLIE(gvars.ActiveCodeSet,ie)) << Break << endl;
			}
			else if (ie==IE_MORE_DATA) {
				f << "ie=" << HexOutput(ie) << Break << "IE="<<IEname(MAKE_FULLIE(gvars.ActiveCodeSet,ie)) << Break << endl;
			} 
			else {
				BYTE d[1]; 
				switch (ie&0xf0) {
					case IE_RESERVED:
						f << "ie=" << HexOutput(ie) << Break << "IE=" << IEname(MAKE_FULLIE(gvars.ActiveCodeSet,ie)) << Break << endl;
						break;
					case IE_SHIFT:
						f << "ie=" << HexOutput(ie) << Break << "IE=" << IEname(MAKE_FULLIE(gvars.ActiveCodeSet,ie)) << Break << endl;
						d[0]=ie;
						DecodeShift(f,3,&gvars,d);
						break;
					case IE_CONGESTION_LEVEL:
						f << "ie=" << HexOutput(ie) << Break << "IE=" << IEname(MAKE_FULLIE(gvars.ActiveCodeSet,ie)) << Break << endl;
						d[0]=ie;
						DecodeCongestionLevel(f,3,&gvars,d);
						break;
					case IE_REPEAT_INDICATOR:
						f << "ie=" << HexOutput(ie) << Break << "IE=" << IEname(MAKE_FULLIE(gvars.ActiveCodeSet,ie)) << Break << endl;
						d[0]=ie;
						DecodeRepeatIndication(f,3,&gvars,d);
						break;
					default:
						f << "**invalid Single Octet IE** (" << HexOutput(ie) << ")" << Break << endl;
						decodeOk = false;
				}
			}
			f<<eFont<<endl;
		}
		else {
			// multiple octet Information Element
			SetFont(f,ElementType(MessageType,ie));
			int ielen;
			try {
				ielen = GetByte(message,bi++);
			} catch (CPException se ) {
				// IE is missing its length
				f << "No IE Length for ie=" << HexOutput(ie) << Break << endl;
				decodeOk = false;
				continue;
			}
			if ( ielen == 0 ) {
				f << "IE length cannot be zero for ie=" << HexOutput(ie) << Break << endl;
				decodeOk = false;
				continue;
			}
			f << "ie=" << HexOutput(ie) << " len=" << HexOutput(ielen) << " data=";
			int dstat = bi;
			BYTE iea[64];
			memset(iea,0,sizeof(iea));
			try {
				iea[0]=0xff;
				for (int i=0; i<ielen; i++)
				{
					int ieb = GetByte(message,dstat++);
					f << " " << HexOutput(ieb);
					iea[i+1]=ieb;
					iea[0]=i+1;
				}
			} catch (CPException se) {
				f << " **more expected**";
				decodeOk=false;
			}
			f << Break << endl;

			if ( decodeOk ) {
				elements.setBit(ie);
				f << "IE=" << IEname(MAKE_FULLIE(gvars.ActiveCodeSet,ie)) << Break << endl;
				psIEDecoderEntry p = &IEDecoders[0];
				if ( p != NULL ) {
					while (p->DecodeFunction!=NULL) {
						if ((p->CodeSet==gvars.ActiveCodeSet) && ((p->IEid&p->IEidMask)==(ie&p->IEidMask))) {
							(p->DecodeFunction)(f,INDENT_SIZE,&gvars,iea);
							break;
						}
						p++;
					}
					if ( p->DecodeFunction == NULL )
						f<<DrawIndent(INDENT_SIZE)<<"!!!NO DECODERS INSTALLED FOR codeset="<<HexOutput(gvars.ActiveCodeSet)<<" ie="<<HexOutput(ie)<<"!!!"<<Break<<endl;
				}
				else 
					f<<DrawIndent(INDENT_SIZE)<<"!!!NO DECODERS INSTALLED!!!"<<Break<<endl;
			}
			f << eFont;
			bi = dstat;
		}
		// decrement the vars->LockCount. If its zero, restore the ActiveCodeSet
		if ( gvars.LockCount > 0 ) {
			gvars.LockCount--;
			if ( gvars.LockCount == 0 )
				gvars.ActiveCodeSet = gvars.LastCodeSet;
		}
    }
/*
	if ( decodeOk ) {
		// Can add some sanity check here to ensure that all the mandatory fields were entered
		if ( Protocol == PROTOCOL_Q931) {
			switch (MessageType) {
			case MESSAGE_ALERTING:
				break;
			case MESSAGE_CALL_PROCEEDING:
				break;
			case MESSAGE_CONNECT:
				break;
			case MESSAGE_CONNECT_ACKNOWLEDGE:
				break;
			case MESSAGE_PROGRESS:
				break;
			case MESSAGE_SETUP:
				break;
			case MESSAGE_SETUP_ACKNOWLEDGE:
				break;
			case MESSAGE_RESUME:
				break;
			case MESSAGE_RESUME_ACKNOWLEDGE:
				break;
			case MESSAGE_RESUME_REJECT:
				break;
			case MESSAGE_SUSPEND:
				break;
			case MESSAGE_SUSPEND_ACKNOWLEDGE:
				break;
			case MESSAGE_SUSPEND_REJECT:
				break;
			case MESSAGE_USER_INFORMATION:
				break;
			case MESSAGE_DISCONNECT:
				break;
			case MESSAGE_RELEASE:
				break;
			case MESSAGE_RELEASE_COMPLETE:
				break;
			case MESSAGE_RESTART:
				break;
			case MESSAGE_RESTART_ACKNOWLEDGE:
				break;
			case MESSAGE_SEGMENT:
				break;
			case MESSAGE_CONGESTION_CONTROL:
				break;
			case MESSAGE_INFORMATION:
				break;
			case MESSAGE_FACILITY:
				break;
			case MESSAGE_FACILITY_REJECT:
				break;
			case MESSAGE_NOTIFY:
				break;
			case MESSAGE_STATUS:
				break;
			case MESSAGE_STATUS_ENQUIRY:
				break;
			default:
				decodeOk=false;
				break;
			}
		}
		if ( Protocol == PROTOCOL_MAINTENANCE ) {
			switch (MessageType) {
			case MESSAGE_SERVICE:
				break;
			case MESSAGE_SERVICE_ACKNOWLEDGE:
				break;
			default:
				decodeOk=false;
				break;
			}
		}
	}
*/
}
Exemple #25
0
//---------------------------------------------------------------------------
//	@function:
//		CPartConstraint::PpartcnstrDisjunction
//
//	@doc:
//		Construct a disjunction of the two part constraints. We can only
//		construct this disjunction if they differ only on the last level
//
//---------------------------------------------------------------------------
CPartConstraint *
CPartConstraint::PpartcnstrDisjunction
	(
	IMemoryPool *mp,
	CPartConstraint *ppartcnstrFst,
	CPartConstraint *ppartcnstrSnd
	)
{
	GPOS_ASSERT(NULL != ppartcnstrFst);
	GPOS_ASSERT(NULL != ppartcnstrSnd);

	if (ppartcnstrFst->IsConstraintUnbounded())
	{
		ppartcnstrFst->AddRef();
		return ppartcnstrFst;
	}
	
	if (ppartcnstrSnd->IsConstraintUnbounded())
	{
		ppartcnstrSnd->AddRef();
		return ppartcnstrSnd;
	}

	if (!FDisjunctionPossible(ppartcnstrFst, ppartcnstrSnd))
	{
		return NULL;
	}

	UlongToConstraintMap *phmulcnstr = GPOS_NEW(mp) UlongToConstraintMap(mp);
	CBitSet *pbsCombined = GPOS_NEW(mp) CBitSet(mp);

	const ULONG ulLevels = ppartcnstrFst->m_num_of_part_levels;
	for (ULONG ul = 0; ul < ulLevels-1; ul++)
	{
		CConstraint *pcnstrFst = ppartcnstrFst->Pcnstr(ul);

		pcnstrFst->AddRef();
#ifdef GPOS_DEBUG
		BOOL result =
#endif // GPOS_DEBUG
		phmulcnstr->Insert(GPOS_NEW(mp) ULONG(ul), pcnstrFst);
		GPOS_ASSERT(result);

		if (ppartcnstrFst->IsDefaultPartition(ul))
		{
			pbsCombined->ExchangeSet(ul);
		}
	}

	// create the disjunction between the constraints of the last level
	CConstraint *pcnstrFst = ppartcnstrFst->Pcnstr(ulLevels - 1);
	CConstraint *pcnstrSnd = ppartcnstrSnd->Pcnstr(ulLevels - 1);

	pcnstrFst->AddRef();
	pcnstrSnd->AddRef();
	CConstraintArray *pdrgpcnstrCombined = GPOS_NEW(mp) CConstraintArray(mp);
	
	pdrgpcnstrCombined->Append(pcnstrFst);
	pdrgpcnstrCombined->Append(pcnstrSnd);

	CConstraint *pcnstrDisj = CConstraint::PcnstrDisjunction(mp, pdrgpcnstrCombined);
	GPOS_ASSERT(NULL != pcnstrDisj);
#ifdef GPOS_DEBUG
	BOOL result =
#endif // GPOS_DEBUG
	phmulcnstr->Insert(GPOS_NEW(mp) ULONG(ulLevels - 1), pcnstrDisj);
	GPOS_ASSERT(result);

	if (ppartcnstrFst->IsDefaultPartition(ulLevels - 1) || ppartcnstrSnd->IsDefaultPartition(ulLevels - 1))
	{
		pbsCombined->ExchangeSet(ulLevels - 1);
	}

	CColRef2dArray *pdrgpdrgpcr = ppartcnstrFst->Pdrgpdrgpcr();
	pdrgpdrgpcr->AddRef();
	return GPOS_NEW(mp) CPartConstraint(mp, phmulcnstr, pbsCombined, false /*is_unbounded*/, pdrgpdrgpcr);
}
Exemple #26
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::PexprBestJoinOrderDP
//
//	@doc:
//		Find the best join order of a given set of elements using dynamic
//		programming;
//		given a set of elements (e.g., {A, B, C}), we find all possible splits
//		of the set (e.g., {A}, {B, C}) where at least one edge connects the
//		two subsets resulting from the split,
//		for each split, we find the best join orders of left and right subsets
//		recursively,
//		the function finds the split with the least cost, and stores the join
//		of its two subsets as the best join order of the given set
//
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprBestJoinOrderDP
	(
	CBitSet *pbs // set of elements to be joined
	)
{
	CDouble dMinCost(0.0);
	CExpression *pexprResult = NULL;

	CBitSetArray *pdrgpbsSubsets = PdrgpbsSubsets(m_mp, pbs);
	const ULONG ulSubsets = pdrgpbsSubsets->Size();
	for (ULONG ul = 0; ul < ulSubsets; ul++)
	{
		CBitSet *pbsCurrent = (*pdrgpbsSubsets)[ul];
		CBitSet *pbsRemaining = GPOS_NEW(m_mp) CBitSet(m_mp, *pbs);
		pbsRemaining->Difference(pbsCurrent);

		// check if subsets are connected with one or more edges
		CExpression *pexprPred = PexprPred(pbsCurrent, pbsRemaining);
		if (NULL != pexprPred)
		{
			// compute solutions of left and right subsets recursively
			CExpression *pexprLeft = PexprBestJoinOrder(pbsCurrent);
			CExpression *pexprRight = PexprBestJoinOrder(pbsRemaining);

			if (NULL != pexprLeft && NULL != pexprRight)
			{
				// we found solutions of left and right subsets, we check if
				// this gives a better solution for the input set
				CExpression *pexprJoin = PexprJoin(pbsCurrent, pbsRemaining);
				CDouble dCost = DCost(pexprJoin);

				if (NULL == pexprResult || dCost < dMinCost)
				{
					// this is the first solution, or we found a better solution
					dMinCost = dCost;
					CRefCount::SafeRelease(pexprResult);
					pexprJoin->AddRef();
					pexprResult = pexprJoin;
				}

				if (m_ulComps == pbs->Size())
				{
					AddJoinOrder(pexprJoin, dCost);
				}

				pexprJoin->Release();
			}
		}
		pbsRemaining->Release();
	}
	pdrgpbsSubsets->Release();

	// store solution in DP table
	if (NULL == pexprResult)
	{
		m_pexprDummy->AddRef();
		pexprResult = m_pexprDummy;
	}

	DeriveStats(pexprResult);
	pbs->AddRef();
#ifdef GPOS_DEBUG
	BOOL fInserted =
#endif // GPOS_DEBUG
		m_phmbsexpr->Insert(pbs, pexprResult);
	GPOS_ASSERT(fInserted);

	// add expression cost to cost map
	InsertExpressionCost(pexprResult, dMinCost, false /*fValidateInsert*/);

	return pexprResult;
}
//---------------------------------------------------------------------------
//      @function:
//		CPartitionPropagationSpec::SplitPartPredicates
//
//	@doc:
//		Split the partition elimination predicates over the various levels
//		as well as the residual predicate and add them to the appropriate
//		hashmaps. These are to be used when creating the partition selector
//
//---------------------------------------------------------------------------
void
CPartitionPropagationSpec::SplitPartPredicates
	(
	IMemoryPool *mp,
	CExpression *pexprScalar,
	CColRef2dArray *pdrgpdrgpcrKeys,
	UlongToExprMap *phmulexprEqFilter,	// output
	UlongToExprMap *phmulexprFilter,		// output
	CExpression **ppexprResidual	// output
	)
{
	GPOS_ASSERT(NULL != pexprScalar);
	GPOS_ASSERT(NULL != pdrgpdrgpcrKeys);
	GPOS_ASSERT(NULL != phmulexprEqFilter);
	GPOS_ASSERT(NULL != phmulexprFilter);
	GPOS_ASSERT(NULL != ppexprResidual);
	GPOS_ASSERT(NULL == *ppexprResidual);

	CExpressionArray *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(mp, pexprScalar);
	CBitSet *pbsUsed = GPOS_NEW(mp) CBitSet(mp);
	CColRefSet *pcrsKeys = PcrsKeys(mp, pdrgpdrgpcrKeys);

	const ULONG ulLevels = pdrgpdrgpcrKeys->Size();
	for (ULONG ul = 0; ul < ulLevels; ul++)
	{
		CColRef *colref = CUtils::PcrExtractPartKey(pdrgpdrgpcrKeys, ul);
		// find conjuncts for this key and mark their positions
		CExpressionArray *pdrgpexprKey = PdrgpexprPredicatesOnKey(mp, pdrgpexprConjuncts, colref, pcrsKeys, &pbsUsed);
		const ULONG length = pdrgpexprKey->Size();
		if (length == 0)
		{
			// no predicates on this key
			pdrgpexprKey->Release();
			continue;
		}

		if (length == 1 && CPredicateUtils::FIdentCompare((*pdrgpexprKey)[0], IMDType::EcmptEq, colref))
		{
			// EqFilters
			// one equality predicate (key = expr); take out the expression
			// and add it to the equality filters map
			CExpression *pexprPartKey = NULL;
			CExpression *pexprOther = NULL;
			IMDType::ECmpType cmp_type = IMDType::EcmptOther;

			CPredicateUtils::ExtractComponents((*pdrgpexprKey)[0], colref, &pexprPartKey, &pexprOther, &cmp_type);
			GPOS_ASSERT(NULL != pexprOther);
			pexprOther->AddRef();
#ifdef GPOS_DEBUG
			BOOL result =
#endif // GPOS_DEBUG
			phmulexprEqFilter->Insert(GPOS_NEW(mp) ULONG(ul), pexprOther);
			GPOS_ASSERT(result);
			pdrgpexprKey->Release();
		}
		else
		{
			// Filters
			// more than one predicate on this key or one non-simple-equality predicate
#ifdef GPOS_DEBUG
			BOOL result =
#endif // GPOS_DEBUG
			phmulexprFilter->Insert(GPOS_NEW(mp) ULONG(ul), CPredicateUtils::PexprConjunction(mp, pdrgpexprKey));
			GPOS_ASSERT(result);
			continue;
		}

	}

	(*ppexprResidual) = PexprResidualFilter(mp, pdrgpexprConjuncts, pbsUsed);

	pcrsKeys->Release();
	pdrgpexprConjuncts->Release();
	pbsUsed->Release();
}
Exemple #28
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::PexprBestJoinOrder
//
//	@doc:
//		find best join order for a given set of elements;
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprBestJoinOrder
	(
	CBitSet *pbs
	)
{
	GPOS_CHECK_STACK_SIZE;
	GPOS_CHECK_ABORT;

	GPOS_ASSERT(NULL != pbs);

	// start by looking-up cost in the DP map
	CExpression *pexpr = PexprLookup(pbs);

	if (pexpr == m_pexprDummy)
	{
		// no join order could be created
		return NULL;
	}

	if (NULL != pexpr)
	{
		// join order is found by looking up map
		return pexpr;
	}

	// find maximal covered subset
	CBitSet *pbsCovered = PbsCovered(pbs);
	if (0 == pbsCovered->Size())
	{
		// set is not covered, return a cross product
		pbsCovered->Release();

		return PexprCross(pbs);
	}

	if (!pbsCovered->Equals(pbs))
	{
		// create a cross product for uncovered subset
		CBitSet *pbsUncovered = GPOS_NEW(m_mp) CBitSet(m_mp, *pbs);
		pbsUncovered->Difference(pbsCovered);
		CExpression *pexprResult =
			PexprJoinCoveredSubsetWithUncoveredSubset(pbs, pbsCovered, pbsUncovered);
		pbsCovered->Release();
		pbsUncovered->Release();

		return pexprResult;
	}
	pbsCovered->Release();

	// if set has size 2, there is only one possible solution
	if (2 == pbs->Size())
	{
		return PexprJoin(pbs);
	}

	// otherwise, compute best join order using dynamic programming
	CExpression *pexprBestJoinOrder = PexprBestJoinOrderDP(pbs);
	if (pexprBestJoinOrder == m_pexprDummy)
	{
		// no join order could be created
		return NULL;
	}

	return pexprBestJoinOrder;
}