/** * Returns a minimum or maximum item. * * @param cmp comparator * @param qc query context * @return resulting item * @throws QueryException query exception */ Item minmax(final OpV cmp, final QueryContext qc) throws QueryException { final Collation coll = toCollation(1, qc); final Iter iter = exprs[0].atomIter(qc, info); Item curr = iter.next(); if (curr == null) return null; // check if first item is comparable cmp.eval(curr, curr, coll, sc, info); // strings if (curr instanceof AStr) { for (Item it; (it = iter.next()) != null; ) { if (!(it instanceof AStr)) throw EXPTYPE_X_X_X.get(info, curr.type, it.type, it); final Type rt = curr.type, ri = it.type; if (cmp.eval(curr, it, coll, sc, info)) curr = it; if (rt != ri && curr.type == URI) curr = STR.cast(curr, qc, sc, info); } return curr; } // dates, durations, booleans, binary values if (curr instanceof ADate || curr instanceof Dur || curr instanceof Bin || curr.type == BLN) { for (Item it; (it = iter.next()) != null; ) { if (curr.type != it.type) throw EXPTYPE_X_X_X.get(info, curr.type, it.type, it); if (cmp.eval(curr, it, coll, sc, info)) curr = it; } return curr; } // numbers if (curr.type.isUntyped()) curr = DBL.cast(curr, qc, sc, info); for (Item it; (it = iter.next()) != null; ) { final Type type = numType(curr, it); if (cmp.eval(curr, it, coll, sc, info) || Double.isNaN(it.dbl(info))) curr = it; if (type != null) curr = (Item) type.cast(curr, qc, sc, info); } return curr; }
/** * Checks if the specified item is a double. Returns the double or throws an exception. * * @param it item * @return double * @throws QueryException query exception */ protected final double toDouble(final Item it) throws QueryException { if (checkNoEmpty(it, AtomType.DBL).type.isNumberOrUntyped()) return it.dbl(info); throw numberError(this, it); }
/** * Checks if the specified, non-empty item is a double. Returns the double or throws an exception. * * @param it item to be checked * @return number * @throws QueryException query exception */ private ANum toNumber(final Item it) throws QueryException { if (it.type.isUntyped()) return Dbl.get(it.dbl(info)); if (it instanceof ANum) return (ANum) it; throw numberError(this, it); }
@Override public final Item test(final QueryContext qc, final InputInfo ii) throws QueryException { final Item it = ebv(qc, info); return (it instanceof ANum ? it.dbl(info) == qc.pos : it.bool(info)) ? it : null; }