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

Giorgi / DuckDB.NET / 21786556530

07 Feb 2026 08:39PM UTC coverage: 89.155% (-0.07%) from 89.223%
21786556530

push

github

Giorgi
Added support for clearing in-progress adapter

Requires DuckDB 1.5

1199 of 1393 branches covered (86.07%)

Branch coverage included in aggregate %.

6 of 8 new or added lines in 1 file covered. (75.0%)

193 existing lines in 43 files now uncovered.

2336 of 2572 relevant lines covered (90.82%)

557295.56 hits per line

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

86.92
/DuckDB.NET.Data/DuckDBConnection.TableFunction.cs
1
using DuckDB.NET.Data.Common;
2
using DuckDB.NET.Data.Connection;
3
using DuckDB.NET.Data.DataChunk.Writer;
4
using System.Runtime.CompilerServices;
5
using System.Runtime.InteropServices;
6

7
namespace DuckDB.NET.Data;
8

9
public record ColumnInfo(string Name, Type Type);
201✔
10

11
public record TableFunction(IReadOnlyList<ColumnInfo> Columns, IEnumerable Data);
156✔
12

13
partial class DuckDBConnection
14
{
15

16
    public void RegisterTableFunction(string name, Func<TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
17
    {
18
        RegisterTableFunctionInternal(name, (_) => resultCallback(), mapperCallback, Array.Empty<Type>());
6✔
19
    }
3✔
20

21
    public void RegisterTableFunction<T>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
22
    {
23
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T));
15✔
24
    }
15✔
25

26
    public void RegisterTableFunction<T1, T2>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
27
    {
28
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2));
9✔
29
    }
9✔
30

31
    public void RegisterTableFunction<T1, T2, T3>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
32
    {
33
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2), typeof(T3));
3✔
34
    }
3✔
35

36
    public void RegisterTableFunction<T1, T2, T3, T4>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
37
    {
38
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2), typeof(T3), typeof(T4));
3✔
39
    }
3✔
40

41
    public void RegisterTableFunction<T1, T2, T3, T4, T5>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
42
    {
43
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5));
3✔
44
    }
3✔
45

46
    public void RegisterTableFunction<T1, T2, T3, T4, T5, T6>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
47
    {
UNCOV
48
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6));
×
UNCOV
49
    }
×
50

51
    public void RegisterTableFunction<T1, T2, T3, T4, T5, T6, T7>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
52
    {
53
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7));
×
54
    }
×
55

56
    public void RegisterTableFunction<T1, T2, T3, T4, T5, T6, T7, T8>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
57
    {
58
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8));
×
59
    }
×
60

61
    public void RegisterTableFunction(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback, params DuckDBType[] parameterTypes)
62
    {
63
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, parameterTypes);
6✔
64
    }
6✔
65

66
    private unsafe void RegisterTableFunctionInternal(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback, params Type[] parameterTypes)
67
    {
68
        var function = NativeMethods.TableFunction.DuckDBCreateTableFunction();
36✔
69
        using (var handle = name.ToUnmanagedString())
36✔
70
        {
71
            NativeMethods.TableFunction.DuckDBTableFunctionSetName(function, handle);
36✔
72
        }
36✔
73

74
        foreach (var type in parameterTypes)
210✔
75
        {
76
            using var logicalType = type.GetLogicalType();
69✔
77
            NativeMethods.TableFunction.DuckDBTableFunctionAddParameter(function, logicalType);
69✔
78
        }
79

80
        var tableFunctionInfo = new TableFunctionInfo(resultCallback, mapperCallback);
36✔
81

82
        NativeMethods.TableFunction.DuckDBTableFunctionSetBind(function, &Bind);
36✔
83
        NativeMethods.TableFunction.DuckDBTableFunctionSetInit(function, &Init);
36✔
84
        NativeMethods.TableFunction.DuckDBTableFunctionSetFunction(function, &TableFunction);
36✔
85
        NativeMethods.TableFunction.DuckDBTableFunctionSetExtraInfo(function, tableFunctionInfo.ToHandle(), &DestroyExtraInfo);
36✔
86

87
        var state = NativeMethods.TableFunction.DuckDBRegisterTableFunction(NativeConnection, function);
36✔
88

89
        if (!state.IsSuccess())
36!
90
        {
UNCOV
91
            throw new InvalidOperationException($"Error registering user defined table function: {name}");
×
92
        }
93

94
        NativeMethods.TableFunction.DuckDBDestroyTableFunction(ref function);
36✔
95
    }
36✔
96

97
    private unsafe void RegisterTableFunctionInternal(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback, params DuckDBType[] parameterTypes)
98
    {
99
        var function = NativeMethods.TableFunction.DuckDBCreateTableFunction();
6✔
100
        using (var handle = name.ToUnmanagedString())
6✔
101
        {
102
            NativeMethods.TableFunction.DuckDBTableFunctionSetName(function, handle);
6✔
103
        }
6✔
104

105
        foreach (var duckDBType in parameterTypes)
42✔
106
        {
107
            using var logicalType = NativeMethods.LogicalType.DuckDBCreateLogicalType(duckDBType);
15✔
108
            NativeMethods.TableFunction.DuckDBTableFunctionAddParameter(function, logicalType);
15✔
109
        }
110

111
        var tableFunctionInfo = new TableFunctionInfo(resultCallback, mapperCallback);
6✔
112

113
        NativeMethods.TableFunction.DuckDBTableFunctionSetBind(function, &Bind);
6✔
114
        NativeMethods.TableFunction.DuckDBTableFunctionSetInit(function, &Init);
6✔
115
        NativeMethods.TableFunction.DuckDBTableFunctionSetFunction(function, &TableFunction);
6✔
116
        NativeMethods.TableFunction.DuckDBTableFunctionSetExtraInfo(function, tableFunctionInfo.ToHandle(), &DestroyExtraInfo);
6✔
117

118
        var state = NativeMethods.TableFunction.DuckDBRegisterTableFunction(NativeConnection, function);
6✔
119

120
        if (!state.IsSuccess())
6!
121
        {
UNCOV
122
            throw new InvalidOperationException($"Error registering user defined table function: {name}");
×
123
        }
124

125
        NativeMethods.TableFunction.DuckDBDestroyTableFunction(ref function);
6✔
126
    }
