From 6505fd5b13bf3c8157ed47b4f6abbe0dd3733d50 Mon Sep 17 00:00:00 2001 From: Roma Date: Sun, 11 Jan 2026 12:10:33 +0100 Subject: [PATCH 01/11] Add support for BigInteger, Int128, and UInt128 in SqliteValueBinder - Bind Int128, UInt128, and BigInteger parameters as TEXT in SQLite. - Add provider-level tests to verify correct binding of these large numeric types. - This change only affects parameter binding; reading values back still returns string. --- .../SqliteValueBinder.cs | 23 +++++++++ .../SqliteParameterTest.cs | 49 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs index 40cdbeb32c6..8d88f9d329c 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Numerics; using Microsoft.Data.Sqlite.Properties; namespace Microsoft.Data.Sqlite; @@ -228,6 +229,22 @@ public virtual void Bind() var value1 = (long)(ushort)value; BindInt64(value1); } + else if (type == typeof(BigInteger)) + { + BindText(((BigInteger)value).ToString(CultureInfo.InvariantCulture)); + } +#if NET7_0_OR_GREATER + else if (type == typeof(Int128)) + { + var value1 = (Int128)value; + BindText((value1).ToString(CultureInfo.InvariantCulture)); + } + else if (type == typeof(UInt128)) + { + var value1 = (UInt128)value; + BindText((value1).ToString(CultureInfo.InvariantCulture)); + } +#endif else { throw new InvalidOperationException(Resources.UnknownDataType(type)); @@ -247,7 +264,13 @@ public virtual void Bind() { typeof(DateOnly), SqliteType.Text }, { typeof(TimeOnly), SqliteType.Text }, #endif + { typeof(DBNull), SqliteType.Text }, + { typeof(BigInteger), SqliteType.Text }, +#if NET7_0_OR_GREATER + { typeof(Int128), SqliteType.Text }, + { 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 97accd942af..1133dc0822c 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.Data.Sqlite.TestUtilities; using Xunit; @@ -570,6 +571,54 @@ public void Add_range_of_parameters_using_DbCommand_base_class() } } + [Fact] + public void Bind_BigInteger_parameter_as_text() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + var command = connection.CreateCommand(); + command.CommandText = "SELECT @Parameter;"; + var value = BigInteger.Parse("1234567890123456789012345678901234567890"); + command.Parameters.AddWithValue("@Parameter", value); + connection.Open(); + var result = (string)command.ExecuteScalar()!; + Assert.Equal("1234567890123456789012345678901234567890", result); + } + } + + +#if NET7_0_OR_GREATER + [Fact] + public void Bind_Int128_parameter_as_text() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + var command = connection.CreateCommand(); + command.CommandText = "SELECT @Parameter;"; + var value = Int128.Parse("170141183460469231731687303715884105727"); + command.Parameters.AddWithValue("@Parameter", value); + connection.Open(); + var result = (string)command.ExecuteScalar()!; + Assert.Equal("170141183460469231731687303715884105727", result); + } + } + + [Fact] + public void Bind_UInt128_parameter_as_text() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + var command = connection.CreateCommand(); + command.CommandText = "SELECT @Parameter;"; + var value = UInt128.Parse("340282366920938463463374607431768211455"); + command.Parameters.AddWithValue("@Parameter", value); + connection.Open(); + var result = (string)command.ExecuteScalar()!; + Assert.Equal("340282366920938463463374607431768211455", result); + } + } +#endif + public static IEnumerable TypesData => new List { From 17b9daf612a6642d612842ba98a1fcdc2c2aabf8 Mon Sep 17 00:00:00 2001 From: Roma Date: Thu, 5 Feb 2026 22:02:58 +0100 Subject: [PATCH 02/11] Update src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs index f90cf9d859d..4d98d243e7a 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs @@ -246,13 +246,11 @@ public virtual void Bind() #if NET7_0_OR_GREATER else if (type == typeof(Int128)) { - var value1 = (Int128)value; - BindText((value1).ToString(CultureInfo.InvariantCulture)); + BindText(((Int128)value).ToString(CultureInfo.InvariantCulture)); } else if (type == typeof(UInt128)) { - var value1 = (UInt128)value; - BindText((value1).ToString(CultureInfo.InvariantCulture)); + BindText(((UInt128)value).ToString(CultureInfo.InvariantCulture)); } #endif else From 4ad4fb1efe3907e8df1b435a30b7fb5a38b91f13 Mon Sep 17 00:00:00 2001 From: Roma Date: Sun, 1 Mar 2026 23:03:16 +0100 Subject: [PATCH 03/11] Create sync.yml --- .github/workflows/sync.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/sync.yml diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml new file mode 100644 index 00000000000..16443f65c34 --- /dev/null +++ b/.github/workflows/sync.yml @@ -0,0 +1,18 @@ +name: Auto Sync Fork + +on: + schedule: + - cron: '*/30 * * * *' # перевіряє кожні 30 хвилин + workflow_dispatch: + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Sync fork + uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 + with: + upstream_sync_repo: ORIGINAL_OWNER/ORIGINAL_REPO + upstream_sync_branch: main + target_sync_branch: main + target_repo_token: ${{ secrets.GITHUB_TOKEN }} From 3fab19adeedbce0234179d99e451a9ffa0494600 Mon Sep 17 00:00:00 2001 From: Roma Date: Sun, 1 Mar 2026 23:04:43 +0100 Subject: [PATCH 04/11] Update sync.yml --- .github/workflows/sync.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 16443f65c34..c21be2c15c4 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -2,13 +2,19 @@ name: Auto Sync Fork on: schedule: - - cron: '*/30 * * * *' # перевіряє кожні 30 хвилин + - cron: '*/30 * * * *' workflow_dispatch: jobs: sync: runs-on: ubuntu-latest steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: main + fetch-depth: 0 + - name: Sync fork uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 with: From 3e2f0e007ac987c7dcae24bb625657bf95efe8b2 Mon Sep 17 00:00:00 2001 From: Roma Date: Sun, 1 Mar 2026 23:06:42 +0100 Subject: [PATCH 05/11] Update TestCosmos.yaml --- .github/workflows/TestCosmos.yaml | 51 ++++++++++--------------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/.github/workflows/TestCosmos.yaml b/.github/workflows/TestCosmos.yaml index 7b5199fea05..0133744434b 100644 --- a/.github/workflows/TestCosmos.yaml +++ b/.github/workflows/TestCosmos.yaml @@ -1,43 +1,24 @@ -name: Test Cosmos +name: Auto Sync Fork on: - push: - branches: - - main - - feature/* - - release/* - pull_request: - branches: - - main - - feature/* - - release/* - -permissions: {} + schedule: + - cron: '*/30 * * * *' + workflow_dispatch: jobs: - build: - runs-on: windows-latest - + sync: + runs-on: ubuntu-latest steps: - - name: Start Cosmos Emulator - run: | - Import-Module "$env:ProgramFiles\Azure Cosmos DB Emulator\PSModules\Microsoft.Azure.CosmosDB.Emulator" - Start-CosmosDbEmulator -Timeout 540 -NoUI -NoTelemetry -NoFirewall -EnablePreview - - name: Checkout - uses: actions/checkout@v6 - - - name: Restore - run: restore.cmd - shell: cmd - - - name: Test on Cosmos - run: dotnet test test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj - shell: cmd + uses: actions/checkout@v4 + with: + ref: main + fetch-depth: 0 - - name: Publish Test Results - uses: actions/upload-artifact@v7 - if: always() + - name: Sync fork + uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 with: - name: test-results - path: artifacts/log/Debug/* + upstream_sync_repo: dotnet/efcore + upstream_sync_branch: main + target_sync_branch: main + target_repo_token: ${{ secrets.GITHUB_TOKEN }} From d38816343dca4e34136bc1b13311605e9cdea1ec Mon Sep 17 00:00:00 2001 From: Roma Date: Sun, 1 Mar 2026 23:09:46 +0100 Subject: [PATCH 06/11] Update TestCosmos.yaml --- .github/workflows/TestCosmos.yaml | 51 +++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/.github/workflows/TestCosmos.yaml b/.github/workflows/TestCosmos.yaml index 0133744434b..7b5199fea05 100644 --- a/.github/workflows/TestCosmos.yaml +++ b/.github/workflows/TestCosmos.yaml @@ -1,24 +1,43 @@ -name: Auto Sync Fork +name: Test Cosmos on: - schedule: - - cron: '*/30 * * * *' - workflow_dispatch: + push: + branches: + - main + - feature/* + - release/* + pull_request: + branches: + - main + - feature/* + - release/* + +permissions: {} jobs: - sync: - runs-on: ubuntu-latest + build: + runs-on: windows-latest + steps: + - name: Start Cosmos Emulator + run: | + Import-Module "$env:ProgramFiles\Azure Cosmos DB Emulator\PSModules\Microsoft.Azure.CosmosDB.Emulator" + Start-CosmosDbEmulator -Timeout 540 -NoUI -NoTelemetry -NoFirewall -EnablePreview + - name: Checkout - uses: actions/checkout@v4 - with: - ref: main - fetch-depth: 0 + uses: actions/checkout@v6 + + - name: Restore + run: restore.cmd + shell: cmd + + - name: Test on Cosmos + run: dotnet test test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj + shell: cmd - - name: Sync fork - uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 + - name: Publish Test Results + uses: actions/upload-artifact@v7 + if: always() with: - upstream_sync_repo: dotnet/efcore - upstream_sync_branch: main - target_sync_branch: main - target_repo_token: ${{ secrets.GITHUB_TOKEN }} + name: test-results + path: artifacts/log/Debug/* From ae8b251dee08bcf6c7fef84007a97dc70c1fd78f Mon Sep 17 00:00:00 2001 From: Roma Date: Sun, 1 Mar 2026 23:10:19 +0100 Subject: [PATCH 07/11] Update sync.yml --- .github/workflows/sync.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index c21be2c15c4..0133744434b 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -18,7 +18,7 @@ jobs: - name: Sync fork uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 with: - upstream_sync_repo: ORIGINAL_OWNER/ORIGINAL_REPO + upstream_sync_repo: dotnet/efcore upstream_sync_branch: main target_sync_branch: main target_repo_token: ${{ secrets.GITHUB_TOKEN }} From 48138a4804956e1099bdd78a7924b4aefb475e08 Mon Sep 17 00:00:00 2001 From: Roma Date: Sun, 1 Mar 2026 23:19:33 +0100 Subject: [PATCH 08/11] Delete .github/workflows/sync.yml --- .github/workflows/sync.yml | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 .github/workflows/sync.yml diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml deleted file mode 100644 index 0133744434b..00000000000 --- a/.github/workflows/sync.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Auto Sync Fork - -on: - schedule: - - cron: '*/30 * * * *' - workflow_dispatch: - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: main - fetch-depth: 0 - - - name: Sync fork - uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 - with: - upstream_sync_repo: dotnet/efcore - upstream_sync_branch: main - target_sync_branch: main - target_repo_token: ${{ secrets.GITHUB_TOKEN }} From 0e688113a972513d4036b30053d3d30109538be0 Mon Sep 17 00:00:00 2001 From: Roma Date: Wed, 27 May 2026 11:19:33 +0200 Subject: [PATCH 09/11] Remove BigInteger support and pad Int128/UInt128 values for correct ordering --- .../SqliteValueBinder.cs | 10 ++- .../SqliteParameterTest.cs | 68 +++++++++++++++++-- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs index 4d98d243e7a..e587615f1db 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs @@ -239,18 +239,16 @@ public virtual void Bind() var value1 = (long)(ushort)value; BindInt64(value1); } - else if (type == typeof(BigInteger)) - { - BindText(((BigInteger)value).ToString(CultureInfo.InvariantCulture)); - } #if NET7_0_OR_GREATER else if (type == typeof(Int128)) { - BindText(((Int128)value).ToString(CultureInfo.InvariantCulture)); + var shifted = (UInt128)((Int128)value - Int128.MinValue); + + BindText(shifted.ToString("D39", CultureInfo.InvariantCulture)); } else if (type == typeof(UInt128)) { - BindText(((UInt128)value).ToString(CultureInfo.InvariantCulture)); + BindText(((UInt128)value).ToString("D39", CultureInfo.InvariantCulture)); } #endif else diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs index a604d2c3a90..0641937e196 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs @@ -607,13 +607,58 @@ public void Bind_BigInteger_parameter_as_text() #if NET7_0_OR_GREATER [Fact] - public void Bind_Int128_parameter_as_text() + public void Bind_Int128_zero_as_text() { using (var connection = new SqliteConnection("Data Source=:memory:")) { var command = connection.CreateCommand(); command.CommandText = "SELECT @Parameter;"; - var value = Int128.Parse("170141183460469231731687303715884105727"); + var value = (Int128)0; + command.Parameters.AddWithValue("@Parameter", value); + connection.Open(); + var result = (string)command.ExecuteScalar()!; + Assert.Equal("170141183460469231731687303715884105728", result); + } + } + + [Fact] + public void Bind_Int128_min_value_as_text() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + var command = connection.CreateCommand(); + command.CommandText = "SELECT @Parameter;"; + var value = Int128.MinValue; + command.Parameters.AddWithValue("@Parameter", value); + connection.Open(); + var result = (string)command.ExecuteScalar()!; + Assert.Equal("000000000000000000000000000000000000000", result); + } + } + + [Fact] + public void Bind_Int128_max_value_as_text() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + var command = connection.CreateCommand(); + command.CommandText = "SELECT @Parameter;"; + var value = Int128.MaxValue; + command.Parameters.AddWithValue("@Parameter", value); + connection.Open(); + var result = (string)command.ExecuteScalar()!; + Assert.Equal("340282366920938463463374607431768211455", result); + } + } + + [Fact] + public void Bind_Int128_negative_as_text() + { + using (var connection = new SqliteConnection("Data Source=:memory:")) + { + var command = connection.CreateCommand(); + command.CommandText = "SELECT @Parameter;"; + var value = (Int128)(-1); command.Parameters.AddWithValue("@Parameter", value); connection.Open(); var result = (string)command.ExecuteScalar()!; @@ -622,13 +667,28 @@ public void Bind_Int128_parameter_as_text() } [Fact] - public void Bind_UInt128_parameter_as_text() + 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.Parse("340282366920938463463374607431768211455"); + var value = UInt128.MaxValue; command.Parameters.AddWithValue("@Parameter", value); connection.Open(); var result = (string)command.ExecuteScalar()!; From 3f3ee80f36e24b3b8a10456f868ae81a89b53602 Mon Sep 17 00:00:00 2001 From: Roma Date: Wed, 27 May 2026 12:02:48 +0200 Subject: [PATCH 10/11] remove BigInteger --- .../SqliteValueBinder.cs | 2 -- .../SqliteParameterTest.cs | 16 ---------------- 2 files changed, 18 deletions(-) diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs index e587615f1db..5be2c658ec7 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.Numerics; using Microsoft.Data.Sqlite.Properties; namespace Microsoft.Data.Sqlite; @@ -274,7 +273,6 @@ public virtual void Bind() #endif { typeof(DBNull), SqliteType.Text }, - { typeof(BigInteger), SqliteType.Text }, #if NET7_0_OR_GREATER { typeof(Int128), SqliteType.Text }, { typeof(UInt128), SqliteType.Text }, diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs index 0641937e196..9dfb9edb9a5 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs @@ -589,22 +589,6 @@ public void Add_range_of_parameters_using_DbCommand_base_class() } } - [Fact] - public void Bind_BigInteger_parameter_as_text() - { - using (var connection = new SqliteConnection("Data Source=:memory:")) - { - var command = connection.CreateCommand(); - command.CommandText = "SELECT @Parameter;"; - var value = BigInteger.Parse("1234567890123456789012345678901234567890"); - command.Parameters.AddWithValue("@Parameter", value); - connection.Open(); - var result = (string)command.ExecuteScalar()!; - Assert.Equal("1234567890123456789012345678901234567890", result); - } - } - - #if NET7_0_OR_GREATER [Fact] public void Bind_Int128_zero_as_text() From 7369202d53a56ce3c2fff74b840f2a1358a61819 Mon Sep 17 00:00:00 2001 From: Roma Date: Wed, 27 May 2026 21:00:59 +0200 Subject: [PATCH 11/11] Add UInt128 ordering and concatenation tests --- .../SqliteValueBinder.cs | 7 -- .../SqliteParameterTest.cs | 74 ++++++++----------- 2 files changed, 31 insertions(+), 50 deletions(-) diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs index 5be2c658ec7..301b8979764 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteValueBinder.cs @@ -239,12 +239,6 @@ public virtual void Bind() BindInt64(value1); } #if NET7_0_OR_GREATER - else if (type == typeof(Int128)) - { - var shifted = (UInt128)((Int128)value - Int128.MinValue); - - BindText(shifted.ToString("D39", CultureInfo.InvariantCulture)); - } else if (type == typeof(UInt128)) { BindText(((UInt128)value).ToString("D39", CultureInfo.InvariantCulture)); @@ -274,7 +268,6 @@ public virtual void Bind() { typeof(DBNull), SqliteType.Text }, #if NET7_0_OR_GREATER - { typeof(Int128), SqliteType.Text }, { typeof(UInt128), SqliteType.Text }, #endif { typeof(decimal), SqliteType.Text }, diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs index 9dfb9edb9a5..6362eb520ef 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteParameterTest.cs @@ -591,28 +591,13 @@ public void Add_range_of_parameters_using_DbCommand_base_class() #if NET7_0_OR_GREATER [Fact] - public void Bind_Int128_zero_as_text() - { - using (var connection = new SqliteConnection("Data Source=:memory:")) - { - var command = connection.CreateCommand(); - command.CommandText = "SELECT @Parameter;"; - var value = (Int128)0; - command.Parameters.AddWithValue("@Parameter", value); - connection.Open(); - var result = (string)command.ExecuteScalar()!; - Assert.Equal("170141183460469231731687303715884105728", result); - } - } - - [Fact] - public void Bind_Int128_min_value_as_text() + 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 = Int128.MinValue; + var value = (UInt128)0; command.Parameters.AddWithValue("@Parameter", value); connection.Open(); var result = (string)command.ExecuteScalar()!; @@ -621,13 +606,13 @@ public void Bind_Int128_min_value_as_text() } [Fact] - public void Bind_Int128_max_value_as_text() + 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 = Int128.MaxValue; + var value = UInt128.MaxValue; command.Parameters.AddWithValue("@Parameter", value); connection.Open(); var result = (string)command.ExecuteScalar()!; @@ -636,47 +621,50 @@ public void Bind_Int128_max_value_as_text() } [Fact] - public void Bind_Int128_negative_as_text() + public void Bind_UInt128_ordering_works() { using (var connection = new SqliteConnection("Data Source=:memory:")) { - var command = connection.CreateCommand(); - command.CommandText = "SELECT @Parameter;"; - var value = (Int128)(-1); - command.Parameters.AddWithValue("@Parameter", value); connection.Open(); - var result = (string)command.ExecuteScalar()!; - Assert.Equal("170141183460469231731687303715884105727", result); - } - } - [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); + 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_max_value_as_text() + public void Bind_UInt128_concatenation_works() { using (var connection = new SqliteConnection("Data Source=:memory:")) { var command = connection.CreateCommand(); - command.CommandText = "SELECT @Parameter;"; - var value = UInt128.MaxValue; + command.CommandText = "SELECT @Parameter || '_suffix';"; + var value = (UInt128)42; command.Parameters.AddWithValue("@Parameter", value); connection.Open(); var result = (string)command.ExecuteScalar()!; - Assert.Equal("340282366920938463463374607431768211455", result); + Assert.Equal("000000000000000000000000000000000000042_suffix", result); } } #endif