@Override public int exprSize() { int sz = 1; for (final Let lt : copies) sz += lt.exprSize(); for (final Expr e : expr) sz += e.exprSize(); return sz; }
@Override public void checkUp() throws QueryException { for (final Let c : copies) c.checkUp(); final Expr m = expr[0]; m.checkUp(); if (!m.isVacuous() && !m.has(Flag.UPD)) throw UPMODIFY.get(info); checkNoUp(expr[1]); }
/** * Tests if the specified expressions are updating or vacuous. * * @param ctx query context * @param expr expression array * @throws QueryException query exception */ public void checkUp(final QueryContext ctx, final Expr... expr) throws QueryException { if (!ctx.updating) return; int s = 0; for (final Expr e : expr) { if (e.vacuous()) continue; final boolean u = e.uses(Use.UPD); if (u && s == 2 || !u && s == 1) UPNOT.thrw(input, desc()); s = u ? 1 : 2; } }
@Override public Item item(final QueryContext qc, final InputInfo ii) throws QueryException { final QNm name = toQNm(exprs[0], qc, sc, false); final long arity = toLong(exprs[1], qc); if (arity < 0 || arity > Integer.MAX_VALUE) throw FUNCUNKNOWN_X.get(ii, name); try { final Expr lit = Functions.getLiteral(name, (int) arity, qc, sc, ii); return lit == null ? null : lit.item(qc, ii); } catch (final QueryException e) { // function not found (in most cases: XPST0017) return null; } }
@Override public Expr optimize(final QueryContext ctx, final VarScope scp) throws QueryException { final int ar = expr.length - 1; final Expr f = expr[ar]; final Type t = f.type().type; if (t instanceof FuncType) { final FuncType ft = (FuncType) t; if (ft.args != null && ft.args.length != ar) throw INVARITY.get(info, f, ar); if (ft.ret != null) type = ft.ret; } if (f instanceof XQFunctionExpr) { // maps can only contain fully evaluated Values, so this is safe if (allAreValues() && f instanceof Map) return optPre(value(ctx), ctx); // try to inline the function if (!(f instanceof FuncItem && comesFrom((FuncItem) f)) && !updating) { final Expr[] args = Arrays.copyOf(expr, expr.length - 1); final Expr inl = ((XQFunctionExpr) f).inlineExpr(args, ctx, scp, info); if (inl != null) return inl; } } return this; }
/** * Checks if the specified expression yields a string or empty sequence. Returns a token * representation or an exception. * * @param e expression to be evaluated * @param ctx query context * @return item * @throws QueryException query exception */ public final byte[] checkEStr(final Expr e, final QueryContext ctx) throws QueryException { return checkEStr(e.item(ctx, input)); }
/** * Checks if the specified expression yields a non-empty item. * * @param e expression to be evaluated * @param ctx query context * @return item * @throws QueryException query exception */ public final Item checkItem(final Expr e, final QueryContext ctx) throws QueryException { return checkEmpty(e.item(ctx, input)); }
/** * Checks if the specified expression is an integer. Returns a token representation or an * exception. * * @param e expression to be checked * @param ctx query context * @return integer value * @throws QueryException query exception */ public final long checkItr(final Expr e, final QueryContext ctx) throws QueryException { return checkItr(checkNoEmpty(e.item(ctx, input), AtomType.ITR)); }
/** * Checks if the specified expression yields a double. Returns the double or throws an exception. * * @param e expression to be checked * @param ctx query context * @return double * @throws QueryException query exception */ public final double checkDbl(final Expr e, final QueryContext ctx) throws QueryException { final Item it = checkNoEmpty(e.item(ctx, input), AtomType.DBL); if (!it.unt() && !it.num()) Err.number(this, it); return it.dbl(input); }
/** * Checks if the specified expression yields a boolean. Returns the boolean or throws an * exception. * * @param e expression to be checked * @param ctx query context * @return boolean * @throws QueryException query exception */ public final boolean checkBln(final Expr e, final QueryContext ctx) throws QueryException { final Item it = checkNoEmpty(e.item(ctx, input), AtomType.BLN); if (!it.unt() && it.type != AtomType.BLN) Err.type(this, AtomType.BLN, it); return it.bool(input); }
/** * Checks if the specified expressions is no updating expression. * * @param e expression * @param ctx query context * @return the specified expression * @throws QueryException query exception */ public final Expr checkUp(final Expr e, final QueryContext ctx) throws QueryException { if (e != null && ctx.updating && e.uses(Use.UPD)) UPNOT.thrw(input, desc()); return e; }
/** * Returns a boolean equivalent for the specified expression. If the specified expression yields a * boolean value anyway, it will be returned as is. Otherwise, it will be wrapped into a boolean * function. * * @param e expression to be rewritten * @return expression */ protected final Expr compBln(final Expr e) { return e.type().eq(SeqType.BLN) ? e : Function.BOOLEAN.get(input, e); }