net.sf.farrago.fennel.calc
Class RexToCalcTranslator

java.lang.Object
  extended by net.sf.farrago.fennel.calc.RexToCalcTranslator
All Implemented Interfaces:
RexVisitor<CalcReg>

public class RexToCalcTranslator
extends Object
implements RexVisitor<CalcReg>

Converts expressions in logical format (RexNode) into calculator assembly-language programs.

Since:
Mar 25, 2008
Version:
$Id: //open/dev/farrago/src/net/sf/farrago/fennel/calc/RexToCalcTranslator.java#2 $
Author:
Wael Chatila
See Also:
RexToCalcTranslator

Nested Class Summary
 class RexToCalcTranslator.ExpressionScope
          Supports scoping rules for calculator programs.
private static class RexToCalcTranslator.TranslationException
          Trivial exception thrown when RexToCalcTranslator.TranslationTester finds a node it cannot translate.
private  class RexToCalcTranslator.TranslationTester
          Visitor which walks over a row expression and throws RexToCalcTranslator.TranslationException if it finds a node which cannot be implemented.
 
Field Summary
private  AggOp aggOp
          Aggregate operation (add, drop) currently being implemented.
(package private)  CalcProgramBuilder builder
           
protected  boolean generateShortCircuit
          Whether the code generator should short-circuit logical operators.
protected  CalcRexImplementorTable implementorTable
           
(package private)  Set<RexNode> inProgressNodeSet
          List of expressions which are currently being implemented.
private  List<Pair<RelDataType,CalcProgramBuilder.OpType>> knownTypes
          Ordered mapping from types (representing a family of types) to the corresponding calculator type.
protected  int labelOrdinal
           
private  Map<String,CalcReg> namedTempRegisters
           
private  RexProgram program
          Program being translated.
private  RelNode rel
          The relational expression this program is being generated for.
protected  RexBuilder rexBuilder
           
private  RexToCalcTranslator.ExpressionScope scope
          Eliminates common-subexpressions, by mapping every expression (the key is generated from a RexNode using getKey(RexNode)) to the CalcReg which holds its value.
 
Constructor Summary
RexToCalcTranslator(RexBuilder rexBuilder, RelNode rel)
           
 
Method Summary
 boolean canTranslate(RexNode node, boolean deep)
          Returns whether an expression can be translated.
 boolean canTranslate(RexProgram program)
          Returns whether a program can be translated.
private  void clearProgram(RexProgram program)
           
(package private)  boolean containsResult(RexNode node)
          Returns whether a given expression has been implemented as a register.
private static List<Pair<RelDataType,CalcProgramBuilder.OpType>> createTypeMap(RelDataTypeFactory fac)
           
private  void fixOutputExps(List<RexNode> extInputs, int start, RexNode[] inputExps, RexNode[] aggs, RexNode[] outputExps, Map<String,RexNode> dups)
           
 String generateProgram(RelDataType inputRowType, RexProgram program)
          Translates an array of project expressions and an optional filter expression into a CalcProgramBuilder calculator program using a depth-first recursive algorithm.
 String getAggProgram(RexProgram program, AggOp aggOp)
          Translates an array of project expressions and an optional filter expression into a CalcProgramBuilder calculator program using a depth-first recursive algorithm when there are aggregate functions.
(package private)  CalcProgramBuilder.RegisterDescriptor getCalcRegisterDescriptor(RelDataType relDataType)
           
(package private)  CalcProgramBuilder.RegisterDescriptor getCalcRegisterDescriptor(RexNode node)
           
 String getKey(RexNode node)
           
 RexLiteral getLiteral(RexNode expr)
           
 RelNode getRelNode()
          Returns the relational expression this program is being generated for.
(package private)  CalcReg getResult(RexNode node, boolean failIfNotFound)
          Returns the register which contains the result of evaluating the given expression.
protected  CalcReg getTempBoolRegister()
           
protected  CalcReg getTempInt4Register()
           
