summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libmysql/libmysql.c2
-rw-r--r--mysys/tree.c53
-rw-r--r--regex/Makefile.am2
-rw-r--r--sql/field.cc26
-rw-r--r--sql/ha_heap.cc10
-rw-r--r--sql/ha_heap.h1
-rw-r--r--sql/item.h4
-rw-r--r--sql/item_func.h4
-rw-r--r--sql/item_strfunc.cc8
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/item_sum.h4
-rw-r--r--sql/lex.h3
-rw-r--r--sql/sql_parse.cc34
-rw-r--r--sql/sql_yacc.yy140
-rw-r--r--strings/ctype-simple.c20
15 files changed, 161 insertions, 152 deletions
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 352ac520fed..94a32477c83 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -4199,7 +4199,7 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number,
static void fetch_result_tinyint(MYSQL_BIND *param, uchar **row)
{
*param->buffer= (uchar) **row;
- *row++;
+ (*row)++;
}
static void fetch_result_short(MYSQL_BIND *param, uchar **row)
diff --git a/mysys/tree.c b/mysys/tree.c
index 364b6992108..4b14ffd7112 100644
--- a/mysys/tree.c
+++ b/mysys/tree.c
@@ -335,54 +335,67 @@ void *tree_search_key(TREE *tree, const void *key,
enum ha_rkey_function flag, void *custom_arg)
{
int cmp;
- TREE_ELEMENT *element = tree->root;
- TREE_ELEMENT **last_left_step_parent = NULL;
- TREE_ELEMENT **last_equal_element = NULL;
+ TREE_ELEMENT *element= tree->root;
+ TREE_ELEMENT **last_left_step_parent= NULL, **last_right_step_parent= NULL;
+ TREE_ELEMENT **last_equal_element= NULL;
/*
- TODO: handle HA_READ_KEY_OR_PREV, HA_READ_BEFORE_KEY, HA_READ_PREFIX,
- HA_READ_PREFIX_LAST flags if needed.
+ TODO: support for HA_READ_KEY_OR_PREV, HA_READ_PREFIX flags if needed.
*/
*parents = &tree->null_element;
while (element != &tree->null_element)
{
- *++parents = element;
- if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element),
- key)) == 0)
+ *++parents= element;
+ if ((cmp= (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element),
+ key)) == 0)
{
switch (flag) {
case HA_READ_KEY_EXACT:
case HA_READ_KEY_OR_NEXT:
- last_equal_element = parents;
- cmp = 1;
- break;
+ case HA_READ_BEFORE_KEY:
+ last_equal_element= parents;
+ cmp= 1;
+ break;
case HA_READ_AFTER_KEY:
- cmp = -1;
- break;
+ cmp= -1;
+ break;
+ case HA_READ_PREFIX_LAST:
+ case HA_READ_PREFIX_LAST_OR_PREV:
+ last_equal_element= parents;
+ cmp= -1;
+ break;
default:
- return NULL;
+ return NULL;
}
}
if (cmp < 0) /* element < key */
{
- element = element->right;
+ last_right_step_parent= parents;
+ element= element->right;
}
else
{
- last_left_step_parent = parents;
- element = element->left;
+ last_left_step_parent= parents;
+ element= element->left;
}
}
switch (flag) {
case HA_READ_KEY_EXACT:
- *last_pos = last_equal_element;
+ case HA_READ_PREFIX_LAST:
+ *last_pos= last_equal_element;
break;
case HA_READ_KEY_OR_NEXT:
- *last_pos = last_equal_element ? last_equal_element : last_left_step_parent;
+ *last_pos= last_equal_element ? last_equal_element : last_left_step_parent;
break;
case HA_READ_AFTER_KEY:
- *last_pos = last_left_step_parent;
+ *last_pos= last_left_step_parent;
+ break;
+ case HA_READ_PREFIX_LAST_OR_PREV:
+ *last_pos= last_equal_element ? last_equal_element : last_right_step_parent;
+ break;
+ case HA_READ_BEFORE_KEY:
+ *last_pos= last_right_step_parent;
break;
default:
return NULL;
diff --git a/regex/Makefile.am b/regex/Makefile.am
index 2e23efcbf2a..fe72f29b16c 100644
--- a/regex/Makefile.am
+++ b/regex/Makefile.am
@@ -17,7 +17,7 @@
INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include
noinst_LIBRARIES = libregex.a
-LDADD = libregex.a ../strings/libmystrings.a
+LDADD = libregex.a ../strings/libmystrings.a ../mysys/libmysys.a
noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c regex.h
libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
noinst_PROGRAMS = re
diff --git a/sql/field.cc b/sql/field.cc
index e0910caeea2..f0f3b22f1cc 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -15,16 +15,6 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/*
- NOTES:
- Some of the number class uses the system functions strtol(), strtoll()...
- To avoid patching the end \0 or copying the buffer unnecessary, all calls
- to system functions are wrapped to a String object that adds the end null
- if it only if it isn't there.
- This adds some overhead when assigning numbers from strings but makes
- everything simpler.
- */
-
/*****************************************************************************
** This file implements classes defined in field.h
*****************************************************************************/
@@ -1592,7 +1582,6 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
}
long tmp;
int error= 0;
- String tmp_str(from,len,default_charset_info);
errno=0;
if (unsigned_flag)
{
@@ -1603,10 +1592,10 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
error= 1;
}
else
- tmp=(long) strtoul(tmp_str.c_ptr(),NULL,10);
+ tmp=(long) my_strntoul(cs,from,len,NULL,10);
}
else
- tmp=strtol(tmp_str.c_ptr(),NULL,10);
+ tmp=my_strntol(cs,from,len,NULL,10);
if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
{
current_thd->cuted_fields++;
@@ -1837,7 +1826,6 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
len--; from++;
}
longlong tmp;
- String tmp_str(from,len,default_charset_info);
int error= 0;
errno=0;
if (unsigned_flag)
@@ -1849,10 +1837,10 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
error= 1;
}
else
- tmp=(longlong) strtoull(tmp_str.c_ptr(),NULL,10);
+ tmp=(longlong) my_strntoull(cs,from,len,NULL,10);
}
else
- tmp=strtoll(tmp_str.c_ptr(),NULL,10);
+ tmp=my_strntoll(cs,from,len,NULL,10);
if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
{
current_thd->cuted_fields++;
@@ -2052,9 +2040,8 @@ void Field_longlong::sql_type(String &res) const
int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
{
- String tmp_str(from,len,default_charset_info);
errno=0;
- Field_float::store(atof(tmp_str.c_ptr()));
+ Field_float::store(my_strntod(cs,from,len,(char**)NULL));
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
{
current_thd->cuted_fields++;
@@ -2314,10 +2301,9 @@ void Field_float::sql_type(String &res) const
int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
{
- String tmp_str(from,len,default_charset_info);
errno=0;
int error= 0;
- double j= atof(tmp_str.c_ptr());
+ double j= my_strntod(cs,from,len,(char**)0);
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
{
current_thd->cuted_fields++;
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index 4a3b9495f6f..fb4061b31e0 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -81,6 +81,15 @@ int ha_heap::index_read(byte * buf, const byte * key, uint key_len,
return error;
}
+int ha_heap::index_read_last(byte *buf, const byte *key, uint key_len)
+{
+ statistic_increment(ha_read_key_count, &LOCK_status);
+ int error= heap_rkey(file, buf, active_index, key, key_len,
+ HA_READ_PREFIX_LAST);
+ table->status= error ? STATUS_NOT_FOUND : 0;
+ return error;
+}
+
int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
uint key_len, enum ha_rkey_function find_flag)
{
@@ -90,7 +99,6 @@ int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
return error;
}
-
int ha_heap::index_next(byte * buf)
{
statistic_increment(ha_read_next_count,&LOCK_status);
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index f82a1a460d8..fe874dab3f2 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -67,6 +67,7 @@ class ha_heap: public handler
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
int index_next(byte * buf);
int index_prev(byte * buf);
int index_first(byte * buf);
diff --git a/sql/item.h b/sql/item.h
index 9ff2b78eb04..766bd7fba41 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -542,9 +542,9 @@ public:
enum Type type() const { return COPY_STR_ITEM; }
enum Item_result result_type () const { return STRING_RESULT; }
double val()
- { return null_value ? 0.0 : atof(str_value.c_ptr()); }
+ { return null_value ? 0.0 : my_strntod(str_value.charset(),str_value.ptr(),str_value.length(),NULL); }
longlong val_int()
- { return null_value ? LL(0) : strtoll(str_value.c_ptr(),(char**) 0,10); }
+ { return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),(char**) 0,10); }
String *val_str(String*);
void make_field(Send_field *field) { item->make_field(field); }
void copy();
diff --git a/sql/item_func.h b/sql/item_func.h
index e3b5fa3445a..67c088f2bd9 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -845,12 +845,12 @@ public:
double val()
{
String *res; res=val_str(&str_value);
- return res ? atof(res->c_ptr()) : 0.0;
+ return res ? my_strntod(res->charset(),res->ptr(),res->length(),0) : 0.0;
}
longlong val_int()
{
String *res; res=val_str(&str_value);
- return res ? strtoll(res->c_ptr(),(char**) 0,10) : (longlong) 0;
+ return res ? my_strntoll(res->charset(),res->ptr(),res->length(),(char**) 0,10) : (longlong) 0;
}
enum Item_result result_type () const { return STRING_RESULT; }
void fix_length_and_dec();
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 7eb7e57a8ca..158947cc221 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -54,14 +54,14 @@ double Item_str_func::val()
{
String *res;
res=val_str(&str_value);
- return res ? atof(res->c_ptr()) : 0.0;
+ return res ? my_strntod(res->charset(),res->ptr(),res->length(),NULL) : 0.0;
}
longlong Item_str_func::val_int()
{
String *res;
res=val_str(&str_value);
- return res ? strtoll(res->c_ptr(),NULL,10) : (longlong) 0;
+ return res ? my_strntoll(res->charset(),res->ptr(),res->length(),NULL,10) : (longlong) 0;
}
@@ -1905,9 +1905,9 @@ String *Item_func_conv::val_str(String *str)
}
null_value=0;
if (from_base < 0)
- dec= strtoll(res->c_ptr(),&endptr,-from_base);
+ dec= my_strntoll(res->charset(),res->ptr(),res->length(),&endptr,-from_base);
else
- dec= (longlong) strtoull(res->c_ptr(),&endptr,from_base);
+ dec= (longlong) my_strntoull(res->charset(),res->ptr(),res->length(),&endptr,from_base);
ptr= longlong2str(dec,ans,to_base);
if (str->copy(ans,(uint32) (ptr-ans), thd_charset()))
return &empty_string;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 6b13cac94ca..fe7523a5fc5 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -334,7 +334,7 @@ double Item_sum_hybrid::val()
switch (hybrid_type) {
case STRING_RESULT:
String *res; res=val_str(&str_value);
- return res ? atof(res->c_ptr()) : 0.0;
+ return res ? my_strntod(res->charset(),res->ptr(),res->length(),(char**)0) : 0.0;
case INT_RESULT:
if (unsigned_flag)
return ulonglong2double(sum_int);
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 70bb3a7c0a1..00803abf25d 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -442,12 +442,12 @@ public:
double val()
{
String *res; res=val_str(&str_value);
- return res ? atof(res->c_ptr()) : 0.0;
+ return res ? my_strntod(res->charset(),res->ptr(),res->length(),(char**) 0) : 0.0;
}
longlong val_int()
{
String *res; res=val_str(&str_value);
- return res ? strtoll(res->c_ptr(),(char**) 0,10) : (longlong) 0;
+ return res ? my_strntoll(res->charset(),res->ptr(),res->length(),(char**) 0,10) : (longlong) 0;
}
enum Item_result result_type () const { return STRING_RESULT; }
void fix_length_and_dec();
diff --git a/sql/lex.h b/sql/lex.h
index 768d995b68b..e55d1cbd4b0 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -135,6 +135,7 @@ static SYMBOL symbols[] = {
{ "DROP", SYM(DROP),0,0},
{ "DUMPFILE", SYM(DUMPFILE),0,0},
{ "DYNAMIC", SYM(DYNAMIC_SYM),0,0},
+ { "DUPLICATE", SYM(DUPLICATE),0,0},
{ "ERRORS", SYM(ERRORS),0,0},
{ "END", SYM(END),0,0},
{ "ELSE", SYM(ELSE),0,0},
@@ -342,7 +343,7 @@ static SYMBOL symbols[] = {
{ "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS),0,0},
{ "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0},
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0},
- { "SQL_THREAD", SYM(SQL_THREAD),0,0},
+ { "SQL_THREAD", SYM(SQL_THREAD),0,0},
{ "SSL", SYM(SSL_SYM),0,0},
{ "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0},
{ "START", SYM(START_SYM),0,0},
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index a410a9f2d7e..529a8b396f9 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1905,7 +1905,7 @@ mysql_execute_command(THD *thd)
select_lex->select_limit,
lex->duplicates);
}
- else
+ else
{
multi_update *result;
uint table_count;
@@ -1932,8 +1932,8 @@ mysql_execute_command(THD *thd)
if ((res=open_and_lock_tables(thd,tables)))
break;
unit->select_limit_cnt= HA_POS_ERROR;
- if (!setup_fields(thd,tables,select_lex->item_list,1,0,0) &&
- !setup_fields(thd,tables,lex->value_list,0,0,0) &&
+ if (!setup_fields(thd,tables,select_lex->item_list,1,0,0) &&
+ !setup_fields(thd,tables,lex->value_list,0,0,0) &&
!thd->fatal_error &&
(result=new multi_update(thd,tables,select_lex->item_list,
lex->duplicates, table_count)))
@@ -1946,7 +1946,7 @@ mysql_execute_command(THD *thd)
total_list.push_back(item);
while ((item=value_list++))
total_list.push_back(item);
-
+
res= mysql_select(thd, tables, total_list,
select_lex->where,
(ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
@@ -1960,26 +1960,20 @@ mysql_execute_command(THD *thd)
res= -1; // Error is not sent
close_thread_tables(thd);
}
- break;
- case SQLCOM_INSERT:
- if (check_access(thd,INSERT_ACL,tables->db,&tables->grant.privilege))
- goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,INSERT_ACL,tables))
- goto error;
- res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
- lex->duplicates);
break;
case SQLCOM_REPLACE:
- if (check_access(thd,INSERT_ACL | DELETE_ACL,
- tables->db,&tables->grant.privilege))
+ case SQLCOM_INSERT:
+ {
+ ulong privilege= (lex->duplicates == DUP_REPLACE ?
+ INSERT_ACL | DELETE_ACL : INSERT_ACL);
+ if (check_access(thd,privilege,tables->db,&tables->grant.privilege))
goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,INSERT_ACL | DELETE_ACL,
- tables))
-
+ if (grant_option && check_grant(thd,privilege,tables))
goto error;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
- DUP_REPLACE);
+ lex->duplicates);
break;
+ }
case SQLCOM_REPLACE_SELECT:
case SQLCOM_INSERT_SELECT:
{
@@ -1989,8 +1983,8 @@ mysql_execute_command(THD *thd)
select privileges for the rest
*/
{
- ulong privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ?
- INSERT_ACL : INSERT_ACL | DELETE_ACL);
+ ulong privilege= (lex->duplicates == DUP_REPLACE ?
+ INSERT_ACL | DELETE_ACL : INSERT_ACL);
TABLE_LIST *save_next=tables->next;
tables->next=0;
if (check_access(thd, privilege,
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 216cd52d408..3be499c19fb 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -204,6 +204,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DES_KEY_FILE
%token DISABLE_SYM
%token DISTINCT
+%token DUPLICATE
%token DYNAMIC_SYM
%token ENABLE_SYM
%token ENCLOSED
@@ -642,7 +643,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
repair restore backup analyze check
field_list field_list_item field_spec kill
select_item_list select_item values_list no_braces
- limit_clause delete_limit_clause fields opt_values values
+ opt_limit_clause delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item
when_list2 expr_list2 handler
opt_precision opt_ignore opt_column opt_restrict
@@ -660,7 +661,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
table_to_table_list table_to_table opt_table_list opt_as
handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild
- union union_list union_option
+ union_clause union_list union_option
precision opt_on_delete_item subselect_start opt_and
subselect_end select_var_list select_var_list_init help opt_len
END_OF_INPUT
@@ -883,7 +884,7 @@ create3:
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
mysql_init_select(lex);
}
- select_options select_item_list opt_select_from union {}
+ select_options select_item_list opt_select_from union_clause {}
;
opt_as:
@@ -918,27 +919,23 @@ create_table_options:
| create_table_option create_table_options;
| create_table_option ',' create_table_options;
-o_eq:
- /* empty */
- | EQ {};
-
create_table_option:
- TYPE_SYM o_eq table_types { Lex->create_info.db_type= $3; }
- | MAX_ROWS o_eq ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
- | MIN_ROWS o_eq ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
- | AVG_ROW_LENGTH o_eq ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
- | PASSWORD o_eq TEXT_STRING { Lex->create_info.password=$3.str; }
- | COMMENT_SYM o_eq TEXT_STRING { Lex->create_info.comment=$3.str; }
- | AUTO_INC o_eq ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
- | PACK_KEYS_SYM o_eq ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
- | PACK_KEYS_SYM o_eq DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
- | CHECKSUM_SYM o_eq ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; }
- | DELAY_KEY_WRITE_SYM o_eq ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; }
- | ROW_FORMAT_SYM o_eq row_types { Lex->create_info.row_type= $3; }
- | RAID_TYPE o_eq raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
- | RAID_CHUNKS o_eq ULONG_NUM { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
- | RAID_CHUNKSIZE o_eq ULONG_NUM { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
- | UNION_SYM o_eq '(' table_list ')'
+ TYPE_SYM opt_equal table_types { Lex->create_info.db_type= $3; }
+ | MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
+ | MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
+ | AVG_ROW_LENGTH opt_equal ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
+ | PASSWORD opt_equal TEXT_STRING { Lex->create_info.password=$3.str; }
+ | COMMENT_SYM opt_equal TEXT_STRING { Lex->create_info.comment=$3.str; }
+ | AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
+ | PACK_KEYS_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
+ | PACK_KEYS_SYM opt_equal DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
+ | CHECKSUM_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; }
+ | DELAY_KEY_WRITE_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; }
+ | ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; }
+ | RAID_TYPE opt_equal raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
+ | RAID_CHUNKS opt_equal ULONG_NUM { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
+ | RAID_CHUNKSIZE opt_equal ULONG_NUM { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
+ | UNION_SYM opt_equal '(' table_list ')'
{
/* Move the union list to the merge_list */
LEX *lex=Lex;
@@ -951,19 +948,19 @@ create_table_option:
table_list->next=0;
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
}
- | opt_default CHARSET o_eq charset_name_or_default
+ | opt_default CHARSET opt_equal charset_name_or_default
{
Lex->create_info.table_charset= $4;
Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET;
}
- | opt_default CHAR_SYM SET o_eq charset_name_or_default
+ | opt_default CHAR_SYM SET opt_equal charset_name_or_default
{
Lex->create_info.table_charset= $5;
Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET;
}
- | INSERT_METHOD o_eq merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
- | DATA_SYM DIRECTORY_SYM o_eq TEXT_STRING { Lex->create_info.data_file_name= $4.str; }
- | INDEX DIRECTORY_SYM o_eq TEXT_STRING { Lex->create_info.index_file_name= $4.str; };
+ | INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
+ | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING { Lex->create_info.data_file_name= $4.str; }
+ | INDEX DIRECTORY_SYM opt_equal TEXT_STRING { Lex->create_info.index_file_name= $4.str; };
table_types:
ISAM_SYM { $$= DB_TYPE_ISAM; }
@@ -990,7 +987,7 @@ merge_insert_types:
| LAST_SYM { $$= MERGE_INSERT_TO_LAST; };
opt_select_from:
- /* empty */
+ opt_limit_clause {}
| select_from select_lock_type;
udf_func_type:
@@ -1635,17 +1632,9 @@ table_to_table:
select:
select_init { Lex->sql_command=SQLCOM_SELECT; };
+/* Need select_init2 for subselects. */
select_init:
- SELECT_SYM select_part2
- {
- LEX *lex= Lex;
- if (lex->current_select->set_braces(false))
- {
- send_error(lex->thd, ER_SYNTAX_ERROR);
- YYABORT;
- }
- }
- union
+ SELECT_SYM select_init2
|
'(' SELECT_SYM select_part2 ')'
{
@@ -1661,6 +1650,19 @@ select_init:
sel->master_unit();
} union_opt;
+select_init2:
+ select_part2
+ {
+ LEX *lex= Lex;
+ if (lex->current_select->set_braces(false))
+ {
+ send_error(lex->thd, ER_SYNTAX_ERROR);
+ YYABORT;
+ }
+ }
+ union_clause
+ ;
+
select_part2:
{
LEX *lex=Lex;
@@ -1671,16 +1673,18 @@ select_part2:
select_options select_item_list select_into select_lock_type;
select_into:
- limit_clause {}
+ opt_limit_clause {}
+ | FROM DUAL_SYM /* oracle compatibility: oracle always requires FROM
+ clause, and DUAL is system table without fields.
+ Is "SELECT 1 FROM DUAL" any better than
+ "SELECT 1" ? Hmmm :) */
+ | into
| select_from
- | FROM DUAL_SYM
- | opt_into
- | opt_into select_from
- | select_from opt_into;
+ | into select_from
+ | select_from into;
select_from:
- FROM join_table_list where_clause group_clause having_clause opt_order_clause limit_clause procedure_clause;
-
+ FROM join_table_list where_clause group_clause having_clause opt_order_clause opt_limit_clause procedure_clause;
select_options:
/* empty*/
@@ -2460,7 +2464,7 @@ join_table:
}
| '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}'
{ add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; }
- | '(' SELECT_SYM select_part3 ')' opt_table_alias
+ | '(' SELECT_SYM select_derived ')' opt_table_alias
{
LEX *lex=Lex;
SELECT_LEX_UNIT *unit= lex->current_select->master_unit();
@@ -2471,7 +2475,7 @@ join_table:
YYABORT;
};
-select_part3:
+select_derived:
{
LEX *lex= Lex;
lex->derived_tables= true;
@@ -2481,11 +2485,8 @@ select_part3:
mysql_init_select(lex);
lex->current_select->linkage= DERIVED_TABLE_TYPE;
}
- select_options select_item_list select_intoto;
-
-select_intoto:
- limit_clause {}
- | select_from;
+ select_options select_item_list opt_select_from
+ ;
opt_outer:
/* empty */ {}
@@ -2675,7 +2676,7 @@ order_dir:
| DESC { $$ =0; };
-limit_clause:
+opt_limit_clause:
/* empty */ {}
| LIMIT
{
@@ -2792,7 +2793,7 @@ select_var_ident: '@' ident_or_text
}
;
-opt_into:
+into:
INTO OUTFILE TEXT_STRING
{
LEX *lex=Lex;
@@ -2904,7 +2905,7 @@ insert:
{
Select->set_lock_for_tables($3);
}
- insert_field_spec
+ insert_field_spec opt_insert_update
;
replace:
@@ -2977,7 +2978,7 @@ insert_values:
mysql_init_select(lex);
}
select_options select_item_list select_from select_lock_type
- union {}
+ union_clause {}
;
values_list:
@@ -3042,6 +3043,11 @@ expr_or_default:
| DEFAULT {$$= new Item_default(); }
;
+opt_insert_update:
+ /* empty */
+ | ON DUPLICATE KEY_SYM UPDATE_SYM SET update_list
+ ;
+
/* Update rows in a table */
update:
@@ -3215,7 +3221,7 @@ show_param:
lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS;
lex->select_lex.select_limit= lex->thd->variables.select_limit;
lex->select_lex.offset_limit= 0L;
- } limit_clause
+ } opt_limit_clause
| keys_or_index FROM table_ident opt_db
{
Lex->sql_command= SQLCOM_SHOW_KEYS;
@@ -3243,9 +3249,9 @@ show_param:
{ (void) create_select_for_variable("warning_count"); }
| COUNT_SYM '(' '*' ')' ERRORS
{ (void) create_select_for_variable("error_count"); }
- | WARNINGS {Select->offset_limit=0L;} limit_clause
+ | WARNINGS {Select->offset_limit=0L;} opt_limit_clause
{ Lex->sql_command = SQLCOM_SHOW_WARNS;}
- | ERRORS {Select->offset_limit=0L;} limit_clause
+ | ERRORS {Select->offset_limit=0L;} opt_limit_clause
{ Lex->sql_command = SQLCOM_SHOW_ERRORS;}
| STATUS_SYM wild
{ Lex->sql_command= SQLCOM_SHOW_STATUS; }
@@ -3997,7 +4003,7 @@ handler:
if (!lex->current_select->add_table_to_list($2, 0, 0))
YYABORT;
}
- handler_read_or_scan where_clause limit_clause { }
+ handler_read_or_scan where_clause opt_limit_clause { }
;
handler_read_or_scan:
@@ -4326,7 +4332,7 @@ rollback:
*/
-union:
+union_clause:
/* empty */ {}
| union_list
;
@@ -4378,7 +4384,7 @@ optional_order_or_limit:
lex->current_select->select_limit=
lex->thd->variables.select_limit;
}
- opt_order_clause limit_clause
+ opt_order_clause opt_limit_clause
;
union_option:
@@ -4393,7 +4399,7 @@ singleval_subselect:
};
singleval_subselect_init:
- select_init
+ select_init2
{
$$= new Item_singleval_subselect(YYTHD,
Lex->current_select->master_unit()->
@@ -4408,7 +4414,7 @@ exists_subselect:
};
exists_subselect_init:
- select_init
+ select_init2
{
$$= new Item_exists_subselect(YYTHD,
Lex->current_select->master_unit()->
@@ -4423,13 +4429,13 @@ in_subselect:
};
in_subselect_init:
- select_init
+ select_init2
{
$$= Lex->current_select->master_unit()->first_select();
};
subselect_start:
- '('
+ '(' SELECT_SYM
{
if (mysql_new_select(Lex, 1))
YYABORT;
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index be4fdc9cb8d..b487159a733 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -18,6 +18,8 @@
#include "m_string.h"
#include "m_ctype.h"
#include "my_sys.h" /* defines errno */
+#include <errno.h>
+
#include "stdarg.h"
#include "assert.h"
@@ -246,8 +248,6 @@ void my_hash_sort_simple(CHARSET_INFO *cs,
}
-#define MY_ERRNO(y)
-
long my_strntol_8bit(CHARSET_INFO *cs,
const char *nptr, uint l, char **endptr, int base)
{
@@ -349,14 +349,14 @@ long my_strntol_8bit(CHARSET_INFO *cs,
if (overflow)
{
- MY_ERRNO(ERANGE);
+ my_errno=(ERANGE);
return negative ? LONG_MIN : LONG_MAX;
}
return (negative ? -((long) i) : (long) i);
noconv:
- MY_ERRNO(EDOM);
+ my_errno=(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
@@ -455,14 +455,14 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs,
if (overflow)
{
- MY_ERRNO(ERANGE);
+ my_errno=(ERANGE);
return ((ulong)~0L);
}
return (negative ? -((long) i) : (long) i);
noconv:
- MY_ERRNO(EDOM);
+ my_errno=(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
@@ -570,14 +570,14 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
if (overflow)
{
- MY_ERRNO(ERANGE);
+ my_errno=(ERANGE);
return negative ? LONGLONG_MIN : LONGLONG_MAX;
}
return (negative ? -((longlong) i) : (longlong) i);
noconv:
- MY_ERRNO(EDOM);
+ my_errno=(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
@@ -677,14 +677,14 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
if (overflow)
{
- MY_ERRNO(ERANGE);
+ my_errno=(ERANGE);
return (~(ulonglong) 0);
}
return (negative ? -((longlong) i) : (longlong) i);
noconv:
- MY_ERRNO(EDOM);
+ my_errno=(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;