diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 8 | ||||
-rw-r--r-- | tests/connect_test.c | 1 | ||||
-rw-r--r-- | tests/deadlock_test.c | 1 | ||||
-rw-r--r-- | tests/insert_test.c | 1 | ||||
-rw-r--r-- | tests/list_test.c | 1 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 1203 | ||||
-rw-r--r-- | tests/select_test.c | 1 | ||||
-rw-r--r-- | tests/showdb_test.c | 1 | ||||
-rw-r--r-- | tests/ssl_test.c | 1 | ||||
-rw-r--r-- | tests/thread_test.c | 1 | ||||
-rw-r--r-- | tests/udf_test | 3 | ||||
-rw-r--r-- | tests/udf_test.res | 24 |
12 files changed, 1134 insertions, 112 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index de4fbb2a4f2..e66637de0aa 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -34,9 +34,11 @@ noinst_PROGRAMS = insert_test select_test thread_test # INCLUDES = -I$(top_srcdir)/include $(openssl_includes) LIBS = @CLIENT_LIBS@ -LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la -mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) -mysql_client_test_SOURCES= mysql_client_test.c +LDADD = @CLIENT_EXTRA_LDFLAGS@ \ + $(top_builddir)/libmysql/libmysqlclient.la +client_test_LDADD= $(LDADD) $(CXXLDFLAGS) \ + $(top_builddir)/mysys/libmysys.a +client_test_SOURCES= mysql_client_test.c insert_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) select_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) diff --git a/tests/connect_test.c b/tests/connect_test.c index fd81ad635ad..c68ade9f78f 100644 --- a/tests/connect_test.c +++ b/tests/connect_test.c @@ -46,6 +46,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + sock->reconnect= 1; if (mysql_select_db(sock,"test")) { diff --git a/tests/deadlock_test.c b/tests/deadlock_test.c index 65a0df5c215..ab8158e0cd8 100644 --- a/tests/deadlock_test.c +++ b/tests/deadlock_test.c @@ -227,6 +227,7 @@ int main() !mysql_real_connect(&sel, host, user, pass, db, 0,0,0 ) || !mysql_real_connect(&del_ins, host, user, pass, db, 0,0,0 )) die("Error in mysql_real_connect(): %s", mysql_error(&lock)); + lock.reconnect= sel.reconnect= del_ins.reconnect= 1; permute(order, num_queries); printf("count = %d\n", count); diff --git a/tests/insert_test.c b/tests/insert_test.c index 052c12bfdf0..2b659e9eecb 100644 --- a/tests/insert_test.c +++ b/tests/insert_test.c @@ -40,6 +40,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + mysql.reconnect= 1; num = atoi(argv[2]); count = 0; diff --git a/tests/list_test.c b/tests/list_test.c index 06bf16d2751..1d50e703133 100644 --- a/tests/list_test.c +++ b/tests/list_test.c @@ -43,6 +43,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + mysql.reconnect= 1; if (mysql_select_db(sock,argv[1]) < 0) { diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 83f8f6ab143..3cbc9918d6c 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -21,6 +21,12 @@ Main author: venu ( venu@mysql.com ) ***************************************************************************/ +/* + XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST + DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. +*/ + + #include <my_global.h> #include <my_sys.h> #include <mysql.h> @@ -29,6 +35,7 @@ #define VER "2.1" #define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */ +#define MAX_KEY 64 /* set default options */ static int opt_testcase = 0; @@ -236,6 +243,7 @@ static void client_connect() fprintf(stdout, "\n Check the connection options using --help or -?\n"); exit(1); } + mysql->reconnect= 1; if (!opt_silent) fprintf(stdout, " OK"); @@ -509,16 +517,18 @@ int my_process_stmt_result(MYSQL_STMT *stmt) buffer[i].buffer= (void *) data[i]; buffer[i].is_null= &is_null[i]; } - my_print_result_metadata(result); rc= mysql_stmt_bind_result(stmt, buffer); check_execute(stmt, rc); + rc= 1; + mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*)&rc); rc= mysql_stmt_store_result(stmt); check_execute(stmt, rc); + my_print_result_metadata(result); mysql_field_seek(result, 0); - while (mysql_stmt_fetch(stmt) == 0) + while ((rc= mysql_stmt_fetch(stmt)) == 0) { if (!opt_silent) { @@ -551,6 +561,7 @@ int my_process_stmt_result(MYSQL_STMT *stmt) } row_count++; } + DIE_UNLESS(rc == MYSQL_NO_DATA); if (!opt_silent) { if (row_count) @@ -651,10 +662,12 @@ static void verify_prepare_field(MYSQL_RES *result, fprintf(stdout, "\n org_name :`%s`\t(expected: `%s`)", field->org_name, org_name); fprintf(stdout, "\n type :`%d`\t(expected: `%d`)", field->type, type); - fprintf(stdout, "\n table :`%s`\t(expected: `%s`)", - field->table, table); - fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)", - field->org_table, org_table); + if (table) + fprintf(stdout, "\n table :`%s`\t(expected: `%s`)", + field->table, table); + if (org_table) + fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)", + field->org_table, org_table); fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db); fprintf(stdout, "\n length :`%ld`\t(expected: `%ld`)", field->length, length * cs->mbmaxlen); @@ -674,16 +687,30 @@ static void verify_prepare_field(MYSQL_RES *result, expect. */ if (cs->mbmaxlen == 1) - DIE_UNLESS(field->type == type); - DIE_UNLESS(strcmp(field->table, table) == 0); - DIE_UNLESS(strcmp(field->org_table, org_table) == 0); + { + if (field->type != type) + { + fprintf(stderr, "Expected field type: %d, got type: %d\n", + (int) type, (int) field->type); + DIE_UNLESS(field->type == type); + } + } + if (table) + DIE_UNLESS(strcmp(field->table, table) == 0); + if (org_table) + DIE_UNLESS(strcmp(field->org_table, org_table) == 0); DIE_UNLESS(strcmp(field->db, db) == 0); /* Character set should be taken into account for multibyte encodings, such as utf8. Field length is calculated as number of characters * maximum number of bytes a character can occupy. */ - DIE_UNLESS(field->length == length * cs->mbmaxlen); + if (length && field->length != length * cs->mbmaxlen) + { + fprintf(stderr, "Expected field length: %d, got length: %d\n", + (int) (length * cs->mbmaxlen), (int) field->length); + DIE_UNLESS(field->length == length * cs->mbmaxlen); + } if (def) DIE_UNLESS(strcmp(field->def, def) == 0); } @@ -707,8 +734,8 @@ static void verify_st_affected_rows(MYSQL_STMT *stmt, ulonglong exp_count) { ulonglong affected_rows= mysql_stmt_affected_rows(stmt); if (!opt_silent) - fprintf(stdout, "\n total affected rows: `%lld` (expected: `%lld`)", - affected_rows, exp_count); + fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)", + (long) affected_rows, (long) exp_count); DIE_UNLESS(affected_rows == exp_count); } @@ -719,8 +746,8 @@ static void verify_affected_rows(ulonglong exp_count) { ulonglong affected_rows= mysql_affected_rows(mysql); if (!opt_silent) - fprintf(stdout, "\n total affected rows: `%lld` (expected: `%lld`)", - affected_rows, exp_count); + fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)", + (long) affected_rows, (long) exp_count); DIE_UNLESS(affected_rows == exp_count); } @@ -753,8 +780,8 @@ static void execute_prepare_query(const char *query, ulonglong exp_count) affected_rows= mysql_stmt_affected_rows(stmt); if (!opt_silent) - fprintf(stdout, "\n total affected rows: `%lld` (expected: `%lld`)", - affected_rows, exp_count); + fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)", + (long) affected_rows, (long) exp_count); DIE_UNLESS(affected_rows == exp_count); mysql_stmt_close(stmt); @@ -802,6 +829,218 @@ static void client_use_result() } +/* + Accepts arbitrary number of queries and runs them against the database. + Used to fill tables for each test. +*/ + +void fill_tables(const char **query_list, unsigned query_count) +{ + int rc; + const char **query; + DBUG_ENTER("fill_tables"); + for (query= query_list; query < query_list + query_count; + ++query) + { + rc= mysql_query(mysql, *query); + myquery(rc); + } + DBUG_VOID_RETURN; +} + +/* + All state of fetch from one statement: statement handle, out buffers, + fetch position. + See fetch_n for for the only use case. +*/ + +enum { MAX_COLUMN_LENGTH= 255 }; + +typedef struct st_stmt_fetch +{ + const char *query; + unsigned stmt_no; + MYSQL_STMT *handle; + my_bool is_open; + MYSQL_BIND *bind_array; + char **out_data; + unsigned long *out_data_length; + unsigned column_count; + unsigned row_count; +} Stmt_fetch; + + +/* + Create statement handle, prepare it with statement, execute and allocate + fetch buffers. +*/ + +void stmt_fetch_init(Stmt_fetch *fetch, unsigned stmt_no_arg, + const char *query_arg) +{ + unsigned long type= CURSOR_TYPE_READ_ONLY; + int rc; + unsigned i; + MYSQL_RES *metadata; + DBUG_ENTER("stmt_fetch_init"); + + /* Save query and statement number for error messages */ + fetch->stmt_no= stmt_no_arg; + fetch->query= query_arg; + + fetch->handle= mysql_stmt_init(mysql); + + rc= mysql_stmt_prepare(fetch->handle, fetch->query, strlen(fetch->query)); + check_execute(fetch->handle, rc); + + /* + The attribute is sent to server on execute and asks to open read-only + for result set + */ + mysql_stmt_attr_set(fetch->handle, STMT_ATTR_CURSOR_TYPE, + (const void*) &type); + + rc= mysql_stmt_execute(fetch->handle); + check_execute(fetch->handle, rc); + + /* Find out total number of columns in result set */ + metadata= mysql_stmt_result_metadata(fetch->handle); + fetch->column_count= mysql_num_fields(metadata); + mysql_free_result(metadata); + + /* + Now allocate bind handles and buffers for output data: + calloc memory to reduce number of MYSQL_BIND members we need to + set up. + */ + + fetch->bind_array= (MYSQL_BIND *) calloc(1, sizeof(MYSQL_BIND) * + fetch->column_count); + fetch->out_data= (char**) calloc(1, sizeof(char*) * fetch->column_count); + fetch->out_data_length= (ulong*) calloc(1, sizeof(ulong) * + fetch->column_count); + for (i= 0; i < fetch->column_count; ++i) + { + fetch->out_data[i]= (char*) calloc(1, MAX_COLUMN_LENGTH); + fetch->bind_array[i].buffer_type= MYSQL_TYPE_STRING; + fetch->bind_array[i].buffer= fetch->out_data[i]; + fetch->bind_array[i].buffer_length= MAX_COLUMN_LENGTH; + fetch->bind_array[i].length= fetch->out_data_length + i; + } + + mysql_stmt_bind_result(fetch->handle, fetch->bind_array); + + fetch->row_count= 0; + fetch->is_open= TRUE; + + /* Ready for reading rows */ + DBUG_VOID_RETURN; +} + + +/* Fetch and print one row from cursor */ + +int stmt_fetch_fetch_row(Stmt_fetch *fetch) +{ + int rc; + unsigned i; + DBUG_ENTER("stmt_fetch_fetch_row"); + + if ((rc= mysql_stmt_fetch(fetch->handle)) == 0) + { + ++fetch->row_count; + if (!opt_silent) + printf("Stmt %d fetched row %d:\n", fetch->stmt_no, fetch->row_count); + for (i= 0; i < fetch->column_count; ++i) + { + fetch->out_data[i][fetch->out_data_length[i]]= '\0'; + if (!opt_silent) + printf("column %d: %s\n", i+1, fetch->out_data[i]); + } + } + else + fetch->is_open= FALSE; + DBUG_RETURN(rc); +} + + +void stmt_fetch_close(Stmt_fetch *fetch) +{ + unsigned i; + DBUG_ENTER("stmt_fetch_close"); + + for (i= 0; i < fetch->column_count; ++i) + free(fetch->out_data[i]); + free(fetch->out_data); + free(fetch->out_data_length); + free(fetch->bind_array); + mysql_stmt_close(fetch->handle); + DBUG_VOID_RETURN; +} + +/* + For given array of queries, open query_count cursors and fetch + from them in simultaneous manner. + In case there was an error in one of the cursors, continue + reading from the rest. +*/ + +my_bool fetch_n(const char **query_list, unsigned query_count) +{ + unsigned open_statements= query_count; + int rc, error_count= 0; + Stmt_fetch *fetch_array= (Stmt_fetch*) calloc(1, sizeof(Stmt_fetch) * + query_count); + Stmt_fetch *fetch; + DBUG_ENTER("fetch_n"); + + for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) + { + /* Init will exit(1) in case of error */ + stmt_fetch_init(fetch, fetch - fetch_array, + query_list[fetch - fetch_array]); + } + + while (open_statements) + { + for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) + { + if (fetch->is_open && (rc= stmt_fetch_fetch_row(fetch))) + { + open_statements--; + /* + We try to fetch from the rest of the statements in case of + error + */ + if (rc != MYSQL_NO_DATA) + { + fprintf(stderr, + "Got error reading rows from statement %d,\n" + "query is: %s,\n" + "error message: %s", (int) (fetch - fetch_array), + fetch->query, + mysql_stmt_error(fetch->handle)); + error_count++; + } + } + } + } + if (error_count) + fprintf(stderr, "Fetch FAILED"); + else + { + unsigned total_row_count= 0; + for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) + total_row_count+= fetch->row_count; + if (!opt_silent) + printf("Success, total rows fetched: %d\n", total_row_count); + } + for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) + stmt_fetch_close(fetch); + free(fetch_array); + DBUG_RETURN(error_count != 0); +} + /* Separate thread query to test some cases */ static my_bool thread_query(char *query) @@ -825,6 +1064,7 @@ static my_bool thread_query(char *query) error= 1; goto end; } + l_mysql->reconnect= 1; if (mysql_query(l_mysql, (char *)query)) { fprintf(stderr, "Query failed (%s)\n", mysql_error(l_mysql)); @@ -1184,7 +1424,9 @@ static void test_prepare_field_result() "t1", "test_prepare_field_result", current_db, 10, 0); verify_prepare_field(result, 3, "ts_c", "ts_c", MYSQL_TYPE_TIMESTAMP, "t1", "test_prepare_field_result", current_db, 19, 0); - verify_prepare_field(result, 4, "char_c", "char_c", MYSQL_TYPE_VAR_STRING, + verify_prepare_field(result, 4, "char_c", "char_c", + (mysql_get_server_version(mysql) <= 50000 ? + MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING), "t1", "test_prepare_field_result", current_db, 4, 0); verify_field_count(result, 5); @@ -1238,6 +1480,7 @@ static void test_prepare() double double_data, o_double_data; ulong length[7], len; my_bool is_null[7]; + char llbuf[22]; MYSQL_BIND bind[7]; myheader("test_prepare"); @@ -1352,11 +1595,11 @@ static void test_prepare() if (!opt_silent) { fprintf(stdout, "\n"); - fprintf(stdout, "\n\t tiny : %d (%lu)", tiny_data, length[0]); fprintf(stdout, "\n\t short : %d (%lu)", small_data, length[3]); fprintf(stdout, "\n\t int : %d (%lu)", int_data, length[2]); - fprintf(stdout, "\n\t big : %lld (%lu)", big_data, length[4]); + fprintf(stdout, "\n\t big : %s (%lu)", llstr(big_data, llbuf), + length[4]); fprintf(stdout, "\n\t float : %f (%lu)", real_data, length[5]); fprintf(stdout, "\n\t double : %f (%lu)", double_data, length[6]); @@ -1695,6 +1938,7 @@ static void test_fetch_null() myquery(rc); /* fetch */ + bzero(bind, sizeof(bind)); for (i= 0; i < (int) array_elements(bind); i++) { bind[i].buffer_type= MYSQL_TYPE_LONG; @@ -2763,11 +3007,13 @@ static void test_long_data_str1() bind[0].buffer= (void *) &data; /* this buffer won't be altered */ bind[0].buffer_length= 16; bind[0].length= &blob_length; + bind[0].error= &bind[0].error_value; rc= mysql_stmt_bind_result(stmt, bind); data[16]= 0; rc= mysql_stmt_fetch(stmt); - DIE_UNLESS(rc == 0); + DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); + DIE_UNLESS(bind[0].error_value); DIE_UNLESS(strlen(data) == 16); DIE_UNLESS(blob_length == max_blob_length); @@ -3131,10 +3377,10 @@ static void test_bind_result() /* fetch */ + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_LONG; bind[0].buffer= (void *) &nData; /* integer data */ bind[0].is_null= &is_null[0]; - bind[0].length= 0; bind[1].buffer_type= MYSQL_TYPE_STRING; bind[1].buffer= szData; /* string data */ @@ -3203,7 +3449,7 @@ static void test_bind_result_ext() MYSQL_BIND bind[8]; ulong length[8]; my_bool is_null[8]; - + char llbuf[22]; myheader("test_bind_result_ext"); rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result"); @@ -3225,6 +3471,7 @@ static void test_bind_result_ext() rc= mysql_commit(mysql); myquery(rc); + bzero(bind, sizeof(bind)); for (i= 0; i < (int) array_elements(bind); i++) { bind[i].length= &length[i]; @@ -3276,7 +3523,7 @@ static void test_bind_result_ext() fprintf(stdout, "\n data (tiny) : %d", t_data); fprintf(stdout, "\n data (short) : %d", s_data); fprintf(stdout, "\n data (int) : %d", i_data); - fprintf(stdout, "\n data (big) : %lld", b_data); + fprintf(stdout, "\n data (big) : %s", llstr(b_data, llbuf)); fprintf(stdout, "\n data (float) : %f", f_data); fprintf(stdout, "\n data (double) : %f", d_data); @@ -3343,37 +3590,46 @@ static void test_bind_result_ext1() rc= mysql_commit(mysql); myquery(rc); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_STRING; bind[0].buffer= (void *) t_data; bind[0].buffer_length= sizeof(t_data); + bind[0].error= &bind[0].error_value; bind[1].buffer_type= MYSQL_TYPE_FLOAT; bind[1].buffer= (void *)&s_data; bind[1].buffer_length= 0; + bind[1].error= &bind[1].error_value; bind[2].buffer_type= MYSQL_TYPE_SHORT; bind[2].buffer= (void *)&i_data; bind[2].buffer_length= 0; + bind[2].error= &bind[2].error_value; bind[3].buffer_type= MYSQL_TYPE_TINY; bind[3].buffer= (void *)&b_data; bind[3].buffer_length= 0; + bind[3].error= &bind[3].error_value; bind[4].buffer_type= MYSQL_TYPE_LONG; bind[4].buffer= (void *)&f_data; bind[4].buffer_length= 0; + bind[4].error= &bind[4].error_value; bind[5].buffer_type= MYSQL_TYPE_STRING; bind[5].buffer= (void *)d_data; bind[5].buffer_length= sizeof(d_data); + bind[5].error= &bind[5].error_value; bind[6].buffer_type= MYSQL_TYPE_LONG; bind[6].buffer= (void *)&bData; bind[6].buffer_length= 0; + bind[6].error= &bind[6].error_value; bind[7].buffer_type= MYSQL_TYPE_DOUBLE; bind[7].buffer= (void *)&szData; bind[7].buffer_length= 0; + bind[7].error= &bind[7].error_value; for (i= 0; i < array_elements(bind); i++) { @@ -3391,7 +3647,8 @@ static void test_bind_result_ext1() check_execute(stmt, rc); rc= mysql_stmt_fetch(stmt); - check_execute(stmt, rc); + DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); + DIE_UNLESS(bind[4].error_value == 1); if (!opt_silent) { @@ -3626,6 +3883,7 @@ static void test_fetch_date() rc= mysql_commit(mysql); myquery(rc); + bzero(bind, sizeof(bind)); for (i= 0; i < array_elements(bind); i++) { bind[i].is_null= &is_null[i]; @@ -4306,6 +4564,7 @@ static void test_stmt_close() myerror("connection failed"); exit(1); } + lmysql->reconnect= 1; if (!opt_silent) fprintf(stdout, " OK"); @@ -4427,8 +4686,6 @@ static void test_set_variable() get_bind[1].buffer_type= MYSQL_TYPE_LONG; get_bind[1].buffer= (void *)&get_count; - get_bind[1].is_null= 0; - get_bind[1].length= 0; rc= mysql_stmt_execute(stmt1); check_execute(stmt1, rc); @@ -5032,7 +5289,7 @@ static void test_manual_sample() affected_rows= mysql_stmt_affected_rows(stmt); if (!opt_silent) - fprintf(stdout, "\n total affected rows: %lld", affected_rows); + fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows); if (affected_rows != 1) /* validate affected rows */ { fprintf(stderr, "\n invalid affected rows by MySQL"); @@ -5057,7 +5314,7 @@ static void test_manual_sample() affected_rows= mysql_stmt_affected_rows(stmt); if (!opt_silent) - fprintf(stdout, "\n total affected rows: %lld", affected_rows); + fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows); if (affected_rows != 1) /* validate affected rows */ { fprintf(stderr, "\n invalid affected rows by MySQL"); @@ -5198,6 +5455,7 @@ DROP TABLE IF EXISTS test_multi_tab"; fprintf(stdout, "\n connection failed(%s)", mysql_error(mysql_local)); exit(1); } + mysql_local->reconnect= 1; rc= mysql_query(mysql_local, query); myquery(rc); @@ -5212,9 +5470,9 @@ DROP TABLE IF EXISTS test_multi_tab"; mysql_free_result(result); } else if (!opt_silent) - fprintf(stdout, "OK, %lld row(s) affected, %d warning(s)\n", - mysql_affected_rows(mysql_local), - mysql_warning_count(mysql_local)); + fprintf(stdout, "OK, %ld row(s) affected, %ld warning(s)\n", + (ulong) mysql_affected_rows(mysql_local), + (ulong) mysql_warning_count(mysql_local)); exp_value= (uint) mysql_affected_rows(mysql_local); if (rows[count] != exp_value) @@ -5306,6 +5564,7 @@ static void test_prepare_multi_statements() fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local)); exit(1); } + mysql_local->reconnect= 1; strmov(query, "select 1; select 'another value'"); stmt= mysql_simple_prepare(mysql_local, query); check_stmt_r(stmt); @@ -5343,6 +5602,7 @@ static void test_store_result() myquery(rc); /* fetch */ + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_LONG; bind[0].buffer= (void *) &nData; /* integer data */ bind[0].length= &length; @@ -5592,6 +5852,7 @@ static void test_subselect() MYSQL_STMT *stmt; int rc, id; MYSQL_BIND bind[1]; + DBUG_ENTER("test_subselect"); myheader("test_subselect"); @@ -5697,6 +5958,7 @@ static void test_subselect() DIE_UNLESS(rc == MYSQL_NO_DATA); mysql_stmt_close(stmt); + DBUG_VOID_RETURN; } @@ -5804,7 +6066,7 @@ static void test_bind_date_conv(uint row_count) for (count= 0; count < row_count; count++) { rc= mysql_stmt_fetch(stmt); - check_execute(stmt, rc); + DIE_UNLESS(rc == 0 || rc == MYSQL_DATA_TRUNCATED); if (!opt_silent) fprintf(stdout, "\n"); @@ -5820,14 +6082,8 @@ static void test_bind_date_conv(uint row_count) DIE_UNLESS(tm[i].day == 0 || tm[i].day == day+count); DIE_UNLESS(tm[i].hour == 0 || tm[i].hour == hour+count); -#ifdef NOT_USED - /* - minute causes problems from date<->time, don't assert, instead - validate separatly in another routine - */ DIE_UNLESS(tm[i].minute == 0 || tm[i].minute == minute+count); DIE_UNLESS(tm[i].second == 0 || tm[i].second == sec+count); -#endif DIE_UNLESS(tm[i].second_part == 0 || tm[i].second_part == second_part+count); } @@ -6058,13 +6314,15 @@ static void test_buffers() rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - bzero(buffer, 20); /* Avoid overruns in printf() */ + bzero(buffer, sizeof(buffer)); /* Avoid overruns in printf() */ + bzero(bind, sizeof(bind)); bind[0].length= &length; bind[0].is_null= &is_null; bind[0].buffer_length= 1; bind[0].buffer_type= MYSQL_TYPE_STRING; bind[0].buffer= (void *)buffer; + bind[0].error= &bind[0].error_value; rc= mysql_stmt_bind_result(stmt, bind); check_execute(stmt, rc); @@ -6074,7 +6332,8 @@ static void test_buffers() buffer[1]= 'X'; rc= mysql_stmt_fetch(stmt); - check_execute(stmt, rc); + DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); + DIE_UNLESS(bind[0].error_value); if (!opt_silent) fprintf(stdout, "\n data: %s (%lu)", buffer, length); DIE_UNLESS(buffer[0] == 'M'); @@ -6108,7 +6367,8 @@ static void test_buffers() check_execute(stmt, rc); rc= mysql_stmt_fetch(stmt); - check_execute(stmt, rc); + DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); + DIE_UNLESS(bind[0].error_value); if (!opt_silent) fprintf(stdout, "\n data: %s (%lu)", buffer, length); DIE_UNLESS(strncmp(buffer, "Popula", 6) == 0); @@ -6245,10 +6505,9 @@ static void test_fetch_nobuffs() fprintf(stdout, "\n total rows : %d", rc); DIE_UNLESS(rc == 1); + bzero(bind, sizeof(MYSQL_BIND)); bind[0].buffer_type= MYSQL_TYPE_STRING; bind[0].buffer= (void *)str[0]; - bind[0].is_null= 0; - bind[0].length= 0; bind[0].buffer_length= sizeof(str[0]); bind[1]= bind[2]= bind[3]= bind[0]; bind[1].buffer= (void *)str[1]; @@ -6293,7 +6552,7 @@ static void test_ushort_bug() ulonglong longlong_value; int rc; uchar tiny_value; - + char llbuf[22]; myheader("test_ushort_bug"); rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ushort"); @@ -6305,7 +6564,8 @@ static void test_ushort_bug() d smallint unsigned)"); myquery(rc); - rc= mysql_query(mysql, "INSERT INTO test_ushort VALUES(35999, 35999, 35999, 200)"); + rc= mysql_query(mysql, + "INSERT INTO test_ushort VALUES(35999, 35999, 35999, 200)"); myquery(rc); @@ -6315,24 +6575,23 @@ static void test_ushort_bug() rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_SHORT; bind[0].buffer= (void *)&short_value; - bind[0].is_null= 0; + bind[0].is_unsigned= TRUE; bind[0].length= &s_length; bind[1].buffer_type= MYSQL_TYPE_LONG; bind[1].buffer= (void *)&long_value; - bind[1].is_null= 0; bind[1].length= &l_length; bind[2].buffer_type= MYSQL_TYPE_LONGLONG; bind[2].buffer= (void *)&longlong_value; - bind[2].is_null= 0; bind[2].length= &ll_length; bind[3].buffer_type= MYSQL_TYPE_TINY; bind[3].buffer= (void *)&tiny_value; - bind[3].is_null= 0; + bind[3].is_unsigned= TRUE; bind[3].length= &t_length; rc= mysql_stmt_bind_result(stmt, bind); @@ -6345,7 +6604,8 @@ static void test_ushort_bug() { fprintf(stdout, "\n ushort : %d (%ld)", short_value, s_length); fprintf(stdout, "\n ulong : %lu (%ld)", (ulong) long_value, l_length); - fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length); + fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf), + ll_length); fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length); } @@ -6380,6 +6640,7 @@ static void test_sshort_bug() ulonglong longlong_value; int rc; uchar tiny_value; + char llbuf[22]; myheader("test_sshort_bug"); @@ -6402,24 +6663,22 @@ static void test_sshort_bug() rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_SHORT; bind[0].buffer= (void *)&short_value; - bind[0].is_null= 0; bind[0].length= &s_length; bind[1].buffer_type= MYSQL_TYPE_LONG; bind[1].buffer= (void *)&long_value; - bind[1].is_null= 0; bind[1].length= &l_length; bind[2].buffer_type= MYSQL_TYPE_LONGLONG; bind[2].buffer= (void *)&longlong_value; - bind[2].is_null= 0; bind[2].length= &ll_length; bind[3].buffer_type= MYSQL_TYPE_TINY; bind[3].buffer= (void *)&tiny_value; - bind[3].is_null= 0; + bind[3].is_unsigned= TRUE; bind[3].length= &t_length; rc= mysql_stmt_bind_result(stmt, bind); @@ -6432,7 +6691,8 @@ static void test_sshort_bug() { fprintf(stdout, "\n sshort : %d (%ld)", short_value, s_length); fprintf(stdout, "\n slong : %ld (%ld)", (long) long_value, l_length); - fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length); + fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf), + ll_length); fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length); } @@ -6467,6 +6727,7 @@ static void test_stiny_bug() ulonglong longlong_value; int rc; uchar tiny_value; + char llbuf[22]; myheader("test_stiny_bug"); @@ -6489,24 +6750,21 @@ static void test_stiny_bug() rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_SHORT; bind[0].buffer= (void *)&short_value; - bind[0].is_null= 0; bind[0].length= &s_length; bind[1].buffer_type= MYSQL_TYPE_LONG; bind[1].buffer= (void *)&long_value; - bind[1].is_null= 0; bind[1].length= &l_length; bind[2].buffer_type= MYSQL_TYPE_LONGLONG; bind[2].buffer= (void *)&longlong_value; - bind[2].is_null= 0; bind[2].length= &ll_length; bind[3].buffer_type= MYSQL_TYPE_TINY; bind[3].buffer= (void *)&tiny_value; - bind[3].is_null= 0; bind[3].length= &t_length; rc= mysql_stmt_bind_result(stmt, bind); @@ -6519,7 +6777,8 @@ static void test_stiny_bug() { fprintf(stdout, "\n sshort : %d (%ld)", short_value, s_length); fprintf(stdout, "\n slong : %ld (%ld)", (long) long_value, l_length); - fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length); + fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf), + ll_length); fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length); } @@ -6599,10 +6858,10 @@ static void test_field_misc() rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_STRING; bind[0].buffer= table_type; bind[0].length= &type_length; - bind[0].is_null= 0; bind[0].buffer_length= NAME_LEN; rc= mysql_stmt_bind_result(stmt, bind); @@ -6632,7 +6891,8 @@ static void test_field_misc() verify_prepare_field(result, 0, "@@table_type", "", /* field and its org name */ - MYSQL_TYPE_STRING, /* field type */ + mysql_get_server_version(mysql) <= 50000 ? + MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, "", "", /* table and its org name */ "", type_length, 0); /* db name, length */ @@ -6672,10 +6932,10 @@ static void test_field_misc() DIE_UNLESS(1 == my_process_stmt_result(stmt)); verify_prepare_field(result, 0, - "@@max_allowed_packet", "", /* field and its org name */ + "@@max_allowed_packet", "", /* field and its org name */ MYSQL_TYPE_LONGLONG, /* field type */ "", "", /* table and its org name */ - "", 10, 0); /* db name, length */ + "", 10, 0); /* db name, length */ mysql_free_result(result); mysql_stmt_close(stmt); @@ -6832,6 +7092,7 @@ static void test_prepare_grant() mysql_close(lmysql); exit(1); } + lmysql->reconnect= 1; if (!opt_silent) fprintf(stdout, " OK"); @@ -6907,11 +7168,10 @@ static void test_frm_bug() rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_STRING; bind[0].buffer= data_dir; bind[0].buffer_length= FN_REFLEN; - bind[0].is_null= 0; - bind[0].length= 0; bind[1]= bind[0]; rc= mysql_stmt_bind_result(stmt, bind); @@ -7107,23 +7367,33 @@ static void test_explain_bug() mysql_num_fields(result)); DIE_UNLESS(6 == mysql_num_fields(result)); - verify_prepare_field(result, 0, "Field", "", MYSQL_TYPE_VAR_STRING, - "", "", "", NAME_LEN, 0); + verify_prepare_field(result, 0, "Field", "COLUMN_NAME", + mysql_get_server_version(mysql) <= 50000 ? + MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, + 0, 0, "", 64, 0); - verify_prepare_field(result, 1, "Type", "", MYSQL_TYPE_VAR_STRING, - "", "", "", 40, 0); + verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", + MYSQL_TYPE_BLOB, 0, 0, "", 0, 0); - verify_prepare_field(result, 2, "Null", "", MYSQL_TYPE_VAR_STRING, - "", "", "", 1, 0); + verify_prepare_field(result, 2, "Null", "IS_NULLABLE", + mysql_get_server_version(mysql) <= 50000 ? + MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, + 0, 0, "", 3, 0); - verify_prepare_field(result, 3, "Key", "", MYSQL_TYPE_VAR_STRING, - "", "", "", 3, 0); + verify_prepare_field(result, 3, "Key", "COLUMN_KEY", + mysql_get_server_version(mysql) <= 50000 ? + MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, + 0, 0, "", 3, 0); - verify_prepare_field(result, 4, "Default", "", MYSQL_TYPE_VAR_STRING, - "", "", "", NAME_LEN, 0); + verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT", + mysql_get_server_version(mysql) <= 50000 ? + MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, + 0, 0, "", 64, 0); - verify_prepare_field(result, 5, "Extra", "", MYSQL_TYPE_VAR_STRING, - "", "", "", 20, 0); + verify_prepare_field(result, 5, "Extra", "EXTRA", + mysql_get_server_version(mysql) <= 50000 ? + MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, + 0, 0, "", 20, 0); mysql_free_result(result); mysql_stmt_close(stmt); @@ -7158,7 +7428,7 @@ static void test_explain_bug() "", "", "", 10, 0); verify_prepare_field(result, 4, "possible_keys", "", MYSQL_TYPE_VAR_STRING, - "", "", "", NAME_LEN*64, 0); + "", "", "", NAME_LEN*MAX_KEY, 0); verify_prepare_field(result, 5, "key", "", MYSQL_TYPE_VAR_STRING, "", "", "", NAME_LEN, 0); @@ -7267,6 +7537,7 @@ static void test_drop_temp() mysql_close(lmysql); exit(1); } + lmysql->reconnect= 1; if (!opt_silent) fprintf(stdout, " OK"); @@ -7479,13 +7750,13 @@ static void test_logs() if (!opt_silent) { - fprintf(stdout, "\n id : %d", id); - fprintf(stdout, "\n name : %s(%ld)", data, length); + fprintf(stdout, "id : %d\n", id); + fprintf(stdout, "name : %s(%ld)\n", data, length); } DIE_UNLESS(id == 9876); - DIE_UNLESS(length == 19); /* Due to VARCHAR(20) */ - DIE_UNLESS(strcmp(data, "MySQL - Open Source") == 0); + DIE_UNLESS(length == 19 || length == 20); /* Due to VARCHAR(20) */ + DIE_UNLESS(is_prefix(data, "MySQL - Open Source") == 1); rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); @@ -7631,17 +7902,13 @@ static void test_fetch_seek() stmt= mysql_simple_prepare(mysql, "select * from t1"); check_stmt(stmt); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_LONG; bind[0].buffer= (void *)&c1; - bind[0].buffer_length= 0; - bind[0].is_null= 0; - bind[0].length= 0; bind[1].buffer_type= MYSQL_TYPE_STRING; bind[1].buffer= (void *)c2; bind[1].buffer_length= sizeof(c2); - bind[1].is_null= 0; - bind[1].length= 0; bind[2]= bind[1]; bind[2].buffer= (void *)c3; @@ -7731,6 +7998,7 @@ static void test_fetch_offset() stmt= mysql_simple_prepare(mysql, "select * from t1"); check_stmt(stmt); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_STRING; bind[0].buffer= (void *)data; bind[0].buffer_length= 11; @@ -7817,6 +8085,7 @@ static void test_fetch_column() stmt= mysql_simple_prepare(mysql, "select * from t1 order by c2 desc"); check_stmt(stmt); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_LONG; bind[0].buffer= (void *)&bc1; bind[0].buffer_length= 0; @@ -8064,10 +8333,9 @@ static void test_free_result() stmt= mysql_simple_prepare(mysql, "select * from test_free_result"); check_stmt(stmt); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_LONG; bind[0].buffer= (void *)&bc1; - bind[0].buffer_length= 0; - bind[0].is_null= 0; bind[0].length= &bl1; rc= mysql_stmt_execute(stmt); @@ -8145,6 +8413,7 @@ static void test_free_store_result() stmt= mysql_simple_prepare(mysql, "select * from test_free_result"); check_stmt(stmt); + bzero(bind, sizeof(bind)); bind[0].buffer_type= MYSQL_TYPE_LONG; bind[0].buffer= (void *)&bc1; bind[0].buffer_length= 0; @@ -8535,10 +8804,6 @@ static void test_bug1500() rc= my_process_stmt_result(stmt); DIE_UNLESS(rc == 1); - /* - FIXME If we comment out next string server will crash too :( - This is another manifestation of bug #1663 - */ mysql_stmt_close(stmt); /* This should work too */ @@ -8709,7 +8974,7 @@ static void test_subqueries() int rc, i; const char *query= "SELECT (SELECT SUM(a+b) FROM t2 where t1.b=t2.b GROUP BY t1.a LIMIT 1) as scalar_s, exists (select 1 from t2 where t2.a/2=t1.a) as exists_s, a in (select a+3 from t2) as in_s, (a-1, b-1) in (select a, b from t2) as in_row_s FROM t1, (select a x, b y from t2) tt WHERE x=a"; - myheader("test_subquery"); + myheader("test_subqueries"); rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2"); myquery(rc); @@ -8760,7 +9025,7 @@ static void test_distinct() const char *query= "SELECT 2+count(distinct b), group_concat(a) FROM t1 group by a"; - myheader("test_subquery"); + myheader("test_distinct"); rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); myquery(rc); @@ -9558,7 +9823,7 @@ static void test_bug3035() { MYSQL_STMT *stmt; int rc; - MYSQL_BIND bind_array[12]; + MYSQL_BIND bind_array[12], *bind= bind_array, *bind_end= bind + 12; int8 int8_val; uint8 uint8_val; int16 int16_val; @@ -9611,6 +9876,9 @@ static void test_bug3035() bzero(bind_array, sizeof(bind_array)); + for (bind= bind_array; bind < bind_end; bind++) + bind->error= &bind->error_value; + bind_array[0].buffer_type= MYSQL_TYPE_TINY; bind_array[0].buffer= (void *) &int8_val; @@ -9716,7 +9984,15 @@ static void test_bug3035() DIE_UNLESS(!strcmp(ulonglong_as_string, "0")); rc= mysql_stmt_fetch(stmt); - check_execute(stmt, rc); + + if (!opt_silent) + { + printf("Truncation mask: "); + for (bind= bind_array; bind < bind_end; bind++) + printf("%d", (int) bind->error_value); + printf("\n"); + } + DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0); DIE_UNLESS(int8_val == int8_max); DIE_UNLESS(uint8_val == uint8_max); @@ -10499,6 +10775,358 @@ static void test_bug4030() mysql_stmt_close(stmt); } +static void test_view() +{ + MYSQL_STMT *stmt; + int rc, i; + MYSQL_BIND bind[1]; + char str_data[50]; + ulong length = 0L; + long is_null = 0L; + const char *query= + "SELECT COUNT(*) FROM v1 WHERE `SERVERNAME`=?"; + + myheader("test_view"); + + rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1"); + myquery(rc); + + rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3"); + myquery(rc); + rc= mysql_query(mysql,"CREATE TABLE `t1` ( `SERVERGRP` varchar(20) character set latin1 collate latin1_bin NOT NULL default '', `DBINSTANCE` varchar(20) character set latin1 collate latin1_bin NOT NULL default '', PRIMARY KEY (`SERVERGRP`)) ENGINE=InnoDB DEFAULT CHARSET=latin1"); + myquery(rc); + rc= mysql_query(mysql,"CREATE TABLE `t2` ( `SERVERNAME` varchar(20) character set latin1 collate latin1_bin NOT NULL default '', `SERVERGRP` varchar(20) character set latin1 collate latin1_bin NOT NULL default '', PRIMARY KEY (`SERVERNAME`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;"); + myquery(rc); + rc= mysql_query(mysql,"CREATE TABLE `t3` ( `SERVERGRP` varchar(20) character set latin1 collate latin1_bin NOT NULL default '', `TABNAME` varchar(30) character set latin1 collate latin1_bin NOT NULL default '', `MAPSTATE` char(1) character set latin1 collate latin1_bin NOT NULL default '', `ACTSTATE` char(1) character set latin1 collate latin1_bin NOT NULL default '', `LOCAL_NAME` varchar(30) character set latin1 collate latin1_bin NOT NULL default '', `CHG_DATE` varchar(8) character set latin1 collate latin1_bin NOT NULL default '00000000', `CHG_TIME` varchar(6) character set latin1 collate latin1_bin NOT NULL default '000000', `MXUSER` varchar(12) character set latin1 collate latin1_bin NOT NULL default '', PRIMARY KEY (`SERVERGRP`,`TABNAME`,`MAPSTATE`,`ACTSTATE`,`LOCAL_NAME`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;"); + myquery(rc); + rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache T0001.SERVERNAME AS `SERVERNAME`,T0003.TABNAME AS `TABNAME`,T0003.LOCAL_NAME AS `LOCAL_NAME`,T0002.DBINSTANCE AS `DBINSTANCE` from t2 T0001 join t1 T0002 join t3 T0003 where ((T0002.SERVERGRP = T0001.SERVERGRP) and (T0002.SERVERGRP = T0003.SERVERGRP) and (T0003.MAPSTATE = _latin1'A') and (T0003.ACTSTATE = _latin1' '))"); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + + strcpy(str_data, "TEST"); + bind[0].buffer_type= FIELD_TYPE_STRING; + bind[0].buffer= (char *)&str_data; + bind[0].buffer_length= 50; + bind[0].length= &length; + length= 4; + bind[0].is_null= (char*)&is_null; + rc= mysql_stmt_bind_param(stmt, bind); + check_execute(stmt,rc); + + for (i= 0; i < 3; i++) + { + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + assert(1 == my_process_stmt_result(stmt)); + } + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "DROP TABLE t1,t2,t3"); + myquery(rc); + rc= mysql_query(mysql, "DROP VIEW v1"); + myquery(rc); +} + + +static void test_view_where() +{ + MYSQL_STMT *stmt; + int rc, i; + const char *query= + "select v1.c,v2.c from v1, v2"; + + myheader("test_view_where"); + + rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1,v2"); + myquery(rc); + + rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,v2,t1"); + myquery(rc); + rc= mysql_query(mysql,"CREATE TABLE t1 (a int, b int)"); + myquery(rc); + rc= mysql_query(mysql,"insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)"); + myquery(rc); + rc= mysql_query(mysql,"create view v1 (c) as select b from t1 where a<3"); + myquery(rc); + rc= mysql_query(mysql,"create view v2 (c) as select b from t1 where a>=3"); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + + for (i= 0; i < 3; i++) + { + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + assert(4 == my_process_stmt_result(stmt)); + } + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); + rc= mysql_query(mysql, "DROP VIEW v1, v2"); + myquery(rc); +} + + +static void test_view_2where() +{ + MYSQL_STMT *stmt; + int rc, i; + MYSQL_BIND bind[8]; + char parms[8][100]; + ulong length[8]; + const char *query= "SELECT `RELID` ,`REPORT` ,`HANDLE` ,`LOG_GROUP` ,`USERNAME` ,`VARIANT` ,`TYPE` ,`VERSION` ,`ERFDAT` ,`ERFTIME` ,`ERFNAME` ,`AEDAT` ,`AETIME` ,`AENAME` ,`DEPENDVARS` ,`INACTIVE` FROM `V_LTDX` WHERE `MANDT` = ? AND `RELID` = ? AND `REPORT` = ? AND `HANDLE` = ? AND `LOG_GROUP` = ? AND `USERNAME` IN ( ? , ? ) AND `TYPE` = ?"; + + myheader("test_view_2where"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX"); + myquery(rc); + rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX"); + myquery(rc); + rc= mysql_query(mysql, "CREATE TABLE `LTDX` ( `MANDT` char(3) character set latin1 collate latin1_bin NOT NULL default '000', `RELID` char(2) character set latin1 collate latin1_bin NOT NULL default '', `REPORT` varchar(40) character set latin1 collate latin1_bin NOT NULL default '', `HANDLE` varchar(4) character set latin1 collate latin1_bin NOT NULL default '', `LOG_GROUP` varchar(4) character set latin1 collate latin1_bin NOT NULL default '', `USERNAME` varchar(12) character set latin1 collate latin1_bin NOT NULL default '', `VARIANT` varchar(12) character set latin1 collate latin1_bin NOT NULL default '', `TYPE` char(1) character set latin1 collate latin1_bin NOT NULL default '', `SRTF2` int(11) NOT NULL default '0', `VERSION` varchar(6) character set latin1 collate latin1_bin NOT NULL default '000000', `ERFDAT` varchar(8) character set latin1 collate latin1_bin NOT NULL default '00000000', `ERFTIME` varchar(6) character set latin1 collate latin1_bin NOT NULL default '000000', `ERFNAME` varchar(12) character set latin1 collate latin1_bin NOT NULL default '', `AEDAT` varchar(8) character set latin1 collate latin1_bin NOT NULL default '00000000', `AETIME` varchar(6) character set latin1 collate latin1_bin NOT NULL default '000000', `AENAME` varchar(12) character set latin1 collate latin1_bin NOT NULL default '', `DEPENDVARS` varchar(10) character set latin1 collate latin1_bin NOT NULL default '', `INACTIVE` char(1) character set latin1 collate latin1_bin NOT NULL default '', `CLUSTR` smallint(6) NOT NULL default '0', `CLUSTD` blob, PRIMARY KEY (`MANDT`,`RELID`,`REPORT`,`HANDLE`,`LOG_GROUP`,`USERNAME`,`VARIANT`,`TYPE`,`SRTF2`)) ENGINE=InnoDB DEFAULT CHARSET=latin1"); + myquery(rc); + rc= mysql_query(mysql, "CREATE VIEW V_LTDX AS select T0001.MANDT AS `MANDT`,T0001.RELID AS `RELID`,T0001.REPORT AS `REPORT`,T0001.HANDLE AS `HANDLE`,T0001.LOG_GROUP AS `LOG_GROUP`,T0001.USERNAME AS `USERNAME`,T0001.VARIANT AS `VARIANT`,T0001.TYPE AS `TYPE`,T0001.VERSION AS `VERSION`,T0001.ERFDAT AS `ERFDAT`,T0001.ERFTIME AS `ERFTIME`,T0001.ERFNAME AS `ERFNAME`,T0001.AEDAT AS `AEDAT`,T0001.AETIME AS `AETIME`,T0001.AENAME AS `AENAME`,T0001.DEPENDVARS AS `DEPENDVARS`,T0001.INACTIVE AS `INACTIVE` from LTDX T0001 where (T0001.SRTF2 = 0)"); + myquery(rc); + for (i=0; i < 8; i++) { + strcpy(parms[i], "1"); + bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; + bind[i].buffer = (char *)&parms[i]; + bind[i].buffer_length = 100; + bind[i].is_null = 0; + bind[i].length = &length[i]; + length[i] = 1; + } + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + + rc= mysql_stmt_bind_param(stmt, bind); + check_execute(stmt,rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + assert(0 == my_process_stmt_result(stmt)); + + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "DROP VIEW V_LTDX"); + myquery(rc); + rc= mysql_query(mysql, "DROP TABLE LTDX"); + myquery(rc); +} + + +static void test_view_star() +{ + MYSQL_STMT *stmt; + int rc, i; + MYSQL_BIND bind[8]; + char parms[8][100]; + ulong length[8]; + const char *query= "SELECT * FROM vt1 WHERE a IN (?,?)"; + + myheader("test_view_star"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, vt1"); + myquery(rc); + rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, vt1"); + myquery(rc); + rc= mysql_query(mysql, "CREATE TABLE t1 (a int)"); + myquery(rc); + rc= mysql_query(mysql, "CREATE VIEW vt1 AS SELECT a FROM t1"); + myquery(rc); + for (i= 0; i < 2; i++) { + sprintf((char *)&parms[i], "%d", i); + bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; + bind[i].buffer = (char *)&parms[i]; + bind[i].buffer_length = 100; + bind[i].is_null = 0; + bind[i].length = &length[i]; + length[i] = 1; + } + + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + + rc= mysql_stmt_bind_param(stmt, bind); + check_execute(stmt,rc); + + for (i= 0; i < 3; i++) + { + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + assert(0 == my_process_stmt_result(stmt)); + } + + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); + rc= mysql_query(mysql, "DROP VIEW vt1"); + myquery(rc); +} + + +static void test_view_insert() +{ + MYSQL_STMT *insert_stmt, *select_stmt; + int rc, i; + MYSQL_BIND bind[1]; + long my_val = 0L; + ulong my_length = 0L; + long my_null = 0L; + const char *query= + "insert into v1 values (?)"; + + myheader("test_view_insert"); + + rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1"); + myquery(rc); + rc = mysql_query(mysql, "DROP VIEW IF EXISTS t1,v1"); + myquery(rc); + + rc= mysql_query(mysql,"create table t1 (a int, primary key (a))"); + myquery(rc); + + rc= mysql_query(mysql, "create view v1 as select a from t1 where a>=1"); + myquery(rc); + + insert_stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(insert_stmt, query, strlen(query)); + check_execute(insert_stmt, rc); + query= "select * from t1"; + select_stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(select_stmt, query, strlen(query)); + check_execute(select_stmt, rc); + + bind[0].buffer_type = FIELD_TYPE_LONG; + bind[0].buffer = (char *)&my_val; + bind[0].length = &my_length; + bind[0].is_null = (char*)&my_null; + rc= mysql_stmt_bind_param(insert_stmt, bind); + check_execute(insert_stmt, rc); + + for (i= 0; i < 3; i++) + { + my_val= i; + + rc= mysql_stmt_execute(insert_stmt); + check_execute(insert_stmt, rc); + + rc= mysql_stmt_execute(select_stmt); + check_execute(select_stmt, rc); + assert(i + 1 == (int) my_process_stmt_result(select_stmt)); + } + mysql_stmt_close(insert_stmt); + mysql_stmt_close(select_stmt); + + rc= mysql_query(mysql, "DROP VIEW v1"); + myquery(rc); + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); +} + + +static void test_left_join_view() +{ + MYSQL_STMT *stmt; + int rc, i; + const char *query= + "select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);"; + + myheader("test_left_join_view"); + + rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1"); + myquery(rc); + + rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1"); + myquery(rc); + rc= mysql_query(mysql,"CREATE TABLE t1 (a int)"); + myquery(rc); + rc= mysql_query(mysql,"insert into t1 values (1), (2), (3)"); + myquery(rc); + rc= mysql_query(mysql,"create view v1 (x) as select a from t1 where a > 1"); + myquery(rc); + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + + for (i= 0; i < 3; i++) + { + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + assert(3 == my_process_stmt_result(stmt)); + } + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "DROP VIEW v1"); + myquery(rc); + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); +} + + +static void test_view_insert_fields() +{ + MYSQL_STMT *stmt; + char parm[11][1000]; + ulong l[11]; + int rc, i; + MYSQL_BIND bind[11]; + const char *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )"; + + myheader("test_view_insert_fields"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1"); + myquery(rc); + rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1"); + myquery(rc); + rc= mysql_query(mysql, "CREATE TABLE t1 ( K1C4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '', K2C4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '', K3C4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '', K4N4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '0000', F1C4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '', F2I4 int(11) NOT NULL default '0', F3N5 varchar(5) character set latin1 collate latin1_bin NOT NULL default '00000', F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) character set latin1 collate latin1_bin NOT NULL default '', F6N4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '0000', F7F8 double NOT NULL default '0', F8F8 double NOT NULL default '0', F9D8 decimal(8,2) NOT NULL default '0.00', PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) ENGINE=InnoDB DEFAULT CHARSET=latin1"); + myquery(rc); + rc= mysql_query(mysql, "CREATE VIEW v1 AS select sql_no_cache K1C4 AS `K1C4`,K2C4 AS `K2C4`,K3C4 AS `K3C4`,K4N4 AS `K4N4`,F1C4 AS `F1C4`,F2I4 AS `F2I4`,F3N5 AS `F3N5`,F7F8 AS `F7F8`,F6N4 AS `F6N4`,F5C8 AS `F5C8`,F9D8 AS `F9D8` from t1 T0001"); + + for (i= 0; i < 11; i++) + { + l[i]= 20; + bind[i].buffer_type= MYSQL_TYPE_STRING; + bind[i].is_null= 0; + bind[i].buffer= (char *)&parm[i]; + + strcpy(parm[i], "1"); + bind[i].buffer_length= 2; + bind[i].length= &l[i]; + } + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + rc= mysql_stmt_bind_param(stmt, bind); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + mysql_stmt_close(stmt); + + query= "select * from t1"; + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + assert(1 == my_process_stmt_result(stmt)); + + mysql_stmt_close(stmt); + rc= mysql_query(mysql, "DROP VIEW v1"); + myquery(rc); + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); + +} static void test_bug5126() { @@ -10643,7 +11271,7 @@ static void test_bug5399() for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt) { - sprintf(buff, "select %d", stmt - stmt_list); + sprintf(buff, "select %d", (int) (stmt - stmt_list)); *stmt= mysql_stmt_init(mysql); rc= mysql_stmt_prepare(*stmt, buff, strlen(buff)); check_execute(*stmt, rc); @@ -10838,7 +11466,7 @@ static void test_bug5194() if (!opt_silent) printf("Insert: query length= %d, row count= %d, param count= %lu\n", - strlen(query), nrows, mysql_stmt_param_count(stmt)); + (int) strlen(query), nrows, mysql_stmt_param_count(stmt)); /* bind the parameter array and execute the query */ rc= mysql_stmt_bind_param(stmt, bind); @@ -11050,6 +11678,62 @@ static void test_bug6046() } + +static void test_basic_cursors() +{ + const char *basic_tables[]= + { + "DROP TABLE IF EXISTS t1, t2", + + "CREATE TABLE t1 " + "(id INTEGER NOT NULL PRIMARY KEY, " + " name VARCHAR(20) NOT NULL)", + + "INSERT INTO t1 (id, name) VALUES " + " (2, 'Ja'), (3, 'Ede'), " + " (4, 'Haag'), (5, 'Kabul'), " + " (6, 'Almere'), (7, 'Utrecht'), " + " (8, 'Qandahar'), (9, 'Amsterdam'), " + " (10, 'Amersfoort'), (11, 'Constantine')", + + "CREATE TABLE t2 " + "(id INTEGER NOT NULL PRIMARY KEY, " + " name VARCHAR(20) NOT NULL)", + + "INSERT INTO t2 (id, name) VALUES " + " (4, 'Guam'), (5, 'Aruba'), " + " (6, 'Angola'), (7, 'Albania'), " + " (8, 'Anguilla'), (9, 'Argentina'), " + " (10, 'Azerbaijan'), (11, 'Afghanistan'), " + " (12, 'Burkina Faso'), (13, 'Faroe Islands')" + }; + const char *queries[]= + { + "SELECT * FROM t1", + "SELECT * FROM t2" + }; + + DBUG_ENTER("test_basic_cursors"); + myheader("test_basic_cursors"); + + fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables)); + + fetch_n(queries, sizeof(queries)/sizeof(*queries)); + DBUG_VOID_RETURN; +} + + +static void test_cursors_with_union() +{ + const char *queries[]= + { + "SELECT t1.name FROM t1 UNION SELECT t2.name FROM t2", + "SELECT t1.id FROM t1 WHERE t1.id < 5" + }; + myheader("test_cursors_with_union"); + fetch_n(queries, sizeof(queries)/sizeof(*queries)); +} + /* Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they should not crash server and should not hang in case of errors. @@ -11088,6 +11772,7 @@ static void test_bug6096() MYSQL_FIELD *query_field_list, *stmt_field_list; ulong query_field_count, stmt_field_count; int rc; + my_bool update_max_length= TRUE; uint i; myheader("test_bug6096"); @@ -11123,8 +11808,8 @@ static void test_bug6096() check_execute(stmt, rc); rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - rc= 1; - mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*)&rc); + mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, + (void*) &update_max_length); mysql_stmt_store_result(stmt); stmt_metadata= mysql_stmt_result_metadata(stmt); stmt_field_list= mysql_fetch_fields(stmt_metadata); @@ -11299,7 +11984,7 @@ static void test_datetime_ranges() rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - DIE_UNLESS(mysql_warning_count(mysql) != 2); + DIE_UNLESS(mysql_warning_count(mysql) == 2); verify_col_data("t1", "day_ovfl", "838:59:59"); verify_col_data("t1", "day", "828:30:30"); @@ -11510,6 +12195,300 @@ static void test_rewind(void) } +static void test_truncation() +{ + MYSQL_STMT *stmt; + const char *stmt_text; + int rc; + uint bind_count; + MYSQL_BIND *bind_array, *bind; + + myheader("test_truncation"); + + /* Prepare the test table */ + rc= mysql_query(mysql, "drop table if exists t1"); + myquery(rc); + + stmt_text= "create table t1 (" + "i8 tinyint, ui8 tinyint unsigned, " + "i16 smallint, i16_1 smallint, " + "ui16 smallint unsigned, i32 int, i32_1 int, " + "d double, d_1 double, ch char(30), ch_1 char(30), " + "tx text, tx_1 text, ch_2 char(30) " + ")"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + stmt_text= "insert into t1 VALUES (" + "-10, " /* i8 */ + "200, " /* ui8 */ + "32000, " /* i16 */ + "-32767, " /* i16_1 */ + "64000, " /* ui16 */ + "1073741824, " /* i32 */ + "1073741825, " /* i32_1 */ + "123.456, " /* d */ + "-12345678910, " /* d_1 */ + "'111111111111111111111111111111',"/* ch */ + "'abcdef', " /* ch_1 */ + "'12345 ', " /* tx */ + "'12345.67 ', " /* tx_1 */ + "'12345.67abc'" /* ch_2 */ + ")"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt_text= "select i8 c1, i8 c2, ui8 c3, i16_1 c4, ui16 c5, " + " i16 c6, ui16 c7, i32 c8, i32_1 c9, i32_1 c10, " + " d c11, d_1 c12, d_1 c13, ch c14, ch_1 c15, tx c16, " + " tx_1 c17, ch_2 c18 " + "from t1"; + + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + check_execute(stmt, rc); + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + bind_count= (uint) mysql_stmt_field_count(stmt); + + /*************** Fill in the bind structure and bind it **************/ + bind_array= malloc(sizeof(MYSQL_BIND) * bind_count); + bzero(bind_array, sizeof(MYSQL_BIND) * bind_count); + for (bind= bind_array; bind < bind_array + bind_count; bind++) + bind->error= &bind->error_value; + bind= bind_array; + + bind->buffer= malloc(sizeof(uint8)); + bind->buffer_type= MYSQL_TYPE_TINY; + bind->is_unsigned= TRUE; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(uint32)); + bind->buffer_type= MYSQL_TYPE_LONG; + bind->is_unsigned= TRUE; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(int8)); + bind->buffer_type= MYSQL_TYPE_TINY; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(uint16)); + bind->buffer_type= MYSQL_TYPE_SHORT; + bind->is_unsigned= TRUE; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(int16)); + bind->buffer_type= MYSQL_TYPE_SHORT; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(uint16)); + bind->buffer_type= MYSQL_TYPE_SHORT; + bind->is_unsigned= TRUE; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(int8)); + bind->buffer_type= MYSQL_TYPE_TINY; + bind->is_unsigned= TRUE; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(float)); + bind->buffer_type= MYSQL_TYPE_FLOAT; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(float)); + bind->buffer_type= MYSQL_TYPE_FLOAT; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(double)); + bind->buffer_type= MYSQL_TYPE_DOUBLE; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(longlong)); + bind->buffer_type= MYSQL_TYPE_LONGLONG; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(ulonglong)); + bind->buffer_type= MYSQL_TYPE_LONGLONG; + bind->is_unsigned= TRUE; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(longlong)); + bind->buffer_type= MYSQL_TYPE_LONGLONG; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(longlong)); + bind->buffer_type= MYSQL_TYPE_LONGLONG; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(longlong)); + bind->buffer_type= MYSQL_TYPE_LONGLONG; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(longlong)); + bind->buffer_type= MYSQL_TYPE_LONGLONG; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(double)); + bind->buffer_type= MYSQL_TYPE_DOUBLE; + + DIE_UNLESS(++bind < bind_array + bind_count); + bind->buffer= malloc(sizeof(double)); + bind->buffer_type= MYSQL_TYPE_DOUBLE; + + rc= mysql_stmt_bind_result(stmt, bind_array); + check_execute(stmt, rc); + rc= mysql_stmt_fetch(stmt); + DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); + + /*************** Verify truncation results ***************************/ + bind= bind_array; + + /* signed tiny -> tiny */ + DIE_UNLESS(*bind->error && * (int8*) bind->buffer == -10); + + /* signed tiny -> uint32 */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(*bind->error && * (int32*) bind->buffer == -10); + + /* unsigned tiny -> tiny */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(*bind->error && * (uint8*) bind->buffer == 200); + + /* short -> ushort */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(*bind->error && * (int16*) bind->buffer == -32767); + + /* ushort -> short */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(*bind->error && * (uint16*) bind->buffer == 64000); + + /* short -> ushort (no truncation, data is in the range of target type) */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(! *bind->error && * (uint16*) bind->buffer == 32000); + + /* ushort -> utiny */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(*bind->error && * (int8*) bind->buffer == 0); + + /* int -> float: no truncation, the number is a power of two */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(! *bind->error && * (float*) bind->buffer == 1073741824); + + /* int -> float: truncation, not enough bits in float */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(*bind->error); + + /* int -> double: no truncation */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(! *bind->error && * (double*) bind->buffer == 1073741825); + + /* double -> longlong: fractional part is lost */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(*bind->error && * (longlong*) bind->buffer == 123); + + /* double -> ulonglong, negative fp number to unsigned integer */ + DIE_UNLESS(++bind < bind_array + bind_count); + /* Value in the buffer is not defined: don't test it */ + DIE_UNLESS(*bind->error); + + /* double -> longlong, negative fp number to signed integer: no loss */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(! *bind->error && * (longlong*) bind->buffer == LL(-12345678910)); + + /* big numeric string -> number */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(*bind->error); + + /* junk string -> number */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(*bind->error && *(longlong*) bind->buffer == 0); + + /* string with trailing spaces -> number */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(! *bind->error && *(longlong*) bind->buffer == 12345); + + /* string with trailing spaces -> double */ + DIE_UNLESS(++bind < bind_array + bind_count); + DIE_UNLESS(! *bind->error && *(double*) bind->buffer == 12345.67); + + /* string with trailing junk -> double */ + DIE_UNLESS(++bind < bind_array + bind_count); + /* + XXX: There must be a truncation error: but it's not the way the server + behaves, so let's leave it for now. + */ + DIE_UNLESS(*(double*) bind->buffer == 12345.67); + /* + TODO: string -> double, double -> time, double -> string (truncation + errors are not supported here yet) + longlong -> time/date/datetime + date -> time, date -> timestamp, date -> number + time -> string, time -> date, time -> timestamp, + number -> date string -> date + */ + /*************** Cleanup *********************************************/ + + mysql_stmt_close(stmt); + + for (bind= bind_array; bind < bind_array + bind_count; bind++) + free(bind->buffer); + free(bind_array); + + rc= mysql_query(mysql, "drop table t1"); + myquery(rc); +} + +static void test_truncation_option() +{ + MYSQL_STMT *stmt; + const char *stmt_text; + int rc; + uint8 buf; + my_bool option= 0; + my_bool error; + MYSQL_BIND bind; + + myheader("test_truncation_option"); + + /* Prepare the test table */ + stmt_text= "select -1"; + + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + check_execute(stmt, rc); + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + bzero(&bind, sizeof(MYSQL_BIND)); + + bind.buffer= (void*) &buf; + bind.buffer_type= MYSQL_TYPE_TINY; + bind.is_unsigned= TRUE; + bind.error= &error; + + rc= mysql_stmt_bind_result(stmt, &bind); + check_execute(stmt, rc); + rc= mysql_stmt_fetch(stmt); + DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); + DIE_UNLESS(error); + rc= mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option); + myquery(rc); + /* need to rebind for the new setting to take effect */ + rc= mysql_stmt_bind_result(stmt, &bind); + check_execute(stmt, rc); + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + rc= mysql_stmt_fetch(stmt); + check_execute(stmt, rc); + /* The only change is rc - error pointers are still filled in */ + DIE_UNLESS(error == 1); + /* restore back the defaults */ + option= 1; + mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option); + + mysql_stmt_close(stmt); +} + + /* Bug#6761 - mysql_list_fields doesn't work */ static void test_bug6761(void) @@ -11532,6 +12511,7 @@ static void test_bug6761(void) myquery(rc); } + /* Read and parse arguments and MySQL options from my.cnf */ @@ -11739,6 +12719,17 @@ static struct my_tests_st my_tests[]= { { "test_conversion", test_conversion }, { "test_rewind", test_rewind }, { "test_bug6761", test_bug6761 }, + { "test_view", test_view }, + { "test_view_where", test_view_where }, + { "test_view_2where", test_view_2where }, + { "test_view_star", test_view_star }, + { "test_view_insert", test_view_insert }, + { "test_left_join_view", test_left_join_view }, + { "test_view_insert_fields", test_view_insert_fields }, + { "test_basic_cursors", test_basic_cursors }, + { "test_cursors_with_union", test_cursors_with_union }, + { "test_truncation", test_truncation }, + { "test_truncation_option", test_truncation_option }, { 0, 0 } }; @@ -11849,7 +12840,6 @@ int main(int argc, char **argv) /* Start of tests */ test_count= 1; start_time= time((time_t *)0); - if (!argc) { for (fptr= my_tests; fptr->name; fptr++) @@ -11879,11 +12869,6 @@ int main(int argc, char **argv) } } - /* - XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST - DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. - */ - end_time= time((time_t *)0); total_time+= difftime(end_time, start_time); diff --git a/tests/select_test.c b/tests/select_test.c index ee2a9192865..64c4fec5167 100644 --- a/tests/select_test.c +++ b/tests/select_test.c @@ -44,6 +44,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + mysql.reconnect= 1; count = 0; num = atoi(argv[2]); diff --git a/tests/showdb_test.c b/tests/showdb_test.c index df2b3037c00..08229fc51ee 100644 --- a/tests/showdb_test.c +++ b/tests/showdb_test.c @@ -45,6 +45,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + mysql.reconnect= 1; count = 0; num = atoi(argv[2]); diff --git a/tests/ssl_test.c b/tests/ssl_test.c index b18e493c267..85f490cb02e 100644 --- a/tests/ssl_test.c +++ b/tests/ssl_test.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) perror(""); exit(1); } + mysql.reconnect= 1; count = 0; num = atoi(argv[2]); while (count < num) diff --git a/tests/thread_test.c b/tests/thread_test.c index 06f335fe1a6..f8577857d0a 100644 --- a/tests/thread_test.c +++ b/tests/thread_test.c @@ -55,6 +55,7 @@ unsigned __stdcall test_thread(void *arg __attribute__((unused))) perror(""); goto end; } + mysql.reconnect= 1; if (verbose) { putchar('*'); fflush(stdout); } for (count=0 ; count < number_of_tests ; count++) { diff --git a/tests/udf_test b/tests/udf_test index 4621a7b34a5..15ad640f984 100644 --- a/tests/udf_test +++ b/tests/udf_test @@ -9,6 +9,7 @@ CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so"; CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "udf_example.so"; +CREATE FUNCTION myfunc_argument_name RETURNS STRING SONAME "udf_example.so"; select metaphon("hello"); select myfunc_double("hello","world"); @@ -20,6 +21,7 @@ create temporary table t1 (a int,b double); insert into t1 values (1,5),(1,4),(2,8),(3,9),(4,11); select avgcost(a,b) from t1; select avgcost(a,b) from t1 group by a; +select a, myfunc_argument_name(a), myfunc_argument_name(a as b) from t1; drop table t1; DROP FUNCTION metaphon; @@ -28,3 +30,4 @@ DROP FUNCTION myfunc_int; DROP FUNCTION lookup; DROP FUNCTION reverse_lookup; DROP FUNCTION avgcost; +DROP FUNCTION myfunc_argument_name; diff --git a/tests/udf_test.res b/tests/udf_test.res index 66634e13616..de9e9969f3a 100644 --- a/tests/udf_test.res +++ b/tests/udf_test.res @@ -35,6 +35,12 @@ CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "udf_example.so" Query OK, 0 rows affected -------------- +CREATE FUNCTION myfunc_argument_name RETURNS STRING SONAME "udf_example.so" +-------------- + +Query OK, 0 rows affected + +-------------- select metaphon("hello") -------------- @@ -107,6 +113,18 @@ avgcost(a,b) 4 rows in set -------------- +select a, myfunc_argument_name(a) from t1; +-------------- + +a myfunc_argument_name(a) myfunc_argument_name(a as b) +1 a b +1 a b +2 a b +3 a b +4 a b +5 rows in set + +-------------- drop table t1 -------------- @@ -148,4 +166,10 @@ DROP FUNCTION avgcost Query OK, 0 rows affected +-------------- +DROP FUNCTION myfunc_argument_name; +-------------- + +Query OK, 0 rows affected + Bye |