Skip to content

Commit

Permalink
Merge pull request #433 from ClickHouse/infer-outer-reflection
Browse files Browse the repository at this point in the history
fix: infer Nullable/Array/LowCardinality with reflection
  • Loading branch information
ernado authored Oct 21, 2024
2 parents 73fa62f + 7719a44 commit 0ae6dfb
Show file tree
Hide file tree
Showing 39 changed files with 88 additions and 153 deletions.
4 changes: 0 additions & 4 deletions proto/cmd/ch-gen-col/infer.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ package proto
func inferGenerated(t ColumnType) Column {
switch t {
{{- range . }}
case ColumnTypeArray.Sub({{ .ColumnType }}):
return new({{ .Type }}).Array()
case ColumnTypeNullable.Sub({{ .ColumnType }}):
return new({{ .Type }}).Nullable()
case {{ .ColumnType }}:
return new({{ .Type }})
{{- end }}
Expand Down
2 changes: 1 addition & 1 deletion proto/cmd/ch-gen-col/main.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (c *{{ .Type }}) AppendArr(vs []{{ .ElemType }}) {
*c = append(*c, vs...)
}

// LowCardinality returns LowCardinality for {{ .Name }} .
// LowCardinality returns LowCardinality for {{ .Name }}.
func (c *{{ .Type }}) LowCardinality() *ColLowCardinality[{{ .ElemType }}] {
return &ColLowCardinality[{{ .ElemType }}]{
index: c,
Expand Down
59 changes: 43 additions & 16 deletions proto/col_auto.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package proto

import (
"reflect"
"strconv"
"strings"

Expand Down Expand Up @@ -37,20 +38,8 @@ func (c *ColAuto) Infer(t ColumnType) error {
switch t {
case ColumnTypeNothing:
c.Data = new(ColNothing)
case ColumnTypeNullable.Sub(ColumnTypeNothing):
c.Data = new(ColNothing).Nullable()
case ColumnTypeArray.Sub(ColumnTypeNothing):
c.Data = new(ColNothing).Array()
case ColumnTypeString:
c.Data = new(ColStr)
case ColumnTypeArray.Sub(ColumnTypeString):
c.Data = new(ColStr).Array()
case ColumnTypeNullable.Sub(ColumnTypeString):
c.Data = new(ColStr).Nullable()
case ColumnTypeLowCardinality.Sub(ColumnTypeString):
c.Data = new(ColStr).LowCardinality()
case ColumnTypeArray.Sub(ColumnTypeLowCardinality.Sub(ColumnTypeString)):
c.Data = new(ColStr).LowCardinality().Array()
case ColumnTypeBool:
c.Data = new(ColBool)
case ColumnTypeDateTime:
Expand All @@ -61,12 +50,50 @@ func (c *ColAuto) Infer(t ColumnType) error {
c.Data = NewMap[string, string](new(ColStr), new(ColStr))
case ColumnTypeUUID:
c.Data = new(ColUUID)
case ColumnTypeArray.Sub(ColumnTypeUUID):
c.Data = new(ColUUID).Array()
case ColumnTypeNullable.Sub(ColumnTypeUUID):
c.Data = new(ColUUID).Nullable()
default:
switch t.Base() {
case ColumnTypeArray:
inner := new(ColAuto)
if err := inner.Infer(t.Elem()); err != nil {
return errors.Wrap(err, "array")
}
innerValue := reflect.ValueOf(inner.Data)
arrayMethod := innerValue.MethodByName("Array")
if arrayMethod.IsValid() && arrayMethod.Type().NumOut() == 1 {
if col, ok := arrayMethod.Call(nil)[0].Interface().(Column); ok {
c.Data = col
c.DataType = t
return nil
}
}
case ColumnTypeNullable:
inner := new(ColAuto)
if err := inner.Infer(t.Elem()); err != nil {
return errors.Wrap(err, "nullable")
}
innerValue := reflect.ValueOf(inner.Data)
nullableMethod := innerValue.MethodByName("Nullable")
if nullableMethod.IsValid() && nullableMethod.Type().NumOut() == 1 {
if col, ok := nullableMethod.Call(nil)[0].Interface().(Column); ok {
c.Data = col
c.DataType = t
return nil
}
}
case ColumnTypeLowCardinality:
inner := new(ColAuto)
if err := inner.Infer(t.Elem()); err != nil {
return errors.Wrap(err, "low cardinality")
}
innerValue := reflect.ValueOf(inner.Data)
lowCardinalityMethod := innerValue.MethodByName("LowCardinality")
if lowCardinalityMethod.IsValid() && lowCardinalityMethod.Type().NumOut() == 1 {
if col, ok := lowCardinalityMethod.Call(nil)[0].Interface().(Column); ok {
c.Data = col
c.DataType = t
return nil
}
}
case ColumnTypeDateTime:
v := new(ColDateTime)
if err := v.Infer(t); err != nil {
Expand Down
100 changes: 0 additions & 100 deletions proto/col_auto_gen.go

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

2 changes: 2 additions & 0 deletions proto/col_auto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ func TestColAuto_Infer(t *testing.T) {
"Decimal64(2)",
"Decimal128(3)",
"Decimal256(4)",
"Array(Nullable(Int8))",
"Nullable(DateTime64(3))",
} {
r := AutoResult("foo")
require.NoError(t, r.Data.(Inferable).Infer(columnType))
Expand Down
2 changes: 1 addition & 1 deletion proto/col_date.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (c ColDate) Row(i int) time.Time {
return c[i].Time()
}

// LowCardinality returns LowCardinality for Enum8 .
// LowCardinality returns LowCardinality for Enum8.
func (c *ColDate) LowCardinality() *ColLowCardinality[time.Time] {
return &ColLowCardinality[time.Time]{
index: c,
Expand Down
2 changes: 1 addition & 1 deletion proto/col_date32.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (c ColDate32) Row(i int) time.Time {
return c[i].Time()
}

// LowCardinality returns LowCardinality for Enum8 .
// LowCardinality returns LowCardinality for Enum8.
func (c *ColDate32) LowCardinality() *ColLowCardinality[time.Time] {
return &ColLowCardinality[time.Time]{
index: c,
Expand Down
2 changes: 1 addition & 1 deletion proto/col_datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (c *ColDateTime) AppendArr(vs []time.Time) {
c.Data = append(c.Data, dates...)
}

// LowCardinality returns LowCardinality for Enum8 .
// LowCardinality returns LowCardinality for Enum8.
func (c *ColDateTime) LowCardinality() *ColLowCardinality[time.Time] {
return &ColLowCardinality[time.Time]{
index: c,
Expand Down
4 changes: 4 additions & 0 deletions proto/col_datetime64.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ func (c ColDateTime64) Raw() *ColDateTime64Raw {
return &ColDateTime64Raw{ColDateTime64: c}
}

func (c *ColDateTime64) Nullable() *ColNullable[time.Time] {
return &ColNullable[time.Time]{Values: c}
}

func (c *ColDateTime64) Array() *ColArr[time.Time] {
return &ColArr[time.Time]{Data: c}
}
Expand Down
2 changes: 1 addition & 1 deletion proto/col_decimal128_gen.go

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

2 changes: 1 addition & 1 deletion proto/col_decimal256_gen.go

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

2 changes: 1 addition & 1 deletion proto/col_decimal32_gen.go

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

2 changes: 1 addition & 1 deletion proto/col_decimal64_gen.go

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

2 changes: 1 addition & 1 deletion proto/col_enum16_gen.go

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

2 changes: 1 addition & 1 deletion proto/col_enum8_gen.go

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

2 changes: 1 addition & 1 deletion proto/col_fixedstr128_gen.go

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

2 changes: 1 addition & 1 deletion proto/col_fixedstr16_gen.go

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

2 changes: 1 addition & 1 deletion proto/col_fixedstr256_gen.go

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

2 changes: 1 addition & 1 deletion proto/col_fixedstr32_gen.go

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

Loading

0 comments on commit 0ae6dfb

Please sign in to comment.