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

Giorgi / DuckDB.NET / 12018740323

25 Nov 2024 09:03PM UTC coverage: 89.898% (-0.05%) from 89.943%
12018740323

push

github

Giorgi
Add wildcards to exception message validation

1071 of 1227 branches covered (87.29%)

Branch coverage included in aggregate %.

2097 of 2297 relevant lines covered (91.29%)

827722.16 hits per line

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

85.71
/DuckDB.NET.Data/DuckDBConnection.TableFunction.cs
1
using DuckDB.NET.Data.Extensions;
2
using DuckDB.NET.Data.Internal;
3
using DuckDB.NET.Data.Internal.Writer;
4
using DuckDB.NET.Data.Writer;
5
using DuckDB.NET.Native;
6
using System;
7
using System.Collections;
8
using System.Collections.Generic;
9
using System.Diagnostics.CodeAnalysis;
10
using System.Runtime.CompilerServices;
11
using System.Runtime.InteropServices;
12

13
namespace DuckDB.NET.Data;
14

15
public record ColumnInfo(string Name, Type Type);
114✔
16

17
public record TableFunction(IReadOnlyList<ColumnInfo> Columns, IEnumerable Data);
84✔
18

19
partial class DuckDBConnection
20
{
21
#if NET8_0_OR_GREATER
22
    [Experimental("DuckDBNET001")]
23
    public void RegisterTableFunction<T>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
24
    {
25
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T));
9✔
26
    }
9✔
27

28
    [Experimental("DuckDBNET001")]
29
    public void RegisterTableFunction<T1, T2>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
30
    {
31
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2));
6✔
32
    }
6✔
33

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

40
    [Experimental("DuckDBNET001")]
41
    public void RegisterTableFunction<T1, T2, T3, T4>(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));
3✔
44
    }
3✔
45

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

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

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

64
    [Experimental("DuckDBNET001")]
65
    public void RegisterTableFunction<T1, T2, T3, T4, T5, T6, T7, T8>(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback)
66
    {
67
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8));
×
68
    }
×
69

70
    [Experimental("DuckDBNET001")]
71
    private unsafe void RegisterTableFunctionInternal(string name, Func<IReadOnlyList<IDuckDBValueReader>, TableFunction> resultCallback, Action<object?, IDuckDBDataWriter[], ulong> mapperCallback, params Type[] parameterTypes)
72
    {
73
        var function = NativeMethods.TableFunction.DuckDBCreateTableFunction();
24✔
74
        using (var handle = name.ToUnmanagedString())
24✔
75
        {
76
            NativeMethods.TableFunction.DuckDBTableFunctionSetName(function, handle);
24✔
77
        }
24✔
78

79
        foreach (var type in parameterTypes)
162✔
80
        {
81
            using var logicalType = DuckDBTypeMap.GetLogicalType(type);
57✔
82
            NativeMethods.TableFunction.DuckDBTableFunctionAddParameter(function, logicalType);
57✔
83
        }
84

85
        var tableFunctionInfo = new TableFunctionInfo(resultCallback, mapperCallback);
24✔
86

87
        NativeMethods.TableFunction.DuckDBTableFunctionSetBind(function, &Bind);
24✔
88
        NativeMethods.TableFunction.DuckDBTableFunctionSetInit(function, &Init);
24✔
89
        NativeMethods.TableFunction.DuckDBTableFunctionSetFunction(function, &TableFunction);
24✔
90
        NativeMethods.TableFunction.DuckDBTableFunctionSetExtraInfo(function, tableFunctionInfo.ToHandle(), &DestroyExtraInfo);
24✔
91

92
        var state = NativeMethods.TableFunction.DuckDBRegisterTableFunction(NativeConnection, function);
24✔
93

94
        if (!state.IsSuccess())
24!
95
        {
96
            throw new InvalidOperationException($"Error registering user defined table function: {name}");
×
97
        }
98

99
        NativeMethods.TableFunction.DuckDBDestroyTableFunction(out function);
24✔
100
    }
24✔
101

102
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
103
    public static unsafe void Bind(IntPtr info)
