Search in sources :

Example 1 with Operator

use of org.exist.indexing.range.RangeIndex.Operator in project exist by eXist-db.

the class RangeIndexConfigAttributeCondition method find.

@Override
public boolean find(Predicate predicate) {
    final Expression inner = this.getInnerExpression(predicate);
    Operator operator;
    Expression lhe;
    Expression rhe;
    // get the type of the expression inside the predicate and determine right and left hand arguments
    if (inner instanceof GeneralComparison) {
        final GeneralComparison comparison = (GeneralComparison) inner;
        operator = RangeQueryRewriter.getOperator(inner);
        lhe = comparison.getLeft();
        rhe = comparison.getRight();
    } else if (inner instanceof InternalFunctionCall) {
        // calls to matches() will not have been rewritten to a comparison, so check for function call
        final Function func = ((InternalFunctionCall) inner).getFunction();
        if (func.isCalledAs("matches")) {
            operator = Operator.MATCH;
            lhe = func.getArgument(0);
            rhe = func.getArgument(1);
            lhe = unwrapSubExpression(lhe);
            rhe = unwrapSubExpression(rhe);
        } else {
            // predicate expression cannot be parsed as condition
            return false;
        }
    } else {
        // predicate expression cannot be parsed as condition
        return false;
    }
    // find the attribute name and value pair from the predicate to check against
    // first assume attribute is on the left and value is on the right
    LocationStep testStep = findLocationStep(lhe);
    AtomicValue testValue = findAtomicValue(rhe);
    switch(this.operator) {
        case EQ:
        case NE:
            // check the other way around
            if (testStep == null && testValue == null) {
                testStep = findLocationStep(rhe);
                testValue = findAtomicValue(lhe);
            }
        case GT:
        case LT:
        case GE:
        case LE:
            // but the operator has to be inverted
            if (testStep == null && testValue == null) {
                testStep = findLocationStep(rhe);
                testValue = findAtomicValue(lhe);
                operator = invertOrdinalOperator(operator);
            }
    }
    if (testStep != null && testValue != null) {
        final QName qname = testStep.getTest().getName();
        Comparable foundValue;
        Comparable requiredValue;
        boolean valueTypeMatches;
        try {
            if (this.numericComparison) {
                valueTypeMatches = testValue instanceof NumericValue;
                requiredValue = this.numericValue;
                foundValue = testValue.toJavaObject(Double.class);
            } else {
                valueTypeMatches = testValue instanceof StringValue;
                if (this.caseSensitive) {
                    requiredValue = this.getLowercaseValue();
                    foundValue = testValue.getStringValue().toLowerCase();
                } else {
                    requiredValue = this.value;
                    foundValue = testValue.getStringValue();
                }
            }
            if (qname.getNameType() == ElementValue.ATTRIBUTE && operator.equals(this.operator) && qname.equals(this.attribute) && valueTypeMatches && foundValue.equals(requiredValue)) {
                return true;
            }
        } catch (XPathException e) {
            RangeIndex.LOG.error("Value conversion error when testing predicate for condition, value: {}", testValue.toString());
            RangeIndex.LOG.error(e);
        }
    }
    return false;
}
Also used : Operator(org.exist.indexing.range.RangeIndex.Operator) QName(org.exist.dom.QName) AtomicValue(org.exist.xquery.value.AtomicValue) NumericValue(org.exist.xquery.value.NumericValue) StringValue(org.exist.xquery.value.StringValue)

Aggregations

QName (org.exist.dom.QName)1 Operator (org.exist.indexing.range.RangeIndex.Operator)1 AtomicValue (org.exist.xquery.value.AtomicValue)1 NumericValue (org.exist.xquery.value.NumericValue)1 StringValue (org.exist.xquery.value.StringValue)1