@Override public Expr comp(final QueryContext ctx) throws QueryException { ts = checkUp(ts, ctx).comp(ctx); final Expr[] tmp = new Expr[cases.length]; for (int i = 0; i < cases.length; ++i) tmp[i] = cases[i].expr; checkUp(ctx, tmp); // static condition: return branch in question if (ts.isValue()) { for (final TypeCase c : cases) { if (c.var.type == null || c.var.type.instance(ts.value(ctx))) return optPre(c.comp(ctx, (Value) ts).expr, ctx); } } // compile branches for (final TypeCase c : cases) c.comp(ctx); // return result if all branches are equal (e.g., empty) boolean eq = true; for (int i = 1; i < cases.length; ++i) { eq &= cases[i - 1].expr.sameAs(cases[i].expr); } if (eq) return optPre(null, ctx); // evaluate return type type = cases[0].type(); for (int c = 1; c < cases.length; ++c) { type = type.intersect(cases[c].type()); } return this; }
@Override public void plan(final Serializer ser) throws IOException { ser.openElement(this); for (final TypeCase c : cases) c.plan(ser); ts.plan(ser); ser.closeElement(); }
@Override public Iter iter(final QueryContext qc) throws QueryException { final Value seq = qc.value(ts); for (final TypeCase tc : cases) { final Iter iter = tc.iter(qc, seq); if (iter != null) return iter; } // will never happen throw Util.notExpected(); }
@Override public Iter iter(final QueryContext ctx) throws QueryException { final Value seq = ctx.value(ts); for (final TypeCase c : cases) { final Iter iter = c.iter(ctx, seq); if (iter != null) return iter; } // will never happen throw Util.notexpected(); }
@Override public Expr compile(final QueryContext qc, final VarScope scp) throws QueryException { ts = ts.compile(qc, scp); // static condition: return branch in question if (ts.isValue()) { final Value val = ts.value(qc); for (final TypeCase tc : cases) { if (tc.matches(val)) return optPre(tc.compile(qc, scp, (Value) ts).expr, qc); } } // compile branches for (final TypeCase tc : cases) tc.compile(qc, scp); return optimize(qc, scp); }
@Override public boolean has(final Flag flag) { for (final TypeCase tc : cases) if (tc.has(flag)) return true; return ts.has(flag); }
@Override public void markTailCalls(final QueryContext qc) { for (final TypeCase t : cases) t.markTailCalls(qc); }
@Override public boolean removable(final Var var) { for (final TypeCase tc : cases) if (!tc.removable(var)) return false; return ts.removable(var); }
@Override public int count(final Var v) { int c = ts.count(v); for (final TypeCase t : cases) c += t.count(v); return c; }
@Override public boolean uses(final Use u) { if (u == Use.VAR) return true; for (final TypeCase c : cases) if (c.uses(u)) return true; return ts.uses(u); }
@Override Expr markTailCalls() { for (final TypeCase t : cases) t.markTailCalls(); return this; }
@Override public boolean removable(final Var v) { for (final TypeCase c : cases) if (!c.removable(v)) return false; return ts.removable(v); }