net.sf.farrago.ojrex
Class FarragoOJRexCastImplementor.CastHelper

java.lang.Object
  extended by net.sf.farrago.ojrex.FarragoOJRexCastImplementor.CastHelper
Enclosing class:
FarragoOJRexCastImplementor

private class FarragoOJRexCastImplementor.CastHelper
extends Object

Helps to implement the CAST operator for a specific cast node.


Field Summary
private  OJClass lhsClass
           
private  Expression lhsExp
           
private  RelDataType lhsType
           
private  Expression rhsExp
           
private  RelDataType rhsType
           
private  StatementList stmtList
           
private  String targetName
           
private  FarragoRexToOJTranslator translator
           
 
Constructor Summary
FarragoOJRexCastImplementor.CastHelper(FarragoRexToOJTranslator translator, StatementList stmtList, String targetName, RelDataType lhsType, RelDataType rhsType, Expression lhsExp, Expression rhsExp)
          Constructs a new CastHelper
 
Method Summary
private  void addStatement(Statement stmt)
          Adds the statement to the statement list if it is not null.
private  void addStatementList(StatementList list)
          Adds a list of statements according to addStatement(Statement)
private  ExpressionStatement assign(Expression a, Expression b)
          Creates a simple assignment statement as in a = b.
private  StatementList borrowStmtList(StatementList newList)
          Borrows the active statement list, by temporarily setting it to a new statement list.
private  Expression castFromNull()
          Implements a cast from NULL.
private  Expression castPrimitiveToNullablePrimitive()
          Implements a cast from any Java primitive to a nullable Java primitive as a simple assignment.
private  Expression castToAssignableValue()
          Casts the rhs to an AssignableValue using that interface's standard assignment method.
private  Expression castToAssignableValueImpl()
           
private  Expression castToNotNullPrimitive()
          Casts the rhs to a non nullable primitive value.
private  void checkNotNull()
          Generates code to throw an exception when a NULL value is casted to a NOT NULL type
private  void checkOverflow()
          Checks for overflow when assigning one primitive type to another.
private  VariableDeclaration declareStackVar(OJClass clazz, Variable var, Expression init)
          Makes a statement to declare a stack variable
private  void ensureLhs()
          Creates a left hand side variable if one was not provided.
private  OJClass getClass(RelDataType type)
          Gets the OJ class for a RelDataType
private  Expression getCurrentDate()
          Gets an expression for the current date
private  Expression getDirectAssignment()
          Directly assigns the right hand side to to an lhs variable and returns the lhs variable.
private  OJClass getLhsClass()
          Gets the OJ class for the left hand side (target) type
private  FieldAccess getNullIndicator(Expression expr)
          Creates a field access, as in expr.[nullIndicator]
private  Expression getValue(RelDataType type, Expression expr)
          Creates a field access, as in expr.[value]
 Expression implement()
          Implement the cast expression.
private  Expression minus(OJClass clazz, Expression expr)
          Creates a unary minus, as in -expr.
private  Expression not(Expression a)
          Creates a not expression as in !a.
private  boolean requiresSpecializedCast()
           
private  void returnStmtList(StatementList oldList)
          Restores the active statement list.
private  Expression rhsAsJava()
          Gets the right hand expression as a simple Java value.
private  Expression rhsAsValue()
          Gets the right hand expression as a valid value to be assigned to the left hand side.
private  Expression round(OJClass clazz, Expression expr, boolean isLong)
          Generates code to round an expression up and cast it.
private  void roundAsNeeded()
          Rounds right hand side, if required.
private  Expression roundAway()
          Generates code to round an expression according to the Farrago convention.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

translator

private FarragoRexToOJTranslator translator

stmtList

private StatementList stmtList

targetName

private String targetName

lhsType

private RelDataType lhsType

rhsType

private RelDataType rhsType

lhsExp

private Expression lhsExp

rhsExp

private Expression rhsExp

lhsClass

private OJClass lhsClass
Constructor Detail

FarragoOJRexCastImplementor.CastHelper

public FarragoOJRexCastImplementor.CastHelper(FarragoRexToOJTranslator translator,
                                              StatementList stmtList,
                                              String targetName,
                                              RelDataType lhsType,
                                              RelDataType rhsType,
                                              Expression lhsExp,
                                              Expression rhsExp)
Constructs a new CastHelper

Parameters:
translator - translator for implementing Rex as Java code
stmtList - statement list in which to insert statements
targetName - the name of the target column or expression
lhsType - the left hand side type
rhsType - the right hand side type
lhsExp - the left hand side expression
rhsExp - the right hand side expression
Method Detail

implement

public Expression implement()
Implement the cast expression.

TODO: check for overflow

Returns:
the rhs expression casted as the lhs type

checkNotNull

private void checkNotNull()
Generates code to throw an exception when a NULL value is casted to a NOT NULL type


rhsAsJava

private Expression rhsAsJava()
Gets the right hand expression as a simple Java value. If the rhs is a more complex expression, then creates a scratch variable and assigns the right hand expression to it. Then returns the scratch variable.


rhsAsValue

