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

Giorgi / DuckDB.NET / 10773748422

09 Sep 2024 01:01PM UTC coverage: 89.795% (-0.2%) from 89.997%
10773748422

push

github

Giorgi
Merge branch 'nightly-builds' into develop

920 of 1056 branches covered (87.12%)

Branch coverage included in aggregate %.

192 of 232 new or added lines in 23 files covered. (82.76%)

5 existing lines in 3 files now uncovered.

1887 of 2070 relevant lines covered (91.16%)

897099.16 hits per line

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

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

13
namespace DuckDB.NET.Data;
14

15
partial class DuckDBConnection
16
{
17
#if NET8_0_OR_GREATER
18
    [Experimental("DuckDBNET001")]
19
    public void RegisterScalarFunction<TResult>(string name, Action<IDuckDBDataReader[], IDuckDBDataWriter, ulong> action, bool isPureFunction = false)
20
    {
21
        RegisterScalarMethod(name, action, DuckDBTypeMap.GetLogicalType<TResult>(), varargs: false, !isPureFunction);
3✔
22
    }
3✔
23

24
    [Experimental("DuckDBNET001")]
25
    public void RegisterScalarFunction<T, TResult>(string name, Action<IDuckDBDataReader[], IDuckDBDataWriter, ulong> action, bool isPureFunction = true, bool @params = false)
26
    {
27
        RegisterScalarMethod(name, action, DuckDBTypeMap.GetLogicalType<TResult>(), @params, !isPureFunction, DuckDBTypeMap.GetLogicalType<T>());
9✔
28
    }
9✔
29

30
    [Experimental("DuckDBNET001")]
31
    public void RegisterScalarFunction<T1, T2, TResult>(string name, Action<IDuckDBDataReader[], IDuckDBDataWriter, ulong> action, bool isPureFunction = true)
32
    {
33
        RegisterScalarMethod(name, action, DuckDBTypeMap.GetLogicalType<TResult>(), varargs: false, !isPureFunction,
6✔
34
                              DuckDBTypeMap.GetLogicalType<T1>(), 
6✔
35
                              DuckDBTypeMap.GetLogicalType<T2>());
6✔
36
    }
6✔
37

38
    [Experimental("DuckDBNET001")]
39
    public void RegisterScalarFunction<T1, T2, T3, TResult>(string name, Action<IDuckDBDataReader[], IDuckDBDataWriter, ulong> action, bool isPureFunction = true)
40
    {
NEW
41
        RegisterScalarMethod(name, action, DuckDBTypeMap.GetLogicalType<TResult>(), varargs: false, !isPureFunction,
×
NEW
42
                              DuckDBTypeMap.GetLogicalType<T1>(),
×
NEW
43
                              DuckDBTypeMap.GetLogicalType<T2>(),
×
NEW
44
                              DuckDBTypeMap.GetLogicalType<T3>());
×
NEW
45
    }
×
46

47
    [Experimental("DuckDBNET001")]
48
    public void RegisterScalarFunction<T1, T2, T3, T4, TResult>(string name, Action<IDuckDBDataReader[], IDuckDBDataWriter, ulong> action, bool isPureFunction = true)
49
    {
NEW
50
        RegisterScalarMethod(name, action, DuckDBTypeMap.GetLogicalType<TResult>(), varargs: false, !isPureFunction,
×
NEW
51
                              DuckDBTypeMap.GetLogicalType<T1>(),
×
NEW
52
                              DuckDBTypeMap.GetLogicalType<T2>(),
×
NEW
53
                              DuckDBTypeMap.GetLogicalType<T3>(),
×
NEW
54
                              DuckDBTypeMap.GetLogicalType<T4>());
×
NEW
55
    }
×
56

57
    [Experimental("DuckDBNET001")]
58
    private unsafe void RegisterScalarMethod(string name, Action<IDuckDBDataReader[], IDuckDBDataWriter, ulong> action, DuckDBLogicalType returnType,
59
                                             bool varargs, bool @volatile, params DuckDBLogicalType[] parameterTypes)
60
    {
61
        var function = NativeMethods.ScalarFunction.DuckDBCreateScalarFunction();
18✔
62
        NativeMethods.ScalarFunction.DuckDBScalarFunctionSetName(function, name.ToUnmanagedString());
18✔
63

64
        if (varargs)
18✔
65
        {
66
            if (parameterTypes.Length != 1)
3!
67
            {
NEW
68
                throw new InvalidOperationException("Cannot use params with multiple parameters");
×
69
            }
70

71
            NativeMethods.ScalarFunction.DuckDBScalarFunctionSetVarargs(function, parameterTypes[0]);
3✔
72
        }
73
        else
74
        {
75
            foreach (var type in parameterTypes)
66✔
76
            {
77
                NativeMethods.ScalarFunction.DuckDBScalarFunctionAddParameter(function, type);
18✔
78
                type.Dispose();
18✔
79
            }
80
        }
81

82
        if (@volatile)
18✔
83
        {
84
            NativeMethods.ScalarFunction.DuckDBScalarFunctionSetVolatile(function);
9✔
85
        }
86

87
        NativeMethods.ScalarFunction.DuckDBScalarFunctionSetReturnType(function, returnType);
18✔
88
        NativeMethods.ScalarFunction.DuckDBScalarFunctionSetFunction(function, &ScalarFunctionCallback);
18✔
89

90
        var info = new ScalarFunctionInfo(returnType, action);
18✔
91

92
        NativeMethods.ScalarFunction.DuckDBScalarFunctionSetExtraInfo(function, info.ToHandle(), &DestroyExtraInfo);
18✔
93

94
        var state = NativeMethods.ScalarFunction.DuckDBRegisterScalarFunction(NativeConnection, function);
18✔
95

96
        NativeMethods.ScalarFunction.DuckDBDestroyScalarFunction(out function);
18✔
97

98
        if (!state.IsSuccess())
18!
99
        {
NEW
100
            throw new InvalidOperationException("Error registering user defined scalar function");
×
101
        }
102
    }
18✔
103

104
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
105
    private static void ScalarFunctionCallback(IntPtr info, IntPtr chunk, IntPtr outputVector)
106
    {
107
        var dataChunk = new DuckDBDataChunk(chunk);
78✔
108

109
        var chunkSize = NativeMethods.DataChunks.DuckDBDataChunkGetSize(dataChunk);
78✔
110
        var handle = GCHandle.FromIntPtr(NativeMethods.ScalarFunction.DuckDBScalarFunctionGetExtraInfo(info));
78✔
111

112
        if (handle.Target is not ScalarFunctionInfo functionInfo)
78!
113
        {
NEW
114
            throw new InvalidOperationException("User defined scalar function execution failed. Function extra info is null");
×
115
        }
116

117
        var readers = new VectorDataReaderBase[NativeMethods.DataChunks.DuckDBDataChunkGetColumnCount(dataChunk)];
78✔
118

119
        for (var index = 0; index < readers.Length; index++)
354✔
120
        {
121
            var vector = NativeMethods.DataChunks.DuckDBDataChunkGetVector(dataChunk, index);
99✔
122
            readers[index] = VectorDataReaderFactory.CreateReader(vector, NativeMethods.Vectors.DuckDBVectorGetColumnType(vector));
99✔
123
        }
124

125
        var writer = VectorDataWriterFactory.CreateWriter(outputVector, functionInfo.ReturnType);
78✔
126

127
        functionInfo.Action(readers, writer, chunkSize);
78✔
128
    }
78✔
129

130
    [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
131
    private static void DestroyExtraInfo(IntPtr pointer) => pointer.FreeHandle();
18✔
132
#endif
133
}
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