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

Giorgi / DuckDB.NET / 28017109290

23 Jun 2026 09:41AM UTC coverage: 89.361% (-0.4%) from 89.738%
28017109290

push

github

Giorgi
Merge branch 'main' into nightly-builds

1330 of 1545 branches covered (86.08%)

Branch coverage included in aggregate %.

362 of 413 new or added lines in 32 files covered. (87.65%)

4 existing lines in 3 files now uncovered.

2769 of 3042 relevant lines covered (91.03%)

434285.19 hits per line

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

92.13
/DuckDB.NET.Data/PreparedStatement/PreparedStatement.cs
1
using System.Linq;
2
using DuckDB.NET.Data.Connection;
3

4
namespace DuckDB.NET.Data.PreparedStatement;
5

6
internal sealed class PreparedStatement : IDisposable
7
{
8
    private readonly DuckDBPreparedStatement statement;
9

10
    private PreparedStatement(DuckDBPreparedStatement statement)
158,273✔
11
    {
12
        this.statement = statement;
158,273✔
13
    }
158,273✔
14

15
    public static IEnumerable<DuckDBResult> PrepareMultiple(DuckDBNativeConnection connection, string query, DuckDBParameterCollection parameters, bool useStreamingMode)
16
    {
17
        var statementCount = NativeMethods.ExtractStatements.DuckDBExtractStatements(connection, query, out var extractedStatements);
158,180✔
18

19
        using (extractedStatements)
158,180✔
20
        {
21
            if (statementCount <= 0)
158,180✔
22
            {
23
                var error = NativeMethods.ExtractStatements.DuckDBExtractStatementsError(extractedStatements);
3✔
24
                throw new DuckDBException(error);
3✔
25
            }
26

27
            for (int index = 0; index < statementCount; index++)
553,804✔
28
            {
29
                var status = NativeMethods.ExtractStatements.DuckDBPrepareExtractedStatement(connection, extractedStatements, index, out var statement);
158,288✔
30

31
                if (status.IsSuccess())
158,288✔
32
                {
33
                    using var preparedStatement = new PreparedStatement(statement);
158,273✔
34
                    yield return preparedStatement.Execute(parameters, useStreamingMode, connection);
158,273✔
35
                }
118,725✔
36
                else
37
                {
38
                    var errorMessage = NativeMethods.PreparedStatements.DuckDBPrepareError(statement);
15✔
39

40
                    if (string.IsNullOrEmpty(errorMessage))
15!
41
                    {
NEW
42
                        errorMessage = "DuckDBQuery failed";
×
43
                    }
44

45
                    throw new DuckDBException(errorMessage, UdfExceptionStore.Retrieve(connection));
15✔
46
                }
47
            }
48
        }
118,614✔
49
    }
118,614✔
50

51
    private DuckDBResult Execute(DuckDBParameterCollection parameterCollection, bool useStreamingMode, DuckDBNativeConnection connection)
52
    {
53
        BindParameters(statement, parameterCollection);
158,273✔
54

55
        var status = useStreamingMode
158,255✔
56
            ? NativeMethods.PreparedStatements.DuckDBExecutePreparedStreaming(statement, out var queryResult)
158,255✔
57
            : NativeMethods.PreparedStatements.DuckDBExecutePrepared(statement, out queryResult);
158,255✔
58

59
        if (!status.IsSuccess())
158,255✔
60
        {
61
            var errorMessage = NativeMethods.Query.DuckDBResultError(ref queryResult);
63✔
62
            var errorType = NativeMethods.Query.DuckDBResultErrorType(ref queryResult);
63✔
63
            queryResult.Close();
63✔
64

65
            if (string.IsNullOrEmpty(errorMessage))
63!
66
            {
67
                errorMessage = "DuckDB execution failed";
×
68
            }
69

70
            if (errorType == DuckDBErrorType.Interrupt)
63✔
71
            {
72
                throw new OperationCanceledException();
12✔
73
            }
74

75
            var innerException = UdfExceptionStore.Retrieve(connection);
51✔
76
            throw innerException != null
51✔
77
                ? new DuckDBException(errorMessage, innerException)
51✔
78
                : new DuckDBException(errorMessage, errorType);
51✔
79
        }
80

81
        return queryResult;
158,192✔
82
    }
83

84
    private static void BindParameters(DuckDBPreparedStatement preparedStatement, DuckDBParameterCollection parameterCollection)
85
    {
86
        var expectedParameters = NativeMethods.PreparedStatements.DuckDBParams(preparedStatement);
158,273✔
87
        if (parameterCollection.Count < expectedParameters)
158,273✔
88
        {
89
            throw new InvalidOperationException($"Invalid number of parameters. Expected {expectedParameters}, got {parameterCollection.Count}");
18✔
90
        }
91

92
        if (parameterCollection.OfType<DuckDBParameter>().Any(p => !string.IsNullOrEmpty(p.ParameterName)))
159,854✔
93
        {
94
            foreach (DuckDBParameter param in parameterCollection)
756✔
95
            {
96
                var state = NativeMethods.PreparedStatements.DuckDBBindParameterIndex(preparedStatement, out var index, param.ParameterName);
225✔
97
                if (state.IsSuccess())
225✔
98
                {
99
                    BindParameter(preparedStatement, index, param);
195✔
100
                }
101
            }
102
        }
103
        else
104
        {
105
            for (var i = 0; i < expectedParameters; ++i)
318,010✔
106
            {
107
                var param = parameterCollection[i];
903✔
108
                BindParameter(preparedStatement, i + 1, param);
903✔
109
            }
110
        }
111
    }
158,255✔
112

113
    private static void BindParameter(DuckDBPreparedStatement preparedStatement, long index, DuckDBParameter parameter)
114
    {
115
        using var parameterLogicalType = NativeMethods.PreparedStatements.DuckDBParamLogicalType(preparedStatement, index);
1,098✔
116
        var duckDBType = NativeMethods.LogicalType.DuckDBGetTypeId(parameterLogicalType);
1,098✔
117

118
        using var duckDBValue = parameter.Value.ToDuckDBValue(parameterLogicalType, duckDBType, parameter.DbType);
1,098✔
119

120
        var result = NativeMethods.PreparedStatements.DuckDBBindValue(preparedStatement, index, duckDBValue);
1,098✔
121

122
        if (!result.IsSuccess())
1,098!
123
        {
124
            var errorMessage = NativeMethods.PreparedStatements.DuckDBPrepareError(preparedStatement);
×
125
            throw new InvalidOperationException($"Unable to bind parameter {index}: {errorMessage}");
×
126
        }
127
    }
2,196✔
128

129
    public void Dispose()
130
    {
131
        statement.Dispose();
157,613✔
132
    }
157,613✔
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