Skip to content

Commit 408fe30

Browse files
authored
Added retrieval of precision and scale information for decimal types (#189)
* Added retrieval of precision and scale information for decimal types to the datareader schema * Transformed GetScale and GetPrecision methods into readonly properties. Also changed the name of a variable to make it more understandable.
1 parent 6cd6c10 commit 408fe30

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

DuckDB.NET.Data/DuckDBDataReader.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,11 +294,13 @@ public override DataTable GetSchemaTable()
294294
{ "ColumnName", typeof(string) },
295295
{ "DataType", typeof(Type) },
296296
{ "ColumnSize", typeof(int) },
297-
{ "AllowDBNull", typeof(bool) }
297+
{ "AllowDBNull", typeof(bool) },
298+
{ "NumericScale", typeof(byte) },
299+
{ "NumericPrecision", typeof(byte) }
298300
}
299301
};
300302

301-
var rowData = new object[5];
303+
var rowData = new object[7];
302304

303305
for (var i = 0; i < FieldCount; i++)
304306
{
@@ -307,6 +309,18 @@ public override DataTable GetSchemaTable()
307309
rowData[2] = GetFieldType(i);
308310
rowData[3] = -1;
309311
rowData[4] = true;
312+
313+
if (vectorReaders[i] is DecimalVectorDataReader decimalVectorDataReader)
314+
{
315+
rowData[5] = decimalVectorDataReader.Scale;
316+
rowData[6] = decimalVectorDataReader.Precision;
317+
}
318+
else
319+
{
320+
rowData[5] = DBNull.Value;
321+
rowData[6] = DBNull.Value;
322+
}
323+
310324
table.Rows.Add(rowData);
311325
}
312326

DuckDB.NET.Data/Internal/Reader/DecimalVectorDataReader.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,33 @@
11
using System;
22
using System.Numerics;
3-
using DuckDB.NET.Data.Extensions;
43
using DuckDB.NET.Native;
54

65
namespace DuckDB.NET.Data.Internal.Reader;
76

87
internal sealed class DecimalVectorDataReader : NumericVectorDataReader
98
{
109
private readonly byte scale;
10+
private readonly byte precision;
1111
private readonly DuckDBType decimalType;
1212

1313
internal unsafe DecimalVectorDataReader(IntPtr vector, void* dataPointer, ulong* validityMaskPointer, DuckDBType columnType, string columnName) : base(dataPointer, validityMaskPointer, columnType, columnName)
1414
{
1515
using var logicalType = NativeMethods.Vectors.DuckDBVectorGetColumnType(vector);
1616
scale = NativeMethods.LogicalType.DuckDBDecimalScale(logicalType);
17+
precision = NativeMethods.LogicalType.DuckDBDecimalWidth(logicalType);
1718
decimalType = NativeMethods.LogicalType.DuckDBDecimalInternalType(logicalType);
1819
}
1920

21+
internal byte Scale
22+
{
23+
get => scale;
24+
}
25+
26+
internal byte Precision
27+
{
28+
get => precision;
29+
}
30+
2031
protected override T GetValidValue<T>(ulong offset, Type targetType)
2132
{
2233
if (DuckDBType!= DuckDBType.Decimal)
@@ -61,4 +72,5 @@ private decimal GetDecimal(ulong offset)
6172
default: throw new DuckDBException($"Invalid type {DuckDBType} ({(int)DuckDBType}) for column {ColumnName}");
6273
}
6374
}
75+
6476
}

DuckDB.NET.Test/DuckDBDataReaderTests.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,4 +323,35 @@ public void ReadNonQueryAsResult()
323323

324324
reader.Invoking(r => r.Close()).Should().NotThrow();
325325
}
326+
327+
[Fact]
328+
public void ReadDecimalSchema()
329+
{
330+
Command.CommandText = "CREATE TABLE decimaltbl(foo decimal(10,2));";
331+
Command.ExecuteNonQuery();
332+
333+
Command.CommandText = "INSERT INTO decimaltbl VALUES (3.45), (9.35), (7.24);";
334+
Command.ExecuteNonQuery();
335+
336+
Command.CommandText = "SELECT foo FROM decimaltbl";
337+
using var reader = Command.ExecuteReader();
338+
339+
var schemaTable = reader.GetSchemaTable();
340+
schemaTable.Rows[0]["NumericScale"].Should().Be(2);
341+
schemaTable.Rows[0]["NumericPrecision"].Should().Be(10);
342+
}
343+
344+
[Fact]
345+
public void ReadDecimalSchemaWithoutTableRow()
346+
{
347+
Command.CommandText = "CREATE TABLE decimaltbl(foo decimal(10,2));";
348+
Command.ExecuteNonQuery();
349+
350+
Command.CommandText = "SELECT foo FROM decimaltbl";
351+
using var reader = Command.ExecuteReader();
352+
353+
var schemaTable = reader.GetSchemaTable();
354+
schemaTable.Rows[0]["NumericScale"].Should().Be(0);
355+
schemaTable.Rows[0]["NumericPrecision"].Should().Be(0);
356+
}
326357
}

0 commit comments

Comments
 (0)