//RUN //DROP TABLE IF EXISTS testbug22290; //CREATE TABLE testbug22290 ( // `id` int(11) NOT NULL default '1', // `cost` decimal(10,2) NOT NULL, // PRIMARY KEY (`id`) //) ENGINE=InnoDB DEFAULT CHARSET=utf8; //INSERT INTO testbug22290 (`id`,`cost`) VALUES (1,'1.00'); //built using: // gcc bug22290.c -o bug22290 -L/home/Tonci/bkwork/copyto/mysql-5-0/lib/mysql -I/home/Tonci/bkwork/copyto/mysql-5-0/include/mysql -lmysqlclient_r -lz //run using: // ./bug22297 //LD_LIBRARY_PATH=/home/Tonci/bkwork/copyto/mysql-5-0/lib/mysql ./bug22290 //RESULTS: //mysql> select * from testbug22290; //+----+------+ //| id | cost | //+----+------+ //| 1 | 2.11 | //+----+------+ //1 row in set (0.00 sec) // //FROM the test case //Connected! // //Running {update testbug22290 set cost = cost + ? where id = 1} // // total parameters in UPDATE: 1 // //Exec prep stmt // total affected rows(UPDATE 1): 1 // //mysql_stmt_result_metadata(), returned no meta information //Segmentation fault #include #include #include #include #include #include #include //#include "mysql.h" #include #include #include #include #include #include #define check_execute(stmt, r) \ { \ if (r) \ mysterror(stmt, NULL); \ DIE_UNLESS(r == 0);\ } /* This is to be what mysql_query() is for mysql_real_query(), for mysql_simple_prepare(): a variant without the 'length' parameter. */ MYSQL_STMT *STDCALL mysql_simple_prepare(MYSQL *mysql, const char *query) { MYSQL_STMT *stmt= mysql_stmt_init(mysql); if (stmt && mysql_stmt_prepare(stmt, query, strlen(query))) { mysql_stmt_close(stmt); return 0; } return stmt; } int main(int argc, const char *argv[]) { MYSQL *mysql; MYSQL_RES *r=NULL; MYSQL_STMT *stmt; int rc, i; int int_data, param_count, column_count; char vc_data1[20], vc_data2[20]; //FOR FETCHING AS String char query[50]; long flt_data2;//double resclo2; MYSQL_BIND bindin[1], bindout[2]; MYSQL_ROW w; my_bool errorin[1], error[2]; unsigned long lengthin[1], length[2]; my_bool is_nullin[1], is_null[2]; MYSQL_RES *prepare_meta_result; double pinput, routput; mysql = mysql_init(NULL); if (!mysql_real_connect(mysql,"localhost","root","","test",3307, NULL, CLIENT_FOUND_ROWS|CLIENT_MULTI_STATEMENTS)) { printf("mysql_real_connect failed: %s\n",mysql_error(mysql)); exit(-1); } printf("Connected!\n"); stmt= mysql_stmt_init(mysql); if (!stmt) { printf("\nmysql_stmt_init(), out of memory\n"); exit(-1); } printf("\nRunning %s\n\n","{update testbug22290 set cost = cost + ? where id = 1}"); strmov(query, "update testbug22290 set cost = cost + ? where id = 1"); stmt= mysql_simple_prepare(mysql, query); //mysql_stmt_prepare(stmt, query, strlen(query)); //DOESN'T WORK EITHER param_count= mysql_stmt_param_count(stmt); fprintf(stdout, " total parameters in UPDATE: %d\n", param_count); if (param_count != 1) /* validate parameter count */ { fprintf(stderr, " invalid parameter count returned by MySQL\n"); exit(0); } bzero((char*) bindin, sizeof(bindin)); memset(bindin, 0, sizeof(bindin)); bzero((char*) bindout, sizeof(bindout)); memset(bindout, 0, sizeof(bindout)); pinput = 1.11; /* double */ bindin[0].buffer_type= MYSQL_TYPE_NEWDECIMAL; bindin[0].buffer= (void *)&pinput;//char bindin[0].length= &lengthin[0]; bindin[0].is_null= &is_nullin[0]; is_null[0]= 0; if (mysql_stmt_bind_param(stmt, bindin)) { fprintf(stderr, " mysql_stmt_bind_param() failed\n"); fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); exit(-1); } printf("\nExec prep stmt\n"); if (mysql_stmt_execute(stmt)) { printf("mysql_stmt_execute(), failed\n"); printf(" %s\n", mysql_stmt_error(stmt)); exit(-1); } /* Get the total number of affected rows */ rc= mysql_stmt_affected_rows(stmt); fprintf(stdout, " total affected rows(UPDATE 1): %lu\n", (unsigned long) rc); if (rc != 1) /* validate affected rows */ { fprintf(stderr, " invalid affected rows by MySQL\n"); exit(-1); } prepare_meta_result = mysql_stmt_result_metadata(stmt); if (!prepare_meta_result) { printf("\nmysql_stmt_result_metadata(), returned no meta information\n"); fprintf("%s\n", mysql_stmt_error(stmt)); exit(-1); } /* Get total columns in the query */ column_count= mysql_num_fields(prepare_meta_result); fprintf(stdout, " total columns in statement: %d\n", column_count); if (column_count != 2) /* validate column count */ { fprintf(stderr, " invalid column count returned by MySQL\n"); exit(0); } printf("\nInit result buffers before fetch\n"); //BIND COLS!!!! bindout[0].buffer_type= MYSQL_TYPE_LONG; //int COL bindout[0].buffer= (char *)&flt_data2;//int_data; bindout[0].is_null= &is_null[0]; bindout[0].length= &length[0]; bindout[0].error= &error[0]; bindout[1].buffer_type= MYSQL_TYPE_NEWDECIMAL; bindout[1].buffer= (char *)&routput; bindout[1].is_null= &is_null[1]; bindout[1].length= &length[1]; bindout[1].error= &error[1]; printf("\nBind result to buffer before fetch\n"); if (mysql_stmt_bind_result(stmt, bindout)) { printf(" mysql_stmt_bind_result() failed\n"); printf(" %s\n", mysql_stmt_error(stmt)); exit(-1); } printf("\nBuffer result\n"); if (mysql_stmt_store_result(stmt)) { printf(" mysql_stmt_store_result() failed\n"); printf(" %s\n", mysql_stmt_error(stmt)); exit(-1); } /* Fetch all rows */ i= 0; fprintf(stdout, "Fetching results ...\n"); while (!mysql_stmt_fetch(stmt)) { i++; fprintf(stdout, " row %d\n", i); /* column 1 */ fprintf(stdout, " column1 (varchar) : "); if (is_null[0]) fprintf(stdout, " NULL(%ld)\n", length[0]); else fprintf(stdout, " %s(%ld)\n", vc_data1, length[0]); /* column 2 */ fprintf(stdout, " column2 (long) : "); if (is_null[1]) fprintf(stdout, " NULL\n"); else fprintf(stdout, " %g(%ld)\n", flt_data2, length[1]);//%s(%ld) fprintf(stdout, "\n"); } /* Validate rows fetched */ fprintf(stdout, " total rows fetched: %d\n", i); if (i != 1) { fprintf(stderr, " MySQL failed to return all rows\n"); exit(0); } /* Free the prepared result metadata */ mysql_free_result(prepare_meta_result); printf("\nCLOSE\n"); /* Close the statement */ if (mysql_stmt_close(stmt)) { fprintf(stderr, " failed while closing the statement\n"); fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); exit(0); } exit(EXIT_SUCCESS); }