In the MySQL and MySQLi drivers, field_data() calls
Code:
show columns from table_name
Normally, this will show the columns as they were defined, so the max_length values should be accurate. However, various options, such as the use of dynamic tables, can generate the behavior you are describing.
Since most of the valid commands to retrieve this data (for example, selecting directly from the information_schema table) get the data from the same place, it's unlikely that using another method to get the data will change the information received.
It should also be noted that the max_length values on integer types are used for display purposes by certain functions in MySQL, but aren't actually the maximum length of the given field (which is fixed, based on the type).
More than likely, given a MySQL database, the most reliable method for determining the structure of a table is probably to call
Code:
show create table table_name
. You would then have to parse the result to get the data you're looking for. In terms of performance, you're probably better off maintaining the information in your model.