@@ -2,6 +2,7 @@ package proto
2
2
3
3
import (
4
4
"fmt"
5
+ "strconv"
5
6
"strings"
6
7
7
8
"github.com/go-faster/errors"
@@ -83,30 +84,58 @@ func (c ColumnType) Base() ColumnType {
83
84
return c [:start ]
84
85
}
85
86
87
+ // reduces Decimal(P, ...) to Decimal32/Decimal64/Decimal128/Decimal256
88
+ // returns c if any errors occur during conversion
89
+ func (c ColumnType ) decimalDowncast () ColumnType {
90
+ if c .Base () != ColumnTypeDecimal {
91
+ return c
92
+ }
93
+ elem := c .Elem ()
94
+ precStr , _ , _ := strings .Cut (string (elem ), "," )
95
+ precStr = strings .TrimSpace (precStr )
96
+ prec , err := strconv .Atoi (precStr )
97
+ if err != nil {
98
+ return c
99
+ }
100
+ switch {
101
+ case prec < 10 :
102
+ return ColumnTypeDecimal32
103
+ case prec < 19 :
104
+ return ColumnTypeDecimal64
105
+ case prec < 39 :
106
+ return ColumnTypeDecimal128
107
+ case prec < 77 :
108
+ return ColumnTypeDecimal256
109
+ default :
110
+ return c
111
+ }
112
+ }
113
+
86
114
// Conflicts reports whether two types conflict.
87
115
func (c ColumnType ) Conflicts (b ColumnType ) bool {
88
116
if c == b {
89
117
return false
90
118
}
91
- {
92
- a := c
93
- if b .Base () == ColumnTypeEnum8 || b .Base () == ColumnTypeEnum16 {
94
- a , b = b , a
95
- }
96
- switch {
97
- case a .Base () == ColumnTypeEnum8 && b == ColumnTypeInt8 :
98
- return false
99
- case a .Base () == ColumnTypeEnum16 && b == ColumnTypeInt16 :
100
- return false
101
- }
119
+ cBase := c .Base ()
120
+ bBase := b .Base ()
121
+ if (cBase == ColumnTypeEnum8 && b == ColumnTypeInt8 ) ||
122
+ (cBase == ColumnTypeEnum16 && b == ColumnTypeInt16 ) ||
123
+ (bBase == ColumnTypeEnum8 && c == ColumnTypeInt8 ) ||
124
+ (bBase == ColumnTypeEnum16 && c == ColumnTypeInt16 ) {
125
+ return false
126
+ }
127
+ if cBase == ColumnTypeDecimal || bBase == ColumnTypeDecimal {
128
+ return c .decimalDowncast () != b .decimalDowncast ()
102
129
}
103
- if c . Base () != b . Base () {
130
+ if cBase != bBase {
104
131
return true
105
132
}
106
133
if c .normalizeCommas () == b .normalizeCommas () {
107
134
return false
108
135
}
109
- switch c .Base () {
136
+ switch cBase {
137
+ case ColumnTypeArray , ColumnTypeNullable , ColumnTypeLowCardinality :
138
+ return c .Elem ().Conflicts (b .Elem ())
110
139
case ColumnTypeDateTime , ColumnTypeDateTime64 :
111
140
// TODO(ernado): improve check
112
141
return false
0 commit comments