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

Giorgi / DuckDB.NET / 9130186384

17 May 2024 02:54PM UTC coverage: 89.487% (-0.06%) from 89.548%
9130186384

push

github

Giorgi
Add UseStreamingMode to DuckDBCommand

666 of 774 branches covered (86.05%)

Branch coverage included in aggregate %.

8 of 8 new or added lines in 3 files covered. (100.0%)

1 existing line in 1 file now uncovered.

1496 of 1642 relevant lines covered (91.11%)

11846.5 hits per line

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

88.27
/DuckDB.NET.Data/Internal/Reader/VectorDataReaderBase.cs
1
using System;
2
using System.Collections.Generic;
3
using System.IO;
4
using System.Numerics;
5
using DuckDB.NET.Data.Extensions;
6
using DuckDB.NET.Native;
7

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

10
internal class VectorDataReaderBase : IDisposable
11
{
12
    private readonly unsafe ulong* validityMaskPointer;
13

14
    private Type? clrType;
15
    public Type ClrType => clrType ??= GetColumnType();
2,812✔
16

17
    private Type? providerSpecificClrType;
18
    public Type ProviderSpecificClrType => providerSpecificClrType ??= GetColumnProviderSpecificType();
174✔
19

20

21
    public string ColumnName { get; }
4,704✔
22
    public DuckDBType DuckDBType { get; }
78,168✔
23
    private protected unsafe void* DataPointer { get; }
65,352✔
24

25
    internal unsafe VectorDataReaderBase(void* dataPointer, ulong* validityMaskPointer, DuckDBType columnType, string columnName)
15,455✔
26
    {
27
        DataPointer = dataPointer;
15,455✔
28
        this.validityMaskPointer = validityMaskPointer;
15,455✔
29

30
        DuckDBType = columnType;
15,455✔
31
        ColumnName = columnName;
15,455✔
32
    }
15,455✔
33

34
    internal unsafe bool IsValid(ulong offset)
35
    {
36
        if (validityMaskPointer == default)
126,729!
37
        {
UNCOV
38
            return true;
×
39
        }
40

41
        var validityMaskEntryIndex = offset / 64;
126,729✔
42
        var validityBitIndex = (int)(offset % 64);
126,729✔
43

44
        var validityMaskEntryPtr = validityMaskPointer + validityMaskEntryIndex;
126,729✔
45
        var validityBit = 1ul << validityBitIndex;
126,729✔
46

47
        var isValid = (*validityMaskEntryPtr & validityBit) != 0;
126,729✔
48
        return isValid;
126,729✔
49
    }
50

51
    internal virtual T GetValue<T>(ulong offset)
52
    {
53
        var (isNullableValueType, targetType) = TypeExtensions.IsNullableValueType<T>();
62,889✔
54

55
        var isValid = IsValid(offset);
62,889✔
56

57
        //If nullable we can't use Unsafe.As because we don't have the underlying type as T so use the non-generic GetValue method.
58
        if (isNullableValueType)
62,889✔
59
        {
60
            return isValid
402✔
61
                ? (T)GetValue(offset, Nullable.GetUnderlyingType(targetType)!)
402✔
62
                : default!; //T is Nullable<> and we are returning null so suppress compiler warning.
402✔
63
        }
64

65
        //If we are here, T isn't Nullable<>. It can be either a value type or a class.
66
        //In both cases if the data is null we should throw.
67
        if (isValid)
62,487✔
68
        {
69
            return GetValidValue<T>(offset, targetType);
62,313✔
70
        }
71
        
72
        throw new InvalidCastException($"Column '{ColumnName}' value is null");
174✔
73
    }
74

75
    /// <summary>
76
    /// Called when the value at specified <param name="offset">offset</param> is valid (isn't null)
77
    /// </summary>
78
    /// <typeparam name="T">Type of the return value</typeparam>
79
    /// <param name="offset">Position to read the data from</param>
80
    /// <param name="targetType">Type of the return value</param>
81
    /// <returns>Data at the specified offset</returns>
82
    protected virtual T GetValidValue<T>(ulong offset, Type targetType)
83
    {
84
        return (T)GetValue(offset, targetType);
357✔
85
    }
86

87
    internal object GetValue(ulong offset)
88
    {
89
        return GetValue(offset, ClrType);
2,307✔
90
    }
91

92
    internal virtual object GetValue(ulong offset, Type targetType)
93
    {
94
        return DuckDBType switch
×
95
        {
×
96
            DuckDBType.Invalid => throw new DuckDBException($"Invalid type for column {ColumnName}"),
×
97
            _ => throw new ArgumentException($"Unrecognised type {DuckDBType} ({(int)DuckDBType}) for column {ColumnName}")
×
98
        };
×
99
    }
100

101
    internal object GetProviderSpecificValue(ulong offset)
102
    {
103
        return GetValue(offset, ProviderSpecificClrType);
48✔
104
    }
105

106
    protected virtual Type GetColumnType()
107
    {
108
        return DuckDBType switch
1,086!
109
        {
1,086✔
110
            DuckDBType.Invalid => throw new DuckDBException($"Invalid type for column {ColumnName}"),
×
111
            DuckDBType.Boolean => typeof(bool),
12✔
112
            DuckDBType.TinyInt => typeof(sbyte),
36✔
113
            DuckDBType.SmallInt => typeof(short),
36✔
114
            DuckDBType.Integer => typeof(int),
145✔
115
            DuckDBType.BigInt => typeof(long),
150✔
116
            DuckDBType.UnsignedTinyInt => typeof(byte),
36✔
117
            DuckDBType.UnsignedSmallInt => typeof(ushort),
36✔
118
            DuckDBType.UnsignedInteger => typeof(uint),
36✔
119
            DuckDBType.UnsignedBigInt => typeof(ulong),
54✔
120
            DuckDBType.Float => typeof(float),
12✔
121
            DuckDBType.Double => typeof(double),
18✔
122
            DuckDBType.Timestamp => typeof(DateTime),
63✔
123
            DuckDBType.Interval => typeof(TimeSpan),
12✔
124
#if NET6_0_OR_GREATER
1,086✔
125
            DuckDBType.Date => typeof(DateOnly),
30✔
126
#else
1,086✔
127
            DuckDBType.Date => typeof(DateTime),
1,086✔
128
#endif
1,086✔
129
#if NET6_0_OR_GREATER
1,086✔
130
            DuckDBType.Time => typeof(TimeOnly),
57✔
131
#else
1,086✔
132
            DuckDBType.Time => typeof(TimeSpan),
1,086✔
133
#endif
1,086✔
134
            DuckDBType.TimeTz => typeof(DateTimeOffset),
21✔
135
            DuckDBType.HugeInt => typeof(BigInteger),
12✔
136
            DuckDBType.UnsignedHugeInt => typeof(BigInteger),
3✔
137
            DuckDBType.Varchar => typeof(string),
83✔
138
            DuckDBType.Decimal => typeof(decimal),
156✔
139
            DuckDBType.TimestampS => typeof(DateTime),
3✔
140
            DuckDBType.TimestampMs => typeof(DateTime),
3✔
141
            DuckDBType.TimestampNs => typeof(DateTime),
6✔
142
            DuckDBType.Blob => typeof(Stream),
9✔
143
            DuckDBType.Enum => typeof(string),
15✔
144
            DuckDBType.Uuid => typeof(Guid),
24✔
145
            DuckDBType.Struct => typeof(Dictionary<string, object>),
9✔
146
            DuckDBType.Bit => typeof(string),
6✔
147
            DuckDBType.TimestampTz => typeof(DateTime),
3✔
148
            _ => throw new ArgumentException($"Unrecognised type {DuckDBType} ({(int)DuckDBType}) for column {ColumnName}")
×
149
        };
1,086✔
150
    }
151

152
    protected virtual Type GetColumnProviderSpecificType()
153
    {
154
        return DuckDBType switch
114!
155
        {
114✔
156
            DuckDBType.Invalid => throw new DuckDBException($"Invalid type for column {ColumnName}"),
×
157
            DuckDBType.Boolean => typeof(bool),
3✔
158
            DuckDBType.TinyInt => typeof(sbyte),
3✔
159
            DuckDBType.SmallInt => typeof(short),
3✔
160
            DuckDBType.Integer => typeof(int),
9✔
161
            DuckDBType.BigInt => typeof(long),
3✔
162
            DuckDBType.UnsignedTinyInt => typeof(byte),
3✔
163
            DuckDBType.UnsignedSmallInt => typeof(ushort),
3✔
164
            DuckDBType.UnsignedInteger => typeof(uint),
3✔
165
            DuckDBType.UnsignedBigInt => typeof(ulong),
3✔
166
            DuckDBType.Float => typeof(float),
3✔
167
            DuckDBType.Double => typeof(double),
6✔
168
            DuckDBType.Timestamp => typeof(DuckDBTimestamp),
3✔
169
            DuckDBType.Interval => typeof(DuckDBInterval),
3✔
170
            DuckDBType.Date => typeof(DuckDBDateOnly),
6✔
171
            DuckDBType.Time => typeof(DuckDBTimeOnly),
3✔
172
            DuckDBType.TimeTz => typeof(DuckDBTimeTz),
3✔
173
            DuckDBType.HugeInt => typeof(DuckDBHugeInt),
3✔
174
            DuckDBType.UnsignedHugeInt => typeof(DuckDBUHugeInt),
3✔
175
            DuckDBType.Varchar => typeof(string),
3✔
176
            DuckDBType.Decimal => typeof(decimal),
12✔
177
            DuckDBType.TimestampS => typeof(DuckDBTimestamp),
3✔
178
            DuckDBType.TimestampMs => typeof(DuckDBTimestamp),
3✔
179
            DuckDBType.TimestampNs => typeof(DuckDBTimestamp),
3✔
180
            DuckDBType.Blob => typeof(Stream),
3✔
181
            DuckDBType.Enum => typeof(string),
9✔
182
            DuckDBType.Uuid => typeof(Guid),
3✔
183
            DuckDBType.Struct => typeof(Dictionary<string, object>),
3✔
184
            DuckDBType.Bit => typeof(string),
3✔
185
            DuckDBType.TimestampTz => typeof(DuckDBTimestamp),
3✔
186
            _ => throw new ArgumentException($"Unrecognised type {DuckDBType} ({(int)DuckDBType}) for column {ColumnName}")
×
187
        };
114✔
188
    }
189

190
    protected unsafe T GetFieldData<T>(ulong offset) where T : unmanaged => *((T*)DataPointer + offset);
34,248✔
191

192
    public virtual void Dispose()
193
    {
194
    }
1,528✔
195
}
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

© 2025 Coveralls, Inc