-
-
Notifications
You must be signed in to change notification settings - Fork 37
Open
Description
I want to insert structures with arbitrary fields which implement driver.Valuer interface.
Take a look to the following code:
package main
import (
"context"
"database/sql"
"database/sql/driver"
"fmt"
"reflect"
"github.com/uptrace/bun/extra/bunbig"
"github.com/uptrace/go-clickhouse/ch"
)
type Address [34]byte
func (x *Address) Value() (driver.Value, error) {
if x == nil {
return nil, nil
}
return x[:], nil
}
func (x *Address) Scan(value interface{}) error {
var i sql.NullString
if err := i.Scan(value); err != nil {
return err
}
if !i.Valid {
return fmt.Errorf("error converting type %T into address", value)
}
if l := len(i.String); l != 34 {
return fmt.Errorf("wrong address length %d", l)
}
copy(x[0:34], i.String)
return nil
}
type ProblemStruct struct {
Addr Address `ch:"type:String"`
OptionalAddr *Address `ch:"type:Nullable(String)"`
OptionalAddrNull *Address `ch:"type:Nullable(String)"`
Balance bunbig.Int `ch:"type:UInt64"`
OptionalBalance *bunbig.Int `ch:"type:Nullable(UInt64)"`
OptionalBalanceNull *bunbig.Int `ch:"type:Nullable(UInt64)"`
}
func main() {
var v = ProblemStruct{
Addr: Address{0x41},
OptionalAddr: &Address{0x44},
Balance: *bunbig.FromInt64(10),
OptionalBalance: bunbig.FromInt64(10),
}
dsnCH := "clickhouse://localhost:9000/default?sslmode=disable"
chDB := ch.Connect(
ch.WithDSN(dsnCH), ch.WithAutoCreateDatabase(true), ch.WithPoolSize(16))
_, err := chDB.NewDropTable().
Model(new(ProblemStruct)).
IfExists().
Exec(context.Background())
if err != nil {
panic(err)
}
_, err = chDB.NewCreateTable().
Model(new(ProblemStruct)).
IfNotExists().
Engine("ReplacingMergeTree").
Exec(context.Background())
if err != nil {
panic(err)
}
_, err = chDB.NewInsert().Model(&v).Exec(context.Background())
if err != nil {
panic(err)
}
var got ProblemStruct
err = chDB.NewSelect().Model(&got).Scan(context.Background())
if err != nil {
panic(err)
}
if !reflect.DeepEqual(v, got) {
fmt.Printf("expected: %+v", v)
fmt.Printf("got: %+v", v)
panic(nil)
}
}What I expect to see while executing this program is no panic and this in a database:
SELECT *
FROM problem_structs
┌─addr─┬─optional_addr─┬─optional_addr_null─┬─balance─┬─optional_balance─┬─optional_balance_null─┐
│ A │ D │ ᴺᵁᴸᴸ │ 10 │ 10 │ ᴺᵁᴸᴸ │
└──────┴───────────────┴────────────────────┴─────────┴──────────────────┴───────────────────────┘
But instead I got this error panic: reflect: call of reflect.Value.Uint on struct Value on go-clickhouse/ch/chschema/column_gen.go:1399 while trying to insert a row.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels