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

Giorgi / DuckDB.NET / 12084884944

29 Nov 2024 12:37PM UTC coverage: 89.839% (-0.04%) from 89.881%
12084884944

push

github

Giorgi
Rename conflicting table function

1055 of 1209 branches covered (87.26%)

Branch coverage included in aggregate %.

2075 of 2275 relevant lines covered (91.21%)

824654.22 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);
126✔
16

17
public record TableFunction(IReadOnlyList<ColumnInfo> Columns, IEnumerable Data);
96✔
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));
12✔
26
    }
12✔
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();
27✔
74
        using (var handle = name.ToUnmanagedString())
27✔
75
        {
76
            NativeMethods.TableFunction.DuckDBTableFunctionSetName(function, handle);
27✔
77
        }
27✔
78

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

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

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

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

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

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

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

110
            if (handle.Target is not TableFunctionInfo functionInfo)
27!
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)];
27✔
116

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

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

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

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

133
            NativeMethods.TableFunction.DuckDBBindSetBindData(info, bindData.ToHandle(), &DestroyExtraInfo);
24✔
134
        }
24✔
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)
174✔
143
            {
144
                (parameter as IDisposable)?.Dispose();
60!
145
            }
146
        }
27✔
147
    }
27✔
148

149
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
150
    public static void Init(IntPtr info) { }
24✔
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));
39✔
158
            var extraInfo = GCHandle.FromIntPtr(NativeMethods.TableFunction.DuckDBFunctionGetExtraInfo(info));
39✔
159

160
            if (bindData.Target is not TableFunctionBindData tableFunctionBindData)
39!
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)
39!
166
            {
167
                throw new InvalidOperationException("User defined table function failed. Function extra info is null");
×
168
            }
169

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

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

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

182
            ulong size = 0;
39✔
183

184
            for (; size < DuckDBGlobalData.VectorSize; size++)
849✔
185
            {
186
                if (tableFunctionBindData.DataEnumerator.MoveNext())
444✔
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);
36✔
197
        }
36✔
198
        catch (Exception ex)
199
        {
200
            using var errorMessage = ex.Message.ToUnmanagedString();
3✔
201
            NativeMethods.TableFunction.DuckDBFunctionSetError(info, errorMessage);
3✔
202
        }
3✔
203
    }
39✔
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