protected  CalcReg getTempRegister(String name, CalcProgramBuilder.OpType opType)
          Return a local variable named "name".
private  CalcReg implement(RexCall call)
           
private  CalcReg implement(RexCorrelVariable node)
           
private  CalcReg implement(RexFieldAccess node)
           
private  CalcReg implement(RexInputRef node)
           
private  CalcReg implement(RexLiteral node)
           
private  CalcReg implement(RexLocalRef node)
           
(package private)  void implementConversionIfNeeded(RexNode op1, RexNode op2, CalcReg[] regs, boolean keepVartypes)
          If conversion is needed between the two operands this function inserts a call to the calculator convert function and silently updates the result register of the operands as needed.
 CalcReg implementNode(RexNode node)
          Adds instructions to implement an expression to the program, and returns the register which returns the result.
 CalcReg implementNode(RexNode node, boolean useCache)
          Adds instructions to implement an expression to the program, and returns the register which returns the result.
private  CalcReg implementShortCircuit(RexCall call)
           
private static boolean isOctetString(RelDataType t)
           
private  boolean isStrCmp(RexCall call)
           
 String newLabel()
           
 void newScope()
          Creates a new expression scope
 void popScope()
          Pops the previous expression scope
 RexNode resolve(RexNode expr)
           
 void setGenerateComments(boolean outputComments)
           
 void setGenerateShortCircuit(boolean generateShortCircuit)
           
 CalcReg setResult(RexNode node, CalcReg register)
           
 CalcReg visitCall(RexCall call)
           
 CalcReg visitCorrelVariable(RexCorrelVariable correlVariable)
           
 CalcReg visitDynamicParam(RexDynamicParam dynamicParam)
           
 CalcReg visitFieldAccess(RexFieldAccess fieldAccess)
           
 CalcReg visitInputRef(RexInputRef inputRef)
           
 CalcReg visitLiteral(RexLiteral literal)
           
 CalcReg visitLocalRef(RexLocalRef localRef)
           
 CalcReg visitOver(RexOver over)
           
 CalcReg visitRangeRef(RexRangeRef rangeRef)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

builder

final CalcProgramBuilder builder

namedTempRegisters

private final Map<String,CalcReg> namedTempRegisters

implementorTable

protected final CalcRexImplementorTable implementorTable

scope

private RexToCalcTranslator.ExpressionScope scope
Eliminates common-subexpressions, by mapping every expression (the key is generated from a RexNode using getKey(RexNode)) to the CalcReg which holds its value.


rexBuilder

protected final RexBuilder rexBuilder

rel

private final RelNode rel
The relational expression this program is being generated for.


generateShortCircuit

protected boolean generateShortCircuit
Whether the code generator should short-circuit logical operators. The default value is false.


labelOrdinal

protected int labelOrdinal

knownTypes

private final List<Pair<RelDataType,CalcProgramBuilder.OpType>> knownTypes
Ordered mapping from types (representing a family of types) to the corresponding calculator type. The ordering ensures determinacy.


aggOp

private AggOp aggOp
Aggregate operation (add, drop) currently being implemented.


program

private RexProgram program
Program being translated.


inProgressNodeSet

final Set<RexNode> inProgressNodeSet
List of expressions which are currently being implemented.

Constructor Detail

RexToCalcTranslator

public RexToCalcTranslator(RexBuilder rexBuilder,
                           RelNode rel)
Method Detail

createTypeMap

private static List<Pair<RelDataType,CalcProgramBuilder.OpType>> createTypeMap(RelDataTypeFactory fac)

getRelNode

public RelNode getRelNode()
Returns the relational expression this program is being generated for.


clearProgram

private void clearProgram(RexProgram program)

newLabel

public String newLabel()

canTranslate

public boolean canTranslate(RexNode node,
                            boolean deep)
Returns whether an expression can be translated.

Parameters:
node - Expression
deep - Whether to check child expressions

canTranslate

