Bug #655 c-api using prepared statements fail to link
Submitted: 14 Jun 2003 3:54 Modified: 17 Jun 2003 12:41
Reporter: Sidney Kelly Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:4.1alpha OS:Windows (windows xp pro)
Assigned to: Bugs System CPU Architecture:Any

[14 Jun 2003 3:54] Sidney Kelly
Description:
Using excerpted C source code from the mysql 4.1 doc, I get unresolved externals at link time when attempting to use prepared style calls. MS Visual Studio 6.0/SP5. The program may not be 100% functional but it simply must link to even begin debugging for function.

Example of unresolved at link time:
: unresolved external symbol _mysql_stmt_close@4
: unresolved external symbol _mysql_stmt_affected_rows@4
: unresolved external symbol _mysql_execute@4
: unresolved external symbol _mysql_stmt_error@4
: unresolved external symbol _mysql_bind_param@8
: unresolved external symbol _mysql_param_count@4
: unresolved external symbol _mysql_prepare@12
: unresolved external symbol _mysql_autocommit@8

How to repeat:
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<mysql.h>
main ()
   {
   MYSQL_BIND bind[3];
   MYSQL_STMT *stmt;
   my_ulonglong affected_rows;
   long length;
   unsigned int param_count;
   int int_data;
   short small_data;
   char str_data[50], query[255];
   my_bool is_null;
MYSQL *mysql;
 
/* Set autocommit mode to true */
   mysql_autocommit( mysql, 1 );
   if ( mysql_query(mysql,"DROP TABLE IF EXISTS test_tagble") )
       {
       fprintf(stderr, "\n drop table failed");
       fprintf(stderr, "\n %s", mysql_error(mysql));
       exit(0);
       }
   if ( mysql_query( mysql,"CREATE TABLE test_table(col1 INT, col2 varchar(50), col3 smallint, col4 
timestamp(14))") )
       {
       fprintf(stderr, "\n create table failed");
       fprintf(stderr, "\n %s", mysql_error(mysql));
       exit(0);
       }
/* Prepare a insert query with 3 parameters */
   strmov(query, "INSERT INTO test_table(col1,col2,col3) values(?,?,?)");
   if ( !(stmt = mysql_prepare(mysql, query, strlen(query))) )
       {
       fprintf(stderr, "\n prepare, insert failed");
       fprintf(stderr, "\n %s", mysql_error(mysql));
       exit(0);
       }
   fprintf(stdout, "\n prepare, insert successful");
/* Get the parameter count from the statement */
   param_count= mysql_param_count(stmt);
   fprintf(stdout, "\n total parameters in insert: %d", param_count);
   if ( param_count != 3 ) /* validate parameter count */
       {
       fprintf(stderr, "\n invalid parameter count returned by MySQL");
       exit(0);
       }
/* Bind the data for the parameters */
/* INTEGER PART */
   bind[0].buffer_type= MYSQL_TYPE_LONG;
   bind[0].buffer= (char *)&int_data;
   bind[0].is_null= 0;
   bind[0].length= 0;
/* STRING PART */
   bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
   bind[1].buffer= (char *)str_data;
   bind[1].buffer_length= sizeof(str_data);
   bind[1].is_null= 0;
   bind[1].length= 0;
/* SMALLINT PART */
   bind[2].buffer_type= MYSQL_TYPE_SHORT;
   bind[2].buffer= (char *)&small_data;
   bind[2].is_null= &is_null;
   bind[2].length= 0;
   is_null= 0;
/* Bind the buffers */
   if ( mysql_bind_param(stmt, bind) )
       {
       fprintf(stderr, "\n param bind failed");
       fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
       exit(0);
       }
/* Specify the data */
   int_data= 10; /* integer */
   strcpy(str_data,"MySQL"); /* string */
/* INSERT SMALLINT data as NULL */
   is_null= 1;
/* Execute the insert statement - 1*/
   if ( mysql_execute(stmt) )
       {
       fprintf(stderr, "\n execute 1 failed");
       fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
       fprintf(stderr, "\n send a bug report to bugs@lists.mysql.com, by asking why this is" );
       exit(0);
       }
/* Get the total rows affected */
   affected_rows= mysql_stmt_affected_rows(stmt);
   fprintf(stdout, "\n total affected rows: %lld", affected_rows);
   if ( affected_rows != 1 ) /* validate affected rows */
       {
       fprintf(stderr, "\n invalid affected rows by MySQL");
       exit(0);
       }
/* Re-execute the insert, by changing the values */
   int_data= 1000;
   strcpy(str_data,"The most popular open source database");
   small_data= 1000; /* smallint */
   is_null= 0; /* reset NULL */
/* Execute the insert statement - 2*/
   if ( mysql_execute(stmt) )
       {
       fprintf(stderr, "\n execute 2 failed");
       fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
       exit(0);
       }
/* Get the total rows affected */
   affected_rows= mysql_stmt_affected_rows(stmt);
   fprintf(stdout, "\n total affected rows: %lld", affected_rows);
   if ( affected_rows != 1 ) /* validate affected rows */
       {
       fprintf(stderr, "\n invalid affected rows by MySQL");
       exit(0);
       }
/* Close the statement */
   if ( mysql_stmt_close(stmt) )
       {
       fprintf(stderr, "\n failed while closing the statement");
       fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
       exit(0);
       }
/* DROP THE TABLE */
   if ( mysql_query(mysql,"DROP TABLE test_table") )
       {
       fprintf(stderr, "\n drop table failed");
       fprintf(stderr, "\n %s", mysql_error(mysql));
       exit(0);
       }
   fprintf(stdout, "Success, MySQL prepared statements are working!!!");
   exit (0);
   }

Suggested fix:
Tried to re-compile on Windows platform, but there was a missing file in the 4.1 alpha source for Windows and it failed to re-compile. MS Visual Studio 6.0/SP5

Also, there was a small problem with a declaration in the prepared statement example provided in the 4.1 api documentation:

   ulonglong affected_rows;

Should be:
   my_ulonglong affected_rows;

Also missing a declaration for:
   MYSQL *mysql;
[14 Jun 2003 5:18] MySQL Verification Team
You either have to include libmysql in the project and / or to set proper options for underlining.
[14 Jun 2003 5:46] MySQL Verification Team
For to resolve the symbols missed please add the mysqlclient.lib
for your project also in your sample:

#include<my_global.h>
#include<m_string.h>

however I found that mysqlclient.lib has some symbols missed too.

For to resolve the problem above, please download the source release,
and compile yourself the mysqlclient.lib
[14 Jun 2003 18:41] Sidney Kelly
Per suggestion I added: 
#include<my_global.h>
 
#include<m_string.h>
[14 Jun 2003 18:56] Sidney Kelly
I tried your suggestion I added: 
    #include<my_global.h>
    #include<m_string.h>
Also rebuilt mysqlclient.lib The problem of undefined symbols got worse, about 60 errors now. I don't see how I could be so far off the mark.

Can you kindly confirm that you have 4.1.0 running on MS-windows platform using prepared statements?
[14 Jun 2003 20:00] MySQL Verification Team
I compiled your sample.
Also you need to set the code generation for example for
debug version use debug multithreaded. When linking the
mysqlclient.lib use the debug version for your debug version
and the optimized one for the optimized project.
[17 Jun 2003 3:24] Sidney Kelly
I've tried all suggestions so far. Still unresolved symbols. I noticed that the libmysql.def files in the 4.1alpha distribution indicate they are from version 4.0 not 4.1

Rebuilding libmysql does not seem to create new libmysql.def file. What is possibly going on?
[17 Jun 2003 4:45] MySQL Verification Team
Well I compiled your example against the static library
mysqclient.lib instead of libmysql.lib for to use the
libmysql.dll.
Then you have the option to link with the static library
or rebuild libmysql.dll adding the missed functions to
the libmysql.def file.
[17 Jun 2003 12:41] Venu Anuganti
Thank you for your bug report. This issue has been fixed in the latest
development tree for that product. You can find more information about
accessing our development trees at 
    http://www.mysql.com/doc/en/Installing_source_tree.html

Hi !! 
 
Its all becuase of libmysql.def file is not updated for 4.1.0-alpha release. Looks like some how 
it got messed out and missed the updates on new APIs for first alpha release. 
 
But it got fixed long back in the 'BitKeeper' source. So, inorder to make things go smother, you 
need to get the letest source from 'BitKeeper'. 
 
For more information on how to build Windows source package from BitKeeper, please refer to 
'INSTALL-WIN-SOURCE' from the mysql-4.1 bk clone tree. 
 
Thanks