Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix null handling #64

Merged
merged 1 commit into from
Sep 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions DuckDB.NET.Data/Extensions/ObjectExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#nullable enable
using System;

namespace DuckDB.NET.Data.Extensions;

internal static class NullExtension
{
public static bool IsNull(this object? value)
=> value is null or DBNull;
}
5 changes: 3 additions & 2 deletions DuckDB.NET.Data/Internal/DbTypeMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Data;
using System.Numerics;
using DuckDB.NET.Data.Extensions;

namespace DuckDB.NET.Data.Internal;

Expand Down Expand Up @@ -33,9 +34,9 @@ internal static class DbTypeMap

public static DbType GetDbTypeForValue(object value)
{
if (value == null)
if (value.IsNull())
{
throw new ArgumentNullException(nameof(value));
return DbType.Object;
}

var type = value.GetType();
Expand Down
3 changes: 2 additions & 1 deletion DuckDB.NET.Data/Internal/PreparedStatement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Data;
using System.Numerics;
using DuckDB.NET.Data.Extensions;

namespace DuckDB.NET.Data;

Expand Down Expand Up @@ -86,7 +87,7 @@ private static void BindParameters(DuckDBPreparedStatement preparedStatement, Du

private static void BindParameter(DuckDBPreparedStatement preparedStatement, long index, DuckDBParameter parameter)
{
if (parameter.Value == null)
if (parameter.Value.IsNull())
{
NativeMethods.PreparedStatements.DuckDBBindNull(preparedStatement, index);
return;
Expand Down
32 changes: 32 additions & 0 deletions DuckDB.NET.Test/Parameters/ParameterCollectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ public void BindSingleValueTest(string query)
var scalar = command.ExecuteScalar();
scalar.Should().Be(42);
}

[Theory]
[InlineData("SELECT ?1;")]
[InlineData("SELECT ?;")]
[InlineData("SELECT $1;")]
public void BindSingleValueNullTest(string query)
{
using var connection = new DuckDBConnection("DataSource=:memory:");
connection.Open();

var command = connection.CreateCommand();

command.Parameters.Add(new DuckDBParameter("test", null));
command.CommandText = query;
var scalar = command.ExecuteScalar();
scalar.Should().Be(DBNull.Value);
}

[Fact]
public void BindNullValueTest()
Expand Down Expand Up @@ -216,6 +233,21 @@ public void BindDapperDynamicParamsOnlyTest(string queryStatement)

connection.Execute(queryStatement, dp);
}

[Theory]
[InlineData("SELECT ?1;")]
[InlineData("SELECT ?;")]
[InlineData("SELECT $1;")]
public void BindSingleValueDapperNullTest(string query)
{
using var connection = new DuckDBConnection("DataSource=:memory:");
connection.Open();

var parameters = new DynamicParameters();
parameters.Add("test", null);
var scalar = connection.QuerySingle<long?>(query, parameters);
scalar.Should().BeNull();
}

[Theory]
// Dapper does not support such placeholders when using an object :(
Expand Down