blob: b8e1bef4825b26f6fdc0ffe7a8ae382f42233c48 [file]
// 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.
#include <fstream>
#include <memory>
#include "common/exception.h"
#include "core/data_type/data_type_decimal.h"
#include "core/data_type/data_type_number.h"
#include "core/data_type/number_traits.h"
#include "core/extended_types.h"
#include "core/types.h"
#include "exprs/function/cast/cast_test.h"
#include "exprs/function/cast/cast_to_decimal_test.h"
#include "storage/olap_common.h"
#include "testutil/test_util.h"
namespace doris {
/*
TODO, fix:
mysql> select cast('+000999998000.5e-3' as Decimal(9, 3));
+---------------------------------------------+
| cast('+000999998000.5e-3' as Decimal(9, 3)) |
+---------------------------------------------+
| 999998.000 |
+---------------------------------------------+
1 row in set (8.54 sec)
// expected result: 9999999999999999.0
select cast('+0009999999999999999040000000.e-9' as decimal(18,1));
+------------------------------------------------------------+
| cast('+0009999999999999999040000000.e-9' as decimal(18,1)) |
+------------------------------------------------------------+
| 99999999999999999.9 |
+------------------------------------------------------------+
1 row in set (0.65 sec)
PG:
e1
postgres=# select cast('1e' as decimal(18,6));
ERROR: invalid input syntax for type numeric: "1e"
LINE 1: select cast('1e' as decimal(18,6));
postgres=# select cast('.e1' as decimal(18,6));
ERROR: invalid input syntax for type numeric: ".e1"
LINE 1: select cast('.e1' as decimal(18,6));
^
postgres=# select cast('.1e1' as decimal(18,6));
numeric
----------
1.000000
(1 row)
edge cases:
1000 digits
postgres=# select cast('1151111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e-999' as decimal(38, 1));
numeric
---------
1.2
(1 row)
MySQL 8.0
ysql> select cast('1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e-980' as decimal(38, 1));
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| cast('111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 9999999999999999999999999999999999999.9 |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set, 3 warnings (0.00 sec)
*/
TEST_F(FunctionCastToDecimalTest, test_from_string_invalid_input) {
int table_index = 0;
from_string_invalid_input_test_func<Decimal32>(9, 3, table_index++);
}
TEST_F(FunctionCastToDecimalTest, test_from_string_scientific_notation) {
InputTypeSet input_types = {PrimitiveType::TYPE_VARCHAR};
DataSet data_set = {
{{std::string("1.4E+2")}, DECIMAL128V3(140, 0, 15)},
{{std::string(".14E+3")}, DECIMAL128V3(140, 0, 15)},
{{std::string("0.001E+5")}, DECIMAL128V3(100, 0, 15)},
{{std::string("1.E+2")}, DECIMAL128V3(100, 0, 15)},
{{std::string("1.4E+0")}, DECIMAL128V3(1, 400000000000000, 15)},
{{std::string("1.4E-2")}, DECIMAL128V3(0, 14000000000000, 15)},
};
check_function_for_cast<DataTypeDecimal<Decimal128V3::PType>>(input_types, data_set, 15, 38);
}
TEST_F(FunctionCastToDecimalTest, string_parser_scientific_rounding) {
auto parse_decimal128 = [](std::string_view value) {
StringParser::ParseResult result = StringParser::PARSE_SUCCESS;
auto parsed = StringParser::string_to_decimal<TYPE_DECIMAL128I>(value.data(), value.size(),
38, 15, &result);
EXPECT_EQ(result, StringParser::PARSE_SUCCESS);
return parsed;
};
EXPECT_EQ(parse_decimal128("5e-16"), 1);
EXPECT_EQ(parse_decimal128("5e-17"), 0);
EXPECT_EQ(parse_decimal128("9e-17"), 0);
EXPECT_EQ(parse_decimal128("-5e-17"), 0);
EXPECT_EQ(parse_decimal128("0.0000000000000005"), 1);
EXPECT_EQ(parse_decimal128("0.00000000000000005"), 0);
}
TEST_F(FunctionCastToDecimalTest, test_from_bool) {
from_bool_test_func<Decimal32>(9, 0);
from_bool_test_func<Decimal32>(9, 1);
from_bool_test_func<Decimal32>(9, 3);
from_bool_test_func<Decimal32>(9, 8);
from_bool_test_func<Decimal64>(18, 0);
from_bool_test_func<Decimal64>(18, 1);
from_bool_test_func<Decimal64>(18, 9);
from_bool_test_func<Decimal64>(18, 17);
from_bool_test_func<DecimalV2Value>(27, 9);
// from_bool_test_func<DecimalV2Value, 27, 1>();
// from_bool_test_func<DecimalV2Value, 27, 13>();
// from_bool_test_func<DecimalV2Value, 27, 26>();
from_bool_test_func<Decimal128V3>(38, 0);
from_bool_test_func<Decimal128V3>(38, 1);
from_bool_test_func<Decimal128V3>(38, 19);
from_bool_test_func<Decimal128V3>(38, 37);
from_bool_test_func<Decimal256>(76, 0);
from_bool_test_func<Decimal256>(76, 1);
from_bool_test_func<Decimal256>(76, 38);
from_bool_test_func<Decimal256>(76, 75);
}
TEST_F(FunctionCastToDecimalTest, test_from_bool_overflow) {
from_bool_overflow_test_func<Decimal32>();
from_bool_overflow_test_func<Decimal64>();
from_bool_overflow_test_func<DecimalV2Value>();
from_bool_overflow_test_func<Decimal128V3>();
from_bool_overflow_test_func<Decimal256>();
}
} // namespace doris