diff --git a/dbms/src/DataTypes/DataTypesDecimal.cpp b/dbms/src/DataTypes/DataTypesDecimal.cpp index 8ec5bb6664fcc8ab13fa117242afc8c14481b67d..ad33e298d3badd37fc11afe83ccd2883b8defa08 100644 --- a/dbms/src/DataTypes/DataTypesDecimal.cpp +++ b/dbms/src/DataTypes/DataTypesDecimal.cpp @@ -52,10 +52,13 @@ void DataTypeDecimal::serializeText(const IColumn & column, size_t row_num, W } template -void DataTypeDecimal::readText(T & x, ReadBuffer & istr, UInt32 precision, UInt32 scale) +void DataTypeDecimal::readText(T & x, ReadBuffer & istr, UInt32 precision, UInt32 scale, bool csv) { UInt32 unread_scale = scale; - readDecimalText(istr, x, precision, unread_scale); + if (csv) + readCSVDecimalText(istr, x, precision, unread_scale); + else + readDecimalText(istr, x, precision, unread_scale); x *= getScaleMultiplier(unread_scale); } @@ -67,6 +70,13 @@ void DataTypeDecimal::deserializeText(IColumn & column, ReadBuffer & istr, co static_cast(column).getData().push_back(x); } +template +void DataTypeDecimal::deserializeTextCSV(IColumn & column, ReadBuffer & istr, const FormatSettings &) const +{ + T x; + readText(x, istr, true); + static_cast(column).getData().push_back(x); +} template T DataTypeDecimal::parseFromString(const String & str) const diff --git a/dbms/src/DataTypes/DataTypesDecimal.h b/dbms/src/DataTypes/DataTypesDecimal.h index e001c094af12ac2a3f9d2451120f1a2e5ace2928..d127d5034619ff6d6e6df18d2e1c9b128e740a0f 100644 --- a/dbms/src/DataTypes/DataTypesDecimal.h +++ b/dbms/src/DataTypes/DataTypesDecimal.h @@ -91,6 +91,7 @@ public: void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings &) const override; void deserializeText(IColumn & column, ReadBuffer & istr, const FormatSettings &) const override; + void deserializeTextCSV(IColumn & column, ReadBuffer & istr, const FormatSettings &) const override; void serializeBinary(const Field & field, WriteBuffer & ostr) const override; void serializeBinary(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override; @@ -175,8 +176,8 @@ public: T parseFromString(const String & str) const; - void readText(T & x, ReadBuffer & istr) const { readText(x, istr, precision, scale); } - static void readText(T & x, ReadBuffer & istr, UInt32 precision, UInt32 scale); + void readText(T & x, ReadBuffer & istr, bool csv = false) const { readText(x, istr, precision, scale, csv); } + static void readText(T & x, ReadBuffer & istr, UInt32 precision, UInt32 scale, bool csv = false); static T getScaleMultiplier(UInt32 scale); private: diff --git a/dbms/src/IO/readFloatText.h b/dbms/src/IO/readFloatText.h index 01303886b7ee2ddc6a86f5e9ebfa13d5a405b4f6..d76d5fd5bd0e9e119221d436beda5b1533bac1b6 100644 --- a/dbms/src/IO/readFloatText.h +++ b/dbms/src/IO/readFloatText.h @@ -668,6 +668,22 @@ inline void readDecimalText(ReadBuffer & buf, T & x, unsigned int precision, uns scale += exponent; } +template +inline void readCSVDecimalText(ReadBuffer & buf, T & x, unsigned int precision, unsigned int & scale) +{ + if (buf.eof()) + throwReadAfterEOF(); + + char maybe_quote = *buf.position(); + + if (maybe_quote == '\'' || maybe_quote == '\"') + ++buf.position(); + + readDecimalText(buf, x, precision, scale, false); + + if (maybe_quote == '\'' || maybe_quote == '\"') + assertChar(maybe_quote, buf); +} template void readFloatTextPrecise(T & x, ReadBuffer & in) { readFloatTextPreciseImpl(x, in); } template bool tryReadFloatTextPrecise(T & x, ReadBuffer & in) { return readFloatTextPreciseImpl(x, in); } diff --git a/dbms/tests/queries/0_stateless/00861_decimal_quoted_csv.reference b/dbms/tests/queries/0_stateless/00861_decimal_quoted_csv.reference new file mode 100644 index 0000000000000000000000000000000000000000..6a2192268356caa4dc2a89765902faf0b2c5a4f5 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00861_decimal_quoted_csv.reference @@ -0,0 +1,5 @@ +1 1.00 1.00 1.00 +2 -1.00 -1.00 -1.00 +3 1.00 1.00 1.00 +4 -0.10 -0.10 -0.10 +5 0.01 0.01 0.01 diff --git a/dbms/tests/queries/0_stateless/00861_decimal_quoted_csv.sql b/dbms/tests/queries/0_stateless/00861_decimal_quoted_csv.sql new file mode 100644 index 0000000000000000000000000000000000000000..100fc47d22e07ec0168f820635f5af09e5953956 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00861_decimal_quoted_csv.sql @@ -0,0 +1,17 @@ +DROP TABLE IF EXISTS test; +CREATE TABLE test (key UInt64, d32 Decimal32(2), d64 Decimal64(2), d128 Decimal128(2)) ENGINE = Memory; + +INSERT INTO test FORMAT CSV "1","1","1","1" +; +INSERT INTO test FORMAT CSV "2","-1","-1","-1" +; +INSERT INTO test FORMAT CSV "3","1.0","1.0","1.0" +; +INSERT INTO test FORMAT CSV "4","-0.1","-0.1","-0.1" +; +INSERT INTO test FORMAT CSV "5","0.010","0.010","0.010" +; + +SELECT * FROM test ORDER BY key; + +DROP TABLE test;