fields.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
  2. //
  3. // Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public
  6. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  7. // You can obtain one at http://mozilla.org/MPL/2.0/.
  8. package mysql
  9. import (
  10. "database/sql"
  11. "reflect"
  12. )
  13. func (mf *mysqlField) typeDatabaseName() string {
  14. switch mf.fieldType {
  15. case fieldTypeBit:
  16. return "BIT"
  17. case fieldTypeBLOB:
  18. if mf.charSet != binaryCollationID {
  19. return "TEXT"
  20. }
  21. return "BLOB"
  22. case fieldTypeDate:
  23. return "DATE"
  24. case fieldTypeDateTime:
  25. return "DATETIME"
  26. case fieldTypeDecimal:
  27. return "DECIMAL"
  28. case fieldTypeDouble:
  29. return "DOUBLE"
  30. case fieldTypeEnum:
  31. return "ENUM"
  32. case fieldTypeFloat:
  33. return "FLOAT"
  34. case fieldTypeGeometry:
  35. return "GEOMETRY"
  36. case fieldTypeInt24:
  37. if mf.flags&flagUnsigned != 0 {
  38. return "UNSIGNED MEDIUMINT"
  39. }
  40. return "MEDIUMINT"
  41. case fieldTypeJSON:
  42. return "JSON"
  43. case fieldTypeLong:
  44. if mf.flags&flagUnsigned != 0 {
  45. return "UNSIGNED INT"
  46. }
  47. return "INT"
  48. case fieldTypeLongBLOB:
  49. if mf.charSet != binaryCollationID {
  50. return "LONGTEXT"
  51. }
  52. return "LONGBLOB"
  53. case fieldTypeLongLong:
  54. if mf.flags&flagUnsigned != 0 {
  55. return "UNSIGNED BIGINT"
  56. }
  57. return "BIGINT"
  58. case fieldTypeMediumBLOB:
  59. if mf.charSet != binaryCollationID {
  60. return "MEDIUMTEXT"
  61. }
  62. return "MEDIUMBLOB"
  63. case fieldTypeNewDate:
  64. return "DATE"
  65. case fieldTypeNewDecimal:
  66. return "DECIMAL"
  67. case fieldTypeNULL:
  68. return "NULL"
  69. case fieldTypeSet:
  70. return "SET"
  71. case fieldTypeShort:
  72. if mf.flags&flagUnsigned != 0 {
  73. return "UNSIGNED SMALLINT"
  74. }
  75. return "SMALLINT"
  76. case fieldTypeString:
  77. if mf.flags&flagEnum != 0 {
  78. return "ENUM"
  79. } else if mf.flags&flagSet != 0 {
  80. return "SET"
  81. }
  82. if mf.charSet == binaryCollationID {
  83. return "BINARY"
  84. }
  85. return "CHAR"
  86. case fieldTypeTime:
  87. return "TIME"
  88. case fieldTypeTimestamp:
  89. return "TIMESTAMP"
  90. case fieldTypeTiny:
  91. if mf.flags&flagUnsigned != 0 {
  92. return "UNSIGNED TINYINT"
  93. }
  94. return "TINYINT"
  95. case fieldTypeTinyBLOB:
  96. if mf.charSet != binaryCollationID {
  97. return "TINYTEXT"
  98. }
  99. return "TINYBLOB"
  100. case fieldTypeVarChar:
  101. if mf.charSet == binaryCollationID {
  102. return "VARBINARY"
  103. }
  104. return "VARCHAR"
  105. case fieldTypeVarString:
  106. if mf.charSet == binaryCollationID {
  107. return "VARBINARY"
  108. }
  109. return "VARCHAR"
  110. case fieldTypeYear:
  111. return "YEAR"
  112. default:
  113. return ""
  114. }
  115. }
  116. var (
  117. scanTypeFloat32 = reflect.TypeOf(float32(0))
  118. scanTypeFloat64 = reflect.TypeOf(float64(0))
  119. scanTypeInt8 = reflect.TypeOf(int8(0))
  120. scanTypeInt16 = reflect.TypeOf(int16(0))
  121. scanTypeInt32 = reflect.TypeOf(int32(0))
  122. scanTypeInt64 = reflect.TypeOf(int64(0))
  123. scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
  124. scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
  125. scanTypeNullTime = reflect.TypeOf(sql.NullTime{})
  126. scanTypeUint8 = reflect.TypeOf(uint8(0))
  127. scanTypeUint16 = reflect.TypeOf(uint16(0))
  128. scanTypeUint32 = reflect.TypeOf(uint32(0))
  129. scanTypeUint64 = reflect.TypeOf(uint64(0))
  130. scanTypeString = reflect.TypeOf("")
  131. scanTypeNullString = reflect.TypeOf(sql.NullString{})
  132. scanTypeBytes = reflect.TypeOf([]byte{})
  133. scanTypeUnknown = reflect.TypeOf(new(any))
  134. )
  135. type mysqlField struct {
  136. tableName string
  137. name string
  138. length uint32
  139. flags fieldFlag
  140. fieldType fieldType
  141. decimals byte
  142. charSet uint8
  143. }
  144. func (mf *mysqlField) scanType() reflect.Type {
  145. switch mf.fieldType {
  146. case fieldTypeTiny:
  147. if mf.flags&flagNotNULL != 0 {
  148. if mf.flags&flagUnsigned != 0 {
  149. return scanTypeUint8
  150. }
  151. return scanTypeInt8
  152. }
  153. return scanTypeNullInt
  154. case fieldTypeShort, fieldTypeYear:
  155. if mf.flags&flagNotNULL != 0 {
  156. if mf.flags&flagUnsigned != 0 {
  157. return scanTypeUint16
  158. }
  159. return scanTypeInt16
  160. }
  161. return scanTypeNullInt
  162. case fieldTypeInt24, fieldTypeLong:
  163. if mf.flags&flagNotNULL != 0 {
  164. if mf.flags&flagUnsigned != 0 {
  165. return scanTypeUint32
  166. }
  167. return scanTypeInt32
  168. }
  169. return scanTypeNullInt
  170. case fieldTypeLongLong:
  171. if mf.flags&flagNotNULL != 0 {
  172. if mf.flags&flagUnsigned != 0 {
  173. return scanTypeUint64
  174. }
  175. return scanTypeInt64
  176. }
  177. return scanTypeNullInt
  178. case fieldTypeFloat:
  179. if mf.flags&flagNotNULL != 0 {
  180. return scanTypeFloat32
  181. }
  182. return scanTypeNullFloat
  183. case fieldTypeDouble:
  184. if mf.flags&flagNotNULL != 0 {
  185. return scanTypeFloat64
  186. }
  187. return scanTypeNullFloat
  188. case fieldTypeBit, fieldTypeTinyBLOB, fieldTypeMediumBLOB, fieldTypeLongBLOB,
  189. fieldTypeBLOB, fieldTypeVarString, fieldTypeString, fieldTypeGeometry:
  190. if mf.charSet == binaryCollationID {
  191. return scanTypeBytes
  192. }
  193. fallthrough
  194. case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
  195. fieldTypeEnum, fieldTypeSet, fieldTypeJSON, fieldTypeTime:
  196. if mf.flags&flagNotNULL != 0 {
  197. return scanTypeString
  198. }
  199. return scanTypeNullString
  200. case fieldTypeDate, fieldTypeNewDate,
  201. fieldTypeTimestamp, fieldTypeDateTime:
  202. // NullTime is always returned for more consistent behavior as it can
  203. // handle both cases of parseTime regardless if the field is nullable.
  204. return scanTypeNullTime
  205. default:
  206. return scanTypeUnknown
  207. }
  208. }