//--------------------------------------------------------------------------- // @function: // CLogical::PcrsDeriveOuterIndexGet // // @doc: // Derive outer references for index get and dynamic index get operators // //--------------------------------------------------------------------------- CColRefSet * CLogical::PcrsDeriveOuterIndexGet ( IMemoryPool *pmp, CExpressionHandle &exprhdl ) { ULONG ulArity = exprhdl.UlArity(); CColRefSet *pcrsOuter = GPOS_NEW(pmp) CColRefSet(pmp); CColRefSet *pcrsOutput = PcrsDeriveOutput(pmp, exprhdl); CColRefSet *pcrsUsed = GPOS_NEW(pmp) CColRefSet(pmp); for (ULONG i = 0; i < ulArity; i++) { GPOS_ASSERT(exprhdl.FScalarChild(i)); CDrvdPropScalar *pdpscalar = exprhdl.Pdpscalar(i); pcrsUsed->Union(pdpscalar->PcrsUsed()); } // outer references are columns used by scalar children // but are not included in the output columns of relational children pcrsOuter->Union(pcrsUsed); pcrsOuter->Exclude(pcrsOutput); pcrsOutput->Release(); pcrsUsed->Release(); return pcrsOuter; }
//--------------------------------------------------------------------------- // @function: // CLogicalGet::PcrsDeriveNotNull // // @doc: // Derive not null output columns // //--------------------------------------------------------------------------- CColRefSet * CLogicalGet::PcrsDeriveNotNull ( IMemoryPool *mp, CExpressionHandle &exprhdl ) const { // get all output columns CColRefSet *pcrs = GPOS_NEW(mp) CColRefSet(mp); pcrs->Include(CDrvdPropRelational::GetRelationalProperties(exprhdl.Pdp())->PcrsOutput()); // filters out nullable columns CColRefSetIter crsi(*CDrvdPropRelational::GetRelationalProperties(exprhdl.Pdp())->PcrsOutput()); while (crsi.Advance()) { CColRefTable *pcrtable = CColRefTable::PcrConvert(const_cast<CColRef*>(crsi.Pcr())); if (pcrtable->IsNullable()) { pcrs->Exclude(pcrtable); } } return pcrs; }
//--------------------------------------------------------------------------- // @function: // CLogical::PcrsDeriveOuter // // @doc: // Derive outer references // //--------------------------------------------------------------------------- CColRefSet * CLogical::PcrsDeriveOuter ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CColRefSet *pcrsUsedAdditional ) { ULONG ulArity = exprhdl.UlArity(); CColRefSet *pcrsOuter = GPOS_NEW(pmp) CColRefSet(pmp); // collect output columns from relational children // and used columns from scalar children CColRefSet *pcrsOutput = GPOS_NEW(pmp) CColRefSet(pmp); CColRefSet *pcrsUsed = GPOS_NEW(pmp) CColRefSet(pmp); for (ULONG i = 0; i < ulArity; i++) { if (exprhdl.FScalarChild(i)) { CDrvdPropScalar *pdpscalar = exprhdl.Pdpscalar(i); pcrsUsed->Union(pdpscalar->PcrsUsed()); } else { CDrvdPropRelational *pdprel = exprhdl.Pdprel(i); pcrsOutput->Union(pdprel->PcrsOutput()); // add outer references from relational children pcrsOuter->Union(pdprel->PcrsOuter()); } } if (NULL != pcrsUsedAdditional) { pcrsUsed->Include(pcrsUsedAdditional); } // outer references are columns used by scalar child // but are not included in the output columns of relational children pcrsOuter->Union(pcrsUsed); pcrsOuter->Exclude(pcrsOutput); pcrsOutput->Release(); pcrsUsed->Release(); return pcrsOuter; }
//--------------------------------------------------------------------------- // @function: // CLogical::PstatsBaseTable // // @doc: // Helper for deriving statistics on a base table // //--------------------------------------------------------------------------- IStatistics * CLogical::PstatsBaseTable ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CTableDescriptor *ptabdesc, CColRefSet *pcrsHistExtra // additional columns required for stats, not required by parent ) { CReqdPropRelational *prprel = CReqdPropRelational::Prprel(exprhdl.Prp()); CColRefSet *pcrsHist = GPOS_NEW(pmp) CColRefSet(pmp); pcrsHist->Include(prprel->PcrsStat()); if (NULL != pcrsHistExtra) { pcrsHist->Include(pcrsHistExtra); } CDrvdPropRelational *pdprel = exprhdl.Pdprel(); CColRefSet *pcrsOutput = pdprel->PcrsOutput(); CColRefSet *pcrsWidth = GPOS_NEW(pmp) CColRefSet(pmp); pcrsWidth->Include(pcrsOutput); pcrsWidth->Exclude(pcrsHist); const COptCtxt *poctxt = COptCtxt::PoctxtFromTLS(); CMDAccessor *pmda = poctxt->Pmda(); CStatisticsConfig *pstatsconf = poctxt->Poconf()->Pstatsconf(); IStatistics *pstats = pmda->Pstats ( pmp, ptabdesc->Pmdid(), pcrsHist, pcrsWidth, pstatsconf ); // clean up pcrsWidth->Release(); pcrsHist->Release(); return pstats; }
//--------------------------------------------------------------------------- // @function: // CPhysical::PcrsChildReqd // // @doc: // Helper for computing required output columns of the n-th child; // the caller must be an operator whose ulScalarIndex-th child is a // scalar // //--------------------------------------------------------------------------- CColRefSet * CPhysical::PcrsChildReqd ( IMemoryPool *mp, CExpressionHandle &exprhdl, CColRefSet *pcrsRequired, ULONG child_index, ULONG ulScalarIndex ) { pcrsRequired->AddRef(); CReqdColsRequest *prcr = GPOS_NEW(mp) CReqdColsRequest(pcrsRequired, child_index, ulScalarIndex); CColRefSet *pcrs = NULL; { // scope of AutoMutex CAutoMutex am(m_mutex); am.Lock(); // lookup required columns map first pcrs = m_phmrcr->Find(prcr); if (NULL != pcrs) { prcr->Release(); pcrs->AddRef(); return pcrs; } } // request was not found in map -- we need to compute it pcrs = GPOS_NEW(mp) CColRefSet(mp, *pcrsRequired); if (gpos::ulong_max != ulScalarIndex) { // include used columns and exclude defined columns of scalar child pcrs->Union(exprhdl.GetDrvdScalarProps(ulScalarIndex)->PcrsUsed()); pcrs->Exclude(exprhdl.GetDrvdScalarProps(ulScalarIndex)->PcrsDefined()); } // intersect computed column set with child's output columns pcrs->Intersection(exprhdl.GetRelationalProperties(child_index)->PcrsOutput()); // lookup map again to handle concurrent map lookup/insertion { // scope of AutoMutex CAutoMutex am(m_mutex); am.Lock(); CColRefSet *pcrsFound = m_phmrcr->Find(prcr); if (NULL != pcrsFound) { // request was found now -- release computed request and use the found request prcr->Release(); pcrs->Release(); pcrsFound->AddRef(); pcrs = pcrsFound; } else { // new request -- insert request in map pcrs->AddRef(); #ifdef GPOS_DEBUG BOOL fSuccess = #endif // GPOS_DEBUG m_phmrcr->Insert(prcr, pcrs); GPOS_ASSERT(fSuccess); } } return pcrs; }
//--------------------------------------------------------------------------- // @function: // CNormalizer::FLocalColsSubsetOfInputCols // // @doc: // Check if the columns used by the operator are a subset of its input columns // //--------------------------------------------------------------------------- BOOL CNormalizer::FLocalColsSubsetOfInputCols ( IMemoryPool *pmp, CExpression *pexpr ) { GPOS_ASSERT(NULL != pexpr); GPOS_CHECK_STACK_SIZE; CExpressionHandle exprhdl(pmp); if (NULL != pexpr->Pgexpr()) { exprhdl.Attach(pexpr->Pgexpr()); } else { exprhdl.Attach(pexpr); } exprhdl.DeriveProps(NULL /*pdpctxt*/); BOOL fValid = true; if (pexpr->Pop()->FLogical()) { if (0 == exprhdl.UlNonScalarChildren()) { return true; } CColRefSet *pcrsInput = GPOS_NEW(pmp) CColRefSet(pmp); const ULONG ulArity = exprhdl.UlArity(); for (ULONG ul = 0; ul < ulArity; ul++) { if (!exprhdl.FScalarChild(ul)) { CDrvdPropRelational *pdprelChild = exprhdl.Pdprel(ul); pcrsInput->Include(pdprelChild->PcrsOutput()); } } // check if the operator's locally used columns are a subset of the input columns CColRefSet *pcrsUsedOp = exprhdl.PcrsUsedColumns(pmp); pcrsUsedOp->Exclude(exprhdl.Pdprel()->PcrsOuter()); fValid = pcrsInput->FSubset(pcrsUsedOp); // release pcrsInput->Release(); pcrsUsedOp->Release(); } // check if its children are valid const ULONG ulExprArity = pexpr->UlArity(); for (ULONG ulChildIdx = 0; ulChildIdx < ulExprArity && fValid; ulChildIdx++) { CExpression *pexprChild = (*pexpr)[ulChildIdx]; fValid = FLocalColsSubsetOfInputCols(pmp, pexprChild); } return fValid; }