Class ReduceDecimalsRule.RexExpander

java.lang.Object
org.apache.calcite.rel.rules.ReduceDecimalsRule.RexExpander
Enclosing class:
ReduceDecimalsRule

public abstract static 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 decimal(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.

  • Method Details

    • 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 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
    • 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)