//--------------------------------------------------------------------------- // @function: // CScalarArrayCmp::PexprExpand // // @doc: // Expand array comparison expression into a conjunctive/disjunctive // expression // //--------------------------------------------------------------------------- CExpression * CScalarArrayCmp::PexprExpand ( IMemoryPool *mp, CExpression *pexprArrayCmp ) { GPOS_ASSERT(NULL != pexprArrayCmp); GPOS_ASSERT(EopScalarArrayCmp == pexprArrayCmp->Pop()->Eopid()); CExpression *pexprIdent = (*pexprArrayCmp)[0]; CExpression *pexprArray = CUtils::PexprScalarArrayChild(pexprArrayCmp); CScalarArrayCmp *popArrayCmp = CScalarArrayCmp::PopConvert(pexprArrayCmp->Pop()); ULONG ulArrayElems = 0; if (CUtils::FScalarArray(pexprArray)) { ulArrayElems = CUtils::UlScalarArrayArity(pexprArray); } // if this condition is true, we know the right child of ArrayCmp is a constant. if (0 == ulArrayElems) { // if right child is not an actual array (e.g., Const of type array), return input // expression without expansion pexprArrayCmp->AddRef(); return pexprArrayCmp; } CExpressionArray *pdrgpexpr = GPOS_NEW(mp) CExpressionArray(mp); for (ULONG ul = 0; ul < ulArrayElems; ul++) { CExpression *pexprArrayElem = CUtils::PScalarArrayExprChildAt(mp, pexprArray, ul); pexprIdent->AddRef(); const CWStringConst *str_opname = popArrayCmp->Pstr(); IMDId *mdid_op = popArrayCmp->MdIdOp(); GPOS_ASSERT(IMDId::IsValid(mdid_op)); mdid_op->AddRef(); CExpression *pexprCmp = CUtils::PexprScalarCmp(mp, pexprIdent, pexprArrayElem, *str_opname, mdid_op); pdrgpexpr->Append(pexprCmp); } GPOS_ASSERT(0 < pdrgpexpr->Size()); // deduplicate resulting array CExpressionArray *pdrgpexprDeduped = CUtils::PdrgpexprDedup(mp, pdrgpexpr); pdrgpexpr->Release(); EArrCmpType earrcmpt = popArrayCmp->Earrcmpt(); if (EarrcmpAny == earrcmpt) { return CPredicateUtils::PexprDisjunction(mp, pdrgpexprDeduped); } GPOS_ASSERT(EarrcmpAll == earrcmpt); return CPredicateUtils::PexprConjunction(mp, pdrgpexprDeduped); }
//--------------------------------------------------------------------------- // @function: // CScalarArrayCmp::Matches // // @doc: // Match function on operator level // //--------------------------------------------------------------------------- BOOL CScalarArrayCmp::Matches ( COperator *pop ) const { if (pop->Eopid() == Eopid()) { CScalarArrayCmp *popCmp = CScalarArrayCmp::PopConvert(pop); // match if operator oid are identical return m_earrccmpt == popCmp->Earrcmpt() && m_mdid_op->Equals(popCmp->MdIdOp()); } return false; }