mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
LOCATE(), INSTR(), POSITION(), FIND_IN_SET(), SUBSTRING_INDEX()
now process arguments according to standard SQL collation determation rules.
This commit is contained in:
@ -249,6 +249,33 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
|
|||||||
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
|
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
|
||||||
1
|
1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
select POSITION(_latin1'B' IN _latin1'abcd');
|
||||||
|
POSITION(_latin1'B' IN _latin1'abcd')
|
||||||
|
2
|
||||||
|
select POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin);
|
||||||
|
POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin)
|
||||||
|
0
|
||||||
|
select POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd');
|
||||||
|
POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd')
|
||||||
|
0
|
||||||
|
select POSITION(_latin1'B' COLLATE latin1_general_ci IN _latin1'abcd' COLLATE latin1_bin);
|
||||||
|
ERROR HY000: Illegal mix of collations (latin1_bin,EXPLICIT) and (latin1_general_ci,EXPLICIT) for operation 'locate'
|
||||||
|
select POSITION(_latin1'B' IN _latin2'abcd');
|
||||||
|
ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'locate'
|
||||||
|
select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d');
|
||||||
|
FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')
|
||||||
|
2
|
||||||
|
select FIND_IN_SET(_latin1'B' COLLATE latin1_general_ci,_latin1'a,b,c,d' COLLATE latin1_bin);
|
||||||
|
ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'find_in_set'
|
||||||
|
select FIND_IN_SET(_latin1'B',_latin2'a,b,c,d');
|
||||||
|
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'find_in_set'
|
||||||
|
select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2);
|
||||||
|
SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2)
|
||||||
|
abcdabc
|
||||||
|
select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2);
|
||||||
|
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'substr_index'
|
||||||
|
select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2);
|
||||||
|
ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'substr_index'
|
||||||
select collation(bin(130)), coercibility(bin(130));
|
select collation(bin(130)), coercibility(bin(130));
|
||||||
collation(bin(130)) coercibility(bin(130))
|
collation(bin(130)) coercibility(bin(130))
|
||||||
latin1_swedish_ci 3
|
latin1_swedish_ci 3
|
||||||
|
@ -136,6 +136,33 @@ DROP TABLE t1;
|
|||||||
#
|
#
|
||||||
# Test collation and coercibility
|
# Test collation and coercibility
|
||||||
#
|
#
|
||||||
|
select POSITION(_latin1'B' IN _latin1'abcd');
|
||||||
|
select POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin);
|
||||||
|
select POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd');
|
||||||
|
--error 1265
|
||||||
|
select POSITION(_latin1'B' COLLATE latin1_general_ci IN _latin1'abcd' COLLATE latin1_bin);
|
||||||
|
--error 1265
|
||||||
|
select POSITION(_latin1'B' IN _latin2'abcd');
|
||||||
|
|
||||||
|
select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d');
|
||||||
|
--fix this:
|
||||||
|
--select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d' COLLATE latin1_bin);
|
||||||
|
--select FIND_IN_SET(_latin1'B' COLLATE latin1_bin,_latin1'a,b,c,d');
|
||||||
|
--error 1265
|
||||||
|
select FIND_IN_SET(_latin1'B' COLLATE latin1_general_ci,_latin1'a,b,c,d' COLLATE latin1_bin);
|
||||||
|
--error 1265
|
||||||
|
select FIND_IN_SET(_latin1'B',_latin2'a,b,c,d');
|
||||||
|
|
||||||
|
select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2);
|
||||||
|
--fix this:
|
||||||
|
--select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_bin,_latin1'd',2);
|
||||||
|
--select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd' COLLATE latin1_bin,2);
|
||||||
|
--error 1265
|
||||||
|
select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2);
|
||||||
|
--error 1265
|
||||||
|
select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2);
|
||||||
|
|
||||||
|
|
||||||
select collation(bin(130)), coercibility(bin(130));
|
select collation(bin(130)), coercibility(bin(130));
|
||||||
select collation(oct(130)), coercibility(oct(130));
|
select collation(oct(130)), coercibility(oct(130));
|
||||||
select collation(conv(130,16,10)), coercibility(conv(130,16,10));
|
select collation(conv(130,16,10)), coercibility(conv(130,16,10));
|
||||||
|
@ -1045,10 +1045,18 @@ longlong Item_func_coercibility::val_int()
|
|||||||
return (longlong) args[0]->derivation();
|
return (longlong) args[0]->derivation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Item_func_locate::fix_length_and_dec()
|
||||||
|
{
|
||||||
|
maybe_null=0; max_length=11;
|
||||||
|
if (cmp_collation.set(args[0]->collation, args[1]->collation))
|
||||||
|
my_coll_agg_error(args[0]->collation, args[1]->collation, func_name());
|
||||||
|
}
|
||||||
|
|
||||||
longlong Item_func_locate::val_int()
|
longlong Item_func_locate::val_int()
|
||||||
{
|
{
|
||||||
String *a=args[0]->val_str(&value1);
|
String *a=args[0]->val_str(&value1);
|
||||||
String *b=args[1]->val_str(&value2);
|
String *b=args[1]->val_str(&value2);
|
||||||
|
bool binary_cmp= (cmp_collation.collation->state & MY_CS_BINSORT) ? 1 : 0;
|
||||||
if (!a || !b)
|
if (!a || !b)
|
||||||
{
|
{
|
||||||
null_value=1;
|
null_value=1;
|
||||||
@ -1063,7 +1071,7 @@ longlong Item_func_locate::val_int()
|
|||||||
{
|
{
|
||||||
start=(uint) args[2]->val_int()-1;
|
start=(uint) args[2]->val_int()-1;
|
||||||
#ifdef USE_MB
|
#ifdef USE_MB
|
||||||
if (use_mb(a->charset()))
|
if (use_mb(cmp_collation.collation))
|
||||||
{
|
{
|
||||||
start0=start;
|
start0=start;
|
||||||
if (!binary_cmp)
|
if (!binary_cmp)
|
||||||
@ -1076,7 +1084,7 @@ longlong Item_func_locate::val_int()
|
|||||||
if (!b->length()) // Found empty string at start
|
if (!b->length()) // Found empty string at start
|
||||||
return (longlong) (start+1);
|
return (longlong) (start+1);
|
||||||
#ifdef USE_MB
|
#ifdef USE_MB
|
||||||
if (use_mb(a->charset()) && !binary_cmp)
|
if (use_mb(cmp_collation.collation) && !binary_cmp)
|
||||||
{
|
{
|
||||||
const char *ptr=a->ptr()+start;
|
const char *ptr=a->ptr()+start;
|
||||||
const char *search=b->ptr();
|
const char *search=b->ptr();
|
||||||
@ -1095,7 +1103,7 @@ longlong Item_func_locate::val_int()
|
|||||||
return (longlong) start0+1;
|
return (longlong) start0+1;
|
||||||
}
|
}
|
||||||
skipp:
|
skipp:
|
||||||
if ((l=my_ismbchar(a->charset(),ptr,strend)))
|
if ((l=my_ismbchar(cmp_collation.collation,ptr,strend)))
|
||||||
ptr+=l;
|
ptr+=l;
|
||||||
else ++ptr;
|
else ++ptr;
|
||||||
++start0;
|
++start0;
|
||||||
@ -1201,6 +1209,8 @@ void Item_func_find_in_set::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cmp_collation.set(args[0]->collation, args[1]->collation))
|
||||||
|
my_coll_agg_error(args[0]->collation, args[1]->collation, func_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char separator=',';
|
static const char separator=',';
|
||||||
@ -1228,7 +1238,6 @@ longlong Item_func_find_in_set::val_int()
|
|||||||
null_value=0;
|
null_value=0;
|
||||||
|
|
||||||
int diff;
|
int diff;
|
||||||
CHARSET_INFO *charset= find->charset();
|
|
||||||
if ((diff=buffer->length() - find->length()) >= 0)
|
if ((diff=buffer->length() - find->length()) >= 0)
|
||||||
{
|
{
|
||||||
const char *f_pos=find->ptr();
|
const char *f_pos=find->ptr();
|
||||||
@ -1242,7 +1251,8 @@ longlong Item_func_find_in_set::val_int()
|
|||||||
const char *pos= f_pos;
|
const char *pos= f_pos;
|
||||||
while (pos != f_end)
|
while (pos != f_end)
|
||||||
{
|
{
|
||||||
if (my_toupper(charset,*str) != my_toupper(charset,*pos))
|
if (my_toupper(cmp_collation.collation,*str) !=
|
||||||
|
my_toupper(cmp_collation.collation,*pos))
|
||||||
goto not_found;
|
goto not_found;
|
||||||
str++;
|
str++;
|
||||||
pos++;
|
pos++;
|
||||||
|
@ -610,17 +610,13 @@ public:
|
|||||||
class Item_func_locate :public Item_int_func
|
class Item_func_locate :public Item_int_func
|
||||||
{
|
{
|
||||||
String value1,value2;
|
String value1,value2;
|
||||||
bool binary_cmp;
|
DTCollation cmp_collation;
|
||||||
public:
|
public:
|
||||||
Item_func_locate(Item *a,Item *b) :Item_int_func(a,b) {}
|
Item_func_locate(Item *a,Item *b) :Item_int_func(a,b) {}
|
||||||
Item_func_locate(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
|
Item_func_locate(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
|
||||||
const char *func_name() const { return "locate"; }
|
const char *func_name() const { return "locate"; }
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec();
|
||||||
{
|
|
||||||
maybe_null=0; max_length=11;
|
|
||||||
binary_cmp = args[0]->binary() || args[1]->binary();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -684,6 +680,7 @@ class Item_func_find_in_set :public Item_int_func
|
|||||||
String value,value2;
|
String value,value2;
|
||||||
uint enum_value;
|
uint enum_value;
|
||||||
ulonglong enum_bit;
|
ulonglong enum_bit;
|
||||||
|
DTCollation cmp_collation;
|
||||||
public:
|
public:
|
||||||
Item_func_find_in_set(Item *a,Item *b) :Item_int_func(a,b),enum_value(0) {}
|
Item_func_find_in_set(Item *a,Item *b) :Item_int_func(a,b),enum_value(0) {}
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
|
@ -1037,6 +1037,15 @@ void Item_func_substr::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_func_substr_index::fix_length_and_dec()
|
||||||
|
{
|
||||||
|
max_length= args[0]->max_length;
|
||||||
|
if (collation.set(args[0]->collation, args[1]->collation) ||
|
||||||
|
(collation.derivation == DERIVATION_NONE))
|
||||||
|
my_coll_agg_error(args[0]->collation, args[1]->collation, func_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String *Item_func_substr_index::val_str(String *str)
|
String *Item_func_substr_index::val_str(String *str)
|
||||||
{
|
{
|
||||||
String *res =args[0]->val_str(str);
|
String *res =args[0]->val_str(str);
|
||||||
@ -1054,6 +1063,8 @@ String *Item_func_substr_index::val_str(String *str)
|
|||||||
if (!res->length() || !delimeter_length || !count)
|
if (!res->length() || !delimeter_length || !count)
|
||||||
return &empty_string; // Wrong parameters
|
return &empty_string; // Wrong parameters
|
||||||
|
|
||||||
|
res->set_charset(collation.collation);
|
||||||
|
|
||||||
#ifdef USE_MB
|
#ifdef USE_MB
|
||||||
if (use_mb(res->charset()))
|
if (use_mb(res->charset()))
|
||||||
{
|
{
|
||||||
|
@ -215,7 +215,7 @@ class Item_func_substr_index :public Item_str_func
|
|||||||
public:
|
public:
|
||||||
Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
|
Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
|
||||||
String *val_str(String *);
|
String *val_str(String *);
|
||||||
void fix_length_and_dec() { max_length= args[0]->max_length; }
|
void fix_length_and_dec();
|
||||||
const char *func_name() const { return "substr_index"; }
|
const char *func_name() const { return "substr_index"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user