Commit 44b2807e authored by unknown's avatar unknown

Portability fixes

Fixed bug in end space handle for WHERE text_column="constant"


heap/hp_hash.c:
  Optimzations (no change of logic)
libmysql/libmysql.c:
  Added missing casts (portability fix)
myisam/mi_key.c:
  Changed macro to take arguments and not depend on local variables
  Simple indentation fixes ?
mysql-test/r/connect.result:
  Added test for setting empty password
mysql-test/r/create_select_tmp.result:
  TYPE -> ENGINE
mysql-test/r/ctype_utf8.result:
  Combine drop's
mysql-test/r/endspace.result:
  Added more tests to test end space behaviour
mysql-test/r/having.result:
  Added missing DROP TABLE
mysql-test/r/type_blob.result:
  Added more tests to ensure that fix for BLOB usage is correct
mysql-test/r/type_timestamp.result:
  Add test from 4.0
mysql-test/t/connect.test:
  Added test for setting empty password
mysql-test/t/create_select_tmp.test:
  TYPE -> ENGINE
mysql-test/t/ctype_utf8.test:
  Combine drop's
mysql-test/t/endspace.test:
  Added more tests to test end space behaviour
mysql-test/t/having.test:
  Added missing DROP TABLE
mysql-test/t/type_blob.test:
  Added more tests to ensure that fix for BLOB usage is correct
mysql-test/t/type_timestamp.test:
  Add test from 4.0
sql/field.cc:
  Removed not used variable
  Portability fix (cast)
  Simplified Field_str::double()
  Simple indentation cleanups
sql/field.h:
  Removed not needed class variable
sql/item_cmpfunc.cc:
  Indentation fix
sql/item_strfunc.cc:
  Use on stack variable for Item_str_func::val() instead of str_value.
  This makes it safe to use str_value inside the Item's val function.
  Cleaned up LEFT() usage, thanks to the above change
sql/item_sum.cc:
  Indentation cleanups
sql/protocol.cc:
  Added missing cast
sql/sql_acl.cc:
  Indentatin cleanups.
  Added missing cast
  Simple optimization of get_sort()
sql/sql_select.cc:
  Don't use 'ref' to search on text field that is not of type BINARY (use 'range' instead).
  The reson is that for 'ref' we use 'index_next_same' to read the next possible row. 
  For text fields, rows in a ref may not come in order, like for 'x', 'x\t' 'x ' (stored in this order) which causes a search for 'column='x ' to fail
sql/tztime.cc:
  Simple cleanup
strings/ctype-bin.c:
  Comment fixes
strings/ctype-mb.c:
  Changed variable names for arguments
