Class ReduceDecimalsRule.RexExpander
- java.lang.Object
-
- org.apache.calcite.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 java.lang.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 toBigDecimal.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
Fields Modifier and Type Field Description (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
Constructors Constructor Description RexExpander(RexBuilder builder)
Constructs a RexExpander
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description 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 representationprotected 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(java.math.BigDecimal bd)
Makes an approximate literal of double precisionprotected RexNode
makeApproxScaleFactor(int scale)
Makes an approximate literal to be used for scalingprotected 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 typeprotected 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 scalingprotected long
powerOfTen(int scale)
Calculates a power of ten, as a long valueprotected 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.
-
-
-
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
-
RexExpander
public 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(java.math.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 decimalscale
- 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 conventionBigDecimal.ROUND_HALF_UP
. (Values midway between two points are rounded away from zero.)- Parameters:
value
- the integer representation of a decimalscale
- 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 decimalscale
- a value from zero to max 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 numberscale
- current scale, 0 for floating point numbersrequired
- 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 decimaldecimalType
- 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 decimaldecimalType
- type integer will be reinterpreted ascheckOverflow
- 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 typenode
- 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 typenode
- expressionmatchNullability
- 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
-
makeCase
protected RexNode makeCase(RexNode whenA, RexNode thenA, RexNode whenB, RexNode thenB, RexNode elseClause)
-
-