AtomicType t0 = operand0.getItemType(th).getAtomizedItemType();
AtomicType t1 = operand1.getItemType(th).getAtomizedItemType();
if (t0.isExternalType() || t1.isExternalType()) {
XPathException err = new XPathException("Cannot perform comparisons involving external objects");
err.setIsTypeError(true);
err.setErrorCode("XPTY0004");
err.setLocator(this);
throw err;
}
BuiltInAtomicType p0 = (BuiltInAtomicType)t0.getPrimitiveItemType();
if (p0.equals(BuiltInAtomicType.UNTYPED_ATOMIC)) {
p0 = BuiltInAtomicType.STRING;
}
BuiltInAtomicType p1 = (BuiltInAtomicType)t1.getPrimitiveItemType();
if (p1.equals(BuiltInAtomicType.UNTYPED_ATOMIC)) {
p1 = BuiltInAtomicType.STRING;
}
needsRuntimeCheck =
p0.equals(BuiltInAtomicType.ANY_ATOMIC) || p1.equals(BuiltInAtomicType.ANY_ATOMIC);
if (!needsRuntimeCheck && !Type.isComparable(p0, p1, Token.isOrderedOperator(operator))) {
boolean opt0 = Cardinality.allowsZero(operand0.getCardinality());
boolean opt1 = Cardinality.allowsZero(operand1.getCardinality());
if (opt0 || opt1) {
// This is a comparison such as (xs:integer? eq xs:date?). This is almost
// certainly an error, but we need to let it through because it will work if
// one of the operands is an empty sequence.
String which = null;
if (opt0) which = "the first operand is";
if (opt1) which = "the second operand is";
if (opt0 && opt1) which = "one or both operands are";
visitor.getStaticContext().issueWarning("Comparison of " + t0.toString(namePool) +
(opt0 ? "?" : "") + " to " + t1.toString(namePool) +
(opt1 ? "?" : "") + " will fail unless " + which + " empty", this);
needsRuntimeCheck = true;
} else {
XPathException err = new XPathException("Cannot compare " + t0.toString(namePool) +
" to " + t1.toString(namePool));
err.setIsTypeError(true);
err.setErrorCode("XPTY0004");
err.setLocator(this);
throw err;
}
}
if (!(operator == Token.FEQ || operator == Token.FNE)) {
if (!p0.isOrdered()) {
XPathException err = new XPathException("Type " + t0.toString(env.getNamePool()) + " is not an ordered type");
err.setErrorCode("XPTY0004");
err.setIsTypeError(true);
err.setLocator(this);
throw err;
}
if (!p1.isOrdered()) {
XPathException err = new XPathException("Type " + t1.toString(env.getNamePool()) + " is not an ordered type");
err.setErrorCode("XPTY0004");
err.setIsTypeError(true);
err.setLocator(this);
throw err;
}
}
if (comparer == null) {