diff options
-rw-r--r-- | libmysql/libmysql.c | 2 | ||||
-rw-r--r-- | mysys/tree.c | 53 | ||||
-rw-r--r-- | regex/Makefile.am | 2 | ||||
-rw-r--r-- | sql/field.cc | 26 | ||||
-rw-r--r-- | sql/ha_heap.cc | 10 | ||||
-rw-r--r-- | sql/ha_heap.h | 1 | ||||
-rw-r--r-- | sql/item.h | 4 | ||||
-rw-r--r-- | sql/item_func.h | 4 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 8 | ||||
-rw-r--r-- | sql/item_sum.cc | 2 | ||||
-rw-r--r-- | sql/item_sum.h | 4 | ||||
-rw-r--r-- | sql/lex.h | 3 | ||||
-rw-r--r-- | sql/sql_parse.cc | 34 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 140 | ||||
-rw-r--r-- | strings/ctype-simple.c | 20 |
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; |