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