public boolean canTranslate(RexProgram program)
Returns whether a program can be translated.


getCalcRegisterDescriptor

CalcProgramBuilder.RegisterDescriptor getCalcRegisterDescriptor(RexNode node)

getCalcRegisterDescriptor

CalcProgramBuilder.RegisterDescriptor getCalcRegisterDescriptor(RelDataType relDataType)

getKey

public String getKey(RexNode node)

setResult

public CalcReg setResult(RexNode node,
                         CalcReg register)

getResult

CalcReg getResult(RexNode node,
                  boolean failIfNotFound)
Returns the register which contains the result of evaluating the given expression.

If failIfNotFound, the node must already have been implemented.

To check whether the result exists, use containsResult(RexNode), or pass in failIfNotFound = false.


containsResult

boolean containsResult(RexNode node)
Returns whether a given expression has been implemented as a register.

See Also:
getResult(RexNode,boolean)

getTempRegister

protected CalcReg getTempRegister(String name,
                                  CalcProgramBuilder.OpType opType)
Return a local variable named "name". Create it using the specified type if it does not already exist.

Parameters:
name - name of variable
opType - Type of variable to create
Returns:
register named "name"

getTempBoolRegister

protected CalcReg getTempBoolRegister()

getTempInt4Register

protected CalcReg getTempInt4Register()

generateProgram

public String generateProgram(RelDataType inputRowType,
                              RexProgram program)
Translates an array of project expressions and an optional filter expression into a CalcProgramBuilder calculator program using a depth-first recursive algorithm.

This method is NOT stateless. TODO: Make method stateless -- so you can call this method several times with different inputs -- and therefore the translator is re-usable.

Parameters:
inputRowType - The type of the input row to the calculator. If inputRowType is not null, the program contains an input register for every field in the input row type; otherwise it contains inputs for only those fields used.
program - Program consisting of a set of common expressions, a list of expressions to project, and an optional condition. Must not be null, but the project list may be empty.

getAggProgram

public String getAggProgram(RexProgram program,
                            AggOp aggOp)
Translates an array of project expressions and an optional filter expression into a CalcProgramBuilder calculator program using a depth-first recursive algorithm when there are aggregate functions.

The aggregate expressions are represented by two RexProgram objects. The lower inputProgram computes the input expressions to the calculator; the upper aggProgram contains calls to aggregate functions. For example, the expressions

Aggs = {
    SUM(a + b),
    SUM(a + b + c),
    COUNT(a + b) * d
    SUM(a + b) + 4
 }
would be represented by the program
aggProgram = {
    exprs = {
       $0,         // a
       $1,         // b
       $2,         // c
       $3,         // d
       $0 + $1,    // a + b
       $4 + $2     // (a + b) + c
       SUM($4),    // SUM(a + b)
       SUM($5),    // SUM(a + b + c)
       COUNT($4),  // COUNT(a + b)
       $8 * $3     // COUNT(a + b) * d
       SUM($4),    // SUM(a + b)
       $10 + 4,    // SUM(a + b) + 4
    },
    projectRefs = {
       $6,         // SUM(a + b)
       $7,         // SUM(a + b + c)
       $9,         // COUNT(a + b) * d
       $11,        // SUM(a + b) + 4
    },
    conditionRef = null
 }

This method is NOT stateless. TODO: Make method stateless -- so you can call this method several times with different inputs -- and therefore the translator is re-usable.

Parameters:
program - Program, containing pre-expressions, aggregate expressions, post-expressions, and optionally a filter.
aggOp - Aggregate operation (Init, Add, InitAdd or Drop), must not be null.

fixOutputExps

private void fixOutputExps(List<RexNode> extInputs,
                           int start,
                           RexNode[] inputExps,
                           RexNode[] aggs,
                           RexNode[] outputExps,
                           Map<String,RexNode> dups)

implementNode

public CalcReg implementNode(RexNode node)
Adds instructions to implement an expression to the program, and returns the register which returns the result. If the expression has already been implemented, does not add more instructions, just returns the existing register.

