org.eigenbase.oj.rel
Class JavaRelImplementor

java.lang.Object
  extended by org.eigenbase.oj.rel.JavaRelImplementor
All Implemented Interfaces:
RelImplementor
Direct Known Subclasses:
FarragoRelImplementor

public class JavaRelImplementor
extends Object
implements RelImplementor

JavaRelImplementor deals with the nastiness of converting a tree of relational expressions into an implementation, generally an openjava parse tree.

The bind(org.eigenbase.rel.RelNode, openjava.ptree.Variable) method allows relational expressions to register which Java variable holds their row. They can bind 'lazily', so that the variable is only declared and initialized if it is actually used in another expression.

TODO jvs 14-June-2004: some of JavaRelImplementor is specific to the JAVA calling convention; those portions should probably be factored out into a subclass.


Nested Class Summary
private static interface JavaRelImplementor.Bind
           
private static class JavaRelImplementor.EagerBind
           
private static class JavaRelImplementor.Frame
           
private static class JavaRelImplementor.LazyBind
           
private  class JavaRelImplementor.RelBind
          Binds a relational expression to whatever another relational expression is currently bound to.
static class JavaRelImplementor.TranslationTester
          Similar to RexToOJTranslator, but instead of translating, merely tests whether an expression can be translated.
static interface JavaRelImplementor.VariableInitializerThunk
          A VariableInitializerThunk yields a VariableInitializer.
 
Field Summary
(package private)  Statement exitStatement
           
protected  OJRexImplementorTable implementorTable
           
(package private)  Map<String,JavaRelImplementor.Frame> mapCorrel2Frame
          Maps a String to the JavaRelImplementor.Frame whose JavaRelImplementor.Frame.rel.correlVariable == correlName.
(package private)  HashMap<String,Variable> mapCorrelNameToVariable
           
(package private)  Map<RelNode,JavaRelImplementor.Frame> mapRel2Frame
          Maps a RelNode to the unique frame whose JavaRelImplementor.Frame.rel is that relational expression.
private  int nextVariableId
           
private  RexBuilder rexBuilder
           
(package private)  Stack<StatementList> stmtListStack
          Stack of StatementList objects.
private static Logger tracer
           
 
Constructor Summary
JavaRelImplementor(RexBuilder rexBuilder, OJRexImplementorTable implementorTable)
          Creates a JavaRelImplementor
 
Method Summary
private  void bind(RelNode rel, JavaRelImplementor.Bind bind)
          Records the fact that instances of rel are available via bind (which may be eager or lazy).
 void bind(RelNode rel, RelNode previous)
          Shares a variable between relations.
 Variable bind(RelNode rel, StatementList statementList, VariableInitializer initializer)
          Declares a variable, and binds it lazily, so it only gets initialized if it is actually used.
 void bind(RelNode rel, Variable variable)
          Records the fact that instances of rel are available in variable.
 void bindCorrel(String correlName, Variable variable)
          Binds a correlating variable.
private  void bindDeferred(JavaRelImplementor.Frame frame, RelNode rel)
           
 boolean canTranslate(RelNode rel, RexNode expression, boolean deep)
          Determines whether it is possible to implement an expression in Java.
 boolean canTranslate(RelNode rel, RexProgram program)
          Determines whether it is possible to implement a set of expressions in Java.
private  int computeFieldOffset(RelNode rel, int ordinal)
          Returns the index of the first field in rel which comes from its ordinalth input.
protected  void createFrame(RelNode parent, int ordinal, RelNode child)
           
private  RelNode findInputRel(RelNode rel, int offset)
           
