diff --git a/src/DataTypes/Serializations/SerializationTuple.cpp b/src/DataTypes/Serializations/SerializationTuple.cpp index 399ad870d60..5fb4337cdfe 100644 --- a/src/DataTypes/Serializations/SerializationTuple.cpp +++ b/src/DataTypes/Serializations/SerializationTuple.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -526,36 +527,17 @@ void SerializationTuple::serializeTextXML(const IColumn & column, size_t row_num void SerializationTuple::serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const { - for (size_t i = 0; i < elems.size(); ++i) - { - if (i != 0) - writeChar(settings.csv.tuple_delimiter, ostr); - elems[i]->serializeTextCSV(extractElementColumn(column, i), row_num, ostr, settings); - } + WriteBufferFromOwnString wb; + serializeText(column, row_num, wb, settings); + writeCSV(wb.str(), ostr); } void SerializationTuple::deserializeTextCSV(IColumn & column, ReadBuffer & istr, const FormatSettings & settings) const { - addElementSafe(elems.size(), column, [&] - { - const size_t size = elems.size(); - for (size_t i = 0; i < size; ++i) - { - if (i != 0) - { - skipWhitespaceIfAny(istr); - assertChar(settings.csv.tuple_delimiter, istr); - skipWhitespaceIfAny(istr); - } - - auto & element_column = extractElementColumn(column, i); - if (settings.null_as_default && !isColumnNullableOrLowCardinalityNullable(element_column)) - SerializationNullable::deserializeNullAsDefaultOrNestedTextCSV(element_column, istr, settings, elems[i]); - else - elems[i]->deserializeTextCSV(element_column, istr, settings); - } - return true; - }); + String s; + readCSV(s, istr, settings.csv); + ReadBufferFromString rb(s); + deserializeText(column, rb, settings, true); } bool SerializationTuple::tryDeserializeTextCSV(IColumn & column, ReadBuffer & istr, const FormatSettings & settings) const diff --git a/src/Formats/EscapingRuleUtils.cpp b/src/Formats/EscapingRuleUtils.cpp index 577988871f3..c0ff67dc462 100644 --- a/src/Formats/EscapingRuleUtils.cpp +++ b/src/Formats/EscapingRuleUtils.cpp @@ -303,8 +303,8 @@ DataTypePtr tryInferDataTypeByEscapingRule(const String & field, const FormatSet /// Try to determine the type of value inside quotes auto type = tryInferDataTypeForSingleField(data, format_settings); - /// If we couldn't infer any type or it's tuple in quotes or it's a number and csv.try_infer_numbers_from_strings = 0, we determine it as a string. - if (!type || isTuple(type) || (isNumber(type) && !format_settings.csv.try_infer_numbers_from_strings)) + /// If we couldn't infer any type or it's a number and csv.try_infer_numbers_from_strings = 0, we determine it as a string. + if (!type || (isNumber(type) && !format_settings.csv.try_infer_numbers_from_strings)) return std::make_shared(); return type; diff --git a/tests/queries/0_stateless/02977_csv_format_support_tuple.reference b/tests/queries/0_stateless/02977_csv_format_support_tuple.reference new file mode 100644 index 00000000000..11902398999 --- /dev/null +++ b/tests/queries/0_stateless/02977_csv_format_support_tuple.reference @@ -0,0 +1,6 @@ +Nullable(String) +Nullable(Int64) +Array(Nullable(String)) +Map(String, Nullable(Int64)) +Tuple(Nullable(String), Nullable(Int64), Map(String, Nullable(Int64))) +20240305 1 ['s','d'] {'a':2} ('222',33,{'abc':5}) diff --git a/tests/queries/0_stateless/02977_csv_format_support_tuple.sql b/tests/queries/0_stateless/02977_csv_format_support_tuple.sql new file mode 100644 index 00000000000..b4726391925 --- /dev/null +++ b/tests/queries/0_stateless/02977_csv_format_support_tuple.sql @@ -0,0 +1,4 @@ +-- Tags: no-fasttest +insert into function file('02977_1.csv') select '20240305', 1, ['s', 'd'], map('a', 2), tuple('222', 33, map('abc', 5)); +desc file('02977_1.csv'); +select * from file('02977_1.csv') settings max_threads=1;