From 0290e159fb11e5a231f99b6103c2cc534269ba60 Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Thu, 14 Oct 2004 13:22:25 +0200 Subject: [PATCH 1/9] There were no tests for bug#1644 and bug#1676, added them now. --- mysql-test/r/ps_11bugs.result | 107 ++++++++++++++++++++++++++++++++++ mysql-test/t/ps_11bugs.test | 101 ++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result index 2aa0df6a431..0f942f6ba78 100644 --- a/mysql-test/r/ps_11bugs.result +++ b/mysql-test/r/ps_11bugs.result @@ -19,3 +19,110 @@ set @arg1= 'abc'; execute st_1180 using @arg1; session_id drop table test_select; +drop table if exists tab_many_null; +Warnings: +Note 1051 Unknown table 'tab_many_null' +create table tab_many_null ( +c_01 char(6), c_02 integer, c_03 real, c_04 int(3), c_05 varchar(20), +c_06 date, c_07 char(1), c_08 real, c_09 int(11), c_10 time, +c_11 char(6), c_12 integer, c_13 real, c_14 int(3), c_15 varchar(20), +c_16 date, c_17 char(1), c_18 real, c_19 int(11), c_20 text); +prepare st_1644 from 'insert into tab_many_null values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; +set @arg01= 'row_1'; +set @arg02= 1; +set @arg03= 1.1; +set @arg04= 111; +set @arg05= 'row_one'; +set @arg06= '2004-10-12'; +set @arg07= '1'; +set @arg08= 1.1; +set @arg09= '100100100'; +set @arg10= '12:34:56'; +set @arg11= 'row_1'; +set @arg12= 1; +set @arg13= 1.1; +set @arg14= 111; +set @arg15= 'row_one'; +set @arg16= '2004-10-12'; +set @arg17= '1'; +set @arg18= 1.1; +set @arg19= '100100100'; +set @arg20= '12:34:56'; +execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10, +@arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20; +set @arg01= NULL; +set @arg02= NULL; +set @arg03= NULL; +set @arg04= NULL; +set @arg05= NULL; +set @arg06= NULL; +set @arg07= NULL; +set @arg08= NULL; +set @arg09= NULL; +set @arg10= NULL; +set @arg11= NULL; +set @arg12= NULL; +set @arg13= NULL; +set @arg14= NULL; +set @arg15= NULL; +set @arg16= NULL; +set @arg17= NULL; +set @arg18= NULL; +set @arg19= NULL; +set @arg20= NULL; +execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10, +@arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20; +set @arg01= 'row_3'; +set @arg02= 3; +set @arg03= 3.3; +set @arg04= 333; +set @arg05= 'row_three'; +set @arg06= '2004-10-12'; +set @arg07= '3'; +set @arg08= 3.3; +set @arg09= '300300300'; +set @arg10= '12:34:56'; +set @arg11= 'row_3'; +set @arg12= 3; +set @arg13= 3.3; +set @arg14= 333; +set @arg15= 'row_three'; +set @arg16= '2004-10-12'; +set @arg17= '3'; +set @arg18= 3.3; +set @arg19= '300300300'; +set @arg20= '12:34:56'; +execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10, +@arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20; +select * from tab_many_null; +c_01 c_02 c_03 c_04 c_05 c_06 c_07 c_08 c_09 c_10 c_11 c_12 c_13 c_14 c_15 c_16 c_17 c_18 c_19 c_20 +row_1 1 1.1 111 row_one 2004-10-12 1 1.1 100100100 12:34:56 row_1 1 1.1 111 row_one 2004-10-12 1 1.1 100100100 12:34:56 +NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL +row_3 3 3.3 333 row_three 2004-10-12 3 3.3 300300300 12:34:56 row_3 3 3.3 333 row_three 2004-10-12 3 3.3 300300300 12:34:56 +drop table tab_many_null; +drop table if exists table1, table2; +Warnings: +Note 1051 Unknown table 'table1' +Note 1051 Unknown table 'table2' +create table table1( +cola varchar(50) not null, +colb varchar(8) not null, +colc varchar(12) not null, +cold varchar(2) not null, +primary key (cola, colb, cold)); +create table table2( +cola varchar(50) not null, +colb varchar(8) not null, +colc varchar(2) not null, +cold float, +primary key (cold)); +insert into table1 values ('aaaa', 'yyyy', 'yyyy-dd-mm', 'R'); +insert into table2 values ('aaaa', 'yyyy', 'R', 203), ('bbbb', 'zzzz', 'C', 201); +prepare st_1676 from 'select a.cola, a.colb, a.cold from table1 a, table2 b where a.cola = ? and a.colb = ? and a.cold = ? and b.cola = a.cola and b.colb = a.colb and b.colc = a.cold'; +set @arg0= "aaaa"; +set @arg1= "yyyy"; +set @arg2= "R"; +execute st_1676 using @arg0, @arg1, @arg2; +cola colb cold +aaaa yyyy R +drop table table1, table2; diff --git a/mysql-test/t/ps_11bugs.test b/mysql-test/t/ps_11bugs.test index 53afc8b5a78..f62d91bc2b6 100644 --- a/mysql-test/t/ps_11bugs.test +++ b/mysql-test/t/ps_11bugs.test @@ -3,6 +3,10 @@ # Prepared Statements # # re-testing bug DB entries # # # +# The bugs are reported as "closed". # +# Command sequences taken from bug report. # +# No other test contains the bug# as comment. # +# # ############################################### use test; @@ -30,3 +34,100 @@ set @arg1= 'abc'; execute st_1180 using @arg1; drop table test_select; + +# end of bug#1180 + + +# bug#1644: Insertion of more than 3 NULL columns with parameter binding fails + +# Using prepared statements, insertion of more than three columns with NULL +# values fails to insert additional NULLS. After the third column NULLS will +# be inserted into the database as zeros. +# First insert four columns of a value (i.e. 22) to verify binding is working +# correctly. Then Bind to each columns bind parameter an is_null value of 1. +# Then insert four more columns of integers, just for sanity. +# A subsequent select on the server will result in this: +# mysql> select * from foo_dfr; +# +------+------+------+------+ +# | col1 | col2 | col3 | col4 | +# +------+------+------+------+ +# | 22 | 22 | 22 | 22 | +# | NULL | NULL | NULL | 0 | +# | 88 | 88 | 88 | 88 | +# +------+------+------+------+ + +# Test is extended to more columns - code stores bit vector in bytes. + +drop table if exists tab_many_null; + +create table tab_many_null ( + c_01 char(6), c_02 integer, c_03 real, c_04 int(3), c_05 varchar(20), + c_06 date, c_07 char(1), c_08 real, c_09 int(11), c_10 time, + c_11 char(6), c_12 integer, c_13 real, c_14 int(3), c_15 varchar(20), + c_16 date, c_17 char(1), c_18 real, c_19 int(11), c_20 text); +# Do not use "timestamp" type, because it has a non-NULL default as of 4.1.2 + +prepare st_1644 from 'insert into tab_many_null values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; + +set @arg01= 'row_1'; set @arg02= 1; set @arg03= 1.1; set @arg04= 111; set @arg05= 'row_one'; +set @arg06= '2004-10-12'; set @arg07= '1'; set @arg08= 1.1; set @arg09= '100100100'; set @arg10= '12:34:56'; +set @arg11= 'row_1'; set @arg12= 1; set @arg13= 1.1; set @arg14= 111; set @arg15= 'row_one'; +set @arg16= '2004-10-12'; set @arg17= '1'; set @arg18= 1.1; set @arg19= '100100100'; set @arg20= '12:34:56'; +execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10, + @arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20; + +set @arg01= NULL; set @arg02= NULL; set @arg03= NULL; set @arg04= NULL; set @arg05= NULL; +set @arg06= NULL; set @arg07= NULL; set @arg08= NULL; set @arg09= NULL; set @arg10= NULL; +set @arg11= NULL; set @arg12= NULL; set @arg13= NULL; set @arg14= NULL; set @arg15= NULL; +set @arg16= NULL; set @arg17= NULL; set @arg18= NULL; set @arg19= NULL; set @arg20= NULL; +execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10, + @arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20; + +set @arg01= 'row_3'; set @arg02= 3; set @arg03= 3.3; set @arg04= 333; set @arg05= 'row_three'; +set @arg06= '2004-10-12'; set @arg07= '3'; set @arg08= 3.3; set @arg09= '300300300'; set @arg10= '12:34:56'; +set @arg11= 'row_3'; set @arg12= 3; set @arg13= 3.3; set @arg14= 333; set @arg15= 'row_three'; +set @arg16= '2004-10-12'; set @arg17= '3'; set @arg18= 3.3; set @arg19= '300300300'; set @arg20= '12:34:56'; +execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10, + @arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20; + +select * from tab_many_null; + +drop table tab_many_null; + +# end of bug#1644 + + +# bug#1677: Prepared statement two-table join returns no rows when one is expected + +drop table if exists table1, table2; + +create table table1( + cola varchar(50) not null, + colb varchar(8) not null, + colc varchar(12) not null, + cold varchar(2) not null, + primary key (cola, colb, cold)); + +create table table2( + cola varchar(50) not null, + colb varchar(8) not null, + colc varchar(2) not null, + cold float, + primary key (cold)); + +insert into table1 values ('aaaa', 'yyyy', 'yyyy-dd-mm', 'R'); + +insert into table2 values ('aaaa', 'yyyy', 'R', 203), ('bbbb', 'zzzz', 'C', 201); + +prepare st_1676 from 'select a.cola, a.colb, a.cold from table1 a, table2 b where a.cola = ? and a.colb = ? and a.cold = ? and b.cola = a.cola and b.colb = a.colb and b.colc = a.cold'; + +set @arg0= "aaaa"; +set @arg1= "yyyy"; +set @arg2= "R"; + +execute st_1676 using @arg0, @arg1, @arg2; + +drop table table1, table2; + +# end of bug#1676 + From d07ade557955861a94792fced85bf6e10394753f Mon Sep 17 00:00:00 2001 From: "jan@hundin.mysql.fi" <> Date: Thu, 14 Oct 2004 15:36:36 +0300 Subject: [PATCH 2/9] This patch removes unnecessary lock from the supremum record, takes X-locks on duplicates also on LOAD DATA...REPLACE clause and fixes a bug #6086 adding --disable_warnings and --enable_warnings around the create table clauses in ctype_utf8 tests for InnoDB. --- innobase/dict/dict0dict.c | 2 +- innobase/include/dict0dict.h | 12 ++++++++++++ innobase/row/row0ins.c | 31 ++++++++++++++----------------- innobase/row/row0sel.c | 26 ++++++++++---------------- mysql-test/t/ctype_utf8.test | 8 ++++++++ 5 files changed, 45 insertions(+), 34 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index fd98538d2ad..f670c0dc16d 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -2244,7 +2244,7 @@ dict_foreign_add_to_cache( Scans from pointer onwards. Stops if is at the start of a copy of 'string' where characters are compared without case sensitivity. Stops also at '\0'. */ -static + const char* dict_scan_to( /*=========*/ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 4dbbd5b4886..ca632691450 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -891,6 +891,18 @@ dict_tables_have_same_db( const char* name2); /* in: table name in the form dbname '/' tablename */ +/************************************************************************* +Scans from pointer onwards. Stops if is at the start of a copy of +'string' where characters are compared without case sensitivity. Stops +also at '\0'. */ + +const char* +dict_scan_to( +/*=========*/ + /* out: scanned up to this */ + const char* ptr, /* in: scan from */ + const char* string);/* in: look for this */ + /* Buffers for storing detailed information about the latest foreign key and unique key errors */ extern FILE* dict_foreign_err_file; diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 7b0beb9d183..3008d6a3812 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -1482,9 +1482,9 @@ row_ins_scan_sec_index_for_duplicate( ulint err = DB_SUCCESS; ibool moved; mtr_t mtr; - trx_t *trx; - ibool success; - + trx_t* trx; + const char* ptr; + n_unique = dict_index_get_n_unique(index); /* If the secondary index is unique, but one of the fields in the @@ -1523,9 +1523,11 @@ row_ins_scan_sec_index_for_duplicate( trx = thr_get_trx(thr); ut_ad(trx); - dict_accept(*trx->mysql_query_str, "REPLACE", &success); - if (success) { + ptr = dict_scan_to(*(trx->mysql_query_str), + "REPLACE"); + + if ( ptr && *ptr != '\0') { /* The manual defines the REPLACE semantics that it is either an INSERT or DELETE(s) for duplicate key @@ -1605,7 +1607,7 @@ row_ins_duplicate_error_in_clust( page_t* page; ulint n_unique; trx_t* trx = thr_get_trx(thr); - ibool success; + const char* ptr; UT_NOT_USED(mtr); @@ -1639,10 +1641,9 @@ row_ins_duplicate_error_in_clust( sure that in roll-forward we get the same duplicate errors as in original execution */ - dict_accept(*trx->mysql_query_str, "REPLACE", - &success); + ptr = dict_scan_to(*(trx->mysql_query_str), "REPLACE"); - if (success) { + if (ptr && *ptr != '\0') { /* The manual defines the REPLACE semantics that it is either an INSERT or DELETE(s) @@ -1683,15 +1684,11 @@ row_ins_duplicate_error_in_clust( /* The manual defines the REPLACE semantics that it is either an INSERT or DELETE(s) for duplicate key + INSERT. Therefore, we should take X-lock for - duplicates. - */ + duplicates. */ - /* Is the first word in MySQL query REPLACE ? */ - - dict_accept(*trx->mysql_query_str, "REPLACE", - &success); - - if (success) { + ptr = dict_scan_to(*(trx->mysql_query_str), "REPLACE"); + + if (ptr && *ptr != '\0') { err = row_ins_set_exclusive_rec_lock( LOCK_REC_NOT_GAP, diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 3ff94c8f238..740241fa210 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2794,7 +2794,7 @@ row_search_for_mysql( rec_t* index_rec; rec_t* clust_rec; rec_t* old_vers; - ulint err; + ulint err = DB_SUCCESS; ibool moved; ibool cons_read_requires_clust_rec; ibool was_lock_wait; @@ -3203,26 +3203,20 @@ rec_loop: if (prebuilt->select_lock_type != LOCK_NONE && set_also_gap_locks) { - /* Try to place a lock on the index record */ + /* Try to place a lock on the index record */ - /* If innodb_locks_unsafe_for_binlog option is used, - we lock only the record, i.e. next-key locking is - not used. - */ - if ( srv_locks_unsafe_for_binlog ) - { - err = sel_set_rec_lock(rec, index, - prebuilt->select_lock_type, - LOCK_REC_NOT_GAP, thr); - } - else + /* If innodb_locks_unsafe_for_binlog option is used, + we do not lock gaps. Supremum record is really + a gap and therefore we do not set locks there. */ + + if ( srv_locks_unsafe_for_binlog == FALSE ) { - err = sel_set_rec_lock(rec, index, + err = sel_set_rec_lock(rec, index, prebuilt->select_lock_type, LOCK_ORDINARY, thr); } - - if (err != DB_SUCCESS) { + + if (err != DB_SUCCESS) { goto lock_wait_or_error; } diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 4a8eb63ed36..55d84ffee53 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -221,7 +221,9 @@ drop table t1; # Bug 4521: unique key prefix interacts poorly with utf8 # InnoDB: keys with prefix compression, case insensitive collation. # +--disable_warnings create table t1 (c varchar(30) character set utf8, unique(c(10))) engine=innodb; +--enable_warnings insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z'); insert into t1 values ('aaaaaaaaaa'); --error 1062 @@ -269,7 +271,9 @@ drop table t1; # Bug 4521: unique key prefix interacts poorly with utf8 # InnoDB: fixed length keys, case insensitive collation # +--disable_warnings create table t1 (c char(3) character set utf8, unique (c(2))) engine=innodb; +--enable_warnings insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z'); insert into t1 values ('a'); insert into t1 values ('aa'); @@ -504,10 +508,12 @@ drop table t1; # Bug#4594: column index make = failed for gbk, but like works # Check InnoDB # +--disable_warnings create table t1 ( str varchar(255) character set utf8 not null, key str (str(2)) ) engine=innodb; +--enable_warnings INSERT INTO t1 VALUES ('str'); INSERT INTO t1 VALUES ('str2'); select * from t1 where str='str'; @@ -562,11 +568,13 @@ DROP TABLE t1; # # Bug #5723: length() returns varying results # +--disable_warnings SET NAMES utf8; CREATE TABLE t1 ( subject varchar(255) character set utf8 collate utf8_unicode_ci, p varchar(15) character set utf8 ) ENGINE=InnoDB DEFAULT CHARSET=latin1; +--enable_warnings INSERT INTO t1 VALUES ('谷川俊二と申しますが、インターネット予約の会員登録をしましたところ、メールアドレスを間違えてしまい会員IDが受け取ることが出来ませんでした。間違えアドレスはtani-shun@n.vodafone.ne.jpを書き込みました。どうすればよいですか? その他、住所等は間違えありません。連絡ください。よろしくお願いします。m(__)m','040312-000057'); INSERT INTO t1 VALUES ('aaa','bbb'); SELECT length(subject) FROM t1; From f45aacd9a3118c44dffceee4b45568c20dc83119 Mon Sep 17 00:00:00 2001 From: "jan@hundin.mysql.fi" <> Date: Fri, 15 Oct 2004 11:28:19 +0300 Subject: [PATCH 3/9] Use already parsed SQL-query in the current thread when determining was the query REPLACE or LOAD DATA INFILE REPLACE. --- innobase/row/row0ins.c | 22 ++++++++++++---------- sql/ha_innodb.cc | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 3008d6a3812..c9c784403c8 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -50,6 +50,15 @@ innobase_invalidate_query_cache( ulint full_name_len); /* in: full name length where also the null chars count */ +/********************************************************************** +This function returns true if SQL-query in the current thread +is either REPLACE or LOAD DATA INFILE REPLACE. +NOTE that /mysql/innobase/row/row0ins.c must contain the +prototype for this function ! */ + +ibool +innobase_query_is_replace(void); +/*===========================*/ /************************************************************************* Creates an insert node struct. */ @@ -1524,10 +1533,7 @@ row_ins_scan_sec_index_for_duplicate( trx = thr_get_trx(thr); ut_ad(trx); - ptr = dict_scan_to(*(trx->mysql_query_str), - "REPLACE"); - - if ( ptr && *ptr != '\0') { + if (innobase_query_is_replace()) { /* The manual defines the REPLACE semantics that it is either an INSERT or DELETE(s) for duplicate key @@ -1641,9 +1647,7 @@ row_ins_duplicate_error_in_clust( sure that in roll-forward we get the same duplicate errors as in original execution */ - ptr = dict_scan_to(*(trx->mysql_query_str), "REPLACE"); - - if (ptr && *ptr != '\0') { + if (innobase_query_is_replace()) { /* The manual defines the REPLACE semantics that it is either an INSERT or DELETE(s) @@ -1686,9 +1690,7 @@ row_ins_duplicate_error_in_clust( + INSERT. Therefore, we should take X-lock for duplicates. */ - ptr = dict_scan_to(*(trx->mysql_query_str), "REPLACE"); - - if (ptr && *ptr != '\0') { + if (innobase_query_is_replace()) { err = row_ins_set_exclusive_rec_lock( LOCK_REC_NOT_GAP, diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index d748c005d02..28f95611ae7 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -5468,4 +5468,29 @@ innobase_get_at_most_n_mbchars( } } +extern "C" { +/********************************************************************** +This function returns true if SQL-query in the current thread +is either REPLACE or LOAD DATA INFILE REPLACE. +NOTE that /mysql/innobase/row/row0ins.c must contain the +prototype for this function ! */ + +ibool +innobase_query_is_replace(void) +/*===========================*/ +{ + THD* thd; + + thd = (THD *)innobase_current_thd(); + + if ( thd->lex->sql_command == SQLCOM_REPLACE || + ( thd->lex->sql_command == SQLCOM_LOAD && + thd->lex->duplicates == DUP_REPLACE )) { + return true; + } else { + return false; + } +} +} + #endif /* HAVE_INNOBASE_DB */ From 1354b1bd5d3aa139cadb121816cc8331452e6651 Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Fri, 15 Oct 2004 12:56:57 +0200 Subject: [PATCH 4/9] New tests for bug#1644 and bug#1676, test for bug#1180 changed to table naming scheme 't#'. --- mysql-test/r/ps_11bugs.result | 42 +++++++++++++---------------------- mysql-test/t/ps_11bugs.test | 42 +++++++++++++++++------------------ 2 files changed, 36 insertions(+), 48 deletions(-) diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result index 0f942f6ba78..c0d7fe502af 100644 --- a/mysql-test/r/ps_11bugs.result +++ b/mysql-test/r/ps_11bugs.result @@ -1,13 +1,10 @@ -use test; -drop table if exists test_select; -Warnings: -Note 1051 Unknown table 'test_select' -CREATE TABLE test_select(session_id char(9) NOT NULL); -INSERT INTO test_select VALUES ("abc"); -SELECT * FROM test_select; +drop table if exists t1, t2; +CREATE TABLE t1(session_id char(9) NOT NULL); +INSERT INTO t1 VALUES ("abc"); +SELECT * FROM t1; session_id abc -prepare st_1180 from 'SELECT * FROM test_select WHERE ?="1111" and session_id = "abc"'; +prepare st_1180 from 'SELECT * FROM t1 WHERE ?="1111" and session_id = "abc"'; set @arg1= 'abc'; execute st_1180 using @arg1; session_id @@ -18,16 +15,13 @@ abc set @arg1= 'abc'; execute st_1180 using @arg1; session_id -drop table test_select; -drop table if exists tab_many_null; -Warnings: -Note 1051 Unknown table 'tab_many_null' -create table tab_many_null ( +drop table t1; +create table t1 ( c_01 char(6), c_02 integer, c_03 real, c_04 int(3), c_05 varchar(20), c_06 date, c_07 char(1), c_08 real, c_09 int(11), c_10 time, c_11 char(6), c_12 integer, c_13 real, c_14 int(3), c_15 varchar(20), c_16 date, c_17 char(1), c_18 real, c_19 int(11), c_20 text); -prepare st_1644 from 'insert into tab_many_null values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; +prepare st_1644 from 'insert into t1 values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; set @arg01= 'row_1'; set @arg02= 1; set @arg03= 1.1; @@ -94,35 +88,31 @@ set @arg19= '300300300'; set @arg20= '12:34:56'; execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10, @arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20; -select * from tab_many_null; +select * from t1; c_01 c_02 c_03 c_04 c_05 c_06 c_07 c_08 c_09 c_10 c_11 c_12 c_13 c_14 c_15 c_16 c_17 c_18 c_19 c_20 row_1 1 1.1 111 row_one 2004-10-12 1 1.1 100100100 12:34:56 row_1 1 1.1 111 row_one 2004-10-12 1 1.1 100100100 12:34:56 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL row_3 3 3.3 333 row_three 2004-10-12 3 3.3 300300300 12:34:56 row_3 3 3.3 333 row_three 2004-10-12 3 3.3 300300300 12:34:56 -drop table tab_many_null; -drop table if exists table1, table2; -Warnings: -Note 1051 Unknown table 'table1' -Note 1051 Unknown table 'table2' -create table table1( +drop table t1; +create table t1( cola varchar(50) not null, colb varchar(8) not null, colc varchar(12) not null, cold varchar(2) not null, primary key (cola, colb, cold)); -create table table2( +create table t2( cola varchar(50) not null, colb varchar(8) not null, colc varchar(2) not null, cold float, primary key (cold)); -insert into table1 values ('aaaa', 'yyyy', 'yyyy-dd-mm', 'R'); -insert into table2 values ('aaaa', 'yyyy', 'R', 203), ('bbbb', 'zzzz', 'C', 201); -prepare st_1676 from 'select a.cola, a.colb, a.cold from table1 a, table2 b where a.cola = ? and a.colb = ? and a.cold = ? and b.cola = a.cola and b.colb = a.colb and b.colc = a.cold'; +insert into t1 values ('aaaa', 'yyyy', 'yyyy-dd-mm', 'R'); +insert into t2 values ('aaaa', 'yyyy', 'R', 203), ('bbbb', 'zzzz', 'C', 201); +prepare st_1676 from 'select a.cola, a.colb, a.cold from t1 a, t2 b where a.cola = ? and a.colb = ? and a.cold = ? and b.cola = a.cola and b.colb = a.colb and b.colc = a.cold'; set @arg0= "aaaa"; set @arg1= "yyyy"; set @arg2= "R"; execute st_1676 using @arg0, @arg1, @arg2; cola colb cold aaaa yyyy R -drop table table1, table2; +drop table t1, t2; diff --git a/mysql-test/t/ps_11bugs.test b/mysql-test/t/ps_11bugs.test index f62d91bc2b6..d0aeaf265bb 100644 --- a/mysql-test/t/ps_11bugs.test +++ b/mysql-test/t/ps_11bugs.test @@ -7,19 +7,21 @@ # Command sequences taken from bug report. # # No other test contains the bug# as comment. # # # +# Tests drop/create tables 't1', 't2', ... # +# # ############################################### -use test; +--disable_warnings +drop table if exists t1, t2; +--enable_warnings # bug#1180: optimized away part of WHERE clause cause incorect prepared satatement results -drop table if exists test_select; +CREATE TABLE t1(session_id char(9) NOT NULL); +INSERT INTO t1 VALUES ("abc"); +SELECT * FROM t1; -CREATE TABLE test_select(session_id char(9) NOT NULL); -INSERT INTO test_select VALUES ("abc"); -SELECT * FROM test_select; - -prepare st_1180 from 'SELECT * FROM test_select WHERE ?="1111" and session_id = "abc"'; +prepare st_1180 from 'SELECT * FROM t1 WHERE ?="1111" and session_id = "abc"'; # Must not find a row set @arg1= 'abc'; @@ -33,7 +35,7 @@ execute st_1180 using @arg1; set @arg1= 'abc'; execute st_1180 using @arg1; -drop table test_select; +drop table t1; # end of bug#1180 @@ -58,16 +60,14 @@ drop table test_select; # Test is extended to more columns - code stores bit vector in bytes. -drop table if exists tab_many_null; - -create table tab_many_null ( +create table t1 ( c_01 char(6), c_02 integer, c_03 real, c_04 int(3), c_05 varchar(20), c_06 date, c_07 char(1), c_08 real, c_09 int(11), c_10 time, c_11 char(6), c_12 integer, c_13 real, c_14 int(3), c_15 varchar(20), c_16 date, c_17 char(1), c_18 real, c_19 int(11), c_20 text); # Do not use "timestamp" type, because it has a non-NULL default as of 4.1.2 -prepare st_1644 from 'insert into tab_many_null values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; +prepare st_1644 from 'insert into t1 values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; set @arg01= 'row_1'; set @arg02= 1; set @arg03= 1.1; set @arg04= 111; set @arg05= 'row_one'; set @arg06= '2004-10-12'; set @arg07= '1'; set @arg08= 1.1; set @arg09= '100100100'; set @arg10= '12:34:56'; @@ -90,36 +90,34 @@ set @arg16= '2004-10-12'; set @arg17= '3'; set @arg18= 3.3; set @arg19= '3003003 execute st_1644 using @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09, @arg10, @arg11, @arg12, @arg13, @arg14, @arg15, @arg16, @arg17, @arg18, @arg19, @arg20; -select * from tab_many_null; +select * from t1; -drop table tab_many_null; +drop table t1; # end of bug#1644 # bug#1677: Prepared statement two-table join returns no rows when one is expected -drop table if exists table1, table2; - -create table table1( +create table t1( cola varchar(50) not null, colb varchar(8) not null, colc varchar(12) not null, cold varchar(2) not null, primary key (cola, colb, cold)); -create table table2( +create table t2( cola varchar(50) not null, colb varchar(8) not null, colc varchar(2) not null, cold float, primary key (cold)); -insert into table1 values ('aaaa', 'yyyy', 'yyyy-dd-mm', 'R'); +insert into t1 values ('aaaa', 'yyyy', 'yyyy-dd-mm', 'R'); -insert into table2 values ('aaaa', 'yyyy', 'R', 203), ('bbbb', 'zzzz', 'C', 201); +insert into t2 values ('aaaa', 'yyyy', 'R', 203), ('bbbb', 'zzzz', 'C', 201); -prepare st_1676 from 'select a.cola, a.colb, a.cold from table1 a, table2 b where a.cola = ? and a.colb = ? and a.cold = ? and b.cola = a.cola and b.colb = a.colb and b.colc = a.cold'; +prepare st_1676 from 'select a.cola, a.colb, a.cold from t1 a, t2 b where a.cola = ? and a.colb = ? and a.cold = ? and b.cola = a.cola and b.colb = a.colb and b.colc = a.cold'; set @arg0= "aaaa"; set @arg1= "yyyy"; @@ -127,7 +125,7 @@ set @arg2= "R"; execute st_1676 using @arg0, @arg1, @arg2; -drop table table1, table2; +drop table t1, t2; # end of bug#1676 From e5be18725f2f5bbf5bcbde62793dbadc5339b5f9 Mon Sep 17 00:00:00 2001 From: "paul@kite-hub.kitebird.com" <> Date: Fri, 15 Oct 2004 10:28:39 -0500 Subject: [PATCH 5/9] texi2html: Change @image argument parsing. --- Docs/Support/texi2html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/Support/texi2html b/Docs/Support/texi2html index 5dda7c8bbd5..8067d8f72ce 100755 --- a/Docs/Support/texi2html +++ b/Docs/Support/texi2html @@ -1811,7 +1811,7 @@ sub fix_image { my($text) = @_; my($arg1, $ext); - $text =~ /^([^,]*)$/; + $text =~ /^([^,]*)/; die "error in image: '$text'" unless defined($1); $arg1 = $1; $arg1 =~ s/@@/@/g; From 37ab172624222a9c414cb265e4c2eff819fd17f5 Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Fri, 15 Oct 2004 22:03:11 +0400 Subject: [PATCH 6/9] Remove stale declaration, fix a typo in comment. --- include/sql_common.h | 1 - sql/password.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/sql_common.h b/include/sql_common.h index cde53786f83..c07a4a831bb 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -25,7 +25,6 @@ extern "C" { MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, my_bool default_value, uint server_capabilities); void free_rows(MYSQL_DATA *cur); -my_bool mysql_autenticate(MYSQL *mysql, const char *passwd); void free_old_query(MYSQL *mysql); void end_server(MYSQL *mysql); my_bool mysql_reconnect(MYSQL *mysql); diff --git a/sql/password.c b/sql/password.c index 0ac91346a55..b9f3a07e596 100644 --- a/sql/password.c +++ b/sql/password.c @@ -35,7 +35,7 @@ update user set password=PASSWORD("hello") where user="test" This saves a hashed number as a string in the password field. - The new autentication is performed in following manner: + The new authentication is performed in following manner: SERVER: public_seed=create_random_string() send(public_seed) From 391a086d525dd6d84cae50144ab93a7f8bd767a3 Mon Sep 17 00:00:00 2001 From: "dlenev@brandersnatch.localdomain" <> Date: Mon, 18 Oct 2004 10:32:52 +0400 Subject: [PATCH 7/9] Fix for broken --with-csv-storage-engine build. Now we use TABLE::timestamp_field_type instead of TABLE::timestamp_default_now/on_update_now for determining if we should auto-set value of TIMESTAMP field during this operation. We are also use Field_timestamp::set_time() instead of handler::update_timestamp(). --- sql/examples/ha_example.cc | 4 ++-- sql/examples/ha_tina.cc | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc index 097abd48e05..cb0780ea74d 100644 --- a/sql/examples/ha_example.cc +++ b/sql/examples/ha_example.cc @@ -263,8 +263,8 @@ int ha_example::write_row(byte * buf) clause was used. Consecutive ordering is not guarenteed. Currently new_data will not have an updated auto_increament record, or and updated timestamp field. You can do these for example by doing these: - if (table->timestamp_on_update_now) - update_timestamp(new_row+table->timestamp_on_update_now-1); + if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) + table->timestamp_field->set_time(); if (table->next_number_field && record == table->record[0]) update_auto_increment(); diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 06a19e478ae..0345a170c3c 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -428,8 +428,8 @@ int ha_tina::write_row(byte * buf) statistic_increment(ha_write_count,&LOCK_status); - if (table->timestamp_default_now) - update_timestamp(buf+table->timestamp_default_now-1); + if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) + table->timestamp_field->set_time(); size= encode_quote(buf); @@ -464,8 +464,8 @@ int ha_tina::update_row(const byte * old_data, byte * new_data) statistic_increment(ha_update_count,&LOCK_status); - if (table->timestamp_default_now) - update_timestamp(new_data+table->timestamp_default_now-1); + if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) + table->timestamp_field->set_time(); size= encode_quote(new_data); From 1fee6aaa62daab5ba1f1af63f59008b85c1eb708 Mon Sep 17 00:00:00 2001 From: "ram@gw.mysql.r18.ru" <> Date: Mon, 18 Oct 2004 12:43:52 +0500 Subject: [PATCH 8/9] A fix (bug #6057: Data Type Problem in manager.c). --- libmysql/manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmysql/manager.c b/libmysql/manager.c index f030eb17889..631bfa26cb2 100644 --- a/libmysql/manager.c +++ b/libmysql/manager.c @@ -237,7 +237,7 @@ int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf, char* res_buf_end=res_buf+res_buf_size; char* net_buf=(char*) con->net.read_pos, *net_buf_end; int res_buf_shift=RES_BUF_SHIFT; - uint num_bytes; + ulong num_bytes; if (res_buf_size Date: Mon, 18 Oct 2004 13:32:30 +0500 Subject: [PATCH 9/9] ctype-mb.c: Remove unnesessary code: use_mb is always TRUE for the multibyte charsets. --- strings/ctype-mb.c | 89 ++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 59 deletions(-) diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index a41449d5e50..e7527b418f5 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -123,8 +123,7 @@ int my_strcasecmp_mb(CHARSET_INFO * cs,const char *s, const char *t) ** 1 if matched with wildcard */ -#define INC_PTR(cs,A,B) A+=((use_mb_flag && \ - my_ismbchar(cs,A,B)) ? my_ismbchar(cs,A,B) : 1) +#define INC_PTR(cs,A,B) A+=(my_ismbchar(cs,A,B) ? my_ismbchar(cs,A,B) : 1) #define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)] @@ -135,8 +134,6 @@ int my_wildcmp_mb(CHARSET_INFO *cs, { int result= -1; /* Not found, using wildcards */ - bool use_mb_flag=use_mb(cs); - while (wildstr != wildend) { while (*wildstr != w_many && *wildstr != w_one) @@ -144,8 +141,7 @@ int my_wildcmp_mb(CHARSET_INFO *cs, int l; if (*wildstr == escape && wildstr+1 != wildend) wildstr++; - if (use_mb_flag && - (l = my_ismbchar(cs, wildstr, wildend))) + if ((l = my_ismbchar(cs, wildstr, wildend))) { if (str+l > str_end || memcmp(str, wildstr, l) != 0) return 1; @@ -200,41 +196,30 @@ int my_wildcmp_mb(CHARSET_INFO *cs, cmp= *++wildstr; mb=wildstr; - LINT_INIT(mblen); - if (use_mb_flag) - mblen = my_ismbchar(cs, wildstr, wildend); + mblen= my_ismbchar(cs, wildstr, wildend); INC_PTR(cs,wildstr,wildend); /* This is compared trough cmp */ cmp=likeconv(cs,cmp); do { - if (use_mb_flag) - { - for (;;) + for (;;) + { + if (str >= str_end) + return -1; + if (mblen) { - if (str >= str_end) - return -1; - if (mblen) + if (str+mblen <= str_end && memcmp(str, mb, mblen) == 0) { - if (str+mblen <= str_end && memcmp(str, mb, mblen) == 0) - { - str += mblen; - break; - } - } - else if (!my_ismbchar(cs, str, str_end) && - likeconv(cs,*str) == cmp) - { - str++; + str += mblen; break; } - INC_PTR(cs,str, str_end); } - } - else - { - while (str != str_end && likeconv(cs,*str) != cmp) + else if (!my_ismbchar(cs, str, str_end) && + likeconv(cs,*str) == cmp) + { str++; - if (str++ == str_end) return (-1); + break; + } + INC_PTR(cs,str, str_end); } { int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one, @@ -555,8 +540,6 @@ static int my_wildcmp_mb_bin(CHARSET_INFO *cs, { int result= -1; /* Not found, using wildcards */ - bool use_mb_flag=use_mb(cs); - while (wildstr != wildend) { while (*wildstr != w_many && *wildstr != w_one) @@ -564,8 +547,7 @@ static int my_wildcmp_mb_bin(CHARSET_INFO *cs, int l; if (*wildstr == escape && wildstr+1 != wildend) wildstr++; - if (use_mb_flag && - (l = my_ismbchar(cs, wildstr, wildend))) + if ((l = my_ismbchar(cs, wildstr, wildend))) { if (str+l > str_end || memcmp(str, wildstr, l) != 0) return 1; @@ -620,39 +602,28 @@ static int my_wildcmp_mb_bin(CHARSET_INFO *cs, cmp= *++wildstr; mb=wildstr; - LINT_INIT(mblen); - if (use_mb_flag) - mblen = my_ismbchar(cs, wildstr, wildend); + mblen= my_ismbchar(cs, wildstr, wildend); INC_PTR(cs,wildstr,wildend); /* This is compared trough cmp */ do { - if (use_mb_flag) - { - for (;;) + for (;;) + { + if (str >= str_end) + return -1; + if (mblen) { - if (str >= str_end) - return -1; - if (mblen) + if (str+mblen <= str_end && memcmp(str, mb, mblen) == 0) { - if (str+mblen <= str_end && memcmp(str, mb, mblen) == 0) - { - str += mblen; - break; - } - } - else if (!my_ismbchar(cs, str, str_end) && *str == cmp) - { - str++; + str += mblen; break; } - INC_PTR(cs,str, str_end); } - } - else - { - while (str != str_end && *str != cmp) + else if (!my_ismbchar(cs, str, str_end) && *str == cmp) + { str++; - if (str++ == str_end) return (-1); + break; + } + INC_PTR(cs,str, str_end); } { int tmp=my_wildcmp_mb_bin(cs,str,str_end,wildstr,wildend,escape,w_one,w_many);