diff --git a/rows.go b/rows.go index 6aa09bd6..4f03bd6d 100644 --- a/rows.go +++ b/rows.go @@ -4,10 +4,8 @@ import ( "database/sql/driver" "fmt" "io" - "math/big" "reflect" "strings" - "time" "github.com/marcboeker/go-duckdb/mapping" ) @@ -91,7 +89,7 @@ func (r *rows) ColumnTypeScanType(index int) reflect.Type { alias := mapping.LogicalTypeGetAlias(logicalType) if alias == aliasJSON { - return reflect.TypeFor[any]() + return reflectTypeAny } t := mapping.ColumnType(&r.res, mapping.IdxT(index)) @@ -99,51 +97,51 @@ func (r *rows) ColumnTypeScanType(index int) reflect.Type { case TYPE_INVALID: return nil case TYPE_BOOLEAN: - return reflect.TypeOf(true) + return reflectTypeBool case TYPE_TINYINT: - return reflect.TypeOf(int8(0)) + return reflectTypeInt8 case TYPE_SMALLINT: - return reflect.TypeOf(int16(0)) + return reflectTypeInt16 case TYPE_INTEGER: - return reflect.TypeOf(int32(0)) + return reflectTypeInt32 case TYPE_BIGINT: - return reflect.TypeOf(int64(0)) + return reflectTypeInt64 case TYPE_UTINYINT: - return reflect.TypeOf(uint8(0)) + return reflectTypeUint8 case TYPE_USMALLINT: - return reflect.TypeOf(uint16(0)) + return reflectTypeUint16 case TYPE_UINTEGER: - return reflect.TypeOf(uint32(0)) + return reflectTypeUint32 case TYPE_UBIGINT: - return reflect.TypeOf(uint64(0)) + return reflectTypeUint64 case TYPE_FLOAT: - return reflect.TypeOf(float32(0)) + return reflectTypeFloat32 case TYPE_DOUBLE: - return reflect.TypeOf(float64(0)) + return reflectTypeFloat64 case TYPE_TIMESTAMP, TYPE_TIMESTAMP_S, TYPE_TIMESTAMP_MS, TYPE_TIMESTAMP_NS, TYPE_DATE, TYPE_TIME, TYPE_TIME_TZ, TYPE_TIMESTAMP_TZ: - return reflect.TypeOf(time.Time{}) + return reflectTypeTime case TYPE_INTERVAL: - return reflect.TypeOf(Interval{}) + return reflectTypeInterval case TYPE_HUGEINT: - return reflect.TypeOf(big.NewInt(0)) + return reflectTypeBigInt case TYPE_VARCHAR, TYPE_ENUM: - return reflect.TypeOf("") + return reflectTypeString case TYPE_BLOB: - return reflect.TypeOf([]byte{}) + return reflectTypeBytes case TYPE_DECIMAL: - return reflect.TypeOf(Decimal{}) + return reflectTypeDecimal case TYPE_LIST: - return reflect.TypeOf([]any{}) + return reflectTypeSliceAny case TYPE_STRUCT: - return reflect.TypeOf(map[string]any{}) + return reflectTypeMapString case TYPE_MAP: - return reflect.TypeOf(Map{}) + return reflectTypeMap case TYPE_ARRAY: - return reflect.TypeOf([]any{}) + return reflectTypeSliceAny case TYPE_UNION: - return reflect.TypeOf(Union{}) + return reflectTypeUnion case TYPE_UUID: - return reflect.TypeOf([]byte{}) + return reflectTypeBytes default: return nil } diff --git a/types.go b/types.go index 7c84c805..b41f912e 100644 --- a/types.go +++ b/types.go @@ -16,6 +16,32 @@ import ( "github.com/marcboeker/go-duckdb/mapping" ) +// Precomputed reflect type values to avoid repeated allocations. +var ( + reflectTypeBool = reflect.TypeOf(true) + reflectTypeInt8 = reflect.TypeOf(int8(0)) + reflectTypeInt16 = reflect.TypeOf(int16(0)) + reflectTypeInt32 = reflect.TypeOf(int32(0)) + reflectTypeInt64 = reflect.TypeOf(int64(0)) + reflectTypeUint8 = reflect.TypeOf(uint8(0)) + reflectTypeUint16 = reflect.TypeOf(uint16(0)) + reflectTypeUint32 = reflect.TypeOf(uint32(0)) + reflectTypeUint64 = reflect.TypeOf(uint64(0)) + reflectTypeFloat32 = reflect.TypeOf(float32(0)) + reflectTypeFloat64 = reflect.TypeOf(float64(0)) + reflectTypeTime = reflect.TypeOf(time.Time{}) + reflectTypeInterval = reflect.TypeOf(Interval{}) + reflectTypeBigInt = reflect.TypeOf(big.NewInt(0)) + reflectTypeString = reflect.TypeOf("") + reflectTypeBytes = reflect.TypeOf([]byte{}) + reflectTypeDecimal = reflect.TypeOf(Decimal{}) + reflectTypeSliceAny = reflect.TypeOf([]any{}) + reflectTypeMapString = reflect.TypeOf(map[string]any{}) + reflectTypeMap = reflect.TypeOf(Map{}) + reflectTypeUnion = reflect.TypeOf(Union{}) + reflectTypeAny = reflect.TypeFor[any]() +) + type numericType interface { int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64 }