| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| import org.apache.drill.exec.expr.annotations.Workspace; |
| |
| <@pp.dropOutputFile /> |
| |
| <#-- TODO: Refactor comparison code from here into ComparisonFunctions (to |
| eliminate duplicate template code and so that ComparisonFunctions actually |
| as all comparison functions. --> |
| |
| <#macro compareNullsSubblock leftType rightType output breakTarget nullCompare nullComparesHigh> |
| <#if nullCompare> |
| <#if nullComparesHigh> |
| <#assign leftNullResult = 1> <#-- if only L is null and nulls are high, then "L > R" (1) --> |
| <#assign rightNullResult = -1> |
| <#else> |
| <#assign leftNullResult = -1> <#-- if only L is null and nulls are low, then "L < R" (-1) --> |
| <#assign rightNullResult = 1> |
| </#if> |
| |
| <#if leftType?starts_with("Nullable")> |
| <#if rightType?starts_with("Nullable")> |
| <#-- Both are nullable. --> |
| if ( left.isSet == 0 ) { |
| if ( right.isSet == 0 ) { |
| <#-- Both are null--result is "L = R". --> |
| ${output} = 0; |
| break ${breakTarget}; |
| } else { |
| <#-- Only left is null--result is "L < R" or "L > R" per null ordering. --> |
| ${output} = ${leftNullResult}; |
| break ${breakTarget}; |
| } |
| } else if ( right.isSet == 0 ) { |
| <#-- Only right is null--result is "L > R" or "L < R" per null ordering. --> |
| ${output} = ${rightNullResult}; |
| break ${breakTarget}; |
| } |
| <#else> |
| <#-- Left is nullable but right is not. --> |
| if ( left.isSet == 0 ) { |
| <#-- Only left is null--result is "L < R" or "L > R" per null ordering. --> |
| ${output} = ${leftNullResult}; |
| break ${breakTarget}; |
| } |
| </#if> |
| <#elseif rightType?starts_with("Nullable")> |
| <#-- Left is not nullable but right is. --> |
| if ( right.isSet == 0 ) { |
| <#-- Only right is null--result is "L > R" or "L < R" per null ordering. --> |
| ${output} = ${rightNullResult}; |
| break ${breakTarget}; |
| } |
| </#if> |
| </#if> |
| |
| </#macro> |
| |
| |
| <#macro compareBlock leftType rightType absCompare output nullCompare nullComparesHigh> |
| outside: |
| { |
| <@compareNullsSubblock leftType=leftType rightType=rightType output=output breakTarget="outside" nullCompare=nullCompare nullComparesHigh=nullComparesHigh /> |
| |
| ${output} = org.apache.drill.exec.util.DecimalUtility.compareSparseBytes(left.buffer, left.start, left.getSign(left.start, left.buffer), |
| left.scale, left.precision, right.buffer, |
| right.start, right.getSign(right.start, right.buffer), right.precision, |
| right.scale, left.WIDTH, left.nDecimalDigits, ${absCompare}); |
| |
| } // outside |
| </#macro> |
| |
| <#macro adjustScale javaType leftType rightType> |
| |
| // Adjust the scale of the two inputs to be the same |
| |
| if (left.scale < right.scale) { |
| left.value = (${javaType}) (org.apache.drill.exec.util.DecimalUtility.adjustScaleMultiply(left.value, (int) (right.scale - left.scale))); |
| left.scale = right.scale; |
| } else if (right.scale < left.scale) { |
| right.value = (${javaType}) (org.apache.drill.exec.util.DecimalUtility.adjustScaleMultiply(right.value, (int) (left.scale - right.scale))); |
| right.scale = left.scale; |
| } |
| </#macro> |
| |
| <#-- For each DECIMAL... type (in DecimalTypes.tdd) ... --> |
| <#list comparisonTypesDecimal.decimalTypes as type> |
| |
| <#if type.name.endsWith("Sparse")> |
| |
| <@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/${type.name}Functions.java" /> |
| |
| <#include "/@includes/license.ftl" /> |
| |
| package org.apache.drill.exec.expr.fn.impl; |
| |
| <#include "/@includes/vv_imports.ftl" /> |
| |
| import org.apache.drill.exec.expr.DrillSimpleFunc; |
| import org.apache.drill.exec.expr.annotations.FunctionTemplate; |
| import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling; |
| import org.apache.drill.exec.expr.annotations.Output; |
| import org.apache.drill.exec.expr.annotations.Param; |
| import org.apache.drill.exec.expr.annotations.Workspace; |
| import org.apache.drill.exec.expr.fn.FunctionGenerationHelper; |
| import org.apache.drill.exec.expr.holders.*; |
| import org.apache.drill.exec.record.RecordBatch; |
| |
| import io.netty.buffer.ByteBuf; |
| import io.netty.buffer.DrillBuf; |
| |
| import java.nio.ByteBuffer; |
| |
| @SuppressWarnings("unused") |
| public class ${type.name}Functions { |
| |
| @FunctionTemplate(name = "subtract", scope = FunctionTemplate.FunctionScope.DECIMAL_ADD_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}SubtractFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Inject DrillBuf buffer; |
| @Workspace int outputScale; |
| @Workspace int outputPrecision; |
| @Output ${type.name}Holder result; |
| |
| public void setup() { |
| int size = (${type.storage} * (org.apache.drill.exec.util.DecimalUtility.integerSize)); |
| buffer = buffer.reallocIfNeeded(size); |
| outputPrecision = Integer.MIN_VALUE; |
| } |
| |
| public void eval() { |
| if (outputPrecision == Integer.MIN_VALUE) { |
| org.apache.drill.common.util.DecimalScalePrecisionAddFunction resultScalePrec = |
| new org.apache.drill.common.util.DecimalScalePrecisionAddFunction((int) left.precision, (int) left.scale, (int) right.precision, (int) right.scale); |
| outputScale = resultScalePrec.getOutputScale(); |
| outputPrecision = resultScalePrec.getOutputPrecision(); |
| } |
| result.precision = outputPrecision; |
| result.scale = outputScale; |
| result.buffer = buffer; |
| result.start = 0; |
| |
| java.math.BigDecimal leftInput = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(left.buffer, left.start, left.nDecimalDigits, left.scale); |
| java.math.BigDecimal rightInput = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(right.buffer, right.start, right.nDecimalDigits, right.scale); |
| java.math.BigDecimal addResult = leftInput.subtract(rightInput); |
| |
| // Set the scale |
| addResult.setScale(result.scale, java.math.BigDecimal.ROUND_HALF_UP); |
| org.apache.drill.exec.util.DecimalUtility.getSparseFromBigDecimal(addResult, result.buffer, result.start, result.scale, result.precision, result.nDecimalDigits); |
| } |
| } |
| |
| @FunctionTemplate(name = "add", scope = FunctionTemplate.FunctionScope.DECIMAL_ADD_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}AddFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Workspace int outputScale; |
| @Workspace int outputPrecision; |
| @Inject DrillBuf buffer; |
| @Output ${type.name}Holder result; |
| |
| public void setup() { |
| int size = (${type.storage} * (org.apache.drill.exec.util.DecimalUtility.integerSize)); |
| buffer = buffer.reallocIfNeeded(size); |
| outputPrecision = Integer.MIN_VALUE; |
| } |
| |
| public void eval() { |
| if (outputPrecision == Integer.MIN_VALUE) { |
| org.apache.drill.common.util.DecimalScalePrecisionAddFunction resultScalePrec = |
| new org.apache.drill.common.util.DecimalScalePrecisionAddFunction((int) left.precision, (int) left.scale, (int) right.precision, (int) right.scale); |
| outputScale = resultScalePrec.getOutputScale(); |
| outputPrecision = resultScalePrec.getOutputPrecision(); |
| } |
| result.precision = outputPrecision; |
| result.scale = outputScale; |
| result.buffer = buffer; |
| result.start = 0; |
| |
| java.math.BigDecimal leftInput = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(left.buffer, left.start, left.nDecimalDigits, left.scale); |
| java.math.BigDecimal rightInput = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(right.buffer, right.start, right.nDecimalDigits, right.scale); |
| java.math.BigDecimal addResult = leftInput.add(rightInput); |
| |
| // Set the scale |
| addResult.setScale(result.scale, java.math.BigDecimal.ROUND_HALF_UP); |
| org.apache.drill.exec.util.DecimalUtility.getSparseFromBigDecimal(addResult, result.buffer, result.start, result.scale, result.precision, result.nDecimalDigits); |
| } |
| } |
| |
| @FunctionTemplate(name = "multiply", scope = FunctionTemplate.FunctionScope.DECIMAL_MUL_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}MultiplyFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Inject DrillBuf buffer; |
| @Workspace int[] tempResult; |
| @Workspace int outputScale; |
| @Workspace int outputPrecision; |
| @Output ${type.name}Holder result; |
| |
| public void setup() { |
| int size = (${type.storage} * (org.apache.drill.exec.util.DecimalUtility.integerSize)); |
| buffer = buffer.reallocIfNeeded(size); |
| tempResult = new int[${type.storage} * ${type.storage}]; |
| outputPrecision = Integer.MIN_VALUE; |
| } |
| |
| public void eval() { |
| if (outputPrecision == Integer.MIN_VALUE) { |
| org.apache.drill.common.util.DecimalScalePrecisionMulFunction resultScalePrec = |
| new org.apache.drill.common.util.DecimalScalePrecisionMulFunction((int) left.precision, (int) left.scale, (int) right.precision, (int) right.scale); |
| outputScale = resultScalePrec.getOutputScale(); |
| outputPrecision = resultScalePrec.getOutputPrecision(); |
| } |
| // Set the scale and precision |
| result.scale = outputScale; |
| result.precision = outputPrecision; |
| result.buffer = buffer; |
| result.start = 0; |
| |
| // Re initialize the temporary array |
| for (int i = 0; i < ${type.storage} * ${type.storage}; i++) { |
| tempResult[i] = 0; |
| } |
| |
| // Remove the leading zeroes from the integer part of the input |
| int leftIndex = 0; |
| int leftStopIndex = left.nDecimalDigits - org.apache.drill.exec.util.DecimalUtility.roundUp(left.scale); |
| |
| while (leftIndex < leftStopIndex) { |
| if (left.getInteger(leftIndex, left.start, left.buffer) > 0) |
| break; |
| leftIndex++; |
| } |
| |
| int leftIntegerSize = leftStopIndex - leftIndex; |
| |
| /* Remove the leading zeroes from the integer part of the input */ |
| int rightIndex = 0; |
| int rightStopIndex = right.nDecimalDigits - org.apache.drill.exec.util.DecimalUtility.roundUp(right.scale); |
| |
| while(rightIndex < rightStopIndex) { |
| if (right.getInteger(rightIndex, right.start, right.buffer) > 0) |
| break; |
| rightIndex++; |
| } |
| |
| int rightIntegerSize = rightStopIndex - rightIndex; |
| |
| int resultIntegerSize = leftIntegerSize + rightIntegerSize; |
| int resultScaleSize = org.apache.drill.exec.util.DecimalUtility.roundUp(left.scale + right.scale); |
| |
| int leftSize = left.nDecimalDigits - 1; |
| int rightSize = right.nDecimalDigits - 1; |
| |
| int resultIndex = tempResult.length - 1; |
| int currentIndex = 0; |
| |
| for (int i = leftSize; i >= leftIndex; i--) { |
| |
| currentIndex = resultIndex; |
| int carry = 0; |
| |
| for (int j = rightSize; j >= rightIndex; j--) { |
| |
| long mulResult = (long) right.getInteger(j, right.start, right.buffer) * (long) left.getInteger(i, left.start, left.buffer); |
| |
| long tempSum = tempResult[currentIndex] + mulResult + carry; |
| |
| if (tempSum >= org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE) { |
| tempResult[currentIndex] = (int) (tempSum % org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE); |
| carry = (int) (tempSum / org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE); |
| } else { |
| tempResult[currentIndex] = (int) tempSum; |
| carry = 0; |
| } |
| |
| currentIndex--; |
| } |
| /* Propagate the carry */ |
| if (carry > 0) |
| tempResult[currentIndex] += carry; |
| |
| resultIndex--; |
| } |
| |
| /* We have computed the result of the multiplication; check if we need to |
| * round a portion of the fractional part |
| */ |
| resultScaleSize = org.apache.drill.exec.util.DecimalUtility.roundUp(result.scale); |
| |
| if (result.scale < (left.scale + right.scale)) { |
| /* The scale of the output data type is less than the scale |
| * we obtained as a result of multiplication, we need to round |
| * a chunk of the fractional part |
| */ |
| int lastScaleIndex = currentIndex + resultIntegerSize + resultScaleSize - 1; |
| |
| // Compute the power of 10 necessary to find if we need to round up |
| int roundFactor = (int) (org.apache.drill.exec.util.DecimalUtility.getPowerOfTen( |
| org.apache.drill.exec.util.DecimalUtility.MAX_DIGITS - ((result.scale + 1) % org.apache.drill.exec.util.DecimalUtility.MAX_DIGITS))); |
| |
| // Index of rounding digit |
| int roundIndex = currentIndex + resultIntegerSize + org.apache.drill.exec.util.DecimalUtility.roundUp(result.scale + 1) - 1; |
| |
| // Check the first chopped digit to see if we need to round up |
| int carry = ((tempResult[roundIndex] / roundFactor) % 10) > 4 ? 1 : 0; |
| |
| if (result.scale > 0) { |
| |
| // Compute the power of 10 necessary to chop of the fractional part |
| int scaleFactor = (int) (org.apache.drill.exec.util.DecimalUtility.getPowerOfTen( |
| org.apache.drill.exec.util.DecimalUtility.MAX_DIGITS - (result.scale % org.apache.drill.exec.util.DecimalUtility.MAX_DIGITS))); |
| // Chop the unwanted fractional part |
| tempResult[lastScaleIndex] /= scaleFactor; |
| tempResult[lastScaleIndex] *= scaleFactor; |
| |
| // Adjust the carry so that it gets added to the correct digit |
| carry *= scaleFactor; |
| } |
| |
| // Propagate the carry |
| while (carry > 0 && lastScaleIndex >= 0) { |
| int tempSum = tempResult[lastScaleIndex] + carry; |
| if (tempSum >= org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE) { |
| tempResult[lastScaleIndex] = (tempSum % org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE); |
| carry = (int) (tempSum / org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE); |
| } else { |
| tempResult[lastScaleIndex] = tempSum; |
| carry = 0; |
| } |
| lastScaleIndex--; |
| } |
| |
| // Check if carry has increased integer digit |
| if ((lastScaleIndex + 1) < currentIndex) { |
| resultIntegerSize++; |
| currentIndex = lastScaleIndex + 1; |
| } |
| } |
| |
| if (resultIntegerSize > result.nDecimalDigits) { |
| throw new org.apache.drill.common.exceptions.DrillRuntimeException("Cannot fit multiplication result in the given decimal type"); |
| } |
| |
| int outputIndex = result.nDecimalDigits - 1; |
| |
| for (int i = (currentIndex + resultIntegerSize + resultScaleSize - 1); i >= currentIndex; i--) { |
| result.setInteger(outputIndex--, tempResult[i], result.start, result.buffer); |
| } |
| |
| // Set the remaining digits to be zero |
| while(outputIndex >= 0) { |
| result.setInteger(outputIndex--, 0, result.start, result.buffer); |
| } |
| result.setSign(left.getSign(left.start, left.buffer) != right.getSign(right.start, right.buffer), result.start, result.buffer); |
| } |
| } |
| |
| @FunctionTemplate(name = "exact_divide", scope = FunctionTemplate.FunctionScope.DECIMAL_DIV_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}DivideFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output ${type.name}Holder result; |
| @Inject DrillBuf buffer; |
| @Workspace int outputScale; |
| @Workspace int outputPrecision; |
| |
| public void setup() { |
| int size = (${type.storage} * (org.apache.drill.exec.util.DecimalUtility.integerSize)); |
| buffer = buffer.reallocIfNeeded(size); |
| outputPrecision = Integer.MIN_VALUE; |
| } |
| |
| public void eval() { |
| if (outputPrecision == Integer.MIN_VALUE) { |
| org.apache.drill.common.util.DecimalScalePrecisionDivideFunction resultScalePrec = |
| new org.apache.drill.common.util.DecimalScalePrecisionDivideFunction((int) left.precision, (int) left.scale, (int) right.precision, (int) right.scale); |
| outputScale = resultScalePrec.getOutputScale(); |
| outputPrecision = resultScalePrec.getOutputPrecision(); |
| } |
| result.scale = outputScale; |
| result.precision = outputPrecision; |
| result.buffer = buffer; |
| result.start = 0; |
| |
| java.math.BigDecimal numerator = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromDrillBuf(left.buffer, left.start, left.nDecimalDigits, left.scale, true); |
| java.math.BigDecimal denominator = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromDrillBuf(right.buffer, right.start, right.nDecimalDigits, right.scale, true); |
| |
| java.math.BigDecimal output = numerator.divide(denominator, (int) result.scale, java.math.BigDecimal.ROUND_HALF_UP); |
| |
| org.apache.drill.exec.util.DecimalUtility.getSparseFromBigDecimal(output, result.buffer, result.start, result.scale, result.precision, result.nDecimalDigits); |
| } |
| } |
| |
| @FunctionTemplate(name = "mod", scope = FunctionTemplate.FunctionScope.DECIMAL_MOD_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}ModFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output ${type.name}Holder result; |
| @Inject DrillBuf buffer; |
| @Workspace int outputScale; |
| @Workspace int outputPrecision; |
| |
| public void setup() { |
| int size = (${type.storage} * (org.apache.drill.exec.util.DecimalUtility.integerSize)); |
| buffer = buffer.reallocIfNeeded(size); |
| outputPrecision = Integer.MIN_VALUE; |
| } |
| |
| public void eval() { |
| if (outputPrecision == Integer.MIN_VALUE) { |
| org.apache.drill.common.util.DecimalScalePrecisionModFunction resultScalePrec = |
| new org.apache.drill.common.util.DecimalScalePrecisionModFunction((int) left.precision, (int) left.scale, (int) right.precision, (int) right.scale); |
| outputScale = resultScalePrec.getOutputScale(); |
| outputPrecision = resultScalePrec.getOutputPrecision(); |
| } |
| result.scale = outputScale; |
| result.precision = outputPrecision; |
| result.buffer = buffer; |
| result.start = 0; |
| |
| java.math.BigDecimal numerator = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromDrillBuf(left.buffer, left.start, left.nDecimalDigits, left.scale, true); |
| java.math.BigDecimal denominator = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromDrillBuf(right.buffer, right.start, right.nDecimalDigits, right.scale, true); |
| |
| java.math.BigDecimal output = numerator.remainder(denominator); |
| output.setScale(result.scale, java.math.BigDecimal.ROUND_HALF_UP); |
| |
| org.apache.drill.exec.util.DecimalUtility.getSparseFromBigDecimal(output, result.buffer, result.start, result.scale, result.precision, result.nDecimalDigits); |
| } |
| } |
| |
| @FunctionTemplate(name = "abs", scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}AbsFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output ${type.name}Holder out; |
| public void setup() { |
| |
| } |
| |
| public void eval() { |
| out.scale = in.scale; |
| out.precision = in.precision; |
| out.buffer = in.buffer; |
| out.start = in.start; |
| |
| // Set the output buffer with the positive sign |
| out.buffer.setInt(out.start, (out.buffer.getInt(out.start) & 0x7fffffff)); |
| } |
| } |
| |
| @FunctionTemplate(name = "sign", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}SignFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output IntHolder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| |
| boolean zeroValue = true; |
| |
| if (in.getSign(in.start, in.buffer) == true) { |
| out.value = -1; |
| } else { |
| for (int i = 0; i < ${type.storage}; i++) { |
| if (in.getInteger(i, in.start, in.buffer) != 0) { |
| zeroValue = false; |
| break; |
| } |
| } |
| out.value = (zeroValue == true) ? 0 : 1; |
| } |
| } |
| } |
| |
| @FunctionTemplate(names = {"ceil", "ceiling"}, scope = FunctionTemplate.FunctionScope.DECIMAL_ZERO_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}CeilFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output ${type.name}Holder out; |
| public void setup() { |
| |
| } |
| |
| public void eval() { |
| out.scale = 0; |
| out.precision = in.precision; |
| out.buffer = in.buffer; |
| out.start = in.start; |
| boolean sign = in.getSign(in.start, in.buffer); |
| |
| // Indicates whether we need to add 1 to the integer part, while performing ceil |
| int carry = 0; |
| |
| int scaleStartIndex = ${type.storage} - org.apache.drill.exec.util.DecimalUtility.roundUp(in.scale); |
| int srcIntIndex = scaleStartIndex - 1; |
| |
| if (sign == false) { |
| // For negative values ceil we don't need to increment the integer part |
| while (scaleStartIndex < ${type.storage}) { |
| if (out.getInteger(scaleStartIndex, out.start, out.buffer) != 0) { |
| carry = 1; |
| break; |
| } |
| scaleStartIndex++; |
| } |
| } |
| |
| // Truncate the fractional part, move the integer part |
| int destIndex = ${type.storage} - 1; |
| while (srcIntIndex >= 0) { |
| out.setInteger(destIndex--, out.getInteger(srcIntIndex--, out.start, out.buffer), out.start, out.buffer); |
| } |
| |
| // Set the remaining portion of the decimal to be zeroes |
| while (destIndex >= 0) { |
| out.setInteger(destIndex--, 0, out.start, out.buffer); |
| } |
| |
| // Add the carry |
| if (carry != 0) { |
| destIndex = ${type.storage} - 1; |
| |
| while (destIndex >= 0) { |
| int intValue = out.getInteger(destIndex, out.start, out.buffer); |
| intValue += carry; |
| |
| if (intValue >= org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE) { |
| out.setInteger(destIndex--, intValue % org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE, out.start, out.buffer); |
| carry = intValue / org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE; |
| } else { |
| out.setInteger(destIndex--, intValue, out.start, out.buffer); |
| break; |
| } |
| } |
| } |
| // Set the sign |
| out.setSign(sign, out.start, out.buffer); |
| } |
| } |
| |
| @FunctionTemplate(name = "floor", scope = FunctionTemplate.FunctionScope.DECIMAL_ZERO_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}FloorFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output ${type.name}Holder out; |
| public void setup() { |
| |
| } |
| |
| public void eval() { |
| out.scale = 0; |
| out.precision = in.precision; |
| out.buffer = in.buffer; |
| out.start = in.start; |
| boolean sign = in.getSign(in.start, in.buffer); |
| |
| // Indicates whether we need to decrement 1 from the integer part, while performing floor, done for -ve values |
| int carry = 0; |
| |
| int scaleStartIndex = ${type.storage} - org.apache.drill.exec.util.DecimalUtility.roundUp(in.scale); |
| int srcIntIndex = scaleStartIndex - 1; |
| |
| if (sign == true) { |
| // For negative values ceil we don't need to increment the integer part |
| while (scaleStartIndex < ${type.storage}) { |
| if (out.getInteger(scaleStartIndex, out.start, out.buffer) != 0) { |
| carry = 1; |
| break; |
| } |
| scaleStartIndex++; |
| } |
| } |
| |
| // Truncate the fractional part, move the integer part |
| int destIndex = ${type.storage} - 1; |
| while (srcIntIndex >= 0) { |
| out.setInteger(destIndex--, out.getInteger(srcIntIndex--, out.start, out.buffer), out.start, out.buffer); |
| } |
| |
| // Set the remaining portion of the decimal to be zeroes |
| while (destIndex >= 0) { |
| out.setInteger(destIndex--, 0, out.start, out.buffer); |
| } |
| // Add the carry |
| if (carry != 0) { |
| destIndex = ${type.storage} - 1; |
| |
| while (destIndex >= 0) { |
| int intValue = out.getInteger(destIndex, out.start, out.buffer); |
| intValue += carry; |
| |
| if (intValue >= org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE) { |
| out.setInteger(destIndex--, intValue % org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE, out.start, out.buffer); |
| carry = intValue / org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE; |
| } else { |
| out.setInteger(destIndex--, intValue, out.start, out.buffer); |
| break; |
| } |
| } |
| } |
| // Set the sign |
| out.setSign(sign, out.start, out.buffer); |
| } |
| } |
| |
| @FunctionTemplate(names = {"trunc", "truncate"}, scope = FunctionTemplate.FunctionScope.DECIMAL_ZERO_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}TruncateFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output ${type.name}Holder out; |
| public void setup() { |
| |
| } |
| |
| public void eval() { |
| out.scale = 0; |
| out.precision = in.precision; |
| out.buffer = in.buffer; |
| out.start = in.start; |
| boolean sign = in.getSign(in.start, in.buffer); |
| |
| // Integer part's src index |
| int srcIntIndex = ${type.storage} - org.apache.drill.exec.util.DecimalUtility.roundUp(in.scale) - 1; |
| |
| // Truncate the fractional part, move the integer part |
| int destIndex = ${type.storage} - 1; |
| while (srcIntIndex >= 0) { |
| out.setInteger(destIndex--, out.getInteger(srcIntIndex--, out.start, out.buffer), out.start, out.buffer); |
| } |
| |
| // Set the remaining portion of the decimal to be zeroes |
| while (destIndex >= 0) { |
| out.setInteger(destIndex--, 0, out.start, out.buffer); |
| } |
| // Set the sign |
| out.setSign(sign, out.start, out.buffer); |
| } |
| } |
| |
| @FunctionTemplate(names = {"trunc", "truncate"}, scope = FunctionTemplate.FunctionScope.DECIMAL_SET_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}TruncateScaleFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param IntHolder right; |
| @Output ${type.name}Holder result; |
| public void setup() { |
| |
| } |
| |
| public void eval() { |
| result.scale = right.value; |
| result.precision = left.precision; |
| result.buffer = left.buffer; |
| result.start = left.start; |
| boolean sign = left.getSign(left.start, left.buffer); |
| |
| int newScaleRoundedUp = org.apache.drill.exec.util.DecimalUtility.roundUp(right.value); |
| int origScaleRoundedUp = org.apache.drill.exec.util.DecimalUtility.roundUp(left.scale); |
| |
| if (right.value < left.scale) { |
| // Get the source index beyond which we will truncate |
| int srcIntIndex = ${type.storage} - origScaleRoundedUp - 1; |
| int srcIndex = srcIntIndex + newScaleRoundedUp; |
| |
| // Truncate the remaining fractional part, move the integer part |
| int destIndex = ${type.storage} - 1; |
| if (srcIndex != destIndex) { |
| while (srcIndex >= 0) { |
| result.setInteger(destIndex--, result.getInteger(srcIndex--, result.start, result.buffer), result.start, result.buffer); |
| } |
| |
| // Set the remaining portion of the decimal to be zeroes |
| while (destIndex >= 0) { |
| result.setInteger(destIndex--, 0, result.start, result.buffer); |
| } |
| } |
| |
| // We truncated the decimal digit. Now we need to truncate within the base 1 billion fractional digit |
| int truncateFactor = org.apache.drill.exec.util.DecimalUtility.MAX_DIGITS - (right.value % org.apache.drill.exec.util.DecimalUtility.MAX_DIGITS); |
| if (truncateFactor != org.apache.drill.exec.util.DecimalUtility.MAX_DIGITS) { |
| truncateFactor = (int) org.apache.drill.exec.util.DecimalUtility.getPowerOfTen(truncateFactor); |
| int fractionalDigits = result.getInteger(${type.storage} - 1, result.start, result.buffer); |
| fractionalDigits /= truncateFactor; |
| result.setInteger(${type.storage} - 1, fractionalDigits * truncateFactor, result.start, result.buffer); |
| } |
| } else if (right.value > left.scale) { |
| // Add fractional digits to the decimal |
| |
| // Check if we need to shift the decimal digits to the left |
| if (newScaleRoundedUp > origScaleRoundedUp) { |
| int srcIndex = 0; |
| int destIndex = newScaleRoundedUp - origScaleRoundedUp; |
| |
| // Check while extending scale, we are not overwriting integer part |
| while (srcIndex < destIndex) { |
| if (result.getInteger(srcIndex++, result.start, result.buffer) != 0) { |
| throw new org.apache.drill.common.exceptions.DrillRuntimeException("Truncate resulting in loss of integer part, reduce scale specified"); |
| } |
| } |
| |
| srcIndex = 0; |
| while (destIndex < ${type.storage}) { |
| result.setInteger(srcIndex++, result.getInteger(destIndex++, result.start, result.buffer), result.start, result.buffer); |
| } |
| |
| // Clear the remaining part |
| while (srcIndex < ${type.storage}) { |
| result.setInteger(srcIndex++, 0, result.start, result.buffer); |
| } |
| } |
| } |
| // Set the sign |
| result.setSign(sign, result.start, result.buffer); |
| } |
| } |
| |
| @FunctionTemplate(name = "round", scope = FunctionTemplate.FunctionScope.DECIMAL_ZERO_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}RoundFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output ${type.name}Holder out; |
| public void setup() { |
| |
| } |
| |
| public void eval() { |
| out.scale = 0; |
| out.precision = in.precision; |
| out.buffer = in.buffer; |
| out.start = in.start; |
| boolean sign = in.getSign(in.start, in.buffer); |
| |
| boolean roundUp = false; |
| |
| // Get the first fractional digit to see if want to round up or not |
| int scaleIndex = ${type.storage} - org.apache.drill.exec.util.DecimalUtility.roundUp(in.scale); |
| if (scaleIndex < ${type.storage}) { |
| int fractionalPart = out.getInteger(scaleIndex, out.start, out.buffer); |
| int digit = fractionalPart / (org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE / 10); |
| |
| if (digit > 4) { |
| roundUp = true; |
| } |
| } |
| |
| // Integer part's src index |
| int srcIntIndex = scaleIndex - 1; |
| |
| // Truncate the fractional part, move the integer part |
| int destIndex = ${type.storage} - 1; |
| while (srcIntIndex >= 0) { |
| out.setInteger(destIndex--, out.getInteger(srcIntIndex--, out.start, out.buffer), out.start, out.buffer); |
| } |
| |
| // Set the remaining portion of the decimal to be zeroes |
| while (destIndex >= 0) { |
| out.setInteger(destIndex--, 0, out.start, out.buffer); |
| } |
| |
| // Perform the roundup |
| srcIntIndex = ${type.storage} - 1; |
| if (roundUp == true) { |
| while (srcIntIndex >= 0) { |
| int value = out.getInteger(srcIntIndex, out.start, out.buffer) + 1; |
| if (value >= org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE) { |
| out.setInteger(srcIntIndex--, value % org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE, out.start, out.buffer); |
| value = value / org.apache.drill.exec.util.DecimalUtility.DIGITS_BASE; |
| } else { |
| out.setInteger(srcIntIndex--, value, out.start, out.buffer); |
| break; |
| } |
| } |
| } |
| // Set the sign |
| out.setSign(sign, out.start, out.buffer); |
| } |
| } |
| |
| @FunctionTemplate(name = "round", scope = FunctionTemplate.FunctionScope.DECIMAL_SET_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}RoundScaleFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param IntHolder right; |
| @Output ${type.name}Holder result; |
| public void setup() { |
| |
| } |
| |
| public void eval() { |
| result.scale = right.value; |
| result.precision = left.precision; |
| result.buffer = left.buffer; |
| result.start = left.start; |
| boolean sign = left.getSign(left.start, left.buffer); |
| |
| org.apache.drill.exec.util.DecimalUtility.roundDecimal(result.buffer, result.start, result.nDecimalDigits, result.scale, left.scale); |
| // Set the sign |
| result.setSign(sign, result.start, result.buffer); |
| } |
| } |
| |
| <#-- Handle 2 x 2 combinations of nullable and non-nullable arguments. --> |
| <#list ["Nullable${type.name}", "${type.name}"] as leftType > |
| <#list ["Nullable${type.name}", "${type.name}"] as rightType > |
| |
| <#-- Comparison function for sorting and grouping relational operators |
| (not for comparison expression operators (=, <, etc.)). --> |
| @FunctionTemplate(name = FunctionGenerationHelper.COMPARE_TO_NULLS_HIGH, |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.INTERNAL) |
| public static class GCompare${leftType}Vs${rightType}NullHigh implements DrillSimpleFunc { |
| |
| @Param ${leftType}Holder left; |
| @Param ${rightType}Holder right; |
| @Output IntHolder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| <@compareBlock leftType=leftType rightType=rightType absCompare="false" output="out.value" nullCompare=true nullComparesHigh=true /> |
| } |
| } |
| |
| |
| |
| <#-- Comparison function for sorting and grouping relational operators |
| (not for comparison expression operators (=, <, etc.)). --> |
| @FunctionTemplate(name = FunctionGenerationHelper.COMPARE_TO_NULLS_LOW, |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.INTERNAL) |
| public static class GCompare${leftType}Vs${rightType}NullLow implements DrillSimpleFunc { |
| |
| @Param ${leftType}Holder left; |
| @Param ${rightType}Holder right; |
| @Output IntHolder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| <@compareBlock leftType=leftType rightType=rightType absCompare="false" output="out.value" nullCompare=true nullComparesHigh=false /> |
| } |
| } |
| |
| </#list> |
| </#list> |
| |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "less than", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}LessThan implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp; |
| <@compareBlock leftType="leftType" rightType="rightType" absCompare="false" output="cmp" nullCompare=false nullComparesHigh=false /> |
| out.value = cmp == -1 ? 1 : 0; |
| } |
| } |
| |
| |
| // TODO: RESOLVE: Here there are spaces in function template names, but |
| // elsewhere there are underlines. Are things being looked up correctly? |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "less than or equal to", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}LessThanEq implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp; |
| <@compareBlock leftType="leftType" rightType="rightType" absCompare="false" output="cmp" nullCompare=false nullComparesHigh=false /> |
| out.value = cmp < 1 ? 1 : 0; |
| } |
| } |
| |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "greater than", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}GreaterThan implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp; |
| <@compareBlock leftType="leftType" rightType="rightType" absCompare="false" output="cmp" nullCompare=false nullComparesHigh=false /> |
| out.value = cmp == 1 ? 1 : 0; |
| } |
| } |
| |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "greater than or equal to", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}GreaterThanEq implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp; |
| <@compareBlock leftType="leftType" rightType="rightType" absCompare="false" output="cmp" nullCompare=false nullComparesHigh=false /> |
| out.value = cmp > -1 ? 1 : 0; |
| } |
| } |
| |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "Equal", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}Equal implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp; |
| <@compareBlock leftType="leftType" rightType="rightType" absCompare="false" output="cmp" nullCompare=false nullComparesHigh=false /> |
| out.value = cmp == 0 ? 1 : 0; |
| } |
| } |
| |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "not equal", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}NotEqual implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp; |
| <@compareBlock leftType="leftType" rightType="rightType" absCompare="false" output="cmp" nullCompare=false nullComparesHigh=false /> |
| out.value = cmp != 0 ? 1 : 0; |
| } |
| } |
| } |
| |
| <#elseif type.name.endsWith("Dense")> |
| |
| <@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/${type.name}Functions.java" /> |
| |
| <#include "/@includes/license.ftl" /> |
| |
| package org.apache.drill.exec.expr.fn.impl; |
| |
| <#include "/@includes/vv_imports.ftl" /> |
| |
| import org.apache.drill.exec.expr.DrillSimpleFunc; |
| import org.apache.drill.exec.expr.annotations.FunctionTemplate; |
| import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling; |
| import org.apache.drill.exec.expr.annotations.Output; |
| import org.apache.drill.exec.expr.annotations.Param; |
| import org.apache.drill.exec.expr.fn.FunctionGenerationHelper; |
| import org.apache.drill.exec.expr.holders.*; |
| import org.apache.drill.exec.record.RecordBatch; |
| |
| import io.netty.buffer.ByteBuf; |
| |
| import java.nio.ByteBuffer; |
| |
| @SuppressWarnings("unused") |
| public class ${type.name}Functions { |
| |
| |
| <#-- Handle 2 x 2 combinations of nullable and non-nullable arguments. --> |
| <#list ["Nullable${type.name}", "${type.name}"] as leftType > |
| <#list ["Nullable${type.name}", "${type.name}"] as rightType > |
| |
| <#-- Comparison function for sorting and grouping relational operators |
| (not for comparison expression operators (=, <, etc.)). --> |
| @FunctionTemplate(name = FunctionGenerationHelper.COMPARE_TO_NULLS_HIGH, |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.INTERNAL) |
| public static class GCompare${leftType}Vs${rightType}NullHigh implements DrillSimpleFunc { |
| |
| @Param ${leftType}Holder left; |
| @Param ${rightType}Holder right; |
| @Output IntHolder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| outside: |
| { |
| <@compareNullsSubblock leftType=leftType rightType=rightType output="out.value" breakTarget="outside" nullCompare=true nullComparesHigh=true /> |
| |
| out.value = org.apache.drill.exec.util.DecimalUtility.compareDenseBytes(left.buffer, left.start, left.getSign(left.start, left.buffer), right.buffer, right.start, right.getSign(right.start, right.buffer), left.WIDTH); |
| } // outside |
| } |
| } |
| |
| <#-- Comparison function for sorting and grouping relational operators |
| (not for comparison expression operators (=, <, etc.)). --> |
| @FunctionTemplate(name = FunctionGenerationHelper.COMPARE_TO_NULLS_LOW, |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.INTERNAL) |
| public static class GCompare${leftType}Vs${rightType}NullLow implements DrillSimpleFunc { |
| |
| @Param ${leftType}Holder left; |
| @Param ${rightType}Holder right; |
| @Output IntHolder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| outside: |
| { |
| <@compareNullsSubblock leftType=leftType rightType=rightType output="out.value" breakTarget="outside" nullCompare=true nullComparesHigh=false /> |
| |
| out.value = org.apache.drill.exec.util.DecimalUtility.compareDenseBytes(left.buffer, left.start, left.getSign(left.start, left.buffer), right.buffer, right.start, right.getSign(right.start, right.buffer), left.WIDTH); |
| } // outside |
| } |
| } |
| |
| </#list> |
| </#list> |
| |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "less than", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}LessThan implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp = org.apache.drill.exec.util.DecimalUtility.compareDenseBytes(left.buffer, left.start, left.getSign(left.start, left.buffer), right.buffer, right.start, right.getSign(right.start, right.buffer), left.WIDTH); |
| out.value = cmp == -1 ? 1 : 0; |
| } |
| } |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "less than or equal to", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}LessThanEq implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp = org.apache.drill.exec.util.DecimalUtility.compareDenseBytes(left.buffer, left.start, left.getSign(left.start, left.buffer), right.buffer, right.start, right.getSign(right.start, right.buffer), left.WIDTH); |
| out.value = cmp < 1 ? 1 : 0; |
| } |
| } |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "greater than", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}GreaterThan implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp = org.apache.drill.exec.util.DecimalUtility.compareDenseBytes(left.buffer, left.start, left.getSign(left.start, left.buffer), right.buffer, right.start, right.getSign(right.start, right.buffer), left.WIDTH); |
| out.value = cmp == 1 ? 1 : 0; |
| } |
| } |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "greater than or equal to", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}GreaterThanEq implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp = org.apache.drill.exec.util.DecimalUtility.compareDenseBytes(left.buffer, left.start, left.getSign(left.start, left.buffer), right.buffer, right.start, right.getSign(right.start, right.buffer), left.WIDTH); |
| out.value = cmp > -1 ? 1 : 0; |
| } |
| } |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "Equal", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}Equal implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| int cmp = org.apache.drill.exec.util.DecimalUtility.compareDenseBytes(left.buffer, left.start, left.getSign(left.start, left.buffer), right.buffer, right.start, right.getSign(right.start, right.buffer), left.WIDTH); |
| out.value = cmp == 0 ? 1 : 0; |
| } |
| } |
| |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "not equal", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}NotEqual implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| |
| int cmp = org.apache.drill.exec.util.DecimalUtility.compareDenseBytes(left.buffer, left.start, left.getSign(left.start, left.buffer), right.buffer, right.start, right.getSign(right.start, right.buffer), left.WIDTH); |
| out.value = cmp != 0 ? 1 : 0; |
| } |
| } |
| } |
| |
| <#elseif type.name.endsWith("Decimal9") || type.name.endsWith("Decimal18")> |
| |
| <@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/${type.name}Functions.java" /> |
| |
| <#include "/@includes/license.ftl" /> |
| |
| package org.apache.drill.exec.expr.fn.impl; |
| |
| <#include "/@includes/vv_imports.ftl" /> |
| |
| import org.apache.drill.exec.expr.DrillSimpleFunc; |
| import org.apache.drill.exec.expr.annotations.FunctionTemplate; |
| import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling; |
| import org.apache.drill.exec.expr.annotations.Output; |
| import org.apache.drill.exec.expr.annotations.Param; |
| import org.apache.drill.exec.expr.annotations.Workspace; |
| import org.apache.drill.exec.expr.fn.FunctionGenerationHelper; |
| import org.apache.drill.exec.expr.holders.*; |
| import org.apache.drill.exec.record.RecordBatch; |
| |
| import io.netty.buffer.ByteBuf; |
| |
| import java.nio.ByteBuffer; |
| |
| @SuppressWarnings("unused") |
| public class ${type.name}Functions { |
| |
| @FunctionTemplate(name = "add", scope = FunctionTemplate.FunctionScope.DECIMAL_ADD_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}AddFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Workspace int outputScale; |
| @Workspace int outputPrecision; |
| @Output ${type.name}Holder result; |
| |
| public void setup() { |
| outputPrecision = Integer.MIN_VALUE; |
| } |
| |
| |
| public void eval() { |
| if (outputPrecision == Integer.MIN_VALUE) { |
| org.apache.drill.common.util.DecimalScalePrecisionAddFunction resultScalePrec = |
| new org.apache.drill.common.util.DecimalScalePrecisionAddFunction((int) left.precision, (int) left.scale, (int) right.precision, (int) right.scale); |
| outputScale = resultScalePrec.getOutputScale(); |
| outputPrecision = resultScalePrec.getOutputPrecision(); |
| } |
| <@adjustScale javaType=type.storage leftType="leftType" rightType="rightType"/> |
| |
| result.value = left.value + right.value; |
| result.precision = outputPrecision; |
| result.scale = outputScale; |
| } |
| } |
| |
| @FunctionTemplate(name = "subtract", scope = FunctionTemplate.FunctionScope.DECIMAL_ADD_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}SubtractFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Workspace int outputScale; |
| @Workspace int outputPrecision; |
| @Output ${type.name}Holder result; |
| |
| public void setup() { |
| outputPrecision = Integer.MIN_VALUE; |
| } |
| |
| public void eval() { |
| if (outputPrecision == Integer.MIN_VALUE) { |
| org.apache.drill.common.util.DecimalScalePrecisionAddFunction resultScalePrec = |
| new org.apache.drill.common.util.DecimalScalePrecisionAddFunction((int) left.precision, (int) left.scale, (int) right.precision, (int) right.scale); |
| outputScale = resultScalePrec.getOutputScale(); |
| outputPrecision = resultScalePrec.getOutputPrecision(); |
| } |
| <@adjustScale javaType=type.storage leftType="leftType" rightType="rightType"/> |
| |
| result.value = left.value - right.value; |
| result.precision = outputPrecision; |
| result.scale = outputScale; |
| } |
| } |
| @FunctionTemplate(name = "multiply", scope = FunctionTemplate.FunctionScope.DECIMAL_MUL_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}MultiplyFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Workspace int outputScale; |
| @Workspace int outputPrecision; |
| @Output ${type.name}Holder result; |
| |
| public void setup() { |
| outputPrecision = Integer.MIN_VALUE; |
| } |
| |
| public void eval() { |
| if (outputPrecision == Integer.MIN_VALUE) { |
| org.apache.drill.common.util.DecimalScalePrecisionMulFunction resultScalePrec = |
| new org.apache.drill.common.util.DecimalScalePrecisionMulFunction((int) left.precision, (int) left.scale, (int) right.precision, (int) right.scale); |
| outputScale = resultScalePrec.getOutputScale(); |
| outputPrecision = resultScalePrec.getOutputPrecision(); |
| } |
| result.value = left.value * right.value; |
| result.precision = outputPrecision; |
| result.scale = outputScale; |
| } |
| } |
| |
| @FunctionTemplate(name = "abs", scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}AbsFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output ${type.name}Holder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| out.precision = out.maxPrecision; |
| out.scale = in.scale; |
| |
| out.value = in.value; |
| |
| if (out.value < 0){ |
| out.value *= -1; |
| } |
| } |
| } |
| |
| @FunctionTemplate(name = "exact_divide", scope = FunctionTemplate.FunctionScope.DECIMAL_DIV_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}DivideFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output ${type.name}Holder result; |
| @Workspace int outputScale; |
| @Workspace int outputPrecision; |
| |
| public void setup() { |
| outputPrecision = Integer.MIN_VALUE; |
| } |
| |
| public void eval() { |
| |
| if (outputPrecision == Integer.MIN_VALUE) { |
| org.apache.drill.common.util.DecimalScalePrecisionDivideFunction resultScalePrec = |
| new org.apache.drill.common.util.DecimalScalePrecisionDivideFunction((int) left.precision, (int) left.scale, (int) right.precision, (int) right.scale); |
| outputScale = resultScalePrec.getOutputScale(); |
| outputPrecision = resultScalePrec.getOutputPrecision(); |
| } |
| result.scale = outputScale; |
| result.precision = outputPrecision; |
| |
| java.math.BigDecimal numerator = new java.math.BigDecimal(java.math.BigInteger.valueOf(left.value), left.scale); |
| java.math.BigDecimal denominator = new java.math.BigDecimal(java.math.BigInteger.valueOf(right.value), right.scale); |
| |
| java.math.BigDecimal output = numerator.divide(denominator, (int) result.scale, java.math.BigDecimal.ROUND_HALF_UP); |
| |
| result.value = output.unscaledValue().${type.storage}Value(); |
| } |
| } |
| |
| @FunctionTemplate(name = "mod", scope = FunctionTemplate.FunctionScope.DECIMAL_MOD_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}ModFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Workspace int outputScale; |
| @Workspace int outputPrecision; |
| @Output ${type.name}Holder result; |
| |
| public void setup() { |
| outputPrecision = Integer.MIN_VALUE; |
| } |
| |
| public void eval() { |
| if (outputPrecision == Integer.MIN_VALUE) { |
| org.apache.drill.common.util.DecimalScalePrecisionModFunction resultScalePrec = |
| new org.apache.drill.common.util.DecimalScalePrecisionModFunction((int) left.precision, (int) left.scale, (int) right.precision, (int) right.scale); |
| outputScale = resultScalePrec.getOutputScale(); |
| outputPrecision = resultScalePrec.getOutputPrecision(); |
| } |
| result.precision = outputPrecision; |
| result.scale = outputScale; |
| java.math.BigDecimal numerator = new java.math.BigDecimal(java.math.BigInteger.valueOf(left.value), left.scale); |
| java.math.BigDecimal denominator = new java.math.BigDecimal(java.math.BigInteger.valueOf(right.value), right.scale); |
| |
| java.math.BigDecimal output = numerator.remainder(denominator); |
| output.setScale(result.scale, java.math.BigDecimal.ROUND_HALF_UP); |
| |
| result.value = output.unscaledValue().${type.storage}Value(); |
| } |
| } |
| |
| @FunctionTemplate(name = "sign", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}SignFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output IntHolder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| |
| out.value = (in.value < 0) ? -1 : ((in.value > 0) ? 1 : 0); |
| } |
| } |
| |
| @FunctionTemplate(names = {"trunc", "truncate"}, scope = FunctionTemplate.FunctionScope.DECIMAL_ZERO_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}TruncFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output ${type.name}Holder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| |
| out.value =(${type.storage}) (org.apache.drill.exec.util.DecimalUtility.adjustScaleDivide(in.value, (int) in.scale)); |
| out.precision = out.maxPrecision; |
| out.scale = 0; |
| } |
| } |
| |
| @FunctionTemplate(names = {"trunc", "truncate"}, scope = FunctionTemplate.FunctionScope.DECIMAL_SET_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}TruncateScaleFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param IntHolder right; |
| @Output ${type.name}Holder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| |
| out.value = (${type.storage}) (org.apache.drill.exec.util.DecimalUtility.adjustScaleDivide(left.value, (int) (left.scale - right.value))); |
| out.precision = out.maxPrecision; |
| out.scale = right.value; |
| } |
| } |
| |
| @FunctionTemplate(names = {"ceil", "ceiling"}, scope = FunctionTemplate.FunctionScope.DECIMAL_ZERO_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}CeilFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output ${type.name}Holder out; |
| |
| public void setup() { |
| |
| } |
| |
| public void eval() { |
| ${type.storage} scaleFactor = (${type.storage}) (org.apache.drill.exec.util.DecimalUtility.getPowerOfTen((int) in.scale)); |
| |
| // Get the integer part |
| ${type.storage} integerPart = in.value / scaleFactor; |
| |
| // Get the fractional part, if its non-zero increment the integer part |
| ${type.storage} fractionalPart = (${type.storage}) (in.value % scaleFactor); |
| if (fractionalPart != 0 && in.value >= 0) { |
| integerPart++; |
| } |
| |
| out.scale = 0; |
| out.value = integerPart; |
| } |
| } |
| |
| @FunctionTemplate(name = "floor", scope = FunctionTemplate.FunctionScope.DECIMAL_ZERO_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}FloorFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output ${type.name}Holder out; |
| |
| public void setup() { |
| } |
| |
| public void eval() { |
| |
| ${type.storage} scaleFactor = (${type.storage}) (org.apache.drill.exec.util.DecimalUtility.getPowerOfTen((int) in.scale)); |
| out.scale = 0; |
| out.value = (in.value / scaleFactor); |
| |
| // For negative values we have to decrement by 1 |
| if (in.value < 0) { |
| ${type.storage} fractionalPart = (${type.storage}) (in.value % scaleFactor); |
| if (fractionalPart != 0) { |
| out.value--; |
| } |
| } |
| } |
| } |
| |
| @FunctionTemplate(name = "round", scope = FunctionTemplate.FunctionScope.DECIMAL_ZERO_SCALE, nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}RoundFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder in; |
| @Output ${type.name}Holder out; |
| |
| public void setup() { |
| } |
| |
| public void eval() { |
| |
| ${type.storage} scaleFactor = (${type.storage}) (org.apache.drill.exec.util.DecimalUtility.getPowerOfTen((int) in.scale)); |
| ${type.storage} extractDigit = scaleFactor / 10; |
| |
| out.scale = 0; |
| // Assign the integer part to the output |
| out.value = in.value / scaleFactor; |
| |
| // Get the fractional part |
| ${type.storage} fractionalPart = in.value % scaleFactor; |
| // Get the first digit to check for rounding |
| int digit = Math.abs((int) (fractionalPart / extractDigit)); |
| |
| if (digit > 4) { |
| if (in.value > 0) { |
| out.value++; |
| } else if (in.value < 0) { |
| out.value--; |
| } |
| } |
| } |
| } |
| |
| @FunctionTemplate(name = "round", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_SET_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}RoundScaleFunction implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param IntHolder right; |
| @Output ${type.name}Holder out; |
| |
| |
| public void setup() { |
| } |
| |
| public void eval() { |
| |
| ${type.storage} scaleFactor = (${type.storage}) (org.apache.drill.exec.util.DecimalUtility.getPowerOfTen((int) left.scale)); |
| ${type.storage} newScaleFactor = (${type.storage}) (org.apache.drill.exec.util.DecimalUtility.getPowerOfTen((int) right.value)); |
| ${type.storage} truncScaleFactor = (${type.storage}) (org.apache.drill.exec.util.DecimalUtility.getPowerOfTen( Math.abs(left.scale - right.value))); |
| int truncFactor = (int) (left.scale - right.value); |
| |
| // If rounding scale is >= current scale |
| if (right.value >= left.scale) { |
| out.value = (${type.storage}) (org.apache.drill.exec.util.DecimalUtility.adjustScaleMultiply(left.value, (int) (right.value - left.scale))); |
| } |
| else { |
| out.scale = right.value; |
| // Assign the integer part to the output |
| out.value = left.value / scaleFactor; |
| |
| // Get the fractional part |
| ${type.storage} fractionalPart = left.value % scaleFactor; |
| |
| // From the entire fractional part extract the digits upto which rounding is needed |
| ${type.storage} newFractionalPart = (${type.storage}) (org.apache.drill.exec.util.DecimalUtility.adjustScaleDivide(fractionalPart, truncFactor)); |
| ${type.storage} truncatedFraction = fractionalPart % truncScaleFactor; |
| |
| |
| // Get the truncated fractional part and extract the first digit to see if we need to add 1 |
| int digit = Math.abs((int) org.apache.drill.exec.util.DecimalUtility.adjustScaleDivide(truncatedFraction, truncFactor - 1)); |
| |
| if (digit > 4) { |
| if (left.value > 0) { |
| newFractionalPart++; |
| } else if (left.value < 0) { |
| newFractionalPart--; |
| } |
| } |
| |
| out.value = (out.value * newScaleFactor) + newFractionalPart; |
| } |
| } |
| } |
| |
| <#-- Handle 2 x 2 combinations of nullable and non-nullable arguments. --> |
| <#list ["Nullable${type.name}", "${type.name}"] as leftType > |
| <#list ["Nullable${type.name}", "${type.name}"] as rightType > |
| |
| <#-- Comparison function for sorting and grouping relational operators |
| (not for comparison expression operators (=, <, etc.)). --> |
| @FunctionTemplate(name = FunctionGenerationHelper.COMPARE_TO_NULLS_HIGH, |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.INTERNAL) |
| public static class GCompare${leftType}Vs${rightType}NullHigh implements DrillSimpleFunc { |
| |
| @Param ${leftType}Holder left; |
| @Param ${rightType}Holder right; |
| @Output IntHolder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| outside: |
| { |
| <@compareNullsSubblock leftType=leftType rightType=rightType output="out.value" breakTarget="outside" nullCompare=true nullComparesHigh=true /> |
| |
| <@adjustScale javaType=type.storage leftType="leftType" rightType="rightType"/> |
| out.value = (left.value < right.value) ? -1 : (left.value > right.value) ? 1 : 0; |
| } // outside |
| } |
| } |
| |
| <#-- Comparison function for sorting and grouping relational operators |
| (not for comparison expression operators (=, <, etc.)). --> |
| @FunctionTemplate(name = FunctionGenerationHelper.COMPARE_TO_NULLS_LOW, |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.INTERNAL) |
| public static class GCompare${leftType}Vs${rightType}NullLow implements DrillSimpleFunc { |
| |
| @Param ${leftType}Holder left; |
| @Param ${rightType}Holder right; |
| @Output IntHolder out; |
| |
| public void setup() {} |
| |
| public void eval() { |
| outside: |
| { |
| <@compareNullsSubblock leftType=leftType rightType=rightType output="out.value" breakTarget="outside" nullCompare=true nullComparesHigh=false /> |
| <@adjustScale javaType=type.storage leftType="leftType" rightType="rightType"/> |
| out.value = (left.value < right.value) ? -1 : (left.value > right.value) ? 1 : 0; |
| } // outside |
| } |
| } |
| |
| </#list> |
| </#list> |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "less than", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}LessThan implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| <@adjustScale javaType=type.storage leftType="leftType" rightType="rightType"/> |
| out.value = (left.value < right.value) ? 1 : 0; |
| } |
| } |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "less than or equal to", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}LessThanEq implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| <@adjustScale javaType=type.storage leftType="leftType" rightType="rightType"/> |
| out.value = (left.value <= right.value) ? 1 : 0; |
| } |
| } |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "greater than", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}GreaterThan implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| <@adjustScale javaType=type.storage leftType="leftType" rightType="rightType"/> |
| out.value = (left.value > right.value) ? 1 : 0; |
| } |
| } |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "greater than or equal to", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}GreaterThanEq implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| <@adjustScale javaType=type.storage leftType="leftType" rightType="rightType"/> |
| out.value = (left.value >= right.value) ? 1 : 0; |
| } |
| } |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "Equal", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}Equal implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| <@adjustScale javaType=type.storage leftType="leftType" rightType="rightType"/> |
| out.value = (left.value == right.value) ? 1 : 0; |
| } |
| } |
| |
| |
| <#-- Comparison function for comparison expression operator (=, <, etc.), |
| not for sorting and grouping relational operators.) --> |
| @FunctionTemplate(name = "not equal", |
| scope = FunctionTemplate.FunctionScope.DECIMAL_MAX_SCALE, |
| nulls = NullHandling.NULL_IF_NULL) |
| public static class ${type.name}NotEqual implements DrillSimpleFunc { |
| |
| @Param ${type.name}Holder left; |
| @Param ${type.name}Holder right; |
| @Output BitHolder out; |
| public void setup() {} |
| |
| public void eval() { |
| <@adjustScale javaType=type.storage leftType="leftType" rightType="rightType"/> |
| out.value = (left.value != right.value) ? 1 : 0; |
| } |
| } |
| } |
| |
| </#if> |
| |
| </#list> |