void mxExpressionTray::ShowRightClickMenu( int mx, int my ) { CExpClass *active = expressions->GetActiveClass(); if ( !active ) return; mxPopupMenu *pop = new mxPopupMenu(); Assert( pop ); CExpression *exp = NULL; if ( m_nClickedCell != -1 ) { exp = active->GetExpression( m_nClickedCell ); } pop->add( "New Expression...", IDC_CONTEXT_NEWEXP ); if ( exp ) { pop->addSeparator(); pop->add( va( "Edit '%s'...", exp->name ), IDC_CONTEXT_EDITEXP ); pop->add( va( "Save '%s'", exp->name ), IDC_CONTEXT_SAVEEXP ); if ( exp->CanUndo() || exp->CanRedo() ) { pop->add( va( "Revert '%s'", exp->name ), IDC_CONTEXT_REVERT ); } pop->addSeparator(); pop->add( va( "Delete '%s'", exp->name ), IDC_CONTEXT_DELETEXP ); pop->addSeparator(); pop->add( va( "Re-create thumbnail for '%s'", exp->name ), IDC_CONTEXT_CREATEBITMAP ); } pop->popup( this, mx, my ); }
//--------------------------------------------------------------------------- // @function: // CXformExpandNAryJoin::AddSpecifiedJoinOrder // // @doc: // Expand NAry join in the specified order of inputs // //--------------------------------------------------------------------------- void CXformExpandNAryJoin::AddSpecifiedJoinOrder ( IMemoryPool *pmp, CExpression *pexpr, CXformResult *pxfres ) { GPOS_ASSERT(COperator::EopLogicalNAryJoin == pexpr->Pop()->Eopid()); const ULONG ulArity = pexpr->UlArity(); if (4 > ulArity) { return; } // create a join order with same order of given relations (*pexpr)[0]->AddRef(); (*pexpr)[1]->AddRef(); CExpression *pexprJoin = CUtils::PexprLogicalJoin<CLogicalInnerJoin>(pmp, (*pexpr)[0], (*pexpr)[1], CPredicateUtils::PexprConjunction(pmp, NULL)); for (ULONG ul = 2; ul < ulArity - 1; ul++) { (*pexpr)[ul]->AddRef(); pexprJoin = CUtils::PexprLogicalJoin<CLogicalInnerJoin>(pmp, pexprJoin, (*pexpr)[ul], CPredicateUtils::PexprConjunction(pmp, NULL)); } CExpression *pexprScalar = (*pexpr)[ulArity - 1]; pexprScalar->AddRef(); CExpression *pexprSelect = CUtils::PexprLogicalSelect(pmp, pexprJoin, pexprScalar); CExpression *pexprNormalized = CNormalizer::PexprNormalize(pmp, pexprSelect); pexprSelect->Release(); pxfres->Add(pexprNormalized); }
//----------------------------------------------------------------------------- // Purpose: // Input : exp - //----------------------------------------------------------------------------- void mxExpressionTray::Select( int exp, bool deselect /*=true*/ ) { int oldcell = m_nCurCell; if ( deselect ) { Deselect(); } m_nPrevCell = oldcell; m_nCurCell = exp; if ( m_nCurCell >= 0 ) { CExpClass *active = expressions->GetActiveClass(); if ( active ) { CExpression *exp = active->GetExpression( m_nCurCell ); if ( exp ) { exp->SetSelected( true ); } } } redraw(); }
//--------------------------------------------------------------------------- // @function: // CStatsPredUtils::Pdrgpstatsjoin // // @doc: // Helper function to extract array of statistics join filter from // an expression //--------------------------------------------------------------------------- DrgPstatsjoin * CStatsPredUtils::Pdrgpstatsjoin ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CExpression *pexprScalarInput, DrgPcrs *pdrgpcrsOutput, // array of output columns of join's relational inputs CColRefSet *pcrsOuterRefs ) { GPOS_ASSERT(NULL != pdrgpcrsOutput); // remove implied predicates from join condition to avoid cardinality under-estimation CExpression *pexprScalar = CPredicateUtils::PexprRemoveImpliedConjuncts(pmp, pexprScalarInput, exprhdl); // extract all the conjuncts CStatsPred *pstatspredUnsupported = NULL; DrgPstatsjoin *pdrgpstatsjoin = PdrgpstatsjoinExtract ( pmp, pexprScalar, pdrgpcrsOutput, pcrsOuterRefs, &pstatspredUnsupported ); // TODO: May 15 2014, handle unsupported predicates for LASJ, LOJ and LS joins // clean up CRefCount::SafeRelease(pstatspredUnsupported); pexprScalar->Release(); return pdrgpstatsjoin; }
//--------------------------------------------------------------------------- // @function: // CConstraint::PexprScalarConjDisj // // @doc: // Construct a conjunction or disjunction scalar expression from an // array of constraints // //--------------------------------------------------------------------------- CExpression * CConstraint::PexprScalarConjDisj ( IMemoryPool *pmp, DrgPcnstr *pdrgpcnstr, BOOL fConj ) const { DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp); const ULONG ulLen = pdrgpcnstr->UlLength(); for (ULONG ul = 0; ul < ulLen; ul++) { CExpression *pexpr = (*pdrgpcnstr)[ul]->PexprScalar(pmp); pexpr->AddRef(); pdrgpexpr->Append(pexpr); } if (fConj) { return CPredicateUtils::PexprConjunction(pmp, pdrgpexpr); } return CPredicateUtils::PexprDisjunction(pmp, pdrgpexpr); }
//--------------------------------------------------------------------------- // @function: // COptimizer::PrintQuery // // @doc: // Helper function to print query expression // //--------------------------------------------------------------------------- void COptimizer::PrintQuery ( IMemoryPool *pmp, CExpression *pexprTranslated, CQueryContext *pqc ) { CAutoTrace at(pmp); at.Os() << std::endl << "Algebrized query: " << std::endl << *pexprTranslated; DrgPexpr *pdrgpexpr = COptCtxt::PoctxtFromTLS()->Pcteinfo()->PdrgPexpr(pmp); const ULONG ulCTEs = pdrgpexpr->UlLength(); if (0 < ulCTEs) { at.Os() << std::endl << "Common Table Expressions: "; for (ULONG ul = 0; ul < ulCTEs; ul++) { at.Os() << std::endl << *(*pdrgpexpr)[ul]; } } pdrgpexpr->Release(); CExpression *pexprPreprocessed = pqc->Pexpr(); (void) pexprPreprocessed->PdpDerive(); at.Os() << std::endl << "Algebrized preprocessed query: " << std::endl << *pexprPreprocessed; }
//--------------------------------------------------------------------------- // @function: // CNormalizer::SplitConjunctForSeqPrj // // @doc: // Split the given conjunct into pushable and unpushable predicates // for a sequence project expression // //--------------------------------------------------------------------------- void CNormalizer::SplitConjunctForSeqPrj ( IMemoryPool *pmp, CExpression *pexprSeqPrj, CExpression *pexprConj, DrgPexpr **ppdrgpexprPushable, DrgPexpr **ppdrgpexprUnpushable ) { GPOS_ASSERT(NULL != pexprSeqPrj); GPOS_ASSERT(NULL != pexprConj); GPOS_ASSERT(NULL != ppdrgpexprPushable); GPOS_ASSERT(NULL != ppdrgpexprUnpushable); *ppdrgpexprPushable = GPOS_NEW(pmp) DrgPexpr(pmp); *ppdrgpexprUnpushable = GPOS_NEW(pmp) DrgPexpr(pmp); DrgPexpr *pdrgpexprPreds = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprConj); const ULONG ulPreds = pdrgpexprPreds->UlLength(); for (ULONG ul = 0; ul < ulPreds; ul++) { CExpression *pexprPred = (*pdrgpexprPreds)[ul]; pexprPred->AddRef(); if (FPushableThruSeqPrjChild(pexprSeqPrj, pexprPred)) { (*ppdrgpexprPushable)->Append(pexprPred); } else { (*ppdrgpexprUnpushable)->Append(pexprPred); } } pdrgpexprPreds->Release(); }
//--------------------------------------------------------------------------- // @function: // CNormalizer::PushThruSetOp // // @doc: // Push a conjunct through set operation // //--------------------------------------------------------------------------- void CNormalizer::PushThruSetOp ( IMemoryPool *pmp, CExpression *pexprSetOp, CExpression *pexprConj, CExpression **ppexprResult ) { GPOS_ASSERT(NULL != pexprSetOp); GPOS_ASSERT(CUtils::FLogicalSetOp(pexprSetOp->Pop())); GPOS_ASSERT(NULL != pexprConj); GPOS_ASSERT(NULL != ppexprResult); CLogicalSetOp *popSetOp = CLogicalSetOp::PopConvert(pexprSetOp->Pop()); DrgPcr *pdrgpcrOutput = popSetOp->PdrgpcrOutput(); CColRefSet *pcrsOutput = GPOS_NEW(pmp) CColRefSet(pmp, pdrgpcrOutput); DrgDrgPcr *pdrgpdrgpcrInput = popSetOp->PdrgpdrgpcrInput(); DrgPexpr *pdrgpexprNewChildren = GPOS_NEW(pmp) DrgPexpr(pmp); const ULONG ulArity = pexprSetOp->UlArity(); for (ULONG ul = 0; ul < ulArity; ul++) { CExpression *pexprChild = (*pexprSetOp)[ul]; DrgPcr *pdrgpcrChild = (*pdrgpdrgpcrInput)[ul]; CColRefSet *pcrsChild = GPOS_NEW(pmp) CColRefSet(pmp, pdrgpcrChild); pexprConj->AddRef(); CExpression *pexprRemappedConj = pexprConj; if (!pcrsChild->FEqual(pcrsOutput)) { // child columns are different from SetOp output columns, // we need to fix conjunct by mapping output columns to child columns, // columns that are not in the output of SetOp child need also to be re-mapped // to new columns, // // for example, if the conjunct looks like 'x > (select max(y) from T)' // and the SetOp child produces only column x, we need to create a new // conjunct that looks like 'x1 > (select max(y1) from T)' // where x1 is a copy of x, and y1 is a copy of y // // this is achieved by passing (fMustExist = True) flag below, which enforces // creating column copies for columns not already in the given map HMUlCr *phmulcr = CUtils::PhmulcrMapping(pmp, pdrgpcrOutput, pdrgpcrChild); pexprRemappedConj->Release(); pexprRemappedConj = pexprConj->PexprCopyWithRemappedColumns(pmp, phmulcr, true /*fMustExist*/); phmulcr->Release(); } CExpression *pexprNewChild = NULL; PushThru(pmp, pexprChild, pexprRemappedConj, &pexprNewChild); pdrgpexprNewChildren->Append(pexprNewChild); pexprRemappedConj->Release(); pcrsChild->Release(); } pcrsOutput->Release(); popSetOp->AddRef(); *ppexprResult = GPOS_NEW(pmp) CExpression(pmp, popSetOp, pdrgpexprNewChildren); }
//--------------------------------------------------------------------------- // @function: // CNormalizer::SplitConjunct // // @doc: // Split the given conjunct into pushable and unpushable predicates // // //--------------------------------------------------------------------------- void CNormalizer::SplitConjunct ( IMemoryPool *pmp, CExpression *pexpr, CExpression *pexprConj, DrgPexpr **ppdrgpexprPushable, DrgPexpr **ppdrgpexprUnpushable ) { GPOS_ASSERT(pexpr->Pop()->FLogical()); GPOS_ASSERT(pexprConj->Pop()->FScalar()); GPOS_ASSERT(NULL != ppdrgpexprPushable); GPOS_ASSERT(NULL != ppdrgpexprUnpushable); // collect pushable predicates from given conjunct *ppdrgpexprPushable = GPOS_NEW(pmp) DrgPexpr(pmp); *ppdrgpexprUnpushable = GPOS_NEW(pmp) DrgPexpr(pmp); DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprConj); const ULONG ulSize = pdrgpexprConjuncts->UlLength(); for (ULONG ul = 0; ul < ulSize; ul++) { CExpression *pexprScalar = (*pdrgpexprConjuncts)[ul]; pexprScalar->AddRef(); if (FPushable(pexpr, pexprScalar)) { (*ppdrgpexprPushable)->Append(pexprScalar); } else { (*ppdrgpexprUnpushable)->Append(pexprScalar); } } pdrgpexprConjuncts->Release(); }
//--------------------------------------------------------------------------- // @function: // CNormalizer::PushThruUnaryWithScalarChild // // @doc: // Push a conjunct through a unary operator with scalar child // //--------------------------------------------------------------------------- void CNormalizer::PushThruUnaryWithScalarChild ( IMemoryPool *pmp, CExpression *pexprLogical, CExpression *pexprConj, CExpression **ppexprResult ) { GPOS_ASSERT(NULL != pexprLogical); GPOS_ASSERT(2 == pexprLogical->UlArity()); GPOS_ASSERT(NULL != pexprConj); GPOS_ASSERT(NULL != ppexprResult); // get logical and scalar children CExpression *pexprLogicalChild = (*pexprLogical)[0]; CExpression *pexprScalarChild = (*pexprLogical)[1]; // push conjuncts through the logical child CExpression *pexprNewLogicalChild = NULL; DrgPexpr *pdrgpexprUnpushable = NULL; // break scalar expression to conjuncts DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprConj); PushThru(pmp, pexprLogicalChild, pdrgpexprConjuncts, &pexprNewLogicalChild, &pdrgpexprUnpushable); pdrgpexprConjuncts->Release(); // create a new logical expression based on recursion results COperator *pop = pexprLogical->Pop(); pop->AddRef(); pexprScalarChild->AddRef(); CExpression *pexprNewLogical = GPOS_NEW(pmp) CExpression(pmp, pop, pexprNewLogicalChild, pexprScalarChild); *ppexprResult = PexprSelect(pmp, pexprNewLogical, pdrgpexprUnpushable); }
//--------------------------------------------------------------------------- // @function: // CNormalizer::PexprPullUpProjections // // @doc: // Pulls up logical projects as far as possible, and combines consecutive // projects if possible // //--------------------------------------------------------------------------- CExpression * CNormalizer::PexprPullUpProjections ( IMemoryPool *pmp, CExpression *pexpr ) { GPOS_ASSERT(NULL != pexpr); BOOL fPullUp = true; pexpr->AddRef(); CExpression *pexprOutput = pexpr; while (fPullUp) { fPullUp = false; CExpression *pexprOutputNew = PexprPullUpAndCombineProjects(pmp, pexprOutput, &fPullUp); pexprOutput->Release(); pexprOutput = pexprOutputNew; } GPOS_ASSERT(FLocalColsSubsetOfInputCols(pmp, pexprOutput)); return pexprOutput; }
//--------------------------------------------------------------------------- // @function: // CXformInnerJoin2DynamicBitmapIndexGetApply::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformInnerJoin2DynamicBitmapIndexGetApply::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(); // extract components CExpression *pexprOuter = (*pexpr)[0]; CExpression *pexprInner = (*pexpr)[1]; CExpression *pexprScalar = (*pexpr)[2]; GPOS_ASSERT(COperator::EopLogicalDynamicGet == pexprInner->Pop()->Eopid()); CLogicalDynamicGet *popDynamicGet = CLogicalDynamicGet::PopConvert(pexprInner->Pop()); CreateHomogeneousIndexApplyAlternatives ( pmp, pexpr->Pop()->UlOpId(), pexprOuter, pexprInner, pexprScalar, popDynamicGet->Ptabdesc(), popDynamicGet, pxfres, IMDIndex::EmdindBitmap ); }
//--------------------------------------------------------------------------- // @function: // CXformTest::PexprStarJoinTree // // @doc: // Generate a randomized star join tree // //--------------------------------------------------------------------------- CExpression * CXformTest::PexprStarJoinTree ( IMemoryPool *pmp, ULONG ulTabs ) { CExpression *pexprLeft = CTestUtils::PexprLogicalGet(pmp); for (ULONG ul = 1; ul < ulTabs; ul++) { CDrvdPropRelational *pdprelLeft = CDrvdPropRelational::Pdprel(pexprLeft->PdpDerive()); CColRef *pcrLeft = pdprelLeft->PcrsOutput()->PcrAny(); CExpression *pexprRight = CTestUtils::PexprLogicalGet(pmp); CDrvdPropRelational *pdprelRight = CDrvdPropRelational::Pdprel(pexprRight->PdpDerive()); CColRef *pcrRight = pdprelRight->PcrsOutput()->PcrAny(); CExpression *pexprPred = CUtils::PexprScalarEqCmp(pmp, pcrLeft, pcrRight); pexprLeft = CUtils::PexprLogicalJoin<CLogicalInnerJoin>(pmp, pexprLeft, pexprRight, pexprPred); } return pexprLeft; }
//--------------------------------------------------------------------------- // @function: // CQueryContext::MapComputedToUsedCols // // @doc: // Walk the expression and add the mapping between computed column // and its used columns // //--------------------------------------------------------------------------- void CQueryContext::MapComputedToUsedCols ( CColumnFactory *pcf, CExpression *pexpr ) { GPOS_ASSERT(NULL != pexpr); if (COperator::EopLogicalProject == pexpr->Pop()->Eopid()) { CExpression *pexprPrL = (*pexpr)[1]; const ULONG ulArity = pexprPrL->UlArity(); for (ULONG ul = 0; ul < ulArity; ul++) { CExpression *pexprPrEl = (*pexprPrL)[ul]; pcf->AddComputedToUsedColsMap(pexprPrEl); } } // process children const ULONG ulChildren = pexpr->UlArity(); for (ULONG ul = 0; ul < ulChildren; ul++) { MapComputedToUsedCols(pcf, (*pexpr)[ul]); } }
//--------------------------------------------------------------------------- // @function: // CDistributionSpecHashed::PdsCopyWithRemappedColumns // // @doc: // Return a copy of the distribution spec with remapped columns // //--------------------------------------------------------------------------- CDistributionSpec * CDistributionSpecHashed::PdsCopyWithRemappedColumns ( IMemoryPool *pmp, HMUlCr *phmulcr, BOOL fMustExist ) { DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp); const ULONG ulLen = m_pdrgpexpr->UlLength(); for (ULONG ul = 0; ul < ulLen; ul++) { CExpression *pexpr = (*m_pdrgpexpr)[ul]; pdrgpexpr->Append(pexpr->PexprCopyWithRemappedColumns(pmp, phmulcr, fMustExist)); } if (NULL == m_pdshashedEquiv) { return GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, m_fNullsColocated); } // copy equivalent distribution CDistributionSpec *pds = m_pdshashedEquiv->PdsCopyWithRemappedColumns(pmp, phmulcr, fMustExist); CDistributionSpecHashed *pdshashed = CDistributionSpecHashed::PdsConvert(pds); return GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, m_fNullsColocated, pdshashed); }
CExpression* COperator1Expr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) { CExpression* newlhs = m_lhs->CheckLink(brokenlinks); if (newlhs) { if (newlhs==m_lhs) { // not changed } else { // changed //numchanges++; newlhs->AddRef(); //m_lhs->Release(); brokenlinks.push_back(new CBrokenLinkInfo(&m_lhs,m_lhs)); m_lhs = newlhs; } return this; } else { //numchanges++; AddRef(); return Release(); } }
//--------------------------------------------------------------------------- // @function: // CPhysical::GetSkew // // @doc: // Helper to compute skew estimate based on given stats and // distribution spec // //--------------------------------------------------------------------------- CDouble CPhysical::GetSkew ( IStatistics *stats, CDistributionSpec *pds ) { CDouble dSkew = 1.0; if (CDistributionSpec::EdtHashed == pds->Edt()) { CDistributionSpecHashed *pdshashed = CDistributionSpecHashed::PdsConvert(pds); const CExpressionArray *pdrgpexpr = pdshashed->Pdrgpexpr(); const ULONG size = pdrgpexpr->Size(); for (ULONG ul = 0; ul < size; ul++) { CExpression *pexpr = (*pdrgpexpr)[ul]; if (COperator::EopScalarIdent == pexpr->Pop()->Eopid()) { // consider only hashed distribution direct columns for now CScalarIdent *popScId = CScalarIdent::PopConvert(pexpr->Pop()); ULONG colid = popScId->Pcr()->Id(); CDouble dSkewCol = stats->GetSkew(colid); if (dSkewCol > dSkew) { dSkew = dSkewCol; } } } } return CDouble(dSkew); }
//--------------------------------------------------------------------------- // @function: // CXformPushGbWithHavingBelowJoin::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformPushGbWithHavingBelowJoin::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); IMemoryPool *mp = pxfctxt->Pmp(); CExpression *pexprGb = (*pexpr)[0]; CLogicalGbAgg *popGbAgg = CLogicalGbAgg::PopConvert(pexprGb->Pop()); if (!popGbAgg->FGlobal()) { // xform only applies to global aggs return; } CExpression *pexprResult = CXformUtils::PexprPushGbBelowJoin(mp, pexpr); if (NULL != pexprResult) { // add alternative to results pxfres->Add(pexprResult); } }
//--------------------------------------------------------------------------- // @function: // CXformGbAggWithMDQA2Join::PexprExpandMDQAs // // @doc: // Expand GbAgg with multiple distinct aggregates into a join of single // distinct aggregates, // return NULL if expansion is not done // //--------------------------------------------------------------------------- CExpression * CXformGbAggWithMDQA2Join::PexprExpandMDQAs ( IMemoryPool *pmp, CExpression *pexpr ) { GPOS_ASSERT(NULL != pexpr); GPOS_ASSERT(COperator::EopLogicalGbAgg == pexpr->Pop()->Eopid()); COperator *pop = pexpr->Pop(); if (CLogicalGbAgg::PopConvert(pop)->FGlobal()) { BOOL fHasMultipleDistinctAggs = CDrvdPropScalar::Pdpscalar((*pexpr)[1]->PdpDerive())->FHasMultipleDistinctAggs(); if (fHasMultipleDistinctAggs) { CExpression *pexprExpanded = PexprMDQAs2Join(pmp, pexpr); // recursively process the resulting expression CExpression *pexprResult = PexprTransform(pmp, pexprExpanded); pexprExpanded->Release(); return pexprResult; } } return NULL; }
//--------------------------------------------------------------------------- // @function: // CCNFConverter::Pdrgpdrgpexpr // // @doc: // Create an array of arrays each holding the children of an expression // from the given array // // //--------------------------------------------------------------------------- DrgPdrgPexpr * CCNFConverter::Pdrgpdrgpexpr ( IMemoryPool *pmp, DrgPexpr *pdrgpexpr ) { GPOS_ASSERT(NULL != pmp); GPOS_ASSERT(NULL != pdrgpexpr); DrgPdrgPexpr *pdrgpdrgpexpr = GPOS_NEW(pmp) DrgPdrgPexpr(pmp); const ULONG ulArity = pdrgpexpr->UlLength(); for (ULONG ul = 0; ul < ulArity; ul++) { CExpression *pexpr = (*pdrgpexpr)[ul]; DrgPexpr *pdrgpexprChild = NULL; if (CPredicateUtils::FAnd(pexpr)) { pdrgpexprChild = pexpr->PdrgPexpr(); pdrgpexprChild->AddRef(); } else { pdrgpexprChild = GPOS_NEW(pmp) DrgPexpr(pmp); pexpr->AddRef(); pdrgpexprChild->Append(pexpr); } pdrgpdrgpexpr->Append(pdrgpexprChild); } return pdrgpdrgpexpr; }
CValue* CParser::GetValue(STR_String& txt, bool bFallbackToText) { // returns parsed text into a value, // empty string returns NULL value ! // if bFallbackToText then unparsed stuff is put into text CValue* result=NULL; CExpression* expr = ProcessText(txt); if (expr) { result = expr->Calculate(); expr->Release(); } if (result) { // if the parsed stuff lead to an errorvalue, don't return errors, just NULL if (result->IsError()) { result->Release(); result=NULL; if (bFallbackToText) { if (txt.Length()>0) { result = new CStringValue(txt,""); } } } } return result; }
//--------------------------------------------------------------------------- // @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: // CPartitionPropagationSpec::PexprFilter // // @doc: // Return the filter expression for the given Scan Id // //--------------------------------------------------------------------------- CExpression * CPartitionPropagationSpec::PexprFilter ( IMemoryPool *mp, ULONG scan_id ) { CExpression *pexprScalar = m_ppfm->Pexpr(scan_id); GPOS_ASSERT(NULL != pexprScalar); if (CUtils::FScalarIdent(pexprScalar)) { // condition of the form "pkey": translate into pkey = true pexprScalar->AddRef(); pexprScalar = CUtils::PexprScalarEqCmp(mp, pexprScalar, CUtils::PexprScalarConstBool(mp, true /*value*/, false /*is_null*/)); } else if (CPredicateUtils::FNot(pexprScalar) && CUtils::FScalarIdent((*pexprScalar)[0])) { // condition of the form "!pkey": translate into pkey = false CExpression *pexprId = (*pexprScalar)[0]; pexprId->AddRef(); pexprScalar = CUtils::PexprScalarEqCmp(mp, pexprId, CUtils::PexprScalarConstBool(mp, false /*value*/, false /*is_null*/)); } else { pexprScalar->AddRef(); } return pexprScalar; }
//--------------------------------------------------------------------------- // @function: // CXformImplementDynamicBitmapTableGet::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformImplementDynamicBitmapTableGet::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(); CLogicalDynamicBitmapTableGet *popLogical = CLogicalDynamicBitmapTableGet::PopConvert(pexpr->Pop()); CTableDescriptor *ptabdesc = popLogical->Ptabdesc(); ptabdesc->AddRef(); CName *pname = GPOS_NEW(pmp) CName(pmp, popLogical->Name()); DrgPcr *pdrgpcrOutput = popLogical->PdrgpcrOutput(); GPOS_ASSERT(NULL != pdrgpcrOutput); pdrgpcrOutput->AddRef(); DrgDrgPcr *pdrgpdrgpcrPart = popLogical->PdrgpdrgpcrPart(); pdrgpdrgpcrPart->AddRef(); CPartConstraint *ppartcnstr = popLogical->Ppartcnstr(); ppartcnstr->AddRef(); CPartConstraint *ppartcnstrRel = popLogical->PpartcnstrRel(); ppartcnstrRel->AddRef(); CPhysicalDynamicBitmapTableScan *popPhysical = GPOS_NEW(pmp) CPhysicalDynamicBitmapTableScan ( pmp, popLogical->FPartial(), ptabdesc, pexpr->Pop()->UlOpId(), pname, popLogical->UlScanId(), pdrgpcrOutput, pdrgpdrgpcrPart, popLogical->UlSecondaryScanId(), ppartcnstr, ppartcnstrRel ); CExpression *pexprCondition = (*pexpr)[0]; CExpression *pexprIndexPath = (*pexpr)[1]; pexprCondition->AddRef(); pexprIndexPath->AddRef(); CExpression *pexprPhysical = GPOS_NEW(pmp) CExpression(pmp, popPhysical, pexprCondition, pexprIndexPath); pxfres->Add(pexprPhysical); }
//--------------------------------------------------------------------------- // @function: // CPhysicalUnionAll::PdshashedPassThru // // @doc: // Compute required hashed distribution of the n-th child // //--------------------------------------------------------------------------- CDistributionSpecHashed * CPhysicalUnionAll::PdshashedPassThru ( IMemoryPool *pmp, CDistributionSpecHashed *pdshashedRequired, ULONG ulChildIndex ) const { DrgPexpr *pdrgpexprRequired = pdshashedRequired->Pdrgpexpr(); DrgPcr *pdrgpcrChild = (*m_pdrgpdrgpcrInput)[ulChildIndex]; const ULONG ulExprs = pdrgpexprRequired->UlLength(); const ULONG ulOutputCols = m_pdrgpcrOutput->UlLength(); DrgPexpr *pdrgpexprChildRequired = GPOS_NEW(pmp) DrgPexpr(pmp); for (ULONG ulExpr = 0; ulExpr < ulExprs; ulExpr++) { CExpression *pexpr = (*pdrgpexprRequired)[ulExpr]; if (COperator::EopScalarIdent != pexpr->Pop()->Eopid()) { // skip expressions that are not in form of scalar identifiers continue; } const CColRef *pcrHashed = CScalarIdent::PopConvert(pexpr->Pop())->Pcr(); const IMDType *pmdtype = pcrHashed->Pmdtype(); if (!pmdtype->FHashable()) { // skip non-hashable columns continue; } for (ULONG ulCol = 0; ulCol < ulOutputCols; ulCol++) { const CColRef *pcrOutput = (*m_pdrgpcrOutput)[ulCol]; if (pcrOutput == pcrHashed) { const CColRef *pcrInput = (*pdrgpcrChild)[ulCol]; pdrgpexprChildRequired->Append(CUtils::PexprScalarIdent(pmp, pcrInput)); } } } if (0 < pdrgpexprChildRequired->UlLength()) { return GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexprChildRequired, true /* fNullsCollocated */); } // failed to create a matching hashed distribution pdrgpexprChildRequired->Release(); if (NULL != pdshashedRequired->PdshashedEquiv()) { // try again with equivalent distribution return PdshashedPassThru(pmp, pdshashedRequired->PdshashedEquiv(), ulChildIndex); } // failed to create hashed distribution return NULL; }
long CCompileEditView::DeleteCurExp(WPARAM wParam /*= 0*/, LPARAM lParam /*= 0*/) { HSTreeToCompileEdit* pppData = (HSTreeToCompileEdit*)lParam; if(pppData == NULL) return 0; CTreeGroup* pTreeGroup = (CTreeGroup*)pppData->m_pName; if(pTreeGroup != NULL) { CExpression* pExpress = pTreeGroup->GetData(); if(pExpress != NULL) { CString strName; strName.Format("%s",pExpress->GetName()); CValue* pValoare; if ( m_pExternExpression->Lookup(strName,pExpress->GetExpressType(),pValoare) ) { if( !pExpress->GetPWD().IsEmpty() ) // 有密码 { CInputPassPwD dlg(this,_T("请输入公式密码"),strName); dlg.m_pExp = pExpress; if( dlg.DoModal() == IDCANCEL ) { return 2; } } if( wParam ) { m_pExternExpression->RemoveKey(strName,pExpress->GetExpressType()); delete pValoare; } } if(m_pwndDlgMainBar != NULL) { CComboBox* pCombox = (CComboBox*)m_pwndDlgMainBar->GetDlgItem(IDC_NAMECOMBO); if(pCombox != NULL) { int nIndex = pCombox->FindString( 0, strName ); if(nIndex != -1) { pCombox->DeleteString( nIndex ); } } } } } else { } if(m_hExpressInTreePos == (HTREEITEM)pppData->m_pData) { OnNewExpress(); } return 0; }
// test cardinality for predicates of the form: a + c = b // for such predicates, NDV based cardinality estimation is not applicable GPOS_RESULT CJoinCardinalityNDVBasedEqPredTest::EresUnittest_NDVCardEstimationNotApplicableMultipleIdents() { // cartesian product / 2.5 // 2.5 = 1/.4 -- where .4 is default selectivity CDouble dRowsExpected(76004000); Fixture f(file_name); IMemoryPool *mp = f.Pmp(); IStatisticsArray *statistics_array = f.PdrgPstat(); CExpression *pexprLgGet = CTestUtils::PexprLogicalGet(mp); CLogicalGet *popGet = CLogicalGet::PopConvert(pexprLgGet->Pop()); CColRefArray *colref_array = popGet->PdrgpcrOutput(); // use the colid available in the input xml file CColRef *pcrLeft1 = (*colref_array)[2]; CColRef *pcrLeft2 = (*colref_array)[1]; CColRef *pcrRight = (*colref_array)[0]; // create a scalar ident // CScalarIdent "column_0000" (0) CExpression *pexprScalarIdentRight = CUtils::PexprScalarIdent(mp, pcrRight); CExpression *pexprScalarIdentLeft2 = CUtils::PexprScalarIdent(mp, pcrLeft2); // create a scalar op expression column_0002 + column_0001 // CScalarOp (+) // |--CScalarIdent "column_0002" (2) // +--CScalarIdent "column_0001" (1) CExpression *pexprScOp = CUtils::PexprScalarOp(mp, pcrLeft1, pexprScalarIdentLeft2, CWStringConst(GPOS_WSZ_LIT("+")), GPOS_NEW(mp) CMDIdGPDB(GPDB_INT4_ADD_OP)); // create a scalar comparision operator // +--CScalarCmp (=) // |--CScalarOp (+) // | |--CScalarIdent "column_0002" (2) // | +--CScalarIdent "column_0001" (1) // +--CScalarIdent "column_0000" (0) CExpression *pScalarCmp = CUtils::PexprScalarEqCmp(mp, pexprScOp, pexprScalarIdentRight); IStatistics *join_stats = CJoinStatsProcessor::CalcAllJoinStats(mp, statistics_array, pScalarCmp, IStatistics::EsjtInnerJoin); GPOS_ASSERT(NULL != join_stats); CDouble dRowsActual(join_stats->Rows()); GPOS_RESULT eres = GPOS_OK; if (floor(dRowsActual.Get()) != dRowsExpected) { eres = GPOS_FAILED; } join_stats->Release(); pexprLgGet->Release(); pScalarCmp->Release(); return eres; }
//--------------------------------------------------------------------------- // @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: // CStatsPredUtils::PdrgpstatsjoinExtract // // @doc: // Helper function to extract array of statistics join filter // from an array of join predicates // //--------------------------------------------------------------------------- DrgPstatsjoin * CStatsPredUtils::PdrgpstatsjoinExtract ( IMemoryPool *pmp, CExpression *pexprScalar, DrgPcrs *pdrgpcrsOutput, // array of output columns of join's relational inputs CColRefSet *pcrsOuterRefs, CStatsPred **ppstatspredUnsupported ) { GPOS_ASSERT(NULL != pexprScalar); GPOS_ASSERT(NULL != pdrgpcrsOutput); DrgPstatsjoin *pdrgpstatsjoin = GPOS_NEW(pmp) DrgPstatsjoin(pmp); DrgPexpr *pdrgpexprUnsupported = GPOS_NEW(pmp) DrgPexpr(pmp); // extract all the conjuncts DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprScalar); const ULONG ulSize = pdrgpexprConjuncts->UlLength(); for (ULONG ul = 0; ul < ulSize; ul++) { CExpression *pexprPred = (*pdrgpexprConjuncts) [ul]; CStatisticsJoin *pstatsjoin = PstatsjoinExtract ( pmp, pexprPred, pdrgpcrsOutput, pcrsOuterRefs, pdrgpexprUnsupported ); if (NULL != pstatsjoin) { pdrgpstatsjoin->Append(pstatsjoin); } } const ULONG ulUnsupported = pdrgpexprUnsupported->UlLength(); if (1 == ulUnsupported) { *ppstatspredUnsupported = CStatsPredUtils::PstatspredExtract(pmp, (*pdrgpexprUnsupported)[0], pcrsOuterRefs); } else if (1 < ulUnsupported) { pdrgpexprUnsupported->AddRef(); CExpression *pexprConj = CPredicateUtils::PexprConjDisj(pmp, pdrgpexprUnsupported, true /* fConjunction */); *ppstatspredUnsupported = CStatsPredUtils::PstatspredExtract(pmp, pexprConj, pcrsOuterRefs); pexprConj->Release(); } // clean up pdrgpexprUnsupported->Release(); pdrgpexprConjuncts->Release(); return pdrgpstatsjoin; }
//--------------------------------------------------------------------------- // @function: // CXformCollapseGbAgg::Transform // // @doc: // Actual transformation to collapse two cascaded group by operators; // if the top Gb grouping columns are subset of bottom Gb grouping // columns AND both Gb operators do not define agg functions, we can // remove the bottom group by operator // // //--------------------------------------------------------------------------- void CXformCollapseGbAgg::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(NULL != pxfres); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); IMemoryPool *pmp = pxfctxt->Pmp(); // extract components CLogicalGbAgg *popTopGbAgg = CLogicalGbAgg::PopConvert(pexpr->Pop()); GPOS_ASSERT(0 < popTopGbAgg->Pdrgpcr()->UlLength()); GPOS_ASSERT(popTopGbAgg->FGlobal()); CExpression *pexprRelational = (*pexpr)[0]; CExpression *pexprTopProjectList = (*pexpr)[1]; CLogicalGbAgg *popBottomGbAgg = CLogicalGbAgg::PopConvert(pexprRelational->Pop()); CExpression *pexprChild = (*pexprRelational)[0]; CExpression *pexprBottomProjectList = (*pexprRelational)[1]; if (!popBottomGbAgg->FGlobal()) { // bottom GbAgg must be global to prevent xform from getting applied to splitted GbAggs return; } if (0 < pexprTopProjectList->UlArity() || 0 < pexprBottomProjectList->UlArity()) { // exit if any of the Gb operators has an aggregate function return; } #ifdef GPOS_DEBUG // for two cascaded GbAgg ops with no agg functions, top grouping // columns must be a subset of bottom grouping columns CColRefSet *pcrsTopGrpCols = GPOS_NEW(pmp) CColRefSet(pmp, popTopGbAgg->Pdrgpcr()); CColRefSet *pcrsBottomGrpCols = GPOS_NEW(pmp) CColRefSet(pmp, popBottomGbAgg->Pdrgpcr()); GPOS_ASSERT(pcrsBottomGrpCols->FSubset(pcrsTopGrpCols)); pcrsTopGrpCols->Release(); pcrsBottomGrpCols->Release(); #endif // GPOS_DEBUG pexprChild->AddRef(); CExpression *pexprSelect = CUtils::PexprLogicalSelect(pmp, pexprChild, CPredicateUtils::PexprConjunction(pmp, NULL /*pdrgpexpr*/)); popTopGbAgg->AddRef(); pexprTopProjectList->AddRef(); CExpression *pexprGbAggNew = GPOS_NEW(pmp) CExpression(pmp, popTopGbAgg, pexprSelect, pexprTopProjectList); pxfres->Add(pexprGbAggNew); }