in driver/utility.cc [1478:1568]
SQLULEN get_column_size(STMT *stmt, MYSQL_FIELD *field)
{
SQLULEN length= field->length;
/* Work around a bug in some versions of the server. */
if (field->max_length > field->length)
length= field->max_length;
length= cap_length(stmt, (unsigned long)length);
switch (field->type) {
case MYSQL_TYPE_TINY:
return (field->flags & NUM_FLAG) ? 3 : 1;
case MYSQL_TYPE_SHORT:
return 5;
case MYSQL_TYPE_LONG:
return 10;
case MYSQL_TYPE_FLOAT:
return 7;
case MYSQL_TYPE_DOUBLE:
return 15;
case MYSQL_TYPE_NULL:
return 0;
case MYSQL_TYPE_LONGLONG:
if (stmt->dbc->ds->opt_NO_BIGINT)
return 10; /* same as MYSQL_TYPE_LONG */
else
return (field->flags & UNSIGNED_FLAG) ? 20 : 19;
case MYSQL_TYPE_INT24:
return 8;
case MYSQL_TYPE_DATE:
return 10;
case MYSQL_TYPE_TIME:
return 8;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_NEWDATE:
return 19;
case MYSQL_TYPE_YEAR:
return 4;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
return (length -
(!(field->flags & UNSIGNED_FLAG) ? 1: 0) - /* sign? */
(field->decimals ? 1 : 0)); /* decimal point? */
case MYSQL_TYPE_BIT:
/*
We treat a BIT(n) as a SQL_BIT if n == 1, otherwise we treat it
as a SQL_BINARY, so length is (bits + 7) / 8.
*/
if (length == 1)
return 1;
return (length + 7) / 8;
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
if (field->charsetnr == BINARY_CHARSET_NUMBER)
return length;
else
{
CHARSET_INFO *charset= get_charset(field->charsetnr, MYF(0));
return length / (charset ? charset->mbmaxlen : 1);
}
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_GEOMETRY:
return length;
case MYSQL_TYPE_JSON:
return UINT32_MAX / 4; // Because JSON is always UTF8MB4
}
return SQL_NO_TOTAL;
}