go-hep.org/x/hep@v0.38.1/groot/rsql/rsqldrv/types.go (about) 1 // Copyright ©2019 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package rsqldrv // import "go-hep.org/x/hep/groot/rsql/rsqldrv" 6 7 import ( 8 "fmt" 9 "math" 10 "reflect" 11 12 "go-hep.org/x/hep/groot/rtree" 13 ) 14 15 type ( 16 idealFloat float64 17 idealInt int64 18 idealUint uint64 19 ) 20 21 func coerce(a, b any) (x, y any) { 22 if reflect.TypeOf(a) == reflect.TypeOf(b) { 23 return a, b 24 } 25 26 switch a.(type) { 27 case idealFloat, idealInt, idealUint: 28 switch b.(type) { 29 case idealFloat, idealInt, idealUint: 30 x, y = coerce1(a, b), b 31 if reflect.TypeOf(x) == reflect.TypeOf(y) { 32 return 33 } 34 35 return a, coerce1(b, a) 36 default: 37 return coerce1(a, b), b 38 } 39 default: 40 switch b.(type) { 41 case idealFloat, idealInt, idealUint: 42 return a, coerce1(b, a) 43 default: 44 return a, b 45 } 46 } 47 } 48 49 func coerce1(inVal, otherVal any) (coercedInVal any) { 50 coercedInVal = inVal 51 if otherVal == nil { 52 return 53 } 54 55 switch x := inVal.(type) { 56 case nil: 57 return 58 case idealFloat: 59 switch otherVal.(type) { 60 case idealFloat: 61 return idealFloat(float64(x)) 62 //case idealInt: 63 //case idealRune: 64 //case idealUint: 65 //case bool: 66 case float32: 67 return float32(float64(x)) 68 case float64: 69 return float64(x) 70 //case int8: 71 //case int16: 72 //case int32: 73 //case int64: 74 //case string: 75 //case uint8: 76 //case uint16: 77 //case uint32: 78 //case uint64: 79 } 80 case idealInt: 81 switch otherVal.(type) { 82 case idealFloat: 83 return idealFloat(int64(x)) 84 case idealInt: 85 return idealInt(int64(x)) 86 //case idealRune: 87 case idealUint: 88 if x >= 0 { 89 return idealUint(int64(x)) 90 } 91 //case bool: 92 case float32: 93 return float32(int64(x)) 94 case float64: 95 return float64(int64(x)) 96 case int8: 97 if x >= math.MinInt8 && x <= math.MaxInt8 { 98 return int8(int64(x)) 99 } 100 case int16: 101 if x >= math.MinInt16 && x <= math.MaxInt16 { 102 return int16(int64(x)) 103 } 104 case int32: 105 if x >= math.MinInt32 && x <= math.MaxInt32 { 106 return int32(int64(x)) 107 } 108 case int64: 109 return int64(x) 110 //case string: 111 case uint8: 112 if x >= 0 && x <= math.MaxUint8 { 113 return uint8(int64(x)) 114 } 115 case uint16: 116 if x >= 0 && x <= math.MaxUint16 { 117 return uint16(int64(x)) 118 } 119 case uint32: 120 if x >= 0 && x <= math.MaxUint32 { 121 return uint32(int64(x)) 122 } 123 case uint64: 124 if x >= 0 { 125 return uint64(int64(x)) 126 } 127 } 128 case idealUint: 129 switch otherVal.(type) { 130 case idealFloat: 131 return idealFloat(uint64(x)) 132 case idealInt: 133 if x <= math.MaxInt64 { 134 return idealInt(int64(x)) 135 } 136 //case idealRune: 137 case idealUint: 138 return idealUint(uint64(x)) 139 //case bool: 140 case float32: 141 return float32(uint64(x)) 142 case float64: 143 return float64(uint64(x)) 144 case int8: 145 if x <= math.MaxInt8 { 146 return int8(int64(x)) 147 } 148 case int16: 149 if x <= math.MaxInt16 { 150 return int16(int64(x)) 151 } 152 case int32: 153 if x <= math.MaxInt32 { 154 return int32(int64(x)) 155 } 156 case int64: 157 if x <= math.MaxInt64 { 158 return int64(x) 159 } 160 //case string: 161 case uint8: 162 if x <= math.MaxUint8 { 163 return uint8(int64(x)) 164 } 165 case uint16: 166 if x <= math.MaxUint16 { 167 return uint16(int64(x)) 168 } 169 case uint32: 170 if x <= math.MaxUint32 { 171 return uint32(int64(x)) 172 } 173 case uint64: 174 return uint64(x) 175 } 176 } 177 return 178 } 179 180 func colDescrFromLeaf(leaf rtree.Leaf) colDescr { 181 name := leaf.Name() 182 etyp := leaf.Type() 183 kind := leaf.Kind() 184 hasCount := leaf.LeafCount() != nil 185 unsigned := leaf.IsUnsigned() 186 187 size := 1 188 if !hasCount { 189 size = leaf.Len() 190 } 191 192 return colDescrFrom(name, etyp, kind, hasCount, size, unsigned) 193 } 194 195 func colDescrFrom(name string, etyp reflect.Type, kind reflect.Kind, hasCount bool, size int, unsigned bool) colDescr { 196 col := colDescr{ 197 Name: name, 198 Len: -1, 199 } 200 201 switch { 202 case hasCount: 203 // slice 204 col.Nullable = true 205 col.Len = math.MaxInt64 206 case size > 1 && kind != reflect.String: 207 // array 208 col.Len = int64(size) 209 } 210 211 switch etyp.Kind() { 212 case reflect.Interface, reflect.Map, reflect.Chan, reflect.Slice, reflect.Array: 213 panic(fmt.Errorf("rsqldrv: type %T not supported", reflect.New(etyp).Elem().Interface())) 214 case reflect.Int8: 215 if unsigned { 216 etyp = reflect.TypeOf(uint8(0)) 217 } 218 case reflect.Int16: 219 if unsigned { 220 etyp = reflect.TypeOf(uint16(0)) 221 } 222 case reflect.Int32: 223 if unsigned { 224 etyp = reflect.TypeOf(uint32(0)) 225 } 226 case reflect.Int64: 227 if unsigned { 228 etyp = reflect.TypeOf(uint64(0)) 229 } 230 } 231 232 col.Type = etyp 233 return col 234 }