Parameters:
node - Expression
Returns:
Register which holds the result of evaluating the expression, never null, and always equivalent to calling getResult(org.eigenbase.rex.RexNode, boolean).
"Postcondition:"
result != null, result == getResult(node)

implementNode

public CalcReg implementNode(RexNode node,
                             boolean useCache)
Adds instructions to implement an expression to the program, and returns the register which returns the result.

The useCache parmaeter controls whether to return the existing register if the expression has already been implemented.

Parameters:
node - Expression
useCache - Whether to look up the expression in the cache of already implemented expressions
Returns:
Register which holds the result of evaluating the expression, never null, and always equivalent to calling getResult(org.eigenbase.rex.RexNode, boolean).
"Postcondition:"
result != null, result == getResult(node)

visitInputRef

public CalcReg visitInputRef(RexInputRef inputRef)
Specified by:
visitInputRef in interface RexVisitor<CalcReg>

visitLocalRef

public CalcReg visitLocalRef(RexLocalRef localRef)
Specified by:
visitLocalRef in interface RexVisitor<CalcReg>

visitLiteral

public CalcReg visitLiteral(RexLiteral literal)
Specified by:
visitLiteral in interface RexVisitor<CalcReg>

visitCall

public CalcReg visitCall(RexCall call)
Specified by:
visitCall in interface RexVisitor<CalcReg>

visitOver

public CalcReg visitOver(RexOver over)
Specified by:
visitOver in interface RexVisitor<CalcReg>

visitCorrelVariable

public CalcReg visitCorrelVariable(RexCorrelVariable correlVariable)
Specified by:
visitCorrelVariable in interface RexVisitor<CalcReg>

visitDynamicParam

public CalcReg visitDynamicParam(RexDynamicParam dynamicParam)
Specified by:
visitDynamicParam in interface RexVisitor<CalcReg>

visitRangeRef

public CalcReg visitRangeRef(RexRangeRef rangeRef)
Specified by:
visitRangeRef in interface RexVisitor<CalcReg>

visitFieldAccess

public CalcReg visitFieldAccess(RexFieldAccess fieldAccess)
Specified by:
visitFieldAccess in interface RexVisitor<CalcReg>

implementShortCircuit

private CalcReg implementShortCircuit(RexCall call)

implement

private CalcReg implement(RexCall call)

isStrCmp

private boolean isStrCmp(RexCall call)

isOctetString

private static boolean isOctetString(RelDataType t)

implementConversionIfNeeded

void implementConversionIfNeeded(RexNode op1,
                                 RexNode op2,
                                 CalcReg[] regs,
                                 boolean keepVartypes)
If conversion is needed between the two operands this function inserts a call to the calculator convert function and silently updates the result register of the operands as needed. The new updated registers are returned in the regs array.

Parameters:
op1 - first operand
op2 - second operand
regs - at the time of calling this methods this array must contain the result registers of op1 and op2. The new updated registers are returned in the regs array.
keepVartypes - - indicates when choosing between VARCHAR and CHAR, to convert to VARCHAR or CHAR. If true, converts to VARCHAR.

implement

private CalcReg implement(RexLiteral node)

implement

private CalcReg implement(RexInputRef node)

implement

private CalcReg implement(RexLocalRef node)

implement

private CalcReg implement(RexFieldAccess node)

implement

private CalcReg implement(RexCorrelVariable node)

setGenerateShortCircuit

public void setGenerateShortCircuit(boolean generateShortCircuit)
Parameters:
generateShortCircuit - If true, tells the code generator to short circuit logical operators
The default valude is false

setGenerateComments

public void setGenerateComments(boolean outputComments)

getLiteral

public RexLiteral getLiteral(RexNode expr)

resolve

public RexNode resolve(RexNode expr)

newScope

public void newScope()
Creates a new expression scope


popScope

public void popScope()
Pops the previous expression scope