aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/ClickHouse/ch-go/proto/col_auto.go
blob: d2b0b61233187d3bdf06e818ee9aa6bcc2982812 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package proto

import (
	"strings"

	"github.com/go-faster/errors"
)

// ColAuto is column that is initialized during decoding.
type ColAuto struct {
	Data     Column
	DataType ColumnType
}

// Infer and initialize Column from ColumnType.
func (c *ColAuto) Infer(t ColumnType) error {
	if c.Data != nil && !c.Type().Conflicts(t) {
		// Already ok.
		c.DataType = t // update subtype if needed
		return nil
	}
	if v := inferGenerated(t); v != nil {
		c.Data = v
		c.DataType = t
		return nil
	}
	if strings.HasPrefix(t.String(), ColumnTypeInterval.String()) {
		v := new(ColInterval)
		if err := v.Infer(t); err != nil {
			return errors.Wrap(err, "interval")
		}
		c.Data = v
		c.DataType = t
		return nil
	}
	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:
		c.Data = new(ColDateTime)
	case ColumnTypeDate:
		c.Data = new(ColDate)
	case "Map(String,String)":
		c.Data = NewMap[string, string](new(ColStr), new(ColStr))
	default:
		switch t.Base() {
		case ColumnTypeDateTime:
			v := new(ColDateTime)
			if err := v.Infer(t); err != nil {
				return errors.Wrap(err, "datetime")
			}
			c.Data = v
			c.DataType = t
			return nil
		case ColumnTypeEnum8, ColumnTypeEnum16:
			v := new(ColEnum)
			if err := v.Infer(t); err != nil {
				return errors.Wrap(err, "enum")
			}
			c.Data = v
			c.DataType = t
			return nil
		case ColumnTypeDateTime64:
			v := new(ColDateTime64)
			if err := v.Infer(t); err != nil {
				return errors.Wrap(err, "datetime64")
			}
			c.Data = v
			c.DataType = t
			return nil
		}
		return errors.Errorf("automatic column inference not supported for %q", t)
	}

	c.DataType = t
	return nil
}

var (
	_ Column    = &ColAuto{}
	_ Inferable = &ColAuto{}
)

func (c ColAuto) Type() ColumnType {
	return c.DataType
}

func (c ColAuto) Rows() int {
	return c.Data.Rows()
}

func (c ColAuto) DecodeColumn(r *Reader, rows int) error {
	return c.Data.DecodeColumn(r, rows)
}

func (c ColAuto) Reset() {
	c.Data.Reset()
}

func (c ColAuto) EncodeColumn(b *Buffer) {
	c.Data.EncodeColumn(b)
}