in src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeProtocol.java [1380:1542]
public static MysqlType findMysqlType(PropertySet propertySet, int mysqlTypeId, short colFlag, long length, LazyString tableName,
LazyString originalTableName, int collationIndex, String encoding) {
boolean isUnsigned = (colFlag & MysqlType.FIELD_FLAG_UNSIGNED) > 0;
boolean isFromFunction = originalTableName.length() == 0;
boolean isBinary = (colFlag & MysqlType.FIELD_FLAG_BINARY) > 0;
/**
* Is this field owned by a server-created temporary table?
*/
boolean isImplicitTemporaryTable = tableName.length() > 0 && tableName.toString().startsWith("#sql_");
boolean isOpaqueBinary = isBinary && collationIndex == CharsetMapping.MYSQL_COLLATION_INDEX_binary
&& (mysqlTypeId == MysqlType.FIELD_TYPE_STRING || mysqlTypeId == MysqlType.FIELD_TYPE_VAR_STRING || mysqlTypeId == MysqlType.FIELD_TYPE_VARCHAR)
?
// queries resolved by temp tables also have this 'signature', check for that
!isImplicitTemporaryTable
: "binary".equalsIgnoreCase(encoding);
switch (mysqlTypeId) {
case MysqlType.FIELD_TYPE_DECIMAL:
case MysqlType.FIELD_TYPE_NEWDECIMAL:
return isUnsigned ? MysqlType.DECIMAL_UNSIGNED : MysqlType.DECIMAL;
case MysqlType.FIELD_TYPE_TINY:
// Adjust for pseudo-boolean
if (!isUnsigned && length == 1 && propertySet.getBooleanProperty(PropertyKey.tinyInt1isBit).getValue()) {
if (propertySet.getBooleanProperty(PropertyKey.transformedBitIsBoolean).getValue()) {
return MysqlType.BOOLEAN;
}
return MysqlType.BIT;
}
return isUnsigned ? MysqlType.TINYINT_UNSIGNED : MysqlType.TINYINT;
case MysqlType.FIELD_TYPE_SHORT:
return isUnsigned ? MysqlType.SMALLINT_UNSIGNED : MysqlType.SMALLINT;
case MysqlType.FIELD_TYPE_LONG:
return isUnsigned ? MysqlType.INT_UNSIGNED : MysqlType.INT;
case MysqlType.FIELD_TYPE_FLOAT:
return isUnsigned ? MysqlType.FLOAT_UNSIGNED : MysqlType.FLOAT;
case MysqlType.FIELD_TYPE_DOUBLE:
return isUnsigned ? MysqlType.DOUBLE_UNSIGNED : MysqlType.DOUBLE;
case MysqlType.FIELD_TYPE_NULL:
return MysqlType.NULL;
case MysqlType.FIELD_TYPE_TIMESTAMP:
return MysqlType.TIMESTAMP;
case MysqlType.FIELD_TYPE_LONGLONG:
return isUnsigned ? MysqlType.BIGINT_UNSIGNED : MysqlType.BIGINT;
case MysqlType.FIELD_TYPE_INT24:
return isUnsigned ? MysqlType.MEDIUMINT_UNSIGNED : MysqlType.MEDIUMINT;
case MysqlType.FIELD_TYPE_DATE:
return MysqlType.DATE;
case MysqlType.FIELD_TYPE_TIME:
return MysqlType.TIME;
case MysqlType.FIELD_TYPE_DATETIME:
return MysqlType.DATETIME;
case MysqlType.FIELD_TYPE_YEAR:
return MysqlType.YEAR;
case MysqlType.FIELD_TYPE_VARCHAR:
case MysqlType.FIELD_TYPE_VAR_STRING:
if (isOpaqueBinary && !(isFromFunction && propertySet.getBooleanProperty(PropertyKey.functionsNeverReturnBlobs).getValue())) {
return MysqlType.VARBINARY;
}
return MysqlType.VARCHAR;
case MysqlType.FIELD_TYPE_BIT:
//if (length > 1) {
// we need to pretend this is a full binary blob
//this.colFlag |= MysqlType.FIELD_FLAG_BINARY;
//this.colFlag |= MysqlType.FIELD_FLAG_BLOB;
//return MysqlType.VARBINARY;
//}
return MysqlType.BIT;
case MysqlType.FIELD_TYPE_JSON:
return MysqlType.JSON;
case MysqlType.FIELD_TYPE_ENUM:
return MysqlType.ENUM;
case MysqlType.FIELD_TYPE_SET:
return MysqlType.SET;
case MysqlType.FIELD_TYPE_TINY_BLOB:
if (!isBinary || collationIndex != CharsetMapping.MYSQL_COLLATION_INDEX_binary
|| propertySet.getBooleanProperty(PropertyKey.blobsAreStrings).getValue()
|| isFromFunction && propertySet.getBooleanProperty(PropertyKey.functionsNeverReturnBlobs).getValue()) {
return MysqlType.TINYTEXT;
}
return MysqlType.TINYBLOB;
case MysqlType.FIELD_TYPE_MEDIUM_BLOB:
if (!isBinary || collationIndex != CharsetMapping.MYSQL_COLLATION_INDEX_binary
|| propertySet.getBooleanProperty(PropertyKey.blobsAreStrings).getValue()
|| isFromFunction && propertySet.getBooleanProperty(PropertyKey.functionsNeverReturnBlobs).getValue()) {
return MysqlType.MEDIUMTEXT;
}
return MysqlType.MEDIUMBLOB;
case MysqlType.FIELD_TYPE_LONG_BLOB:
if (!isBinary || collationIndex != CharsetMapping.MYSQL_COLLATION_INDEX_binary
|| propertySet.getBooleanProperty(PropertyKey.blobsAreStrings).getValue()
|| isFromFunction && propertySet.getBooleanProperty(PropertyKey.functionsNeverReturnBlobs).getValue()) {
return MysqlType.LONGTEXT;
}
return MysqlType.LONGBLOB;
case MysqlType.FIELD_TYPE_BLOB:
// Sometimes MySQL uses this protocol-level type for all possible BLOB variants,
// we can divine what the actual type is by the length reported
int newMysqlTypeId = mysqlTypeId;
// fixing initial type according to length
if (length <= MysqlType.TINYBLOB.getPrecision()) {
newMysqlTypeId = MysqlType.FIELD_TYPE_TINY_BLOB;
} else if (length <= MysqlType.BLOB.getPrecision()) {
if (!isBinary || collationIndex != CharsetMapping.MYSQL_COLLATION_INDEX_binary
|| propertySet.getBooleanProperty(PropertyKey.blobsAreStrings).getValue()
|| isFromFunction && propertySet.getBooleanProperty(PropertyKey.functionsNeverReturnBlobs).getValue()) {
newMysqlTypeId = MysqlType.FIELD_TYPE_VARCHAR;
return MysqlType.TEXT;
}
return MysqlType.BLOB;
} else if (length <= MysqlType.MEDIUMBLOB.getPrecision()) {
newMysqlTypeId = MysqlType.FIELD_TYPE_MEDIUM_BLOB;
} else {
newMysqlTypeId = MysqlType.FIELD_TYPE_LONG_BLOB;
}
// call this method again with correct this.mysqlType set
return findMysqlType(propertySet, newMysqlTypeId, colFlag, length, tableName, originalTableName, collationIndex, encoding);
case MysqlType.FIELD_TYPE_STRING:
if (isOpaqueBinary && !propertySet.getBooleanProperty(PropertyKey.blobsAreStrings).getValue()) {
return MysqlType.BINARY;
}
return MysqlType.CHAR;
case MysqlType.FIELD_TYPE_GEOMETRY:
return MysqlType.GEOMETRY;
case MysqlType.FIELD_TYPE_VECTOR:
return MysqlType.VECTOR;
default:
return MysqlType.UNKNOWN;
}
}