[KYUUBI #2996] Remove Hive storage-api dependencies from Kyuubi Hive JDBC

### _Why are the changes needed?_

fix #2996

### _How was this patch tested?_
- [ ] Add some test cases that check the changes thoroughly including negative and positive cases if possible

- [ ] Add screenshots for manual tests if appropriate

- [ ] [Run test](https://kyuubi.apache.org/docs/latest/develop_tools/testing.html#running-tests) locally before make a pull request

Closes #3003 from jiaoqingbo/kyuubi-2996.

Closes #2996

bc919312 [jiaoqingbo] [KYUUBI #2996] Remove Hive storage-api dependencies from Kyuubi Hive JDBC

Authored-by: jiaoqingbo <1178404354@qq.com>
Signed-off-by: Cheng Pan <chengpan@apache.org>
This commit is contained in:
jiaoqingbo 2022-07-04 18:46:51 +08:00 committed by Cheng Pan
parent 407fc8db45
commit 4b8dc7962d
No known key found for this signature in database
GPG Key ID: 8001952629BCC75D
13 changed files with 11708 additions and 36 deletions

View File

@ -42,19 +42,6 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-storage-api</artifactId>
<version>${hive.storage-api.version}</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-service-rpc</artifactId>

View File

@ -37,18 +37,6 @@
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-storage-api</artifactId>
<version>${hive.storage-api.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libfb303</artifactId>

View File

@ -23,8 +23,8 @@ import java.math.BigInteger;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Timestamp;
import org.apache.hadoop.hive.common.type.HiveIntervalDayTime;
import org.apache.hive.service.rpc.thrift.TTypeId;
import org.apache.kyuubi.jdbc.hive.common.HiveIntervalDayTime;
import org.apache.kyuubi.jdbc.hive.common.HiveIntervalYearMonth;
import org.apache.kyuubi.jdbc.hive.common.TimestampTZ;

View File

@ -24,10 +24,10 @@ import java.math.MathContext;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.util.List;
import org.apache.hadoop.hive.common.type.HiveIntervalDayTime;
import org.apache.hive.service.rpc.thrift.TTableSchema;
import org.apache.hive.service.rpc.thrift.TTypeId;
import org.apache.kyuubi.jdbc.hive.adapter.SQLResultSet;
import org.apache.kyuubi.jdbc.hive.common.HiveIntervalDayTime;
import org.apache.kyuubi.jdbc.hive.common.HiveIntervalYearMonth;
import org.apache.kyuubi.jdbc.hive.common.TimestampTZUtil;

View File

@ -22,10 +22,10 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.hadoop.hive.common.type.HiveDecimal;
import org.apache.hive.service.rpc.thrift.*;
import org.apache.kyuubi.jdbc.hive.cli.RowSet;
import org.apache.kyuubi.jdbc.hive.cli.RowSetFactory;
import org.apache.kyuubi.jdbc.hive.common.HiveDecimal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -21,11 +21,11 @@ import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.hadoop.hive.common.type.HiveDecimal;
import org.apache.hive.service.rpc.thrift.TColumn;
import org.apache.hive.service.rpc.thrift.TRow;
import org.apache.hive.service.rpc.thrift.TRowSet;
import org.apache.hive.service.rpc.thrift.TTypeId;
import org.apache.kyuubi.jdbc.hive.common.HiveDecimal;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;

View File

@ -19,13 +19,8 @@ package org.apache.kyuubi.jdbc.hive.cli;
import java.sql.Date;
import java.sql.Timestamp;
import org.apache.hadoop.hive.common.type.HiveDecimal;
import org.apache.hadoop.hive.common.type.HiveIntervalDayTime;
import org.apache.hive.service.rpc.thrift.*;
import org.apache.kyuubi.jdbc.hive.common.HiveChar;
import org.apache.kyuubi.jdbc.hive.common.HiveIntervalYearMonth;
import org.apache.kyuubi.jdbc.hive.common.HiveVarchar;
import org.apache.kyuubi.jdbc.hive.common.TimestampTZ;
import org.apache.kyuubi.jdbc.hive.common.*;
/** Protocols before HIVE_CLI_SERVICE_PROTOCOL_V6 (used by RowBasedSet) */
public class ColumnValue {

View File

@ -18,11 +18,11 @@
package org.apache.kyuubi.jdbc.hive.cli;
import java.util.List;
import org.apache.hadoop.hive.common.type.HiveDecimal;
import org.apache.hive.service.rpc.thrift.TPrimitiveTypeEntry;
import org.apache.hive.service.rpc.thrift.TTypeDesc;
import org.apache.hive.service.rpc.thrift.TTypeEntry;
import org.apache.hive.service.rpc.thrift.TTypeId;
import org.apache.kyuubi.jdbc.hive.common.HiveDecimal;
/** TypeDescriptor. */
public class TypeDescriptor {

View File

@ -0,0 +1,752 @@
/*
* 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.kyuubi.jdbc.hive.common;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
* FastHiveDecimal is a mutable fast decimal object. It is the base class for both the HiveDecimal
* and HiveDecimalWritable classes. All fast* methods are protected so they cannot be accessed by
* clients of HiveDecimal and HiveDecimalWritable. HiveDecimal ensures it creates new objects when
* the value changes since it provides immutable semantics; HiveDecimalWritable does not create new
* objects since it provides mutable semantics.
*
* <p>The methods in this class are shells that pickup the member variables from FastHiveDecimal
* parameters and pass them as individual parameters to static methods in the FastHiveDecimalImpl
* class that do the real work.
*
* <p>NOTE: The rationale for fast decimal is in FastHiveDecimalImpl.
*/
public class FastHiveDecimal {
/*
* We use protected for the fields so the FastHiveDecimalImpl class can access them. Other
* classes including HiveDecimal should not access these fields directly.
*/
// See FastHiveDecimalImpl for more details on these fields.
// -1 when negative; 0 when decimal is zero; 1 when positive.
protected int fastSignum;
// Decimal longwords.
protected long fast2;
protected long fast1;
protected long fast0;
// The number of integer digits in the decimal. When the integer portion is zero, this is 0.
protected int fastIntegerDigitCount;
// The scale of the decimal.
protected int fastScale;
// Used for legacy HiveDecimalV1 setScale compatibility for binary / display serialization of
// trailing zeroes (or rounding).
protected int fastSerializationScale;
protected FastHiveDecimal() {
fastReset();
}
protected FastHiveDecimal(FastHiveDecimal fastDec) {
this();
fastSignum = fastDec.fastSignum;
fast0 = fastDec.fast0;
fast1 = fastDec.fast1;
fast2 = fastDec.fast2;
fastIntegerDigitCount = fastDec.fastIntegerDigitCount;
fastScale = fastDec.fastScale;
// Not propagated.
fastSerializationScale = -1;
}
protected FastHiveDecimal(int fastSignum, FastHiveDecimal fastDec) {
this();
this.fastSignum = fastSignum;
fast0 = fastDec.fast0;
fast1 = fastDec.fast1;
fast2 = fastDec.fast2;
fastIntegerDigitCount = fastDec.fastIntegerDigitCount;
fastScale = fastDec.fastScale;
// Not propagated.
fastSerializationScale = -1;
}
protected FastHiveDecimal(
int fastSignum,
long fast0,
long fast1,
long fast2,
int fastIntegerDigitCount,
int fastScale) {
this();
this.fastSignum = fastSignum;
this.fast0 = fast0;
this.fast1 = fast1;
this.fast2 = fast2;
this.fastIntegerDigitCount = fastIntegerDigitCount;
this.fastScale = fastScale;
fastSerializationScale = -1;
}
protected FastHiveDecimal(long longValue) {
this();
FastHiveDecimalImpl.fastSetFromLong(longValue, this);
}
protected FastHiveDecimal(String string) {
this();
FastHiveDecimalImpl.fastSetFromString(string, false, this);
}
protected void fastReset() {
fastSignum = 0;
fast0 = 0;
fast1 = 0;
fast2 = 0;
fastIntegerDigitCount = 0;
fastScale = 0;
fastSerializationScale = -1;
}
protected void fastSet(FastHiveDecimal fastDec) {
fastSignum = fastDec.fastSignum;
fast0 = fastDec.fast0;
fast1 = fastDec.fast1;
fast2 = fastDec.fast2;
fastIntegerDigitCount = fastDec.fastIntegerDigitCount;
fastScale = fastDec.fastScale;
fastSerializationScale = fastDec.fastSerializationScale;
}
protected void fastSet(
int fastSignum,
long fast0,
long fast1,
long fast2,
int fastIntegerDigitCount,
int fastScale) {
this.fastSignum = fastSignum;
this.fast0 = fast0;
this.fast1 = fast1;
this.fast2 = fast2;
this.fastIntegerDigitCount = fastIntegerDigitCount;
this.fastScale = fastScale;
// Not specified.
fastSerializationScale = -1;
}
protected void fastSetSerializationScale(int fastSerializationScale) {
this.fastSerializationScale = fastSerializationScale;
}
protected int fastSerializationScale() {
return fastSerializationScale;
}
protected static final String STRING_ENFORCE_PRECISION_OUT_OF_RANGE =
"Decimal precision out of allowed range [1," + HiveDecimal.MAX_PRECISION + "]";
protected static final String STRING_ENFORCE_SCALE_OUT_OF_RANGE =
"Decimal scale out of allowed range [0," + HiveDecimal.MAX_SCALE + "]";
protected static final String STRING_ENFORCE_SCALE_LESS_THAN_EQUAL_PRECISION =
"Decimal scale must be less than or equal to precision";
protected boolean fastSetFromBigDecimal(BigDecimal bigDecimal, boolean allowRounding) {
return FastHiveDecimalImpl.fastSetFromBigDecimal(bigDecimal, allowRounding, this);
}
protected boolean fastSetFromBigInteger(BigInteger bigInteger) {
return FastHiveDecimalImpl.fastSetFromBigInteger(bigInteger, this);
}
protected boolean fastSetFromBigIntegerAndScale(BigInteger bigInteger, int scale) {
return FastHiveDecimalImpl.fastSetFromBigInteger(bigInteger, scale, this);
}
protected boolean fastSetFromString(String string, boolean trimBlanks) {
byte[] bytes = string.getBytes();
return fastSetFromBytes(bytes, 0, bytes.length, trimBlanks);
}
protected boolean fastSetFromBytes(byte[] bytes, int offset, int length, boolean trimBlanks) {
return FastHiveDecimalImpl.fastSetFromBytes(bytes, offset, length, trimBlanks, this);
}
protected boolean fastSetFromDigitsOnlyBytesAndScale(
boolean isNegative, byte[] bytes, int offset, int length, int scale) {
return FastHiveDecimalImpl.fastSetFromDigitsOnlyBytesAndScale(
isNegative, bytes, offset, length, scale, this);
}
protected void fastSetFromInt(int intValue) {
FastHiveDecimalImpl.fastSetFromInt(intValue, this);
}
protected void fastSetFromLong(long longValue) {
FastHiveDecimalImpl.fastSetFromLong(longValue, this);
}
protected boolean fastSetFromLongAndScale(long longValue, int scale) {
return FastHiveDecimalImpl.fastSetFromLongAndScale(longValue, scale, this);
}
protected boolean fastSetFromFloat(float floatValue) {
return FastHiveDecimalImpl.fastSetFromFloat(floatValue, this);
}
protected boolean fastSetFromDouble(double doubleValue) {
return FastHiveDecimalImpl.fastSetFromDouble(doubleValue, this);
}
protected void fastFractionPortion() {
FastHiveDecimalImpl.fastFractionPortion(fastSignum, fast0, fast1, fast2, fastScale, this);
}
protected void fastIntegerPortion() {
FastHiveDecimalImpl.fastIntegerPortion(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale, this);
}
protected static final int FAST_SCRATCH_BUFFER_LEN_SERIALIZATION_UTILS_READ = 8 * 3;
protected boolean fastSerializationUtilsRead(
InputStream inputStream, int scale, byte[] scratchBytes) throws IOException, EOFException {
return FastHiveDecimalImpl.fastSerializationUtilsRead(inputStream, scale, scratchBytes, this);
}
protected boolean fastSetFromBigIntegerBytesAndScale(
byte[] bytes, int offset, int length, int scale) {
return FastHiveDecimalImpl.fastSetFromBigIntegerBytesAndScale(
bytes, offset, length, scale, this);
}
protected static final int SCRATCH_LONGS_LEN_FAST_SERIALIZATION_UTILS_WRITE = 6;
protected boolean fastSerializationUtilsWrite(OutputStream outputStream, long[] scratchLongs)
throws IOException {
return FastHiveDecimalImpl.fastSerializationUtilsWrite(
outputStream,
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
scratchLongs);
}
/*
* Deserializes 64-bit decimals up to the maximum 64-bit precision (18 decimal digits).
*/
protected void fastDeserialize64(long decimalLong, int scale) {
FastHiveDecimalImpl.fastDeserialize64(decimalLong, scale, this);
}
/*
* Serializes decimal64 up to the maximum 64-bit precision (18 decimal digits).
*/
protected long fastSerialize64(int scale) {
return FastHiveDecimalImpl.fastSerialize64(scale, fastSignum, fast1, fast0, fastScale);
}
// The fastBigIntegerBytes method returns 3 56 bit (7 byte) words and a possible sign byte.
// However, the fastBigIntegerBytes can take on trailing zeroes -- so make it larger.
protected static final int FAST_SCRATCH_BUFFER_LEN_BIG_INTEGER_BYTES = 1 + 48;
protected static final int FAST_SCRATCH_LONGS_LEN = 6;
protected int fastBigIntegerBytes(long[] scratchLongs, byte[] buffer) {
return FastHiveDecimalImpl.fastBigIntegerBytes(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
fastSerializationScale,
scratchLongs,
buffer);
}
protected int fastBigIntegerBytesScaled(
int serializationScale, long[] scratchLongs, byte[] buffer) {
return FastHiveDecimalImpl.fastBigIntegerBytesScaled(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
serializationScale,
scratchLongs,
buffer);
}
protected boolean fastIsByte() {
return FastHiveDecimalImpl.fastIsByte(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected byte fastByteValueClip() {
return FastHiveDecimalImpl.fastByteValueClip(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected boolean fastIsShort() {
return FastHiveDecimalImpl.fastIsShort(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected short fastShortValueClip() {
return FastHiveDecimalImpl.fastShortValueClip(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected boolean fastIsInt() {
return FastHiveDecimalImpl.fastIsInt(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected int fastIntValueClip() {
return FastHiveDecimalImpl.fastIntValueClip(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected boolean fastIsLong() {
return FastHiveDecimalImpl.fastIsLong(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected long fastLongValueClip() {
return FastHiveDecimalImpl.fastLongValueClip(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected float fastFloatValue() {
return FastHiveDecimalImpl.fastFloatValue(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected double fastDoubleValue() {
return FastHiveDecimalImpl.fastDoubleValue(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected BigInteger fastBigIntegerValue() {
return FastHiveDecimalImpl.fastBigIntegerValue(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale, fastSerializationScale);
}
protected BigDecimal fastBigDecimalValue() {
return FastHiveDecimalImpl.fastBigDecimalValue(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected int fastScale() {
return fastScale;
}
protected int fastSignum() {
return fastSignum;
}
protected int fastCompareTo(FastHiveDecimal right) {
return FastHiveDecimalImpl.fastCompareTo(
fastSignum,
fast0,
fast1,
fast2,
fastScale,
right.fastSignum,
right.fast0,
right.fast1,
right.fast2,
right.fastScale);
}
protected static int fastCompareTo(FastHiveDecimal left, FastHiveDecimal right) {
return FastHiveDecimalImpl.fastCompareTo(
left.fastSignum,
left.fast0,
left.fast1,
left.fast2,
left.fastScale,
right.fastSignum,
right.fast0,
right.fast1,
right.fast2,
right.fastScale);
}
protected boolean fastEquals(FastHiveDecimal that) {
return FastHiveDecimalImpl.fastEquals(
fastSignum,
fast0,
fast1,
fast2,
fastScale,
that.fastSignum,
that.fast0,
that.fast1,
that.fast2,
that.fastScale);
}
protected void fastAbs() {
if (fastSignum == 0) {
return;
}
fastSignum = 1;
}
protected void fastNegate() {
if (fastSignum == 0) {
return;
}
fastSignum = (fastSignum == 1 ? -1 : 1);
}
protected int fastNewFasterHashCode() {
return FastHiveDecimalImpl.fastNewFasterHashCode(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected int fastHashCode() {
return FastHiveDecimalImpl.fastHashCode(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected int fastIntegerDigitCount() {
return fastIntegerDigitCount;
}
protected int fastSqlPrecision() {
return FastHiveDecimalImpl.fastSqlPrecision(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
}
protected int fastRawPrecision() {
return FastHiveDecimalImpl.fastRawPrecision(fastSignum, fast0, fast1, fast2);
}
protected boolean fastScaleByPowerOfTen(int n, FastHiveDecimal fastResult) {
return FastHiveDecimalImpl.fastScaleByPowerOfTen(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale, n, fastResult);
}
protected static String fastRoundingModeToString(int roundingMode) {
String roundingModeString;
switch (roundingMode) {
case BigDecimal.ROUND_DOWN:
roundingModeString = "ROUND_DOWN";
break;
case BigDecimal.ROUND_UP:
roundingModeString = "ROUND_UP";
break;
case BigDecimal.ROUND_FLOOR:
roundingModeString = "ROUND_FLOOR";
break;
case BigDecimal.ROUND_CEILING:
roundingModeString = "ROUND_CEILING";
break;
case BigDecimal.ROUND_HALF_UP:
roundingModeString = "ROUND_HALF_UP";
break;
case BigDecimal.ROUND_HALF_EVEN:
roundingModeString = "ROUND_HALF_EVEN";
break;
default:
roundingModeString = "Unknown";
}
return roundingModeString + " (" + roundingMode + ")";
}
protected boolean fastRound(int newScale, int roundingMode, FastHiveDecimal fastResult) {
return FastHiveDecimalImpl.fastRound(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
newScale,
roundingMode,
fastResult);
}
protected boolean isAllZeroesBelow(int power) {
return FastHiveDecimalImpl.isAllZeroesBelow(fastSignum, fast0, fast1, fast2, power);
}
protected boolean fastEnforcePrecisionScale(int maxPrecision, int maxScale) {
if (maxPrecision <= 0 || maxPrecision > HiveDecimal.MAX_PRECISION) {
return false;
}
if (maxScale < 0 || maxScale > HiveDecimal.MAX_SCALE) {
return false;
}
/*
if (!fastIsValid()) {
fastRaiseInvalidException();
}
*/
FastCheckPrecisionScaleStatus status =
FastHiveDecimalImpl.fastCheckPrecisionScale(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
maxPrecision,
maxScale);
switch (status) {
case NO_CHANGE:
return true;
case OVERFLOW:
return false;
case UPDATE_SCALE_DOWN:
{
if (!FastHiveDecimalImpl.fastUpdatePrecisionScale(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
maxPrecision,
maxScale,
status,
this)) {
return false;
}
/*
if (!fastIsValid()) {
fastRaiseInvalidException();
}
*/
return true;
}
default:
throw new RuntimeException(
"Unknown fast decimal check precision and scale status " + status);
}
}
protected FastCheckPrecisionScaleStatus fastCheckPrecisionScale(int maxPrecision, int maxScale) {
return FastHiveDecimalImpl.fastCheckPrecisionScale(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale, maxPrecision, maxScale);
}
protected static enum FastCheckPrecisionScaleStatus {
NO_CHANGE,
OVERFLOW,
UPDATE_SCALE_DOWN;
}
protected boolean fastUpdatePrecisionScale(
int maxPrecision,
int maxScale,
FastCheckPrecisionScaleStatus status,
FastHiveDecimal fastResult) {
return FastHiveDecimalImpl.fastUpdatePrecisionScale(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
maxPrecision,
maxScale,
status,
fastResult);
}
protected boolean fastAdd(FastHiveDecimal fastRight, FastHiveDecimal fastResult) {
return FastHiveDecimalImpl.fastAdd(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
fastRight.fastSignum,
fastRight.fast0,
fastRight.fast1,
fastRight.fast2,
fastRight.fastIntegerDigitCount,
fastRight.fastScale,
fastResult);
}
protected boolean fastSubtract(FastHiveDecimal fastRight, FastHiveDecimal fastResult) {
return FastHiveDecimalImpl.fastSubtract(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
fastRight.fastSignum,
fastRight.fast0,
fastRight.fast1,
fastRight.fast2,
fastRight.fastIntegerDigitCount,
fastRight.fastScale,
fastResult);
}
protected boolean fastMultiply(FastHiveDecimal fastRight, FastHiveDecimal fastResult) {
return FastHiveDecimalImpl.fastMultiply(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
fastRight.fastSignum,
fastRight.fast0,
fastRight.fast1,
fastRight.fast2,
fastRight.fastIntegerDigitCount,
fastRight.fastScale,
fastResult);
}
protected boolean fastRemainder(FastHiveDecimal fastRight, FastHiveDecimal fastResult) {
return FastHiveDecimalImpl.fastRemainder(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
fastRight.fastSignum,
fastRight.fast0,
fastRight.fast1,
fastRight.fast2,
fastRight.fastIntegerDigitCount,
fastRight.fastScale,
fastResult);
}
protected boolean fastDivide(FastHiveDecimal fastRight, FastHiveDecimal fastResult) {
return FastHiveDecimalImpl.fastDivide(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
fastRight.fastSignum,
fastRight.fast0,
fastRight.fast1,
fastRight.fast2,
fastRight.fastIntegerDigitCount,
fastRight.fastScale,
fastResult);
}
protected boolean fastPow(int exponent, FastHiveDecimal fastResult) {
return FastHiveDecimalImpl.fastPow(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale, exponent, fastResult);
}
protected String fastToString(byte[] scratchBuffer) {
return FastHiveDecimalImpl.fastToString(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale, -1, scratchBuffer);
}
protected String fastToString() {
return FastHiveDecimalImpl.fastToString(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale, -1);
}
protected String fastToFormatString(int formatScale) {
return FastHiveDecimalImpl.fastToFormatString(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale, formatScale);
}
protected String fastToFormatString(int formatScale, byte[] scratchBuffer) {
return FastHiveDecimalImpl.fastToFormatString(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
formatScale,
scratchBuffer);
}
protected String fastToDigitsOnlyString() {
return FastHiveDecimalImpl.fastToDigitsOnlyString(fast0, fast1, fast2, fastIntegerDigitCount);
}
// Sign, zero, dot, 2 * digits (to support toFormatString which can add a lot of trailing zeroes).
protected static final int FAST_SCRATCH_BUFFER_LEN_TO_BYTES =
1 + 1 + 1 + 2 * FastHiveDecimalImpl.MAX_DECIMAL_DIGITS;
protected int fastToBytes(byte[] scratchBuffer) {
return FastHiveDecimalImpl.fastToBytes(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale, -1, scratchBuffer);
}
protected int fastToFormatBytes(int formatScale, byte[] scratchBuffer) {
return FastHiveDecimalImpl.fastToFormatBytes(
fastSignum,
fast0,
fast1,
fast2,
fastIntegerDigitCount,
fastScale,
formatScale,
scratchBuffer);
}
protected int fastToDigitsOnlyBytes(byte[] scratchBuffer) {
return FastHiveDecimalImpl.fastToDigitsOnlyBytes(
fast0, fast1, fast2, fastIntegerDigitCount, scratchBuffer);
}
@Override
public String toString() {
return FastHiveDecimalImpl.fastToString(
fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale, -1);
}
protected boolean fastIsValid() {
return FastHiveDecimalImpl.fastIsValid(this);
}
protected void fastRaiseInvalidException() {
FastHiveDecimalImpl.fastRaiseInvalidException(this);
}
protected void fastRaiseInvalidException(String parameters) {
FastHiveDecimalImpl.fastRaiseInvalidException(this, parameters);
}
}

View File

@ -0,0 +1,256 @@
/*
* 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.kyuubi.jdbc.hive.common;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.builder.HashCodeBuilder;
/**
* Day-time interval type representing an offset in days/hours/minutes/seconds, with nanosecond
* precision. 1 day = 24 hours = 1440 minutes = 86400 seconds
*/
public class HiveIntervalDayTime implements Comparable<HiveIntervalDayTime> {
// days/hours/minutes/seconds all represented as seconds
protected long totalSeconds;
protected int nanos;
public HiveIntervalDayTime() {}
public HiveIntervalDayTime(int days, int hours, int minutes, int seconds, int nanos) {
set(days, hours, minutes, seconds, nanos);
}
public HiveIntervalDayTime(long seconds, int nanos) {
set(seconds, nanos);
}
public HiveIntervalDayTime(BigDecimal seconds) {
set(seconds);
}
public HiveIntervalDayTime(HiveIntervalDayTime other) {
set(other.totalSeconds, other.nanos);
}
public int getDays() {
return (int) TimeUnit.SECONDS.toDays(totalSeconds);
}
public int getHours() {
return (int) (TimeUnit.SECONDS.toHours(totalSeconds) % TimeUnit.DAYS.toHours(1));
}
public int getMinutes() {
return (int) (TimeUnit.SECONDS.toMinutes(totalSeconds) % TimeUnit.HOURS.toMinutes(1));
}
public int getSeconds() {
return (int) (totalSeconds % TimeUnit.MINUTES.toSeconds(1));
}
public int getNanos() {
return nanos;
}
/**
* Returns days/hours/minutes all converted into seconds. Nanos still need to be retrieved using
* getNanos()
*
* @return
*/
public long getTotalSeconds() {
return totalSeconds;
}
/** @return double representation of the interval day time, accurate to nanoseconds */
public double getDouble() {
return totalSeconds + nanos / 1000000000;
}
/** Ensures that the seconds and nanoseconds fields have consistent sign */
protected void normalizeSecondsAndNanos() {
if (totalSeconds > 0 && nanos < 0) {
--totalSeconds;
nanos += IntervalDayTimeUtils.NANOS_PER_SEC;
} else if (totalSeconds < 0 && nanos > 0) {
++totalSeconds;
nanos -= IntervalDayTimeUtils.NANOS_PER_SEC;
}
}
public void set(int days, int hours, int minutes, int seconds, int nanos) {
long totalSeconds = seconds;
totalSeconds += TimeUnit.DAYS.toSeconds(days);
totalSeconds += TimeUnit.HOURS.toSeconds(hours);
totalSeconds += TimeUnit.MINUTES.toSeconds(minutes);
totalSeconds += TimeUnit.NANOSECONDS.toSeconds(nanos);
nanos = nanos % IntervalDayTimeUtils.NANOS_PER_SEC;
this.totalSeconds = totalSeconds;
this.nanos = nanos;
normalizeSecondsAndNanos();
}
public void set(long seconds, int nanos) {
this.totalSeconds = seconds;
this.nanos = nanos;
normalizeSecondsAndNanos();
}
public void set(BigDecimal totalSecondsBd) {
long totalSeconds = totalSecondsBd.longValue();
BigDecimal fractionalSecs = totalSecondsBd.remainder(BigDecimal.ONE);
int nanos = fractionalSecs.multiply(IntervalDayTimeUtils.NANOS_PER_SEC_BD).intValue();
set(totalSeconds, nanos);
}
public void set(HiveIntervalDayTime other) {
set(other.getTotalSeconds(), other.getNanos());
}
public HiveIntervalDayTime negate() {
return new HiveIntervalDayTime(-getTotalSeconds(), -getNanos());
}
@Override
public int compareTo(HiveIntervalDayTime other) {
long cmp = this.totalSeconds - other.totalSeconds;
if (cmp == 0) {
cmp = this.nanos - other.nanos;
}
if (cmp != 0) {
cmp = cmp > 0 ? 1 : -1;
}
return (int) cmp;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof HiveIntervalDayTime)) {
return false;
}
return 0 == compareTo((HiveIntervalDayTime) obj);
}
/** Return a copy of this object. */
@Override
public Object clone() {
return new HiveIntervalDayTime(totalSeconds, nanos);
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(totalSeconds).append(nanos).toHashCode();
}
@Override
public String toString() {
// If normalize() was used, then day-hour-minute-second-nanos should have the same sign.
// This is currently working with that assumption.
boolean isNegative = (totalSeconds < 0 || nanos < 0);
String daySecondSignStr = isNegative ? "-" : "";
return String.format(
"%s%d %02d:%02d:%02d.%09d",
daySecondSignStr,
Math.abs(getDays()),
Math.abs(getHours()),
Math.abs(getMinutes()),
Math.abs(getSeconds()),
Math.abs(getNanos()));
}
public static HiveIntervalDayTime valueOf(String strVal) {
HiveIntervalDayTime result = null;
if (strVal == null) {
throw new IllegalArgumentException("Interval day-time string was null");
}
Matcher patternMatcher = PATTERN_MATCHER.get();
patternMatcher.reset(strVal);
if (patternMatcher.matches()) {
// Parse out the individual parts
try {
// Sign - whether interval is positive or negative
int sign = 1;
String field = patternMatcher.group(1);
if (field != null && field.equals("-")) {
sign = -1;
}
int days =
sign
* IntervalDayTimeUtils.parseNumericValueWithRange(
"day", patternMatcher.group(2), 0, Integer.MAX_VALUE);
byte hours =
(byte)
(sign
* IntervalDayTimeUtils.parseNumericValueWithRange(
"hour", patternMatcher.group(3), 0, 23));
byte minutes =
(byte)
(sign
* IntervalDayTimeUtils.parseNumericValueWithRange(
"minute", patternMatcher.group(4), 0, 59));
int seconds = 0;
int nanos = 0;
field = patternMatcher.group(5);
if (field != null) {
BigDecimal bdSeconds = new BigDecimal(field);
if (bdSeconds.compareTo(IntervalDayTimeUtils.MAX_INT_BD) > 0) {
throw new IllegalArgumentException("seconds value of " + bdSeconds + " too large");
}
seconds = sign * bdSeconds.intValue();
nanos =
sign
* bdSeconds
.subtract(new BigDecimal(bdSeconds.toBigInteger()))
.multiply(IntervalDayTimeUtils.NANOS_PER_SEC_BD)
.intValue();
}
result = new HiveIntervalDayTime(days, hours, minutes, seconds, nanos);
} catch (Exception err) {
throw new IllegalArgumentException(
"Error parsing interval day-time string: " + strVal, err);
}
} else {
throw new IllegalArgumentException(
"Interval string does not match day-time format of 'd h:m:s.n': " + strVal);
}
return result;
}
// Simple pattern: D H:M:S.nnnnnnnnn
private static final String PARSE_PATTERN = "([+|-])?(\\d+) (\\d+):(\\d+):((\\d+)(\\.(\\d+))?)";
private static final ThreadLocal<Matcher> PATTERN_MATCHER =
new ThreadLocal<Matcher>() {
@Override
protected Matcher initialValue() {
return Pattern.compile(PARSE_PATTERN).matcher("");
}
};
}

View File

@ -0,0 +1,41 @@
/*
* 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.kyuubi.jdbc.hive.common;
import java.math.BigDecimal;
/** DateUtils. Thread-safe class */
public class IntervalDayTimeUtils {
public static final int NANOS_PER_SEC = 1000000000;
public static final BigDecimal MAX_INT_BD = new BigDecimal(Integer.MAX_VALUE);
public static final BigDecimal NANOS_PER_SEC_BD = new BigDecimal(NANOS_PER_SEC);
public static int parseNumericValueWithRange(
String fieldName, String strVal, int minValue, int maxValue) throws IllegalArgumentException {
int result = 0;
if (strVal != null) {
result = Integer.parseInt(strVal);
if (result < minValue || result > maxValue) {
throw new IllegalArgumentException(
String.format(
"%s value %d outside range [%d, %d]", fieldName, result, minValue, maxValue));
}
}
return result;
}
}