Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sql.Valuer support for all types #1144

Merged
merged 21 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contributors/list
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ Chao Wang <chaowang@uber.com>
Chris Duncan <veqryn@hotmail.com>
Daguang <28806852+DGuang21@users.noreply.github.com>
Dale McDiarmid <dale@clickhouse.com>
Dale Mcdiarmid <dale@clickhouse.com>
Damir Sayfutdinov <sayfutdinov@selectel.ru>
Dan Walters <dan@walters.io>
Daniel Bershatsky <daniel.bershatsky@skolkovotech.ru>
Danila Migalin <miga@uber.com>
Danny.Dunn <danny@DannyDunndeMBP.lan>
Darío <dgrripoll@gmail.com>
Dave Josephsen <dave.josephsen@gmail.com>
Dean Karn <dean.karn@gmail.com>
Denis Gukov <denguk@gmail.com>
Denis Krivak <dokrivak@avito.ru>
Denys <drimd@ukr.net>
Expand Down
20 changes: 15 additions & 5 deletions lib/column/array.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,23 @@ func appendNullableRowPlain[T any](col *Array, arr []*T) error {

func (col *Array) append(elem reflect.Value, level int) error {
if level < col.depth {
col.appendOffset(level, uint64(elem.Len()))
for i := 0; i < elem.Len(); i++ {
if err := col.append(elem.Index(i), level+1); err != nil {
return err
switch elem.Kind() {
// reflect.Value.Len() & reflect.Value.Index() is called in `append` method which is only valid for
// Slice, Array and String that make sense here.
case reflect.Slice, reflect.Array, reflect.String:
col.appendOffset(level, uint64(elem.Len()))
for i := 0; i < elem.Len(); i++ {
if err := col.append(elem.Index(i), level+1); err != nil {
return err
}
}
return nil
}
return &ColumnConverterError{
Op: "AppendRow",
To: "Array",
From: fmt.Sprintf("%T", elem),
}
return nil
jkaflik marked this conversation as resolved.
Show resolved Hide resolved
}
if elem.Kind() == reflect.Ptr && elem.IsNil() {
return col.values.AppendRow(nil)
Expand Down
14 changes: 14 additions & 0 deletions lib/column/array_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions lib/column/bigint.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package column

import (
"database/sql/driver"
"encoding/binary"
"fmt"
"github.com/ClickHouse/ch-go/proto"
Expand Down Expand Up @@ -97,6 +98,18 @@ func (col *BigInt) Append(v any) (nulls []uint8, err error) {
}
}
default:
if valuer, ok := v.(driver.Valuer); ok {
val, err := valuer.Value()
if err != nil {
return nil, &ColumnConverterError{
Op: "Append",
To: string(col.chType),
From: fmt.Sprintf("%T", v),
Hint: "could not get driver.Valuer value",
}
}
return col.Append(val)
}
return nil, &ColumnConverterError{
Op: "Append",
To: string(col.chType),
Expand All @@ -120,6 +133,18 @@ func (col *BigInt) AppendRow(v any) error {
case nil:
col.append(big.NewInt(0))
default:
if valuer, ok := v.(driver.Valuer); ok {
val, err := valuer.Value()
if err != nil {
return &ColumnConverterError{
Op: "AppendRow",
To: string(col.chType),
From: fmt.Sprintf("%T", v),
Hint: "could not get driver.Valuer value",
}
}
return col.AppendRow(val)
}
return &ColumnConverterError{
Op: "AppendRow",
To: string(col.chType),
Expand Down
25 changes: 25 additions & 0 deletions lib/column/bool.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package column

import (
"database/sql"
"database/sql/driver"
"fmt"
"github.com/ClickHouse/ch-go/proto"
"reflect"
Expand Down Expand Up @@ -110,6 +111,18 @@ func (col *Bool) Append(v any) (nulls []uint8, err error) {
col.Append(v[i])
}
default:
if valuer, ok := v.(driver.Valuer); ok {
val, err := valuer.Value()
if err != nil {
return nil, &ColumnConverterError{
Op: "Append",
To: "Bool",
From: fmt.Sprintf("%T", v),
Hint: "could not get driver.Valuer value",
}
}
return col.Append(val)
}
return nil, &ColumnConverterError{
Op: "Append",
To: "Bool",
Expand Down Expand Up @@ -140,6 +153,18 @@ func (col *Bool) AppendRow(v any) error {
}
case nil:
default:
if valuer, ok := v.(driver.Valuer); ok {
val, err := valuer.Value()
if err != nil {
return &ColumnConverterError{
Op: "AppendRow",
To: "Bool",
From: fmt.Sprintf("%T", v),
Hint: "could not get driver.Valuer value",
}
}
return col.AppendRow(val)
}
return &ColumnConverterError{
Op: "AppendRow",
To: "Bool",
Expand Down
14 changes: 14 additions & 0 deletions lib/column/codegen/array.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package column

import (
"database/sql"
"database/sql/driver"
"github.com/ClickHouse/ch-go/proto"
"github.com/google/uuid"
"github.com/paulmach/orb"
Expand All @@ -30,6 +31,7 @@ import (
"net"
"net/netip"
"time"
"fmt"
)

// appendRowPlain is a reflection-free realisation of append for plain arrays.
Expand All @@ -42,6 +44,18 @@ func (col *Array) appendRowPlain(v any) error {
return appendNullableRowPlain(col, tv)
{{- end }}
default:
if valuer, ok := v.(driver.Valuer); ok {
val, err := valuer.Value()
if err != nil {
return &ColumnConverterError{
Op: "AppendRow",
To: "Array",
From: fmt.Sprintf("%T", v),
Hint: "could not get driver.Valuer value",
}
}
return col.appendRowPlain(val)
}
return col.appendRowDefault(v)
}
}
29 changes: 29 additions & 0 deletions lib/column/codegen/column.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/paulmach/orb"
"github.com/shopspring/decimal"
"database/sql"
"database/sql/driver"
"github.com/ClickHouse/ch-go/proto"
)

Expand Down Expand Up @@ -315,6 +316,20 @@ func (col *{{ .ChType }}) Append(v any) (nulls []uint8,err error) {
}
{{- end }}
default:

if valuer, ok := v.(driver.Valuer); ok {
val, err := valuer.Value()
if err != nil {
return nil, &ColumnConverterError{
Op: "Append",
To: "{{ .ChType }}",
From: fmt.Sprintf("%T", v),
Hint: "could not get driver.Valuer value",
}
}
return col.Append(val)
}

return nil, &ColumnConverterError{
Op: "Append",
To: "{{ .ChType }}",
Expand Down Expand Up @@ -382,6 +397,20 @@ func (col *{{ .ChType }}) AppendRow(v any) error {
col.col.Append(val)
{{- end }}
default:

if valuer, ok := v.(driver.Valuer); ok {
val, err := valuer.Value()
if err != nil {
return &ColumnConverterError{
Op: "AppendRow",
To: "{{ .ChType }}",
From: fmt.Sprintf("%T", v),
Hint: "could not get driver.Valuer value",
}
}
return col.AppendRow(val)
}

if rv := reflect.ValueOf(v); rv.Kind() == col.ScanType().Kind() || rv.CanConvert(col.ScanType()) {
col.col.Append(rv.Convert(col.ScanType()).Interface().({{ .GoType }}))
} else {
Expand Down
Loading
Loading