Beispiel #1
0
bool ComparisonMatchExpression::matchesSingleElement(const BSONElement& e) const {

    if (e.canonicalType() != _rhs.canonicalType()) {
        // some special cases
        //  jstNULL and undefined are treated the same
        if (e.canonicalType() + _rhs.canonicalType() == 5) {
            return matchType() == EQ || matchType() == LTE || matchType() == GTE;
        }

        if (_rhs.type() == MaxKey || _rhs.type() == MinKey) {
            return matchType() != EQ;
        }

        return false;
    }

    // Special case handling for NaN. NaN is equal to NaN but
    // otherwise always compares to false.
    if (std::isnan(e.numberDouble()) || std::isnan(_rhs.numberDouble())) {
        bool bothNaN = std::isnan(e.numberDouble()) && std::isnan(_rhs.numberDouble());
        switch (matchType()) {
            case LT:
                return false;
            case LTE:
                return bothNaN;
            case EQ:
                return bothNaN;
            case GT:
                return false;
            case GTE:
                return bothNaN;
            default:
                // This is a comparison match expression, so it must be either
                // a $lt, $lte, $gt, $gte, or equality expression.
                fassertFailed(17448);
        }
    }

    int x = compareElementValues(e, _rhs, _collator);

    switch (matchType()) {
        case LT:
            return x < 0;
        case LTE:
            return x <= 0;
        case EQ:
            return x == 0;
        case GT:
            return x > 0;
        case GTE:
            return x >= 0;
        default:
            // This is a comparison match expression, so it must be either
            // a $lt, $lte, $gt, $gte, or equality expression.
            fassertFailed(16828);
    }
}
Beispiel #2
0
 /* wo = "well ordered" */
 int BSONElement::woCompare( const BSONElement &e,
                             bool considerFieldName ) const {
     int lt = (int) canonicalType();
     int rt = (int) e.canonicalType();
     int x = lt - rt;
     if( x != 0 && (!isNumber() || !e.isNumber()) )
         return x;
     if ( considerFieldName ) {
         x = strcmp(fieldName(), e.fieldName());
         if ( x != 0 )
             return x;
     }
     x = compareElementValues(*this, e);
     return x;
 }
Beispiel #3
0
    int BSONElement::woCompare( const BSONElement &e,
                                bool considerFieldName ) const {
        int lt = (int) type();
        if ( lt == NumberInt ) lt = NumberDouble;
        int rt = (int) e.type();
        if ( rt == NumberInt ) rt = NumberDouble;

        int x = lt - rt;
        if ( x != 0 )
            return x;
        if ( considerFieldName ) {
            x = strcmp(fieldName(), e.fieldName());
            if ( x != 0 )
                return x;
        }
        x = compareElementValues(*this, e);
        return x;
    }
Beispiel #4
0
bool ComparisonMatchExpression::matchesSingleElement( const BSONElement& e ) const {
    //log() << "\t ComparisonMatchExpression e: " << e << " _rhs: " << _rhs << "\n"
    //<< toString() << std::endl;

    if ( e.canonicalType() != _rhs.canonicalType() ) {
        // some special cases
        //  jstNULL and undefined are treated the same
        if ( e.canonicalType() + _rhs.canonicalType() == 5 ) {
            return matchType() == EQ || matchType() == LTE || matchType() == GTE;
        }

        if ( _rhs.type() == MaxKey || _rhs.type() == MinKey ) {
            return matchType() != EQ;
        }

        return false;
    }

    if ( _rhs.type() == Array ) {
        if ( matchType() != EQ ) {
            return false;
        }
    }

    int x = compareElementValues( e, _rhs );

    //log() << "\t\t" << x << endl;

    switch ( matchType() ) {
    case LT:
        return x < 0;
    case LTE:
        return x <= 0;
    case EQ:
        return x == 0;
    case GT:
        return x > 0;
    case GTE:
        return x >= 0;
    default:
        throw 1;
    }
    throw 1;
}