You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fields.go 4.6KB

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