diff options
author | msvensson@neptunus.(none) <> | 2006-12-04 19:06:42 +0100 |
---|---|---|
committer | msvensson@neptunus.(none) <> | 2006-12-04 19:06:42 +0100 |
commit | 33c248eee586113be632d0ccafc0721c4a21a2c3 (patch) | |
tree | d1ad41db4406b4986f9f3b7475df088707a265be | |
parent | a9f4f4ed11e604f53bb79a0ee327624852813875 (diff) | |
parent | e6a2d1842194c539271e8fe1095b000607aedb0c (diff) | |
download | mariadb-git-33c248eee586113be632d0ccafc0721c4a21a2c3.tar.gz |
Merge neptunus.(none):/home/msvensson/mysql/mysql-4.1
into neptunus.(none):/home/msvensson/mysql/mysql-4.1-maint
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | client/mysqltest.c | 2 | ||||
-rw-r--r-- | libmysql/libmysql.c | 14 | ||||
-rw-r--r-- | libmysqld/lib_sql.cc | 14 | ||||
-rw-r--r-- | mysql-test/lib/mtr_process.pl | 2 | ||||
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 1 | ||||
-rw-r--r-- | mysql-test/r/func_in.result | 8 | ||||
-rw-r--r-- | mysql-test/r/ps.result | 101 | ||||
-rw-r--r-- | mysql-test/t/func_in.test | 22 | ||||
-rw-r--r-- | mysql-test/t/ps.test | 57 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 1 | ||||
-rw-r--r-- | sql/item_sum.cc | 10 | ||||
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | sql/set_var.cc | 14 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 146 |
15 files changed, 283 insertions, 112 deletions
diff --git a/Makefile.am b/Makefile.am index 19d7678e611..36175ce55e4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -91,6 +91,7 @@ bin-dist: all # Remove BK's "SCCS" subdirectories from source distribution dist-hook: rm -rf `find $(distdir) -type d -name SCCS -print` + rm -f `find $(distdir) -type l -print` tags: support-files/build-tags diff --git a/client/mysqltest.c b/client/mysqltest.c index 2dcf718918e..c6cbf6aabe0 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -222,11 +222,13 @@ struct st_connection char *name; MYSQL_STMT* stmt; +#ifdef EMBEDDED_LIBRARY const char *cur_query; int cur_query_len; pthread_mutex_t mutex; pthread_cond_t cond; int query_done; +#endif /*EMBEDDED_LIBRARY*/ }; struct st_connection connections[128]; struct st_connection* cur_con, *next_con, *connections_end; diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 5577ecdb556..e963c0e429c 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -2496,6 +2496,8 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length) NET *net= &mysql->net; char buff[4 /* size of stmt id */ + 5 /* execution flags */]; + my_bool res; + DBUG_ENTER("execute"); DBUG_PRINT("enter",("packet: %s, length :%d",packet ? packet :" ", length)); @@ -2503,15 +2505,17 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length) int4store(buff, stmt->stmt_id); /* Send stmt id to server */ buff[4]= (char) 0; /* no flags */ int4store(buff+5, 1); /* iteration count */ - if (cli_advanced_command(mysql, COM_EXECUTE, buff, sizeof(buff), - packet, length, 1, NULL) || - (*mysql->methods->read_query_result)(mysql)) + + res= test(cli_advanced_command(mysql, COM_EXECUTE, buff, sizeof(buff), + packet, length, 1, NULL) || + (*mysql->methods->read_query_result)(mysql)); + stmt->affected_rows= mysql->affected_rows; + stmt->insert_id= mysql->insert_id; + if (res) { set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); DBUG_RETURN(1); } - stmt->affected_rows= mysql->affected_rows; - stmt->insert_id= mysql->insert_id; DBUG_RETURN(0); } diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 64bc37fb40d..804c4e001d2 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -224,20 +224,24 @@ static int emb_stmt_execute(MYSQL_STMT *stmt) { DBUG_ENTER("emb_stmt_execute"); char header[4]; + my_bool res; + int4store(header, stmt->stmt_id); THD *thd= (THD*)stmt->mysql->thd; thd->client_param_count= stmt->param_count; thd->client_params= stmt->params; - if (emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0, - header, sizeof(header), 1, stmt) || - emb_mysql_read_query_result(stmt->mysql)) + + res= test(emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0, + header, sizeof(header), 1, stmt) || + emb_mysql_read_query_result(stmt->mysql)); + stmt->affected_rows= stmt->mysql->affected_rows; + stmt->insert_id= stmt->mysql->insert_id; + if (res) { NET *net= &stmt->mysql->net; set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); DBUG_RETURN(1); } - stmt->affected_rows= stmt->mysql->affected_rows; - stmt->insert_id= stmt->mysql->insert_id; DBUG_RETURN(0); } diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 37a82177f46..cf0dc0dc6f8 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -1052,7 +1052,7 @@ sub sleep_until_file_created ($$$) { # Print extra message every 60 seconds my $seconds= ($loop * $sleeptime) / 1000; - if ( $seconds > 1 and int($seconds) % 60 == 0 ) + if ( $seconds > 1 and int($seconds * 10) % 600 == 0 ) { my $left= $timeout - $seconds; mtr_warning("Waited $seconds seconds for $pidfile to be created, " . diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 7ed84f9cc3f..5002f778da5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -63,7 +63,6 @@ use Getopt::Long; use Sys::Hostname; use IO::Socket; use IO::Socket::INET; -use Data::Dumper; use strict; use warnings; diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result index 3cf2afc83d1..f74c63f7260 100644 --- a/mysql-test/r/func_in.result +++ b/mysql-test/r/func_in.result @@ -202,3 +202,11 @@ select count(*) from t1 where id not in (1,2); count(*) 1 drop table t1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 SELECT 1 IN (2, NULL); +SELECT should return NULL. +SELECT * FROM t1; +1 IN (2, NULL) +NULL +DROP TABLE t1; +End of 4.1 tests diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 2bb5df6e6cf..94c51fdc18b 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -775,12 +775,12 @@ set @old_max_prepared_stmt_count= @@max_prepared_stmt_count; show variables like 'max_prepared_stmt_count'; Variable_name Value max_prepared_stmt_count 16382 -show variables like 'prepared_stmt_count'; +show status like 'prepared_stmt_count'; Variable_name Value -prepared_stmt_count 0 -select @@max_prepared_stmt_count, @@prepared_stmt_count; -@@max_prepared_stmt_count @@prepared_stmt_count -16382 0 +Prepared_stmt_count 0 +select @@max_prepared_stmt_count; +@@max_prepared_stmt_count +16382 set global max_prepared_stmt_count=-1; select @@max_prepared_stmt_count; @@max_prepared_stmt_count @@ -799,67 +799,70 @@ set max_prepared_stmt_count=1; ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL set local max_prepared_stmt_count=1; ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL -set local prepared_stmt_count=0; -ERROR HY000: Variable 'prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL -set @@prepared_stmt_count=0; -ERROR HY000: Variable 'prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL -set global prepared_stmt_count=1; -ERROR 42000: Incorrect argument type to variable 'prepared_stmt_count' set global max_prepared_stmt_count=1; select @@max_prepared_stmt_count; @@max_prepared_stmt_count 1 set global max_prepared_stmt_count=0; -select @@max_prepared_stmt_count, @@prepared_stmt_count; -@@max_prepared_stmt_count @@prepared_stmt_count -0 0 +select @@max_prepared_stmt_count; +@@max_prepared_stmt_count +0 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 0 prepare stmt from "select 1"; ERROR HY000: Unknown error -select @@prepared_stmt_count; -@@prepared_stmt_count -0 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 0 set global max_prepared_stmt_count=1; prepare stmt from "select 1"; -select @@prepared_stmt_count; -@@prepared_stmt_count -1 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 1 prepare stmt1 from "select 1"; ERROR HY000: Unknown error -select @@prepared_stmt_count; -@@prepared_stmt_count -1 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 1 deallocate prepare stmt; -select @@prepared_stmt_count; -@@prepared_stmt_count -0 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 0 prepare stmt from "select 1"; -select @@prepared_stmt_count; -@@prepared_stmt_count -1 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 1 prepare stmt from "select 2"; -select @@prepared_stmt_count; -@@prepared_stmt_count +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 1 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 1 +select @@max_prepared_stmt_count; +@@max_prepared_stmt_count 1 -select @@prepared_stmt_count, @@max_prepared_stmt_count; -@@prepared_stmt_count @@max_prepared_stmt_count -1 1 set global max_prepared_stmt_count=0; prepare stmt from "select 1"; ERROR HY000: Unknown error execute stmt; ERROR HY000: Unknown prepared statement handler (stmt) given to EXECUTE -select @@prepared_stmt_count; -@@prepared_stmt_count -0 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 0 prepare stmt from "select 1"; ERROR HY000: Unknown error -select @@prepared_stmt_count; -@@prepared_stmt_count -0 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 0 set global max_prepared_stmt_count=3; -select @@max_prepared_stmt_count, @@prepared_stmt_count; -@@max_prepared_stmt_count @@prepared_stmt_count -3 0 +select @@max_prepared_stmt_count; +@@max_prepared_stmt_count +3 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 0 prepare stmt from "select 1"; prepare stmt from "select 2"; prepare stmt1 from "select 3"; @@ -867,13 +870,13 @@ prepare stmt2 from "select 4"; ERROR HY000: Unknown error prepare stmt2 from "select 4"; ERROR HY000: Unknown error -select @@max_prepared_stmt_count, @@prepared_stmt_count; -@@max_prepared_stmt_count @@prepared_stmt_count -3 3 +select @@max_prepared_stmt_count; +@@max_prepared_stmt_count +3 +show status like 'prepared_stmt_count'; +Variable_name Value +Prepared_stmt_count 3 deallocate prepare stmt; -select @@max_prepared_stmt_count, @@prepared_stmt_count; -@@max_prepared_stmt_count @@prepared_stmt_count -3 0 set global max_prepared_stmt_count= @old_max_prepared_stmt_count; drop table if exists t1; create temporary table if not exists t1 (a1 int); diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test index 2ffe5a2d5f7..ffed2aac2a0 100644 --- a/mysql-test/t/func_in.test +++ b/mysql-test/t/func_in.test @@ -109,4 +109,24 @@ select count(*) from t1 where id not in (1); select count(*) from t1 where id not in (1,2); drop table t1; -# End of 4.1 tests + +# +# BUG#17047: CHAR() and IN() can return NULL without signaling NULL +# result +# +# The problem was in the IN() function that ignored maybe_null flags +# of all arguments except the first (the one _before_ the IN +# keyword, '1' in the test case below). +# +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 SELECT 1 IN (2, NULL); +--echo SELECT should return NULL. +SELECT * FROM t1; + +DROP TABLE t1; + + +--echo End of 4.1 tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 5b488ae4393..fbeaaa494e0 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -811,6 +811,9 @@ drop table t1; # Bug#16365 Prepared Statements: DoS with too many open statements # Check that the limit @@max_prpeared_stmt_count works. # +# This is also the test for bug#23159 prepared_stmt_count should be +# status variable. +# # Save the old value set @old_max_prepared_stmt_count= @@max_prepared_stmt_count; # @@ -820,17 +823,17 @@ set @old_max_prepared_stmt_count= @@max_prepared_stmt_count; # --disable_ps_protocol # -# A. Check that the new variables are present in SHOW VARIABLES list. +# A. Check that the new variables are present in SHOW VARIABLES and +# SHOW STATUS lists. # show variables like 'max_prepared_stmt_count'; -show variables like 'prepared_stmt_count'; +show status like 'prepared_stmt_count'; # -# B. Check that the new variables are selectable. +# B. Check that the new system variable is selectable. # -select @@max_prepared_stmt_count, @@prepared_stmt_count; +select @@max_prepared_stmt_count; # -# C. Check that max_prepared_stmt_count is settable (global only), -# whereas prepared_stmt_count is readonly. +# C. Check that max_prepared_stmt_count is settable (global only). # set global max_prepared_stmt_count=-1; select @@max_prepared_stmt_count; @@ -844,12 +847,6 @@ set @@max_prepared_stmt_count=1; set max_prepared_stmt_count=1; --error 1229 # ER_GLOBAL_VARIABLE set local max_prepared_stmt_count=1; ---error 1229 # ER_GLOBAL_VARIABLE -set local prepared_stmt_count=0; ---error 1229 # ER_GLOBAL_VARIABLE -set @@prepared_stmt_count=0; ---error 1232 # ER_WRONG_TYPE_FOR_VAR -set global prepared_stmt_count=1; # set to a reasonable limit works set global max_prepared_stmt_count=1; select @@max_prepared_stmt_count; @@ -857,47 +854,50 @@ select @@max_prepared_stmt_count; # D. Check that the variables actually work. # set global max_prepared_stmt_count=0; -select @@max_prepared_stmt_count, @@prepared_stmt_count; +select @@max_prepared_stmt_count; +show status like 'prepared_stmt_count'; --error 1105 # ER_UNKNOWN_ERROR prepare stmt from "select 1"; -select @@prepared_stmt_count; +show status like 'prepared_stmt_count'; set global max_prepared_stmt_count=1; prepare stmt from "select 1"; -select @@prepared_stmt_count; +show status like 'prepared_stmt_count'; --error 1105 # ER_UNKNOWN_ERROR prepare stmt1 from "select 1"; -select @@prepared_stmt_count; +show status like 'prepared_stmt_count'; deallocate prepare stmt; -select @@prepared_stmt_count; +show status like 'prepared_stmt_count'; # # E. Check that we can prepare a statement with the same name # successfully, without hitting the limit. # prepare stmt from "select 1"; -select @@prepared_stmt_count; +show status like 'prepared_stmt_count'; prepare stmt from "select 2"; -select @@prepared_stmt_count; +show status like 'prepared_stmt_count'; # # F. We can set the max below the current count. In this case no new # statements should be allowed to prepare. # -select @@prepared_stmt_count, @@max_prepared_stmt_count; +show status like 'prepared_stmt_count'; +select @@max_prepared_stmt_count; set global max_prepared_stmt_count=0; --error 1105 # ER_UNKNOWN_ERROR prepare stmt from "select 1"; # Result: the old statement is deallocated, the new is not created. --error 1243 # ER_UNKNOWN_STMT_HANDLER execute stmt; -select @@prepared_stmt_count; +show status like 'prepared_stmt_count'; --error 1105 # ER_UNKNOWN_ERROR prepare stmt from "select 1"; -select @@prepared_stmt_count; +show status like 'prepared_stmt_count'; # # G. Show that the variables are up to date even after a connection with all # statements in it was terminated. # set global max_prepared_stmt_count=3; -select @@max_prepared_stmt_count, @@prepared_stmt_count; +select @@max_prepared_stmt_count; +show status like 'prepared_stmt_count'; prepare stmt from "select 1"; connect (con1,localhost,root,,); connection con1; @@ -908,18 +908,11 @@ prepare stmt2 from "select 4"; connection default; --error 1105 # ER_UNKNOWN_ERROR prepare stmt2 from "select 4"; -select @@max_prepared_stmt_count, @@prepared_stmt_count; +select @@max_prepared_stmt_count; +show status like 'prepared_stmt_count'; disconnect con1; connection default; -# Wait for the connection to die: deal with a possible race deallocate prepare stmt; -let $count= `select @@prepared_stmt_count`; -if ($count) -{ ---sleep 2 - let $count= `select @@prepared_stmt_count`; -} -select @@max_prepared_stmt_count, @@prepared_stmt_count; # # Restore the old value. # diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 6b6996160a1..859b4e0ecc1 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1998,7 +1998,6 @@ void Item_func_in::fix_length_and_dec() if (cmp_type == STRING_RESULT) in_item->cmp_charset= cmp_collation.collation; } - maybe_null= args[0]->maybe_null; max_length= 1; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 2c8158b35fd..419efd07615 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -71,9 +71,13 @@ void Item_sum::make_field(Send_field *tmp_field) if (args[0]->type() == Item::FIELD_ITEM && keep_field_type()) { ((Item_field*) args[0])->field->make_field(tmp_field); - tmp_field->db_name=(char*)""; - tmp_field->org_table_name=tmp_field->table_name=(char*)""; - tmp_field->org_col_name=tmp_field->col_name=name; + /* For expressions only col_name should be non-empty string. */ + char *empty_string= (char*)""; + tmp_field->db_name= empty_string; + tmp_field->org_table_name= empty_string; + tmp_field->table_name= empty_string; + tmp_field->org_col_name= empty_string; + tmp_field->col_name= name; if (maybe_null) tmp_field->flags&= ~NOT_NULL_FLAG; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6571717b61d..cd0ddc00624 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5733,6 +5733,7 @@ struct show_var_st status_vars[]= { {"Open_streams", (char*) &my_stream_opened, SHOW_LONG_CONST}, {"Open_tables", (char*) 0, SHOW_OPENTABLES}, {"Opened_tables", (char*) &opened_tables, SHOW_LONG}, + {"Prepared_stmt_count", (char*) &prepared_stmt_count, SHOW_LONG_CONST}, #ifdef HAVE_QUERY_CACHE {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_CONST}, @@ -5903,6 +5904,7 @@ static void mysql_init_variables(void) binlog_cache_use= binlog_cache_disk_use= 0; max_used_connections= slow_launch_threads = 0; mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0; + prepared_stmt_count= 0; errmesg= 0; mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS; bzero((gptr) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list)); diff --git a/sql/set_var.cc b/sql/set_var.cc index 4433b6bf7d8..71ca382f9d9 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -119,7 +119,6 @@ static KEY_CACHE *create_key_cache(const char *name, uint length); void fix_sql_mode_var(THD *thd, enum_var_type type); static byte *get_error_count(THD *thd); static byte *get_warning_count(THD *thd); -static byte *get_prepared_stmt_count(THD *thd); static byte *get_have_innodb(THD *thd); /* @@ -482,9 +481,6 @@ static sys_var_readonly sys_warning_count("warning_count", OPT_SESSION, SHOW_LONG, get_warning_count); -static sys_var_readonly sys_prepared_stmt_count("prepared_stmt_count", - OPT_GLOBAL, SHOW_LONG, - get_prepared_stmt_count); /* alias for last_insert_id() to be compatible with Sybase */ #ifdef HAVE_REPLICATION @@ -604,7 +600,6 @@ sys_var *sys_variables[]= &sys_new_mode, &sys_old_passwords, &sys_preload_buff_size, - &sys_prepared_stmt_count, &sys_pseudo_thread_id, &sys_query_alloc_block_size, &sys_query_cache_size, @@ -860,7 +855,6 @@ struct show_var_st init_vars[]= { {"pid_file", (char*) pidfile_name, SHOW_CHAR}, {"port", (char*) &mysqld_port, SHOW_INT}, {sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS}, - {sys_prepared_stmt_count.name, (char*) &sys_prepared_stmt_count, SHOW_SYS}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size, SHOW_SYS}, @@ -2715,14 +2709,6 @@ static byte *get_have_innodb(THD *thd) } -static byte *get_prepared_stmt_count(THD *thd) -{ - pthread_mutex_lock(&LOCK_prepared_stmt_count); - thd->sys_var_tmp.ulong_value= prepared_stmt_count; - pthread_mutex_unlock(&LOCK_prepared_stmt_count); - return (byte*) &thd->sys_var_tmp.ulong_value; -} - /**************************************************************************** Main handling of variables: - Initialisation diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b1ee144e517..98d7182d46f 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -11950,6 +11950,150 @@ static void test_bug21726() /* + BUG#23383: mysql_affected_rows() returns different values than + mysql_stmt_affected_rows() + + Test that both mysql_affected_rows() and mysql_stmt_affected_rows() + return -1 on error, 0 when no rows were affected, and (positive) row + count when some rows were affected. +*/ +static void test_bug23383() +{ + const char *insert_query= "INSERT INTO t1 VALUES (1), (2)"; + const char *update_query= "UPDATE t1 SET i= 4 WHERE i = 3"; + MYSQL_STMT *stmt; + my_ulonglong row_count; + int rc; + + DBUG_ENTER("test_bug23383"); + myheader("test_bug23383"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + + rc= mysql_query(mysql, "CREATE TABLE t1 (i INT UNIQUE)"); + myquery(rc); + + rc= mysql_query(mysql, insert_query); + myquery(rc); + row_count= mysql_affected_rows(mysql); + DIE_UNLESS(row_count == 2); + + rc= mysql_query(mysql, insert_query); + DIE_UNLESS(rc != 0); + row_count= mysql_affected_rows(mysql); + DIE_UNLESS(row_count == (my_ulonglong)-1); + + rc= mysql_query(mysql, update_query); + myquery(rc); + row_count= mysql_affected_rows(mysql); + DIE_UNLESS(row_count == 0); + + rc= mysql_query(mysql, "DELETE FROM t1"); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + DIE_UNLESS(stmt != 0); + + rc= mysql_stmt_prepare(stmt, insert_query, strlen(insert_query)); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + row_count= mysql_stmt_affected_rows(stmt); + DIE_UNLESS(row_count == 2); + + rc= mysql_stmt_execute(stmt); + DIE_UNLESS(rc != 0); + row_count= mysql_stmt_affected_rows(stmt); + DIE_UNLESS(row_count == (my_ulonglong)-1); + + rc= mysql_stmt_prepare(stmt, update_query, strlen(update_query)); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + row_count= mysql_stmt_affected_rows(stmt); + DIE_UNLESS(row_count == 0); + + rc= mysql_stmt_close(stmt); + check_execute(stmt, rc); + + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); + + DBUG_VOID_RETURN; +} + + +/* + BUG#21635: MYSQL_FIELD struct's member strings seem to misbehave for + expression cols + + Check that for MIN(), MAX(), COUNT() only MYSQL_FIELD::name is set + to either expression or its alias, and db, org_table, table, + org_name fields are empty strings. +*/ +static void test_bug21635() +{ + const char *expr[]= + { + "MIN(i)", "MIN(i)", + "MIN(i) AS A1", "A1", + "MAX(i)", "MAX(i)", + "MAX(i) AS A2", "A2", + "COUNT(i)", "COUNT(i)", + "COUNT(i) AS A3", "A3", + }; + char *query_end; + MYSQL_RES *result; + MYSQL_FIELD *field; + unsigned int field_count, i; + int rc; + + DBUG_ENTER("test_bug21635"); + myheader("test_bug21635"); + + query_end= strxmov(query, "SELECT ", NullS); + for (i= 0; i < sizeof(expr) / sizeof(*expr) / 2; ++i) + query_end= strxmov(query_end, expr[i * 2], ", ", NullS); + query_end= strxmov(query_end - 2, " FROM t1 GROUP BY i", NullS); + DIE_UNLESS(query_end - query < MAX_TEST_QUERY_LENGTH); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + rc= mysql_query(mysql, "CREATE TABLE t1 (i INT)"); + myquery(rc); + rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)"); + myquery(rc); + + rc= mysql_real_query(mysql, query, query_end - query); + myquery(rc); + + result= mysql_use_result(mysql); + DIE_UNLESS(result); + + field_count= mysql_field_count(mysql); + for (i= 0; i < field_count; ++i) + { + field= mysql_fetch_field_direct(result, i); + printf("%s -> %s ... ", expr[i * 2], field->name); + fflush(stdout); + DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 && + field->table[0] == 0 && field->org_name[0] == 0); + DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0); + puts("OK"); + } + + mysql_free_result(result); + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); + + DBUG_VOID_RETURN; +} + + +/* Read and parse arguments and MySQL options from my.cnf */ @@ -12176,6 +12320,8 @@ static struct my_tests_st my_tests[]= { { "test_bug15613", test_bug15613 }, { "test_bug20152", test_bug20152 }, { "test_bug21726", test_bug21726 }, + { "test_bug23383", test_bug23383 }, + { "test_bug21635", test_bug21635 }, { 0, 0 } }; |