• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Giorgi / DuckDB.NET / 8686186157

15 Apr 2024 08:49AM UTC coverage: 89.65% (-0.1%) from 89.795%
8686186157

push

github

Giorgi
Update ReadMe, read hugeint as unsigned numeric types.

591 of 690 branches covered (85.65%)

Branch coverage included in aggregate %.

2 of 4 new or added lines in 1 file covered. (50.0%)

1384 of 1513 relevant lines covered (91.47%)

12568.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.4
/DuckDB.NET.Data/Internal/Reader/NumericVectorDataReader.cs
1
using System;
2
using System.Numerics;
3
using System.Runtime.CompilerServices;
4
using DuckDB.NET.Data.Extensions;
5
using DuckDB.NET.Native;
6

7
namespace DuckDB.NET.Data.Internal.Reader;
8

9
internal class NumericVectorDataReader : VectorDataReaderBase
10
{
11
    internal unsafe NumericVectorDataReader(void* dataPointer, ulong* validityMaskPointer, DuckDBType columnType, string columnName) : base(dataPointer, validityMaskPointer, columnType, columnName)
5,616✔
12
    {
13
    }
5,616✔
14

15
    protected override T GetValidValue<T>(ulong offset, Type targetType)
16
    {
17
        var isFloatingNumericType = TypeExtensions.IsFloatingNumericType<T>();
31,329✔
18
        var isIntegralNumericType = TypeExtensions.IsIntegralNumericType<T>();
31,329✔
19

20
        if (!(isIntegralNumericType || isFloatingNumericType))
31,329✔
21
        {
22
            return base.GetValidValue<T>(offset, targetType);
99✔
23
        }
24

25
        //If T is integral type and column is also integral read the data and use Unsafe.As<> or Convert.ChangeType to change type
26
        //If T is floating and column is floating too, read data and cast to T
27
        //Otherwise use the non-generic path
28
        if (isIntegralNumericType)
31,230✔
29
        {
30
            return DuckDBType switch
31,191!
31
            {
31,191✔
32
                DuckDBType.TinyInt => GetUnmanagedTypeValue<sbyte, T>(offset),
96✔
33
                DuckDBType.SmallInt => GetUnmanagedTypeValue<short, T>(offset),
96✔
34
                DuckDBType.Integer => GetUnmanagedTypeValue<int, T>(offset),
30,273✔
35
                DuckDBType.BigInt => GetUnmanagedTypeValue<long, T>(offset),
174✔
36
                DuckDBType.UnsignedTinyInt => GetUnmanagedTypeValue<byte, T>(offset),
96✔
37
                DuckDBType.UnsignedSmallInt => GetUnmanagedTypeValue<ushort, T>(offset),
96✔
38
                DuckDBType.UnsignedInteger => GetUnmanagedTypeValue<uint, T>(offset),
96✔
39
                DuckDBType.UnsignedBigInt => GetUnmanagedTypeValue<ulong, T>(offset),
168✔
40
                DuckDBType.HugeInt => GetBigInteger<T>(offset, false),
60✔
41
                DuckDBType.UnsignedHugeInt => GetBigInteger<T>(offset, true),
36✔
42
                _ => base.GetValidValue<T>(offset, targetType)
×
43
            };
31,191✔
44
        }
45

46
        return DuckDBType switch
39!
47
        {
39✔
48
            DuckDBType.Float => (T)(object)GetFieldData<float>(offset),
15✔
49
            DuckDBType.Double => (T)(object)GetFieldData<double>(offset),
24✔
50
            _ => base.GetValidValue<T>(offset, targetType)
×
51
        };
39✔
52
    }
53

54
    internal override object GetValue(ulong offset, Type targetType)
55
    {
56
        var value = DuckDBType switch
1,542!
57
        {
1,542✔
58
            DuckDBType.TinyInt => GetFieldData<sbyte>(offset),
93✔
59
            DuckDBType.SmallInt => GetFieldData<short>(offset),
93✔
60
            DuckDBType.Integer => GetFieldData<int>(offset),
546✔
61
            DuckDBType.BigInt => GetFieldData<long>(offset),
231✔
62
            DuckDBType.UnsignedTinyInt => GetFieldData<byte>(offset),
93✔
63
            DuckDBType.UnsignedSmallInt => GetFieldData<ushort>(offset),
93✔
64
            DuckDBType.UnsignedInteger => GetFieldData<uint>(offset),
93✔
65
            DuckDBType.UnsignedBigInt => GetFieldData<ulong>(offset),
120✔
66
            DuckDBType.Float => GetFieldData<float>(offset),
75✔
67
            DuckDBType.Double => GetFieldData<double>(offset),
87✔
68
            DuckDBType.HugeInt => GetBigInteger(offset, false),
12✔
69
            DuckDBType.UnsignedHugeInt => GetBigInteger(offset, true),
6✔
70
            _ => base.GetValue(offset, targetType)
×
71
        };
1,542✔
72

73
        if (targetType.IsNumeric())
1,542✔
74
        {
75
            try
76
            {
77
                return Convert.ChangeType(value, targetType);
1,443✔
78
            }
79
            catch (OverflowException)
15✔
80
            {
81
                throw new InvalidCastException($"Cannot cast from {value.GetType().Name} to {targetType.Name} in column {ColumnName}");
15✔
82
            }
83
        }
84

85
        throw new InvalidCastException($"Cannot cast from {value.GetType().Name} to {targetType.Name} in column {ColumnName}");
99✔
86
    }
1,428✔
87

88
    protected unsafe BigInteger GetBigInteger(ulong offset, bool unsigned)
89
    {
90
        if (unsigned)
264✔
91
        {
92
            var unsignedHugeInt = ((DuckDBUHugeInt*)DataPointer + offset);
42✔
93
            return unsignedHugeInt->ToBigInteger();
42✔
94
        }
95
        else
96
        {
97
            var hugeInt = (DuckDBHugeInt*)DataPointer + offset;
222✔
98
            return hugeInt->ToBigInteger();
222✔
99
        }
100
    }
101

102
    protected T GetBigInteger<T>(ulong offset, bool unsigned)
103
    {
104
        var bigInteger = GetBigInteger(offset, unsigned);
96✔
105

106
        if (typeof(T) == typeof(sbyte))
96✔
107
        {
108
            return (T)(object)(sbyte)bigInteger;
3✔
109
        }
110

111
        if (typeof(T) == typeof(short))
93✔
112
        {
113
            return (T)(object)(short)bigInteger;
3✔
114
        }
115

116
        if (typeof(T) == typeof(int))
90✔
117
        {
118
            return (T)(object)(int)bigInteger;
3✔
119
        }
120

121
        if (typeof(T) == typeof(long))
87✔
122
        {
123
            return (T)(object)(long)bigInteger;
3✔
124
        }
125

126
        if (typeof(T) == typeof(uint))
84!
127
        {
NEW
128
            return (T)(object)(uint)bigInteger;
×
129
        }
130

131
        if (typeof(T) == typeof(ulong))
84!
132
        {
NEW
133
            return (T)(object)(ulong)bigInteger;
×
134
        }
135

136
        return (T)(object)bigInteger;
84✔
137
    }
138

139
    private TResult GetUnmanagedTypeValue<TQuery, TResult>(ulong offset) where TQuery : unmanaged
140
    {
141
        var value = GetFieldData<TQuery>(offset);
31,095✔
142

143
        if (typeof(TQuery) == typeof(TResult))
31,095✔
144
        {
145
            return Unsafe.As<TQuery, TResult>(ref value);
30,396✔
146
        }
147

148
        try
149
        {
150
            return (TResult)Convert.ChangeType(value, typeof(TResult));
699✔
151
        }
152
        catch (OverflowException)
243✔
153
        {
154
            throw new InvalidCastException($"Cannot cast from {value.GetType().Name} to {typeof(TResult).Name} in column {ColumnName}");
243✔
155
        }
156
    }
456✔
157
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc