1#pragma once
2
3#include <Core/Types.h>
4#include <functional>
5#include <optional>
6#include <Formats/FormatSchemaInfo.h>
7#include <Formats/FormatSettings.h>
8
9namespace DB
10{
11
12class Block;
13
14struct ParsedTemplateFormatString
15{
16 enum class ColumnFormat
17 {
18 None,
19 Escaped,
20 Quoted,
21 Csv,
22 Json,
23 Xml,
24 Raw
25 };
26
27 /// Format string has syntax: "Delimiter0 ${ColumnName0:Format0} Delimiter1 ${ColumnName1:Format1} Delimiter2"
28 /// The following vectors is filled with corresponding values, delimiters.size() - 1 = formats.size() = format_idx_to_column_idx.size()
29 /// If format_idx_to_column_idx[i] has no value, then TemplateRowInputFormat will skip i-th column.
30
31 std::vector<String> delimiters;
32 std::vector<ColumnFormat> formats;
33 std::vector<std::optional<size_t>> format_idx_to_column_idx;
34
35 /// For diagnostic info
36 Strings column_names;
37
38 typedef std::function<std::optional<size_t>(const String &)> ColumnIdxGetter;
39
40 ParsedTemplateFormatString() = default;
41 ParsedTemplateFormatString(const FormatSchemaInfo & schema, const ColumnIdxGetter & idx_by_name);
42
43 void parse(const String & format_string, const ColumnIdxGetter & idx_by_name);
44
45 static ColumnFormat stringToFormat(const String & format);
46 static String formatToString(ColumnFormat format);
47 static const char * readMayBeQuotedColumnNameInto(const char * pos, size_t size, String & s);
48 size_t columnsCount() const;
49
50 String dump() const;
51 [[noreturn]] void throwInvalidFormat(const String & message, size_t column) const;
52
53 static ParsedTemplateFormatString setupCustomSeparatedResultsetFormat(const FormatSettings::Custom & settings);
54 static ParsedTemplateFormatString setupCustomSeparatedRowFormat(const FormatSettings::Custom & settings, const Block & sample);
55};
56
57}
58
59