org.eigenbase.rel.rules
Class ReduceDecimalsRule.RexExpander

java.lang.Object
  extended by org.eigenbase.rel.rules.ReduceDecimalsRule.RexExpander
Direct Known Subclasses:
ReduceDecimalsRule.BinaryArithmeticExpander, ReduceDecimalsRule.CaseExpander, ReduceDecimalsRule.CastArgAsTypeExpander, ReduceDecimalsRule.CastExpander, ReduceDecimalsRule.CeilExpander, ReduceDecimalsRule.FloorExpander, ReduceDecimalsRule.PassThroughExpander, ReduceDecimalsRule.ReinterpretExpander
Enclosing class:
ReduceDecimalsRule

public abstract class ReduceDecimalsRule.RexExpander
extends Object

Rewrites a decimal expression for a specific set of SqlOperator's. In general, most expressions are rewritten in such a way that SqlOperator's do not have to deal with decimals. Decimals are represented by their unscaled integer representations, similar to BigDecimal.unscaledValue() (i.e. 10^scale). Once decimals are decoded, SqlOperators can then operate on the integer representations. The value can later be recoded as a decimal.

For example, suppose one casts 2.0 as a decima(10,4). The value is decoded (20), multiplied by a scale factor (1000), for a result of (20000) which is encoded as a decimal(10,4), in this case 2.0000

To avoid the lengthy coding of RexNode expressions, this base class provides succinct methods for building expressions used in rewrites.


Field Summary
(package private)  RexBuilder builder
          Factory for constructing new relational expressions
(package private)  RelDataType int8
          Type for the internal representation of decimals.
(package private)  RelDataType real8
          Type for doubles.
 
Constructor Summary
ReduceDecimalsRule.RexExpander(RexBuilder builder)
          Constructs a RexExpander
 
Method Summary
protected  RexNode accessValue(RexNode node)
          Retrieves the primitive value of a numeric node.
 boolean canExpand(RexCall call)
          This defaults to the utility method, RexUtil.requiresDecimalExpansion(RexNode, boolean) which checks general guidelines on whether a rewrite should be considered at all.
protected  RexNode decodeValue(RexNode decimalNode)
          Retrieves a decimal node's integer representation
protected  RexNode encodeValue(RexNode value, RelDataType decimalType)
          Casts a decimal's integer representation to a decimal node.
protected  RexNode encodeValue(RexNode value, RelDataType decimalType, boolean checkOverflow)
          Casts a decimal's integer representation to a decimal node.
protected  RexNode ensureScale(RexNode value, int scale, int required)
          Ensures a value is of a required scale.
protected  RexNode ensureType(RelDataType type, RexNode node)
          Ensures expression is interpreted as a specified type.
protected  RexNode ensureType(RelDataType type, RexNode node, boolean matchNullability)
          Ensures expression is interpreted as a specified type.
abstract  RexNode expand(RexCall call)
          Rewrites an expression containing decimals.
protected  RexNode makeApproxLiteral(BigDecimal bd)
          Makes an approximate literal of double precision
protected  RexNode makeApproxScaleFactor(int scale)
          Makes an approximate literal to be used for scaling
protected  RexNode makeCase(RexNode condition, RexNode thenClause, RexNode elseClause)
           
protected  RexNode makeCase(RexNode whenA, RexNode thenA, RexNode whenB, RexNode thenB, RexNode elseClause)
           
protected  RexNode makeDivide(RexNode a, RexNode b)
           
protected  RexNode makeExactLiteral(long l)
          Makes an exact, non-nullable literal of Bigint type
protected  RexNode makeIsNegative(RexNode a)
           
protected  RexNode makeIsPositive(RexNode a)
           
protected  RexNode makeMinus(RexNode a, RexNode b)
           
protected  RexNode makeMultiply(RexNode a, RexNode b)
           
protected  RexNode makePlus(RexNode a, RexNode b)
           
