/**
 * 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;
/*
 * This class is generated using freemarker and the ${.template_name} template.
 */

@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.INTEGER_SIZE));
            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.INTEGER_SIZE));
            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.INTEGER_SIZE));
            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.INTEGER_SIZE));
            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.INTEGER_SIZE));
            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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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;

/*
 * This class is generated using freemarker and the ${.template_name} template.
 */

@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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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 (=, &lt;, 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>
