1 #include <mysql.h>
2 #include <rudiments/process.h>
3 #include <rudiments/charstring.h>
4 #include <rudiments/bytestring.h>
5 #include <rudiments/environment.h>
6 #include <rudiments/stringbuffer.h>
7 #include <rudiments/stdio.h>
8 #include <config.h>
9 
10 // MySQL 8+ doesn't have my_bool, but MariaDB 10+ does
11 #ifndef MARIADB_BASE_VERSION
12 	#if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID>=80000
13 		typedef bool my_bool;
14 	#endif
15 #endif
16 
17 MYSQL		mysql;
18 MYSQL_RES	*result;
19 MYSQL_FIELD	*field;
20 MYSQL_ROW	row;
21 
checkSuccess(const char * value,const char * success)22 void checkSuccess(const char *value, const char *success) {
23 
24 	if (!success) {
25 		if (!value) {
26 			stdoutput.printf("success ");
27 			return;
28 		} else {
29 			stdoutput.printf("\"%s\"!=\"%s\"\n",value,success);
30 			stdoutput.printf("failure ");
31 stdoutput.printf("\n%s\n",mysql_error(&mysql));
32 			process::exit(1);
33 		}
34 	}
35 
36 	if (!charstring::compare(value,success)) {
37 		stdoutput.printf("success ");
38 	} else {
39 		stdoutput.printf("\"%s\"!=\"%s\"\n",value,success);
40 		stdoutput.printf("failure ");
41 		process::exit(1);
42 	}
43 }
44 
checkSuccess(int value,int success)45 void checkSuccess(int value, int success) {
46 
47 	if (value==success) {
48 		stdoutput.printf("success ");
49 	} else {
50 		stdoutput.printf("\"%d\"!=\"%d\"\n",value,success);
51 		stdoutput.printf("failure ");
52 stdoutput.printf("\n%s\n",mysql_error(&mysql));
53 		process::exit(1);
54 	}
55 }
56 
main(int argc,char ** argv)57 int	main(int argc, char **argv) {
58 
59 	#ifdef HAVE_MYSQL_STMT_PREPARE
60 
61 	const char	*host="127.0.0.1";
62 	const char	*port;
63 	const char	*socket;
64 	const char	*user;
65 	const char	*password;
66 	const char	*db;
67 	if (!charstring::isNullOrEmpty(environment::getValue("LD_PRELOAD"))) {
68 		port="9000";
69 		socket="/tmp/test.socket";
70 		user="test";
71 		password="test";
72 		db="";
73 	} else {
74 		// to run against a real mysql instance, provide a host name
75 		// eg: ./mysql db64
76 		if (argc==2) {
77 			host=argv[1];
78 		}
79 		port="3306";
80 		socket="/var/lib/mysql/mysql.sock";
81 		user="testuser";
82 		password="testpassword";
83 		db="testdb";
84 	}
85 
86 
87 	stdoutput.printf("\n============ Traditional API ============\n\n");
88 
89 	#ifdef HAVE_MYSQL_REAL_CONNECT_FOR_SURE
90 		stdoutput.printf("mysql_init\n");
91 		checkSuccess((long)mysql_init(&mysql),(long)&mysql);
92 		stdoutput.printf("\n");
93 		stdoutput.printf("mysql_real_connect\n");
94 		#if MYSQL_VERSION_ID>=32200
95 			checkSuccess((long)mysql_real_connect(
96 						&mysql,host,user,password,db,
97 						charstring::toInteger(port),
98 						socket,0),(long)&mysql);
99 		#else
100 			checkSuccess((long)mysql_real_connect(
101 						&mysql,host,user,password,
102 						charstring::toInteger(port),
103 						socket,0),(long)&mysql);
104 			if (!charstring::isNullOrEmpty(db)) {
105 				checkSuccess(mysql_select_db(&mysql,db),0);
106 			}
107 		#endif
108 	#else
109 		checkSuccess((long)mysql_connect(&mysql,host,
110 						user,password),
111 						(long)mysql);
112 	#endif
113 	stdoutput.printf("\n");
114 
115 	#ifdef HAVE_MYSQL_PING
116 	stdoutput.printf("mysql_ping\n");
117 	checkSuccess(mysql_ping(&mysql),0);
118 	stdoutput.printf("\n");
119 	#endif
120 
121 	stdoutput.printf("mysql_character_set_name:\n");
122 	#if !defined(MARIADB_BASE_VERSION) && \
123 		defined(MYSQL_VERSION_ID) && \
124 		MYSQL_VERSION_ID>=80000
125 	checkSuccess((char *)mysql_character_set_name(&mysql),"utf8mb4");
126 	#else
127 	const char	*charset=mysql_character_set_name(&mysql);
128 	checkSuccess(!charstring::compare(charset,"latin1") ||
129 				!charstring::compare(charset,"utf8"),true);
130 	#endif
131 	stdoutput.printf("\n");
132 
133 	stdoutput.printf("mysql_list_dbs\n");
134 	result=mysql_list_dbs(&mysql,NULL);
135 	// FIXME: crashes with drop-in lib
136 	//checkSuccess(mysql_field_count(&mysql),1);
137 	checkSuccess(mysql_num_fields(result),1);
138 	field=mysql_fetch_field_direct(result,0);
139 	if (charstring::isNullOrEmpty(environment::getValue("LD_PRELOAD"))) {
140 		checkSuccess(
141 			!charstring::compare(field->name,"Database") ||
142 			!charstring::compare(field->name,"Database (%)"),1);
143 	} else {
144 		// sqlrelay calls this column schema_name rather
145 		// than Database so the drop-in lib does too
146 		checkSuccess(field->name,"schema_name");
147 	}
148 	row=mysql_fetch_row(result);
149 	checkSuccess(row[0],"information_schema");
150 	row=mysql_fetch_row(result);
151 	checkSuccess(row[0],"testdb");
152 	row=mysql_fetch_row(result);
153 	checkSuccess((row==NULL),1);
154 	mysql_free_result(result);
155 	stdoutput.printf("\n");
156 
157 	const char	*query="drop table testdb.testtable";
158 	mysql_real_query(&mysql,query,charstring::length(query));
159 
160 	stdoutput.printf("mysql_real_query: create\n");
161 	query="create table testdb.testtable (testtinyint tinyint, testsmallint smallint, testmediumint mediumint, testint int, testbigint bigint, testfloat float, testreal real, testdecimal decimal(2,1), testdate date, testtime time, testdatetime datetime, testyear year, testchar char(40), testtext text, testvarchar varchar(40), testtinytext tinytext, testmediumtext mediumtext, testlongtext longtext, testtimestamp timestamp)";
162 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
163 	checkSuccess(mysql_info(&mysql),NULL);
164 	stdoutput.printf("\n");
165 
166 	stdoutput.printf("mysql_list_tables\n");
167 	result=mysql_list_tables(&mysql,NULL);
168 	// FIXME: crashes with drop-in lib
169 	//checkSuccess(mysql_field_count(&mysql),1);
170 	checkSuccess(mysql_num_fields(result),1);
171 	field=mysql_fetch_field_direct(result,0);
172 	if (charstring::isNullOrEmpty(environment::getValue("LD_PRELOAD"))) {
173 		checkSuccess(
174 		!charstring::compare(field->name,"Tables_in_testdb") ||
175 		!charstring::compare(field->name,"Tables_in_testdb (%)"),1);
176 	} else {
177 		// sqlrelay calls this column schema_name rather
178 		// than Database so the drop-in lib does too
179 		checkSuccess(field->name,"table_name");
180 	}
181 	row=mysql_fetch_row(result);
182 	checkSuccess(row[0],"testtable");
183 	row=mysql_fetch_row(result);
184 	checkSuccess((row==NULL),1);
185 	mysql_free_result(result);
186 	stdoutput.printf("\n");
187 
188 	stdoutput.printf("mysql_list_fields\n");
189 	result=mysql_list_fields(&mysql,"testtable",NULL);
190 	// FIXME: crashes with drop-in lib
191 	//checkSuccess(mysql_field_count(&mysql),19);
192 	checkSuccess(mysql_num_fields(result),19);
193 	stdoutput.printf("\n");
194 
195 	stdoutput.printf("tinyint\n");
196 	field=mysql_fetch_field_direct(result,0);
197 	checkSuccess(field->name,"testtinyint");
198 	/*if (argc==2) {
199 		checkSuccess(field->org_name,"testtinyint");
200 		checkSuccess(field->table,"testtable");
201 		checkSuccess(field->org_table,"testtable");
202 		checkSuccess(field->db,"testdb");
203 	}*/
204 	checkSuccess(field->catalog,"def");
205 	checkSuccess(field->def,NULL);
206 	checkSuccess(field->length,4);
207 	checkSuccess(field->max_length,0);
208 	checkSuccess(field->name_length,11);
209 	/*if (argc==2) {
210 		checkSuccess(field->org_name_length,11);
211 		checkSuccess(field->db_length,6);
212 	}*/
213 	checkSuccess(field->catalog_length,3);
214 	// Some client API's don't set this if def is NULL
215 	//checkSuccess(field->def_length,0);
216 	checkSuccess(field->flags,NUM_FLAG);
217 	checkSuccess(field->decimals,0);
218 	/*if (argc==2) {
219 		checkSuccess(field->charsetnr,63);
220 	}*/
221 	checkSuccess(field->type,MYSQL_TYPE_TINY);
222 	stdoutput.printf("\n");
223 
224 	stdoutput.printf("smallint\n");
225 	field=mysql_fetch_field_direct(result,1);
226 	checkSuccess(field->name,"testsmallint");
227 	checkSuccess(field->length,6);
228 	checkSuccess(field->flags,NUM_FLAG);
229 	checkSuccess(field->type,MYSQL_TYPE_SHORT);
230 	stdoutput.printf("\n");
231 
232 	stdoutput.printf("mediumint\n");
233 	field=mysql_fetch_field_direct(result,2);
234 	checkSuccess(field->name,"testmediumint");
235 	checkSuccess(field->length,9);
236 	checkSuccess(field->flags,NUM_FLAG);
237 	checkSuccess(field->type,MYSQL_TYPE_INT24);
238 	stdoutput.printf("\n");
239 
240 	stdoutput.printf("int\n");
241 	field=mysql_fetch_field_direct(result,3);
242 	checkSuccess(field->name,"testint");
243 	checkSuccess(field->length,11);
244 	checkSuccess(field->flags,NUM_FLAG);
245 	checkSuccess(field->type,MYSQL_TYPE_LONG);
246 	stdoutput.printf("\n");
247 
248 	stdoutput.printf("bigint\n");
249 	field=mysql_fetch_field_direct(result,4);
250 	checkSuccess(field->name,"testbigint");
251 	checkSuccess(field->length,20);
252 	checkSuccess(field->flags,NUM_FLAG);
253 	checkSuccess(field->type,MYSQL_TYPE_LONGLONG);
254 	stdoutput.printf("\n");
255 
256 	stdoutput.printf("float\n");
257 	field=mysql_fetch_field_direct(result,5);
258 	checkSuccess(field->name,"testfloat");
259 	checkSuccess(field->length,12);
260 	checkSuccess(field->flags,NUM_FLAG);
261 	checkSuccess(field->type,MYSQL_TYPE_FLOAT);
262 	stdoutput.printf("\n");
263 
264 	stdoutput.printf("real\n");
265 	field=mysql_fetch_field_direct(result,6);
266 	checkSuccess(field->name,"testreal");
267 	checkSuccess(field->length,22);
268 	checkSuccess(field->flags,NUM_FLAG);
269 	checkSuccess(field->type,MYSQL_TYPE_DOUBLE);
270 	stdoutput.printf("\n");
271 
272 	stdoutput.printf("decimal\n");
273 	field=mysql_fetch_field_direct(result,7);
274 	checkSuccess(field->name,"testdecimal");
275 	checkSuccess(field->length,4);
276 	// MariaDB LGPL connector doesn't always get this right
277 	//checkSuccess(field->flags,NUM_FLAG);
278 	checkSuccess(field->type,MYSQL_TYPE_NEWDECIMAL);
279 	checkSuccess(field->decimals,1);
280 	stdoutput.printf("\n");
281 
282 	stdoutput.printf("date\n");
283 	field=mysql_fetch_field_direct(result,8);
284 	checkSuccess(field->name,"testdate");
285 	checkSuccess(field->length,10);
286 	checkSuccess(field->flags,BINARY_FLAG);
287 	checkSuccess(field->type,MYSQL_TYPE_DATE);
288 	stdoutput.printf("\n");
289 
290 	stdoutput.printf("time\n");
291 	field=mysql_fetch_field_direct(result,9);
292 	checkSuccess(field->name,"testtime");
293 	checkSuccess(field->length,10);
294 	checkSuccess(field->flags,BINARY_FLAG);
295 	checkSuccess(field->type,MYSQL_TYPE_TIME);
296 	stdoutput.printf("\n");
297 
298 	stdoutput.printf("datetime\n");
299 	field=mysql_fetch_field_direct(result,10);
300 	checkSuccess(field->name,"testdatetime");
301 	checkSuccess(field->length,19);
302 	checkSuccess(field->flags,BINARY_FLAG);
303 	checkSuccess(field->type,MYSQL_TYPE_DATETIME);
304 	stdoutput.printf("\n");
305 
306 	stdoutput.printf("year\n");
307 	field=mysql_fetch_field_direct(result,11);
308 	checkSuccess(field->name,"testyear");
309 	checkSuccess(field->length,4);
310 	checkSuccess(field->flags,NUM_FLAG|UNSIGNED_FLAG|ZEROFILL_FLAG);
311 	checkSuccess(field->type,MYSQL_TYPE_YEAR);
312 	stdoutput.printf("\n");
313 
314 	stdoutput.printf("char\n");
315 	field=mysql_fetch_field_direct(result,12);
316 	checkSuccess(field->name,"testchar");
317 	checkSuccess(field->length,40);
318 	checkSuccess(field->flags,0);
319 	checkSuccess(field->type,MYSQL_TYPE_STRING);
320 	stdoutput.printf("\n");
321 
322 	stdoutput.printf("text\n");
323 	field=mysql_fetch_field_direct(result,13);
324 	checkSuccess(field->name,"testtext");
325 	checkSuccess(field->length,65535);
326 	checkSuccess(field->flags,BLOB_FLAG);
327 	checkSuccess(field->type,MYSQL_TYPE_BLOB);
328 	stdoutput.printf("\n");
329 
330 	stdoutput.printf("varchar\n");
331 	field=mysql_fetch_field_direct(result,14);
332 	checkSuccess(field->name,"testvarchar");
333 	checkSuccess(field->length,40);
334 	checkSuccess(field->flags,0);
335 	checkSuccess(field->type,MYSQL_TYPE_VAR_STRING);
336 	stdoutput.printf("\n");
337 
338 	stdoutput.printf("tinytext\n");
339 	field=mysql_fetch_field_direct(result,15);
340 	checkSuccess(field->name,"testtinytext");
341 	checkSuccess(field->length,255);
342 	checkSuccess(field->flags,BLOB_FLAG);
343 	checkSuccess(field->type,MYSQL_TYPE_BLOB);
344 	stdoutput.printf("\n");
345 
346 	stdoutput.printf("mediumtext\n");
347 	field=mysql_fetch_field_direct(result,16);
348 	checkSuccess(field->name,"testmediumtext");
349 	checkSuccess(field->length,16777215);
350 	checkSuccess(field->flags,BLOB_FLAG);
351 	checkSuccess(field->type,MYSQL_TYPE_BLOB);
352 	stdoutput.printf("\n");
353 
354 	stdoutput.printf("longtext\n");
355 	field=mysql_fetch_field_direct(result,17);
356 	checkSuccess(field->name,"testlongtext");
357 	// The length of these can be reported by the db as either
358 	// 2^31-1 or 2^32-1.  It's not clear why it varies, but it can.
359 	//checkSuccess(field->length,2147483647);
360 	checkSuccess(field->flags,BLOB_FLAG);
361 	checkSuccess(field->type,MYSQL_TYPE_BLOB);
362 	stdoutput.printf("\n");
363 
364 	stdoutput.printf("timestamp\n");
365 	field=mysql_fetch_field_direct(result,18);
366 	checkSuccess(field->name,"testtimestamp");
367 	checkSuccess(field->length,19);
368 	checkSuccess(field->flags,
369 			TIMESTAMP_FLAG|
370 			#ifdef ON_UPDATE_NOW_FLAG
371 			ON_UPDATE_NOW_FLAG|
372 			#endif
373 			BINARY_FLAG|
374 			UNSIGNED_FLAG|
375 			NOT_NULL_FLAG);
376 	checkSuccess(field->type,MYSQL_TYPE_TIMESTAMP);
377 	mysql_free_result(result);
378 	stdoutput.printf("\n");
379 
380 	stdoutput.printf("mysql_real_query: insert\n");
381 	query="insert into testdb.testtable values (1,1,1,1,1,1.1,1.1,1.1,'2001-01-01','01:00:00','2001-01-01 01:00:00','2001','char1','text1','varchar1','tinytext1','mediumtext1','longtext1',NULL)";
382 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
383 	checkSuccess(mysql_info(&mysql),NULL);
384 	checkSuccess(mysql_affected_rows(&mysql),1);
385 	stdoutput.printf("\n");
386 
387 	stdoutput.printf("mysql_send_query: insert\n");
388 	query="insert into testdb.testtable values (2,2,2,2,2,2.1,2.1,2.1,'2002-01-01','02:00:00','2002-01-01 02:00:00','2002','char2','text2','varchar2','tinytext2','mediumtext2','longtext2',NULL)";
389 	checkSuccess(mysql_send_query(&mysql,query,charstring::length(query)),0);
390 	checkSuccess(mysql_info(&mysql),NULL);
391 	checkSuccess(mysql_read_query_result(&mysql),0);
392 	checkSuccess(mysql_affected_rows(&mysql),1);
393 	stdoutput.printf("\n");
394 
395 	stdoutput.printf("mysql_real_query: select\n");
396 	query="select * from testdb.testtable";
397 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
398 	checkSuccess(mysql_info(&mysql),NULL);
399 	stdoutput.printf("\n");
400 
401 
402 	stdoutput.printf("mysql_field_count:\n");
403 	checkSuccess(mysql_field_count(&mysql),19);
404 	stdoutput.printf("\n");
405 
406 
407 	stdoutput.printf("mysql_store_result:\n");
408 	result=mysql_store_result(&mysql);
409 
410 	stdoutput.printf("mysql_num_fields:\n");
411 	checkSuccess(mysql_num_fields(result),19);
412 	stdoutput.printf("\n");
413 
414 
415 	stdoutput.printf("mysql_num_rows:\n");
416 	checkSuccess(mysql_num_rows(result),2);
417 	stdoutput.printf("\n");
418 
419 
420 	stdoutput.printf("mysql_field_seek:\n");
421 	checkSuccess(mysql_field_seek(result,0),0);
422 	stdoutput.printf("\n");
423 
424 
425 	stdoutput.printf("mysql_fetch_field/mysql_field_tell:\n");
426 	field=mysql_fetch_field(result);
427 	checkSuccess(mysql_field_tell(result),1);
428 	checkSuccess(field->name,"testtinyint");
429 	// FIXME: field->...
430 	field=mysql_fetch_field(result);
431 	checkSuccess(mysql_field_tell(result),2);
432 	checkSuccess(field->name,"testsmallint");
433 	field=mysql_fetch_field(result);
434 	checkSuccess(mysql_field_tell(result),3);
435 	checkSuccess(field->name,"testmediumint");
436 	field=mysql_fetch_field(result);
437 	checkSuccess(mysql_field_tell(result),4);
438 	checkSuccess(field->name,"testint");
439 	field=mysql_fetch_field(result);
440 	checkSuccess(mysql_field_tell(result),5);
441 	checkSuccess(field->name,"testbigint");
442 	field=mysql_fetch_field(result);
443 	checkSuccess(mysql_field_tell(result),6);
444 	checkSuccess(field->name,"testfloat");
445 	field=mysql_fetch_field(result);
446 	checkSuccess(mysql_field_tell(result),7);
447 	checkSuccess(field->name,"testreal");
448 	field=mysql_fetch_field(result);
449 	checkSuccess(mysql_field_tell(result),8);
450 	checkSuccess(field->name,"testdecimal");
451 	field=mysql_fetch_field(result);
452 	checkSuccess(mysql_field_tell(result),9);
453 	checkSuccess(field->name,"testdate");
454 	field=mysql_fetch_field(result);
455 	checkSuccess(mysql_field_tell(result),10);
456 	checkSuccess(field->name,"testtime");
457 	field=mysql_fetch_field(result);
458 	checkSuccess(mysql_field_tell(result),11);
459 	checkSuccess(field->name,"testdatetime");
460 	field=mysql_fetch_field(result);
461 	checkSuccess(mysql_field_tell(result),12);
462 	checkSuccess(field->name,"testyear");
463 	field=mysql_fetch_field(result);
464 	checkSuccess(mysql_field_tell(result),13);
465 	checkSuccess(field->name,"testchar");
466 	field=mysql_fetch_field(result);
467 	checkSuccess(mysql_field_tell(result),14);
468 	checkSuccess(field->name,"testtext");
469 	field=mysql_fetch_field(result);
470 	checkSuccess(mysql_field_tell(result),15);
471 	checkSuccess(field->name,"testvarchar");
472 	field=mysql_fetch_field(result);
473 	checkSuccess(mysql_field_tell(result),16);
474 	checkSuccess(field->name,"testtinytext");
475 	field=mysql_fetch_field(result);
476 	checkSuccess(mysql_field_tell(result),17);
477 	checkSuccess(field->name,"testmediumtext");
478 	field=mysql_fetch_field(result);
479 	checkSuccess(mysql_field_tell(result),18);
480 	checkSuccess(field->name,"testlongtext");
481 	field=mysql_fetch_field(result);
482 	checkSuccess(mysql_field_tell(result),19);
483 	checkSuccess(field->name,"testtimestamp");
484 	stdoutput.printf("\n");
485 
486 
487 	stdoutput.printf("mysql_field_seek:\n");
488 	checkSuccess(mysql_field_seek(result,0),19);
489 	stdoutput.printf("\n");
490 
491 
492 	stdoutput.printf("mysql_fetch_field_direct:\n");
493 	field=mysql_fetch_field_direct(result,0);
494 	checkSuccess(field->name,"testtinyint");
495 	// FIXME: field->...
496 	field=mysql_fetch_field_direct(result,1);
497 	checkSuccess(field->name,"testsmallint");
498 	field=mysql_fetch_field_direct(result,2);
499 	checkSuccess(field->name,"testmediumint");
500 	field=mysql_fetch_field_direct(result,3);
501 	checkSuccess(field->name,"testint");
502 	field=mysql_fetch_field_direct(result,4);
503 	checkSuccess(field->name,"testbigint");
504 	field=mysql_fetch_field_direct(result,5);
505 	checkSuccess(field->name,"testfloat");
506 	field=mysql_fetch_field_direct(result,6);
507 	checkSuccess(field->name,"testreal");
508 	field=mysql_fetch_field_direct(result,7);
509 	checkSuccess(field->name,"testdecimal");
510 	field=mysql_fetch_field_direct(result,8);
511 	checkSuccess(field->name,"testdate");
512 	field=mysql_fetch_field_direct(result,9);
513 	checkSuccess(field->name,"testtime");
514 	field=mysql_fetch_field_direct(result,10);
515 	checkSuccess(field->name,"testdatetime");
516 	field=mysql_fetch_field_direct(result,11);
517 	checkSuccess(field->name,"testyear");
518 	field=mysql_fetch_field_direct(result,12);
519 	checkSuccess(field->name,"testchar");
520 	field=mysql_fetch_field_direct(result,13);
521 	checkSuccess(field->name,"testtext");
522 	field=mysql_fetch_field_direct(result,14);
523 	checkSuccess(field->name,"testvarchar");
524 	field=mysql_fetch_field_direct(result,15);
525 	checkSuccess(field->name,"testtinytext");
526 	field=mysql_fetch_field_direct(result,16);
527 	checkSuccess(field->name,"testmediumtext");
528 	field=mysql_fetch_field_direct(result,17);
529 	checkSuccess(field->name,"testlongtext");
530 	field=mysql_fetch_field_direct(result,18);
531 	checkSuccess(field->name,"testtimestamp");
532 	stdoutput.printf("\n");
533 
534 
535 	stdoutput.printf("mysql_fetch_fields:\n");
536 	field=mysql_fetch_fields(result);
537 	checkSuccess(field[0].name,"testtinyint");
538 	checkSuccess(field[1].name,"testsmallint");
539 	checkSuccess(field[2].name,"testmediumint");
540 	checkSuccess(field[3].name,"testint");
541 	checkSuccess(field[4].name,"testbigint");
542 	checkSuccess(field[5].name,"testfloat");
543 	checkSuccess(field[6].name,"testreal");
544 	checkSuccess(field[7].name,"testdecimal");
545 	checkSuccess(field[8].name,"testdate");
546 	checkSuccess(field[9].name,"testtime");
547 	checkSuccess(field[10].name,"testdatetime");
548 	checkSuccess(field[11].name,"testyear");
549 	checkSuccess(field[12].name,"testchar");
550 	checkSuccess(field[13].name,"testtext");
551 	checkSuccess(field[14].name,"testvarchar");
552 	checkSuccess(field[15].name,"testtinytext");
553 	checkSuccess(field[16].name,"testmediumtext");
554 	checkSuccess(field[17].name,"testlongtext");
555 	checkSuccess(field[18].name,"testtimestamp");
556 	stdoutput.printf("\n");
557 
558 
559 	stdoutput.printf("mysql_fetch_row:\n");
560 	row=mysql_fetch_row(result);
561 	checkSuccess(row[0],"1");
562 	checkSuccess(row[1],"1");
563 	checkSuccess(row[2],"1");
564 	checkSuccess(row[3],"1");
565 	checkSuccess(row[4],"1");
566 	//checkSuccess(row[5],"1.1");
567 	//checkSuccess(row[6],"1.1");
568 	checkSuccess(row[7],"1.1");
569 	checkSuccess(row[8],"2001-01-01");
570 	checkSuccess(row[9],"01:00:00");
571 	checkSuccess(row[10],"2001-01-01 01:00:00");
572 	checkSuccess(row[11],"2001");
573 	checkSuccess(row[12],"char1");
574 	checkSuccess(!charstring::compare(row[13],"text1",5),1);
575 	checkSuccess(row[14],"varchar1");
576 	checkSuccess(!charstring::compare(row[15],"tinytext1",9),1);
577 	checkSuccess(!charstring::compare(row[16],"mediumtext1",11),1);
578 	checkSuccess(!charstring::compare(row[17],"longtext1",9),1);
579 	stdoutput.printf("\n");
580 
581 
582 	stdoutput.printf("mysql_fetch_lengths:\n");
583 	unsigned long	*lengths;
584 	lengths=mysql_fetch_lengths(result);
585 	checkSuccess(lengths[0],1);
586 	checkSuccess(lengths[1],1);
587 	checkSuccess(lengths[2],1);
588 	checkSuccess(lengths[3],1);
589 	checkSuccess(lengths[4],1);
590 	//checkSuccess(lengths[5],3);
591 	//checkSuccess(lengths[6],3);
592 	checkSuccess(lengths[7],3);
593 	checkSuccess(lengths[8],10);
594 	checkSuccess(lengths[9],8);
595 	checkSuccess(lengths[10],19);
596 	checkSuccess(lengths[11],4);
597 	checkSuccess(lengths[12],5);
598 	checkSuccess(lengths[13],5);
599 	checkSuccess(lengths[14],8);
600 	checkSuccess(lengths[15],9);
601 	checkSuccess(lengths[16],11);
602 	checkSuccess(lengths[17],9);
603 	stdoutput.printf("\n");
604 
605 
606 	stdoutput.printf("mysql_fetch_row:\n");
607 	row=mysql_fetch_row(result);
608 	checkSuccess(row[0],"2");
609 	checkSuccess(row[1],"2");
610 	checkSuccess(row[2],"2");
611 	checkSuccess(row[3],"2");
612 	checkSuccess(row[4],"2");
613 	//checkSuccess(row[5],"2.1");
614 	//checkSuccess(row[6],"2.1");
615 	checkSuccess(row[7],"2.1");
616 	checkSuccess(row[8],"2002-01-01");
617 	checkSuccess(row[9],"02:00:00");
618 	checkSuccess(row[10],"2002-01-01 02:00:00");
619 	checkSuccess(row[11],"2002");
620 	checkSuccess(row[12],"char2");
621 	checkSuccess(!charstring::compare(row[13],"text2",5),1);
622 	checkSuccess(row[14],"varchar2");
623 	checkSuccess(!charstring::compare(row[15],"tinytext2",9),1);
624 	checkSuccess(!charstring::compare(row[16],"mediumtext2",11),1);
625 	checkSuccess(!charstring::compare(row[17],"longtext2",9),1);
626 	stdoutput.printf("\n");
627 
628 
629 	stdoutput.printf("mysql_data_seek:\n");
630 	mysql_data_seek(result,0);
631 	row=mysql_fetch_row(result);
632 	checkSuccess(row[0],"1");
633 	stdoutput.printf("\n");
634 
635 
636 	stdoutput.printf("mysql_row_tell/mysql_row_seek:\n");
637 	mysql_data_seek(result,0);
638 	MYSQL_ROW_OFFSET	zerorowoffset=mysql_row_tell(result);
639 	row=mysql_fetch_row(result);
640 	checkSuccess(row[0],"1");
641 	row=mysql_fetch_row(result);
642 	checkSuccess(row[0],"2");
643 	mysql_row_seek(result,zerorowoffset);
644 	row=mysql_fetch_row(result);
645 	checkSuccess(row[0],"1");
646 	stdoutput.printf("\n");
647 
648 
649 	stdoutput.printf("mysql_eof:\n");
650 	mysql_data_seek(result,1);
651 	row=mysql_fetch_row(result);
652 	checkSuccess(mysql_eof(result),1);
653 	stdoutput.printf("\n");
654 
655 
656 	mysql_free_result(result);
657 
658 
659 
660 	stdoutput.printf("mysql_real_query: select\n");
661 	query="select * from testdb.testtable";
662 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
663 	checkSuccess(mysql_info(&mysql),NULL);
664 	stdoutput.printf("\n");
665 
666 
667 	stdoutput.printf("mysql_use_result:\n");
668 	result=mysql_use_result(&mysql);
669 	stdoutput.printf("\n");
670 
671 
672 	stdoutput.printf("mysql_fetch_row:\n");
673 	row=mysql_fetch_row(result);
674 	checkSuccess(row[0],"1");
675 	checkSuccess(row[1],"1");
676 	checkSuccess(row[2],"1");
677 	checkSuccess(row[3],"1");
678 	checkSuccess(row[4],"1");
679 	//checkSuccess(row[5],"1.1");
680 	//checkSuccess(row[6],"1.1");
681 	checkSuccess(row[7],"1.1");
682 	checkSuccess(row[8],"2001-01-01");
683 	checkSuccess(row[9],"01:00:00");
684 	checkSuccess(row[10],"2001-01-01 01:00:00");
685 	checkSuccess(row[11],"2001");
686 	checkSuccess(row[12],"char1");
687 	checkSuccess(!charstring::compare(row[13],"text1",5),1);
688 	checkSuccess(row[14],"varchar1");
689 	checkSuccess(!charstring::compare(row[15],"tinytext1",9),1);
690 	checkSuccess(!charstring::compare(row[16],"mediumtext1",11),1);
691 	checkSuccess(!charstring::compare(row[17],"longtext1",9),1);
692 	row=mysql_fetch_row(result);
693 	checkSuccess(row[0],"2");
694 	checkSuccess(row[1],"2");
695 	checkSuccess(row[2],"2");
696 	checkSuccess(row[3],"2");
697 	checkSuccess(row[4],"2");
698 	//checkSuccess(row[5],"2.1");
699 	//checkSuccess(row[6],"2.1");
700 	checkSuccess(row[7],"2.1");
701 	checkSuccess(row[8],"2002-01-01");
702 	checkSuccess(row[9],"02:00:00");
703 	checkSuccess(row[10],"2002-01-01 02:00:00");
704 	checkSuccess(row[11],"2002");
705 	checkSuccess(row[12],"char2");
706 	checkSuccess(!charstring::compare(row[13],"text2",5),1);
707 	checkSuccess(row[14],"varchar2");
708 	checkSuccess(!charstring::compare(row[15],"tinytext2",9),1);
709 	checkSuccess(!charstring::compare(row[16],"mediumtext2",11),1);
710 	checkSuccess(!charstring::compare(row[17],"longtext2",9),1);
711 	checkSuccess((long)mysql_fetch_row(result),0);
712 	stdoutput.printf("\n");
713 
714 
715 	mysql_free_result(result);
716 
717 
718 	stdoutput.printf("mysql_real_query: drop\n");
719 	query="drop table testdb.testtable";
720 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
721 	checkSuccess(mysql_info(&mysql),NULL);
722 	stdoutput.printf("\n");
723 
724 
725 	stdoutput.printf("mysql_escape_string:\n");
726 	char	to[100];
727 	char	from[100];
728 	charstring::printf(from,sizeof(from)," ' \" \n \r \\ ; %c ",26);
729 	checkSuccess(mysql_escape_string(to,from,15),21);
730 	checkSuccess(to," \\' \\\" \\n \\r \\\\ ; \\Z ");
731 	stdoutput.printf("\n");
732 
733 
734 	stdoutput.printf("mysql_real_escape_string:\n");
735 	checkSuccess(mysql_real_escape_string(&mysql,to,from,15),21);
736 	checkSuccess(to," \\' \\\" \\n \\r \\\\ ; \\Z ");
737 	stdoutput.printf("\n");
738 
739 	stdoutput.printf("mysql_insert_id\n");
740 	query="create table testdb.testtable (col1 int not null primary key auto_increment, col2 int)";
741 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
742 	query="insert into testdb.testtable (col2) values (1)";
743 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
744 	checkSuccess(mysql_insert_id(&mysql),1);
745 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
746 	checkSuccess(mysql_insert_id(&mysql),2);
747 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
748 	checkSuccess(mysql_insert_id(&mysql),3);
749 	query="drop table testdb.testtable";
750 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
751 	stdoutput.printf("\n");
752 
753 
754 	stdoutput.printf("mysql_error/mysql_errno\n");
755 	query="known bad query";
756 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),1);
757 	char	*error=charstring::duplicate(mysql_error(&mysql));
758 	if (charstring::length(error)>36) {
759 		error[36]='\0';
760 	}
761 	checkSuccess(error,"You have an error in your SQL syntax");
762 	delete[] error;
763 	checkSuccess(mysql_errno(&mysql),1064);
764 	stdoutput.printf("\n");
765 
766 
767 	if (charstring::isNullOrEmpty(environment::getValue("LD_PRELOAD"))) {
768 		stdoutput.printf("mysql_thread_id\n");
769 		checkSuccess((mysql_thread_id(&mysql)!=0),1);
770 		stdoutput.printf("\n");
771 	}
772 
773 
774 	// some versions of mariadb crash when you call this
775 	// (arguably, I should figure out which versions and look for that too)
776 	#ifndef MARIADB_BASE_VERSION
777 	stdoutput.printf("mysql_list_processes\n");
778 	result=mysql_list_processes(&mysql);
779 	checkSuccess(mysql_num_fields(result),9);
780 	field=mysql_fetch_field_direct(result,0);
781 	checkSuccess(field->name,"Id");
782 	field=mysql_fetch_field_direct(result,1);
783 	checkSuccess(field->name,"User");
784 	field=mysql_fetch_field_direct(result,2);
785 	checkSuccess(field->name,"Host");
786 	field=mysql_fetch_field_direct(result,3);
787 	checkSuccess(field->name,"db");
788 	field=mysql_fetch_field_direct(result,4);
789 	checkSuccess(field->name,"Command");
790 	field=mysql_fetch_field_direct(result,5);
791 	checkSuccess(field->name,"Time");
792 	field=mysql_fetch_field_direct(result,6);
793 	checkSuccess(field->name,"State");
794 	field=mysql_fetch_field_direct(result,7);
795 	checkSuccess(field->name,"Info");
796 	field=mysql_fetch_field_direct(result,8);
797 	checkSuccess(field->name,"Progress");
798 	row=mysql_fetch_row(result);
799 	stdoutput.printf("\n");
800 	mysql_free_result(result);
801 	stdoutput.printf("\n");
802 	#endif
803 
804 	// FIXME: mysql_info for:
805 	// insert into ... select ...
806 	// insert into ... values (...),(...),(...)...
807 	// load data infile ...
808 	// alter table
809 	// update
810 
811 	// FIXME: mysql_change_user
812 
813 	#if defined(MARIADB_BASE_VERSION) || \
814 		(defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID<80000)
815 	stdoutput.printf("mysql_shutdown\n");
816 	// should fail for lack of permissions
817 	// deprecated in real mysql, and always returns 1 on error
818 	checkSuccess(mysql_shutdown(&mysql,SHUTDOWN_DEFAULT),1);
819 	stdoutput.printf("\n");
820 	#endif
821 
822 	stdoutput.printf("mysql_refresh\n");
823 	// these should all fail for lack of permissions
824 	checkSuccess(mysql_refresh(&mysql,REFRESH_GRANT),1);
825 	checkSuccess(mysql_refresh(&mysql,REFRESH_LOG),1);
826 	checkSuccess(mysql_refresh(&mysql,REFRESH_TABLES),1);
827 	checkSuccess(mysql_refresh(&mysql,REFRESH_HOSTS),1);
828 	checkSuccess(mysql_refresh(&mysql,REFRESH_STATUS),1);
829 	checkSuccess(mysql_refresh(&mysql,REFRESH_SLAVE),1);
830 	checkSuccess(mysql_refresh(&mysql,REFRESH_MASTER),1);
831 	/*if (argc==2) {
832 		checkSuccess(mysql_refresh(&mysql,REFRESH_THREADS),1);
833 	} else {
834 		// no-op in this case
835 		checkSuccess(mysql_refresh(&mysql,REFRESH_THREADS),0);
836 	}*/
837 	stdoutput.printf("\n");
838 
839 	stdoutput.printf("mysql_reload\n");
840 	// should fail for lack of permissions
841 	checkSuccess(mysql_reload(&mysql),1);
842 	stdoutput.printf("\n");
843 
844 	stdoutput.printf("mysql_stat\n");
845 	const char	*stat=mysql_stat(&mysql);
846 	checkSuccess(charstring::contains(stat,"Uptime: "),1);
847 	checkSuccess(charstring::contains(stat,"Threads: "),1);
848 	checkSuccess(charstring::contains(stat,"Questions: "),1);
849 	checkSuccess(charstring::contains(stat,"Slow queries: "),1);
850 	checkSuccess(charstring::contains(stat,"Opens: "),1);
851 	checkSuccess(charstring::contains(stat,"Flush tables: "),1);
852 	checkSuccess(charstring::contains(stat,"Open tables: "),1);
853 	checkSuccess(charstring::contains(stat,"Queries per second avg: "),1);
854 	stdoutput.printf("\n");
855 
856 	stdoutput.printf("mysql_kill\n");
857 	// should fail for lack of permissions (or invalid thread id)
858 	// deprecated in real mysql, and always returns 1 on error
859 	checkSuccess(mysql_kill(&mysql,0),1);
860 	stdoutput.printf("\n");
861 
862 	// FIXME: mysql_options
863 	// (no options are currently supported, except against a real database)
864 
865 	mysql_close(&mysql);
866 
867 
868 	stdoutput.printf("\n============ Statement API ============\n\n");
869 
870 	// statement api...
871 	#ifdef HAVE_MYSQL_REAL_CONNECT_FOR_SURE
872 		stdoutput.printf("mysql_init\n");
873 		checkSuccess((long)mysql_init(&mysql),(long)&mysql);
874 		stdoutput.printf("\n");
875 		stdoutput.printf("mysql_real_connect\n");
876 		#if MYSQL_VERSION_ID>=32200
877 			checkSuccess((long)mysql_real_connect(
878 						&mysql,host,user,password,db,
879 						charstring::toInteger(port),
880 						socket,0),(long)&mysql);
881 		#else
882 			checkSuccess((long)mysql_real_connect(
883 						&mysql,host,user,password,
884 						charstring::toInteger(port),
885 						socket,0),(long)&mysql);
886 			if (!charstring::isNullOrEmpty(db)) {
887 				checkSuccess(mysql_select_db(&mysql,db),0);
888 			}
889 		#endif
890 	#else
891 		checkSuccess((long)mysql_connect(&mysql,host,
892 						user,password),
893 						(long)mysql);
894 	#endif
895 	stdoutput.printf("\n");
896 
897 	stdoutput.printf("mysql_stmt_init:\n");
898 	MYSQL_STMT	*stmt=mysql_stmt_init(&mysql);
899 	checkSuccess((int)(stmt!=NULL),1);
900 	stdoutput.printf("\n");
901 	stdoutput.printf("mysql_stmt_prepare: create\n");
902 	query="create table testdb.testtable (testtinyint tinyint, testsmallint smallint, testmediumint mediumint, testint int, testbigint bigint, testfloat float, testreal real, testdecimal decimal(2,1), testdate date, testtime time, testdatetime datetime, testyear year, testchar char(40), testtext text, testvarchar varchar(40), testtinytext tinytext, testmediumtext mediumtext, testlongtext longtext, testtimestamp timestamp)";
903 	checkSuccess(mysql_stmt_prepare(stmt,query,
904 				charstring::length(query)),0);
905 	stdoutput.printf("\n");
906 
907 
908 	stdoutput.printf("mysql_stmt_execute: create\n");
909 	checkSuccess(mysql_stmt_execute(stmt),0);
910 	stdoutput.printf("\n");
911 
912 
913 	stdoutput.printf("mysql_stmt_prepare/execute: insert\n");
914 	query="insert into testdb.testtable values (1,1,1,1,1,1.1,1.1,1.1,'2001-01-01','01:00:00','2001-01-01 01:00:00','2001','char1','text1','varchar1','tinytext1','mediumtext1','longtext1',NULL)";
915 	checkSuccess(mysql_stmt_prepare(stmt,query,charstring::length(query)),0);
916 	checkSuccess(mysql_stmt_execute(stmt),0);
917 	stdoutput.printf("\n");
918 
919 
920 	stdoutput.printf("mysql_stmt_prepare/execute: insert\n");
921 	query="insert into testdb.testtable values (2,2,2,2,2,2.1,2.1,2.1,'2002-01-01','02:00:00','2002-01-01 02:00:00','2002','char2','text2','varchar2','tinytext2','mediumtext2','longtext2',NULL)";
922 	checkSuccess(mysql_stmt_prepare(stmt,query,charstring::length(query)),0);
923 	checkSuccess(mysql_stmt_execute(stmt),0);
924 	stdoutput.printf("\n");
925 
926 
927 	stdoutput.printf("mysql_stmt_prepare: select\n");
928 	query="select * from testdb.testtable";
929 	checkSuccess(mysql_stmt_prepare(stmt,query,charstring::length(query)),0);
930 	stdoutput.printf("\n");
931 
932 
933 	stdoutput.printf("mysql_stmt_field_count:\n");
934 	checkSuccess(mysql_stmt_field_count(stmt),19);
935 	stdoutput.printf("\n");
936 
937 
938 	stdoutput.printf("mysql_fetch_field/mysql_field_tell:\n");
939 	result=mysql_stmt_result_metadata(stmt);
940 	field=mysql_fetch_field(result);
941 	checkSuccess(mysql_field_tell(result),1);
942 	checkSuccess(field->name,"testtinyint");
943 	field=mysql_fetch_field(result);
944 	checkSuccess(mysql_field_tell(result),2);
945 	checkSuccess(field->name,"testsmallint");
946 	field=mysql_fetch_field(result);
947 	checkSuccess(mysql_field_tell(result),3);
948 	checkSuccess(field->name,"testmediumint");
949 	field=mysql_fetch_field(result);
950 	checkSuccess(mysql_field_tell(result),4);
951 	checkSuccess(field->name,"testint");
952 	field=mysql_fetch_field(result);
953 	checkSuccess(mysql_field_tell(result),5);
954 	checkSuccess(field->name,"testbigint");
955 	field=mysql_fetch_field(result);
956 	checkSuccess(mysql_field_tell(result),6);
957 	checkSuccess(field->name,"testfloat");
958 	field=mysql_fetch_field(result);
959 	checkSuccess(mysql_field_tell(result),7);
960 	checkSuccess(field->name,"testreal");
961 	field=mysql_fetch_field(result);
962 	checkSuccess(mysql_field_tell(result),8);
963 	checkSuccess(field->name,"testdecimal");
964 	field=mysql_fetch_field(result);
965 	checkSuccess(mysql_field_tell(result),9);
966 	checkSuccess(field->name,"testdate");
967 	field=mysql_fetch_field(result);
968 	checkSuccess(mysql_field_tell(result),10);
969 	checkSuccess(field->name,"testtime");
970 	field=mysql_fetch_field(result);
971 	checkSuccess(mysql_field_tell(result),11);
972 	checkSuccess(field->name,"testdatetime");
973 	field=mysql_fetch_field(result);
974 	checkSuccess(mysql_field_tell(result),12);
975 	checkSuccess(field->name,"testyear");
976 	field=mysql_fetch_field(result);
977 	checkSuccess(mysql_field_tell(result),13);
978 	checkSuccess(field->name,"testchar");
979 	field=mysql_fetch_field(result);
980 	checkSuccess(mysql_field_tell(result),14);
981 	checkSuccess(field->name,"testtext");
982 	field=mysql_fetch_field(result);
983 	checkSuccess(mysql_field_tell(result),15);
984 	checkSuccess(field->name,"testvarchar");
985 	field=mysql_fetch_field(result);
986 	checkSuccess(mysql_field_tell(result),16);
987 	checkSuccess(field->name,"testtinytext");
988 	field=mysql_fetch_field(result);
989 	checkSuccess(mysql_field_tell(result),17);
990 	checkSuccess(field->name,"testmediumtext");
991 	field=mysql_fetch_field(result);
992 	checkSuccess(mysql_field_tell(result),18);
993 	checkSuccess(field->name,"testlongtext");
994 	field=mysql_fetch_field(result);
995 	checkSuccess(mysql_field_tell(result),19);
996 	checkSuccess(field->name,"testtimestamp");
997 	stdoutput.printf("\n");
998 
999 
1000 	stdoutput.printf("mysql_stmt_bind_result:\n");
1001 	MYSQL_BIND	fieldbind[19];
1002 	char		fieldbuffer[19*1024];
1003 	my_bool		fieldisnull[19];
1004 	unsigned long	fieldlength[19];
1005 	for (uint16_t i=0; i<19; i++) {
1006 		bytestring::zero(&fieldbind[i],sizeof(MYSQL_BIND));
1007 		fieldbind[i].buffer_type=MYSQL_TYPE_STRING;
1008 		fieldbind[i].buffer=&fieldbuffer[i*1024];
1009 		fieldbind[i].buffer_length=1024;
1010 		fieldbind[i].is_null=&fieldisnull[i];
1011 		fieldbind[i].length=&fieldlength[i];
1012 	}
1013 	checkSuccess(mysql_stmt_bind_result(stmt,fieldbind),0);
1014 	stdoutput.printf("\n");
1015 
1016 	stdoutput.printf("mysql_stmt_execute: select\n");
1017 	checkSuccess(mysql_stmt_execute(stmt),0);
1018 	stdoutput.printf("\n");
1019 
1020 	stdoutput.printf("mysql_stmt_fetch:\n");
1021 	checkSuccess(mysql_stmt_fetch(stmt),0);
1022 	checkSuccess((const char *)fieldbind[0].buffer,"1");
1023 	checkSuccess((const char *)fieldbind[1].buffer,"1");
1024 	checkSuccess((const char *)fieldbind[2].buffer,"1");
1025 	checkSuccess((const char *)fieldbind[3].buffer,"1");
1026 	checkSuccess((const char *)fieldbind[4].buffer,"1");
1027 	//checkSuccess((const char *)fieldbind[5].buffer,"1.1");
1028 	//checkSuccess((const char *)fieldbind[6].buffer,"1.1");
1029 	checkSuccess((const char *)fieldbind[7].buffer,"1.1");
1030 	checkSuccess((const char *)fieldbind[8].buffer,"2001-01-01");
1031 	checkSuccess((const char *)fieldbind[9].buffer,"01:00:00");
1032 	checkSuccess((const char *)fieldbind[10].buffer,"2001-01-01 01:00:00");
1033 	checkSuccess((const char *)fieldbind[11].buffer,"2001");
1034 	checkSuccess((const char *)fieldbind[12].buffer,"char1");
1035 	checkSuccess(!charstring::compare(
1036 			(const char *)fieldbind[13].buffer,"text1",5),1);
1037 	checkSuccess((const char *)fieldbind[14].buffer,"varchar1");
1038 	checkSuccess(!charstring::compare(
1039 			(const char *)fieldbind[15].buffer,"tinytext1",9),1);
1040 	checkSuccess(!charstring::compare(
1041 			(const char *)fieldbind[16].buffer,"mediumtext1",11),1);
1042 	checkSuccess(!charstring::compare(
1043 			(const char *)fieldbind[17].buffer,"longtext1",9),1);
1044 	stdoutput.printf("\n");
1045 	checkSuccess(mysql_stmt_fetch(stmt),0);
1046 	checkSuccess((const char *)fieldbind[0].buffer,"2");
1047 	checkSuccess((const char *)fieldbind[1].buffer,"2");
1048 	checkSuccess((const char *)fieldbind[2].buffer,"2");
1049 	checkSuccess((const char *)fieldbind[3].buffer,"2");
1050 	checkSuccess((const char *)fieldbind[4].buffer,"2");
1051 	//checkSuccess((const char *)fieldbind[5].buffer,"2.1");
1052 	//checkSuccess((const char *)fieldbind[6].buffer,"2.1");
1053 	checkSuccess((const char *)fieldbind[7].buffer,"2.1");
1054 	checkSuccess((const char *)fieldbind[8].buffer,"2002-01-01");
1055 	checkSuccess((const char *)fieldbind[9].buffer,"02:00:00");
1056 	checkSuccess((const char *)fieldbind[10].buffer,"2002-01-01 02:00:00");
1057 	checkSuccess((const char *)fieldbind[11].buffer,"2002");
1058 	checkSuccess((const char *)fieldbind[12].buffer,"char2");
1059 	checkSuccess(!charstring::compare(
1060 			(const char *)fieldbind[13].buffer,"text2",5),1);
1061 	checkSuccess((const char *)fieldbind[14].buffer,"varchar2");
1062 	checkSuccess(!charstring::compare(
1063 			(const char *)fieldbind[15].buffer,"tinytext2",9),1);
1064 	checkSuccess(!charstring::compare(
1065 			(const char *)fieldbind[16].buffer,"mediumtext2",11),1);
1066 	checkSuccess(!charstring::compare(
1067 			(const char *)fieldbind[17].buffer,"longtext2",9),1);
1068 	stdoutput.printf("\n");
1069 	checkSuccess(mysql_stmt_fetch(stmt),MYSQL_NO_DATA);
1070 	stdoutput.printf("\n");
1071 
1072 
1073 	stdoutput.printf("mysql_stmt_prepare/execute: drop\n");
1074 	query="drop table testdb.testtable";
1075 	checkSuccess(mysql_stmt_prepare(stmt,query,charstring::length(query)),0);
1076 	checkSuccess(mysql_stmt_execute(stmt),0);
1077 	stdoutput.printf("\n");
1078 
1079 
1080 	stdoutput.printf("mysql_stmt_prepare/execute: select with odd NULLS\n");
1081 	query="select NULL,1,NULL,1,NULL,1";
1082 	checkSuccess(mysql_stmt_prepare(stmt,query,charstring::length(query)),0);
1083 	checkSuccess(mysql_stmt_execute(stmt),0);
1084 	checkSuccess(mysql_stmt_bind_result(stmt,fieldbind),0);
1085 	checkSuccess(mysql_stmt_fetch(stmt),0);
1086 	checkSuccess(fieldisnull[0],1);
1087 	checkSuccess(fieldisnull[1],0);
1088 	checkSuccess(fieldisnull[2],1);
1089 	checkSuccess(fieldisnull[3],0);
1090 	checkSuccess(fieldisnull[4],1);
1091 	checkSuccess(fieldisnull[5],0);
1092 	#ifdef MARIADB_BASE_VERSION
1093 	checkSuccess(mysql_stmt_fetch(stmt),100);
1094 	#endif
1095 	stdoutput.printf("\n");
1096 
1097 	stdoutput.printf("mysql_stmt_prepare/execute: select with even NULLS\n");
1098 	query="select 1,NULL,1,NULL,1,NULL";
1099 	checkSuccess(mysql_stmt_prepare(stmt,query,charstring::length(query)),0);
1100 	checkSuccess(mysql_stmt_execute(stmt),0);
1101 	checkSuccess(mysql_stmt_bind_result(stmt,fieldbind),0);
1102 	checkSuccess(mysql_stmt_fetch(stmt),0);
1103 	checkSuccess(fieldisnull[0],0);
1104 	checkSuccess(fieldisnull[1],1);
1105 	checkSuccess(fieldisnull[2],0);
1106 	checkSuccess(fieldisnull[3],1);
1107 	checkSuccess(fieldisnull[4],0);
1108 	checkSuccess(fieldisnull[5],1);
1109 	#ifdef MARIADB_BASE_VERSION
1110 	checkSuccess(mysql_stmt_fetch(stmt),100);
1111 	#endif
1112 	stdoutput.printf("\n");
1113 
1114 
1115 
1116 	stdoutput.printf("mysql_stmt_prepare/execute: select with binds\n");
1117 	query="select ?,?,?,?,?,?,?,?,?,?,?,?,?,?";
1118 	checkSuccess(mysql_stmt_prepare(stmt,query,charstring::length(query)),0);
1119 	MYSQL_BIND	bind[14];
1120 	unsigned long	bindlength[14];
1121 	my_bool		bindisnull[14];
1122 	bytestring::zero(&bind,sizeof(bind));
1123 	bytestring::zero(&bindlength,sizeof(bindlength));
1124 	bytestring::zero(&bindisnull,sizeof(bindisnull));
1125 
1126 	char	tinyval=1;
1127 	bind[0].buffer_type=MYSQL_TYPE_TINY;
1128 	bind[0].buffer=&tinyval;
1129 	bind[0].buffer_length=sizeof(tinyval);
1130 	bindlength[0]=sizeof(tinyval);
1131 	bind[0].length=&bindlength[0];
1132 	bindisnull[0]=0;
1133 	bind[0].is_null=&bindisnull[0];
1134 
1135 	int16_t	shortval=1;
1136 	bind[1].buffer_type=MYSQL_TYPE_SHORT;
1137 	bind[1].buffer=&shortval;
1138 	bind[1].buffer_length=sizeof(shortval);
1139 	bindlength[1]=sizeof(shortval);
1140 	bind[1].length=&bindlength[1];
1141 	bindisnull[1]=0;
1142 	bind[1].is_null=&bindisnull[1];
1143 
1144 	int32_t	longval=1;
1145 	bind[2].buffer_type=MYSQL_TYPE_LONG;
1146 	bind[2].buffer=&longval;
1147 	bind[2].buffer_length=sizeof(longval);
1148 	bindlength[2]=sizeof(longval);
1149 	bind[2].length=&bindlength[2];
1150 	bindisnull[2]=0;
1151 	bind[2].is_null=&bindisnull[2];
1152 
1153 	int64_t	longlongval=1;
1154 	bind[3].buffer_type=MYSQL_TYPE_LONGLONG;
1155 	bind[3].buffer=&longlongval;
1156 	bind[3].buffer_length=sizeof(longlongval);
1157 	bindlength[3]=sizeof(longlongval);
1158 	bind[3].length=&bindlength[3];
1159 	bindisnull[3]=0;
1160 	bind[3].is_null=&bindisnull[3];
1161 
1162 	float	floatval=1.1;
1163 	bind[4].buffer_type=MYSQL_TYPE_FLOAT;
1164 	bind[4].buffer=&floatval;
1165 	bind[4].buffer_length=sizeof(floatval);
1166 	bindlength[4]=sizeof(floatval);
1167 	bind[4].length=&bindlength[4];
1168 	bindisnull[4]=0;
1169 	bind[4].is_null=&bindisnull[4];
1170 
1171 	double	doubleval=1.1;
1172 	bind[5].buffer_type=MYSQL_TYPE_DOUBLE;
1173 	bind[5].buffer=&doubleval;
1174 	bind[5].buffer_length=sizeof(doubleval);
1175 	bindlength[5]=sizeof(doubleval);
1176 	bind[5].length=&bindlength[5];
1177 	bindisnull[5]=0;
1178 	bind[5].is_null=&bindisnull[5];
1179 
1180 	bind[6].buffer_type=MYSQL_TYPE_STRING;
1181 	bind[6].buffer=(void *)"string1";
1182 	bind[6].buffer_length=7;
1183 	bindlength[6]=7;
1184 	bind[6].length=&bindlength[6];
1185 	bindisnull[6]=0;
1186 	bind[6].is_null=&bindisnull[6];
1187 
1188 	bind[7].buffer_type=MYSQL_TYPE_VAR_STRING;
1189 	bind[7].buffer=(void *)"varstring1";
1190 	bind[7].buffer_length=10;
1191 	bindlength[7]=10;
1192 	bind[7].length=&bindlength[7];
1193 	bindisnull[7]=0;
1194 	bind[7].is_null=&bindisnull[7];
1195 
1196 	bind[8].buffer_type=MYSQL_TYPE_TINY_BLOB;
1197 	bind[8].buffer=(void *)"tinyblob1";
1198 	bind[8].buffer_length=9;
1199 	bindlength[8]=9;
1200 	bind[8].length=&bindlength[8];
1201 	bindisnull[8]=0;
1202 	bind[8].is_null=&bindisnull[8];
1203 
1204 	bind[9].buffer_type=MYSQL_TYPE_MEDIUM_BLOB;
1205 	bind[9].buffer=(void *)"mediumblob1";
1206 	bind[9].buffer_length=11;
1207 	bindlength[9]=11;
1208 	bind[9].length=&bindlength[9];
1209 	bindisnull[9]=0;
1210 	bind[9].is_null=&bindisnull[9];
1211 
1212 	bind[10].buffer_type=MYSQL_TYPE_LONG_BLOB;
1213 	bind[10].buffer=(void *)"longblob1";
1214 	bind[10].buffer_length=9;
1215 	bindlength[10]=9;
1216 	bind[10].length=&bindlength[10];
1217 	bindisnull[10]=0;
1218 	bind[10].is_null=&bindisnull[10];
1219 
1220 	bind[11].buffer_type=MYSQL_TYPE_DATE;
1221 	MYSQL_TIME	datetm;
1222 	bytestring::zero(&datetm,sizeof(datetm));
1223 	datetm.year=2001;
1224 	datetm.month=1;
1225 	datetm.day=2;
1226 	bind[11].buffer=(void *)&datetm;
1227 	bind[11].buffer_length=sizeof(datetm);
1228 	bindlength[11]=sizeof(datetm);
1229 	bind[11].length=&bindlength[11];
1230 	bindisnull[11]=0;
1231 	bind[11].is_null=&bindisnull[11];
1232 
1233 	bind[12].buffer_type=MYSQL_TYPE_TIME;
1234 	MYSQL_TIME	timetm;
1235 	bytestring::zero(&timetm,sizeof(timetm));
1236 	timetm.neg=1;
1237 	timetm.day=1;
1238 	timetm.hour=12;
1239 	timetm.minute=10;
1240 	timetm.second=11;
1241 	bind[12].buffer=(void *)&timetm;
1242 	bind[12].buffer_length=sizeof(timetm);
1243 	bindlength[12]=sizeof(timetm);
1244 	bind[12].length=&bindlength[12];
1245 	bindisnull[12]=0;
1246 	bind[12].is_null=&bindisnull[12];
1247 
1248 	bind[13].buffer_type=MYSQL_TYPE_DATETIME;
1249 	MYSQL_TIME	datetimetm;
1250 	bytestring::zero(&datetimetm,sizeof(datetimetm));
1251 	datetimetm.year=2001;
1252 	datetimetm.month=1;
1253 	datetimetm.day=2;
1254 	datetimetm.hour=12;
1255 	datetimetm.minute=10;
1256 	datetimetm.second=11;
1257 	bind[13].buffer=(void *)&datetimetm;
1258 	bind[13].buffer_length=sizeof(datetimetm);
1259 	bindlength[13]=sizeof(datetimetm);
1260 	bind[13].length=&bindlength[13];
1261 	bindisnull[13]=0;
1262 	bind[13].is_null=&bindisnull[13];
1263 
1264 	checkSuccess(mysql_stmt_bind_param(stmt,bind),0);
1265 	checkSuccess(mysql_stmt_execute(stmt),0);
1266 	checkSuccess(mysql_stmt_bind_result(stmt,fieldbind),0);
1267 	checkSuccess(mysql_stmt_fetch(stmt),0);
1268 	checkSuccess((const char *)fieldbind[0].buffer,"1");
1269 	checkSuccess((const char *)fieldbind[1].buffer,"1");
1270 	checkSuccess((const char *)fieldbind[2].buffer,"1");
1271 	checkSuccess((const char *)fieldbind[3].buffer,"1");
1272 	//checkSuccess((const char *)fieldbind[4].buffer,"1.1");
1273 	//checkSuccess((const char *)fieldbind[5].buffer,"1.1");
1274 	checkSuccess((const char *)fieldbind[6].buffer,"string1");
1275 	checkSuccess((const char *)fieldbind[7].buffer,"varstring1");
1276 	checkSuccess((const char *)fieldbind[8].buffer,"tinyblob1");
1277 	checkSuccess((const char *)fieldbind[9].buffer,"mediumblob1");
1278 	checkSuccess((const char *)fieldbind[10].buffer,"longblob1");
1279 	checkSuccess((const char *)fieldbind[11].buffer,"2001-01-02");
1280 	checkSuccess((const char *)fieldbind[12].buffer,"-36:10:11");
1281 	checkSuccess((const char *)fieldbind[13].buffer,"2001-01-02 12:10:11");
1282 	#ifdef MARIADB_BASE_VERSION
1283 	checkSuccess(mysql_stmt_fetch(stmt),100);
1284 	#endif
1285 	stdoutput.printf("\n");
1286 
1287 
1288 	stdoutput.printf("mysql_stmt_prepare/execute: select with even null binds\n");
1289 	query="select ?,?,?,?";
1290 	checkSuccess(mysql_stmt_prepare(stmt,query,charstring::length(query)),0);
1291 	bytestring::zero(&bind,sizeof(bind));
1292 	bytestring::zero(&bindlength,sizeof(bindlength));
1293 	bytestring::zero(&bindisnull,sizeof(bindisnull));
1294 
1295 	bind[0].buffer_type=MYSQL_TYPE_TINY;
1296 	bind[0].buffer=&tinyval;
1297 	bind[0].buffer_length=sizeof(tinyval);
1298 	bindlength[0]=sizeof(tinyval);
1299 	bind[0].length=&bindlength[0];
1300 	bindisnull[0]=0;
1301 	bind[0].is_null=&bindisnull[0];
1302 
1303 	bind[1].buffer_type=MYSQL_TYPE_TINY;
1304 	bind[1].buffer=0;
1305 	bind[1].buffer_length=0;
1306 	bindlength[1]=0;
1307 	bind[1].length=&bindlength[1];
1308 	bindisnull[1]=1;
1309 	bind[1].is_null=&bindisnull[1];
1310 
1311 	bind[2].buffer_type=MYSQL_TYPE_TINY;
1312 	bind[2].buffer=&tinyval;
1313 	bind[2].buffer_length=sizeof(tinyval);
1314 	bindlength[2]=sizeof(tinyval);
1315 	bind[2].length=&bindlength[2];
1316 	bindisnull[2]=0;
1317 	bind[2].is_null=&bindisnull[2];
1318 
1319 	bind[3].buffer_type=MYSQL_TYPE_TINY;
1320 	bind[3].buffer=0;
1321 	bind[3].buffer_length=0;
1322 	bindlength[3]=0;
1323 	bind[3].length=&bindlength[3];
1324 	bindisnull[3]=1;
1325 	bind[3].is_null=&bindisnull[3];
1326 
1327 	checkSuccess(mysql_stmt_bind_param(stmt,bind),0);
1328 	checkSuccess(mysql_stmt_execute(stmt),0);
1329 	checkSuccess(mysql_stmt_bind_result(stmt,fieldbind),0);
1330 	checkSuccess(mysql_stmt_fetch(stmt),0);
1331 	checkSuccess(bindisnull[0],0);
1332 	checkSuccess(bindisnull[1],1);
1333 	checkSuccess(bindisnull[2],0);
1334 	checkSuccess(bindisnull[3],1);
1335 	#ifdef MARIADB_BASE_VERSION
1336 	checkSuccess(mysql_stmt_fetch(stmt),100);
1337 	#endif
1338 	stdoutput.printf("\n");
1339 
1340 
1341 	stdoutput.printf("mysql_stmt_prepare/execute: select with odd null binds\n");
1342 	query="select ?,?,?,?";
1343 	checkSuccess(mysql_stmt_prepare(stmt,query,charstring::length(query)),0);
1344 	bytestring::zero(&bind,sizeof(bind));
1345 	bytestring::zero(&bindlength,sizeof(bindlength));
1346 	bytestring::zero(&bindisnull,sizeof(bindisnull));
1347 
1348 	bind[0].buffer_type=MYSQL_TYPE_TINY;
1349 	bind[0].buffer=0;
1350 	bind[0].buffer_length=0;
1351 	bindlength[0]=0;
1352 	bind[0].length=&bindlength[0];
1353 	bindisnull[0]=1;
1354 	bind[0].is_null=&bindisnull[0];
1355 
1356 	bind[1].buffer_type=MYSQL_TYPE_TINY;
1357 	bind[1].buffer=&tinyval;
1358 	bind[1].buffer_length=sizeof(tinyval);
1359 	bindlength[1]=sizeof(tinyval);
1360 	bind[1].length=&bindlength[1];
1361 	bindisnull[1]=0;
1362 	bind[1].is_null=&bindisnull[1];
1363 
1364 	bind[2].buffer_type=MYSQL_TYPE_TINY;
1365 	bind[2].buffer=0;
1366 	bind[2].buffer_length=0;
1367 	bindlength[2]=0;
1368 	bind[2].length=&bindlength[2];
1369 	bindisnull[2]=1;
1370 	bind[2].is_null=&bindisnull[2];
1371 
1372 	bind[3].buffer_type=MYSQL_TYPE_TINY;
1373 	bind[3].buffer=&tinyval;
1374 	bind[3].buffer_length=sizeof(tinyval);
1375 	bindlength[3]=sizeof(tinyval);
1376 	bind[3].length=&bindlength[3];
1377 	bindisnull[3]=0;
1378 	bind[3].is_null=&bindisnull[3];
1379 
1380 	checkSuccess(mysql_stmt_bind_param(stmt,bind),0);
1381 	checkSuccess(mysql_stmt_execute(stmt),0);
1382 	checkSuccess(mysql_stmt_bind_result(stmt,fieldbind),0);
1383 	checkSuccess(mysql_stmt_fetch(stmt),0);
1384 	checkSuccess(fieldisnull[0],1);
1385 	checkSuccess(fieldisnull[1],0);
1386 	checkSuccess(fieldisnull[2],1);
1387 	checkSuccess(fieldisnull[3],0);
1388 	#ifdef MARIADB_BASE_VERSION
1389 	checkSuccess(mysql_stmt_fetch(stmt),100);
1390 	#endif
1391 	stdoutput.printf("\n");
1392 
1393 	stdoutput.printf("mysql_stmt_close:\n");
1394 	checkSuccess(mysql_stmt_close(stmt),0);
1395 	stdoutput.printf("\n");
1396 
1397 
1398 	stdoutput.printf("mysql_stmt_prepare/execute: binary data\n");
1399 	query="create table testdb.testtable (col1 longblob)";
1400 	checkSuccess(mysql_real_query(&mysql,query,charstring::length(query)),0);
1401 	const char	value[]={0,'"','"','\n'};
1402 	stringbuffer	q;
1403 	q.append("insert into testdb.testtable values (_binary'");
1404 	q.append(value,sizeof(value));
1405 	q.append("')");
1406 	checkSuccess(mysql_real_query(&mysql,q.getString(),q.getSize()),0);
1407 	stmt=mysql_stmt_init(&mysql);
1408 	query="select col1 from testdb.testtable";
1409 	checkSuccess(mysql_stmt_prepare(stmt,query,charstring::length(query)),0);
1410 	checkSuccess(mysql_stmt_bind_result(stmt,fieldbind),0);
1411 	for (uint16_t i=0; i<19; i++) {
1412 		bytestring::zero(&fieldbind[i],sizeof(MYSQL_BIND));
1413 		fieldbind[i].buffer_type=MYSQL_TYPE_STRING;
1414 		fieldbind[i].buffer=&fieldbuffer[i*1024];
1415 		fieldbind[i].buffer_length=1024;
1416 		fieldbind[i].is_null=&fieldisnull[i];
1417 		fieldbind[i].length=&fieldlength[i];
1418 	}
1419 	checkSuccess(mysql_stmt_execute(stmt),0);
1420 	checkSuccess(mysql_stmt_bind_result(stmt,fieldbind),0);
1421 	checkSuccess(mysql_stmt_fetch(stmt),0);
1422 	stdoutput.printf("\n");
1423 	checkSuccess(fieldlength[0],sizeof(value));
1424 	checkSuccess(bytestring::compare(fieldbind[0].buffer,
1425 					value,sizeof(value)),0);
1426 	stdoutput.printf("\n");
1427 
1428 	stdoutput.printf("mysql_stmt_close:\n");
1429 	checkSuccess(mysql_stmt_close(stmt),0);
1430 	stdoutput.printf("\n");
1431 
1432 
1433 	stdoutput.printf("\n============ Info ============\n\n");
1434 
1435 	stdoutput.printf("mysql_get_server_info: %s\n",
1436 				mysql_get_server_info(&mysql));
1437 	stdoutput.printf("mysql_get_client_info: %s\n",
1438 				mysql_get_client_info());
1439 	stdoutput.printf("mysql_get_host_info: %s\n",
1440 				mysql_get_host_info(&mysql));
1441 	stdoutput.printf("mysql_get_proto_info: %d\n",
1442 				mysql_get_proto_info(&mysql));
1443 	stdoutput.printf("\n");
1444 
1445 
1446 	mysql_close(&mysql);
1447 
1448 	#else
1449 
1450 	stdoutput.printf("\n====== MySQL Client Too Old to Test ======\n\n");
1451 
1452 	#endif
1453 
1454 	return 0;
1455 }
1456