private  RelNode findInputRel(RelNode rel, int offset, int[] offsets)
           
 Variable findInputVariable(RelNode rel)
          Returns the variable which, in the generated program, will hold the current row of a given relational expression.
 JavaRel findRel(JavaRel rel, RexNode expression)
           
 void generateParentBody(RelNode rel, StatementList stmtList)
          Implements the body of the current expression's parent.
 int generateVariableId()
           
 List<RelNode> getAncestorRels(RelNode rel)
          Returns a list of the relational expressions which are ancestors of the current one.
 Variable getConnectionVariable()
           
 Statement getExitStatement()
           
 RexBuilder getRexBuilder()
           
 StatementList getStatementList()
           
 RelDataTypeFactory getTypeFactory()
           
 JavaRel implementFieldAccess(JavaRel rel, String fieldName)
          Burrows into a synthetic record and returns the underlying relation which provides the field called fieldName.
 void implementNext(AggregateCall call, JavaRel rel, Expression accumulator)
           
 Expression implementResult(AggregateCall call, Expression accumulator)
          Generates the expression to retrieve the result of this aggregation.
 Expression implementRoot(JavaRel rel)
          Starts an iteration, by calling JavaRel.implement(org.eigenbase.oj.rel.JavaRelImplementor) on the root element.
 Expression implementStart(AggregateCall call, JavaRel rel)
           
 Expression implementStartAndNext(AggregateCall call, JavaRel rel)
           
 Expression makeReference(String correlName, RelNode rel)
          Creates an expression which references correlating variable correlName from the context of rel.
 RexToOJTranslator newStmtTranslator(JavaRel rel, StatementList stmtList, MemberDeclarationList memberList)
          Creates a translator which can translate a succession of expressions, possibly using multiple statements, scratch variables, and helper functions.
protected  RexToOJTranslator newTranslator(RelNode rel)
          Creates a RexToOJTranslator with which to translate the row-expressions within a relational expression into OpenJava expressions.
 Variable newVariable()
          Generates a variable with a unique name.
 Variable newVariable(String base)
          Generates a variable with a unique name and a stem which indicates its purpose.
 void popStatementList(StatementList stmtList)
           
 void pushStatementList(StatementList stmtList)
           
 void setExitStatement(Statement stmt)
           
 Expression translate(JavaRel rel, RexNode exp)
          Converts an expression in internal form (the input relation is referenced using the variable $input0) to generated form (the input relation is referenced using the bindings in this JavaRelImplementor).
 Expression translateInput(JavaRel rel, int ordinal)
          Creates an expression which references the ordinalth input.
 Expression translateInputField(JavaRel rel, int ordinal, int fieldOrdinal)
          Creates an expression which references the fieldOrdinalth field of the ordinalth input.
 ExpressionList translateList(JavaRel rel, RexNode[] exps)
          Converts an array of expressions in internal into a list of expressions in generated form.
 Expression translateViaStatements(JavaRel rel, RexNode exp, StatementList stmtList, MemberDeclarationList memberList)
          Generates code for an expression, possibly using multiple statements, scratch variables, and helper functions.
 Object visitChild(RelNode parent, int ordinal, RelNode child)
          Implements a relational expression according to a calling convention.
 Object visitChildInternal(RelNode child)
          Called from RelImplementor.visitChild(org.eigenbase.rel.RelNode, int, org.eigenbase.rel.RelNode) after the frame has been set up.
 Object visitChildInternal(RelNode child, int ordinal)
          Called from RelImplementor.visitChild(org.eigenbase.rel.RelNode, int, org.eigenbase.rel.RelNode) after the frame has been set up.
 Expression visitJavaChild(RelNode parent, int ordinal, JavaRel child)
          Convenience wrapper around RelImplementor.visitChild(org.eigenbase.rel.RelNode, int, org.eigenbase.rel.RelNode) for the common case where JavaRel has a child which is a JavaRel.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

tracer

private static final Logger tracer

mapCorrel2Frame

final Map<String,JavaRelImplementor.Frame> mapCorrel2Frame
Maps a String to the JavaRelImplementor.Frame whose JavaRelImplementor.Frame.rel.correlVariable == correlName.


mapCorrelNameToVariable

final HashMap<String,Variable> mapCorrelNameToVariable

mapRel2Frame

final Map<RelNode,JavaRelImplementor.Frame> mapRel2Frame
Maps a RelNode to the unique frame whose JavaRelImplementor.Frame.rel is that relational expression.


stmtListStack

final Stack<StatementList> stmtListStack
Stack of StatementList objects.


exitStatement

Statement exitStatement

rexBuilder

private final RexBuilder rexBuilder

nextVariableId

private int nextVariableId

implementorTable

protected final OJRexImplementorTable implementorTable
Constructor Detail

JavaRelImplementor

public JavaRelImplementor(RexBuilder rexBuilder,
                          OJRexImplementorTable implementorTable)
Creates a JavaRelImplementor

Parameters:
rexBuilder - Builder for RexNodes
implementorTable - Table of implementations of operators. Must not be null
Method Detail

setExitStatement

public void setExitStatement(Statement stmt)

getExitStatement

public Statement getExitStatement()

getStatementList

public StatementList getStatementList()

getRexBuilder

