decimal.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. package column
  2. import (
  3. b "encoding/binary"
  4. "errors"
  5. "fmt"
  6. "math"
  7. "reflect"
  8. "strconv"
  9. "strings"
  10. "github.com/ClickHouse/clickhouse-go/lib/binary"
  11. )
  12. // Table of powers of 10 for fast casting from floating types to decimal type
  13. // representations.
  14. var factors10 = []float64{
  15. 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13,
  16. 1e14, 1e15, 1e16, 1e17, 1e18,
  17. }
  18. // Decimal represents Decimal(P, S) ClickHouse. Decimal is represented as
  19. // integral. Also floating-point types are supported for query parameters.
  20. //
  21. // Since there is no support for int128 in Golang, decimals with precision 19
  22. // through 38 are represented as 16 little-endian bytes.
  23. type Decimal struct {
  24. base
  25. nobits int // its domain is {32, 64}
  26. precision int
  27. scale int
  28. }
  29. func (d *Decimal) Read(decoder *binary.Decoder, isNull bool) (interface{}, error) {
  30. switch d.nobits {
  31. case 32:
  32. return decoder.Int32()
  33. case 64:
  34. return decoder.Int64()
  35. case 128:
  36. return decoder.Decimal128()
  37. default:
  38. return nil, errors.New("unachievable execution path")
  39. }
  40. }
  41. func (d *Decimal) Write(encoder *binary.Encoder, v interface{}) error {
  42. switch d.nobits {
  43. case 32:
  44. return d.write32(encoder, v)
  45. case 64:
  46. return d.write64(encoder, v)
  47. case 128:
  48. return d.write128(encoder, v)
  49. default:
  50. return errors.New("unachievable execution path")
  51. }
  52. }
  53. func (d *Decimal) float2int32(floating float64) int32 {
  54. fixed := int32(floating * factors10[d.scale])
  55. return fixed
  56. }
  57. func (d *Decimal) float2int64(floating float64) int64 {
  58. fixed := int64(floating * factors10[d.scale])
  59. return fixed
  60. }
  61. func (d *Decimal) write32(encoder *binary.Encoder, v interface{}) error {
  62. switch v := v.(type) {
  63. case int8:
  64. return encoder.Int32(int32(v))
  65. case int16:
  66. return encoder.Int32(int32(v))
  67. case int32:
  68. return encoder.Int32(int32(v))
  69. case int64:
  70. if v > math.MaxInt32 || v < math.MinInt32 {
  71. return errors.New("overflow when narrowing type conversion from int64 to int32")
  72. }
  73. return encoder.Int32(int32(v))
  74. case uint8:
  75. return encoder.Int32(int32(v))
  76. case uint16:
  77. return encoder.Int32(int32(v))
  78. case uint32:
  79. if v > math.MaxInt32 {
  80. return errors.New("overflow when narrowing type conversion from uint32 to int32")
  81. }
  82. return encoder.Int32(int32(v))
  83. case uint64:
  84. if v > math.MaxInt32 {
  85. return errors.New("overflow when narrowing type conversion from uint64 to int32")
  86. }
  87. return encoder.Int32(int32(v))
  88. case float32:
  89. fixed := d.float2int32(float64(v))
  90. return encoder.Int32(fixed)
  91. case float64:
  92. fixed := d.float2int32(float64(v))
  93. return encoder.Int32(fixed)
  94. // this relies on Nullable never sending nil values through
  95. case *int8:
  96. return encoder.Int32(int32(*v))
  97. case *int16:
  98. return encoder.Int32(int32(*v))
  99. case *int32:
  100. return encoder.Int32(int32(*v))
  101. case *int64:
  102. if *v > math.MaxInt32 || *v < math.MinInt32 {
  103. return errors.New("overflow when narrowing type conversion from int64 to int32")
  104. }
  105. return encoder.Int32(int32(*v))
  106. case *uint8:
  107. return encoder.Int32(int32(*v))
  108. case *uint16:
  109. return encoder.Int32(int32(*v))
  110. case *uint32:
  111. if *v > math.MaxInt32 {
  112. return errors.New("overflow when narrowing type conversion from uint34 to int32")
  113. }
  114. return encoder.Int32(int32(*v))
  115. case *uint64:
  116. if *v > math.MaxInt32 {
  117. return errors.New("overflow when narrowing type conversion from uint64 to int32")
  118. }
  119. return encoder.Int32(int32(*v))
  120. case *float32:
  121. fixed := d.float2int32(float64(*v))
  122. return encoder.Int32(fixed)
  123. case *float64:
  124. fixed := d.float2int32(float64(*v))
  125. return encoder.Int32(fixed)
  126. }
  127. return &ErrUnexpectedType{
  128. T: v,
  129. Column: d,
  130. }
  131. }
  132. func (d *Decimal) write64(encoder *binary.Encoder, v interface{}) error {
  133. switch v := v.(type) {
  134. case int:
  135. return encoder.Int64(int64(v))
  136. case int8:
  137. return encoder.Int64(int64(v))
  138. case int16:
  139. return encoder.Int64(int64(v))
  140. case int32:
  141. return encoder.Int64(int64(v))
  142. case int64:
  143. return encoder.Int64(int64(v))
  144. case uint8:
  145. return encoder.Int64(int64(v))
  146. case uint16:
  147. return encoder.Int64(int64(v))
  148. case uint32:
  149. return encoder.Int64(int64(v))
  150. case uint64:
  151. if v > math.MaxInt64 {
  152. return errors.New("overflow when narrowing type conversion from uint64 to int64")
  153. }
  154. return encoder.Int64(int64(v))
  155. case float32:
  156. fixed := d.float2int64(float64(v))
  157. return encoder.Int64(fixed)
  158. case float64:
  159. fixed := d.float2int64(float64(v))
  160. return encoder.Int64(fixed)
  161. // this relies on Nullable never sending nil values through
  162. case *int:
  163. return encoder.Int64(int64(*v))
  164. case *int8:
  165. return encoder.Int64(int64(*v))
  166. case *int16:
  167. return encoder.Int64(int64(*v))
  168. case *int32:
  169. return encoder.Int64(int64(*v))
  170. case *int64:
  171. return encoder.Int64(int64(*v))
  172. case *uint8:
  173. return encoder.Int64(int64(*v))
  174. case *uint16:
  175. return encoder.Int64(int64(*v))
  176. case *uint32:
  177. return encoder.Int64(int64(*v))
  178. case *uint64:
  179. if *v > math.MaxInt64 {
  180. return errors.New("overflow when narrowing type conversion from uint64 to int64")
  181. }
  182. return encoder.Int64(int64(*v))
  183. case *float32:
  184. fixed := d.float2int64(float64(*v))
  185. return encoder.Int64(fixed)
  186. case *float64:
  187. fixed := d.float2int64(float64(*v))
  188. return encoder.Int64(fixed)
  189. }
  190. return &ErrUnexpectedType{
  191. T: v,
  192. Column: d,
  193. }
  194. }
  195. // Turns an int64 into 16 little-endian bytes.
  196. func int64ToDecimal128(v int64) []byte {
  197. bytes := make([]byte, 16)
  198. b.LittleEndian.PutUint64(bytes[:8], uint64(v))
  199. sign := 0
  200. if v < 0 {
  201. sign = -1
  202. }
  203. b.LittleEndian.PutUint64(bytes[8:], uint64(sign))
  204. return bytes
  205. }
  206. // Turns a uint64 into 16 little-endian bytes.
  207. func uint64ToDecimal128(v uint64) []byte {
  208. bytes := make([]byte, 16)
  209. b.LittleEndian.PutUint64(bytes[:8], uint64(v))
  210. return bytes
  211. }
  212. func (d *Decimal) write128(encoder *binary.Encoder, v interface{}) error {
  213. switch v := v.(type) {
  214. case int:
  215. return encoder.Decimal128(int64ToDecimal128(int64(v)))
  216. case int8:
  217. return encoder.Decimal128(int64ToDecimal128(int64(v)))
  218. case int16:
  219. return encoder.Decimal128(int64ToDecimal128(int64(v)))
  220. case int32:
  221. return encoder.Decimal128(int64ToDecimal128(int64(v)))
  222. case int64:
  223. return encoder.Decimal128(int64ToDecimal128(v))
  224. case uint8:
  225. return encoder.Decimal128(uint64ToDecimal128(uint64(v)))
  226. case uint16:
  227. return encoder.Decimal128(uint64ToDecimal128(uint64(v)))
  228. case uint32:
  229. return encoder.Decimal128(uint64ToDecimal128(uint64(v)))
  230. case uint64:
  231. return encoder.Decimal128(uint64ToDecimal128(v))
  232. case float32:
  233. fixed := d.float2int64(float64(v))
  234. return encoder.Decimal128(int64ToDecimal128(fixed))
  235. case float64:
  236. fixed := d.float2int64(float64(v))
  237. return encoder.Decimal128(int64ToDecimal128(fixed))
  238. case []byte:
  239. if len(v) != 16 {
  240. return errors.New("expected 16 bytes")
  241. }
  242. return encoder.Decimal128(v)
  243. // this relies on Nullable never sending nil values through
  244. case *int:
  245. return encoder.Decimal128(int64ToDecimal128(int64(*v)))
  246. case *int8:
  247. return encoder.Decimal128(int64ToDecimal128(int64(*v)))
  248. case *int16:
  249. return encoder.Decimal128(int64ToDecimal128(int64(*v)))
  250. case *int32:
  251. return encoder.Decimal128(int64ToDecimal128(int64(*v)))
  252. case *int64:
  253. return encoder.Decimal128(int64ToDecimal128(*v))
  254. case *uint8:
  255. return encoder.Decimal128(uint64ToDecimal128(uint64(*v)))
  256. case *uint16:
  257. return encoder.Decimal128(uint64ToDecimal128(uint64(*v)))
  258. case *uint32:
  259. return encoder.Decimal128(uint64ToDecimal128(uint64(*v)))
  260. case *uint64:
  261. return encoder.Decimal128(uint64ToDecimal128(*v))
  262. case *float32:
  263. fixed := d.float2int64(float64(*v))
  264. return encoder.Decimal128(int64ToDecimal128(fixed))
  265. case *float64:
  266. fixed := d.float2int64(float64(*v))
  267. return encoder.Decimal128(int64ToDecimal128(fixed))
  268. case *[]byte:
  269. if len(*v) != 16 {
  270. return errors.New("expected 16 bytes")
  271. }
  272. return encoder.Decimal128(*v)
  273. }
  274. return &ErrUnexpectedType{
  275. T: v,
  276. Column: d,
  277. }
  278. }
  279. func parseDecimal(name, chType string) (Column, error) {
  280. switch {
  281. case len(chType) < 12:
  282. fallthrough
  283. case !strings.HasPrefix(chType, "Decimal"):
  284. fallthrough
  285. case chType[7] != '(':
  286. fallthrough
  287. case chType[len(chType)-1] != ')':
  288. return nil, fmt.Errorf("invalid Decimal format: '%s'", chType)
  289. }
  290. var params = strings.Split(chType[8:len(chType)-1], ",")
  291. if len(params) != 2 {
  292. return nil, fmt.Errorf("invalid Decimal format: '%s'", chType)
  293. }
  294. params[0] = strings.TrimSpace(params[0])
  295. params[1] = strings.TrimSpace(params[1])
  296. var err error
  297. var decimal = &Decimal{
  298. base: base{
  299. name: name,
  300. chType: chType,
  301. },
  302. }
  303. if decimal.precision, err = strconv.Atoi(params[0]); err != nil {
  304. return nil, fmt.Errorf("'%s' is not Decimal type: %s", chType, err)
  305. } else if decimal.precision < 1 {
  306. return nil, errors.New("wrong precision of Decimal type")
  307. }
  308. if decimal.scale, err = strconv.Atoi(params[1]); err != nil {
  309. return nil, fmt.Errorf("'%s' is not Decimal type: %s", chType, err)
  310. } else if decimal.scale < 0 || decimal.scale > decimal.precision {
  311. return nil, errors.New("wrong scale of Decimal type")
  312. }
  313. switch {
  314. case decimal.precision <= 9:
  315. decimal.nobits = 32
  316. decimal.valueOf = columnBaseTypes[int32(0)]
  317. case decimal.precision <= 18:
  318. decimal.nobits = 64
  319. decimal.valueOf = columnBaseTypes[int64(0)]
  320. case decimal.precision <= 38:
  321. decimal.nobits = 128
  322. decimal.valueOf = reflect.ValueOf([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
  323. default:
  324. return nil, errors.New("precision of Decimal exceeds max bound")
  325. }
  326. return decimal, nil
  327. }
  328. func (d *Decimal) GetPrecision() int {
  329. return d.precision
  330. }
  331. func (d *Decimal) GetScale() int {
  332. return d.scale
  333. }