int main(void) { for(int i=0; i<= 1; ++i) for(int j=0; j<= 1; ++j) for(int k=0; k<= 1; ++k) std::cout << and_result(S{i}, S{j}, S{k}) << std::endl; for(int i=0; i<= 1; ++i) for(int j=0; j<= 1; ++j) for(int k=0; k<= 1; ++k) std::cout << or_result(S{i}, S{j}, S{k}) << std::endl; return 0; }
NABoolean MdamColumn::buildDisjunct(MdamPredIterator & predIterator, sql_buffer_pool *pool, atp_struct *atp0, atp_struct *workAtp, unsigned short valueAtpIndex, Lng32 disjunct_number, NABoolean disjunct_number_in_stop_list, FixedSizeHeapManager & mdamIntervalHeap, FixedSizeHeapManager & mdamRefListEntryHeap, FixedSizeHeapManager & mdamRefListEntrysForStopListsHeap, Lng32 & dataConvErrorFlag) { NABoolean rc = disjunct_number_in_stop_list; NABoolean got_a_predicate = FALSE; // Note that we defer supplying the ref list for now MdamInterval * accumulator = new(mdamIntervalHeap) MdamInterval(lo_, MdamEnums::MDAM_INCLUDED, hi_, MdamEnums::MDAM_INCLUDED); tentative_intervals_.append(accumulator); // Advance the predicate list to the current disjunct, if necessary. // This will cause any left-over predicates that were not processed due // to an earlier conflict to be skipped. // Case number 10-971205-3848. predIterator.positionToCurrentDisjunct(¤tPred_); // Loop over the OR groups. while ((predIterator.positionToNextOr(¤tPred_)) && (!tentative_intervals_.isEmpty())) { #if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF ) MdamIntervalList or_result(3); #else MdamIntervalList or_result; #endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */ MdamPred * predPtr; // Loop over the predicates within an OR group. while (predPtr = predIterator.getNextPred(¤tPred_)) { // build an interval representing this predicate, if possible MdamInterval * or_accumulator = 0; tupp & pv = workAtp->getTupp(valueAtpIndex); tupp & pv2 = workAtp->getTupp(valueAtpIndex+1); #pragma nowarn(1506) // warning elimination pool->get_free_tuple(pv,columnGenInfo_->getLength()); if (predPtr->getPredType() == MdamPred::MDAM_BETWEEN) pool->get_free_tuple(pv2,columnGenInfo_->getLength()); #pragma warn(1506) // warning elimination got_a_predicate = TRUE; dataConvErrorFlag = 0; // The zero hard-coded here should be // ex_conv_clause::CONV_RESULT_OK in // file exp/exp_clause_derived.h. // The call to getValue sets dataConvErrorFlag. We use it twice in the // case of MDAM_BETWEEN, copying the values to other local variables. ex_expr::exp_return_type errorCode = predPtr->getValue(atp0,workAtp); Int32 dcErrFlag1 = dataConvErrorFlag; Int32 dcErrFlag2 = 0; if (errorCode == ex_expr::EXPR_OK && predPtr->getPredType() == MdamPred::MDAM_BETWEEN) { dataConvErrorFlag = 0; errorCode = predPtr->getValue2(atp0,workAtp); dcErrFlag2 = dataConvErrorFlag; } MdamPred::MdamPredType predType = MdamPred::MDAM_RETURN_FALSE; // Next 2 used only for MDAM_BETWEEN. MdamEnums::MdamInclusion startInclusion = predPtr->getStartInclusion(); MdamEnums::MdamInclusion endInclusion = predPtr->getEndInclusion(); if (errorCode == ex_expr::EXPR_OK) predType = predPtr->getTransformedPredType(dcErrFlag1, dcErrFlag2, startInclusion, endInclusion); // The switch statement below implements the following mapping... // MDAM_EQ -> [pv,pv] // MDAM_LE -> [nonNullLo, pv] // MDAM_LT -> [nonNullLo, pv) // MDAM_GE -> [pv, nonNullHi] // MDAM_GT -> (pv,nonNullHi] // MDAM_BETWEEN -> [pv,pv2] // MDAM_ISNULL -> [hi,hi] // MDAM_ISNULL_DESC -> [lo,lo] // MDAM_ISNOTNULL -> [nonNullLo,nonNullHi] // MDAM_RETURN_FALSE -> no interval switch (predType) { case MdamPred::MDAM_EQ: { or_accumulator = new(mdamIntervalHeap) MdamInterval(pv, MdamEnums::MDAM_INCLUDED, pv, MdamEnums::MDAM_INCLUDED); break; } case MdamPred::MDAM_LE: { or_accumulator = new(mdamIntervalHeap) MdamInterval(nonNullLo_, MdamEnums::MDAM_INCLUDED, pv, MdamEnums::MDAM_INCLUDED); break; } case MdamPred::MDAM_LT: { or_accumulator = new(mdamIntervalHeap) MdamInterval(nonNullLo_, MdamEnums::MDAM_INCLUDED, pv, MdamEnums::MDAM_EXCLUDED); break; } case MdamPred::MDAM_GE: { or_accumulator = new(mdamIntervalHeap) MdamInterval(pv, MdamEnums::MDAM_INCLUDED, nonNullHi_, MdamEnums::MDAM_INCLUDED); break; } case MdamPred::MDAM_GT: { or_accumulator = new(mdamIntervalHeap) MdamInterval(pv, MdamEnums::MDAM_EXCLUDED, nonNullHi_, MdamEnums::MDAM_INCLUDED); break; } case MdamPred::MDAM_BETWEEN: { // If the predicate is on a descending key column, switch the // endpoints. if (predPtr->reverseEndpoints()) or_accumulator = new(mdamIntervalHeap) MdamInterval(pv2, endInclusion, pv, startInclusion); else or_accumulator = new(mdamIntervalHeap) MdamInterval(pv, startInclusion, pv2, endInclusion); break; } case MdamPred::MDAM_ISNULL: // IS NULL predicate on ASC column { // if the column is nullable and ASC, we know that hi_ // is the NULL value or_accumulator = new(mdamIntervalHeap) MdamInterval(hi_, MdamEnums::MDAM_INCLUDED, hi_, MdamEnums::MDAM_INCLUDED); break; } case MdamPred::MDAM_ISNULL_DESC: // IS NULL predicate on DESC column { // if the column is nullable and DESC, we know that lo_ // is the NULL value or_accumulator = new(mdamIntervalHeap) MdamInterval(lo_, MdamEnums::MDAM_INCLUDED, lo_, MdamEnums::MDAM_INCLUDED); break; } case MdamPred::MDAM_ISNOTNULL: { or_accumulator = new(mdamIntervalHeap) MdamInterval(nonNullLo_, MdamEnums::MDAM_INCLUDED, nonNullHi_, MdamEnums::MDAM_INCLUDED); break; } case MdamPred::MDAM_RETURN_FALSE: { // The predicate cannot be satisfied so no interval is created. break; } default: { ex_assert(0,"Invalid predicate type"); //LCOV_EXCL_LINE break; } } // release tupp_descriptor assigned to pv now that we are done // with pv pv.release(); // OR in the interval just obtained into or_result if (or_accumulator) { if (or_result.isEmpty()) { or_result.append(or_accumulator); } else { #if defined ( NA_MDAM_EXECUTOR_DEBUG_ILTF ) MdamIntervalList or_temp1(4); #else MdamIntervalList or_temp1; #endif /* NA_MDAM_EXECUTOR_DEBUG_ILTF */ or_temp1.append(or_accumulator); or_result.unionSameDisjunct(or_temp1, columnGenInfo_->getLength(), mdamIntervalHeap, mdamRefListEntryHeap); or_temp1.deleteAllIntervals(mdamIntervalHeap, mdamRefListEntryHeap); } } } // AND the OR result to the accumulator tentative_intervals_.intersect(or_result, columnGenInfo_->getLength(), mdamIntervalHeap, mdamRefListEntryHeap); or_result.deleteAllIntervals(mdamIntervalHeap, mdamRefListEntryHeap); } if (((got_a_predicate) && (!rc)) || ((previous_ == 0) && (!rc))) { // this is the last key column that has a predicate // for this disjunct, or there is no key column having // a predicate for this column (in which case one wonders // why MDAM was picked!) -- add the disjunct number to the // stop list for this key column stop_list_.insert((Int32)disjunct_number,mdamRefListEntrysForStopListsHeap); rc = TRUE; } return rc; }