Minimal code reproduction:
using DuckDB.NET.Data;
enum Mood : byte
{
Happy = 1,
Sad = 2,
// Skip 3
Neutral = 4
}
internal static class Program
{
private static void Main()
{
var enumNames = Enum.GetNames<Mood>();
var enumLabelsSql = string.Join(", ", enumNames.Select(n => $"'{n}'"));
var enumTypeSql = $"CREATE TYPE Mood AS ENUM ({enumLabelsSql});";
using var connection = new DuckDBConnection("Data Source=:memory:");
connection.Open();
using var command = connection.CreateCommand();
command.CommandText = enumTypeSql;
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE EnumTest (Value Mood);";
command.ExecuteNonQuery();
var valuesToInsert = new[]
{
Mood.Happy,
Mood.Sad,
Mood.Neutral
};
using (var appender = connection.CreateAppender("EnumTest"))
{
foreach (var enumValue in valuesToInsert)
{
var row = appender.CreateRow();
row.AppendValue(enumValue);
row.EndRow();
}
}
}
}
I believe this is because DuckDB.NET casts the enum to an integer value and then writes that to the database. As long as the enum values are consecutive, DuckDB's internal enum map and C#'s enum map align, so this works out. When the C# enum has gaps in its values, this assumption is no longer true and the code crashes.
This also means that [Flags] enums can cause a bit of chaos as well. Since DuckDB enums aren't designed to be used as flags, DuckDB.NET should probably prevent [Flags] enums from being used entirely, because something like "Happy | Neutral" cannot convert to a DuckDB enum.
Minimal code reproduction:
I believe this is because DuckDB.NET casts the enum to an integer value and then writes that to the database. As long as the enum values are consecutive, DuckDB's internal enum map and C#'s enum map align, so this works out. When the C# enum has gaps in its values, this assumption is no longer true and the code crashes.
This also means that [Flags] enums can cause a bit of chaos as well. Since DuckDB enums aren't designed to be used as flags, DuckDB.NET should probably prevent [Flags] enums from being used entirely, because something like "Happy | Neutral" cannot convert to a DuckDB enum.