/* ========================================================================== * test.c -- Reproduce MYSQL client library bug with bulk inserts in * prepared statements * ========================================================================== */ #include #include #include #include /* DB Connection Params */ #define DBHOST "localhost" #define DBUSER "" #define DBPASS "" #define DBNAME "" #define DBPORT 3306 #define START_ROWS 16 /* Number of value sets to start with */ #define MAX_ROW_INSERTS 300 /* Max number of value sets to end with */ #define ROW_SIZE 250 int main (int argc, char **argv) { int lc; int lc2; int lc3; int bind_index; MYSQL *DB; MYSQL_STMT *db_stmt; MYSQL_BIND *db_bind; u_long qlength; char *query; char *paramstr; char *qptr; float nenfit2[250] = { 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.5000000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000, 0.2500000 }; /* Connect to the database */ if (!(DB = mysql_init(NULL))) { fprintf(stderr, "mysql_init() failed\n"); exit(1); } if (!(mysql_real_connect(DB, DBHOST, DBUSER, DBPASS, DBNAME, DBPORT, NULL, 0))) { fprintf(stderr, "DB Connect Failed (%s)\n", mysql_error(DB)); exit(1); } /* allocate space for the bind parameter arrays and query strings */ db_bind = (MYSQL_BIND *) malloc(MAX_ROW_INSERTS * ROW_SIZE * sizeof(MYSQL_BIND)); if (!db_bind) { fprintf(stderr, "Can't allocate enough memory for query structs\n"); exit(1); } paramstr = (char *) malloc(1024); query = (char *) malloc(50 + (MAX_ROW_INSERTS * 1024)); /* create the test table, if it doesn't already exist */ sprintf(query, "create table if not exists prep_test (c1 float, c2 float, c3 float,\ c4 float, c5 float, c6 float, c7 float, c8 float, c9 float, c10 float, c11 float,\ c12 float, c13 float, c14 float, c15 float, c16 float, c17 float, c18 float, c19 float,\ c20 float, c21 float, c22 float, c23 float, c24 float, c25 float, c26 float, c27 float,\ c28 float, c29 float, c30 float, c31 float, c32 float, c33 float, c34 float, c35 float,\ c36 float, c37 float, c38 float, c39 float, c40 float, c41 float, c42 float, c43 float,\ c44 float, c45 float, c46 float, c47 float, c48 float, c49 float, c50 float, c51 float,\ c52 float, c53 float, c54 float, c55 float, c56 float, c57 float, c58 float, c59 float,\ c60 float, c61 float, c62 float, c63 float, c64 float, c65 float, c66 float, c67 float,\ c68 float, c69 float, c70 float, c71 float, c72 float, c73 float, c74 float, c75 float,\ c76 float, c77 float, c78 float, c79 float, c80 float, c81 float, c82 float, c83 float,\ c84 float, c85 float, c86 float, c87 float, c88 float, c89 float, c90 float, c91 float,\ c92 float, c93 float, c94 float, c95 float, c96 float, c97 float, c98 float, c99 float,\ c100 float, c101 float, c102 float, c103 float, c104 float, c105 float, c106 float,\ c107 float, c108 float, c109 float, c110 float, c111 float, c112 float, c113 float,\ c114 float, c115 float, c116 float, c117 float, c118 float, c119 float, c120 float,\ c121 float, c122 float, c123 float, c124 float, c125 float, c126 float, c127 float,\ c128 float, c129 float, c130 float, c131 float, c132 float, c133 float, c134 float,\ c135 float, c136 float, c137 float, c138 float, c139 float, c140 float, c141 float,\ c142 float, c143 float, c144 float, c145 float, c146 float, c147 float, c148 float,\ c149 float, c150 float, c151 float, c152 float, c153 float, c154 float, c155 float,\ c156 float, c157 float, c158 float, c159 float, c160 float, c161 float, c162 float,\ c163 float, c164 float, c165 float, c166 float, c167 float, c168 float, c169 float,\ c170 float, c171 float, c172 float, c173 float, c174 float, c175 float, c176 float,\ c177 float, c178 float, c179 float, c180 float, c181 float, c182 float, c183 float,\ c184 float, c185 float, c186 float, c187 float, c188 float, c189 float, c190 float,\ c191 float, c192 float, c193 float, c194 float, c195 float, c196 float, c197 float,\ c198 float, c199 float, c200 float, c201 float, c202 float, c203 float, c204 float,\ c205 float, c206 float, c207 float, c208 float, c209 float, c210 float, c211 float,\ c212 float, c213 float, c214 float, c215 float, c216 float, c217 float, c218 float,\ c219 float, c220 float, c221 float, c222 float, c223 float, c224 float, c225 float,\ c226 float, c227 float, c228 float, c229 float, c230 float, c231 float, c232 float,\ c233 float, c234 float, c235 float, c236 float, c237 float, c238 float, c239 float,\ c240 float, c241 float, c242 float, c243 float, c244 float, c245 float, c246 float,\ c247 float, c248 float, c249 float, c250 float)"); if (mysql_query(DB, query)) { fprintf(stderr, "Table creation query failed: %s\n", mysql_error(DB)); } /* setup a string for the value parameters */ sprintf(paramstr, "("); for (lc = 1; lc < ROW_SIZE; lc++) { strcat(paramstr, "?,"); } strcat(paramstr, "?)"); db_stmt = mysql_stmt_init(DB); /* build a query for each set of bulk inserts, so we can see where it fails */ for (lc = START_ROWS; lc <= MAX_ROW_INSERTS; lc++) { sprintf(query, "INSERT INTO prep_test values %s", paramstr); qptr = query + strlen(query); for (lc2 = 1; lc2 < lc; lc2++) { strcpy(qptr, ","); qptr++; strcat(qptr, paramstr); qptr += 501; } /* fprintf(stderr, "query: %s\n", query); */ qlength = strlen(query); if (mysql_stmt_prepare(db_stmt, query, qlength)) { fprintf(stderr, "Statement Prep failed (%s)\n", mysql_stmt_error(db_stmt)); exit(1); } fprintf(stderr, "Insert: %d rows query: %lub params: (data) %db (expected) %d (prep'd) %lu\n", lc, qlength, 4 * lc * ROW_SIZE, lc * 250, mysql_stmt_param_count(db_stmt)); /* Setup the parameter bindings */ bind_index = 0; for (lc2 = 0; lc2 < lc; lc2++) { for (lc3 = 0; lc3 < ROW_SIZE; lc3++) { db_bind[bind_index].buffer_type = MYSQL_TYPE_FLOAT; db_bind[bind_index].buffer = &nenfit2[lc3]; db_bind[bind_index].length = 0; db_bind[bind_index].is_null = 0; bind_index++; } } /* bind the parameter array and execute the query */ if (mysql_stmt_bind_param(db_stmt, db_bind)) { fprintf(stderr, "parameter binding failed (set %d) [%s]\n", lc, mysql_stmt_error(db_stmt)); exit(1); } if (mysql_stmt_execute(db_stmt)) { fprintf(stderr, "stmt exec failed (sets %d) [%s]\n", lc, mysql_stmt_error(db_stmt)); exit(1); } } /* Disconnect from the Database */ mysql_close(DB); free(db_bind); free(paramstr); free(query); exit(0); } /* ========================================================================= */