fields.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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 != collations[binaryCollation] {
  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. return "MEDIUMINT"
  38. case fieldTypeJSON:
  39. return "JSON"
  40. case fieldTypeLong:
  41. if mf.flags&flagUnsigned != 0 {
  42. return "UNSIGNED INT"
  43. }
  44. return "INT"
  45. case fieldTypeLongBLOB:
  46. if mf.charSet != collations[binaryCollation] {
  47. return "LONGTEXT"
  48. }
  49. return "LONGBLOB"
  50. case fieldTypeLongLong:
  51. if mf.flags&flagUnsigned != 0 {
  52. return "UNSIGNED BIGINT"
  53. }
  54. return "BIGINT"
  55. case fieldTypeMediumBLOB:
  56. if mf.charSet != collations[binaryCollation] {
  57. return "MEDIUMTEXT"
  58. }
  59. return "MEDIUMBLOB"
  60. case fieldTypeNewDate:
  61. return "DATE"
  62. case fieldTypeNewDecimal:
  63. return "DECIMAL"
  64. case fieldTypeNULL:
  65. return "NULL"
  66. case fieldTypeSet:
  67. return "SET"
  68. case fieldTypeShort:
  69. if mf.flags&flagUnsigned != 0 {
  70. return "UNSIGNED SMALLINT"
  71. }
  72. return "SMALLINT"
  73. case fieldTypeString:
  74. if mf.charSet == collations[binaryCollation] {
  75. return "BINARY"
  76. }
  77. return "CHAR"
  78. case fieldTypeTime:
  79. return "TIME"
  80. case fieldTypeTimestamp:
  81. return "TIMESTAMP"
  82. case fieldTypeTiny:
  83. if mf.flags&flagUnsigned != 0 {
  84. return "UNSIGNED TINYINT"
  85. }
  86. return "TINYINT"
  87. case fieldTypeTinyBLOB:
  88. if mf.charSet != collations[binaryCollation] {
  89. return "TINYTEXT"
  90. }
  91. return "TINYBLOB"
  92. case fieldTypeVarChar:
  93. if mf.charSet == collations[binaryCollation] {
  94. return "VARBINARY"
  95. }
  96. return "VARCHAR"
  97. case fieldTypeVarString:
  98. if mf.charSet == collations[binaryCollation] {
  99. return "VARBINARY"
  100. }
  101. return "VARCHAR"
  102. case fieldTypeYear:
  103. return "YEAR"
  104. default:
  105. return ""
  106. }
  107. }
  108. var (
  109. scanTypeFloat32 = reflect.TypeOf(float32(0))
  110. scanTypeFloat64 = reflect.TypeOf(float64(0))
  111. scanTypeInt8 = reflect.TypeOf(int8(0))
  112. scanTypeInt16 = reflect.TypeOf(int16(0))
  113. scanTypeInt32 = reflect.TypeOf(int32(0))
  114. scanTypeInt64 = reflect.TypeOf(int64(0))
  115. scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
  116. scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
  117. scanTypeNullTime = reflect.TypeOf(sql.NullTime{})
  118. scanTypeUint8 = reflect.TypeOf(uint8(0))
  119. scanTypeUint16 = reflect.TypeOf(uint16(0))
  120. scanTypeUint32 = reflect.TypeOf(uint32(0))
  121. scanTypeUint64 = reflect.TypeOf(uint64(0))
  122. scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{})
  123. scanTypeUnknown = reflect.TypeOf(new(interface{}))
  124. )
  125. type mysqlField struct {
  126. tableName string
  127. name string
  128. length uint32
  129. flags fieldFlag
  130. fieldType fieldType
  131. decimals byte
  132. charSet uint8
  133. }
  134. func (mf *mysqlField) scanType() reflect.Type {
  135. switch mf.fieldType {
  136. case fieldTypeTiny:
  137. if mf.flags&flagNotNULL != 0 {
  138. if mf.flags&flagUnsigned != 0 {
  139. return scanTypeUint8
  140. }
  141. return scanTypeInt8
  142. }
  143. return scanTypeNullInt
  144. case fieldTypeShort, fieldTypeYear:
  145. if mf.flags&flagNotNULL != 0 {
  146. if mf.flags&flagUnsigned != 0 {
  147. return scanTypeUint16
  148. }
  149. return scanTypeInt16
  150. }
  151. return scanTypeNullInt
  152. case fieldTypeInt24, fieldTypeLong:
  153. if mf.flags&flagNotNULL != 0 {
  154. if mf.flags&flagUnsigned != 0 {
  155. return scanTypeUint32
  156. }
  157. return scanTypeInt32
  158. }
  159. return scanTypeNullInt
  160. case fieldTypeLongLong:
  161. if mf.flags&flagNotNULL != 0 {
  162. if mf.flags&flagUnsigned != 0 {
  163. return scanTypeUint64
  164. }
  165. return scanTypeInt64
  166. }
  167. return scanTypeNullInt
  168. case fieldTypeFloat:
  169. if mf.flags&flagNotNULL != 0 {
  170. return scanTypeFloat32
  171. }
  172. return scanTypeNullFloat
  173. case fieldTypeDouble:
  174. if mf.flags&flagNotNULL != 0 {
  175. return scanTypeFloat64
  176. }
  177. return scanTypeNullFloat
  178. case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
  179. fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB,
  180. fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB,
  181. fieldTypeVarString, fieldTypeString, fieldTypeGeometry, fieldTypeJSON,
  182. fieldTypeTime:
  183. return scanTypeRawBytes
  184. case fieldTypeDate, fieldTypeNewDate,
  185. fieldTypeTimestamp, fieldTypeDateTime:
  186. // NullTime is always returned for more consistent behavior as it can
  187. // handle both cases of parseTime regardless if the field is nullable.
  188. return scanTypeNullTime
  189. default:
  190. return scanTypeUnknown
  191. }
  192. }