@@ -10,7 +10,7 @@ namespace {
10
10
11
11
class TCsvToYdbConverter {
12
12
public:
13
- explicit TCsvToYdbConverter (TTypeParser& parser, const TString& nullValue)
13
+ explicit TCsvToYdbConverter (TTypeParser& parser, const std::optional< TString> & nullValue)
14
14
: Parser(parser)
15
15
, NullValue(nullValue)
16
16
{
@@ -106,15 +106,30 @@ class TCsvToYdbConverter {
106
106
case EPrimitiveType::DyNumber:
107
107
Builder.DyNumber (token);
108
108
break ;
109
- case EPrimitiveType::Date:
110
- Builder.Date (TInstant::Days (GetArithmetic<ui16>(token)));
109
+ case EPrimitiveType::Date: {
110
+ TInstant date;
111
+ if (!TInstant::TryParseIso8601 (token, date)) {
112
+ date = TInstant::Days (GetArithmetic<ui16>(token));
113
+ }
114
+ Builder.Date (date);
111
115
break ;
112
- case EPrimitiveType::Datetime:
113
- Builder.Datetime (TInstant::Seconds (GetArithmetic<ui32>(token)));
116
+ }
117
+ case EPrimitiveType::Datetime: {
118
+ TInstant datetime;
119
+ if (!TInstant::TryParseIso8601 (token, datetime)) {
120
+ datetime = TInstant::Seconds (GetArithmetic<ui32>(token));
121
+ }
122
+ Builder.Datetime (datetime);
114
123
break ;
115
- case EPrimitiveType::Timestamp:
116
- Builder.Timestamp (TInstant::MicroSeconds (GetArithmetic<ui64>(token)));
124
+ }
125
+ case EPrimitiveType::Timestamp: {
126
+ TInstant timestamp;
127
+ if (!TInstant::TryParseIso8601 (token, timestamp)) {
128
+ timestamp = TInstant::MicroSeconds (GetArithmetic<ui64>(token));
129
+ }
130
+ Builder.Timestamp (timestamp);
117
131
break ;
132
+ }
118
133
case EPrimitiveType::Interval:
119
134
Builder.Interval (GetArithmetic<i64>(token));
120
135
break ;
@@ -144,7 +159,7 @@ class TCsvToYdbConverter {
144
159
}
145
160
case TTypeParser::ETypeKind::Optional: {
146
161
Parser.OpenOptional ();
147
- if (token == NullValue) {
162
+ if (NullValue && token == NullValue) {
148
163
Builder.EmptyOptional (GetType ());
149
164
} else {
150
165
Builder.BeginOptional ();
@@ -247,13 +262,13 @@ class TCsvToYdbConverter {
247
262
248
263
private:
249
264
TTypeParser& Parser;
250
- const TString NullValue = " " ;
265
+ const std::optional< TString> NullValue = " " ;
251
266
TValueBuilder Builder;
252
267
};
253
268
254
269
}
255
270
256
- TCsvParser::TCsvParser (TString&& headerRow, const char delimeter, const TString& nullValue,
271
+ TCsvParser::TCsvParser (TString&& headerRow, const char delimeter, const std::optional< TString> & nullValue,
257
272
const std::map<TString, TType>* paramTypes,
258
273
const std::map<TString, TString>* paramSources)
259
274
: HeaderRow(std::move(headerRow))
@@ -266,7 +281,7 @@ TCsvParser::TCsvParser(TString&& headerRow, const char delimeter, const TString&
266
281
Header = static_cast <TVector<TString>>(splitter);
267
282
}
268
283
269
- TCsvParser::TCsvParser (TVector<TString>&& header, const char delimeter, const TString& nullValue,
284
+ TCsvParser::TCsvParser (TVector<TString>&& header, const char delimeter, const std::optional< TString> & nullValue,
270
285
const std::map<TString, TType>* paramTypes,
271
286
const std::map<TString, TString>* paramSources)
272
287
: Header(std::move(header))
@@ -333,7 +348,7 @@ void TCsvParser::GetValue(TString&& data, TValueBuilder& builder, const TType& t
333
348
parser.OpenStruct ();
334
349
while (parser.TryNextMember ()) {
335
350
TString name = parser.GetMemberName ();
336
- if (name == NullValue ) {
351
+ if (name == " __ydb_skip_column_name " ) {
337
352
continue ;
338
353
}
339
354
auto fieldIt = fields.find (name);
@@ -353,7 +368,7 @@ TType TCsvParser::GetColumnsType() const {
353
368
if (ParamTypes->find (colName) != ParamTypes->end ()) {
354
369
builder.AddMember (colName, ParamTypes->at (colName));
355
370
} else {
356
- builder.AddMember (NullValue , TTypeBuilder ().Build ());
371
+ builder.AddMember (" __ydb_skip_column_name " , TTypeBuilder ().Build ());
357
372
}
358
373
}
359
374
builder.EndStruct ();
0 commit comments