Skip to content

Commit a157fab

Browse files
committed
Feat ADO.NET: Added YSON type support
1 parent 523bbd8 commit a157fab

File tree

8 files changed

+53
-9
lines changed

8 files changed

+53
-9
lines changed

src/Ydb.Sdk/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
- Feat ADO.NET: Added YSON type support (YdbDbType.Yson) with byte[] values.
2+
13
## v0.23.0
24

35
- Feat ADO.NET: `YdbDataSource.OpenRetryableConnectionAsync` opens a retryable connection with automatic retries for transient failures.

src/Ydb.Sdk/src/Ado/Internal/YdbTypedValueExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ internal static TypedValue Decimal(this decimal value, byte precision, byte scal
119119

120120
internal static TypedValue Bytes(this byte[] value) => MakePrimitiveTypedValue(Type.Types.PrimitiveTypeId.String,
121121
new Ydb.Value { BytesValue = ByteString.CopyFrom(value) });
122+
123+
internal static TypedValue Yson(this byte[] value) => MakePrimitiveTypedValue(Type.Types.PrimitiveTypeId.Yson,
124+
new Ydb.Value { BytesValue = ByteString.CopyFrom(value) });
122125

123126
internal static TypedValue Json(this string value) => MakeText(Type.Types.PrimitiveTypeId.Json, value);
124127

src/Ydb.Sdk/src/Ado/Internal/YdbValueExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ internal static TimeSpan GetInterval64(this Ydb.Value value) =>
5353
TimeSpan.FromTicks(value.Int64Value * TimeSpanUtils.TicksPerMicrosecond);
5454

5555
internal static byte[] GetBytes(this Ydb.Value value) => value.BytesValue.ToByteArray();
56+
57+
internal static byte[] GetYson(this Ydb.Value value) => value.BytesValue.ToByteArray();
5658

5759
internal static string GetText(this Ydb.Value value) => value.TextValue;
5860

src/Ydb.Sdk/src/Ado/YdbDataReader.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,18 @@ public override byte GetByte(int ordinal) =>
9494

9595
public sbyte GetSByte(int ordinal) => GetPrimitiveValue(Type.Types.PrimitiveTypeId.Int8, ordinal).GetInt8();
9696

97-
public byte[] GetBytes(int ordinal) => GetPrimitiveValue(Type.Types.PrimitiveTypeId.String, ordinal).GetBytes();
97+
public byte[] GetBytes(int ordinal)
98+
{
99+
var type = UnwrapColumnType(ordinal);
100+
return type.TypeId switch
101+
{
102+
Type.Types.PrimitiveTypeId.String => CurrentRow[ordinal].GetBytes(),
103+
Type.Types.PrimitiveTypeId.Yson => CurrentRow[ordinal].GetYson(),
104+
_ => throw InvalidCastException(Type.Types.PrimitiveTypeId.String, ordinal)
105+
};
106+
}
107+
108+
public byte[] GetYson(int ordinal) => GetPrimitiveValue(Type.Types.PrimitiveTypeId.Yson, ordinal).GetYson();
98109

99110
public override long GetBytes(int ordinal, long dataOffset, byte[]? buffer, int bufferOffset, int length)
100111
{
@@ -281,6 +292,7 @@ or Type.Types.PrimitiveTypeId.Timestamp
281292
or Type.Types.PrimitiveTypeId.JsonDocument
282293
or Type.Types.PrimitiveTypeId.Json => typeof(string),
283294
Type.Types.PrimitiveTypeId.String => typeof(byte[]),
295+
Type.Types.PrimitiveTypeId.Yson => typeof(byte[]),
284296
Type.Types.PrimitiveTypeId.Uuid => typeof(Guid),
285297
_ => throw new YdbException($"Unsupported ydb type {type}")
286298
};
@@ -440,6 +452,7 @@ public override object GetValue(int ordinal)
440452
Type.Types.PrimitiveTypeId.Utf8 => ydbValue.GetText(),
441453
Type.Types.PrimitiveTypeId.Json => ydbValue.GetJson(),
442454
Type.Types.PrimitiveTypeId.JsonDocument => ydbValue.GetJsonDocument(),
455+
Type.Types.PrimitiveTypeId.Yson => ydbValue.GetYson(),
443456
Type.Types.PrimitiveTypeId.String => ydbValue.GetBytes(),
444457
Type.Types.PrimitiveTypeId.Uuid => ydbValue.GetUuid(),
445458
_ => throw new YdbException($"Unsupported ydb type {GetColumnType(ordinal)}")
@@ -707,7 +720,7 @@ private class Metadata : IMetadata
707720
public Metadata(ResultSet resultSet)
708721
{
709722
Columns = resultSet.Columns;
710-
ColumnNameToOrdinal = ColumnNameToOrdinal = Columns
723+
ColumnNameToOrdinal = Columns
711724
.Select((c, idx) => (c.Name, Index: idx))
712725
.ToDictionary(t => t.Name, t => t.Index);
713726
RowsCount = resultSet.Rows.Count;

src/Ydb.Sdk/src/Ado/YdbParameter.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public sealed class YdbParameter : DbParameter
3333
{ YdbDbType.Float, Type.Types.PrimitiveTypeId.Float.Null() },
3434
{ YdbDbType.Double, Type.Types.PrimitiveTypeId.Double.Null() },
3535
{ YdbDbType.Uuid, Type.Types.PrimitiveTypeId.Uuid.Null() },
36+
{ YdbDbType.Yson, Type.Types.PrimitiveTypeId.Yson.Null() },
3637
{ YdbDbType.Json, Type.Types.PrimitiveTypeId.Json.Null() },
3738
{ YdbDbType.JsonDocument, Type.Types.PrimitiveTypeId.JsonDocument.Null() },
3839
{ YdbDbType.Date32, Type.Types.PrimitiveTypeId.Date32.Null() },
@@ -155,6 +156,7 @@ internal TypedValue TypedValue
155156
YdbDbType.Double => MakeDouble(value),
156157
YdbDbType.Decimal when value is decimal decimalValue => Decimal(decimalValue),
157158
YdbDbType.Bytes => MakeBytes(value),
159+
YdbDbType.Yson => MakeYson(value),
158160
YdbDbType.Json when value is string stringValue => stringValue.Json(),
159161
YdbDbType.JsonDocument when value is string stringValue => stringValue.JsonDocument(),
160162
YdbDbType.Uuid when value is Guid guidValue => guidValue.Uuid(),
@@ -239,6 +241,13 @@ internal TypedValue TypedValue
239241
MemoryStream memoryStream => memoryStream.ToArray().Bytes(),
240242
_ => throw ValueTypeNotSupportedException
241243
};
244+
245+
private TypedValue MakeYson(object value) => value switch
246+
{
247+
byte[] bytesValue => bytesValue.Yson(),
248+
MemoryStream memoryStream => memoryStream.ToArray().Yson(),
249+
_ => throw ValueTypeNotSupportedException
250+
};
242251

243252
private TypedValue MakeDate(object value) => value switch
244253
{

src/Ydb.Sdk/src/Ado/YdbType/YdbDbType.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ public enum YdbDbType
104104
/// This type is an alias for the deprecated <c>Utf8</c> type.
105105
/// </remarks>
106106
Text,
107+
108+
/// <summary>
109+
/// YSON in binary form (passed/returned as byte[]).
110+
/// </summary>
111+
/// <remarks>
112+
/// Can't be used in the primary key.
113+
/// </remarks>
114+
Yson,
107115

108116
/// <summary>
109117
/// JSON represented as text.

src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbParameterTests.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ CustomDecimalColumn Decimal(35, 5) NOT NULL,
343343
IntervalColumn Interval NOT NULL,
344344
JsonColumn Json NOT NULL,
345345
JsonDocumentColumn JsonDocument NOT NULL,
346+
YsonColumn Yson NOT NULL,
346347
Date32Column Date32 NOT NULL,
347348
Datetime64Column DateTime64 NOT NULL,
348349
Timestamp64Column Timestamp64 NOT NULL,
@@ -359,13 +360,13 @@ PRIMARY KEY (Int32Column)
359360
Int32Column, BoolColumn, Int64Column, Int16Column, Int8Column, FloatColumn, DoubleColumn,
360361
DefaultDecimalColumn, CustomDecimalColumn, Uint8Column, Uint16Column, Uint32Column,
361362
Uint64Column, TextColumn, BytesColumn, DateColumn, DatetimeColumn, TimestampColumn,
362-
IntervalColumn, JsonColumn, JsonDocumentColumn, Date32Column, Datetime64Column,
363+
IntervalColumn, JsonColumn, JsonDocumentColumn, YsonColumn, Date32Column, Datetime64Column,
363364
Timestamp64Column, Interval64Column
364365
) VALUES (
365366
@Int32Column, @BoolColumn, @Int64Column, @Int16Column, @Int8Column, @FloatColumn,
366367
@DoubleColumn, @DefaultDecimalColumn, @CustomDecimalColumn, @Uint8Column, @Uint16Column,
367368
@Uint32Column, @Uint64Column, @TextColumn, @BytesColumn, @DateColumn, @DatetimeColumn,
368-
@TimestampColumn, @IntervalColumn, @JsonColumn, @JsonDocumentColumn, @Date32Column,
369+
@TimestampColumn, @IntervalColumn, @JsonColumn, @JsonDocumentColumn, @YsonColumn, @Date32Column,
369370
@Datetime64Column, @Timestamp64Column, @Interval64Column
370371
);
371372
""",
@@ -392,6 +393,7 @@ PRIMARY KEY (Int32Column)
392393
new YdbParameter("IntervalColumn", YdbDbType.Interval, TimeSpan.Zero),
393394
new YdbParameter("JsonColumn", YdbDbType.Json, "{}"),
394395
new YdbParameter("JsonDocumentColumn", YdbDbType.JsonDocument, "{}"),
396+
new YdbParameter("YsonColumn", YdbDbType.Yson, "{a=1u}"u8.ToArray()),
395397
new YdbParameter("Date32Column", YdbDbType.Date32, DateTime.MinValue),
396398
new YdbParameter("Datetime64Column", YdbDbType.Datetime64, DateTime.MinValue),
397399
new YdbParameter("Timestamp64Column", YdbDbType.Timestamp64, DateTime.MinValue),
@@ -407,7 +409,7 @@ PRIMARY KEY (Int32Column)
407409
Int32Column, BoolColumn, Int64Column, Int16Column, Int8Column, FloatColumn, DoubleColumn,
408410
DefaultDecimalColumn, CustomDecimalColumn, Uint8Column, Uint16Column, Uint32Column,
409411
Uint64Column, TextColumn, BytesColumn, DateColumn, DatetimeColumn, TimestampColumn,
410-
IntervalColumn, JsonColumn, JsonDocumentColumn, Date32Column, Datetime64Column,
412+
IntervalColumn, JsonColumn, JsonDocumentColumn, YsonColumn, Date32Column, Datetime64Column,
411413
Timestamp64Column, Interval64Column
412414
FROM {tableName};
413415
"""
@@ -435,10 +437,12 @@ PRIMARY KEY (Int32Column)
435437
Assert.Equal(TimeSpan.Zero, ydbDataReader.GetInterval(18));
436438
Assert.Equal("{}", ydbDataReader.GetJson(19));
437439
Assert.Equal("{}", ydbDataReader.GetJsonDocument(20));
438-
Assert.Equal(DateTime.MinValue, ydbDataReader.GetDateTime(21));
440+
Assert.Equal("{a=1u}"u8.ToArray(), ydbDataReader.GetBytes(21));
441+
Assert.Equal("{a=1u}"u8.ToArray(), ydbDataReader.GetYson(21));
439442
Assert.Equal(DateTime.MinValue, ydbDataReader.GetDateTime(22));
440443
Assert.Equal(DateTime.MinValue, ydbDataReader.GetDateTime(23));
441-
Assert.Equal(TimeSpan.FromMilliseconds(TimeSpan.MinValue.Milliseconds), ydbDataReader.GetInterval(24));
444+
Assert.Equal(DateTime.MinValue, ydbDataReader.GetDateTime(24));
445+
Assert.Equal(TimeSpan.FromMilliseconds(TimeSpan.MinValue.Milliseconds), ydbDataReader.GetInterval(25));
442446
Assert.False(ydbDataReader.Read());
443447
await ydbDataReader.CloseAsync();
444448

src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbSchemaTests.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ public async Task GetSchema_WhenAllTypesTable_ReturnAllTypes()
176176
var dataTable = await ydbConnection.GetSchemaAsync("Columns", [_allTypesTable, null]);
177177
var dataTableNullable = await ydbConnection.GetSchemaAsync("Columns", [_allTypesTableNullable, null]);
178178

179-
Assert.Equal(17, dataTable.Rows.Count);
180-
Assert.Equal(17, dataTableNullable.Rows.Count);
179+
Assert.Equal(18, dataTable.Rows.Count);
180+
Assert.Equal(18, dataTableNullable.Rows.Count);
181181

182182
CheckAllColumns(dataTable, false);
183183
CheckAllColumns(dataTableNullable, true);
@@ -202,6 +202,7 @@ void CheckAllColumns(DataTable pDataTable, bool isNullableTable)
202202
CheckColumn(pDataTable.Rows[14], "DateColumn", 14, isNullableTable);
203203
CheckColumn(pDataTable.Rows[15], "DatetimeColumn", 15, isNullableTable);
204204
CheckColumn(pDataTable.Rows[16], "TimestampColumn", 16, isNullableTable);
205+
CheckColumn(pDataTable.Rows[17], "YsonColumn", 17, isNullableTable, "Yson");
205206
}
206207

207208
void CheckColumn(DataRow column, string columnName, int ordinal, bool isNullable, string? dataType = null)
@@ -243,6 +244,7 @@ DefaultDecimalColumn Decimal(22,9) NOT NULL,
243244
DateColumn Date NOT NULL,
244245
DatetimeColumn Datetime NOT NULL,
245246
TimestampColumn Timestamp NOT NULL,
247+
YsonColumn Yson NOT NULL,
246248
PRIMARY KEY (Int32Column)
247249
);
248250
@@ -264,6 +266,7 @@ DefaultDecimalColumn Decimal(22,9),
264266
DateColumn Date,
265267
DatetimeColumn Datetime,
266268
TimestampColumn Timestamp,
269+
YsonColumn Yson,
267270
PRIMARY KEY (Int32Column)
268271
);
269272
"""

0 commit comments

Comments
 (0)