@@ -9,40 +9,40 @@ namespace DuckDB.NET.Data.Internal.Writer;
9
9
internal sealed unsafe class EnumVectorDataWriter : VectorDataWriterBase
10
10
{
11
11
private readonly DuckDBType enumType ;
12
+ private readonly DuckDBLogicalType logicalType ;
12
13
13
14
private readonly uint enumDictionarySize ;
14
15
15
- private readonly Dictionary < string , uint > enumValues ;
16
+ private readonly Dictionary < string , uint > enumValues = [ ] ;
16
17
17
18
public EnumVectorDataWriter ( IntPtr vector , void * vectorData , DuckDBLogicalType logicalType , DuckDBType columnType ) : base ( vector , vectorData , columnType )
18
19
{
20
+ this . logicalType = logicalType ;
21
+
19
22
enumType = NativeMethods . LogicalType . DuckDBEnumInternalType ( logicalType ) ;
20
23
enumDictionarySize = NativeMethods . LogicalType . DuckDBEnumDictionarySize ( logicalType ) ;
21
24
22
- uint maxEnumDictionarySize = enumType switch
25
+ var maxEnumDictionarySize = enumType switch
23
26
{
24
27
DuckDBType . UnsignedTinyInt => byte . MaxValue ,
25
28
DuckDBType . UnsignedSmallInt => ushort . MaxValue ,
26
29
DuckDBType . UnsignedInteger => uint . MaxValue ,
27
30
_ => throw new NotSupportedException ( $ "The internal enum type must be utinyint, usmallint, or uinteger.") ,
28
31
} ;
29
- if ( enumDictionarySize > maxEnumDictionarySize )
30
- {
31
- // This exception should only be thrown if the DuckDB library has a bug.
32
- throw new InvalidOperationException ( $ "The internal enum type is \" { enumType } \" but the enum dictionary size is greater than { maxEnumDictionarySize } .") ;
33
- }
34
-
35
- enumValues = [ ] ;
36
- for ( uint index = 0 ; index < enumDictionarySize ; index ++ )
37
- {
38
- string enumValueName = NativeMethods . LogicalType . DuckDBEnumDictionaryValue ( logicalType , index ) . ToManagedString ( ) ;
39
- enumValues . Add ( enumValueName , index ) ;
40
- }
41
32
}
42
33
43
34
internal override bool AppendString ( string value , int rowIndex )
44
35
{
45
- if ( enumValues . TryGetValue ( value , out uint enumValue ) )
36
+ if ( enumValues . Count == 0 )
37
+ {
38
+ for ( uint index = 0 ; index < enumDictionarySize ; index ++ )
39
+ {
40
+ var enumValueName = NativeMethods . LogicalType . DuckDBEnumDictionaryValue ( logicalType , index ) . ToManagedString ( ) ;
41
+ enumValues . Add ( enumValueName , index ) ;
42
+ }
43
+ }
44
+
45
+ if ( enumValues . TryGetValue ( value , out var enumValue ) )
46
46
{
47
47
// The following casts to byte and ushort are safe because we ensure in the constructor that the value enumDictionarySize is not too high.
48
48
return enumType switch
@@ -59,7 +59,7 @@ internal override bool AppendString(string value, int rowIndex)
59
59
60
60
internal override bool AppendEnum < TEnum > ( TEnum value , int rowIndex )
61
61
{
62
- ulong enumValue = ConvertEnumValueToUInt64 ( value ) ;
62
+ var enumValue = ConvertEnumValueToUInt64 ( value ) ;
63
63
if ( enumValue < enumDictionarySize )
64
64
{
65
65
// The following casts to byte, ushort and uint are safe because we ensure in the constructor that the value enumDictionarySize is not too high.
@@ -72,12 +72,12 @@ internal override bool AppendEnum<TEnum>(TEnum value, int rowIndex)
72
72
} ;
73
73
}
74
74
75
- throw new InvalidOperationException ( $ "Failed to write Enum column because the value is outside the range (0-{ enumDictionarySize - 1 } ).") ;
75
+ throw new InvalidOperationException ( $ "Failed to write Enum column because the value is outside the range (0-{ enumDictionarySize - 1 } ).") ;
76
76
}
77
77
78
78
private static ulong ConvertEnumValueToUInt64 < TEnum > ( TEnum value ) where TEnum : Enum
79
79
{
80
- return Convert . GetTypeCode ( value ) switch
80
+ return value . GetTypeCode ( ) switch
81
81
{
82
82
TypeCode . SByte => ( ulong ) Convert . ToSByte ( value ) ,
83
83
TypeCode . Byte => Convert . ToByte ( value ) ,
@@ -90,4 +90,10 @@ private static ulong ConvertEnumValueToUInt64<TEnum>(TEnum value) where TEnum :
90
90
_ => throw new InvalidOperationException ( $ "Failed to convert the enum value { value } to ulong.") ,
91
91
} ;
92
92
}
93
+
94
+ public override void Dispose ( )
95
+ {
96
+ logicalType . Dispose ( ) ;
97
+ base . Dispose ( ) ;
98
+ }
93
99
}
0 commit comments