/** * Returns the new target type, or {@code null} if conversion is not necessary. * * @param curr old item * @param it new item * @return result (or {@code null}) * @throws QueryException query exception */ private AtomType numType(final Item curr, final Item it) throws QueryException { final Type ti = it.type; if (ti.isUntyped()) return DBL; final Type tc = curr.type; if (!(it instanceof ANum)) throw EXPTYPE_X_X_X.get(info, tc, ti, it); return tc == ti ? null : tc == DBL || ti == DBL ? DBL : tc == FLT || ti == FLT ? FLT : null; }
/** * Checks if the specified item is a QName. Returns the item or throws an exception. * * @param it item * @param empty allow empty result * @return QNm item * @throws QueryException query exception */ protected final QNm toQNm(final Item it, final boolean empty) throws QueryException { if (empty && it == null) return null; final Type ip = checkNoEmpty(it, AtomType.QNM).type; if (ip == AtomType.QNM) return (QNm) it; if (ip.isUntyped()) throw NSSENS_X_X.get(info, ip, AtomType.QNM); throw castError(it, AtomType.QNM, info); }
@Override public Expr optimize(final QueryContext ctx, final VarScope scp) throws QueryException { final SeqType s0 = expr[0].type(); final SeqType s1 = expr[1].type(); final Type t0 = s0.type; final Type t1 = s1.type; if (t0.isNumberOrUntyped() && t1.isNumberOrUntyped()) { final Occ occ = s0.one() && s1.one() ? Occ.ONE : Occ.ZERO_ONE; type = SeqType.get(Calc.type(t0, t1), occ); } else if (s0.one() && s1.one()) { type = SeqType.ITEM; } return optPre(oneIsEmpty() ? null : allAreValues() ? item(ctx, info) : this, ctx); }
@Override public Type union(final Type t) { if (instanceOf(t)) return t; if (t instanceof ArrayType) { final ArrayType mt = (ArrayType) t; return mt.instanceOf(this) ? this : get(retType.union(mt.retType)); } return t instanceof MapType ? ANY_FUN : t instanceof FuncType ? t.union(this) : AtomType.ITEM; }
/** * 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 number. Returns a token representation or throws an * exception. * * @param it item to be checked * @return number * @throws QueryException query exception */ protected final long toLong(final Item it) throws QueryException { final Type ip = checkNoEmpty(it, AtomType.ITR).type; if (ip.instanceOf(AtomType.ITR) || ip.isUntyped()) return it.itr(info); throw castError(it, AtomType.ITR, info); }
/** * Checks if the specified item is a boolean. Returns the boolean or throws an exception. * * @param it item be checked * @return boolean * @throws QueryException query exception */ protected final boolean toBoolean(final Item it) throws QueryException { final Type ip = checkNoEmpty(it, AtomType.BLN).type; if (ip == AtomType.BLN) return it.bool(info); if (ip.isUntyped()) return Bln.parse(it.string(info), info); throw castError(it, AtomType.BLN, info); }
/** * Checks if the specified non-empty item is a string. Returns its value as token or throws an * exception. * * @param it item to be checked * @return token * @throws QueryException query exception */ protected final byte[] toToken(final Item it) throws QueryException { final Type ip = it.type; if (ip.isStringOrUntyped()) return it.string(info); throw it instanceof FItem ? FIATOM_X.get(info, it.type) : castError(it, AtomType.STR, info); }