parent 92dfd1bf
......@@ -246,12 +246,12 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
if (seg->type == HA_KEYTYPE_TEXT)
{
CHARSET_INFO *cs= seg->charset;
uint length= ((uchar*)key) - pos;
uint char_length= length / cs->mbmaxlen;
if (length > char_length)
uint char_length= (uint) ((uchar*) key - pos);
if (cs->mbmaxlen > 1)
{
char_length= my_charpos(cs, pos, pos + length, char_length);
set_if_smaller(char_length, length);
uint length= char_length;
char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen);
set_if_smaller(char_length, length); /* QQ: ok to remove? */
}
cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2);
}
......@@ -289,11 +289,12 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
if (seg->type == HA_KEYTYPE_TEXT)
{
CHARSET_INFO *cs= seg->charset;
uint char_length= seg->length / cs->mbmaxlen;
if (seg->length > char_length)
uint char_length= seg->length;
if (cs->mbmaxlen > 1)
{
char_length= my_charpos(cs, pos, pos + seg->length, char_length);
set_if_smaller(char_length, seg->length);
char_length= my_charpos(cs, pos, pos + char_length,
char_length / cs->mbmaxlen);
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
}
cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2);
}
......@@ -417,17 +418,17 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
if (seg->type == HA_KEYTYPE_TEXT)
{
CHARSET_INFO *cs= seg->charset;
uint char_length= seg->length / cs->mbmaxlen;
uint char_length1;
uint char_length2;
uchar *pos1= (uchar*)rec1 + seg->start;
uchar *pos2= (uchar*)rec2 + seg->start;
if (seg->length > char_length)
if (cs->mbmaxlen > 1)
{
uint char_length= seg->length / cs->mbmaxlen;
char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length);
set_if_smaller(char_length1, seg->length);
set_if_smaller(char_length1, seg->length); /* QQ: ok to remove? */
char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length);
set_if_smaller(char_length2, seg->length);
set_if_smaller(char_length2, seg->length); /* QQ: ok to remove? */
}
else
{
......@@ -468,12 +469,12 @@ int hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
if (seg->type == HA_KEYTYPE_TEXT)
{
CHARSET_INFO *cs= seg->charset;
uint char_length= seg->length / cs->mbmaxlen;
uint char_length_key;
uint char_length_rec;
uchar *pos= (uchar*) rec + seg->start;
if (seg->length > char_length)
if (cs->mbmaxlen > 1)
{
uint char_length= seg->length / cs->mbmaxlen;
char_length_key= my_charpos(cs, key, key + seg->length, char_length);
set_if_smaller(char_length_key, seg->length);
char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length);
......@@ -509,21 +510,22 @@ void hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{
CHARSET_INFO *cs= seg->charset;
uint char_length= (cs && cs->mbmaxlen > 1) ? seg->length / cs->mbmaxlen :
seg->length;
uint char_length= seg->length;
uchar *pos= (uchar*) rec + seg->start;
if (seg->null_bit)
*key++= test(rec[seg->null_pos] & seg->null_bit);
if (seg->length > char_length)
if (cs->mbmaxlen > 1)
{
char_length= my_charpos(cs, pos, pos + seg->length, char_length);
set_if_smaller(char_length, seg->length);
char_length= my_charpos(cs, pos, pos + seg->length,
char_length / cs->mbmaxlen);
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
}
memcpy(key,rec+seg->start,(size_t) char_length);
key+= char_length;
}
}
uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
const byte *rec, byte *recpos)
{
......@@ -575,13 +577,13 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
}
continue;
}
char_length= seg->length / (seg->charset ? seg->charset->mbmaxlen : 1);
if (seg->length > char_length)
char_length= seg->length;
if (seg->charset->mbmaxlen > 1)
{
char_length= my_charpos(seg->charset,
rec + seg->start, rec + seg->start + seg->length,
char_length);
set_if_smaller(char_length, seg->length);
rec + seg->start, rec + seg->start + char_length,
char_length / seg->charset->mbmaxlen);
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
if (char_length < seg->length)
seg->charset->cset->fill(seg->charset, key + char_length,
seg->length - char_length, ' ');
......@@ -593,7 +595,9 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
return key - start_key;
}
uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len)
uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
uint k_len)
{
HA_KEYSEG *seg, *endseg;
uchar *start_key= key;
......@@ -623,11 +627,12 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len)
}
continue;
}
char_length= seg->length / (seg->charset ? seg->charset->mbmaxlen : 1);
if (seg->length > char_length)
char_length= seg->length;
if (seg->charset->mbmaxlen > 1)
{
char_length= my_charpos(seg->charset, old, old+seg->length, char_length);
set_if_smaller(char_length, seg->length);
char_length= my_charpos(seg->charset, old, old+char_length,
char_length / seg->charset->mbmaxlen);
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
if (char_length < seg->length)
seg->charset->cset->fill(seg->charset, key + char_length,
seg->length - char_length, ' ');
......@@ -639,12 +644,14 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len)
return key - start_key;
}
uint hp_rb_key_length(HP_KEYDEF *keydef,
const byte *key __attribute__((unused)))
{
return keydef->length;
}
uint hp_rb_null_key_length(HP_KEYDEF *keydef, const byte *key)
{
const byte *start_key= key;
......
......@@ -3429,7 +3429,7 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
char buff[22]; /* Enough for longlong */
char *end= longlong10_to_str(value, buff, field_is_unsigned ? 10: -10);
/* Resort to string conversion which supports all typecodes */
fetch_string_with_conversion(param, buff, end - buff);
fetch_string_with_conversion(param, buff, (uint) (end - buff));
break;
}
}
......@@ -3505,7 +3505,7 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
sprintf(buff, "%.*f", (int) field->decimals, value);
end= strend(buff);
}
fetch_string_with_conversion(param, buff, end - buff);
fetch_string_with_conversion(param, buff, (uint) (end - buff));
break;
}
}
......
......@@ -23,9 +23,9 @@
#include <ieeefp.h>
#endif
#define CHECK_KEYS
#define CHECK_KEYS /* Enable safety checks */
#define FIX_LENGTH \
#define FIX_LENGTH(cs, pos, length, char_length) \
do { \
if (length > char_length) \
char_length= my_charpos(cs, pos, pos+length, char_length); \
......@@ -48,7 +48,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
DBUG_ENTER("_mi_make_key");
if(info->s->keyinfo[keynr].flag & HA_SPATIAL)
if (info->s->keyinfo[keynr].flag & HA_SPATIAL)
{
/*
TODO: nulls processing
......@@ -78,7 +78,8 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
*key++=1; /* Not NULL */
}
char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
length);
pos= (byte*) record+keyseg->start;
if (keyseg->flag & HA_SPACE_PACK)
......@@ -95,7 +96,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
pos++;
}
length=(uint) (end-pos);
FIX_LENGTH;
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
memcpy((byte*) key,(byte*) pos,(size_t) char_length);
key+=char_length;
......@@ -106,7 +107,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
uint tmp_length=uint2korr(pos);
pos+=2; /* Skip VARCHAR length */
set_if_smaller(length,tmp_length);
FIX_LENGTH;
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
memcpy((byte*) key,(byte*) pos,(size_t) char_length);
key+= char_length;
......@@ -117,7 +118,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
memcpy_fixed((byte*) &pos,pos+keyseg->bit_start,sizeof(char*));
set_if_smaller(length,tmp_length);
FIX_LENGTH;
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
memcpy((byte*) key,(byte*) pos,(size_t) char_length);
key+= char_length;
......@@ -157,7 +158,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
}
continue;
}
FIX_LENGTH;
FIX_LENGTH(cs, pos, length, char_length);
memcpy((byte*) key, pos, char_length);
if (length > char_length)
cs->cset->fill(cs, key+char_length, length-char_length, ' ');
......@@ -237,7 +238,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
}
k_length-=length;
length=(uint) (end-pos);
FIX_LENGTH;
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
memcpy((byte*) key,pos,(size_t) char_length);
key+= char_length;
......@@ -250,7 +251,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
k_length-= 2+length;
pos+=2;
set_if_smaller(length,tmp_length); /* Safety */
FIX_LENGTH;
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
old+=2; /* Skip length */
memcpy((byte*) key, pos,(size_t) char_length);
......@@ -267,7 +268,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
}
continue;
}
FIX_LENGTH;
FIX_LENGTH(cs, pos, length, char_length);
memcpy((byte*) key, pos, char_length);
if (length > char_length)
cs->cset->fill(cs,key+char_length, length-char_length, ' ');
......
......@@ -40,6 +40,7 @@ show tables;
Tables_in_test
update mysql.user set password=old_password("gambling2") where user=_binary"test";
flush privileges;
set password="";
set password='gambling3';
ERROR HY000: Password hash should be a 41-digit hexadecimal number
set password=old_password('gambling3');
......
drop table if exists t1, t2;
CREATE TABLE t1 ( a int );
INSERT INTO t1 VALUES (1),(2),(1);
CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1;
CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1;
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
ERROR 42S02: Table 'test.t2' doesn't exist
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1;
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1;
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
ERROR 42S02: Table 'test.t2' doesn't exist
CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1;
CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1;
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
ERROR 42S02: Table 'test.t2' doesn't exist
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1;
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1;
ERROR 23000: Duplicate entry '1' for key 1
select * from t2;
ERROR 42S02: Table 'test.t2' doesn't exist
drop table if exists t1;
drop table if exists t2;
drop table if exists t1,t2;
set names utf8;
select left(_utf8 0xD0B0D0B1D0B2,1);
left(_utf8 0xD0B0D0B1D0B2,1)
......
......@@ -52,13 +52,13 @@ select * from t1 ignore key (key1) where text1='teststring' or text1 like 'tests
text1
teststring
teststring
select * from t1 where text1='teststring' or text1 like 'teststring_%';
text1
teststring
teststring
select * from t1 where text1='teststring' or text1 > 'teststring\t';
text1
teststring
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
concat('|', text1, '|')
|teststring |
|teststring|
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
concat('|', text1, '|')
|teststring|
select text1, length(text1) from t1 order by text1;
text1 length(text1)
nothing 7
......@@ -77,7 +77,28 @@ concat('|', text1, '|')
|teststring|
|teststring |
|teststring |
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
concat('|', text1, '|')
|teststring|
|teststring |
select concat('|', text1, '|') from t1 where text1='teststring';
concat('|', text1, '|')
|teststring|
select concat('|', text1, '|') from t1 where text1='teststring ';
concat('|', text1, '|')
|teststring |
alter table t1 modify text1 text not null, pack_keys=1;
select concat('|', text1, '|') from t1 where text1='teststring';
concat('|', text1, '|')
|teststring|
|teststring |
select concat('|', text1, '|') from t1 where text1='teststring ';
concat('|', text1, '|')
|teststring|
|teststring |
explain select concat('|', text1, '|') from t1 where text1='teststring ';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range key1 key1 22 NULL 2 Using where
select * from t1 where text1 like 'teststring_%';
text1
teststring
......@@ -87,10 +108,10 @@ text1
teststring
teststring
teststring
select * from t1 where text1='teststring' or text1 > 'teststring\t';
text1
teststring
teststring
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
concat('|', text1, '|')
|teststring|
|teststring |
select concat('|', text1, '|') from t1 order by text1;
concat('|', text1, '|')
|nothing|
......
......@@ -127,3 +127,4 @@ having (a.description is not null) and (c=0);
id description c
1 test 0
2 test2 0
drop table t1,t2,t3;
......@@ -593,9 +593,12 @@ create table t1 (id integer primary key auto_increment, txt text, unique index t
insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL);
select * from t1 where txt='Chevy' or txt is NULL;
id txt
3 NULL
1 Chevy
2 Chevy
3 NULL
explain select * from t1 where txt='Chevy' or txt is NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range txt_index txt_index 23 NULL 2 Using where
select * from t1 where txt='Chevy ';
id txt
1 Chevy
......@@ -663,6 +666,21 @@ id txt
1 Chevy
2 Chevy
4 Ford
alter table t1 modify column txt blob;
explain select * from t1 where txt='Chevy' or txt is NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref_or_null txt_index txt_index 23 const 2 Using where
select * from t1 where txt='Chevy' or txt is NULL;
id txt
1 Chevy
3 NULL
explain select * from t1 where txt='Chevy' or txt is NULL order by txt;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref_or_null txt_index txt_index 23 const 2 Using where; Using filesort
select * from t1 where txt='Chevy' or txt is NULL order by txt;
id txt
3 NULL
1 Chevy
drop table t1;
CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1)));
INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
......
......@@ -365,3 +365,15 @@ select * from t1;
t1 i
2004-04-01 00:00:00 10
drop table t1;
create table t1 (ts timestamp(19));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`ts` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1
set TIMESTAMP=1000000000;
insert into t1 values ();
select * from t1;
ts
2001-09-09 04:46:40
drop table t1;
......@@ -48,6 +48,7 @@ flush privileges;
#connect (con1,localhost,test,gambling2,"");
#show tables;
connect (con1,localhost,test,gambling2,mysql);
set password="";
--error 1105
set password='gambling3';
set password=old_password('gambling3');
......
......@@ -12,18 +12,18 @@ drop table if exists t1, t2;
CREATE TABLE t1 ( a int );
INSERT INTO t1 VALUES (1),(2),(1);
--error 1062;
CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1;
CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1;
--error 1146;
select * from t2;
--error 1062;
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1;
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1;
--error 1146;
select * from t2;
--error 1062;
CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1;
CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1;
--error 1146;
select * from t2;
--error 1062;
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1;
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1;
--error 1146;
select * from t2;
......@@ -3,8 +3,7 @@
#
--disable_warnings
drop table if exists t1;
drop table if exists t2;
drop table if exists t1,t2;
--enable_warnings
set names utf8;
......
......@@ -31,19 +31,25 @@ explain select * from t1 order by text1;
alter table t1 modify text1 char(32) binary not null;
check table t1;
select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
select * from t1 where text1='teststring' or text1 like 'teststring_%';
select * from t1 where text1='teststring' or text1 > 'teststring\t';
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
select text1, length(text1) from t1 order by text1;
select text1, length(text1) from t1 order by binary text1;
alter table t1 modify text1 blob not null, drop key key1, add key key1 (text1(20));
insert into t1 values ('teststring ');
select concat('|', text1, '|') from t1 order by text1;
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
select concat('|', text1, '|') from t1 where text1='teststring';
select concat('|', text1, '|') from t1 where text1='teststring ';
alter table t1 modify text1 text not null, pack_keys=1;
select concat('|', text1, '|') from t1 where text1='teststring';
select concat('|', text1, '|') from t1 where text1='teststring ';
explain select concat('|', text1, '|') from t1 where text1='teststring ';
select * from t1 where text1 like 'teststring_%';
select * from t1 where text1='teststring' or text1 like 'teststring_%';
select * from t1 where text1='teststring' or text1 > 'teststring\t';
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
select concat('|', text1, '|') from t1 order by text1;
drop table t1;
......
......@@ -121,3 +121,4 @@ select
from t1 a left join t3 b on a.id=b.order_id
group by a.id, a.description
having (a.description is not null) and (c=0);
drop table t1,t2,t3;
......@@ -340,6 +340,7 @@ drop table t1;
create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20)));
insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL);
select * from t1 where txt='Chevy' or txt is NULL;
explain select * from t1 where txt='Chevy' or txt is NULL;
select * from t1 where txt='Chevy ';
select * from t1 where txt='Chevy ' or txt='Chevy';
select * from t1 where txt='Chevy' or txt='Chevy ';
......@@ -358,7 +359,13 @@ select * from t1 where txt < 'Chevy ' or txt is NULL;
select * from t1 where txt <= 'Chevy';
select * from t1 where txt > 'Chevy';
select * from t1 where txt >= 'Chevy';
alter table t1 modify column txt blob;
explain select * from t1 where txt='Chevy' or txt is NULL;
select * from t1 where txt='Chevy' or txt is NULL;
explain select * from t1 where txt='Chevy' or txt is NULL order by txt;
select * from t1 where txt='Chevy' or txt is NULL order by txt;
drop table t1;
CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1)));
INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
select max(i) from t1 where c = '';
......
......@@ -234,3 +234,13 @@ alter table t1 add i int default 10;
select * from t1;
drop table t1;
# Test for bug #4491, TIMESTAMP(19) should be possible to create and not
# only read in 4.0
#
create table t1 (ts timestamp(19));
show create table t1;
set TIMESTAMP=1000000000;
insert into t1 values ();
select * from t1;
drop table t1;
......@@ -1753,7 +1753,7 @@ void Field_medium::sql_type(String &res) const
int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
{
long tmp;
int error= 0, cuted_fields= 0;
int error= 0;
char *end;
tmp= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
......@@ -1781,7 +1781,7 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
#if SIZEOF_LONG > 4
if (unsigned_flag)
{
if (tmp > UINT_MAX32)
if ((ulong) tmp > UINT_MAX32)
{
tmp= UINT_MAX32;
error= 1;
......@@ -4277,27 +4277,17 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
int Field_str::store(double nr)
{
bool use_scientific_notation=TRUE;
char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
uint length;
if (field_length < 32 && nr > 1) // TODO: negative numbers
{
if (ceiling == 0)
{
static double e[]= {1e1, 1e2, 1e4, 1e8, 1e16 };
double p= 1;
for (int i= sizeof(e)/sizeof(e[0]), j= 1<<i ; j; i--, j>>= 1 )
{
if (field_length & j)
p*= e[i];
}
ceiling= p-1;
}
use_scientific_notation= (ceiling < nr);
}
length= (uint)sprintf(buff, "%-.*g",
use_scientific_notation ? max(0,(int)field_length-5) : field_length,
nr);
bool use_scientific_notation= TRUE;
use_scientific_notation= TRUE;
if (field_length < 32 && fabs(nr) < log_10[field_length]-1)
use_scientific_notation= FALSE;
length= (uint) my_sprintf(buff, (buff, "%-.*g",
(use_scientific_notation ?
max(0, (int)field_length-5) :
field_length),
nr));
/*
+1 below is because "precision" in %g above means the
max. number of significant digits, not the output width.
......@@ -4310,6 +4300,7 @@ int Field_str::store(double nr)
return store((const char *)buff, min(length, field_length), charset());
}
int Field_string::store(longlong nr)
{
char buff[64];
......@@ -4403,9 +4394,8 @@ char *Field_string::pack(char *to, const char *from, uint max_length)
char *Field_string::pack_key(char *to, const char *from, uint max_length)
{
int length=min(field_length,max_length);
uint char_length= (field_charset->mbmaxlen > 1) ?
max_length/field_charset->mbmaxlen : max_length;
uint length= min(field_length,max_length);
uint char_length= max_length/field_charset->mbmaxlen;
if (length > char_length)
char_length= my_charpos(field_charset, from, from+length, char_length);
set_if_smaller(length, char_length);
......
......@@ -336,14 +336,13 @@ public:
class Field_str :public Field {
protected:
CHARSET_INFO *field_charset;
double ceiling; // for ::store(double nr)
public:
Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
const char *field_name_arg,
struct st_table *table_arg,CHARSET_INFO *charset)
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg), ceiling(0.0)
unireg_check_arg, field_name_arg, table_arg)
{
field_charset=charset;
if (charset->state & MY_CS_BINSORT)
......
......@@ -1732,8 +1732,8 @@ bool Item_func_in::nulls_in_row()
static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
{
return cs->coll->strnncollsp(cs,
(unsigned char *) x->ptr(),x->length(),
(unsigned char *) y->ptr(),y->length());
(uchar *) x->ptr(),x->length(),
(uchar *) y->ptr(),y->length());
}
......
......@@ -39,7 +39,8 @@ C_MODE_END
String my_empty_string("",default_charset_info);
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname)
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
const char *fname)
{
my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0),
c1.collation->name,c1.derivation_name(),
......@@ -62,8 +63,9 @@ double Item_str_func::val()
{
DBUG_ASSERT(fixed == 1);
int err;
String *res;
res=val_str(&str_value);
char buff[64];
String *res, tmp(buff,sizeof(buff), &my_charset_bin);
res= val_str(&tmp);
return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(),
NULL, &err) : 0.0;
}
......@@ -72,8 +74,9 @@ longlong Item_str_func::val_int()
{
DBUG_ASSERT(fixed == 1);
int err;
String *res;
res=val_str(&str_value);
char buff[22];
String *res, tmp(buff,sizeof(buff), &my_charset_bin);
res= val_str(&tmp);
return (res ?
my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL,
&err) :
......@@ -986,10 +989,7 @@ String *Item_func_left::val_str(String *str)
if (res->length() <= (uint) length ||
res->length() <= (char_pos= res->charpos(length)))
return res;
if (&str_value == res)
str_value.length(char_pos);
else
str_value.set(*res, 0, char_pos);
str_value.set(*res, 0, char_pos);
return &str_value;
}
......@@ -2200,7 +2200,8 @@ String *Item_func_conv_charset::val_str(String *str)
null_value=1;
return 0;
}
null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),conv_charset);
null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),
conv_charset);
return null_value ? 0 : &str_value;
}
......
......@@ -1945,13 +1945,12 @@ void Item_func_group_concat::reset_field()
bool
Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
uint i; /* for loop variable */
DBUG_ASSERT(fixed == 0);
if (save_args_for_prepared_statement(thd))
return 1;
uint i; /* for loop variable */
if (!thd->allow_sum_func)
{
my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0));
......@@ -1971,7 +1970,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1))
return 1;
if (i < arg_count_field)
maybe_null |= args[i]->maybe_null;
maybe_null|= args[i]->maybe_null;
}
result_field= 0;
......@@ -2048,7 +2047,8 @@ bool Item_func_group_concat::setup(THD *thd)
of a record instead of a pointer of one.
*/
if (!(table=create_tmp_table(thd, tmp_table_param, all_fields,
(ORDER*) 0, 0, TRUE,select_lex->options | thd->options,
(ORDER*) 0, 0, TRUE,
select_lex->options | thd->options,
HA_POS_ERROR,(char *) "")))
DBUG_RETURN(1);
table->file->extra(HA_EXTRA_NO_ROWS);
......
......@@ -200,7 +200,7 @@ net_printf(THD *thd, uint errcode, ...)
2+SQLSTATE_LENGTH+1 : 2) : 0);
#ifndef EMBEDDED_LIBRARY
text_pos=(char*) net->buff + head_length + offset + 1;
length=(char*)net->buff_end-text_pos;
length= (uint) ((char*)net->buff_end - text_pos);
#else
length=sizeof(text_pos)-1;
#endif
......
......@@ -551,21 +551,19 @@ static ulong get_sort(uint count,...)
uint chars= 0;
uint wild_pos= 0; /* first wildcard position */
if (start= str)
if ((start= str))
{
for (; *str ; str++)
{
if (*str == wild_many || *str == wild_one || *str == wild_prefix)
{
wild_pos= str - start + 1;
wild_pos= (uint) (str - start) + 1;
break;
}
else
chars++;
chars= 128; // Marker that chars existed
}
}
sort= (sort << 8) + (wild_pos ? (wild_pos > 127 ? 127 : wild_pos) :
(chars ? 128 : 0));
sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars);
}
va_end(args);
return sort;
......
......@@ -833,7 +833,8 @@ JOIN::optimize()
((group_list && const_tables != tables &&
(!simple_group ||
!test_if_skip_sort_order(&join_tab[const_tables], group_list,
unit->select_limit_cnt, 0))) || select_distinct) &&
unit->select_limit_cnt, 0))) ||
select_distinct) &&
tmp_table_param.quick_group && !procedure)
{
need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort
......@@ -2163,22 +2164,32 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, COND *cond,
number. cmp_type() is checked to allow compare of dates to numbers.
eq_func is NEVER true when num_values > 1
*/
if (!eq_func ||
field->result_type() == STRING_RESULT &&
(*value)->result_type() != STRING_RESULT &&
field->cmp_type() != (*value)->result_type())
return;
/*
We can't use indexes if the effective collation
of the operation differ from the field collation.
*/
if (field->result_type() == STRING_RESULT &&
(*value)->result_type() == STRING_RESULT &&
field->cmp_type() == STRING_RESULT &&
((Field_str*)field)->charset() != cond->compare_collation())
return;
if (!eq_func)
return;
if (field->result_type() == STRING_RESULT)
{
if ((*value)->result_type() != STRING_RESULT)
{
if (field->cmp_type() != (*value)->result_type())
return;
}
else
{
/*
We can't use indexes if the effective collation
of the operation differ from the field collation.
We can also not used index on a text column, as the column may
contain 'x' 'x\t' 'x ' and 'read_next_same' will stop after
'x' when searching for WHERE col='x '
*/
if (field->cmp_type() == STRING_RESULT &&
(((Field_str*)field)->charset() != cond->compare_collation() ||
((*value)->type() != Item::NULL_ITEM &&
(field->flags & BLOB_FLAG) && !field->binary())))
return;
}
}
}
}
DBUG_ASSERT(num_values == 1);
......@@ -5564,9 +5575,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
table->file->info(HA_STATUS_VARIABLE); /* update table->file->records */
new_table.file->start_bulk_insert(table->file->records);
#else
/*
HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it explicitly.
*/
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
#endif
......@@ -7234,9 +7243,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
keys.merge(table->used_keys);
/*
We are adding here also the index speified in FORCE INDEX clause,
We are adding here also the index specified in FORCE INDEX clause,
if any.
This is to allow users to use index in ORDER BY.
This is to allow users to use index in ORDER BY.
*/
if (table->force_index)
keys.merge(table->keys_in_use_for_query);
......
......@@ -2158,20 +2158,21 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
if (!(result_tz= new (&tz_storage) Time_zone_offset(offset)) ||
my_hash_insert(&offset_tzs, (const byte *) result_tz))
{
result_tz= 0;
sql_print_error("Fatal error: Out of memory "
"while setting new time zone");
result_tz= 0;
}
}
} else {
}
else
{
result_tz= 0;
if ((tmp_tzname= (TZ_NAMES_ENTRY *)hash_search(&tz_names,
(const byte *)name->ptr(),
name->length())))
result_tz= tmp_tzname->tz;
else if(time_zone_tables_exist)
else if (time_zone_tables_exist)
result_tz= tz_load_from_open_tables(name, tz_tables);
else
result_tz= 0;
}
VOID(pthread_mutex_unlock(&tz_LOCK));
......
......@@ -93,7 +93,7 @@ static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)),
NOTE
This function is used for real binary strings, i.e. for
BLOB, BINARY(N) and VARBINARY(N).
It does not ignore trailing spaces.
It compares trailing spaces as spaces.
RETURN
< 0 s < t
......@@ -133,7 +133,8 @@ static int my_strnncoll_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),
NOTE
This function is used for character strings with binary collations.
It ignores trailing spaces.
The shorter string is extended with end space to be as long as the longer
one.
RETURN
< 0 s < t
......
......@@ -237,7 +237,8 @@ int my_wildcmp_mb(CHARSET_INFO *cs,
if (str++ == str_end) return (-1);
}
{
int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,w_many);
int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,
w_many);
if (tmp <= 0)
return (tmp);
}
......@@ -248,41 +249,46 @@ int my_wildcmp_mb(CHARSET_INFO *cs,
return (str != str_end ? 1 : 0);
}
uint my_numchars_mb(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e)
const char *pos, const char *end)
{
register uint32 n=0,mblen;
while (b < e)
register uint32 count=0;
while (pos < end)
{
b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1;
++n;
uint mblen;
pos+= (mblen= my_ismbchar(cs,pos,end)) ? mblen : 1;
count++;
}
return n;
return count;
}
uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e, uint pos)
const char *pos, const char *end, uint length)
{
uint mblen;
const char *b0=b;
const char *start= pos;
while (pos && b<e)
while (length && pos < end)
{
b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1;
pos--;
uint mblen;
pos+= (mblen= my_ismbchar(cs, pos, end)) ? mblen : 1;
length--;
}
return pos ? e+2-b0 : b-b0;
return length ? end+2-start : pos-start;
}
uint my_well_formed_len_mb(CHARSET_INFO *cs,
const char *b, const char *e, uint pos)
{
my_wc_t wc;
int mblen;
const char *b_start= b;
while (pos)
{
my_wc_t wc;
int mblen;
if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <0)
break;
b+= mblen;
......@@ -374,7 +380,8 @@ static int my_strnncoll_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
NOTE
This function is used for character strings with binary collations.
It ignores trailing spaces.
The shorter string is extended with end space to be as long as the longer
one.
RETURN
A negative number if s < t
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment