Skip to content

Commit 3d089c7

Browse files
committed
Add GetString to ColumnDecimal.
It converts the internal integer to a decimal string relative to the scale and precision.
1 parent b8544bb commit 3d089c7

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

clickhouse/columns/decimal.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <sstream>
12
#include "decimal.h"
23

34
namespace
@@ -246,4 +247,39 @@ size_t ColumnDecimal::GetPrecision() const
246247
return type_->As<DecimalType>()->GetPrecision();
247248
}
248249

250+
std::string ColumnDecimal::GetString(size_t index) const {
251+
auto val = At(index);
252+
253+
// Convert the Int128 to a string.
254+
std::stringstream ss;
255+
ss << val;
256+
std::string str = ss.str();
257+
258+
// Start a destination string.
259+
std::stringstream res;
260+
auto scale = GetScale();
261+
262+
// Output a dash for negative values
263+
if (val < 0) {
264+
res << '-';
265+
str.erase(0, 1);
266+
}
267+
268+
if (str.length() <= scale) {
269+
// Append the entire value prepended with zeros after the decimal.
270+
res << "0." << std::string(scale-1, '0') << str;
271+
} else {
272+
// There are digits before the decimal.
273+
auto decAt = str.length() - scale;
274+
res << str.substr(0, decAt);
275+
276+
// Append any digits after the decimal.
277+
if (decAt < str.length()) {
278+
res << '.' << str.substr(decAt);
279+
}
280+
}
281+
282+
return res.str();
283+
}
284+
249285
}

clickhouse/columns/decimal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ class ColumnDecimal : public Column {
3333
void Swap(Column& other) override;
3434
ItemView GetItem(size_t index) const override;
3535

36+
/// Returns a string representation of the Decimal value at \p index.
37+
std::string GetString(size_t index) const;
38+
3639
size_t GetScale() const;
3740
size_t GetPrecision() const;
3841

ut/client_ut.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,9 @@ TEST_P(ClientCase, Decimal) {
841841
auto decimal = [&b](size_t column, size_t row) {
842842
return b[column]->As<ColumnDecimal>()->At(row);
843843
};
844+
auto dec_string = [&b](size_t column, size_t row) {
845+
return b[column]->As<ColumnDecimal>()->GetString(row);
846+
};
844847

845848
EXPECT_EQ(1u, b[0]->As<ColumnUInt64>()->At(0));
846849
EXPECT_EQ("123456789", int128_to_string(decimal(1, 0)));
@@ -849,6 +852,12 @@ TEST_P(ClientCase, Decimal) {
849852
EXPECT_EQ("123456789", int128_to_string(decimal(4, 0)));
850853
EXPECT_EQ("123456789012345678", int128_to_string(decimal(5, 0)));
851854
EXPECT_EQ("1234567890123456789", int128_to_string(decimal(6, 0)));
855+
EXPECT_EQ("12345.6789", dec_string(1, 0));
856+
EXPECT_EQ("123456789.012345678", dec_string(2, 0));
857+
EXPECT_EQ("0.0000000000000000001234567890123456789", dec_string(3, 0));
858+
EXPECT_EQ("12345.6789", dec_string(4, 0));
859+
EXPECT_EQ("123456789.012345678", dec_string(5, 0));
860+
EXPECT_EQ("0.0000000000000000001234567890123456789", dec_string(6, 0));
852861

853862
EXPECT_EQ(2u, b[0]->As<ColumnUInt64>()->At(1));
854863
EXPECT_EQ("999999999", int128_to_string(decimal(1, 1)));
@@ -857,6 +866,12 @@ TEST_P(ClientCase, Decimal) {
857866
EXPECT_EQ("999999999", int128_to_string(decimal(4, 1)));
858867
EXPECT_EQ("999999999999999999", int128_to_string(decimal(5, 1)));
859868
EXPECT_EQ("999999999999999999", int128_to_string(decimal(6, 1)));
869+
EXPECT_EQ("99999.9999", dec_string(1, 1));
870+
EXPECT_EQ("999999999.999999999", dec_string(2, 1));
871+
EXPECT_EQ("0.000000000000000000999999999999999999", dec_string(3, 1));
872+
EXPECT_EQ("99999.9999", dec_string(4, 1));
873+
EXPECT_EQ("999999999.999999999", dec_string(5, 1));
874+
EXPECT_EQ("0.000000000000000000999999999999999999", dec_string(6, 1));
860875

861876
EXPECT_EQ(3u, b[0]->As<ColumnUInt64>()->At(2));
862877
EXPECT_EQ("-999999999", int128_to_string(decimal(1, 2)));
@@ -865,6 +880,12 @@ TEST_P(ClientCase, Decimal) {
865880
EXPECT_EQ("-999999999", int128_to_string(decimal(4, 2)));
866881
EXPECT_EQ("-999999999999999999", int128_to_string(decimal(5, 2)));
867882
EXPECT_EQ("-999999999999999999", int128_to_string(decimal(6, 2)));
883+
EXPECT_EQ("-99999.9999", dec_string(1, 2));
884+
EXPECT_EQ("-999999999.999999999", dec_string(2, 2));
885+
EXPECT_EQ("-0.000000000000000000999999999999999999", dec_string(3, 2));
886+
EXPECT_EQ("-99999.9999", dec_string(4, 2));
887+
EXPECT_EQ("-999999999.999999999", dec_string(5, 2));
888+
EXPECT_EQ("-0.000000000000000000999999999999999999", dec_string(6, 2));
868889

869890
EXPECT_EQ(4u, b[0]->As<ColumnUInt64>()->At(3));
870891
EXPECT_EQ("123456789", int128_to_string(decimal(1, 3)));
@@ -873,6 +894,12 @@ TEST_P(ClientCase, Decimal) {
873894
EXPECT_EQ("123456789", int128_to_string(decimal(4, 3)));
874895
EXPECT_EQ("123456789012345678", int128_to_string(decimal(5, 3)));
875896
EXPECT_EQ("12345678901234567890123456789012345678", int128_to_string(decimal(6, 3)));
897+
EXPECT_EQ("12345.6789", dec_string(1, 3));
898+
EXPECT_EQ("123456789.012345678", dec_string(2, 3));
899+
EXPECT_EQ("1234567890123456789.0123456789012345678", dec_string(3, 3));
900+
EXPECT_EQ("12345.6789", dec_string(4, 3));
901+
EXPECT_EQ("123456789.012345678", dec_string(5, 3));
902+
EXPECT_EQ("1234567890123456789.0123456789012345678", dec_string(6, 3));
876903

877904
EXPECT_EQ(5u, b[0]->As<ColumnUInt64>()->At(4));
878905
EXPECT_EQ("-123456789", int128_to_string(decimal(1, 4)));
@@ -881,6 +908,12 @@ TEST_P(ClientCase, Decimal) {
881908
EXPECT_EQ("-123456789", int128_to_string(decimal(4, 4)));
882909
EXPECT_EQ("-123456789012345678", int128_to_string(decimal(5, 4)));
883910
EXPECT_EQ("-12345678901234567890123456789012345678", int128_to_string(decimal(6, 4)));
911+
EXPECT_EQ("-12345.6789", dec_string(1, 4));
912+
EXPECT_EQ("-123456789.012345678", dec_string(2, 4));
913+
EXPECT_EQ("-1234567890123456789.0123456789012345678", dec_string(3, 4));
914+
EXPECT_EQ("-12345.6789", dec_string(4, 4));
915+
EXPECT_EQ("-123456789.012345678", dec_string(5, 4));
916+
EXPECT_EQ("-1234567890123456789.0123456789012345678", dec_string(6, 4));
884917

885918
EXPECT_EQ(6u, b[0]->As<ColumnUInt64>()->At(5));
886919
EXPECT_EQ("123456780", int128_to_string(decimal(1, 5)));
@@ -889,6 +922,12 @@ TEST_P(ClientCase, Decimal) {
889922
EXPECT_EQ("123456789", int128_to_string(decimal(4, 5)));
890923
EXPECT_EQ("123456789012345678", int128_to_string(decimal(5, 5)));
891924
EXPECT_EQ("12345678901234567890123456789012345678", int128_to_string(decimal(6, 5)));
925+
EXPECT_EQ("12345.6780", dec_string(1, 5));
926+
EXPECT_EQ("123456789.012345678", dec_string(2, 5));
927+
EXPECT_EQ("1234567890123456789.0123456789012345678", dec_string(3, 5));
928+
EXPECT_EQ("12345.6789", dec_string(4, 5));
929+
EXPECT_EQ("123456789.012345678", dec_string(5, 5));
930+
EXPECT_EQ("1234567890123456789.0123456789012345678", dec_string(6, 5));
892931
});
893932
}
894933

0 commit comments

Comments
 (0)