From 5a4985fe27426a9a66c541ec9077e24222c27a07 Mon Sep 17 00:00:00 2001 From: PHO Date: Fri, 17 Sep 2021 11:12:05 +0900 Subject: [PATCH 1/2] Do not initialize std::pair with a std::tuple GCC/libstdc++ does not allow this and emits a compilation error. The standard does not say they are supposed to be interchangeable. --- src/Storages/PostgreSQL/MaterializedPostgreSQLConsumer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storages/PostgreSQL/MaterializedPostgreSQLConsumer.cpp b/src/Storages/PostgreSQL/MaterializedPostgreSQLConsumer.cpp index 1fc279bff23..0fd9d0a0856 100644 --- a/src/Storages/PostgreSQL/MaterializedPostgreSQLConsumer.cpp +++ b/src/Storages/PostgreSQL/MaterializedPostgreSQLConsumer.cpp @@ -433,7 +433,7 @@ void MaterializedPostgreSQLConsumer::processReplicationMessage(const char * repl if (new_relation_definition) { - current_schema_data.column_identifiers.emplace_back(std::make_tuple(data_type_id, type_modifier)); + current_schema_data.column_identifiers.emplace_back(std::make_pair(data_type_id, type_modifier)); } else { From 3c4b1ea9c5abfffa3e497e3c2e5c16f7e242a6dc Mon Sep 17 00:00:00 2001 From: PHO Date: Fri, 17 Sep 2021 11:18:01 +0900 Subject: [PATCH 2/2] New setting: output_format_csv_null_representation This is the same as output_format_tsv_null_representation but is for CSV output. --- docs/en/operations/settings/settings.md | 37 +++++++++++++++++++ src/Core/Settings.h | 1 + .../Serializations/SerializationNullable.cpp | 2 +- src/Formats/FormatFactory.cpp | 1 + src/Formats/FormatSettings.h | 1 + ...9_output_csv_null_representation.reference | 4 ++ .../02029_output_csv_null_representation.sql | 16 ++++++++ 7 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tests/queries/0_stateless/02029_output_csv_null_representation.reference create mode 100644 tests/queries/0_stateless/02029_output_csv_null_representation.sql diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index e3a46d46cd7..330d38db705 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -2833,6 +2833,43 @@ Possible values: Default value: `1`. +## output_format_csv_null_representation {#output_format_csv_null_representation} + +Defines the representation of `NULL` for [CSV](../../interfaces/formats.md#csv) output format. User can set any string as a value, for example, `My NULL`. + +Default value: `\N`. + +**Examples** + +Query + +```sql +SELECT * from csv_custom_null FORMAT CSV; +``` + +Result + +```text +788 +\N +\N +``` + +Query + +```sql +SET output_format_csv_null_representation = 'My NULL'; +SELECT * FROM csv_custom_null FORMAT CSV; +``` + +Result + +```text +788 +My NULL +My NULL +``` + ## output_format_tsv_null_representation {#output_format_tsv_null_representation} Defines the representation of `NULL` for [TSV](../../interfaces/formats.md#tabseparated) output format. User can set any string as a value, for example, `My NULL`. diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 0e29168f906..58c100e7b64 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -574,6 +574,7 @@ class IColumn; M(String, output_format_avro_codec, "", "Compression codec used for output. Possible values: 'null', 'deflate', 'snappy'.", 0) \ M(UInt64, output_format_avro_sync_interval, 16 * 1024, "Sync interval in bytes.", 0) \ M(Bool, output_format_tsv_crlf_end_of_line, false, "If it is set true, end of line in TSV format will be \\r\\n instead of \\n.", 0) \ + M(String, output_format_csv_null_representation, "\\N", "Custom NULL representation in CSV format", 0) \ M(String, output_format_tsv_null_representation, "\\N", "Custom NULL representation in TSV format", 0) \ M(Bool, output_format_decimal_trailing_zeros, false, "Output trailing zeros when printing Decimal values. E.g. 1.230000 instead of 1.23.", 0) \ \ diff --git a/src/DataTypes/Serializations/SerializationNullable.cpp b/src/DataTypes/Serializations/SerializationNullable.cpp index 4de2b08c043..b607d5871d6 100644 --- a/src/DataTypes/Serializations/SerializationNullable.cpp +++ b/src/DataTypes/Serializations/SerializationNullable.cpp @@ -327,7 +327,7 @@ void SerializationNullable::serializeTextCSV(const IColumn & column, size_t row_ const ColumnNullable & col = assert_cast(column); if (col.isNullAt(row_num)) - writeCString("\\N", ostr); + writeString(settings.csv.null_representation, ostr); else nested->serializeTextCSV(col.getNestedColumn(), row_num, ostr, settings); } diff --git a/src/Formats/FormatFactory.cpp b/src/Formats/FormatFactory.cpp index a014f85d45f..24132e9c585 100644 --- a/src/Formats/FormatFactory.cpp +++ b/src/Formats/FormatFactory.cpp @@ -60,6 +60,7 @@ FormatSettings getFormatSettings(ContextPtr context, const Settings & settings) format_settings.csv.delimiter = settings.format_csv_delimiter; format_settings.csv.empty_as_default = settings.input_format_defaults_for_omitted_fields; format_settings.csv.input_format_enum_as_number = settings.input_format_csv_enum_as_number; + format_settings.csv.null_representation = settings.output_format_csv_null_representation; format_settings.csv.unquoted_null_literal_as_null = settings.input_format_csv_unquoted_null_literal_as_null; format_settings.csv.input_format_arrays_as_nested_csv = settings.input_format_csv_arrays_as_nested_csv; format_settings.custom.escaping_rule = settings.format_custom_escaping_rule; diff --git a/src/Formats/FormatSettings.h b/src/Formats/FormatSettings.h index 3e1e00584c0..3a274f99a5c 100644 --- a/src/Formats/FormatSettings.h +++ b/src/Formats/FormatSettings.h @@ -76,6 +76,7 @@ struct FormatSettings bool crlf_end_of_line = false; bool input_format_enum_as_number = false; bool input_format_arrays_as_nested_csv = false; + String null_representation = "\\N"; } csv; struct Custom diff --git a/tests/queries/0_stateless/02029_output_csv_null_representation.reference b/tests/queries/0_stateless/02029_output_csv_null_representation.reference new file mode 100644 index 00000000000..a5174f4424f --- /dev/null +++ b/tests/queries/0_stateless/02029_output_csv_null_representation.reference @@ -0,0 +1,4 @@ +# output_format_csv_null_representation should initially be \\N +"val1",\N,"val3" +# Changing output_format_csv_null_representation +"val1",∅,"val3" diff --git a/tests/queries/0_stateless/02029_output_csv_null_representation.sql b/tests/queries/0_stateless/02029_output_csv_null_representation.sql new file mode 100644 index 00000000000..772c6c89144 --- /dev/null +++ b/tests/queries/0_stateless/02029_output_csv_null_representation.sql @@ -0,0 +1,16 @@ +DROP TABLE IF EXISTS test_data; +CREATE TABLE test_data ( + col1 Nullable(String), + col2 Nullable(String), + col3 Nullable(String) +) ENGINE = Memory; + +INSERT INTO test_data VALUES ('val1', NULL, 'val3'); + +SELECT '# output_format_csv_null_representation should initially be \\N'; +SELECT * FROM test_data FORMAT CSV; + +SELECT '# Changing output_format_csv_null_representation'; +SET output_format_csv_null_representation = '∅'; +SELECT * FROM test_data FORMAT CSV; +SET output_format_csv_null_representation = '\\N';