-
Notifications
You must be signed in to change notification settings - Fork 1
/
typeconv.go
124 lines (115 loc) · 4.02 KB
/
typeconv.go
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
119
120
121
122
123
124
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
package typeconv
import (
"fmt"
"time"
"github.com/cockroachdb/apd/v3"
"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
"github.com/cockroachdb/cockroachdb-parser/pkg/util/duration"
"github.com/cockroachdb/cockroachdb-parser/pkg/util/json"
)
// DatumVecCanonicalTypeFamily is the "canonical" type family of all types that
// are physically represented by coldata.DatumVec.
var DatumVecCanonicalTypeFamily = types.Family(1000000)
// TypeFamilyToCanonicalTypeFamily converts all type families to their
// "canonical" counterparts. "Canonical" type families are representatives
// from a set of "equivalent" type families where "equivalence" means having
// the same physical representation.
//
// All type families that do not have an optimized physical representation are
// handled by using tree.Datums, and such types are mapped to
// DatumVecCanonicalTypeFamily.
func TypeFamilyToCanonicalTypeFamily(family types.Family) types.Family {
switch family {
case types.BoolFamily:
return types.BoolFamily
case types.BytesFamily, types.StringFamily, types.UuidFamily, types.EncodedKeyFamily, types.EnumFamily:
// Note that by using Bytes family as the canonical one for other type
// families we allow the execution engine to evaluate invalid operations
// (e.g. the concat binary operation between a UUID and an enum "has"
// the execution engine support). However, it's not a big deal since the
// type-checking for validity of operations is done before the query
// reaches the execution engine.
return types.BytesFamily
case types.DecimalFamily:
return types.DecimalFamily
case types.JsonFamily:
return types.JsonFamily
case types.IntFamily, types.DateFamily:
return types.IntFamily
case types.FloatFamily:
return types.FloatFamily
case types.TimestampTZFamily, types.TimestampFamily:
return types.TimestampTZFamily
case types.IntervalFamily:
return types.IntervalFamily
default:
// TODO(yuzefovich): consider adding native support for
// types.UnknownFamily.
return DatumVecCanonicalTypeFamily
}
}
// ToCanonicalTypeFamilies converts typs to the corresponding canonical type
// families.
func ToCanonicalTypeFamilies(typs []*types.T) []types.Family {
families := make([]types.Family, len(typs))
for i := range typs {
families[i] = TypeFamilyToCanonicalTypeFamily(typs[i].Family())
}
return families
}
// UnsafeFromGoType returns the type for a Go value, if applicable. Shouldn't
// be used at runtime. This method is unsafe because multiple logical types can
// be represented by the same physical type. Types that are backed by DatumVec
// are *not* supported by this function.
func UnsafeFromGoType(v interface{}) *types.T {
switch t := v.(type) {
case int16:
return types.Int2
case int32:
return types.Int4
case int, int64:
return types.Int
case bool:
return types.Bool
case float64:
return types.Float
case []byte:
return types.Bytes
case string:
return types.String
case apd.Decimal:
return types.Decimal
case time.Time:
return types.TimestampTZ
case duration.Duration:
return types.Interval
case json.JSON:
return types.Jsonb
default:
panic(fmt.Sprintf("type %s not supported yet", t))
}
}
// TypesSupportedNatively contains types that are supported natively by the
// vectorized engine.
var TypesSupportedNatively []*types.T
func init() {
for _, t := range types.Scalar {
if TypeFamilyToCanonicalTypeFamily(t.Family()) == DatumVecCanonicalTypeFamily {
continue
}
if t.Family() == types.IntFamily {
TypesSupportedNatively = append(TypesSupportedNatively, types.Int2)
TypesSupportedNatively = append(TypesSupportedNatively, types.Int4)
}
TypesSupportedNatively = append(TypesSupportedNatively, t)
}
}