diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs index c9eabf0bc27..301b8979764 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs @@ -238,6 +238,12 @@ public virtual void Bind() var value1 = (long)(ushort)value; BindInt64(value1); } +#if NET7_0_OR_GREATER + else if (type == typeof(UInt128)) + { + BindText(((UInt128)value).ToString("D39", CultureInfo.InvariantCulture)); + } +#endif else { throw new InvalidOperationException(Resources.UnknownDataType(type)); @@ -259,7 +265,11 @@ public virtual void Bind() { typeof(DateOnly), SqliteType.Text }, { typeof(TimeOnly), SqliteType.Text }, #endif + { typeof(DBNull), SqliteType.Text }, +#if NET7_0_OR_GREATER + { typeof(UInt128), SqliteType.Text }, +#endif { typeof(decimal), SqliteType.Text }, { typeof(double), SqliteType.Real }, { typeof(float), SqliteType.Real }, diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs index 1f3dd7d4b78..6362eb520ef 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; +using System.Numerics; using Microsoft.Data.Sqlite.Properties; using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; using Xunit; @@ -588,6 +589,86 @@ public void Add_range_of_parameters_using_DbCommand_base_class() } } +#if NET7_0_OR_GREATER + [Fact] + public void Bind_UInt128_zero_as_text() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + var command = connection.CreateCommand(); + command.CommandText = "SELECT @Parameter;"; + var value = (UInt128)0; + command.Parameters.AddWithValue("@Parameter", value); + connection.Open(); + var result = (string)command.ExecuteScalar()!; + Assert.Equal("000000000000000000000000000000000000000", result); + } + } + + [Fact] + public void Bind_UInt128_max_value_as_text() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + var command = connection.CreateCommand(); + command.CommandText = "SELECT @Parameter;"; + var value = UInt128.MaxValue; + command.Parameters.AddWithValue("@Parameter", value); + connection.Open(); + var result = (string)command.ExecuteScalar()!; + Assert.Equal("340282366920938463463374607431768211455", result); + } + } + + [Fact] + public void Bind_UInt128_ordering_works() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + connection.Open(); + + var command = connection.CreateCommand(); + command.CommandText = """ + CREATE TABLE TestOrdering (Value TEXT); + INSERT INTO TestOrdering VALUES (@A); + INSERT INTO TestOrdering VALUES (@B); + INSERT INTO TestOrdering VALUES (@C); + SELECT Value FROM TestOrdering ORDER BY Value; + """; + command.Parameters.AddWithValue("@A", (UInt128)500); + command.Parameters.AddWithValue("@B", UInt128.MaxValue); + command.Parameters.AddWithValue("@C", (UInt128)1); + + var results = new List(); + using var reader = command.ExecuteReader(); + while (reader.Read()) + { + results.Add(reader.GetString(0)); + } + + Assert.Equal(3, results.Count); + Assert.Equal("000000000000000000000000000000000000001", results[0]); + Assert.Equal("000000000000000000000000000000000000500", results[1]); + Assert.Equal("340282366920938463463374607431768211455", results[2]); + } + } + + [Fact] + public void Bind_UInt128_concatenation_works() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + var command = connection.CreateCommand(); + command.CommandText = "SELECT @Parameter || '_suffix';"; + var value = (UInt128)42; + command.Parameters.AddWithValue("@Parameter", value); + connection.Open(); + var result = (string)command.ExecuteScalar()!; + Assert.Equal("000000000000000000000000000000000000042_suffix", result); + } + } +#endif + public static IEnumerable TypesData => new List {