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;
}
Aggregations