2361
/* reads Qcache_hits from server and returns its value */
2362
static uint query_cache_hits(MYSQL *conn)
2369
rc= mysql_query(conn, "show status like 'qcache_hits'");
2371
res= mysql_use_result(conn);
2374
row= mysql_fetch_row(res);
2377
result= atoi(row[1]);
2378
mysql_free_result(res);
2384
utility for the next test; expects 3 rows in the result from a SELECT,
2385
compares each row/field with an expected value.
2387
#define test_ps_query_cache_result(i1,s1,l1,i2,s2,l2,i3,s3,l3) \
2388
r_metadata= mysql_stmt_result_metadata(stmt); \
2389
DIE_UNLESS(r_metadata != NULL); \
2390
rc= mysql_stmt_fetch(stmt); \
2391
check_execute(stmt, rc); \
2393
fprintf(stdout, "\n row 1: %d, %s(%lu)", r_int_data, \
2394
r_str_data, r_str_length); \
2395
DIE_UNLESS((r_int_data == i1) && (r_str_length == l1) && \
2396
(strcmp(r_str_data, s1) == 0)); \
2397
rc= mysql_stmt_fetch(stmt); \
2398
check_execute(stmt, rc); \
2400
fprintf(stdout, "\n row 2: %d, %s(%lu)", r_int_data, \
2401
r_str_data, r_str_length); \
2402
DIE_UNLESS((r_int_data == i2) && (r_str_length == l2) && \
2403
(strcmp(r_str_data, s2) == 0)); \
2404
rc= mysql_stmt_fetch(stmt); \
2405
check_execute(stmt, rc); \
2407
fprintf(stdout, "\n row 3: %d, %s(%lu)", r_int_data, \
2408
r_str_data, r_str_length); \
2409
DIE_UNLESS((r_int_data == i3) && (r_str_length == l3) && \
2410
(strcmp(r_str_data, s3) == 0)); \
2411
rc= mysql_stmt_fetch(stmt); \
2412
DIE_UNLESS(rc == MYSQL_NO_DATA); \
2413
mysql_free_result(r_metadata);
2417
Test that prepared statements make use of the query cache just as normal
2418
statements (BUG#735).
2420
static void test_ps_query_cache()
2422
MYSQL *org_mysql= mysql, *lmysql;
2425
MYSQL_BIND p_bind[2],r_bind[2]; /* p: param bind; r: result bind */
2426
int32 p_int_data, r_int_data;
2427
char p_str_data[32], r_str_data[32];
2428
unsigned long p_str_length, r_str_length;
2429
MYSQL_RES *r_metadata;
2430
char query[MAX_TEST_QUERY_LENGTH];
2432
enum enum_test_ps_query_cache
2435
We iterate the same prepare/executes block, but have iterations where
2436
we vary the query cache conditions.
2438
/* the query cache is enabled for the duration of prep&execs: */
2441
same but using a new connection (to see if qcache serves results from
2442
the previous connection as it should):
2444
TEST_QCACHE_ON_WITH_OTHER_CONN,
2446
First border case: disables the query cache before prepare and
2447
re-enables it before execution (to test if we have no bug then):
2451
Second border case: enables the query cache before prepare and
2452
disables it before execution:
2456
enum enum_test_ps_query_cache iteration;
2459
myheader("test_ps_query_cache");
2461
/* prepare the table */
2463
rc= mysql_query(mysql, "drop table if exists t1");
2466
rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2467
"value2 varchar(100), value1 varchar(100))");
2470
rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2471
"(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2474
for (iteration= TEST_QCACHE_ON; iteration < TEST_QCACHE_ON_OFF; iteration++)
2479
case TEST_QCACHE_ON:
2480
case TEST_QCACHE_ON_OFF:
2481
rc= mysql_query(mysql, "set global query_cache_size=1000000");
2484
case TEST_QCACHE_OFF_ON:
2485
rc= mysql_query(mysql, "set global query_cache_size=0");
2488
case TEST_QCACHE_ON_WITH_OTHER_CONN:
2490
fprintf(stdout, "\n Establishing a test connection ...");
2491
if (!(lmysql= mysql_init(NULL)))
2493
myerror("mysql_init() failed");
2496
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
2497
opt_password, current_db, opt_port,
2498
opt_unix_socket, 0)))
2500
myerror("connection failed");
2501
mysql_close(lmysql);
2505
fprintf(stdout, "OK");
2509
strmov(query, "select id1, value1 from t1 where id1= ? or "
2510
"CONVERT(value1 USING utf8)= ?");
2511
stmt= mysql_simple_prepare(mysql, query);
2514
verify_param_count(stmt, 2);
2518
case TEST_QCACHE_OFF_ON:
2519
rc= mysql_query(mysql, "set global query_cache_size=1000000");
2522
case TEST_QCACHE_ON_OFF:
2523
rc= mysql_query(mysql, "set global query_cache_size=0");
2529
bzero((char*) p_bind, sizeof(p_bind));
2530
p_bind[0].buffer_type= MYSQL_TYPE_LONG;
2531
p_bind[0].buffer= (void *)&p_int_data;
2532
p_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2533
p_bind[1].buffer= (void *)p_str_data;
2534
p_bind[1].buffer_length= array_elements(p_str_data);
2535
p_bind[1].length= &p_str_length;
2537
rc= mysql_stmt_bind_param(stmt, p_bind);
2538
check_execute(stmt, rc);
2541
strmov(p_str_data, "hh");
2542
p_str_length= strlen(p_str_data);
2544
bzero((char*) r_bind, sizeof(r_bind));
2545
r_bind[0].buffer_type= MYSQL_TYPE_LONG;
2546
r_bind[0].buffer= (void *)&r_int_data;
2547
r_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2548
r_bind[1].buffer= (void *)r_str_data;
2549
r_bind[1].buffer_length= array_elements(r_str_data);
2550
r_bind[1].length= &r_str_length;
2552
rc= mysql_stmt_bind_result(stmt, r_bind);
2553
check_execute(stmt, rc);
2555
rc= mysql_stmt_execute(stmt);
2556
check_execute(stmt, rc);
2558
test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2560
/* now retry with the same parameter values and see qcache hits */
2561
hits1= query_cache_hits(mysql);
2562
rc= mysql_stmt_execute(stmt);
2563
check_execute(stmt, rc);
2564
test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2565
hits2= query_cache_hits(mysql);
2568
case TEST_QCACHE_ON_WITH_OTHER_CONN:
2569
case TEST_QCACHE_ON: /* should have hit */
2570
DIE_UNLESS(hits2-hits1 == 1);
2572
case TEST_QCACHE_OFF_ON:
2573
case TEST_QCACHE_ON_OFF: /* should not have hit */
2574
DIE_UNLESS(hits2-hits1 == 0);
2577
/* now modify parameter values and see qcache hits */
2578
strmov(p_str_data, "ii");
2579
p_str_length= strlen(p_str_data);
2580
rc= mysql_stmt_execute(stmt);
2581
check_execute(stmt, rc);
2582
test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2583
hits1= query_cache_hits(mysql);
2587
case TEST_QCACHE_ON:
2588
case TEST_QCACHE_OFF_ON:
2589
case TEST_QCACHE_ON_OFF: /* should not have hit */
2590
DIE_UNLESS(hits2-hits1 == 0);
2592
case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2593
DIE_UNLESS(hits1-hits2 == 1);
2596
rc= mysql_stmt_execute(stmt);
2597
check_execute(stmt, rc);
2599
test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2600
hits2= query_cache_hits(mysql);
2602
mysql_stmt_close(stmt);
2606
case TEST_QCACHE_ON: /* should have hit */
2607
DIE_UNLESS(hits2-hits1 == 1);
2609
case TEST_QCACHE_OFF_ON:
2610
case TEST_QCACHE_ON_OFF: /* should not have hit */
2611
DIE_UNLESS(hits2-hits1 == 0);
2613
case TEST_QCACHE_ON_WITH_OTHER_CONN:
2614
mysql_close(lmysql);
2618
} /* for(iteration=...) */
2620
rc= mysql_query(mysql, "set global query_cache_size=0");
2357
2626
/* Test BUG#1115 (incorrect string parameter value allocation) */
2359
2628
static void test_bug1115()
15118
15418
rc= mysql_query(mysql, "flush logs");
15121
master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1);
15122
strcpy(master_log_filename, opt_vardir);
15123
strcat(master_log_filename, "/log/master.log");
15124
printf("Opening '%s'\n", master_log_filename);
15125
log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(MY_WME));
15126
free(master_log_filename);
15128
if (log_file != NULL) {
15130
for (statement_cursor= statements; statement_cursor->buffer != NULL;
15131
statement_cursor++) {
15132
int expected_hits= 1, hits= 0;
15133
char line_buffer[MAX_TEST_QUERY_LENGTH*2];
15134
/* more than enough room for the query and some marginalia. */
15136
/* Prepared statments always occurs twice in log */
15137
if (statement_cursor->qt == QT_PREPARED)
15140
/* Loop until we found expected number of log entries */
15421
for (statement_cursor= statements; statement_cursor->buffer != NULL;
15422
statement_cursor++)
15424
int expected_hits= 1, hits= 0;
15425
char line_buffer[MAX_TEST_QUERY_LENGTH*2];
15426
/* more than enough room for the query and some marginalia. */
15428
/* Prepared statments always occurs twice in log */
15429
if (statement_cursor->qt == QT_PREPARED)
15432
/* Loop until we found expected number of log entries */
15434
/* Loop until statement is found in log */
15142
/* Loop until statement is found in log */
15144
memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
15146
if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
15148
/* If fgets returned NULL, it indicates either error or EOF */
15149
if (feof(log_file))
15150
DIE("Found EOF before all statements where found");
15152
fprintf(stderr, "Got error %d while reading from file\n",
15157
} while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
15158
statement_cursor->buffer,
15159
statement_cursor->length) == NULL);
15161
} while (hits < expected_hits);
15436
memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
15438
if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
15440
/* If fgets returned NULL, it indicates either error or EOF */
15441
if (feof(log_file))
15442
DIE("Found EOF before all statements where found");
15444
fprintf(stderr, "Got error %d while reading from file\n",
15449
} while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
15450
statement_cursor->buffer,
15451
statement_cursor->length) == NULL);
15453
} while (hits < expected_hits);
15163
15456
printf("Found statement starting with \"%s\"\n",
15164
15457
statement_cursor->buffer);
15167
15461
printf("success. All queries found intact in the log.\n");
15172
fprintf(stderr, "Could not find the log file, VARDIR/log/master.log, so "
15173
"test_bug17667 is \ninconclusive. Run test from the "
15174
"mysql-test/mysql-test-run* program \nto set up the correct "
15175
"environment for this test.\n\n");
15178
if (log_file != NULL)
15179
my_fclose(log_file, MYF(0));
15463
my_fclose(log_file, MYF(0));