Beispiel #1
0
  @Override
  public final Expr compile(final QueryContext qc, final VarScope scp) throws QueryException {
    if (root != null) root = root.compile(qc, scp);
    // no steps
    if (steps.length == 0) return root == null ? new Context(info) : root;

    final Value init = qc.value, cv = initial(qc);
    final boolean doc = cv != null && cv.type == NodeType.DOC;
    qc.value = cv;
    try {
      final int sl = steps.length;
      for (int s = 0; s < sl; s++) {
        Expr e = steps[s];

        // axis step: if input is a document, its type is temporarily generalized
        final boolean as = e instanceof Step;
        if (as && s == 0 && doc) cv.type = NodeType.NOD;

        e = e.compile(qc, scp);
        if (e.isEmpty()) return optPre(qc);
        steps[s] = e;

        // no axis step: invalidate context value
        if (!as) qc.value = null;
      }
    } finally {
      if (doc) cv.type = NodeType.DOC;
      qc.value = init;
    }
    // optimize path
    return optimize(qc, scp);
  }
Beispiel #2
0
  @Override
  public Expr compile(final QueryContext ctx) throws QueryException {
    for (int e = 0; e < expr.length; e++) expr[e] = expr[e].compile(ctx);

    // compute number of results
    size = 0;
    for (final Expr e : expr) {
      final long c = e.size();
      if (c == -1) {
        size = c;
        break;
      }
      size += c;
    }

    // evaluate sequence type
    type = SeqType.EMP;
    Value[] val = new Value[expr.length];
    for (int v = 0; v < expr.length; v++) {
      final Expr e = expr[v];
      // check if all expressions are values
      if (val != null) {
        if (e.isValue()) val[v] = (Value) e;
        else val = null;
      }
      // skip expression that will not add any results
      if (e.isEmpty()) continue;
      // evaluate sequence type
      final SeqType et = e.type();
      type =
          type == SeqType.EMP
              ? et
              : SeqType.get(
                  et.type == type.type ? et.type : AtomType.ITEM,
                  et.mayBeZero() && type.mayBeZero() ? Occ.ZERO_MORE : Occ.ONE_MORE);
    }

    // return cached integer sequence, cached values or self reference
    Expr e = this;
    final int s = (int) size;
    if (val != null && size <= Integer.MAX_VALUE) {
      if (type.type == AtomType.STR) e = StrSeq.get(val, s);
      else if (type.type == AtomType.BLN) e = BlnSeq.get(val, s);
      else if (type.type == AtomType.FLT) e = FltSeq.get(val, s);
      else if (type.type == AtomType.DBL) e = DblSeq.get(val, s);
      else if (type.type == AtomType.DEC) e = DecSeq.get(val, s);
      else if (type.type == AtomType.BYT) e = BytSeq.get(val, s);
      else if (type.type.instanceOf(AtomType.ITR)) e = IntSeq.get(val, s, type.type);
      else {
        final ValueBuilder vb = new ValueBuilder(s);
        for (final Value v : val) vb.add(v);
        e = vb.value();
      }
    }
    return optPre(e, ctx);
  }
Beispiel #3
0
  @Override
  public Expr optimize(final QueryContext ctx, final VarScope scp) throws QueryException {
    if (root instanceof Context) {
      ctx.compInfo(OPTREMCTX);
      root = null;
    }

    for (final Expr e : steps) {
      // check for empty steps
      if (e.isEmpty()) return optPre(null, ctx);
    }

    return this;
  }
Beispiel #4
0
  @Override
  public final Expr optimize(final QueryContext ctx, final VarScope scp) throws QueryException {
    // invalidate current context value (will be overwritten by filter)
    final Value cv = ctx.value;
    try {
      // return empty root
      if (root.isEmpty()) return optPre(null, ctx);
      // convert filters without numeric predicates to axis paths
      if (root instanceof AxisPath && !super.has(Flag.FCS))
        return ((AxisPath) root.copy(ctx, scp)).addPreds(ctx, scp, preds);

      // no predicates.. return root; otherwise, do some advanced compilations
      return preds.length == 0 ? root : opt(ctx);
    } finally {
      ctx.value = cv;
    }
  }
Beispiel #5
0
  @Override
  public Expr optimize(final QueryContext qc, final VarScope scp) throws QueryException {
    super.optimize(qc, scp);

    final ExprList el = new ExprList(exprs.length);
    for (final Expr ex : exprs) {
      if (ex.isEmpty()) {
        // remove empty operands (return empty sequence if first value is empty)
        if (el.isEmpty()) return optPre(qc);
        qc.compInfo(OPTREMOVE_X_X, this, ex);
      } else {
        el.add(ex);
      }
    }
    // ensure that results are always sorted
    if (el.size() == 1 && iterable) return el.get(0);
    // replace expressions with optimized list
    exprs = el.finish();
    return this;
  }
Beispiel #6
0
 /**
  * Returns true if at least one argument is empty or will yield 0 results.
  *
  * @return result of check
  */
 protected final boolean oneIsEmpty() {
   for (final Expr e : exprs) if (e.isEmpty()) return true;
   return false;
 }