// Go MySQL Driver - A MySQL-Driver for Go's database/sql package // // Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. package mysql import ( "database/sql" "reflect" ) var typeDatabaseName = map[fieldType]string{ fieldTypeBit: "BIT", fieldTypeBLOB: "BLOB", fieldTypeDate: "DATE", fieldTypeDateTime: "DATETIME", fieldTypeDecimal: "DECIMAL", fieldTypeDouble: "DOUBLE", fieldTypeEnum: "ENUM", fieldTypeFloat: "FLOAT", fieldTypeGeometry: "GEOMETRY", fieldTypeInt24: "MEDIUMINT", fieldTypeJSON: "JSON", fieldTypeLong: "INT", fieldTypeLongBLOB: "LONGBLOB", fieldTypeLongLong: "BIGINT", fieldTypeMediumBLOB: "MEDIUMBLOB", fieldTypeNewDate: "DATE", fieldTypeNewDecimal: "DECIMAL", fieldTypeNULL: "NULL", fieldTypeSet: "SET", fieldTypeShort: "SMALLINT", fieldTypeString: "CHAR", fieldTypeTime: "TIME", fieldTypeTimestamp: "TIMESTAMP", fieldTypeTiny: "TINYINT", fieldTypeTinyBLOB: "TINYBLOB", fieldTypeVarChar: "VARCHAR", fieldTypeVarString: "VARCHAR", fieldTypeYear: "YEAR", } var ( scanTypeFloat32 = reflect.TypeOf(float32(0)) scanTypeFloat64 = reflect.TypeOf(float64(0)) scanTypeInt8 = reflect.TypeOf(int8(0)) scanTypeInt16 = reflect.TypeOf(int16(0)) scanTypeInt32 = reflect.TypeOf(int32(0)) scanTypeInt64 = reflect.TypeOf(int64(0)) scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{}) scanTypeNullInt = reflect.TypeOf(sql.NullInt64{}) scanTypeNullTime = reflect.TypeOf(NullTime{}) scanTypeUint8 = reflect.TypeOf(uint8(0)) scanTypeUint16 = reflect.TypeOf(uint16(0)) scanTypeUint32 = reflect.TypeOf(uint32(0)) scanTypeUint64 = reflect.TypeOf(uint64(0)) scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{}) scanTypeUnknown = reflect.TypeOf(new(interface{})) ) type mysqlField struct { tableName string name string length uint32 flags fieldFlag fieldType fieldType decimals byte } func (mf *mysqlField) scanType() reflect.Type { switch mf.fieldType { case fieldTypeTiny: if mf.flags&flagNotNULL != 0 { if mf.flags&flagUnsigned != 0 { return scanTypeUint8 } return scanTypeInt8 } return scanTypeNullInt case fieldTypeShort, fieldTypeYear: if mf.flags&flagNotNULL != 0 { if mf.flags&flagUnsigned != 0 { return scanTypeUint16 } return scanTypeInt16 } return scanTypeNullInt case fieldTypeInt24, fieldTypeLong: if mf.flags&flagNotNULL != 0 { if mf.flags&flagUnsigned != 0 { return scanTypeUint32 } return scanTypeInt32 } return scanTypeNullInt case fieldTypeLongLong: if mf.flags&flagNotNULL != 0 { if mf.flags&flagUnsigned != 0 { return scanTypeUint64 } return scanTypeInt64 } return scanTypeNullInt case fieldTypeFloat: if mf.flags&flagNotNULL != 0 { return scanTypeFloat32 } return scanTypeNullFloat case fieldTypeDouble: if mf.flags&flagNotNULL != 0 { return scanTypeFloat64 } return scanTypeNullFloat case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar, fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB, fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB, fieldTypeVarString, fieldTypeString, fieldTypeGeometry, fieldTypeJSON, fieldTypeTime: return scanTypeRawBytes case fieldTypeDate, fieldTypeNewDate, fieldTypeTimestamp, fieldTypeDateTime: // NullTime is always returned for more consistent behavior as it can // handle both cases of parseTime regardless if the field is nullable. return scanTypeNullTime default: return scanTypeUnknown } }