public RexBuilder getRexBuilder()

getTypeFactory

public RelDataTypeFactory getTypeFactory()

bind

public void bind(RelNode rel,
                 Variable variable)
Records the fact that instances of rel are available in variable.


bind

public Variable bind(RelNode rel,
                     StatementList statementList,
                     VariableInitializer initializer)
Declares a variable, and binds it lazily, so it only gets initialized if it is actually used.

Returns:
the Variable so declared

bind

public void bind(RelNode rel,
                 RelNode previous)
Shares a variable between relations. previous already has a variable, and calling this method indicates that rel's output will appear in this variable too.


bindCorrel

public void bindCorrel(String correlName,
                       Variable variable)
Binds a correlating variable. References to correlating variables such as $cor2 will be replaced with java variables such as $Oj14.


findRel

public JavaRel findRel(JavaRel rel,
                       RexNode expression)

implementFieldAccess

public JavaRel implementFieldAccess(JavaRel rel,
                                    String fieldName)
Burrows into a synthetic record and returns the underlying relation which provides the field called fieldName.


generateParentBody

public void generateParentBody(RelNode rel,
                               StatementList stmtList)
Implements the body of the current expression's parent. If variable is not null, bind the current expression to variable. For example, a nested loops join would generate
 for (int i = 0; i < emps.length; i++) {
   Emp emp = emps[i];
   for (int j = 0; j < depts.length; j++) {
     Dept dept = depts[j];
     if (emp.deptno == dept.deptno) {
       <>
     }
   }
 }
 
which corresponds to
 [emp:iter
   [dept:iter
     [join:body(emp,dept)
       [parent:body]
     ]
   ]
 ]
 

Parameters:
rel - child relation
stmtList - block that child was generating its code into

bindDeferred

private void bindDeferred(JavaRelImplementor.Frame frame,
                          RelNode rel)

visitJavaChild

public final Expression visitJavaChild(RelNode parent,
                                       int ordinal,
                                       JavaRel child)
Convenience wrapper around RelImplementor.visitChild(org.eigenbase.rel.RelNode, int, org.eigenbase.rel.RelNode) for the common case where JavaRel has a child which is a JavaRel.


visitChild

public final Object visitChild(RelNode parent,
                               int ordinal,
                               RelNode child)
Description copied from interface: RelImplementor
Implements a relational expression according to a calling convention.

Specified by:
visitChild in interface RelImplementor
Parameters:
parent - Parent relational expression
ordinal - Ordinal of child within its parent
child - Child relational expression
Returns:
Interpretation of the return value is left to the implementor

createFrame

protected void createFrame(RelNode parent,
                           int ordinal,
                           RelNode child)

visitChildInternal

public Object visitChildInternal(RelNode child)
Description copied from interface: RelImplementor
Called from RelImplementor.visitChild(org.eigenbase.rel.RelNode, int, org.eigenbase.rel.RelNode) after the frame has been set up. Specific implementors should override this method.

Specified by:
visitChildInternal in interface RelImplementor
Parameters:
child - Child relational expression
Returns:
Interpretation of the return value is left to the implementor

visitChildInternal

public Object visitChildInternal(RelNode child,
                                 int ordinal)
Description copied from interface: RelImplementor
Called from RelImplementor.visitChild(org.eigenbase.rel.RelNode, int, org.eigenbase.rel.RelNode) after the frame has been set up. Specific implementors should override this method.

Specified by:
visitChildInternal in interface RelImplementor
Parameters:
child - Child relational expression
ordinal - Ordinal of child within its parent
Returns:
Interpretation of the return value is left to the implementor

implementRoot

public Expression implementRoot(JavaRel rel)
Starts an iteration, by calling JavaRel.implement(org.eigenbase.oj.rel.JavaRelImplementor) on the root element.


makeReference

public Expression makeReference(String correlName,
                                RelNode rel)
Creates an expression which references correlating variable correlName from the context of rel. For example, if correlName is set by the 1st child of rel's 2nd child, then this method returns $input2.$input1.


newVariable

public Variable newVariable()
Generates a variable with a unique name.


newVariable

public Variable newVariable(String base)
Generates a variable with a unique name and a stem which indicates its purpose. For example, newVariable("binding") might generate a variable called "binding_12".


generateVariableId

public int generateVariableId()
Returns:
unique generated variable ID

getConnectionVariable

public Variable getConnectionVariable()

popStatementList

public void popStatementList(StatementList stmtList)

