ericsink / SQLitePCL.raw

A Portable Class Library (PCL) for low-level (raw) access to SQLite
Apache License 2.0
525 stars 109 forks source link

sqlite3_create_collation(..., null) doesn't delete collations #421

Open bricelam opened 3 years ago

bricelam commented 3 years ago
using System;
using static SQLitePCL.raw;

SQLitePCL.Batteries_V2.Init();

sqlite3_open(":memory:", out var db);

sqlite3_create_collation(db, "DELETE_ME", null, (_, strA, strB) => string.CompareOrdinal(strA, strB));
sqlite3_create_collation(db, "DELETE_ME", null, null);

sqlite3_prepare_v2(db, "select group_concat(name) from pragma_collation_list", out var stmt);
sqlite3_step(stmt);
var collations = sqlite3_column_text(stmt, 0).utf8_to_string();

Console.WriteLine(collations);

The result should not contain DELETE_ME.

I suspect the wrapping hook_handle is preventing it from being deleted.

https://github.com/ericsink/SQLitePCL.raw/blob/1b2e50535cf3c3e4811197b72b7dc694715227f6/src/SQLitePCLRaw.provider.dynamic_cdecl/Generated/provider_dynamic_cdecl.cs#L798-L802

bricelam commented 3 years ago

This might just be a SQLite bug. Versions before 3.31.0 also returned deleted functions.

ericsink commented 3 years ago

I do need to investigate this a bit.

To be clear, you do not appear to be saying that this is something which was previously working and now does not?

bricelam commented 3 years ago

I don’t know if it worked previously. This is my first try and I think I only tried on the latest prerelease of e_sqlite3

ericsink commented 3 years ago

Hmmm.

I went to write a failing test for this and noticed that there is already a test case that verifies a collation gets deleted: test_collation_remove

The code in the test is different, as it verifies the removal by actually trying to use the collation and expecting an error.

So there is something more subtle going on here.

ericsink commented 3 years ago

Wait -- what is pragma_collation_list ? I expected that to be PRAGMA collation_list rather than a SELECT.