private Expression rhsAsValue()
Gets the right hand expression as a valid value to be assigned to the left hand side. Usually returns the original rhs. However, if the lhs is of a primitive type, and the rhs is an explicit null, returns a primitive value instead.


castFromNull

private Expression castFromNull()
Implements a cast from NULL. Creates a scratch variable if one was not provided and assigns NULL to it.


castPrimitiveToNullablePrimitive

private Expression castPrimitiveToNullablePrimitive()
Implements a cast from any Java primitive to a nullable Java primitive as a simple assignment. i.e.
 [NullablePrimitiveType] lhs;
 lhs.[nullIndicator] = ...;
 if (! lhs.[nullIndicator]) {
     // check overflow ...
     // round ...
     lhs.[value] = ...;
 }
 


castToAssignableValue

private Expression castToAssignableValue()
Casts the rhs to an AssignableValue using that interface's standard assignment method. i.e.
 [AssignableValueType] lhs;
 lhs.[assignMethod](rhs);
 
or perhaps a type-specific cast:
 [AssignableValueType] lhs;
 lhs.[castMethod](rhs, lhs.getPrecision());
 

Code is also generated to pad and truncate values which need special handling, such as date and time types. Plus good old null handling.


requiresSpecializedCast

private boolean requiresSpecializedCast()

castToAssignableValueImpl

private Expression castToAssignableValueImpl()

castToNotNullPrimitive

private Expression castToNotNullPrimitive()
Casts the rhs to a non nullable primitive value. Non nullable primitive values only have a single value field.


getDirectAssignment

private Expression getDirectAssignment()
Directly assigns the right hand side to to an lhs variable and returns the lhs variable. If no variable was provided, returns the original rhs.


checkOverflow

private void checkOverflow()
Checks for overflow when assigning one primitive type to another. Non-primitive types check for overflow during assignment.


ensureLhs

private void ensureLhs()
Creates a left hand side variable if one was not provided.


getLhsClass

private OJClass getLhsClass()
Gets the OJ class for the left hand side (target) type


getClass

private OJClass getClass(RelDataType type)
Gets the OJ class for a RelDataType


addStatement

private void addStatement(Statement stmt)
Adds the statement to the statement list if it is not null. Otherwise, adds the statement to the translator list.

Parameters:
stmt - the statement to be added

addStatementList

private void addStatementList(StatementList list)
Adds a list of statements according to addStatement(Statement)

Parameters:
list - list of statements to be added

borrowStmtList

private StatementList borrowStmtList(StatementList newList)
Borrows the active statement list, by temporarily setting it to a new statement list. What is borrowed must be returned!

Example:

 StatementList block = new StatementList();
 StatementList oldList = borrowStmtList(block);
 try {
     // add statements to block
 } finally {
     returnStmtList(oldList);
 }
 

Parameters:
newList - the new statement list
Returns:
the old statement list
See Also:
returnStmtList(StatementList)

returnStmtList

private void returnStmtList(StatementList oldList)
Restores the active statement list. Called after borrowing a statement list.

Parameters:
oldList - the previously active statement list.
See Also:
borrowStmtList(StatementList)

assign

private ExpressionStatement assign(Expression a,
                                   Expression b)
Creates a simple assignment statement as in a = b.


not

private Expression not(Expression a)
Creates a not expression as in !a.


getNullIndicator

private FieldAccess getNullIndicator(Expression expr)
Creates a field access, as in expr.[nullIndicator]


getValue

private Expression getValue(RelDataType type,
                            Expression expr)
Creates a field access, as in expr.[value]


roundAsNeeded

private void roundAsNeeded()
Rounds right hand side, if required. Rounding is required when casting from an approximate numeric to an exact numeric.


roundAway

private Expression roundAway()
Generates code to round an expression according to the Farrago convention. The Farrago convention is to round away from zero. Rounding is performed with the following algorithm.
 in = rhs;
 if (value < 0) {
     in = -in;
     out = Math.round(in);
     out = -out;
 } else {
     out = Math.round(in);
 }
 

PRECONDITION: rhsExp must be an unwrapped (not null) Java primitive

TODO: account for overflow in both unary minus and round.


minus

private Expression minus(OJClass clazz,
                         Expression expr)
Creates a unary minus, as in -expr. The type of the expression returned is the same type as the the original expression. This is required for situations such as byte:
 byte b;
 b = -b; // cannot cast int to byte
 
The unary minus operator returns an integer value. Note that unary minus potentially causes an overflow, because in most cases, |MIN_VALUE| > |MAX_VALUE| (ex. |-128| > |127| for byte)


round

private Expression round(OJClass clazz,
                         Expression expr,
                         boolean isLong)
Generates code to round an expression up and cast it. Performs a lenient rounding. Values less than target min or max become the min or max while, rounding (not a number) results in zero.

Parameters:
clazz - type to cast rounded expression as
expr - expression to be rounded
isLong - whether the result should have long precision

declareStackVar

private VariableDeclaration declareStackVar(OJClass clazz,
                                            Variable var,
                                            Expression init)
Makes a statement to declare a stack variable

Parameters:
clazz - OJ class of the variable to declare
var - the variable to be declared
init - initial value for the declaration.

getCurrentDate

private Expression getCurrentDate()
Gets an expression for the current date