@Override
    public ByteBuffer getHashValue(Type type) {
        ByteBuffer buffer;
        // no need to consider the overflow when cast decimal to other type, because this func only be used when querying, not storing.
        // e.g. For column A with type INT, the data stored certainly no overflow.
        switch (type.getPrimitiveType()) {
            case TINYINT:
                buffer = ByteBuffer.allocate(8);
                buffer.order(ByteOrder.LITTLE_ENDIAN);
                buffer.put(value.byteValue());
                break;
            case SMALLINT:
                buffer = ByteBuffer.allocate(8);
                buffer.order(ByteOrder.LITTLE_ENDIAN);
                buffer.putShort(value.shortValue());
                break;
            case INT:
                buffer = ByteBuffer.allocate(8);
                buffer.order(ByteOrder.LITTLE_ENDIAN);
                buffer.putInt(value.intValue());
                break;
            case BIGINT:
                buffer = ByteBuffer.allocate(8);
                buffer.order(ByteOrder.LITTLE_ENDIAN);
                buffer.putLong(value.longValue());
                break;
            case DECIMALV2:
                buffer = getHashValueOfDecimalV2();
                break;
            case DECIMAL32:
            case DECIMAL64: {
                checkType(type);
                buffer = ByteBuffer.allocate(8);
                buffer.order(ByteOrder.LITTLE_ENDIAN);
                int scale = ((ScalarType) type).getScalarScale();
                BigDecimal scaledValue = value.multiply(SCALE_FACTOR[scale]);
                if (type.getPrimitiveType() == PrimitiveType.DECIMAL32) {
                    buffer.putInt(scaledValue.intValue());
                } else {
                    buffer.putLong(scaledValue.longValue());
                }
                break;
            }
            case DECIMAL128: {
                checkType(type);
                int precision = ((ScalarType) type).getScalarPrecision();
                int scale = ((ScalarType) type).getScalarScale();
                if (precision == 27 && scale == 9) {
                    buffer = getHashValueOfDecimalV2();
                } else {
                    BigDecimal scaledValue = value.multiply(SCALE_FACTOR[scale]);
                    try {
                        LargeIntLiteral largeIntLiteral = new LargeIntLiteral(scaledValue.toBigInteger().toString());
                        return largeIntLiteral.getHashValue(Type.LARGEINT);
                    } catch (AnalysisException e) {
                        throw new InternalError(e.getMessage());
                    }
                }
                break;
            }
            default:
                return super.getHashValue(type);
        }
        buffer.flip();
        return buffer;
    }
@Test
    public void testGetHashValueOfDecimal128p27s9() throws AnalysisException {
        String[] testCases = new String[] {
                "0.0",
                Strings.repeat("9", 18) + "." + Strings.repeat("9", 9),
                "+" + Strings.repeat("9", 18) + "." + Strings.repeat("9", 9),
                "0.1",
                "-0.1",
                "123456789123456789.9654321",
                "-123456789123456789.9654321",
                "1." + Strings.repeat("9", 9),
                "-1." + Strings.repeat("0", 8) + "1",
                "3.1415926",
                "-3.1415926",
                "0.000000001",
                "-0.000000001",
        };
        for (String tc : testCases) {
            DecimalLiteral decimalLiteral = new DecimalLiteral(tc);
            ByteBuffer a = decimalLiteral.getHashValue(Type.DECIMALV2);
            ByteBuffer b = decimalLiteral.getHashValue(ScalarType.createDecimalV3Type(PrimitiveType.DECIMAL128, 27, 9));
            Assert.assertEquals(a.limit(), 12);
            Assert.assertEquals(a.limit(), b.limit());
            Assert.assertEquals(a.getLong(), b.getLong());
            Assert.assertEquals(a.getInt(), b.getInt());
        }
    }