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

Giorgi / DuckDB.NET / 11718008762

07 Nov 2024 06:48AM UTC coverage: 89.937% (+0.09%) from 89.848%
11718008762

push

github

Giorgi
Merge branch 'develop'

1063 of 1216 branches covered (87.42%)

Branch coverage included in aggregate %.

256 of 275 new or added lines in 15 files covered. (93.09%)

1 existing line in 1 file now uncovered.

2083 of 2282 relevant lines covered (91.28%)

833197.35 hits per line

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

84.95
/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);
87✔
16

17
public record TableFunction(IReadOnlyList<ColumnInfo> Columns, IEnumerable Data);
60✔
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));
3✔
26
    }
3✔
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));
3✔
32
    }
3✔
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
    {
NEW
55
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6));
×
NEW
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
    {
NEW
61
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7));
×
NEW
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
    {
NEW
67
        RegisterTableFunctionInternal(name, resultCallback, mapperCallback, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8));
×
NEW
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();
15✔
74
        using (var handle = name.ToUnmanagedString())
15✔
75
        {
76
            NativeMethods.TableFunction.DuckDBTableFunctionSetName(function, handle);
15✔
77
        }
15✔
78

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

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

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

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

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

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

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

107
        if (handle.Target is not TableFunctionInfo functionInfo)
15!
108
        {
NEW
109
            throw new InvalidOperationException("User defined table function bind failed. Bind extra info is null");
×
110
        }
111

112
        var parameters = new IDuckDBValueReader[NativeMethods.TableFunction.DuckDBBindGetParameterCount(info)];
15✔
113

114
        for (var i = 0; i < parameters.Length; i++)
120✔
115
        {
116
            var value = NativeMethods.TableFunction.DuckDBBindGetParameter(info, (ulong)i);
45✔
117
            parameters[i] = value;
45✔
118
        }
119

120
        var tableFunctionData = functionInfo.Bind(parameters);
15✔
121

122
        foreach (var parameter in parameters)
120✔
123
        {
124
            ((DuckDBValue)parameter).Dispose();
45✔
125
        }
126

127
        foreach (var columnInfo in tableFunctionData.Columns)
66✔
128
        {
129
            using var logicalType = DuckDBTypeMap.GetLogicalType(columnInfo.Type);
18✔
130
            NativeMethods.TableFunction.DuckDBBindAddResultColumn(info, columnInfo.Name.ToUnmanagedString(), logicalType);
18✔
131
        }
132

133
        var bindData = new TableFunctionBindData(tableFunctionData.Columns, tableFunctionData.Data.GetEnumerator());
15✔
134

135
        NativeMethods.TableFunction.DuckDBBindSetBindData(info, bindData.ToHandle(), &DestroyExtraInfo);
15✔
136
    }
15✔
137

138
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
139
    public static void Init(IntPtr info) { }
15✔
140

141
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
142
    public static void TableFunction(IntPtr info, IntPtr chunk)
143
    {
144
        var bindData = GCHandle.FromIntPtr(NativeMethods.TableFunction.DuckDBFunctionGetBindData(info));
27✔
145
        var extraInfo = GCHandle.FromIntPtr(NativeMethods.TableFunction.DuckDBFunctionGetExtraInfo(info));
27✔
146

147
        if (bindData.Target is not TableFunctionBindData tableFunctionBindData)
27!
148
        {
NEW
149
            throw new InvalidOperationException("User defined table function failed. Function bind data is null");
×
150
        }
151

152
        if (extraInfo.Target is not TableFunctionInfo tableFunctionInfo)
27!
153
        {
NEW
154
            throw new InvalidOperationException("User defined table function failed. Function extra info is null");
×
155
        }
156

157
        var dataChunk = new DuckDBDataChunk(chunk);
27✔
158

159
        var writers = new VectorDataWriterBase[tableFunctionBindData.Columns.Count];
27✔
160
        for (var columnIndex = 0; columnIndex < tableFunctionBindData.Columns.Count; columnIndex++)
120✔
161
        {
162
            var column = tableFunctionBindData.Columns[columnIndex];
33✔
163
            var vector = NativeMethods.DataChunks.DuckDBDataChunkGetVector(dataChunk, columnIndex);
33✔
164

165
            using var logicalType = DuckDBTypeMap.GetLogicalType(column.Type);
33✔
166
            writers[columnIndex] = VectorDataWriterFactory.CreateWriter(vector, logicalType);
33✔
167
        }
168

169
        ulong size = 0;
27✔
170

171
        for (; size < DuckDBGlobalData.VectorSize; size++)
789✔
172
        {
173
            if (tableFunctionBindData.DataEnumerator.MoveNext())
408✔
174
            {
175
                tableFunctionInfo.Mapper(tableFunctionBindData.DataEnumerator.Current, writers, size);
381✔
176
            }
177
            else
178
            {
179
                break;
180
            }
181
        }
182

183
        NativeMethods.DataChunks.DuckDBDataChunkSetSize(dataChunk, size);
27✔
184
    }
27✔
185
#endif
186
}
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