diff options
Diffstat (limited to 'exec/java-exec/src/main/codegen/templates/Decimal/CastIntDecimal.java')
-rw-r--r-- | exec/java-exec/src/main/codegen/templates/Decimal/CastIntDecimal.java | 100 |
1 files changed, 28 insertions, 72 deletions
diff --git a/exec/java-exec/src/main/codegen/templates/Decimal/CastIntDecimal.java b/exec/java-exec/src/main/codegen/templates/Decimal/CastIntDecimal.java index 15304daf5..162c5629e 100644 --- a/exec/java-exec/src/main/codegen/templates/Decimal/CastIntDecimal.java +++ b/exec/java-exec/src/main/codegen/templates/Decimal/CastIntDecimal.java @@ -48,79 +48,35 @@ import java.nio.ByteBuffer; @SuppressWarnings("unused") @FunctionTemplate(name = "cast${type.to?upper_case}", - scope = FunctionTemplate.FunctionScope.SIMPLE, - returnType = FunctionTemplate.ReturnType.DECIMAL_CAST, - nulls = NullHandling.NULL_IF_NULL) + scope = FunctionTemplate.FunctionScope.SIMPLE, + returnType = FunctionTemplate.ReturnType.DECIMAL_CAST, + nulls = NullHandling.NULL_IF_NULL) public class Cast${type.from}${type.to} implements DrillSimpleFunc { - - @Param ${type.from}Holder in; - <#if type.to.startsWith("Decimal28") || type.to.startsWith("Decimal38") || type.to.endsWith("VarDecimal")> - @Inject DrillBuf buffer; - </#if> - @Param BigIntHolder precision; - @Param BigIntHolder scale; - @Output ${type.to}Holder out; - - public void setup() { - <#if type.to.startsWith("Decimal28") || type.to.startsWith("Decimal38")> - int size = ${type.arraySize} * (org.apache.drill.exec.util.DecimalUtility.INTEGER_SIZE); - buffer = buffer.reallocIfNeeded(size); - </#if> - - } - - public void eval() { - out.scale = (int) scale.value; - - <#if !type.to.endsWith("VarDecimal")> - out.precision = (int) precision.value; - </#if> - - <#if type.to.endsWith("VarDecimal")> - out.start = 0; - out.buffer = buffer; - StringBuilder sb = new StringBuilder(); - sb.append(Long.toString((long)in.value)); - for (int i = 0; i < out.scale; ++i) { // add 0's to get unscaled integer - sb.append("0"); - } - java.math.BigInteger bi = new java.math.BigInteger(sb.toString()); - java.math.BigDecimal bd = new java.math.BigDecimal(bi, out.scale); - int len = org.apache.drill.exec.util.DecimalUtility.getVarDecimalFromBigDecimal(bd, out.buffer, out.start); - out.end = out.start + len; - <#elseif type.to == "Decimal9" || type.to == "Decimal18"> - out.value = (${type.javatype}) in.value; - - // converting from integer to decimal, pad zeroes if scale is non zero - out.value = (${type.javatype}) org.apache.drill.exec.util.DecimalUtility.adjustScaleMultiply(out.value, (int) scale.value); - - <#else> - - out.start = 0; - out.buffer = buffer; - - // Initialize the buffer - for (int i = 0; i < ${type.arraySize}; i++) { - out.setInteger(i, 0, out.start, out.buffer); - } - - // check if input is a negative number and store the sign - if (in.value < 0) { - out.setSign(true, out.start, out.buffer); - } - - // Figure out how many array positions to be left for the scale part - int scaleSize = org.apache.drill.exec.util.DecimalUtility.roundUp((int) scale.value); - int integerIndex = (${type.arraySize} - scaleSize - 1); - - long inValue = in.value; - while (inValue != 0 && integerIndex >= 0) { - out.setInteger(integerIndex--, (int) Math.abs((inValue % org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE)), out.start, out.buffer); - inValue = inValue / org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE; - } - - </#if> - } + @Param ${type.from}Holder in; + @Inject DrillBuf buffer; + @Param IntHolder precision; + @Param IntHolder scale; + @Output ${type.to}Holder out; + + public void setup() { + } + + public void eval() { + out.scale = scale.value; + out.precision = precision.value; + + out.start = 0; + out.buffer = buffer; + java.math.BigDecimal bd = new java.math.BigDecimal(in.value, + new java.math.MathContext(precision.value, java.math.RoundingMode.HALF_UP)) + .setScale(out.scale, java.math.BigDecimal.ROUND_DOWN); + + byte[] bytes = bd.unscaledValue().toByteArray(); + int len = bytes.length; + out.buffer = out.buffer.reallocIfNeeded(len); + out.buffer.setBytes(out.start, bytes); + out.end = out.start + len; + } } </#if> <#-- type.major --> </#list> |