Skip to content

Commit 9d86c6f

Browse files
committed
Add decimal and guid reading support
1 parent 0c710f6 commit 9d86c6f

File tree

4 files changed

+52
-7
lines changed

4 files changed

+52
-7
lines changed

DuckDB.NET.Bindings/DuckDBWrapperObjects.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,24 @@ public T GetValue<T>()
137137

138138
DuckDBType.Float => Cast(NativeMethods.Value.DuckDBGetFloat(this)),
139139
DuckDBType.Double => Cast(NativeMethods.Value.DuckDBGetDouble(this)),
140-
140+
141+
DuckDBType.Decimal => Cast(decimal.Parse(NativeMethods.Value.DuckDBGetVarchar(this))),
142+
DuckDBType.Uuid => Cast(new Guid(NativeMethods.Value.DuckDBGetVarchar(this))),
143+
144+
//DuckDBType.HugeInt => expr,
145+
//DuckDBType.UnsignedHugeInt => expr,
146+
141147
DuckDBType.Varchar => Cast(NativeMethods.Value.DuckDBGetVarchar(this)),
148+
149+
//DuckDBType.Date => expr,
150+
//DuckDBType.Time => expr,
151+
//DuckDBType.TimeTz => expr,
152+
//DuckDBType.Interval => expr,
142153
DuckDBType.Timestamp => Cast(NativeMethods.DateTimeHelpers.DuckDBFromTimestamp(NativeMethods.Value.DuckDBGetTimestamp(this)).ToDateTime()),
143-
//DuckDBType.Decimal => Cast(decimal.Parse(NativeMethods.Value.DuckDBGetVarchar(this))),
144-
//DuckDBType.Uuid => Cast(new Guid(NativeMethods.Value.DuckDBGetVarchar(this))),
145154
//DuckDBType.TimestampS => expr,
146155
//DuckDBType.TimestampMs => expr,
147156
//DuckDBType.TimestampNs => expr,
148-
//DuckDBType.TimeTz => expr,
149157
//DuckDBType.TimestampTz => expr,
150-
151158
_ => throw new NotImplementedException($"Cannot read value of type {typeof(T).FullName}")
152159
};
153160

DuckDB.NET.Bindings/NativeMethods/NativeMethods.LogicalType.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ public static class LogicalType
1111
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_logical_type")]
1212
public static extern DuckDBLogicalType DuckDBCreateLogicalType(DuckDBType type);
1313

14+
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_decimal_type")]
15+
public static extern DuckDBLogicalType DuckDBCreateDecimalType(byte width, byte scale);
16+
1417
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_type_id")]
1518
public static extern DuckDBType DuckDBGetTypeId(DuckDBLogicalType type);
1619

DuckDB.NET.Data/Internal/DuckDBTypeMap.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ internal static class DuckDBTypeMap
4949
{ typeof(ulong), DuckDBType.UnsignedBigInt },
5050
{ typeof(float), DuckDBType.Float },
5151
{ typeof(double), DuckDBType.Double},
52+
{ typeof(Guid), DuckDBType.Uuid},
5253
{ typeof(DateTime), DuckDBType.Timestamp},
5354
{ typeof(TimeSpan), DuckDBType.Interval},
5455
#if NET6_0_OR_GREATER
@@ -83,6 +84,11 @@ public static DbType GetDbTypeForValue(object? value)
8384

8485
public static DuckDBLogicalType GetLogicalType(Type type)
8586
{
87+
if (type == typeof(decimal))
88+
{
89+
return NativeMethods.LogicalType.DuckDBCreateDecimalType(38, 18);
90+
}
91+
8692
if (ClrToDuckDBTypeMap.TryGetValue(type, out var duckDBType))
8793
{
8894
return NativeMethods.LogicalType.DuckDBCreateLogicalType(duckDBType);

DuckDB.NET.Test/TableFunctionTests.cs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void RegisterTableFunctionWithThreeParameters()
6565
{
6666
var count = 30;
6767
var startDate = new DateTime(2024, 11, 6);
68-
var minutesParam= 10;
68+
var minutesParam = 10;
6969
var secondsParam = 2.5;
7070

7171
Connection.RegisterTableFunction<DateTime, long, double>("demo3", (parameters) =>
@@ -86,6 +86,35 @@ public void RegisterTableFunctionWithThreeParameters()
8686
var data = Connection.Query<DateTime>($"SELECT * FROM demo3('2024-11-06'::TIMESTAMP, 10, 2.5 );").ToList();
8787

8888
var dateTimes = Enumerable.Range(0, count).Select(i => startDate.AddDays(i).AddMinutes(minutesParam).AddSeconds(secondsParam));
89-
data.Select(dateTime => dateTime).Should().BeEquivalentTo(dateTimes);
89+
data.Should().BeEquivalentTo(dateTimes);
90+
}
91+
92+
[Fact]
93+
public void RegisterTableFunctionWithFourParameters()
94+
{
95+
var guid = Guid.NewGuid();
96+
97+
Connection.RegisterTableFunction<bool, decimal, byte, Guid>("demo4", (parameters) =>
98+
{
99+
var param1 = parameters[0].GetValue<bool>();
100+
var param2 = parameters[1].GetValue<decimal>();
101+
var param3 = parameters[2].GetValue<byte>();
102+
var param4 = parameters[3].GetValue<Guid>();
103+
104+
var enumerable = param4.ToByteArray(param1).Append(param3);
105+
106+
return new TableFunction(new List<ColumnInfo>()
107+
{
108+
new ColumnInfo("foo", typeof(byte)),
109+
}, enumerable);
110+
}, (item, writers, rowIndex) =>
111+
{
112+
writers[0].WriteValue((byte)item, rowIndex);
113+
});
114+
115+
var data = Connection.Query<byte>($"SELECT * FROM demo4(false, 10::DECIMAL(18, 3), 4::UTINYINT, '{guid}'::UUID );").ToList();
116+
117+
var bytes = guid.ToByteArray(false).Append((byte)4);
118+
data.Should().BeEquivalentTo(bytes);
90119
}
91120
}

0 commit comments

Comments
 (0)