本文整理汇总了C++中CBitSet类的典型用法代码示例。如果您正苦于以下问题:C++ CBitSet类的具体用法?C++ CBitSet怎么用?C++ CBitSet使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了CBitSet类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: GPOS_NEW
//---------------------------------------------------------------------------
// @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;
}
示例2: GPOS_ASSERT
//---------------------------------------------------------------------------
// @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;
}
示例3: GPOS_ASSERT
//---------------------------------------------------------------------------
// @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();
}
}
}
示例4: GPOS_ASSERT
//---------------------------------------------------------------------------
// @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);
}
示例5:
// ***************************************************************************
CBitSet CBitSet::operator~() const
{
CBitSet ret;
ret= *this;
ret.flip();
return ret;
}
示例6: GPOS_ASSERT
//---------------------------------------------------------------------------
// @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);
}
示例7: SzId
//---------------------------------------------------------------------------
// @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;
}
示例8: GPOS_NEW
//---------------------------------------------------------------------------
// @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;
}
示例9: xml_serializer
//---------------------------------------------------------------------------
// @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();
}
示例10: GPOS_ASSERT
//---------------------------------------------------------------------------
// @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);
}
示例11: GPOS_NEW
//---------------------------------------------------------------------------
// @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;
}
示例12: GPOS_ASSERT
//---------------------------------------------------------------------------
// @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();
}
示例13: GPOS_NEW
//---------------------------------------------------------------------------
// @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;
}
示例14: GPOS_ASSERT
//---------------------------------------------------------------------------
// @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);
}
示例15: GPOS_ASSERT
//---------------------------------------------------------------------------
// @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();
}