104
    {
105
        IDuckDBValueReader[] parameters = [];
24✔
106
        try
107
        {
108
            var handle = GCHandle.FromIntPtr(NativeMethods.TableFunction.DuckDBBindGetExtraInfo(info));
24✔
109

110
            if (handle.Target is not TableFunctionInfo functionInfo)
24!
111
            {
112
                throw new InvalidOperationException("User defined table function bind failed. Bind extra info is null");
×
113
            }
114

115
            parameters = new IDuckDBValueReader[NativeMethods.TableFunction.DuckDBBindGetParameterCount(info)];
24✔
116

117
            for (var i = 0; i < parameters.Length; i++)
162✔
118
            {
119
                var value = NativeMethods.TableFunction.DuckDBBindGetParameter(info, (ulong)i);
57✔
120
                parameters[i] = value;
57✔
121
            }
122

123
            var tableFunctionData = functionInfo.Bind(parameters);
24✔
124

125
            foreach (var columnInfo in tableFunctionData.Columns)
90✔
126
            {
127
                using var logicalType = DuckDBTypeMap.GetLogicalType(columnInfo.Type);
24✔
128
                NativeMethods.TableFunction.DuckDBBindAddResultColumn(info, columnInfo.Name.ToUnmanagedString(), logicalType);
24✔
129
            }
130

131
            var bindData = new TableFunctionBindData(tableFunctionData.Columns, tableFunctionData.Data.GetEnumerator());
21✔
132

133
            NativeMethods.TableFunction.DuckDBBindSetBindData(info, bindData.ToHandle(), &DestroyExtraInfo);
21✔
134
        }
21✔
135
        catch (Exception ex)
136
        {
137
            using var errorMessage = ex.Message.ToUnmanagedString();
3✔
138
            NativeMethods.TableFunction.DuckDBBindSetError(info, errorMessage);
3✔
139
        }
3✔
140
        finally
141
        {
142
            foreach (var parameter in parameters)
162✔
143
            {
144
                (parameter as IDisposable)?.Dispose();
57!
145
            }
146
        }
24✔
147
    }
24✔
148

149
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
150
    public static void Init(IntPtr info) { }
21✔
151

152
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
153
    public static void TableFunction(IntPtr info, IntPtr chunk)
154
    {
155
        try
156
        {
157
            var bindData = GCHandle.FromIntPtr(NativeMethods.TableFunction.DuckDBFunctionGetBindData(info));
36✔
158
            var extraInfo = GCHandle.FromIntPtr(NativeMethods.TableFunction.DuckDBFunctionGetExtraInfo(info));
36✔
159

160
            if (bindData.Target is not TableFunctionBindData tableFunctionBindData)
36!
161
            {
162
                throw new InvalidOperationException("User defined table function failed. Function bind data is null");
×
163
            }
164

165
            if (extraInfo.Target is not TableFunctionInfo tableFunctionInfo)
36!
166
            {
167
                throw new InvalidOperationException("User defined table function failed. Function extra info is null");
×
168
            }
169

170
            var dataChunk = new DuckDBDataChunk(chunk);
36✔
171

172
            var writers = new VectorDataWriterBase[tableFunctionBindData.Columns.Count];
36✔
173
            for (var columnIndex = 0; columnIndex < tableFunctionBindData.Columns.Count; columnIndex++)
156✔
174
            {
175
                var column = tableFunctionBindData.Columns[columnIndex];
42✔
176
                var vector = NativeMethods.DataChunks.DuckDBDataChunkGetVector(dataChunk, columnIndex);
42✔
177

178
                using var logicalType = DuckDBTypeMap.GetLogicalType(column.Type);
42✔
179
                writers[columnIndex] = VectorDataWriterFactory.CreateWriter(vector, logicalType);
42✔
180
            }
181

182
            ulong size = 0;
36✔
183

184
            for (; size < DuckDBGlobalData.VectorSize; size++)
846✔
185
            {
186
                if (tableFunctionBindData.DataEnumerator.MoveNext())
441✔
187
                {
188
                    tableFunctionInfo.Mapper(tableFunctionBindData.DataEnumerator.Current, writers, size);
408✔
189
                }
190
                else
191
                {
192
                    break;
193
                }
194
            }
195

196
            NativeMethods.DataChunks.DuckDBDataChunkSetSize(dataChunk, size);
33✔
197
        }
33✔
198
        catch (Exception ex)
199
        {
200
            using var errorMessage = ex.Message.ToUnmanagedString();
3✔
201
            NativeMethods.TableFunction.DuckDBFunctionSetError(info, errorMessage);
3✔
202
        }
3✔
203
    }
36✔
204
#endif
205
}
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