Bug #11278 Old MYSQL_FIELD struct returned by mysql_fetch_fields()
Submitted: 13 Jun 2005 6:48 Modified: 21 Jun 2005 2:24
Reporter: David Armour Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:4.1.12a OS:Windows (Windows)
Assigned to: CPU Architecture:Any

[13 Jun 2005 6:48] David Armour
Description:
The function mysql_fetch_fields() returns an array of MYSQL_FIELD objects. The definition of the MYSQL_FIELD typedef changed recently (I am not sure which version) from a 40 byte struct to an 80 byte struct in the header mysql.h.

When using the mysql_fetch_fields() function provided with the Windows Essentials (x86) version of the library libmysql.lib, it returns MYSQL_FIELD objects with the old format typedef instead of the new one.

This causes code recompiled with the 4.1.12a includes & library to break.

How to repeat:
Compile the following code with 4.1.12a where 'result' is already obtained from a query. Note that the query must return more than 1 field to see the problem.

unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *fields;

num_fields = mysql_num_fields(result);
fields = mysql_fetch_fields(result);
for(i = 0; i < num_fields; i++)
{
   printf("Field %u is %s\n", i, fields[i].name);   // NOTE A
}

NOTE A
=====
Crashed here when i > num_fields/2.

Suggested fix:
Changing MYSQL_FIELD struct in the header mysql.h 

from:

typedef struct st_mysql_field {
char *name; /* Name of column */
char *org_name; /* Original column name, if an alias */
char *table; /* Table of column if column was a field */
char *org_table; /* Org table name, if table was an alias */
char *db; /* Database for table */
char *catalog; /* Catalog for table */
char *def; /* Default value (set by mysql_list_fields) */
unsigned long length; /* Width of column (create length) */
unsigned long max_length; /* Max width for selected set */
unsigned int name_length;
unsigned int org_name_length;
unsigned int table_length;
unsigned int org_table_length;
unsigned int db_length;
unsigned int catalog_length;
unsigned int def_length;
unsigned int flags; /* Div flags */
unsigned int decimals; /* Number of decimals in field */
unsigned int charsetnr; /* Character set */
enum enum_field_types type; /* Type of field. See mysql_com.h for types */
} MYSQL_FIELD; 

to:

typedef struct st_mysql_field {
char *name; /* Name of column */
char *table; /* Table of column if column was a field */
char *org_table; /* Org table name if table was an alias */
char *db; /* Database for table */
char *def; /* Default value (set by mysql_list_fields) */
unsigned long length; /* Width of column */
unsigned long max_length; /* Max width of selected set */
unsigned int flags; /* Div flags */
unsigned int decimals; /* Number of decimals in field */
enum enum_field_types type; /* Type of field. Se mysql_com.h for types */
} MYSQL_FIELD;

will temporarily fix the problem.
[20 Jun 2005 16:41] MySQL Verification Team
What you mean "for to see the problem". Below the output
for a table with 2 columns:

C:\temp>bug11278a
Connected with the Server: 4.1.12a-nt
Select Query done!
Field 0 is col1
Field 1 is col2
Field 2 is col3

Thanks in advance.
[20 Jun 2005 16:45] MySQL Verification Team
Sorry I meant table with 3 columns.
[21 Jun 2005 2:06] David Armour
After re-running the test on another computer the problem did not appear. It is suspected that an old libmysql.dll file was located somewhere in the path and resulted in this problem.

Once the original PC was cleaned of any spurious libmysql.dll files the problem was resolved.
[21 Jun 2005 2:24] MySQL Verification Team
Thanks for the feedback.