protected  RexNode makeRoundFactor(int scale)
          Makes an exact numeric value to be used for rounding.
protected  RexNode makeScaleFactor(int scale)
          Makes an exact numeric literal to be used for scaling
protected  RelDataType matchNullability(RelDataType type, RexNode value)
          Ensure's type's nullability matches a value's nullability
protected  long powerOfTen(int scale)
          Calculates a power of ten, as a long value
protected  RexNode scaleDown(RexNode value, int scale)
          Scales down a decimal value, and returns the scaled value as an exact numeric.
protected  RexNode scaleDownDouble(RexNode value, int scale)
          Scales down a decimal value and returns the scaled value as a an double precision approximate value.
protected  RexNode scaleUp(RexNode value, int scale)
          Scales up a decimal value and returns the scaled value as an exact number.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

builder

RexBuilder builder
Factory for constructing new relational expressions


int8

RelDataType int8
Type for the internal representation of decimals. This type is a non-nullable type and requires extra work to make it nullable.


real8

RelDataType real8
Type for doubles. This type is a non-nullable type and requires extra work to make it nullable.

Constructor Detail

ReduceDecimalsRule.RexExpander

public ReduceDecimalsRule.RexExpander(RexBuilder builder)
Constructs a RexExpander

Method Detail

canExpand

public boolean canExpand(RexCall call)
This defaults to the utility method, RexUtil.requiresDecimalExpansion(RexNode, boolean) which checks general guidelines on whether a rewrite should be considered at all. In general, it is helpful to update the utility method since that method is often used to filter the somewhat expensive rewrite process.

However, this method provides another place for implementations of RexExpander to make a more detailed analysis before deciding on whether to perform a rewrite.


expand

public abstract RexNode expand(RexCall call)
Rewrites an expression containing decimals. Normally, this method always performs a rewrite, but implementations may choose to return the original expression if no change was required.


makeScaleFactor

protected RexNode makeScaleFactor(int scale)
Makes an exact numeric literal to be used for scaling

Parameters:
scale - a scale from one to max precision - 1
Returns:
10^scale as an exact numeric value

makeApproxScaleFactor

protected RexNode makeApproxScaleFactor(int scale)
Makes an approximate literal to be used for scaling

Parameters:
scale - a scale from -99 to 99
Returns:
10^scale as an approximate value

makeRoundFactor

protected RexNode makeRoundFactor(int scale)
Makes an exact numeric value to be used for rounding.

Parameters:
scale - a scale from 1 to max precision - 1
Returns:
10^scale / 2 as an exact numeric value

powerOfTen

protected long powerOfTen(int scale)
Calculates a power of ten, as a long value


makeExactLiteral

protected RexNode makeExactLiteral(long l)
Makes an exact, non-nullable literal of Bigint type


makeApproxLiteral

protected RexNode makeApproxLiteral(BigDecimal bd)
Makes an approximate literal of double precision


scaleUp

protected RexNode scaleUp(RexNode value,
                          int scale)
Scales up a decimal value and returns the scaled value as an exact number.

Parameters:
value - the integer representation of a decimal
scale - a value from zero to max precision - 1
Returns:
value * 10^scale as an exact numeric value

scaleDown

protected RexNode scaleDown(RexNode value,
                            int scale)
Scales down a decimal value, and returns the scaled value as an exact numeric. with the rounding convention BigDecimal.ROUND_HALF_UP. (Values midway between two points are rounded away from zero.)

Parameters:
value - the integer representation of a decimal
scale - a value from zero to max precision
Returns:
value/10^scale, rounded away from zero and returned as an exact numeric value

scaleDownDouble

protected RexNode scaleDownDouble(RexNode value,
                                  int scale)
Scales down a decimal value and returns the scaled value as a an double precision approximate value. Scaling is implemented with double precision arithmetic.

Parameters:
value - the integer representation of a decimal
scale - a value from zero to MAX_NUMERIC_PRECISION
Returns:
value/10^scale as a double precision value

