コード例 #1
0
ファイル: Path.java プロジェクト: runeengh/basex
  @Override
  public final Expr optimize(final QueryContext qc, final VarScope scp) throws QueryException {
    final Value v = initial(qc);
    if (v != null && v.isEmpty() || emptyPath(v)) return optPre(qc);

    // merge descendant steps
    Expr e = mergeSteps(qc);
    if (e == this && v != null && v.type == NodeType.DOC) {
      // check index access
      e = index(qc, v);
      // rewrite descendant to child steps
      if (e == this) e = children(qc, v);
    }
    // recompile path if it has changed
    if (e != this) return e.compile(qc, scp);

    // set atomic type for single attribute steps to speed up predicate tests
    if (root == null && steps.length == 1 && steps[0] instanceof Step) {
      final Step curr = (Step) steps[0];
      if (curr.axis == ATTR && curr.test.kind == Kind.URI_NAME) curr.seqType(SeqType.NOD_ZO);
    }

    // choose best path implementation and set type information
    final Path path = get(info, root, steps);
    path.size = path.size(qc);
    path.seqType = SeqType.get(steps[steps.length - 1].seqType().type, size);
    return path;
  }
コード例 #2
0
ファイル: List.java プロジェクト: ngrstad/basex
  @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);
  }