From 8b9bab27634a012e35b87c440000e2c9ebc9f078 Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Fri, 28 Oct 2005 23:31:32 +0400 Subject: [PATCH 1/2] Fix for BUG#13814: in mi_pack_key(), when processing NULL value for TINYBLOB key segment, do advance the source pointer over 2 bytes that specify value length. --- myisam/mi_key.c | 3 +++ mysql-test/r/myisam.result | 18 ++++++++++++++++++ mysql-test/t/myisam.test | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 9df22889b22..f4b92f969db 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -217,7 +217,10 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, { k_length-=length; if (keyseg->flag & (HA_VAR_LENGTH | HA_BLOB_PART)) + { + old+= 2; k_length-=2; /* Skip length */ + } continue; /* Found NULL */ } } diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 17dba82dc00..55504e8e75b 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -702,3 +702,21 @@ t1 1 a 2 b A 0 NULL NULL YES BTREE t1 1 a 3 c A 0 NULL NULL YES BTREE t1 1 a 4 d A 0 NULL NULL YES BTREE set myisam_stats_method=DEFAULT; +drop table t1; +create table t1( +cip INT NOT NULL, +time TIME NOT NULL, +score INT NOT NULL DEFAULT 0, +bob TINYBLOB +); +insert into t1 (cip, time) VALUES (1, '00:01'), (2, '00:02'), (3,'00:03'); +insert into t1 (cip, bob, time) VALUES (4, 'a', '00:04'), (5, 'b', '00:05'), +(6, 'c', '00:06'); +select * from t1 where bob is null and cip=1; +cip time score bob +1 00:01:00 0 NULL +create index bug on t1 (bob(22), cip, time); +select * from t1 where bob is null and cip=1; +cip time score bob +1 00:01:00 0 NULL +drop table t1; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index fbde658660d..8e9862015bc 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -656,4 +656,22 @@ analyze table t1; show index from t1; set myisam_stats_method=DEFAULT; +drop table t1; + +# BUG#13814 - key value packed incorrectly for TINYBLOBs + +create table t1( + cip INT NOT NULL, + time TIME NOT NULL, + score INT NOT NULL DEFAULT 0, + bob TINYBLOB +); + +insert into t1 (cip, time) VALUES (1, '00:01'), (2, '00:02'), (3,'00:03'); +insert into t1 (cip, bob, time) VALUES (4, 'a', '00:04'), (5, 'b', '00:05'), + (6, 'c', '00:06'); +select * from t1 where bob is null and cip=1; +create index bug on t1 (bob(22), cip, time); +select * from t1 where bob is null and cip=1; +drop table t1; # End of 4.1 tests From edd094b194eb81054c6190a8d084f6fb294bf28d Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Mon, 7 Nov 2005 09:23:43 +0300 Subject: [PATCH 2/2] BUG#14480, attempt2: In CREATE ... SELECT ..., don't count the same field twice when calculating table->null_fields. --- mysql-test/r/create.result | 68 +++++++++++++++++++++++++++++++++++++- mysql-test/t/create.test | 64 ++++++++++++++++++++++++++++++++++- sql/sql_table.cc | 9 ++++- 3 files changed, 138 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 55ad6e3304a..0c3b7d5d5e7 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1,4 +1,4 @@ -drop table if exists t1,t2,t3; +drop table if exists t1,t2,t3,t4,t5; drop database if exists mysqltest; create table t1 (b char(0)); insert into t1 values (""),(null); @@ -632,3 +632,69 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`a`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +CREATE TABLE t2 ( +a int(11) default NULL +); +insert into t2 values(111); +create table t1 ( +a varchar(12) charset utf8 collate utf8_bin not null, +b int not null, primary key (a) +) select a, 1 as b from t2 ; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(12) character set utf8 collate utf8_bin NOT NULL default '', + `b` int(11) NOT NULL default '0', + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 ( +a varchar(12) charset utf8 collate utf8_bin not null, +b int not null, primary key (a) +) select 'a' as a , 1 as b from t2 ; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(12) character set utf8 collate utf8_bin NOT NULL default '', + `b` int(11) NOT NULL default '0', + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 ( +a varchar(12) charset utf8 collate utf8_bin, +b int not null, primary key (a) +) select 'a' as a , 1 as b from t2 ; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(12) character set utf8 collate utf8_bin NOT NULL default '', + `b` int(11) NOT NULL default '0', + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1, t2; +create table t1 ( +a1 int not null, +a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +); +insert into t1 values (1,1,1, 1,1,1, 1,1,1); +create table t2 ( +a1 varchar(12) charset utf8 collate utf8_bin not null, +a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, +primary key (a1) +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ; +drop table t2; +create table t2 ( +a1 varchar(12) charset utf8 collate utf8_bin, +a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1; +drop table t1, t2; +create table t1 ( +a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +); +insert into t1 values (1,1,1, 1,1,1, 1,1,1); +create table t2 ( +a1 varchar(12) charset utf8 collate utf8_bin not null, +a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, +primary key (a1) +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ; +drop table t1, t2; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 966be8b58a3..3bdc970027b 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -3,7 +3,7 @@ # --disable_warnings -drop table if exists t1,t2,t3; +drop table if exists t1,t2,t3,t4,t5; drop database if exists mysqltest; --enable_warnings @@ -534,4 +534,66 @@ create table t1 ( show create table t1; drop table t1; +# +# BUG#14480: assert failure in CREATE ... SELECT because of wrong +# calculation of number of NULLs. +# +CREATE TABLE t2 ( + a int(11) default NULL +); +insert into t2 values(111); + +create table t1 ( + a varchar(12) charset utf8 collate utf8_bin not null, + b int not null, primary key (a) +) select a, 1 as b from t2 ; +show create table t1; +drop table t1; + +create table t1 ( + a varchar(12) charset utf8 collate utf8_bin not null, + b int not null, primary key (a) +) select 'a' as a , 1 as b from t2 ; +show create table t1; +drop table t1; + +create table t1 ( + a varchar(12) charset utf8 collate utf8_bin, + b int not null, primary key (a) +) select 'a' as a , 1 as b from t2 ; +show create table t1; +drop table t1, t2; + +create table t1 ( + a1 int not null, + a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +); +insert into t1 values (1,1,1, 1,1,1, 1,1,1); + +create table t2 ( + a1 varchar(12) charset utf8 collate utf8_bin not null, + a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, + primary key (a1) +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ; +drop table t2; + +create table t2 ( + a1 varchar(12) charset utf8 collate utf8_bin, + a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1; + +drop table t1, t2; +create table t1 ( + a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +); +insert into t1 values (1,1,1, 1,1,1, 1,1,1); + +create table t2 ( + a1 varchar(12) charset utf8 collate utf8_bin not null, + a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, + primary key (a1) +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ; + +drop table t1, t2; + # End of 4.1 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index dcbc2018b49..40777682251 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -647,8 +647,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->pack_length= dup_field->pack_length; sql_field->create_length_to_internal_length(); sql_field->decimals= dup_field->decimals; - sql_field->flags= dup_field->flags; sql_field->unireg_check= dup_field->unireg_check; + /* + We're making one field from two, the result field will have + dup_field->flags as flags. If we've incremented null_fields + because of sql_field->flags, decrement it back. + */ + if (!(sql_field->flags & NOT_NULL_FLAG)) + null_fields--; + sql_field->flags= dup_field->flags; it2.remove(); // Remove first (create) definition select_field_pos--; break;