ensureScale

protected RexNode ensureScale(RexNode value,
                              int scale,
                              int required)
Ensures a value is of a required scale. If it is not, then the value is multiplied by a scale factor. Scaling up an exact value is limited to max precision - 1, because we cannot represent the result of larger scales internally. Scaling up a floating point value is more flexible since the value may be very small despite having a scale of zero and the scaling may still produce a reasonable result

Parameters:
value - integer representation of decimal, or a floating point number
scale - current scale, 0 for floating point numbers
required - required scale, must be at least the current scale; the scale difference may not be greater than max precision - 1 for exact numerics
Returns:
value * 10^scale, returned as an exact or approximate value corresponding to the input value

decodeValue

protected RexNode decodeValue(RexNode decimalNode)
Retrieves a decimal node's integer representation

Parameters:
decimalNode - the decimal value as an opaque type
Returns:
an integer representation of the decimal value

accessValue

protected RexNode accessValue(RexNode node)
Retrieves the primitive value of a numeric node. If the node is a decimal, then it must first be decoded. Otherwise the original node may be returned.

Parameters:
node - a numeric node, possibly a decimal
Returns:
the primitive value of the numeric node

encodeValue

protected RexNode encodeValue(RexNode value,
                              RelDataType decimalType)
Casts a decimal's integer representation to a decimal node. If the expression is not the expected integer type, then it is casted first.

This method does not request an overflow check.

Parameters:
value - integer representation of decimal
decimalType - type integer will be reinterpreted as
Returns:
the integer representation reinterpreted as a decimal type

encodeValue

protected RexNode encodeValue(RexNode value,
                              RelDataType decimalType,
                              boolean checkOverflow)
Casts a decimal's integer representation to a decimal node. If the expression is not the expected integer type, then it is casted first.

An overflow check may be requested to ensure the internal value does not exceed the maximum value of the decimal type.

Parameters:
value - integer representation of decimal
decimalType - type integer will be reinterpreted as
checkOverflow - indicates whether an overflow check is required when reinterpreting this particular value as the decimal type. A check usually not required for arithmetic, but is often required for rounding and explicit casts.
Returns:
the integer reinterpreted as an opaque decimal type

ensureType

protected RexNode ensureType(RelDataType type,
                             RexNode node)
Ensures expression is interpreted as a specified type. The returned expression may be wrapped with a cast.

This method corrects the nullability of the specified type to match the nullability of the expression.

Parameters:
type - desired type
node - expression
Returns:
a casted expression or the original expression

ensureType

protected RexNode ensureType(RelDataType type,
                             RexNode node,
                             boolean matchNullability)
Ensures expression is interpreted as a specified type. The returned expression may be wrapped with a cast.

Parameters:
type - desired type
node - expression
matchNullability - whether to correct nullability of specified type to match the expression; this usually should be true, except for explicit casts which can override default nullability
Returns:
a casted expression or the original expression

matchNullability

protected RelDataType matchNullability(RelDataType type,
                                       RexNode value)
Ensure's type's nullability matches a value's nullability


makeCase

protected RexNode makeCase(RexNode condition,
                           RexNode thenClause,
                           RexNode elseClause)

makeCase

protected RexNode makeCase(RexNode whenA,
                           RexNode thenA,
                           RexNode whenB,
                           RexNode thenB,
                           RexNode elseClause)

makePlus

protected RexNode makePlus(RexNode a,
                           RexNode b)

makeMinus

protected RexNode makeMinus(RexNode a,
                            RexNode b)

makeDivide

protected RexNode makeDivide(RexNode a,
                             RexNode b)

makeMultiply

protected RexNode makeMultiply(RexNode a,
                               RexNode b)

makeIsPositive

protected RexNode makeIsPositive(RexNode a)

makeIsNegative

protected RexNode makeIsNegative(RexNode a)