示例#1
0
 /**
  * Returns the index of the first field in <code>rel</code> which comes from its <code>ordinal
  * </code>th input.
  *
  * <p>For example, if rel joins T0(A,B,C) to T1(D,E), then countFields(0,rel) yields 0, and
  * countFields(1,rel) yields 3.
  */
 private int computeFieldOffset(RelNode rel, int ordinal) {
   if (ordinal == 0) {
     // short-circuit for the common case
     return 0;
   }
   int fieldOffset = 0;
   final List<RelNode> inputs = rel.getInputs();
   for (int i = 0; i < ordinal; i++) {
     RelNode input = inputs.get(i);
     fieldOffset += input.getRowType().getFieldList().size();
   }
   return fieldOffset;
 }
示例#2
0
 @Override
 public ParseTree visitChildInternal(RelNode child, int ordinal) {
   final Convention convention = child.getConvention();
   if (!(child instanceof JavaRel)) {
     throw Util.newInternal(
         "Relational expression '"
             + child
             + "' has '"
             + convention
             + "' calling convention, so must implement interface "
             + JavaRel.class);
   }
   JavaRel javaRel = (JavaRel) child;
   final ParseTree p = javaRel.implement(this);
   if ((convention == CallingConvention.JAVA) && (p != null)) {
     throw Util.newInternal(
         "Relational expression '"
             + child
             + "' returned '"
             + p
             + " on implement, but should have "
             + "returned null, because it has JAVA calling-convention. "
             + "(Note that similar calling-conventions, such as "
             + "Iterator, must return a value.)");
   }
   return p;
 }
示例#3
0
 private void bindDeferred(JavaFrame frame, final RelNode rel) {
   final StatementList statementList = getStatementList();
   if (frame.bind == null) {
     // this relational expression has not bound itself, so we presume
     // that we can call its implementSelf() method
     if (!(rel instanceof JavaSelfRel)) {
       throw Util.newInternal(
           "In order to bind-deferred, a "
               + "relational expression must implement JavaSelfRel: "
               + rel);
     }
     final JavaSelfRel selfRel = (JavaSelfRel) rel;
     LazyBind lazyBind =
         new LazyBind(
             newVariable(),
             statementList,
             getTypeFactory(),
             rel.getRowType(),
             new VariableInitializerThunk() {
               public VariableInitializer getInitializer() {
                 return selfRel.implementSelf(JavaRelImplementor.this);
               }
             });
     bind(rel, lazyBind);
   } else if ((frame.bind instanceof LazyBind)
       && (((LazyBind) frame.bind).statementList != statementList)) {
     // Frame is already bound, but to a variable declared in a different
     // scope. Re-bind it.
     final LazyBind lazyBind = (LazyBind) frame.bind;
     lazyBind.statementList = statementList;
     lazyBind.bound = false;
   }
 }
示例#4
0
    private JavaFrame findFrame() {
      RelNode previous = rel;
      while (true) {
        JavaFrame frame = (JavaFrame) mapRel2Frame.get(previous);
        if (frame.bind != null) {
          tracer.log(
              Level.FINE,
              "Bind " + rel.toString() + " to " + previous.toString() + "(" + frame.bind + ")");
          return frame;
        }

        // go deeper
        List<RelNode> inputs = previous.getInputs();
        assert (inputs.size() == 1) : "input is not bound";
        previous = inputs.get(0);
      }
    }
示例#5
0
 /**
  * Records the fact that instances of <code>rel</code> are available via <code>bind</code> (which
  * may be eager or lazy).
  */
 private void bind(RelNode rel, Bind bind) {
   tracer.log(Level.FINE, "Bind " + rel.toString() + " to " + bind);
   JavaFrame frame = (JavaFrame) mapRel2Frame.get(rel);
   frame.bind = bind;
   boolean stupid = SaffronProperties.instance().stupid.get();
   if (stupid) {
     // trigger the declaration of the variable, even though it
     // may not be used
     Util.discard(bind.getVariable());
   }
 }
示例#6
0
 /**
  * Returns the variable which, in the generated program, will hold the current row of a given
  * relational expression. This method is only applicable if the relational expression is the
  * current one or an input; if it is an ancestor, there is no current value, and this method
  * returns null.
  */
 public Variable findInputVariable(RelNode rel) {
   while (true) {
     JavaFrame frame = (JavaFrame) mapRel2Frame.get(rel);
     if ((frame != null) && frame.hasVariable()) {
       return frame.getVariable();
     }
     List<RelNode> inputs = rel.getInputs();
     if (inputs.size() == 1) {
       rel = inputs.get(0);
     } else {
       return null;
     }
   }
 }
示例#7
0
  /**
   * Declares a variable, and binds it lazily, so it only gets initialized if it is actually used.
   *
   * @return the Variable so declared
   */
  public Variable bind(
      RelNode rel, StatementList statementList, final VariableInitializer initializer) {
    VariableInitializerThunk thunk =
        new VariableInitializerThunk() {
          public VariableInitializer getInitializer() {
            return initializer;
          }
        };

    Variable variable = newVariable();
    LazyBind bind =
        new LazyBind(variable, statementList, getTypeFactory(), rel.getRowType(), thunk);
    bind(rel, bind);
    return bind.getVariable();
  }