dotnet / dotnet/efcore

Support span based collations comparison functions in Sqlite

Open
#35,236 4 comments 1 reaction 0 assignees View on GitHub
area-adonet-sqlite area-perf customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

Sqlite supports creating custom collations via `SqliteConnection.CreateCollation`
https://github.com/dotnet/efcore/blob/d1e1dfa531dbf2d90df4a42ba71890ed5025dffd/src/Microsoft.Data.Sqlite.Core/SqliteConnection.cs#L463
this calls [`sqlite3_create_collation`](https://github.com/ericsink/SQLitePCL.raw/blob/685942a31a9e43db85366a719b3b30547f90ef79/src/SQLitePCLRaw.core/raw.cs#L531), however this function allocates strings for every comparison.

I'd like to have a function which works with spans, there's already the function [`sqlite3__create_collation_utf8`](https://github.com/ericsink/SQLitePCL.raw/blob/685942a31a9e43db85366a719b3b30547f90ef79/src/SQLitePCLRaw.core/raw.cs#L558) which exposes the span based API we just need to wire it up. I'm happy to contribute a PR if it would be accepted.
```C#
private void CreateSpanCollation(SqliteConnection connection,
string name, T state,
Func, ReadOnlySpan, int> compare)
{
if (connection.State != ConnectionState.Open)
throw new InvalidOperationException("Unable to create custom collation Connection must be open.");
var rc = SQLitePCL.raw.sqlite3__create_collation_utf8(connection.Handle,
name,
Tuple.Create(state, compare),
static (s, x, y) =>
{
var (state, compare) = (Tuple, ReadOnlySpan, int>>) s;
Span xSpan = stackalloc char[Encoding.UTF8.GetCharCount(x)];
Span ySpan = stackalloc char[Encoding.UTF8.GetCharCount(y)];
Encoding.UTF8.GetChars(x, xSpan);
Encoding.UTF8.GetChars(y, ySpan);

return compare(state, xSpan, ySpan);
});
SqliteException.ThrowExceptionForRC(rc, connection.Handle);
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.