6✔
127

128
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
129
    public static unsafe void Bind(IntPtr info)
130
    {
131
        IDuckDBValueReader[] parameters = [];
42✔
132
        try
133
        {
134
            var handle = GCHandle.FromIntPtr(NativeMethods.TableFunction.DuckDBBindGetExtraInfo(info));
42✔
135

136
            if (handle.Target is not TableFunctionInfo functionInfo)
42!
137
            {
UNCOV
138
                throw new InvalidOperationException("User defined table function bind failed. Bind extra info is null");
×
139
            }
140

141
            parameters = new IDuckDBValueReader[NativeMethods.TableFunction.DuckDBBindGetParameterCount(info)];
42✔
142

143
            for (var i = 0; i < parameters.Length; i++)
252✔
144
            {
145
                var value = NativeMethods.TableFunction.DuckDBBindGetParameter(info, (ulong)i);
84✔
146
                parameters[i] = value;
84✔
147
            }
148

149
            var tableFunctionData = functionInfo.Bind(parameters);
42✔
150

151
            foreach (var columnInfo in tableFunctionData.Columns)
162✔
152
            {
153
                using var logicalType = columnInfo.Type.GetLogicalType();
42✔
154
                NativeMethods.TableFunction.DuckDBBindAddResultColumn(info, columnInfo.Name.ToUnmanagedString(), logicalType);
42✔
155
            }
156

157
            var bindData = new TableFunctionBindData(tableFunctionData.Columns, tableFunctionData.Data.GetEnumerator());
39✔
158

159
            NativeMethods.TableFunction.DuckDBBindSetBindData(info, bindData.ToHandle(), &DestroyExtraInfo);
39✔
160
        }
39✔
161
        catch (Exception ex)
162
        {
163
            using var errorMessage = ex.Message.ToUnmanagedString();
3✔
164
            NativeMethods.TableFunction.DuckDBBindSetError(info, errorMessage);
3✔
165
        }
3✔
166
        finally
167
        {
168
            foreach (var parameter in parameters)
252✔
169
            {
170
                (parameter as IDisposable)?.Dispose();
84!
171
            }
172
        }
42✔
173
    }
42✔
174

175
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
176
    public static void Init(IntPtr info) { }
39✔
177

178
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
179
    public static void TableFunction(IntPtr info, IntPtr chunk)
180
    {
181
        try
182
        {
183
            var bindData = GCHandle.FromIntPtr(NativeMethods.TableFunction.DuckDBFunctionGetBindData(info));
69✔
184
            var extraInfo = GCHandle.FromIntPtr(NativeMethods.TableFunction.DuckDBFunctionGetExtraInfo(info));
69✔
185

186
            if (bindData.Target is not TableFunctionBindData tableFunctionBindData)
69!
187
            {
UNCOV
188
                throw new InvalidOperationException("User defined table function failed. Function bind data is null");
×
189
            }
190

191
            if (extraInfo.Target is not TableFunctionInfo tableFunctionInfo)
69!
192
            {
193
                throw new InvalidOperationException("User defined table function failed. Function extra info is null");
×
194
            }
195

196
            var dataChunk = new DuckDBDataChunk(chunk);
69✔
197

198
            var writers = new VectorDataWriterBase[tableFunctionBindData.Columns.Count];
69✔
199
            for (var columnIndex = 0; columnIndex < tableFunctionBindData.Columns.Count; columnIndex++)
288✔
200
            {
201
                var column = tableFunctionBindData.Columns[columnIndex];
75✔
202
                var vector = NativeMethods.DataChunks.DuckDBDataChunkGetVector(dataChunk, columnIndex);
75✔
203

204
                using var logicalType = column.Type.GetLogicalType();
75✔
205
                writers[columnIndex] = VectorDataWriterFactory.CreateWriter(vector, logicalType);
75✔
206
            }
207

208
            ulong size = 0;
69✔
209

210
            for (; size < DuckDBGlobalData.VectorSize; size++)
909✔
211
            {
212
                if (tableFunctionBindData.DataEnumerator.MoveNext())
489✔
213
                {
214
                    tableFunctionInfo.Mapper(tableFunctionBindData.DataEnumerator.Current, writers, size);
423✔
215
                }
216
                else
217
                {
218
                    break;
219
                }
220
            }
221

222
            NativeMethods.DataChunks.DuckDBDataChunkSetSize(dataChunk, size);
66✔
223
        }
66✔
224
        catch (Exception ex)
225
        {
226
            using var errorMessage = ex.Message.ToUnmanagedString();
3✔
227
            NativeMethods.TableFunction.DuckDBFunctionSetError(info, errorMessage);
3✔
228
        }
3✔
229
    }
69✔
230
}
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