Bug #10645 mysql_fetch_fields not returning array
Submitted: 15 May 2005 19:04 Modified: 18 May 2005 19:33
Reporter: Jonathan martens Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:4.1.11.nt OS:Microsoft Windows (Windows XP SP2)
Assigned to: CPU Architecture:Any

[15 May 2005 19:04] Jonathan martens
Description:
I am trying to determine the field names using the C API using the
example from mysql manual
(http://dev.mysql.com/doc/mysql/en/mysql-fetch-fields.html):

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)

Description

Returns an array of all MYSQL_FIELD structures for a result set. Each
structure provides the field definition for one column of the result set.

Return Values

An array of MYSQL_FIELD structures for all columns of a result set.

Errors

None.

Example

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);
}

The manual says that the function returns an array. 

I ran a query which returns data in six columns so to my opinion the valid indexes should be 0 upto and including 5. The definition of the variables does not indicate an array being declared for fields to my opinion. It seems to be more like a single field definition to me.

The first time I run the loop (i=0) everything works perfectly and the first field name gets returned, but when the loop goes through its second iteration (i=1) the system crashes with an access violation in the vc98\crt\src\output.c file.

I added a watch to see whether the result was really an array and it
does *not* seem to be an array, at least not to me.

System:
Microsoft Visual C++ 6 SP6
Mysql 4.1.11-nt

How to repeat:
Implement the example after making a connection and running a query on a table in the database, run the loop to display the field names.

Suggested fix:
Really return an array?
[15 May 2005 19:15] Jonathan martens
Changed the category to libmysql in stead of libmysqld, I selected the wrong item by accident.
[16 May 2005 1:31] Miguel Solorzano
I was unable to repeat the output showed below is from the
the application at the bottom:

C:\temp>bug10645
Connected with the Server: 4.1.12-nt
Field 0 is cl1
Field 1 is cl2
Field 2 is cl3
Field 3 is cl4
Field 4 is cl5
Field 5 is cl6

#ifdef WIN32
typedef unsigned __int64 ulonglong;
typedef __int64 longlong;
typedef unsigned long ulong;
#endif

#include <stdio.h>
#include <string.h>
#include <my_global.h>
#include <m_ctype.h>
#include <m_string.h>
#include <mysql.h>

#define query1 "Create Table A (cl1 int,cl2 int,cl3 int,cl4 int,cl5 int,cl6 int)"
#define query2 "Insert into A values (1,2,3,4,5,6)"
#define query3 "Select * from A"

void main()
{
 
  MYSQL *MySQL;
  MYSQL_RES	* result ;
  unsigned int num_fields;
  unsigned int i;
  MYSQL_FIELD *fields;
  
  if ( (MySQL = mysql_init((MYSQL*) 0)) && 
        mysql_real_connect( MySQL,"localhost","root",
                           "",	"test",	0, NULL, 0 ))
  {  
     printf("Connected with the Server: %s\n",
            mysql_get_server_info(MySQL));
  }
  else
  {
    printf("Failed to connect with the server\n");
    mysql_close( MySQL );
    return;
  }
    
 if (mysql_real_query(MySQL,query1,sizeof(query1)) < 0)
 {
   printf("Create Table A failed (%s)\n",mysql_error(MySQL));
   mysql_close( MySQL );
   return;
 }

 if (mysql_real_query(MySQL,query2,sizeof(query2)) < 0)
 {
   printf("Insert  query failed (%s)\n",mysql_error(MySQL));
   mysql_close( MySQL );
   return;
 }

 if (mysql_real_query(MySQL,query3,sizeof(query3)) < 0)
 {
   printf("Select query failed (%s)\n",mysql_error(MySQL));
   mysql_close( MySQL );
   return;
 }

 result = mysql_store_result( MySQL );
 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);
 }
 
 mysql_close( MySQL );
   
}
[16 May 2005 10:30] Jonathan martens
Unfortunately with the example provided I still get the same error.

Access violation in the printf routine when trying to print the field name of the second column (i=1).

I also noticed that when I connect with a user with a password I get the following error:

Failed to connect with the server (Client does not support authentication protocol requested by the server; consider upgrading MySQL client)

If I connect with a user without a password I am able to login to the mysql server and run the queries. However the sample code still crashes on displaying the second field name.

I was thinking of some version incomaptibility as a result of the files I specified not being linked but some file from a different location with an other version. Therefore I explicitly linked to the libmysql.lib file in the lib\opt directory of the server. In my opinion I don't think I should have this error, as I am linking to the file that came with the server installation. The filestamp of this file is 4-4-2005 16:57. Unfortunately no version information is available under the properties tab in the explorer.

I also removed all the include directories in the tools > options > directory tab to see if some other version of the header file was included from some other location perhaps but then it fails to compile, on the my_globals.h file. It says it cannot find it. As soon as I add the include path again it succesfully compiles.

Again I use Microsoft Visual C++ 6 SP 6 on Windows XP SP2 and Mysql 4.1.11-nt.
[16 May 2005 18:41] Miguel Solorzano
Please verify if you have a libmysql.dll in the Windows environment
path (Windows..system32). I use the static library mysqlclient.lib.
So you are linking with 4.1.1 libmysql.lib and the application
loading another older one.
[18 May 2005 19:33] Miguel Solorzano
Thank you for the feedback.
[19 Dec 2006 11:16] Yipeng Huang
I am facing the exact same problem with MYSQL 5.0, I believe I may have accidently changed the version of libmysql.dll/lib. 

Where can I download a compatible version?