Exemplo n.º 1
0
  @Override
  protected final Expr compPath(final QueryContext ctx) throws QueryException {
    for (final Expr s : steps) checkUp(s, ctx);

    // merge two axis paths
    if (root instanceof AxisPath) {
      Expr[] st = ((AxisPath) root).steps;
      root = ((AxisPath) root).root;
      for (final Expr s : steps) st = Array.add(st, s);
      steps = st;
      // refresh root context
      ctx.compInfo(OPTMERGE);
      ctx.value = root(ctx);
    }

    final AxisStep s = voidStep(steps);
    if (s != null) COMPSELF.thrw(input, s);

    for (int i = 0; i != steps.length; ++i) {
      final Expr e = steps[i].comp(ctx);
      if (!(e instanceof AxisStep)) return e;
      steps[i] = e;
    }
    optSteps(ctx);

    // retrieve data reference
    final Data data = ctx.data();
    if (data != null && ctx.value.type == NodeType.DOC) {
      // check index access
      Expr e = index(ctx, data);
      // check children path rewriting
      if (e == this) e = children(ctx, data);
      // return optimized expression
      if (e != this) return e.comp(ctx);
    }

    // analyze if result set can be cached - no predicates/variables...
    cache = root != null && !uses(Use.VAR);

    // if applicable, use iterative evaluation
    final Path path = finish(ctx);

    // heuristics: wrap with filter expression if only one result is expected
    return size() != 1 ? path : new Filter(input, this, Pos.get(1, size(), input)).comp2(ctx);
  }