mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge
sql/item_subselect.cc: Auto merged sql/sql_select.cc: Auto merged mysql-test/r/subselect.result: SCCS merged mysql-test/t/subselect.test: SCCS merged
This commit is contained in:
commit
9e7b3cde60
50 changed files with 597 additions and 318 deletions
|
@ -2452,9 +2452,11 @@ char *get_arg(char *line, my_bool get_next_arg)
|
|||
ptr++;
|
||||
if (*ptr == '\\') // short command was used
|
||||
ptr+= 2;
|
||||
while (!my_isspace(system_charset_info, *ptr)) // skip command
|
||||
while (*ptr &&!my_isspace(system_charset_info, *ptr)) // skip command
|
||||
ptr++;
|
||||
}
|
||||
if (!*ptr)
|
||||
return NullS;
|
||||
while (my_isspace(system_charset_info, *ptr))
|
||||
ptr++;
|
||||
if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
|
||||
|
|
|
@ -74,6 +74,22 @@ typedef struct my_uni_idx_st
|
|||
} MY_UNI_IDX;
|
||||
|
||||
|
||||
enum my_lex_states
|
||||
{
|
||||
MY_LEX_START, MY_LEX_CHAR, MY_LEX_IDENT,
|
||||
MY_LEX_IDENT_SEP, MY_LEX_IDENT_START,
|
||||
MY_LEX_FOUND_IDENT, MY_LEX_SIGNED_NUMBER, MY_LEX_REAL, MY_LEX_HEX_NUMBER,
|
||||
MY_LEX_CMP_OP, MY_LEX_LONG_CMP_OP, MY_LEX_STRING, MY_LEX_COMMENT, MY_LEX_END,
|
||||
MY_LEX_OPERATOR_OR_IDENT, MY_LEX_NUMBER_IDENT, MY_LEX_INT_OR_REAL,
|
||||
MY_LEX_REAL_OR_POINT, MY_LEX_BOOL, MY_LEX_EOL, MY_LEX_ESCAPE,
|
||||
MY_LEX_LONG_COMMENT, MY_LEX_END_LONG_COMMENT, MY_LEX_COLON,
|
||||
MY_LEX_SET_VAR, MY_LEX_USER_END, MY_LEX_HOSTNAME, MY_LEX_SKIP,
|
||||
MY_LEX_USER_VARIABLE_DELIMITER, MY_LEX_SYSTEM_VAR,
|
||||
MY_LEX_IDENT_OR_KEYWORD, MY_LEX_IDENT_OR_HEX, MY_LEX_IDENT_OR_BIN,
|
||||
MY_LEX_STRING_OR_DELIMITER
|
||||
};
|
||||
|
||||
|
||||
typedef struct charset_info_st
|
||||
{
|
||||
uint number;
|
||||
|
@ -89,6 +105,8 @@ typedef struct charset_info_st
|
|||
uchar *sort_order;
|
||||
uint16 *tab_to_uni;
|
||||
MY_UNI_IDX *tab_from_uni;
|
||||
uchar state_map[256];
|
||||
uchar ident_map[256];
|
||||
|
||||
/* Collation routines */
|
||||
uint strxfrm_multiply;
|
||||
|
|
|
@ -3824,8 +3824,8 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows)
|
|||
MI_KEYDEF *key=share->keyinfo;
|
||||
for (i=0 ; i < share->base.keys ; i++,key++)
|
||||
{
|
||||
if (!(key->flag & HA_NOSAME) && ! mi_too_big_key_for_sort(key,rows) &&
|
||||
info->s->base.auto_key != i+1)
|
||||
if (!(key->flag & (HA_NOSAME | HA_SPATIAL)) &&
|
||||
! mi_too_big_key_for_sort(key,rows) && info->s->base.auto_key != i+1)
|
||||
{
|
||||
share->state.key_map&= ~ ((ulonglong) 1 << i);
|
||||
info->update|= HA_STATE_CHANGED;
|
||||
|
|
|
@ -45,29 +45,30 @@ name
|
|||
drop table t1,t2;
|
||||
create table t1 (a char(10) not null, b char(10) binary not null,key (a), key(b));
|
||||
insert into t1 values ("hello ","hello "),("hello2 ","hello2 ");
|
||||
select * from t1 where a="hello";
|
||||
a b
|
||||
hello hello
|
||||
select * from t1 where a="hello ";
|
||||
a b
|
||||
hello hello
|
||||
select * from t1 ignore index (a) where a="hello ";
|
||||
a b
|
||||
hello hello
|
||||
select * from t1 where b="hello";
|
||||
a b
|
||||
hello hello
|
||||
select * from t1 where b="hello ";
|
||||
a b
|
||||
hello hello
|
||||
select * from t1 ignore index (b) where b="hello ";
|
||||
a b
|
||||
select concat("-",a,"-",b,"-") from t1 where a="hello";
|
||||
concat("-",a,"-",b,"-")
|
||||
-hello-hello-
|
||||
select concat("-",a,"-",b,"-") from t1 where a="hello ";
|
||||
concat("-",a,"-",b,"-")
|
||||
-hello-hello-
|
||||
select concat("-",a,"-",b,"-") from t1 ignore index (a) where a="hello ";
|
||||
concat("-",a,"-",b,"-")
|
||||
-hello-hello-
|
||||
select concat("-",a,"-",b,"-") from t1 where b="hello";
|
||||
concat("-",a,"-",b,"-")
|
||||
-hello-hello-
|
||||
select concat("-",a,"-",b,"-") from t1 where b="hello ";
|
||||
concat("-",a,"-",b,"-")
|
||||
-hello-hello-
|
||||
select concat("-",a,"-",b,"-") from t1 ignore index (b) where b="hello ";
|
||||
concat("-",a,"-",b,"-")
|
||||
-hello-hello-
|
||||
alter table t1 modify b tinytext not null, drop key b, add key (b(100));
|
||||
select * from t1 where b="hello ";
|
||||
a b
|
||||
select * from t1 ignore index (b) where b="hello ";
|
||||
a b
|
||||
hello hello
|
||||
select concat("-",a,"-",b,"-") from t1 where b="hello ";
|
||||
concat("-",a,"-",b,"-")
|
||||
select concat("-",a,"-",b,"-") from t1 ignore index (b) where b="hello ";
|
||||
concat("-",a,"-",b,"-")
|
||||
-hello-hello-
|
||||
drop table t1;
|
||||
create table t1 (b char(8));
|
||||
insert into t1 values(NULL);
|
||||
|
|
|
@ -528,6 +528,10 @@ SET NAMES latin1 COLLATE latin1_bin;
|
|||
SHOW VARIABLES LIKE 'client_collation';
|
||||
Variable_name Value
|
||||
client_collation latin1_bin
|
||||
SET NAMES LATIN1 COLLATE Latin1_Bin;
|
||||
SHOW VARIABLES LIKE 'client_collation';
|
||||
Variable_name Value
|
||||
client_collation latin1_bin
|
||||
SET NAMES 'latin1' COLLATE 'latin1_bin';
|
||||
SHOW VARIABLES LIKE 'client_collation';
|
||||
Variable_name Value
|
||||
|
|
|
@ -40,7 +40,12 @@ set insert_id=1234;
|
|||
insert into t2 values(NULL);
|
||||
set global sql_slave_skip_counter=1;
|
||||
start slave;
|
||||
purge master logs to 'master-bin.000003';
|
||||
purge master logs to 'master-bin.000002';
|
||||
show binary logs;
|
||||
Log_name
|
||||
master-bin.000002
|
||||
master-bin.000003
|
||||
purge logs before now();
|
||||
show binary logs;
|
||||
Log_name
|
||||
master-bin.000003
|
||||
|
|
|
@ -1072,3 +1072,13 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
2 DEPENDENT SUBSELECT NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||
drop table t1;
|
||||
CREATE TABLE `t1` (
|
||||
`i` int(11) NOT NULL default '0',
|
||||
PRIMARY KEY (`i`)
|
||||
) TYPE=MyISAM CHARSET=latin1;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i));
|
||||
Invalid use of group function
|
||||
UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
|
||||
Invalid use of group function
|
||||
drop table t1;
|
||||
|
|
|
@ -269,3 +269,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
drop table t1,t2;
|
||||
(select 1) union (select 2) order by 0;
|
||||
Unknown column '0' in 'order clause'
|
||||
SELECT @a:=1 UNION SELECT @a:=@a+1;
|
||||
@a:=1
|
||||
1
|
||||
2
|
||||
|
|
|
@ -30,16 +30,16 @@ drop table t1,t2;
|
|||
|
||||
create table t1 (a char(10) not null, b char(10) binary not null,key (a), key(b));
|
||||
insert into t1 values ("hello ","hello "),("hello2 ","hello2 ");
|
||||
select * from t1 where a="hello";
|
||||
select * from t1 where a="hello ";
|
||||
select * from t1 ignore index (a) where a="hello ";
|
||||
select * from t1 where b="hello";
|
||||
select * from t1 where b="hello ";
|
||||
select * from t1 ignore index (b) where b="hello ";
|
||||
select concat("-",a,"-",b,"-") from t1 where a="hello";
|
||||
select concat("-",a,"-",b,"-") from t1 where a="hello ";
|
||||
select concat("-",a,"-",b,"-") from t1 ignore index (a) where a="hello ";
|
||||
select concat("-",a,"-",b,"-") from t1 where b="hello";
|
||||
select concat("-",a,"-",b,"-") from t1 where b="hello ";
|
||||
select concat("-",a,"-",b,"-") from t1 ignore index (b) where b="hello ";
|
||||
# blob test
|
||||
alter table t1 modify b tinytext not null, drop key b, add key (b(100));
|
||||
select * from t1 where b="hello ";
|
||||
select * from t1 ignore index (b) where b="hello ";
|
||||
select concat("-",a,"-",b,"-") from t1 where b="hello ";
|
||||
select concat("-",a,"-",b,"-") from t1 ignore index (b) where b="hello ";
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
|
|
|
@ -135,6 +135,8 @@ SHOW VARIABLES LIKE 'client_collation';
|
|||
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
|
||||
SET NAMES latin1 COLLATE latin1_bin;
|
||||
SHOW VARIABLES LIKE 'client_collation';
|
||||
SET NAMES LATIN1 COLLATE Latin1_Bin;
|
||||
SHOW VARIABLES LIKE 'client_collation';
|
||||
SET NAMES 'latin1' COLLATE 'latin1_bin';
|
||||
SHOW VARIABLES LIKE 'client_collation';
|
||||
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
|
||||
|
|
|
@ -89,7 +89,9 @@ connection master;
|
|||
#let slave catch up
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
purge master logs to 'master-bin.000003';
|
||||
purge master logs to 'master-bin.000002';
|
||||
show binary logs;
|
||||
purge logs before now();
|
||||
show binary logs;
|
||||
insert into t2 values (65);
|
||||
sync_slave_with_master;
|
||||
|
|
|
@ -661,3 +661,15 @@ INSERT INTO t1 (pseudo) VALUES ('test1');
|
|||
SELECT 0 IN (SELECT 1 FROM t1 a);
|
||||
EXPLAIN SELECT 0 IN (SELECT 1 FROM t1 a);
|
||||
drop table t1;
|
||||
|
||||
CREATE TABLE `t1` (
|
||||
`i` int(11) NOT NULL default '0',
|
||||
PRIMARY KEY (`i`)
|
||||
) TYPE=MyISAM CHARSET=latin1;
|
||||
|
||||
INSERT INTO t1 VALUES (1);
|
||||
-- error 1111
|
||||
UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i));
|
||||
-- error 1111
|
||||
UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
|
||||
drop table t1;
|
||||
|
|
|
@ -144,3 +144,5 @@ explain (select * from t1 where a=1) union (select * from t1 where b=1);
|
|||
drop table t1,t2;
|
||||
--error 1054
|
||||
(select 1) union (select 2) order by 0;
|
||||
|
||||
SELECT @a:=1 UNION SELECT @a:=@a+1;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
- Initializing charset related structures
|
||||
- Loading dynamic charsets
|
||||
- Searching for a proper CHARSET_INFO
|
||||
using charset name, collation name or collatio ID
|
||||
using charset name, collation name or collation ID
|
||||
- Setting server default character set
|
||||
*/
|
||||
|
||||
|
@ -54,6 +54,62 @@ static void set_max_sort_char(CHARSET_INFO *cs)
|
|||
}
|
||||
|
||||
|
||||
static void init_state_maps(CHARSET_INFO *cs)
|
||||
{
|
||||
uint i;
|
||||
uchar *state_map= cs->state_map;
|
||||
uchar *ident_map= cs->ident_map;
|
||||
|
||||
/* Fill state_map with states to get a faster parser */
|
||||
for (i=0; i < 256 ; i++)
|
||||
{
|
||||
if (my_isalpha(cs,i))
|
||||
state_map[i]=(uchar) MY_LEX_IDENT;
|
||||
else if (my_isdigit(cs,i))
|
||||
state_map[i]=(uchar) MY_LEX_NUMBER_IDENT;
|
||||
#if defined(USE_MB) && defined(USE_MB_IDENT)
|
||||
else if (use_mb(cs) && my_ismbhead(cs, i))
|
||||
state_map[i]=(uchar) MY_LEX_IDENT;
|
||||
#endif
|
||||
else if (!my_isgraph(cs,i))
|
||||
state_map[i]=(uchar) MY_LEX_SKIP;
|
||||
else
|
||||
state_map[i]=(uchar) MY_LEX_CHAR;
|
||||
}
|
||||
state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) MY_LEX_IDENT;
|
||||
state_map[(uchar)'\'']=(uchar) MY_LEX_STRING;
|
||||
state_map[(uchar)'-']=state_map[(uchar)'+']=(uchar) MY_LEX_SIGNED_NUMBER;
|
||||
state_map[(uchar)'.']=(uchar) MY_LEX_REAL_OR_POINT;
|
||||
state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) MY_LEX_CMP_OP;
|
||||
state_map[(uchar)'<']= (uchar) MY_LEX_LONG_CMP_OP;
|
||||
state_map[(uchar)'&']=state_map[(uchar)'|']=(uchar) MY_LEX_BOOL;
|
||||
state_map[(uchar)'#']=(uchar) MY_LEX_COMMENT;
|
||||
state_map[(uchar)';']=(uchar) MY_LEX_COLON;
|
||||
state_map[(uchar)':']=(uchar) MY_LEX_SET_VAR;
|
||||
state_map[0]=(uchar) MY_LEX_EOL;
|
||||
state_map[(uchar)'\\']= (uchar) MY_LEX_ESCAPE;
|
||||
state_map[(uchar)'/']= (uchar) MY_LEX_LONG_COMMENT;
|
||||
state_map[(uchar)'*']= (uchar) MY_LEX_END_LONG_COMMENT;
|
||||
state_map[(uchar)'@']= (uchar) MY_LEX_USER_END;
|
||||
state_map[(uchar) '`']= (uchar) MY_LEX_USER_VARIABLE_DELIMITER;
|
||||
state_map[(uchar)'"']= (uchar) MY_LEX_STRING_OR_DELIMITER;
|
||||
|
||||
/*
|
||||
Create a second map to make it faster to find identifiers
|
||||
*/
|
||||
for (i=0; i < 256 ; i++)
|
||||
{
|
||||
ident_map[i]= (uchar) (state_map[i] == MY_LEX_IDENT ||
|
||||
state_map[i] == MY_LEX_NUMBER_IDENT);
|
||||
}
|
||||
|
||||
/* Special handling of hex and binary strings */
|
||||
state_map[(uchar)'x']= state_map[(uchar)'X']= (uchar) MY_LEX_IDENT_OR_HEX;
|
||||
state_map[(uchar)'b']= state_map[(uchar)'b']= (uchar) MY_LEX_IDENT_OR_BIN;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void simple_cs_init_functions(CHARSET_INFO *cs)
|
||||
{
|
||||
|
||||
|
@ -211,8 +267,11 @@ static void simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from)
|
|||
to->name= my_once_strdup(from->name,MYF(MY_WME));
|
||||
|
||||
if (from->ctype)
|
||||
{
|
||||
to->ctype= (uchar*) my_once_memdup((char*) from->ctype,
|
||||
MY_CS_CTYPE_TABLE_SIZE, MYF(MY_WME));
|
||||
init_state_maps(to);
|
||||
}
|
||||
if (from->to_lower)
|
||||
to->to_lower= (uchar*) my_once_memdup((char*) from->to_lower,
|
||||
MY_CS_TO_LOWER_TABLE_SIZE, MYF(MY_WME));
|
||||
|
@ -447,7 +506,10 @@ static my_bool init_available_charsets(myf myflags)
|
|||
for (cs=all_charsets; cs < all_charsets+255 ; cs++)
|
||||
{
|
||||
if (*cs)
|
||||
{
|
||||
set_max_sort_char(*cs);
|
||||
init_state_maps(*cs);
|
||||
}
|
||||
}
|
||||
|
||||
strmov(get_charsets_dir(fname), MY_CHARSET_INDEX);
|
||||
|
@ -479,7 +541,7 @@ uint get_charset_number(const char *charset_name)
|
|||
|
||||
for (cs= all_charsets; cs < all_charsets+255; ++cs)
|
||||
{
|
||||
if ( cs[0] && cs[0]->name && !strcmp(cs[0]->name, charset_name))
|
||||
if ( cs[0] && cs[0]->name && !strcasecmp(cs[0]->name, charset_name))
|
||||
return cs[0]->number;
|
||||
}
|
||||
return 0; /* this mimics find_type() */
|
||||
|
@ -593,7 +655,7 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name,
|
|||
for (css= all_charsets; css < all_charsets+255; ++css)
|
||||
{
|
||||
if ( css[0] && (css[0]->state & cs_flags) &&
|
||||
css[0]->csname && !strcmp(css[0]->csname, cs_name))
|
||||
css[0]->csname && !strcasecmp(css[0]->csname, cs_name))
|
||||
{
|
||||
cs= css[0]->number ? get_internal_charset(css[0]->number,flags) : NULL;
|
||||
break;
|
||||
|
|
|
@ -5163,7 +5163,7 @@ void Field_set::sql_type(String &res) const
|
|||
|
||||
bool Field::eq_def(Field *field)
|
||||
{
|
||||
if (real_type() != field->real_type() || binary() != field->binary() ||
|
||||
if (real_type() != field->real_type() || charset() != field->charset() ||
|
||||
pack_length() != field->pack_length())
|
||||
return 0;
|
||||
return 1;
|
||||
|
|
|
@ -507,8 +507,7 @@ static void make_sortkey(register SORTPARAM *param,
|
|||
if (res->ptr() != (char*) to)
|
||||
memcpy(to,res->ptr(),length);
|
||||
bzero((char *)to+length,diff);
|
||||
if (!item->binary())
|
||||
my_tosort(cs, (char*) to,length);
|
||||
my_tosort(cs, (char*) to,length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -918,6 +917,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset)
|
|||
{
|
||||
reg2 uint length;
|
||||
THD *thd= current_thd;
|
||||
CHARSET_INFO *cs;
|
||||
*multi_byte_charset= 0;
|
||||
|
||||
length=0;
|
||||
|
@ -926,20 +926,17 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset)
|
|||
sortorder->need_strxnfrm= 0;
|
||||
if (sortorder->field)
|
||||
{
|
||||
|
||||
if (sortorder->field->type() == FIELD_TYPE_BLOB)
|
||||
sortorder->length= thd->variables.max_sort_length;
|
||||
else
|
||||
{
|
||||
sortorder->length=sortorder->field->pack_length();
|
||||
if (!sortorder->field->binary())
|
||||
if (use_strnxfrm((cs=sortorder->field->charset())))
|
||||
{
|
||||
CHARSET_INFO *cs=sortorder->field->charset();
|
||||
if (use_strnxfrm(cs))
|
||||
{
|
||||
sortorder->need_strxnfrm= 1;
|
||||
*multi_byte_charset= 1;
|
||||
sortorder->length= sortorder->length*cs->strxfrm_multiply;
|
||||
}
|
||||
sortorder->need_strxnfrm= 1;
|
||||
*multi_byte_charset= 1;
|
||||
sortorder->length= sortorder->length*cs->strxfrm_multiply;
|
||||
}
|
||||
}
|
||||
if (sortorder->field->maybe_null())
|
||||
|
@ -950,15 +947,11 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset)
|
|||
switch ((sortorder->result_type=sortorder->item->result_type())) {
|
||||
case STRING_RESULT:
|
||||
sortorder->length=sortorder->item->max_length;
|
||||
if (!sortorder->item->binary())
|
||||
{
|
||||
CHARSET_INFO *cs=sortorder->item->charset();
|
||||
if (use_strnxfrm(cs))
|
||||
{
|
||||
sortorder->length= sortorder->length*cs->strxfrm_multiply;
|
||||
sortorder->need_strxnfrm= 1;
|
||||
*multi_byte_charset= 1;
|
||||
}
|
||||
if (use_strnxfrm((cs=sortorder->item->charset())))
|
||||
{
|
||||
sortorder->length= sortorder->length*cs->strxfrm_multiply;
|
||||
sortorder->need_strxnfrm= 1;
|
||||
*multi_byte_charset= 1;
|
||||
}
|
||||
break;
|
||||
case INT_RESULT:
|
||||
|
|
|
@ -1024,7 +1024,7 @@ longlong Item_func_char_length::val_int()
|
|||
return 0; /* purecov: inspected */
|
||||
}
|
||||
null_value=0;
|
||||
return (longlong) (!args[0]->binary()) ? res->numchars() : res->length();
|
||||
return (longlong) res->numchars();
|
||||
}
|
||||
|
||||
longlong Item_func_coercibility::val_int()
|
||||
|
@ -1156,7 +1156,7 @@ longlong Item_func_ord::val_int()
|
|||
null_value=0;
|
||||
if (!res->length()) return 0;
|
||||
#ifdef USE_MB
|
||||
if (use_mb(res->charset()) && !args[0]->binary())
|
||||
if (use_mb(res->charset()))
|
||||
{
|
||||
register const char *str=res->ptr();
|
||||
register uint32 n=0, l=my_ismbchar(res->charset(),str,str+res->length());
|
||||
|
|
|
@ -650,7 +650,7 @@ String *Item_func_reverse::val_str(String *str)
|
|||
ptr = (char *) res->ptr();
|
||||
end=ptr+res->length();
|
||||
#ifdef USE_MB
|
||||
if (use_mb(res->charset()) && !binary())
|
||||
if (use_mb(res->charset()))
|
||||
{
|
||||
String tmpstr;
|
||||
tmpstr.copy(*res);
|
||||
|
@ -1015,7 +1015,7 @@ String *Item_func_substr_index::val_str(String *str)
|
|||
return &empty_string; // Wrong parameters
|
||||
|
||||
#ifdef USE_MB
|
||||
if (use_mb(res->charset()) && !binary())
|
||||
if (use_mb(res->charset()))
|
||||
{
|
||||
const char *ptr=res->ptr();
|
||||
const char *strend = ptr+res->length();
|
||||
|
@ -1169,7 +1169,7 @@ String *Item_func_rtrim::val_str(String *str)
|
|||
{
|
||||
char chr=(*remove_str)[0];
|
||||
#ifdef USE_MB
|
||||
if (use_mb(res->charset()) && !binary())
|
||||
if (use_mb(res->charset()))
|
||||
{
|
||||
while (ptr < end)
|
||||
{
|
||||
|
@ -1186,7 +1186,7 @@ String *Item_func_rtrim::val_str(String *str)
|
|||
{
|
||||
const char *r_ptr=remove_str->ptr();
|
||||
#ifdef USE_MB
|
||||
if (use_mb(res->charset()) && !binary())
|
||||
if (use_mb(res->charset()))
|
||||
{
|
||||
loop:
|
||||
while (ptr + remove_length < end)
|
||||
|
@ -1237,7 +1237,7 @@ String *Item_func_trim::val_str(String *str)
|
|||
while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
|
||||
ptr+=remove_length;
|
||||
#ifdef USE_MB
|
||||
if (use_mb(res->charset()) && !binary())
|
||||
if (use_mb(res->charset()))
|
||||
{
|
||||
char *p=ptr;
|
||||
register uint32 l;
|
||||
|
|
|
@ -88,7 +88,14 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
if (have_to_be_excluded)
|
||||
engine->exclude();
|
||||
substitution= 0;
|
||||
return (*ref)->fix_fields(thd, tables, ref);
|
||||
int ret= (*ref)->fix_fields(thd, tables, ref);
|
||||
// We can't substitute aggregate functions (like (SELECT (max(i)))
|
||||
if ((*ref)->with_sum_func)
|
||||
{
|
||||
my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0));
|
||||
return 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char const *save_where= thd->where;
|
||||
|
|
|
@ -67,7 +67,7 @@ int find_ref_key(TABLE *table,Field *field, uint *key_length)
|
|||
|
||||
|
||||
/* Copy a key from record to some buffer */
|
||||
/* if length == 0 then copy hole key */
|
||||
/* if length == 0 then copy whole key */
|
||||
|
||||
void key_copy(byte *key,TABLE *table,uint idx,uint key_length)
|
||||
{
|
||||
|
|
|
@ -64,6 +64,7 @@ static SYMBOL symbols[] = {
|
|||
{ "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH),0,0},
|
||||
{ "AUTO_INCREMENT", SYM(AUTO_INC),0,0},
|
||||
{ "BACKUP", SYM(BACKUP_SYM),0,0},
|
||||
{ "BEFORE", SYM(BEFORE_SYM),0,0},
|
||||
{ "BEGIN", SYM(BEGIN_SYM),0,0},
|
||||
{ "BERKELEYDB", SYM(BERKELEY_DB_SYM),0,0},
|
||||
{ "BDB", SYM(BERKELEY_DB_SYM),0,0},
|
||||
|
|
97
sql/log.cc
97
sql/log.cc
|
@ -687,6 +687,19 @@ err:
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
Update log index_file
|
||||
*/
|
||||
|
||||
int MYSQL_LOG::update_log_index(LOG_INFO* log_info)
|
||||
{
|
||||
if (copy_up_file_and_fill(&index_file, log_info->index_file_start_offset))
|
||||
return LOG_INFO_IO;
|
||||
|
||||
// now update offsets in index file for running threads
|
||||
adjust_linfo_offsets(log_info->index_file_start_offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove all logs before the given log from disk and from the index file.
|
||||
|
@ -739,21 +752,76 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
|
|||
If we get killed -9 here, the sysadmin would have to edit
|
||||
the log index file after restart - otherwise, this should be safe
|
||||
*/
|
||||
|
||||
if (copy_up_file_and_fill(&index_file, log_info.index_file_start_offset))
|
||||
{
|
||||
error= LOG_INFO_IO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
// now update offsets in index file for running threads
|
||||
adjust_linfo_offsets(log_info.index_file_start_offset);
|
||||
error= update_log_index(&log_info);
|
||||
|
||||
err:
|
||||
pthread_mutex_unlock(&LOCK_index);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
Remove all logs before the given file date from disk and from the
|
||||
index file.
|
||||
|
||||
SYNOPSIS
|
||||
purge_logs_before_date()
|
||||
thd Thread pointer
|
||||
before_date Delete all log files before given date.
|
||||
|
||||
NOTES
|
||||
If any of the logs before the deleted one is in use,
|
||||
only purge logs up to this one.
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated
|
||||
*/
|
||||
|
||||
int MYSQL_LOG::purge_logs_before_date(THD* thd, time_t purge_time)
|
||||
{
|
||||
int error;
|
||||
LOG_INFO log_info;
|
||||
MY_STAT stat_area;
|
||||
|
||||
DBUG_ENTER("purge_logs_before_date");
|
||||
|
||||
if (no_rotate)
|
||||
DBUG_RETURN(LOG_INFO_PURGE_NO_ROTATE);
|
||||
|
||||
pthread_mutex_lock(&LOCK_index);
|
||||
|
||||
/*
|
||||
Delete until we find curren file
|
||||
or a file that is used or a file
|
||||
that is older than purge_time.
|
||||
*/
|
||||
if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
|
||||
goto err;
|
||||
|
||||
while (strcmp(log_file_name, log_info.log_file_name) &&
|
||||
!log_in_use(log_info.log_file_name))
|
||||
{
|
||||
/* It's not fatal even if we can't delete a log file */
|
||||
if (!my_stat(log_info.log_file_name, &stat_area, MYF(0)) ||
|
||||
stat_area.st_mtime >= purge_time)
|
||||
break;
|
||||
my_delete(log_info.log_file_name, MYF(0));
|
||||
if (find_next_log(&log_info, 0))
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
If we get killed -9 here, the sysadmin would have to edit
|
||||
the log index file after restart - otherwise, this should be safe
|
||||
*/
|
||||
error= update_log_index(&log_info);
|
||||
|
||||
err:
|
||||
pthread_mutex_unlock(&LOCK_index);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
|
||||
|
@ -1043,6 +1111,7 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
|
|||
bool MYSQL_LOG::write(Log_event* event_info)
|
||||
{
|
||||
bool error=0;
|
||||
bool should_rotate = 0;
|
||||
DBUG_ENTER("MYSQL_LOG::write(event)");
|
||||
|
||||
if (!inited) // Can't use mutex if not init
|
||||
|
@ -1055,7 +1124,6 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
|||
/* In most cases this is only called if 'is_open()' is true */
|
||||
if (is_open())
|
||||
{
|
||||
bool should_rotate = 0;
|
||||
THD *thd=event_info->thd;
|
||||
const char *local_db = event_info->get_db();
|
||||
#ifdef USING_TRANSACTIONS
|
||||
|
@ -1192,6 +1260,15 @@ err:
|
|||
}
|
||||
|
||||
pthread_mutex_unlock(&LOCK_log);
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (should_rotate && expire_logs_days)
|
||||
{
|
||||
long purge_time= time(0) - expire_logs_days*24*60*60;
|
||||
if (purge_time >= 0)
|
||||
error= purge_logs_before_date(current_thd, purge_time);
|
||||
}
|
||||
|
||||
#endif
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
|
|
@ -713,6 +713,7 @@ extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
|
|||
extern ulong max_binlog_size, rpl_recovery_rank, thread_cache_size;
|
||||
extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log;
|
||||
extern ulong specialflag, current_pid;
|
||||
extern ulong expire_logs_days;
|
||||
|
||||
extern uint test_flags,select_errors,ha_open_options;
|
||||
extern uint protocol_version,dropping_tables;
|
||||
|
|
|
@ -413,6 +413,7 @@ ulong max_connections,max_insert_delayed_threads,max_used_connections,
|
|||
max_connect_errors, max_user_connections = 0;
|
||||
ulong thread_id=1L,current_pid;
|
||||
ulong slow_launch_threads = 0;
|
||||
ulong expire_logs_days = 0;
|
||||
|
||||
char mysql_real_data_home[FN_REFLEN],
|
||||
language[LIBLEN],reg_ext[FN_EXTLEN],
|
||||
|
@ -2175,6 +2176,14 @@ static int init_server_components()
|
|||
open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
|
||||
opt_binlog_index_name,LOG_BIN);
|
||||
using_update_log=1;
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (expire_logs_days)
|
||||
{
|
||||
long purge_time= time(0) - expire_logs_days*24*60*60;
|
||||
if (purge_time >= 0)
|
||||
mysql_bin_log.purge_logs_before_date(current_thd, purge_time);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (opt_error_log)
|
||||
|
@ -3469,6 +3478,7 @@ enum options
|
|||
OPT_ENABLE_SHARED_MEMORY,
|
||||
OPT_SHARED_MEMORY_BASE_NAME,
|
||||
OPT_OLD_PASSWORDS,
|
||||
OPT_EXPIRE_LOGS_DAYS,
|
||||
OPT_DEFAULT_WEEK_FORMAT
|
||||
};
|
||||
|
||||
|
@ -4286,6 +4296,11 @@ struct my_option my_long_options[] =
|
|||
(gptr*) &global_system_variables.net_wait_timeout,
|
||||
(gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
|
||||
REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
|
||||
{"expire_logs_days", OPT_EXPIRE_LOGS_DAYS,
|
||||
"Logs will be rotated after expire-log-days days. ",
|
||||
(gptr*) &expire_logs_days,
|
||||
(gptr*) &expire_logs_days, 0, GET_ULONG,
|
||||
REQUIRED_ARG, 0, 0, 99, 0, 1, 0},
|
||||
{ "default-week-format", OPT_DEFAULT_WEEK_FORMAT,
|
||||
"The default week format used by WEEK() functions.",
|
||||
(gptr*) &global_system_variables.default_week_format,
|
||||
|
@ -4336,6 +4351,7 @@ struct show_var_st status_vars[]= {
|
|||
{"Com_lock_tables", (char*) (com_stat+(uint) SQLCOM_LOCK_TABLES),SHOW_LONG},
|
||||
{"Com_optimize", (char*) (com_stat+(uint) SQLCOM_OPTIMIZE),SHOW_LONG},
|
||||
{"Com_purge", (char*) (com_stat+(uint) SQLCOM_PURGE),SHOW_LONG},
|
||||
{"Com_purge_before_date", (char*) (com_stat+(uint) SQLCOM_PURGE_BEFORE),SHOW_LONG},
|
||||
{"Com_rename_table", (char*) (com_stat+(uint) SQLCOM_RENAME_TABLE),SHOW_LONG},
|
||||
{"Com_repair", (char*) (com_stat+(uint) SQLCOM_REPAIR),SHOW_LONG},
|
||||
{"Com_replace", (char*) (com_stat+(uint) SQLCOM_REPLACE),SHOW_LONG},
|
||||
|
|
|
@ -719,7 +719,8 @@ bool Protocol_simple::store(const char *from, uint length)
|
|||
bool Protocol_simple::store_tiny(longlong from)
|
||||
{
|
||||
#ifndef DEBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 || field_types[field_pos++] == MYSQL_TYPE_TINY);
|
||||
DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[20];
|
||||
return net_store_data((char*) buff,
|
||||
|
@ -731,7 +732,8 @@ bool Protocol_simple::store_short(longlong from)
|
|||
{
|
||||
#ifndef DEBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos++] == MYSQL_TYPE_SHORT);
|
||||
field_types[field_pos] == MYSQL_TYPE_SHORT);
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[20];
|
||||
return net_store_data((char*) buff,
|
||||
|
@ -742,7 +744,10 @@ bool Protocol_simple::store_short(longlong from)
|
|||
bool Protocol_simple::store_long(longlong from)
|
||||
{
|
||||
#ifndef DEBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 || field_types[field_pos++] == MYSQL_TYPE_LONG);
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_INT24 ||
|
||||
field_types[field_pos] == MYSQL_TYPE_LONG);
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[20];
|
||||
return net_store_data((char*) buff,
|
||||
|
@ -754,7 +759,8 @@ bool Protocol_simple::store_longlong(longlong from, bool unsigned_flag)
|
|||
{
|
||||
#ifndef DEBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos++] == MYSQL_TYPE_LONGLONG);
|
||||
field_types[field_pos] == MYSQL_TYPE_LONGLONG);
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[22];
|
||||
return net_store_data((char*) buff,
|
||||
|
@ -768,7 +774,8 @@ bool Protocol_simple::store(float from, uint32 decimals, String *buffer)
|
|||
{
|
||||
#ifndef DEBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos++] == MYSQL_TYPE_FLOAT);
|
||||
field_types[field_pos] == MYSQL_TYPE_FLOAT);
|
||||
field_pos++;
|
||||
#endif
|
||||
buffer->set((double) from, decimals, thd->variables.thd_charset);
|
||||
return net_store_data((char*) buffer->ptr(), buffer->length());
|
||||
|
@ -779,7 +786,8 @@ bool Protocol_simple::store(double from, uint32 decimals, String *buffer)
|
|||
{
|
||||
#ifndef DEBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos++] == MYSQL_TYPE_DOUBLE);
|
||||
field_types[field_pos] == MYSQL_TYPE_DOUBLE);
|
||||
field_pos++;
|
||||
#endif
|
||||
buffer->set(from, decimals, thd->variables.thd_charset);
|
||||
return net_store_data((char*) buffer->ptr(), buffer->length());
|
||||
|
@ -827,7 +835,8 @@ bool Protocol_simple::store_date(TIME *tm)
|
|||
{
|
||||
#ifndef DEBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos++] == MYSQL_TYPE_DATE);
|
||||
field_types[field_pos] == MYSQL_TYPE_DATE);
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[40];
|
||||
uint length;
|
||||
|
@ -843,7 +852,8 @@ bool Protocol_simple::store_time(TIME *tm)
|
|||
{
|
||||
#ifndef DEBUG_OFF
|
||||
DBUG_ASSERT(field_types == 0 ||
|
||||
field_types[field_pos++] == MYSQL_TYPE_TIME);
|
||||
field_types[field_pos] == MYSQL_TYPE_TIME);
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[40];
|
||||
uint length;
|
||||
|
@ -1033,7 +1043,7 @@ bool Protocol_prep::store(TIME *tm)
|
|||
uint length;
|
||||
field_pos++;
|
||||
pos= buff+1;
|
||||
|
||||
|
||||
int2store(pos, tm->year);
|
||||
pos[2]= (uchar) tm->month;
|
||||
pos[3]= (uchar) tm->day;
|
||||
|
@ -1072,7 +1082,7 @@ bool Protocol_prep::store_time(TIME *tm)
|
|||
field_pos++;
|
||||
pos= buff+1;
|
||||
pos[0]= tm->neg ? 1 : 0;
|
||||
int4store(pos+1, tm->day);
|
||||
int4store(pos+1, tm->day);
|
||||
pos[5]= (uchar) tm->hour;
|
||||
pos[6]= (uchar) tm->minute;
|
||||
pos[7]= (uchar) tm->second;
|
||||
|
|
|
@ -120,6 +120,8 @@ sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout",
|
|||
&delayed_insert_timeout);
|
||||
sys_var_long_ptr sys_delayed_queue_size("delayed_queue_size",
|
||||
&delayed_queue_size);
|
||||
sys_var_long_ptr sys_expire_logs_days("expire_logs_days",
|
||||
&expire_logs_days);
|
||||
sys_var_bool_ptr sys_flush("flush", &myisam_flush);
|
||||
sys_var_long_ptr sys_flush_time("flush_time", &flush_time);
|
||||
sys_var_thd_ulong sys_interactive_timeout("interactive_timeout",
|
||||
|
@ -342,6 +344,7 @@ sys_var *sys_variables[]=
|
|||
&sys_delayed_insert_timeout,
|
||||
&sys_delayed_queue_size,
|
||||
&sys_error_count,
|
||||
&sys_expire_logs_days,
|
||||
&sys_flush,
|
||||
&sys_flush_time,
|
||||
&sys_foreign_key_checks,
|
||||
|
@ -449,6 +452,7 @@ struct show_var_st init_vars[]= {
|
|||
{sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS},
|
||||
{sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS},
|
||||
{sys_delayed_queue_size.name,(char*) &sys_delayed_queue_size, SHOW_SYS},
|
||||
{sys_expire_logs_days.name, (char*) &sys_expire_logs_days, SHOW_SYS},
|
||||
{sys_flush.name, (char*) &sys_flush, SHOW_SYS},
|
||||
{sys_flush_time.name, (char*) &sys_flush_time, SHOW_SYS},
|
||||
{"ft_boolean_syntax", (char*) ft_boolean_syntax, SHOW_CHAR},
|
||||
|
|
|
@ -732,7 +732,7 @@ void field_str::get_opt_type(String *answer, ha_rows total_rows)
|
|||
{
|
||||
if (must_be_blob)
|
||||
{
|
||||
if (item->binary())
|
||||
if (item->charset() == &my_charset_bin)
|
||||
answer->append("TINYBLOB", 8);
|
||||
else
|
||||
answer->append("TINYTEXT", 8);
|
||||
|
@ -750,21 +750,21 @@ void field_str::get_opt_type(String *answer, ha_rows total_rows)
|
|||
}
|
||||
else if (max_length < (1L << 16))
|
||||
{
|
||||
if (item->binary())
|
||||
if (item->charset() == &my_charset_bin)
|
||||
answer->append("BLOB", 4);
|
||||
else
|
||||
answer->append("TEXT", 4);
|
||||
}
|
||||
else if (max_length < (1L << 24))
|
||||
{
|
||||
if (item->binary())
|
||||
if (item->charset() == &my_charset_bin)
|
||||
answer->append("MEDIUMBLOB", 10);
|
||||
else
|
||||
answer->append("MEDIUMTEXT", 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item->binary())
|
||||
if (item->charset() == &my_charset_bin)
|
||||
answer->append("LONGBLOB", 8);
|
||||
else
|
||||
answer->append("LONGTEXT", 8);
|
||||
|
|
|
@ -143,7 +143,9 @@ public:
|
|||
int generate_new_name(char *new_name,const char *old_name);
|
||||
void make_log_name(char* buf, const char* log_ident);
|
||||
bool is_active(const char* log_file_name);
|
||||
int update_log_index(LOG_INFO* linfo);
|
||||
int purge_logs(THD* thd, const char* to_log);
|
||||
int purge_logs_before_date(THD* thd, time_t purge_time);
|
||||
int purge_first_log(struct st_relay_log_info* rli);
|
||||
bool reset_logs(THD* thd);
|
||||
// if we are exiting, we also want to close the index file
|
||||
|
|
314
sql/sql_lex.cc
314
sql/sql_lex.cc
|
@ -75,8 +75,6 @@ inline int lex_casecmp(const char *s, const char *t, uint len)
|
|||
|
||||
#include "lex_hash.h"
|
||||
|
||||
static uchar state_map[256], ident_map[256];
|
||||
|
||||
|
||||
void lex_init(void)
|
||||
{
|
||||
|
@ -89,53 +87,6 @@ void lex_init(void)
|
|||
|
||||
VOID(pthread_key_create(&THR_LEX,NULL));
|
||||
|
||||
/* Fill state_map with states to get a faster parser */
|
||||
for (i=0; i < sizeof(state_map) ; i++)
|
||||
{
|
||||
if (my_isalpha(system_charset_info,i))
|
||||
state_map[i]=(uchar) STATE_IDENT;
|
||||
else if (my_isdigit(system_charset_info,i))
|
||||
state_map[i]=(uchar) STATE_NUMBER_IDENT;
|
||||
#if defined(USE_MB) && defined(USE_MB_IDENT)
|
||||
else if (use_mb(system_charset_info) && my_ismbhead(system_charset_info, i))
|
||||
state_map[i]=(uchar) STATE_IDENT;
|
||||
#endif
|
||||
else if (!my_isgraph(system_charset_info,i))
|
||||
state_map[i]=(uchar) STATE_SKIP;
|
||||
else
|
||||
state_map[i]=(uchar) STATE_CHAR;
|
||||
}
|
||||
state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) STATE_IDENT;
|
||||
state_map[(uchar)'\'']=(uchar) STATE_STRING;
|
||||
state_map[(uchar)'-']=state_map[(uchar)'+']=(uchar) STATE_SIGNED_NUMBER;
|
||||
state_map[(uchar)'.']=(uchar) STATE_REAL_OR_POINT;
|
||||
state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) STATE_CMP_OP;
|
||||
state_map[(uchar)'<']= (uchar) STATE_LONG_CMP_OP;
|
||||
state_map[(uchar)'&']=state_map[(uchar)'|']=(uchar) STATE_BOOL;
|
||||
state_map[(uchar)'#']=(uchar) STATE_COMMENT;
|
||||
state_map[(uchar)';']=(uchar) STATE_COLON;
|
||||
state_map[(uchar)':']=(uchar) STATE_SET_VAR;
|
||||
state_map[0]=(uchar) STATE_EOL;
|
||||
state_map[(uchar)'\\']= (uchar) STATE_ESCAPE;
|
||||
state_map[(uchar)'/']= (uchar) STATE_LONG_COMMENT;
|
||||
state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT;
|
||||
state_map[(uchar)'@']= (uchar) STATE_USER_END;
|
||||
state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER;
|
||||
state_map[(uchar)'"']= (uchar) STAT_STRING_OR_DELIMITER;
|
||||
|
||||
/*
|
||||
Create a second map to make it faster to find identifiers
|
||||
*/
|
||||
for (i=0; i < sizeof(ident_map) ; i++)
|
||||
{
|
||||
ident_map[i]= (uchar) (state_map[i] == STATE_IDENT ||
|
||||
state_map[i] == STATE_NUMBER_IDENT);
|
||||
}
|
||||
|
||||
/* Special handling of hex and binary strings */
|
||||
state_map[(uchar)'x']= state_map[(uchar)'X']= (uchar) STATE_IDENT_OR_HEX;
|
||||
state_map[(uchar)'b']= state_map[(uchar)'b']= (uchar) STATE_IDENT_OR_BIN;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -156,7 +107,7 @@ void lex_free(void)
|
|||
LEX *lex_start(THD *thd, uchar *buf,uint length)
|
||||
{
|
||||
LEX *lex= &thd->lex;
|
||||
lex->next_state=STATE_START;
|
||||
lex->next_state=MY_LEX_START;
|
||||
lex->end_of_query=(lex->ptr=buf)+length;
|
||||
lex->yylineno = 1;
|
||||
lex->select_lex.create_refs=lex->in_comment=0;
|
||||
|
@ -258,6 +209,7 @@ static char *get_text(LEX *lex)
|
|||
{
|
||||
reg1 uchar c,sep;
|
||||
uint found_escape=0;
|
||||
CHARSET_INFO *cs= lex->thd->variables.thd_charset;
|
||||
|
||||
sep= yyGetLast(); // String should end with this
|
||||
//lex->tok_start=lex->ptr-1; // Remember '
|
||||
|
@ -266,8 +218,8 @@ static char *get_text(LEX *lex)
|
|||
c = yyGet();
|
||||
#ifdef USE_MB
|
||||
int l;
|
||||
if (use_mb(system_charset_info) &&
|
||||
(l = my_ismbchar(system_charset_info,
|
||||
if (use_mb(cs) &&
|
||||
(l = my_ismbchar(cs,
|
||||
(const char *)lex->ptr-1,
|
||||
(const char *)lex->end_of_query))) {
|
||||
lex->ptr += l-1;
|
||||
|
@ -311,8 +263,8 @@ static char *get_text(LEX *lex)
|
|||
{
|
||||
#ifdef USE_MB
|
||||
int l;
|
||||
if (use_mb(system_charset_info) &&
|
||||
(l = my_ismbchar(system_charset_info,
|
||||
if (use_mb(cs) &&
|
||||
(l = my_ismbchar(cs,
|
||||
(const char *)str, (const char *)end))) {
|
||||
while (l--)
|
||||
*to++ = *str++;
|
||||
|
@ -359,8 +311,6 @@ static char *get_text(LEX *lex)
|
|||
*to=0;
|
||||
lex->yytoklen=(uint) (to-start);
|
||||
}
|
||||
if (lex->convert_set)
|
||||
lex->convert_set->convert((char*) start,lex->yytoklen);
|
||||
return (char*) start;
|
||||
}
|
||||
}
|
||||
|
@ -460,8 +410,8 @@ inline static uint int_token(const char *str,uint length)
|
|||
|
||||
|
||||
// yylex remember the following states from the following yylex()
|
||||
// STATE_EOQ ; found end of query
|
||||
// STATE_OPERATOR_OR_IDENT ; last state was an ident, text or number
|
||||
// MY_LEX_EOQ ; found end of query
|
||||
// MY_LEX_OPERATOR_OR_IDENT ; last state was an ident, text or number
|
||||
// (which can't be followed by a signed number)
|
||||
|
||||
int yylex(void *arg, void *yythd)
|
||||
|
@ -469,76 +419,79 @@ int yylex(void *arg, void *yythd)
|
|||
reg1 uchar c;
|
||||
int tokval;
|
||||
uint length;
|
||||
enum lex_states state,prev_state;
|
||||
enum my_lex_states state,prev_state;
|
||||
LEX *lex= &(((THD *)yythd)->lex);
|
||||
YYSTYPE *yylval=(YYSTYPE*) arg;
|
||||
CHARSET_INFO *cs= ((THD *) yythd)->variables.thd_charset;
|
||||
uchar *state_map= cs->state_map;
|
||||
uchar *ident_map= cs->ident_map;
|
||||
|
||||
lex->yylval=yylval; // The global state
|
||||
lex->tok_start=lex->tok_end=lex->ptr;
|
||||
prev_state=state=lex->next_state;
|
||||
lex->next_state=STATE_OPERATOR_OR_IDENT;
|
||||
lex->next_state=MY_LEX_OPERATOR_OR_IDENT;
|
||||
LINT_INIT(c);
|
||||
for (;;)
|
||||
{
|
||||
switch (state) {
|
||||
case STATE_OPERATOR_OR_IDENT: // Next is operator or keyword
|
||||
case STATE_START: // Start of token
|
||||
case MY_LEX_OPERATOR_OR_IDENT: // Next is operator or keyword
|
||||
case MY_LEX_START: // Start of token
|
||||
// Skip startspace
|
||||
for (c=yyGet() ; (state_map[c] == STATE_SKIP) ; c= yyGet())
|
||||
for (c=yyGet() ; (state_map[c] == MY_LEX_SKIP) ; c= yyGet())
|
||||
{
|
||||
if (c == '\n')
|
||||
lex->yylineno++;
|
||||
}
|
||||
lex->tok_start=lex->ptr-1; // Start of real token
|
||||
state= (enum lex_states) state_map[c];
|
||||
state= (enum my_lex_states) state_map[c];
|
||||
break;
|
||||
case STATE_ESCAPE:
|
||||
case MY_LEX_ESCAPE:
|
||||
if (yyGet() == 'N')
|
||||
{ // Allow \N as shortcut for NULL
|
||||
yylval->lex_str.str=(char*) "\\N";
|
||||
yylval->lex_str.length=2;
|
||||
return NULL_SYM;
|
||||
}
|
||||
case STATE_CHAR: // Unknown or single char token
|
||||
case STATE_SKIP: // This should not happen
|
||||
case MY_LEX_CHAR: // Unknown or single char token
|
||||
case MY_LEX_SKIP: // This should not happen
|
||||
yylval->lex_str.str=(char*) (lex->ptr=lex->tok_start);// Set to first chr
|
||||
yylval->lex_str.length=1;
|
||||
c=yyGet();
|
||||
if (c != ')')
|
||||
lex->next_state= STATE_START; // Allow signed numbers
|
||||
lex->next_state= MY_LEX_START; // Allow signed numbers
|
||||
if (c == ',')
|
||||
lex->tok_start=lex->ptr; // Let tok_start point at next item
|
||||
return((int) c);
|
||||
|
||||
case STATE_IDENT_OR_HEX:
|
||||
case MY_LEX_IDENT_OR_HEX:
|
||||
if (yyPeek() == '\'')
|
||||
{ // Found x'hex-number'
|
||||
state= STATE_HEX_NUMBER;
|
||||
state= MY_LEX_HEX_NUMBER;
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
case STATE_IDENT_OR_BIN: // TODO: Add binary string handling
|
||||
case STATE_IDENT:
|
||||
case MY_LEX_IDENT_OR_BIN: // TODO: Add binary string handling
|
||||
case MY_LEX_IDENT:
|
||||
#if defined(USE_MB) && defined(USE_MB_IDENT)
|
||||
if (use_mb(system_charset_info))
|
||||
if (use_mb(cs))
|
||||
{
|
||||
if (my_ismbhead(system_charset_info, yyGetLast()))
|
||||
if (my_ismbhead(cs, yyGetLast()))
|
||||
{
|
||||
int l = my_ismbchar(system_charset_info,
|
||||
int l = my_ismbchar(cs,
|
||||
(const char *)lex->ptr-1,
|
||||
(const char *)lex->end_of_query);
|
||||
if (l == 0) {
|
||||
state = STATE_CHAR;
|
||||
state = MY_LEX_CHAR;
|
||||
continue;
|
||||
}
|
||||
lex->ptr += l - 1;
|
||||
}
|
||||
while (ident_map[c=yyGet()])
|
||||
{
|
||||
if (my_ismbhead(system_charset_info, c))
|
||||
if (my_ismbhead(cs, c))
|
||||
{
|
||||
int l;
|
||||
if ((l = my_ismbchar(system_charset_info,
|
||||
if ((l = my_ismbchar(cs,
|
||||
(const char *)lex->ptr-1,
|
||||
(const char *)lex->end_of_query)) == 0)
|
||||
break;
|
||||
|
@ -552,16 +505,16 @@ int yylex(void *arg, void *yythd)
|
|||
length= (uint) (lex->ptr - lex->tok_start)-1;
|
||||
if (lex->ignore_space)
|
||||
{
|
||||
for (; state_map[c] == STATE_SKIP ; c= yyGet());
|
||||
for (; state_map[c] == MY_LEX_SKIP ; c= yyGet());
|
||||
}
|
||||
if (c == '.' && ident_map[yyPeek()])
|
||||
lex->next_state=STATE_IDENT_SEP;
|
||||
lex->next_state=MY_LEX_IDENT_SEP;
|
||||
else
|
||||
{ // '(' must follow directly if function
|
||||
yyUnget();
|
||||
if ((tokval = find_keyword(lex,length,c == '(')))
|
||||
{
|
||||
lex->next_state= STATE_START; // Allow signed numbers
|
||||
lex->next_state= MY_LEX_START; // Allow signed numbers
|
||||
return(tokval); // Was keyword
|
||||
}
|
||||
yySkip(); // next state does a unget
|
||||
|
@ -584,30 +537,30 @@ int yylex(void *arg, void *yythd)
|
|||
else
|
||||
return(IDENT);
|
||||
|
||||
case STATE_IDENT_SEP: // Found ident and now '.'
|
||||
lex->next_state=STATE_IDENT_START;// Next is an ident (not a keyword)
|
||||
case MY_LEX_IDENT_SEP: // Found ident and now '.'
|
||||
lex->next_state=MY_LEX_IDENT_START;// Next is an ident (not a keyword)
|
||||
yylval->lex_str.str=(char*) lex->ptr;
|
||||
yylval->lex_str.length=1;
|
||||
c=yyGet(); // should be '.'
|
||||
return((int) c);
|
||||
|
||||
case STATE_NUMBER_IDENT: // number or ident which num-start
|
||||
while (my_isdigit(system_charset_info,(c = yyGet()))) ;
|
||||
case MY_LEX_NUMBER_IDENT: // number or ident which num-start
|
||||
while (my_isdigit(cs,(c = yyGet()))) ;
|
||||
if (!ident_map[c])
|
||||
{ // Can't be identifier
|
||||
state=STATE_INT_OR_REAL;
|
||||
state=MY_LEX_INT_OR_REAL;
|
||||
break;
|
||||
}
|
||||
if (c == 'e' || c == 'E')
|
||||
{
|
||||
// The following test is written this way to allow numbers of type 1e1
|
||||
if (my_isdigit(system_charset_info,yyPeek()) ||
|
||||
if (my_isdigit(cs,yyPeek()) ||
|
||||
(c=(yyGet())) == '+' || c == '-')
|
||||
{ // Allow 1E+10
|
||||
if (my_isdigit(system_charset_info,yyPeek())) // Number must have digit after sign
|
||||
if (my_isdigit(cs,yyPeek())) // Number must have digit after sign
|
||||
{
|
||||
yySkip();
|
||||
while (my_isdigit(system_charset_info,yyGet())) ;
|
||||
while (my_isdigit(cs,yyGet())) ;
|
||||
yylval->lex_str=get_token(lex,yyLength());
|
||||
return(FLOAT_NUM);
|
||||
}
|
||||
|
@ -617,7 +570,7 @@ int yylex(void *arg, void *yythd)
|
|||
else if (c == 'x' && (lex->ptr - lex->tok_start) == 2 &&
|
||||
lex->tok_start[0] == '0' )
|
||||
{ // Varbinary
|
||||
while (my_isxdigit(system_charset_info,(c = yyGet()))) ;
|
||||
while (my_isxdigit(cs,(c = yyGet()))) ;
|
||||
if ((lex->ptr - lex->tok_start) >= 4 && !ident_map[c])
|
||||
{
|
||||
yylval->lex_str=get_token(lex,yyLength());
|
||||
|
@ -629,28 +582,28 @@ int yylex(void *arg, void *yythd)
|
|||
yyUnget();
|
||||
}
|
||||
// fall through
|
||||
case STATE_IDENT_START: // Incomplete ident
|
||||
case MY_LEX_IDENT_START: // Incomplete ident
|
||||
#if defined(USE_MB) && defined(USE_MB_IDENT)
|
||||
if (use_mb(system_charset_info))
|
||||
if (use_mb(cs))
|
||||
{
|
||||
if (my_ismbhead(system_charset_info, yyGetLast()))
|
||||
if (my_ismbhead(cs, yyGetLast()))
|
||||
{
|
||||
int l = my_ismbchar(system_charset_info,
|
||||
int l = my_ismbchar(cs,
|
||||
(const char *)lex->ptr-1,
|
||||
(const char *)lex->end_of_query);
|
||||
if (l == 0)
|
||||
{
|
||||
state = STATE_CHAR;
|
||||
state = MY_LEX_CHAR;
|
||||
continue;
|
||||
}
|
||||
lex->ptr += l - 1;
|
||||
}
|
||||
while (ident_map[c=yyGet()])
|
||||
{
|
||||
if (my_ismbhead(system_charset_info, c))
|
||||
if (my_ismbhead(cs, c))
|
||||
{
|
||||
int l;
|
||||
if ((l = my_ismbchar(system_charset_info,
|
||||
if ((l = my_ismbchar(cs,
|
||||
(const char *)lex->ptr-1,
|
||||
(const char *)lex->end_of_query)) == 0)
|
||||
break;
|
||||
|
@ -663,28 +616,28 @@ int yylex(void *arg, void *yythd)
|
|||
while (ident_map[c = yyGet()]) ;
|
||||
|
||||
if (c == '.' && ident_map[yyPeek()])
|
||||
lex->next_state=STATE_IDENT_SEP;// Next is '.'
|
||||
lex->next_state=MY_LEX_IDENT_SEP;// Next is '.'
|
||||
// fall through
|
||||
|
||||
case STATE_FOUND_IDENT: // Complete ident
|
||||
case MY_LEX_FOUND_IDENT: // Complete ident
|
||||
yylval->lex_str=get_token(lex,yyLength());
|
||||
if (lex->convert_set)
|
||||
lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
|
||||
return(IDENT);
|
||||
|
||||
case STATE_USER_VARIABLE_DELIMITER:
|
||||
case MY_LEX_USER_VARIABLE_DELIMITER:
|
||||
{
|
||||
char delim= c; // Used char
|
||||
lex->tok_start=lex->ptr; // Skip first `
|
||||
#ifdef USE_MB
|
||||
if (use_mb(system_charset_info))
|
||||
if (use_mb(cs))
|
||||
{
|
||||
while ((c=yyGet()) && c != delim && c != (uchar) NAMES_SEP_CHAR)
|
||||
{
|
||||
if (my_ismbhead(system_charset_info, c))
|
||||
if (my_ismbhead(cs, c))
|
||||
{
|
||||
int l;
|
||||
if ((l = my_ismbchar(system_charset_info,
|
||||
if ((l = my_ismbchar(cs,
|
||||
(const char *)lex->ptr-1,
|
||||
(const char *)lex->end_of_query)) == 0)
|
||||
break;
|
||||
|
@ -723,67 +676,67 @@ int yylex(void *arg, void *yythd)
|
|||
yySkip(); // Skip end `
|
||||
return(IDENT);
|
||||
}
|
||||
case STATE_SIGNED_NUMBER: // Incomplete signed number
|
||||
if (prev_state == STATE_OPERATOR_OR_IDENT)
|
||||
case MY_LEX_SIGNED_NUMBER: // Incomplete signed number
|
||||
if (prev_state == MY_LEX_OPERATOR_OR_IDENT)
|
||||
{
|
||||
if (c == '-' && yyPeek() == '-' &&
|
||||
(my_isspace(system_charset_info,yyPeek2()) ||
|
||||
my_iscntrl(system_charset_info,yyPeek2())))
|
||||
state=STATE_COMMENT;
|
||||
(my_isspace(cs,yyPeek2()) ||
|
||||
my_iscntrl(cs,yyPeek2())))
|
||||
state=MY_LEX_COMMENT;
|
||||
else
|
||||
state= STATE_CHAR; // Must be operator
|
||||
state= MY_LEX_CHAR; // Must be operator
|
||||
break;
|
||||
}
|
||||
if (!my_isdigit(system_charset_info,c=yyGet()) || yyPeek() == 'x')
|
||||
if (!my_isdigit(cs,c=yyGet()) || yyPeek() == 'x')
|
||||
{
|
||||
if (c != '.')
|
||||
{
|
||||
if (c == '-' && my_isspace(system_charset_info,yyPeek()))
|
||||
state=STATE_COMMENT;
|
||||
if (c == '-' && my_isspace(cs,yyPeek()))
|
||||
state=MY_LEX_COMMENT;
|
||||
else
|
||||
state = STATE_CHAR; // Return sign as single char
|
||||
state = MY_LEX_CHAR; // Return sign as single char
|
||||
break;
|
||||
}
|
||||
yyUnget(); // Fix for next loop
|
||||
}
|
||||
while (my_isdigit(system_charset_info,c=yyGet())) ; // Incomplete real or int number
|
||||
while (my_isdigit(cs,c=yyGet())) ; // Incomplete real or int number
|
||||
if ((c == 'e' || c == 'E') &&
|
||||
(yyPeek() == '+' || yyPeek() == '-' || my_isdigit(system_charset_info,yyPeek())))
|
||||
(yyPeek() == '+' || yyPeek() == '-' || my_isdigit(cs,yyPeek())))
|
||||
{ // Real number
|
||||
yyUnget();
|
||||
c= '.'; // Fool next test
|
||||
}
|
||||
// fall through
|
||||
case STATE_INT_OR_REAL: // Compleat int or incompleat real
|
||||
case MY_LEX_INT_OR_REAL: // Compleat int or incompleat real
|
||||
if (c != '.')
|
||||
{ // Found complete integer number.
|
||||
yylval->lex_str=get_token(lex,yyLength());
|
||||
return int_token(yylval->lex_str.str,yylval->lex_str.length);
|
||||
}
|
||||
// fall through
|
||||
case STATE_REAL: // Incomplete real number
|
||||
while (my_isdigit(system_charset_info,c = yyGet())) ;
|
||||
case MY_LEX_REAL: // Incomplete real number
|
||||
while (my_isdigit(cs,c = yyGet())) ;
|
||||
|
||||
if (c == 'e' || c == 'E')
|
||||
{
|
||||
c = yyGet();
|
||||
if (c == '-' || c == '+')
|
||||
c = yyGet(); // Skip sign
|
||||
if (!my_isdigit(system_charset_info,c))
|
||||
if (!my_isdigit(cs,c))
|
||||
{ // No digit after sign
|
||||
state= STATE_CHAR;
|
||||
state= MY_LEX_CHAR;
|
||||
break;
|
||||
}
|
||||
while (my_isdigit(system_charset_info,yyGet())) ;
|
||||
while (my_isdigit(cs,yyGet())) ;
|
||||
yylval->lex_str=get_token(lex,yyLength());
|
||||
return(FLOAT_NUM);
|
||||
}
|
||||
yylval->lex_str=get_token(lex,yyLength());
|
||||
return(REAL_NUM);
|
||||
|
||||
case STATE_HEX_NUMBER: // Found x'hexstring'
|
||||
case MY_LEX_HEX_NUMBER: // Found x'hexstring'
|
||||
yyGet(); // Skip '
|
||||
while (my_isxdigit(system_charset_info,(c = yyGet()))) ;
|
||||
while (my_isxdigit(cs,(c = yyGet()))) ;
|
||||
length=(lex->ptr - lex->tok_start); // Length of hexnum+3
|
||||
if (!(length & 1) || c != '\'')
|
||||
{
|
||||
|
@ -796,71 +749,73 @@ int yylex(void *arg, void *yythd)
|
|||
lex->yytoklen-=3;
|
||||
return (HEX_NUM);
|
||||
|
||||
case STATE_CMP_OP: // Incomplete comparison operator
|
||||
if (state_map[yyPeek()] == STATE_CMP_OP ||
|
||||
state_map[yyPeek()] == STATE_LONG_CMP_OP)
|
||||
case MY_LEX_CMP_OP: // Incomplete comparison operator
|
||||
if (state_map[yyPeek()] == MY_LEX_CMP_OP ||
|
||||
state_map[yyPeek()] == MY_LEX_LONG_CMP_OP)
|
||||
yySkip();
|
||||
if ((tokval = find_keyword(lex,(uint) (lex->ptr - lex->tok_start),0)))
|
||||
{
|
||||
lex->next_state= STATE_START; // Allow signed numbers
|
||||
lex->next_state= MY_LEX_START; // Allow signed numbers
|
||||
return(tokval);
|
||||
}
|
||||
state = STATE_CHAR; // Something fishy found
|
||||
state = MY_LEX_CHAR; // Something fishy found
|
||||
break;
|
||||
|
||||
case STATE_LONG_CMP_OP: // Incomplete comparison operator
|
||||
if (state_map[yyPeek()] == STATE_CMP_OP ||
|
||||
state_map[yyPeek()] == STATE_LONG_CMP_OP)
|
||||
case MY_LEX_LONG_CMP_OP: // Incomplete comparison operator
|
||||
if (state_map[yyPeek()] == MY_LEX_CMP_OP ||
|
||||
state_map[yyPeek()] == MY_LEX_LONG_CMP_OP)
|
||||
{
|
||||
yySkip();
|
||||
if (state_map[yyPeek()] == STATE_CMP_OP)
|
||||
if (state_map[yyPeek()] == MY_LEX_CMP_OP)
|
||||
yySkip();
|
||||
}
|
||||
if ((tokval = find_keyword(lex,(uint) (lex->ptr - lex->tok_start),0)))
|
||||
{
|
||||
lex->next_state= STATE_START; // Found long op
|
||||
lex->next_state= MY_LEX_START; // Found long op
|
||||
return(tokval);
|
||||
}
|
||||
state = STATE_CHAR; // Something fishy found
|
||||
state = MY_LEX_CHAR; // Something fishy found
|
||||
break;
|
||||
|
||||
case STATE_BOOL:
|
||||
case MY_LEX_BOOL:
|
||||
if (c != yyPeek())
|
||||
{
|
||||
state=STATE_CHAR;
|
||||
state=MY_LEX_CHAR;
|
||||
break;
|
||||
}
|
||||
yySkip();
|
||||
tokval = find_keyword(lex,2,0); // Is a bool operator
|
||||
lex->next_state= STATE_START; // Allow signed numbers
|
||||
lex->next_state= MY_LEX_START; // Allow signed numbers
|
||||
return(tokval);
|
||||
|
||||
case STAT_STRING_OR_DELIMITER:
|
||||
case MY_LEX_STRING_OR_DELIMITER:
|
||||
if (((THD *) yythd)->variables.sql_mode & MODE_ANSI_QUOTES)
|
||||
{
|
||||
state= STATE_USER_VARIABLE_DELIMITER;
|
||||
state= MY_LEX_USER_VARIABLE_DELIMITER;
|
||||
break;
|
||||
}
|
||||
/* " used for strings */
|
||||
case STATE_STRING: // Incomplete text string
|
||||
case MY_LEX_STRING: // Incomplete text string
|
||||
if (!(yylval->lex_str.str = get_text(lex)))
|
||||
{
|
||||
state= STATE_CHAR; // Read char by char
|
||||
state= MY_LEX_CHAR; // Read char by char
|
||||
break;
|
||||
}
|
||||
yylval->lex_str.length=lex->yytoklen;
|
||||
if (lex->convert_set)
|
||||
lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
|
||||
return(TEXT_STRING);
|
||||
|
||||
case STATE_COMMENT: // Comment
|
||||
case MY_LEX_COMMENT: // Comment
|
||||
lex->select_lex.options|= OPTION_FOUND_COMMENT;
|
||||
while ((c = yyGet()) != '\n' && c) ;
|
||||
yyUnget(); // Safety against eof
|
||||
state = STATE_START; // Try again
|
||||
state = MY_LEX_START; // Try again
|
||||
break;
|
||||
case STATE_LONG_COMMENT: /* Long C comment? */
|
||||
case MY_LEX_LONG_COMMENT: /* Long C comment? */
|
||||
if (yyPeek() != '*')
|
||||
{
|
||||
state=STATE_CHAR; // Probable division
|
||||
state=MY_LEX_CHAR; // Probable division
|
||||
break;
|
||||
}
|
||||
yySkip(); // Skip '*'
|
||||
|
@ -869,8 +824,8 @@ int yylex(void *arg, void *yythd)
|
|||
{
|
||||
ulong version=MYSQL_VERSION_ID;
|
||||
yySkip();
|
||||
state=STATE_START;
|
||||
if (my_isdigit(system_charset_info,yyPeek()))
|
||||
state=MY_LEX_START;
|
||||
if (my_isdigit(cs,yyPeek()))
|
||||
{ // Version number
|
||||
version=strtol((char*) lex->ptr,(char**) &lex->ptr,10);
|
||||
}
|
||||
|
@ -888,88 +843,87 @@ int yylex(void *arg, void *yythd)
|
|||
}
|
||||
if (lex->ptr != lex->end_of_query)
|
||||
yySkip(); // remove last '/'
|
||||
state = STATE_START; // Try again
|
||||
state = MY_LEX_START; // Try again
|
||||
break;
|
||||
case STATE_END_LONG_COMMENT:
|
||||
case MY_LEX_END_LONG_COMMENT:
|
||||
if (lex->in_comment && yyPeek() == '/')
|
||||
{
|
||||
yySkip();
|
||||
lex->in_comment=0;
|
||||
state=STATE_START;
|
||||
state=MY_LEX_START;
|
||||
}
|
||||
else
|
||||
state=STATE_CHAR; // Return '*'
|
||||
state=MY_LEX_CHAR; // Return '*'
|
||||
break;
|
||||
case STATE_SET_VAR: // Check if ':='
|
||||
case MY_LEX_SET_VAR: // Check if ':='
|
||||
if (yyPeek() != '=')
|
||||
{
|
||||
state=STATE_CHAR; // Return ':'
|
||||
state=MY_LEX_CHAR; // Return ':'
|
||||
break;
|
||||
}
|
||||
yySkip();
|
||||
return (SET_VAR);
|
||||
case STATE_COLON: // optional line terminator
|
||||
case MY_LEX_COLON: // optional line terminator
|
||||
if (yyPeek())
|
||||
{
|
||||
if (((THD *)yythd)->client_capabilities & CLIENT_MULTI_QUERIES)
|
||||
{
|
||||
lex->found_colon=(char*)lex->ptr;
|
||||
((THD *)yythd)->server_status |= SERVER_MORE_RESULTS_EXISTS;
|
||||
lex->next_state=STATE_END;
|
||||
lex->next_state=MY_LEX_END;
|
||||
return(END_OF_INPUT);
|
||||
}
|
||||
else
|
||||
state=STATE_CHAR; // Return ';'
|
||||
state=MY_LEX_CHAR; // Return ';'
|
||||
break;
|
||||
}
|
||||
/* fall true */
|
||||
case STATE_EOL:
|
||||
lex->next_state=STATE_END; // Mark for next loop
|
||||
case MY_LEX_EOL:
|
||||
lex->next_state=MY_LEX_END; // Mark for next loop
|
||||
return(END_OF_INPUT);
|
||||
case STATE_END:
|
||||
lex->next_state=STATE_END;
|
||||
case MY_LEX_END:
|
||||
lex->next_state=MY_LEX_END;
|
||||
return(0); // We found end of input last time
|
||||
|
||||
/* Actually real shouldn't start with . but allow them anyhow */
|
||||
case STATE_REAL_OR_POINT:
|
||||
if (my_isdigit(system_charset_info,yyPeek()))
|
||||
state = STATE_REAL; // Real
|
||||
case MY_LEX_REAL_OR_POINT:
|
||||
if (my_isdigit(cs,yyPeek()))
|
||||
state = MY_LEX_REAL; // Real
|
||||
else
|
||||
{
|
||||
state = STATE_CHAR; // return '.'
|
||||
lex->next_state=STATE_IDENT_START;// Next is an ident (not a keyword)
|
||||
state = MY_LEX_CHAR; // return '.'
|
||||
lex->next_state=MY_LEX_IDENT_START;// Next is an ident (not a keyword)
|
||||
}
|
||||
break;
|
||||
case STATE_USER_END: // end '@' of user@hostname
|
||||
case MY_LEX_USER_END: // end '@' of user@hostname
|
||||
switch (state_map[yyPeek()]) {
|
||||
case STATE_STRING:
|
||||
case STATE_USER_VARIABLE_DELIMITER:
|
||||
case STAT_STRING_OR_DELIMITER:
|
||||
case MY_LEX_STRING:
|
||||
case MY_LEX_USER_VARIABLE_DELIMITER:
|
||||
case MY_LEX_STRING_OR_DELIMITER:
|
||||
break;
|
||||
case STATE_USER_END:
|
||||
lex->next_state=STATE_SYSTEM_VAR;
|
||||
case MY_LEX_USER_END:
|
||||
lex->next_state=MY_LEX_SYSTEM_VAR;
|
||||
break;
|
||||
default:
|
||||
lex->next_state=STATE_HOSTNAME;
|
||||
lex->next_state=MY_LEX_HOSTNAME;
|
||||
break;
|
||||
}
|
||||
yylval->lex_str.str=(char*) lex->ptr;
|
||||
yylval->lex_str.length=1;
|
||||
return((int) '@');
|
||||
case STATE_HOSTNAME: // end '@' of user@hostname
|
||||
for (c=yyGet() ;
|
||||
my_isalnum(system_charset_info,c) || c == '.' || c == '_' ||
|
||||
c == '$';
|
||||
case MY_LEX_HOSTNAME: // end '@' of user@hostname
|
||||
for (c=yyGet() ;
|
||||
my_isalnum(cs,c) || c == '.' || c == '_' || c == '$';
|
||||
c= yyGet()) ;
|
||||
yylval->lex_str=get_token(lex,yyLength());
|
||||
return(LEX_HOSTNAME);
|
||||
case STATE_SYSTEM_VAR:
|
||||
case MY_LEX_SYSTEM_VAR:
|
||||
yylval->lex_str.str=(char*) lex->ptr;
|
||||
yylval->lex_str.length=1;
|
||||
lex->next_state=STATE_IDENT_OR_KEYWORD;
|
||||
lex->next_state=MY_LEX_IDENT_OR_KEYWORD;
|
||||
yySkip(); // Skip '@'
|
||||
return((int) '@');
|
||||
case STATE_IDENT_OR_KEYWORD:
|
||||
case MY_LEX_IDENT_OR_KEYWORD:
|
||||
/*
|
||||
We come here when we have found two '@' in a row.
|
||||
We should now be able to handle:
|
||||
|
@ -978,7 +932,7 @@ int yylex(void *arg, void *yythd)
|
|||
|
||||
while (ident_map[c=yyGet()]) ;
|
||||
if (c == '.')
|
||||
lex->next_state=STATE_IDENT_SEP;
|
||||
lex->next_state=MY_LEX_IDENT_SEP;
|
||||
length= (uint) (lex->ptr - lex->tok_start)-1;
|
||||
if ((tokval= find_keyword(lex,length,0)))
|
||||
{
|
||||
|
|
|
@ -64,7 +64,7 @@ enum enum_sql_command {
|
|||
SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
|
||||
SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
|
||||
SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE,
|
||||
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS,
|
||||
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_PURGE_BEFORE, SQLCOM_SHOW_BINLOGS,
|
||||
SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA,
|
||||
SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
|
||||
SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_DELETE_MULTI, SQLCOM_UPDATE_MULTI,
|
||||
|
@ -77,19 +77,6 @@ enum enum_sql_command {
|
|||
SQLCOM_END
|
||||
};
|
||||
|
||||
enum lex_states
|
||||
{
|
||||
STATE_START, STATE_CHAR, STATE_IDENT, STATE_IDENT_SEP, STATE_IDENT_START,
|
||||
STATE_FOUND_IDENT, STATE_SIGNED_NUMBER, STATE_REAL, STATE_HEX_NUMBER,
|
||||
STATE_CMP_OP, STATE_LONG_CMP_OP, STATE_STRING, STATE_COMMENT, STATE_END,
|
||||
STATE_OPERATOR_OR_IDENT, STATE_NUMBER_IDENT, STATE_INT_OR_REAL,
|
||||
STATE_REAL_OR_POINT, STATE_BOOL, STATE_EOL, STATE_ESCAPE, STATE_LONG_COMMENT,
|
||||
STATE_END_LONG_COMMENT, STATE_COLON, STATE_SET_VAR, STATE_USER_END,
|
||||
STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER, STATE_SYSTEM_VAR,
|
||||
STATE_IDENT_OR_KEYWORD, STATE_IDENT_OR_HEX, STATE_IDENT_OR_BIN,
|
||||
STAT_STRING_OR_DELIMITER
|
||||
};
|
||||
|
||||
|
||||
typedef List<Item> List_item;
|
||||
|
||||
|
@ -436,6 +423,7 @@ typedef struct st_lex
|
|||
char *length,*dec,*change,*name;
|
||||
char *backup_dir; /* For RESTORE/BACKUP */
|
||||
char* to_log; /* For PURGE MASTER LOGS TO */
|
||||
time_t purge_time; /* For PURGE MASTER LOGS BEFORE */
|
||||
char* x509_subject,*x509_issuer,*ssl_cipher;
|
||||
char* found_colon; /* For multi queries - next query */
|
||||
enum SSL_type ssl_type; /* defined in violite.h */
|
||||
|
@ -473,7 +461,7 @@ typedef struct st_lex
|
|||
ulong thread_id,type;
|
||||
enum_sql_command sql_command;
|
||||
thr_lock_type lock_option;
|
||||
enum lex_states next_state;
|
||||
enum my_lex_states next_state;
|
||||
enum enum_duplicates duplicates;
|
||||
enum enum_tx_isolation tx_isolation;
|
||||
enum enum_ha_read_modes ha_read_mode;
|
||||
|
@ -500,11 +488,13 @@ typedef struct st_lex
|
|||
but we should merk all subselects as uncacheable from current till
|
||||
most upper
|
||||
*/
|
||||
for (SELECT_LEX_NODE *sl= current_select;
|
||||
sl != &select_lex;
|
||||
sl= sl->outer_select())
|
||||
SELECT_LEX_NODE *sl;
|
||||
SELECT_LEX_UNIT *un;
|
||||
for (sl= current_select, un= sl->master_unit();
|
||||
un != &unit;
|
||||
sl= sl->outer_select(), un= sl->master_unit())
|
||||
{
|
||||
sl->uncacheable = sl->master_unit()->uncacheable= 1;
|
||||
sl->uncacheable = un->uncacheable= 1;
|
||||
}
|
||||
}
|
||||
} LEX;
|
||||
|
|
|
@ -1744,9 +1744,18 @@ mysql_execute_command(THD *thd)
|
|||
{
|
||||
if (check_global_access(thd, SUPER_ACL))
|
||||
goto error;
|
||||
// PURGE MASTER LOGS TO 'file'
|
||||
res = purge_master_logs(thd, lex->to_log);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_PURGE_BEFORE:
|
||||
{
|
||||
if (check_global_access(thd, SUPER_ACL))
|
||||
goto error;
|
||||
// PURGE MASTER LOGS BEFORE 'data'
|
||||
res = purge_master_logs_before_date(thd, lex->purge_time);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case SQLCOM_SHOW_WARNS:
|
||||
|
@ -2866,7 +2875,7 @@ mysql_execute_command(THD *thd)
|
|||
if (check_global_access(thd,RELOAD_ACL) || check_db_used(thd, tables))
|
||||
goto error;
|
||||
/* error sending is deferred to reload_acl_and_cache */
|
||||
reload_acl_and_cache(thd, lex->type, tables) ;
|
||||
reload_acl_and_cache(thd, lex->type, tables);
|
||||
break;
|
||||
case SQLCOM_KILL:
|
||||
kill_one_thread(thd,lex->thread_id);
|
||||
|
@ -3931,6 +3940,14 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
|
|||
mysql_log.new_file(1);
|
||||
mysql_update_log.new_file(1);
|
||||
mysql_bin_log.new_file(1);
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (expire_logs_days)
|
||||
{
|
||||
long purge_time= time(0) - expire_logs_days*24*60*60;
|
||||
if (purge_time >= 0)
|
||||
mysql_bin_log.purge_logs_before_date(thd, purge_time);
|
||||
}
|
||||
#endif
|
||||
mysql_slow_log.new_file(1);
|
||||
if (ha_flush_logs())
|
||||
result=1;
|
||||
|
|
|
@ -257,15 +257,10 @@ bool log_in_use(const char* log_name)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
int purge_master_logs(THD* thd, const char* to_log)
|
||||
int purge_error_message(THD* thd, int res)
|
||||
{
|
||||
char search_file_name[FN_REFLEN];
|
||||
const char* errmsg = 0;
|
||||
|
||||
mysql_bin_log.make_log_name(search_file_name, to_log);
|
||||
int res = mysql_bin_log.purge_logs(thd, search_file_name);
|
||||
|
||||
switch(res) {
|
||||
case 0: break;
|
||||
case LOG_INFO_EOF: errmsg = "Target log not found in binlog index"; break;
|
||||
|
@ -289,10 +284,26 @@ binlog purge"; break;
|
|||
}
|
||||
else
|
||||
send_ok(thd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int purge_master_logs(THD* thd, const char* to_log)
|
||||
{
|
||||
char search_file_name[FN_REFLEN];
|
||||
|
||||
mysql_bin_log.make_log_name(search_file_name, to_log);
|
||||
int res = mysql_bin_log.purge_logs(thd, search_file_name);
|
||||
|
||||
return purge_error_message(thd, res);
|
||||
}
|
||||
|
||||
|
||||
int purge_master_logs_before_date(THD* thd, time_t purge_time)
|
||||
{
|
||||
int res = mysql_bin_log.purge_logs_before_date(thd, purge_time);
|
||||
return purge_error_message(thd ,res);
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Clean up loop to only have one call to send_file()
|
||||
*/
|
||||
|
|
|
@ -34,6 +34,7 @@ int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
|
|||
int reset_slave(THD *thd, MASTER_INFO* mi);
|
||||
int reset_master(THD* thd);
|
||||
int purge_master_logs(THD* thd, const char* to_log);
|
||||
int purge_master_logs_before_date(THD* thd, time_t purge_time);
|
||||
bool log_in_use(const char* log_name);
|
||||
void adjust_linfo_offsets(my_off_t purge_offset);
|
||||
int show_binlogs(THD* thd);
|
||||
|
|
|
@ -2766,19 +2766,15 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
|||
if (!keyuse->used_tables &&
|
||||
!(join->select_options & SELECT_DESCRIBE))
|
||||
{ // Compare against constant
|
||||
store_key_item *tmp=new store_key_item(thd,
|
||||
keyinfo->key_part[i].field,
|
||||
(char*)key_buff +
|
||||
maybe_null,
|
||||
maybe_null ?
|
||||
(char*) key_buff : 0,
|
||||
keyinfo->key_part[i].length,
|
||||
keyuse->val);
|
||||
store_key_item tmp(thd, keyinfo->key_part[i].field,
|
||||
(char*)key_buff + maybe_null,
|
||||
maybe_null ? (char*) key_buff : 0,
|
||||
keyinfo->key_part[i].length, keyuse->val);
|
||||
if (thd->is_fatal_error)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
tmp->copy();
|
||||
tmp.copy();
|
||||
}
|
||||
else
|
||||
*ref_key++= get_store_key(thd,
|
||||
|
|
|
@ -174,7 +174,7 @@ class JOIN :public Sql_alloc
|
|||
Item_sum **sum_funcs;
|
||||
Procedure *procedure;
|
||||
Item *having;
|
||||
Item *tmp_having; // To store Having when processed tenporary table
|
||||
Item *tmp_having; // To store Having when processed temporary table
|
||||
uint select_options;
|
||||
select_result *result;
|
||||
TMP_TABLE_PARAM tmp_table_param;
|
||||
|
@ -306,7 +306,6 @@ class store_key :public Sql_alloc
|
|||
{
|
||||
protected:
|
||||
Field *to_field; // Store data here
|
||||
Field *key_field; // Copy of key field
|
||||
char *null_ptr;
|
||||
char err;
|
||||
public:
|
||||
|
|
|
@ -532,6 +532,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||
%token SUBJECT_SYM
|
||||
%token CIPHER_SYM
|
||||
|
||||
%token HELP
|
||||
%token BEFORE_SYM
|
||||
%left SET_VAR
|
||||
%left OR_OR_CONCAT OR
|
||||
%left AND
|
||||
|
@ -3683,13 +3685,34 @@ purge:
|
|||
PURGE
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->sql_command = SQLCOM_PURGE;
|
||||
lex->type=0;
|
||||
} purge_options
|
||||
{}
|
||||
;
|
||||
|
||||
purge_options:
|
||||
LOGS_SYM purge_option
|
||||
| MASTER_SYM LOGS_SYM purge_option
|
||||
;
|
||||
|
||||
purge_option:
|
||||
TO_SYM TEXT_STRING
|
||||
{
|
||||
Lex->sql_command = SQLCOM_PURGE;
|
||||
Lex->to_log = $2.str;
|
||||
}
|
||||
| BEFORE_SYM expr
|
||||
{
|
||||
if ($2->check_cols(1) || $2->fix_fields(Lex->thd, 0, &$2))
|
||||
{
|
||||
net_printf(Lex->thd, ER_WRONG_ARGUMENTS, "PURGE LOGS BEFORE");
|
||||
YYABORT;
|
||||
}
|
||||
Item *tmp= new Item_func_unix_timestamp($2);
|
||||
Lex->sql_command = SQLCOM_PURGE_BEFORE;
|
||||
Lex->purge_time= tmp->val_int();
|
||||
}
|
||||
MASTER_SYM LOGS_SYM TO_SYM TEXT_STRING
|
||||
{
|
||||
Lex->to_log = $6.str;
|
||||
} ;
|
||||
;
|
||||
|
||||
/* kill threads */
|
||||
|
||||
|
@ -3844,7 +3867,7 @@ literal:
|
|||
| REAL_NUM { $$ = new Item_real($1.str, $1.length); }
|
||||
| FLOAT_NUM { $$ = new Item_float($1.str, $1.length); }
|
||||
| NULL_SYM { $$ = new Item_null();
|
||||
Lex->next_state=STATE_OPERATOR_OR_IDENT;}
|
||||
Lex->next_state=MY_LEX_OPERATOR_OR_IDENT;}
|
||||
| HEX_NUM { $$ = new Item_varbinary($1.str,$1.length);}
|
||||
| DATE_SYM text_literal { $$ = $2; }
|
||||
| TIME_SYM text_literal { $$ = $2; }
|
||||
|
@ -3941,8 +3964,8 @@ ident:
|
|||
LEX *lex= Lex;
|
||||
$$.str= lex->thd->strmake($1.str,$1.length);
|
||||
$$.length=$1.length;
|
||||
if (lex->next_state != STATE_END)
|
||||
lex->next_state=STATE_OPERATOR_OR_IDENT;
|
||||
if (lex->next_state != MY_LEX_END)
|
||||
lex->next_state= MY_LEX_OPERATOR_OR_IDENT;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -6244,6 +6244,7 @@ CHARSET_INFO my_charset_big5 =
|
|||
sort_order_big5,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
1, /* strxfrm_multiply */
|
||||
my_strnncoll_big5,
|
||||
my_strnncollsp_big5,
|
||||
|
|
|
@ -75,6 +75,21 @@ static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)),
|
|||
return cmp ? cmp : (int) (slen - tlen);
|
||||
}
|
||||
|
||||
static int my_strnncollsp_binary(CHARSET_INFO * cs,
|
||||
const uchar *s, uint slen,
|
||||
const uchar *t, uint tlen)
|
||||
{
|
||||
int len, cmp;
|
||||
|
||||
for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--);
|
||||
for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--);
|
||||
|
||||
len = ( slen > tlen ) ? tlen : slen;
|
||||
|
||||
cmp= memcmp(s,t,len);
|
||||
return cmp ? cmp : (int) (slen - tlen);
|
||||
}
|
||||
|
||||
static void my_caseup_str_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||
char *str __attribute__((unused)))
|
||||
{
|
||||
|
@ -306,9 +321,10 @@ CHARSET_INFO my_charset_bin =
|
|||
bin_char_array, /* sort_order */
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_binary, /* strnncoll */
|
||||
my_strnncoll_binary,
|
||||
my_strnncollsp_binary,
|
||||
my_strnxfrm_bin, /* strxnfrm */
|
||||
my_like_range_simple, /* like_range */
|
||||
my_wildcmp_bin, /* wildcmp */
|
||||
|
|
|
@ -618,6 +618,7 @@ CHARSET_INFO my_charset_czech =
|
|||
sort_order_czech,
|
||||
tab_8859_2_uni, /* tab_to_uni */
|
||||
idx_uni_8859_2, /* tab_from_uni */
|
||||
"","",
|
||||
4, /* strxfrm_multiply */
|
||||
my_strnncoll_czech,
|
||||
my_strnncollsp_czech,
|
||||
|
|
|
@ -8652,6 +8652,7 @@ CHARSET_INFO my_charset_euc_kr =
|
|||
sort_order_euc_kr,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,
|
||||
|
|
|
@ -2818,6 +2818,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_latin1,
|
||||
tab_8859_1_uni, /* tab_to_uni */
|
||||
idx_uni_8859_1, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -2869,6 +2870,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_cp1251,
|
||||
tab_cp1251_uni, /* tab_to_uni */
|
||||
idx_uni_cp1251, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -2919,6 +2921,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_cp1257,
|
||||
tab_cp1257_uni, /* tab_to_uni */
|
||||
idx_uni_cp1257, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -2969,6 +2972,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_croat,
|
||||
tab_8859_2_uni, /* tab_to_uni */
|
||||
idx_uni_8859_2, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3020,6 +3024,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_danish,
|
||||
tab_8859_1_uni, /* tab_to_uni */
|
||||
idx_uni_8859_1, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3070,6 +3075,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_dec8,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3120,6 +3126,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_dos,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3170,6 +3177,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_estonia,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3221,6 +3229,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_german1,
|
||||
tab_8859_1_uni, /* tab_to_uni */
|
||||
idx_uni_8859_1, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3271,6 +3280,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_greek,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3321,6 +3331,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_hebrew,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3371,6 +3382,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_hp8,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3421,6 +3433,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_hungarian,
|
||||
tab_8859_2_uni, /* tab_to_uni */
|
||||
idx_uni_8859_2, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3471,6 +3484,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_koi8_ru,
|
||||
tab_koi8_r_uni, /* tab_to_uni */
|
||||
idx_uni_koi8_r, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3521,6 +3535,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_koi8_ukr,
|
||||
tab_koi8_u_uni, /* tab_to_uni */
|
||||
idx_uni_koi8_u, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3572,6 +3587,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_latin2,
|
||||
tab_8859_2_uni, /* tab_to_uni */
|
||||
idx_uni_8859_2, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3622,6 +3638,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_latin5,
|
||||
tab_8859_9_uni, /* tab_to_uni */
|
||||
idx_uni_8859_9, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3673,6 +3690,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_swe7,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3724,6 +3742,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_usa7,
|
||||
tab_us_ascii_uni, /* tab_to_uni */
|
||||
idx_uni_us_ascii, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3774,6 +3793,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_win1250,
|
||||
tab_cp1250_uni, /* tab_to_uni */
|
||||
idx_uni_cp1250, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3824,6 +3844,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_win1251ukr,
|
||||
tab_cp1251_uni, /* tab_to_uni */
|
||||
idx_uni_cp1251, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3874,6 +3895,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_armscii8,
|
||||
tab_armscii_8_uni, /* tab_to_uni */
|
||||
idx_uni_armscii_8, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3924,6 +3946,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
sort_order_win1251,
|
||||
tab_cp1251_uni, /* tab_to_uni */
|
||||
idx_uni_cp1251, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,/* strnncollsp */
|
||||
|
@ -3973,6 +3996,7 @@ CHARSET_INFO compiled_charsets[] = {
|
|||
NULL,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0,
|
||||
NULL, /* strnncoll */
|
||||
NULL, /* strnncollsp */
|
||||
|
|
|
@ -5702,6 +5702,7 @@ CHARSET_INFO my_charset_gb2312 =
|
|||
sort_order_gb2312,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,
|
||||
|
|
|
@ -9899,6 +9899,7 @@ CHARSET_INFO my_charset_gbk =
|
|||
sort_order_gbk,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
1, /* strxfrm_multiply */
|
||||
my_strnncoll_gbk,
|
||||
my_strnncollsp_gbk,
|
||||
|
|
|
@ -188,6 +188,7 @@ CHARSET_INFO my_charset_latin1 =
|
|||
sort_order_latin1,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
2, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,
|
||||
my_strnncollsp_simple,
|
||||
|
|
|
@ -359,6 +359,7 @@ CHARSET_INFO my_charset_latin1_de =
|
|||
sort_order_latin1_de,
|
||||
tab_8859_1_uni, /* tab_to_uni */
|
||||
idx_uni_8859_1, /* tab_from_uni */
|
||||
"","",
|
||||
2, /* strxfrm_multiply */
|
||||
my_strnncoll_latin1_de,
|
||||
my_strnncollsp_latin1_de,
|
||||
|
|
|
@ -4486,6 +4486,7 @@ CHARSET_INFO my_charset_sjis =
|
|||
sort_order_sjis,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
1, /* strxfrm_multiply */
|
||||
my_strnncoll_sjis,
|
||||
my_strnncollsp_sjis,
|
||||
|
|
|
@ -709,6 +709,7 @@ CHARSET_INFO my_charset_tis620 =
|
|||
sort_order_tis620,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
4, /* strxfrm_multiply */
|
||||
my_strnncoll_tis620,
|
||||
my_strnncollsp_tis620,
|
||||
|
|
|
@ -8443,6 +8443,7 @@ CHARSET_INFO my_charset_ujis =
|
|||
sort_order_ujis,
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
0, /* strxfrm_multiply */
|
||||
my_strnncoll_simple,/* strnncoll */
|
||||
my_strnncollsp_simple,
|
||||
|
|
|
@ -1988,6 +1988,7 @@ CHARSET_INFO my_charset_utf8 =
|
|||
to_upper_utf8, /* sort_order */
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
1, /* strxfrm_multiply */
|
||||
my_strnncoll_utf8, /* strnncoll */
|
||||
my_strnncollsp_utf8,
|
||||
|
@ -3095,6 +3096,7 @@ CHARSET_INFO my_charset_ucs2 =
|
|||
to_upper_ucs2, /* sort_order */
|
||||
NULL, /* tab_to_uni */
|
||||
NULL, /* tab_from_uni */
|
||||
"","",
|
||||
1, /* strxfrm_multiply */
|
||||
my_strnncoll_ucs2, /* strnncoll */
|
||||
my_strnncoll_ucs2,
|
||||
|
|
|
@ -653,6 +653,7 @@ CHARSET_INFO my_charset_win1250ch =
|
|||
sort_order_win1250ch,
|
||||
tab_cp1250_uni, /* tab_to_uni */
|
||||
idx_uni_cp1250, /* tab_from_uni */
|
||||
"","",
|
||||
2, /* strxfrm_multiply */
|
||||
my_strnncoll_win1250ch,
|
||||
my_strnncollsp_win1250ch,
|
||||
|
|
Loading…
Reference in a new issue