/** * 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. */ package org.apache.hadoop.hive.ql.exec.vector.expressions; import org.apache.hadoop.hive.common.type.HiveDecimal; import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector; import org.apache.hadoop.hive.ql.exec.vector.LongColumnVector; import org.apache.hadoop.hive.ql.udf.generic.RoundUtils; import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable; /** * Utility functions for vector operations on decimal values. */ public class DecimalUtil { public static int compare(HiveDecimalWritable writableLeft, HiveDecimal right) { return writableLeft.getHiveDecimal().compareTo(right); } public static int compare(HiveDecimal left, HiveDecimalWritable writableRight) { return HiveDecimalWritable.compareTo(left, writableRight); } // Addition with overflow check. Overflow produces NULL output. public static void addChecked(int i, HiveDecimal left, HiveDecimal right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateAdd(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void addChecked(int i, HiveDecimalWritable left, HiveDecimalWritable right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateAdd(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void addChecked(int i, HiveDecimalWritable left, HiveDecimal right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateAdd(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void addChecked(int i, HiveDecimal left, HiveDecimalWritable right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateAdd(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } // Subtraction with overflow check. Overflow produces NULL output. public static void subtractChecked(int i, HiveDecimal left, HiveDecimal right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateSubtract(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void subtractChecked(int i, HiveDecimalWritable left, HiveDecimalWritable right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateSubtract(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void subtractChecked(int i, HiveDecimalWritable left, HiveDecimal right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateSubtract(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void subtractChecked(int i, HiveDecimal left, HiveDecimalWritable right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateSubtract(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } // Multiplication with overflow check. Overflow produces NULL output. public static void multiplyChecked(int i, HiveDecimal left, HiveDecimal right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateMultiply(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void multiplyChecked(int i, HiveDecimalWritable left, HiveDecimalWritable right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateMultiply(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void multiplyChecked(int i, HiveDecimalWritable left, HiveDecimal right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateMultiply(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void multiplyChecked(int i, HiveDecimal left, HiveDecimalWritable right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateMultiply(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } // Division with overflow/zero-divide check. Error produces NULL output. public static void divideChecked(int i, HiveDecimal left, HiveDecimal right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateDivide(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void divideChecked(int i, HiveDecimalWritable left, HiveDecimalWritable right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateDivide(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void divideChecked(int i, HiveDecimalWritable left, HiveDecimal right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateDivide(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void divideChecked(int i, HiveDecimal left, HiveDecimalWritable right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateDivide(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } // Modulo operator with overflow/zero-divide check. public static void moduloChecked(int i, HiveDecimal left, HiveDecimal right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateRemainder(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void moduloChecked(int i, HiveDecimalWritable left, HiveDecimalWritable right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateRemainder(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void moduloChecked(int i, HiveDecimalWritable left, HiveDecimal right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateRemainder(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void moduloChecked(int i, HiveDecimal left, HiveDecimalWritable right, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(left); decWritable.mutateRemainder(right); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } // UNDONE: Why don't these methods take decimalPlaces? public static void floor(int i, HiveDecimal input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateSetScale(0, HiveDecimal.ROUND_FLOOR); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void floor(int i, HiveDecimalWritable input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateSetScale(0, HiveDecimal.ROUND_FLOOR); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void ceiling(int i, HiveDecimal input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateSetScale(0, HiveDecimal.ROUND_CEILING); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void ceiling(int i, HiveDecimalWritable input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateSetScale(0, HiveDecimal.ROUND_CEILING); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void round(int i, HiveDecimal input, int decimalPlaces, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateSetScale(decimalPlaces, HiveDecimal.ROUND_HALF_UP); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void round(int i, HiveDecimalWritable input, int decimalPlaces, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateSetScale(decimalPlaces, HiveDecimal.ROUND_HALF_UP); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void round(int i, HiveDecimal input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateSetScale(outputColVector.scale, HiveDecimal.ROUND_HALF_UP); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void round(int i, HiveDecimalWritable input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateSetScale(outputColVector.scale, HiveDecimal.ROUND_HALF_UP); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void bround(int i, HiveDecimalWritable input, int decimalPlaces, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateSetScale(decimalPlaces, HiveDecimal.ROUND_HALF_EVEN); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void bround(int i, HiveDecimalWritable input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateSetScale(outputColVector.scale, HiveDecimal.ROUND_HALF_EVEN); decWritable.mutateEnforcePrecisionScale(outputColVector.precision, outputColVector.scale); if (!decWritable.isSet()) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; } } public static void sign(int i, HiveDecimal input, LongColumnVector outputColVector) { outputColVector.vector[i] = input.signum(); } public static void sign(int i, HiveDecimalWritable input, LongColumnVector outputColVector) { outputColVector.vector[i] = input.signum(); } public static void abs(int i, HiveDecimal input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateAbs(); } public static void abs(int i, HiveDecimalWritable input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateAbs(); } public static void negate(int i, HiveDecimal input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateNegate(); } public static void negate(int i, HiveDecimalWritable input, DecimalColumnVector outputColVector) { HiveDecimalWritable decWritable = outputColVector.vector[i]; decWritable.set(input); decWritable.mutateNegate(); } }