pushStatementList

public void pushStatementList(StatementList stmtList)

translate

public Expression translate(JavaRel rel,
                            RexNode exp)
Converts an expression in internal form (the input relation is referenced using the variable $input0) to generated form (the input relation is referenced using the bindings in this JavaRelImplementor). Compare this method with net.sf.saffron.oj.xlat.QueryInfo.convertExpToInternal(), which converts from source form to internal form.

Parameters:
exp - the expression to translate (it is cloned, not modified)
rel - the relational expression which is the context for exp

canTranslate

public boolean canTranslate(RelNode rel,
                            RexProgram program)
Determines whether it is possible to implement a set of expressions in Java.

Parameters:
program - Program to translate
Returns:
whether all expressions in the program can be implemented

canTranslate

public boolean canTranslate(RelNode rel,
                            RexNode expression,
                            boolean deep)
Determines whether it is possible to implement an expression in Java.

Parameters:
rel - Relational expression
expression - Expression
deep - if true, operands of the given expression are tested for translatability as well; if false only the top level expression is tested
Returns:
whether the expression can be implemented

translateViaStatements

public Expression translateViaStatements(JavaRel rel,
                                         RexNode exp,
                                         StatementList stmtList,
                                         MemberDeclarationList memberList)
Generates code for an expression, possibly using multiple statements, scratch variables, and helper functions.

If you want to avoid generating common expressions, it is better to create a translator using newStmtTranslator(JavaRel, StatementList, MemberDeclarationList) and use it to translate multiple expressions.

Parameters:
rel - the relational expression which is the context for exp
exp - the row expression to be translated
stmtList - optional code can be appended here
memberList - optional member declarations can be appended here (if needed for reusable scratch space or helper functions; local variables can also be allocated in stmtList)

translateList

public ExpressionList translateList(JavaRel rel,
                                    RexNode[] exps)
Converts an array of expressions in internal into a list of expressions in generated form.

See Also:
translate(JavaRel,RexNode)

newTranslator

protected RexToOJTranslator newTranslator(RelNode rel)
Creates a RexToOJTranslator with which to translate the row-expressions within a relational expression into OpenJava expressions.


newStmtTranslator

public RexToOJTranslator newStmtTranslator(JavaRel rel,
                                           StatementList stmtList,
                                           MemberDeclarationList memberList)
Creates a translator which can translate a succession of expressions, possibly using multiple statements, scratch variables, and helper functions.

Typical usage:

 Translator translator = newStmtTranslator(rel, stmtList, memberList);
 translator.translateRexNode(exp1);
 translator.translateRexNode(exp2);
 

Parameters:
rel - the relational expression which is the context for exp
stmtList - optional code can be appended here
memberList - optional member declarations can be appended here (if needed for reusable scratch space or helper functions; local variables

translateInput

public Expression translateInput(JavaRel rel,
                                 int ordinal)
Creates an expression which references the ordinalth input.


computeFieldOffset

private int computeFieldOffset(RelNode rel,
                               int ordinal)
Returns the index of the first field in rel which comes from its ordinalth input.

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.


translateInputField

public Expression translateInputField(JavaRel rel,
                                      int ordinal,
                                      int fieldOrdinal)
Creates an expression which references the fieldOrdinalth field of the ordinalth input.

(We can potentially optimize the generation process, so we can access field values without actually instantiating the row.)


bind

private void bind(RelNode rel,
                  JavaRelImplementor.Bind bind)
Records the fact that instances of rel are available via bind (which may be eager or lazy).


findInputRel

private RelNode findInputRel(RelNode rel,
                             int offset)

findInputRel

private RelNode findInputRel(RelNode rel,
                             int offset,
                             int[] offsets)

findInputVariable

public Variable findInputVariable(RelNode rel)
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.


implementStart

public Expression implementStart(AggregateCall call,
                                 JavaRel rel)

implementStartAndNext

public Expression implementStartAndNext(AggregateCall call,
                                        JavaRel rel)

implementNext

public void implementNext(AggregateCall call,
                          JavaRel rel,
                          Expression accumulator)

implementResult

public Expression implementResult(AggregateCall call,
                                  Expression accumulator)
Generates the expression to retrieve the result of this aggregation.


getAncestorRels

public List<RelNode> getAncestorRels(RelNode rel)
Returns a list of the relational expressions which are ancestors of the current one.

"Precondition:"
// rel must be on the implementation stack