Commit c1527b6f authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

Merge sanja.is.com.ua:/home/bell/mysql/mysql-4.1

into sanja.is.com.ua:/home/bell/mysql/work-row-4.1
parents eb512dce f60e47fd
...@@ -4199,7 +4199,7 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number, ...@@ -4199,7 +4199,7 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number,
static void fetch_result_tinyint(MYSQL_BIND *param, uchar **row) static void fetch_result_tinyint(MYSQL_BIND *param, uchar **row)
{ {
*param->buffer= (uchar) **row; *param->buffer= (uchar) **row;
*row++; (*row)++;
} }
static void fetch_result_short(MYSQL_BIND *param, uchar **row) static void fetch_result_short(MYSQL_BIND *param, uchar **row)
......
...@@ -335,30 +335,35 @@ void *tree_search_key(TREE *tree, const void *key, ...@@ -335,30 +335,35 @@ void *tree_search_key(TREE *tree, const void *key,
enum ha_rkey_function flag, void *custom_arg) enum ha_rkey_function flag, void *custom_arg)
{ {
int cmp; int cmp;
TREE_ELEMENT *element = tree->root; TREE_ELEMENT *element= tree->root;
TREE_ELEMENT **last_left_step_parent = NULL; TREE_ELEMENT **last_left_step_parent= NULL, **last_right_step_parent= NULL;
TREE_ELEMENT **last_equal_element = NULL; TREE_ELEMENT **last_equal_element= NULL;
/* /*
TODO: handle HA_READ_KEY_OR_PREV, HA_READ_BEFORE_KEY, HA_READ_PREFIX, TODO: support for HA_READ_KEY_OR_PREV, HA_READ_PREFIX flags if needed.
HA_READ_PREFIX_LAST flags if needed.
*/ */
*parents = &tree->null_element; *parents = &tree->null_element;
while (element != &tree->null_element) while (element != &tree->null_element)
{ {
*++parents = element; *++parents= element;
if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element), if ((cmp= (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element),
key)) == 0) key)) == 0)
{ {
switch (flag) { switch (flag) {
case HA_READ_KEY_EXACT: case HA_READ_KEY_EXACT:
case HA_READ_KEY_OR_NEXT: case HA_READ_KEY_OR_NEXT:
last_equal_element = parents; case HA_READ_BEFORE_KEY:
cmp = 1; last_equal_element= parents;
cmp= 1;
break; break;
case HA_READ_AFTER_KEY: case HA_READ_AFTER_KEY:
cmp = -1; cmp= -1;
break;
case HA_READ_PREFIX_LAST:
case HA_READ_PREFIX_LAST_OR_PREV:
last_equal_element= parents;
cmp= -1;
break; break;
default: default:
return NULL; return NULL;
...@@ -366,23 +371,31 @@ void *tree_search_key(TREE *tree, const void *key, ...@@ -366,23 +371,31 @@ void *tree_search_key(TREE *tree, const void *key,
} }
if (cmp < 0) /* element < key */ if (cmp < 0) /* element < key */
{ {
element = element->right; last_right_step_parent= parents;
element= element->right;
} }
else else
{ {
last_left_step_parent = parents; last_left_step_parent= parents;
element = element->left; element= element->left;
} }
} }
switch (flag) { switch (flag) {
case HA_READ_KEY_EXACT: case HA_READ_KEY_EXACT:
*last_pos = last_equal_element; case HA_READ_PREFIX_LAST:
*last_pos= last_equal_element;
break; break;
case HA_READ_KEY_OR_NEXT: 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; break;
case HA_READ_AFTER_KEY: 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; break;
default: default:
return NULL; return NULL;
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include
noinst_LIBRARIES = libregex.a 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 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 libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
noinst_PROGRAMS = re noinst_PROGRAMS = re
......
...@@ -15,16 +15,6 @@ ...@@ -15,16 +15,6 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 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 ** This file implements classes defined in field.h
*****************************************************************************/ *****************************************************************************/
...@@ -1592,7 +1582,6 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -1592,7 +1582,6 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
} }
long tmp; long tmp;
int error= 0; int error= 0;
String tmp_str(from,len,default_charset_info);
errno=0; errno=0;
if (unsigned_flag) if (unsigned_flag)
{ {
...@@ -1603,10 +1592,10 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -1603,10 +1592,10 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
error= 1; error= 1;
} }
else else
tmp=(long) strtoul(tmp_str.c_ptr(),NULL,10); tmp=(long) my_strntoul(cs,from,len,NULL,10);
} }
else 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)) if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
{ {
current_thd->cuted_fields++; current_thd->cuted_fields++;
...@@ -1837,7 +1826,6 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -1837,7 +1826,6 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
len--; from++; len--; from++;
} }
longlong tmp; longlong tmp;
String tmp_str(from,len,default_charset_info);
int error= 0; int error= 0;
errno=0; errno=0;
if (unsigned_flag) if (unsigned_flag)
...@@ -1849,10 +1837,10 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -1849,10 +1837,10 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
error= 1; error= 1;
} }
else else
tmp=(longlong) strtoull(tmp_str.c_ptr(),NULL,10); tmp=(longlong) my_strntoull(cs,from,len,NULL,10);
} }
else 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)) if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
{ {
current_thd->cuted_fields++; current_thd->cuted_fields++;
...@@ -2052,9 +2040,8 @@ void Field_longlong::sql_type(String &res) const ...@@ -2052,9 +2040,8 @@ void Field_longlong::sql_type(String &res) const
int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
String tmp_str(from,len,default_charset_info);
errno=0; 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)) if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
{ {
current_thd->cuted_fields++; current_thd->cuted_fields++;
...@@ -2314,10 +2301,9 @@ void Field_float::sql_type(String &res) const ...@@ -2314,10 +2301,9 @@ void Field_float::sql_type(String &res) const
int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
String tmp_str(from,len,default_charset_info);
errno=0; errno=0;
int error= 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)) if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
{ {
current_thd->cuted_fields++; current_thd->cuted_fields++;
......
...@@ -81,6 +81,15 @@ int ha_heap::index_read(byte * buf, const byte * key, uint key_len, ...@@ -81,6 +81,15 @@ int ha_heap::index_read(byte * buf, const byte * key, uint key_len,
return error; 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, int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
uint key_len, enum ha_rkey_function find_flag) 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, ...@@ -90,7 +99,6 @@ int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
return error; return error;
} }
int ha_heap::index_next(byte * buf) int ha_heap::index_next(byte * buf)
{ {
statistic_increment(ha_read_next_count,&LOCK_status); statistic_increment(ha_read_next_count,&LOCK_status);
......
...@@ -67,6 +67,7 @@ class ha_heap: public handler ...@@ -67,6 +67,7 @@ class ha_heap: public handler
uint key_len, enum ha_rkey_function find_flag); uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key, int index_read_idx(byte * buf, uint idx, const byte * key,
uint key_len, enum ha_rkey_function find_flag); 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_next(byte * buf);
int index_prev(byte * buf); int index_prev(byte * buf);
int index_first(byte * buf); int index_first(byte * buf);
......
...@@ -542,9 +542,9 @@ public: ...@@ -542,9 +542,9 @@ public:
enum Type type() const { return COPY_STR_ITEM; } enum Type type() const { return COPY_STR_ITEM; }
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
double val() 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() 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*); String *val_str(String*);
void make_field(Send_field *field) { item->make_field(field); } void make_field(Send_field *field) { item->make_field(field); }
void copy(); void copy();
......
...@@ -845,12 +845,12 @@ public: ...@@ -845,12 +845,12 @@ public:
double val() double val()
{ {
String *res; res=val_str(&str_value); 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() longlong val_int()
{ {
String *res; res=val_str(&str_value); 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; } enum Item_result result_type () const { return STRING_RESULT; }
void fix_length_and_dec(); void fix_length_and_dec();
......
...@@ -54,14 +54,14 @@ double Item_str_func::val() ...@@ -54,14 +54,14 @@ double Item_str_func::val()
{ {
String *res; String *res;
res=val_str(&str_value); 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() longlong Item_str_func::val_int()
{ {
String *res; String *res;
res=val_str(&str_value); 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) ...@@ -1905,9 +1905,9 @@ String *Item_func_conv::val_str(String *str)
} }
null_value=0; null_value=0;
if (from_base < 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 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); ptr= longlong2str(dec,ans,to_base);
if (str->copy(ans,(uint32) (ptr-ans), thd_charset())) if (str->copy(ans,(uint32) (ptr-ans), thd_charset()))
return &empty_string; return &empty_string;
......
...@@ -334,7 +334,7 @@ double Item_sum_hybrid::val() ...@@ -334,7 +334,7 @@ double Item_sum_hybrid::val()
switch (hybrid_type) { switch (hybrid_type) {
case STRING_RESULT: case STRING_RESULT:
String *res; res=val_str(&str_value); 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: case INT_RESULT:
if (unsigned_flag) if (unsigned_flag)
return ulonglong2double(sum_int); return ulonglong2double(sum_int);
......
...@@ -442,12 +442,12 @@ public: ...@@ -442,12 +442,12 @@ public:
double val() double val()
{ {
String *res; res=val_str(&str_value); 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() longlong val_int()
{ {
String *res; res=val_str(&str_value); 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; } enum Item_result result_type () const { return STRING_RESULT; }
void fix_length_and_dec(); void fix_length_and_dec();
......
...@@ -135,6 +135,7 @@ static SYMBOL symbols[] = { ...@@ -135,6 +135,7 @@ static SYMBOL symbols[] = {
{ "DROP", SYM(DROP),0,0}, { "DROP", SYM(DROP),0,0},
{ "DUMPFILE", SYM(DUMPFILE),0,0}, { "DUMPFILE", SYM(DUMPFILE),0,0},
{ "DYNAMIC", SYM(DYNAMIC_SYM),0,0}, { "DYNAMIC", SYM(DYNAMIC_SYM),0,0},
{ "DUPLICATE", SYM(DUPLICATE),0,0},
{ "ERRORS", SYM(ERRORS),0,0}, { "ERRORS", SYM(ERRORS),0,0},
{ "END", SYM(END),0,0}, { "END", SYM(END),0,0},
{ "ELSE", SYM(ELSE),0,0}, { "ELSE", SYM(ELSE),0,0},
......
...@@ -1961,25 +1961,19 @@ mysql_execute_command(THD *thd) ...@@ -1961,25 +1961,19 @@ mysql_execute_command(THD *thd)
close_thread_tables(thd); close_thread_tables(thd);
} }
break; break;
case SQLCOM_REPLACE:
case SQLCOM_INSERT: case SQLCOM_INSERT:
if (check_access(thd,INSERT_ACL,tables->db,&tables->grant.privilege)) {
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 */ goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,INSERT_ACL,tables)) if (grant_option && check_grant(thd,privilege,tables))
goto error; goto error;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values, res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
lex->duplicates); lex->duplicates);
break; break;
case SQLCOM_REPLACE: }
if (check_access(thd,INSERT_ACL | DELETE_ACL,
tables->db,&tables->grant.privilege))
goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,INSERT_ACL | DELETE_ACL,
tables))
goto error;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
DUP_REPLACE);
break;
case SQLCOM_REPLACE_SELECT: case SQLCOM_REPLACE_SELECT:
case SQLCOM_INSERT_SELECT: case SQLCOM_INSERT_SELECT:
{ {
...@@ -1989,8 +1983,8 @@ mysql_execute_command(THD *thd) ...@@ -1989,8 +1983,8 @@ mysql_execute_command(THD *thd)
select privileges for the rest select privileges for the rest
*/ */
{ {
ulong privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ? ulong privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL : INSERT_ACL | DELETE_ACL); INSERT_ACL | DELETE_ACL : INSERT_ACL);
TABLE_LIST *save_next=tables->next; TABLE_LIST *save_next=tables->next;
tables->next=0; tables->next=0;
if (check_access(thd, privilege, if (check_access(thd, privilege,
......
This diff is collapsed.
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include "m_string.h" #include "m_string.h"
#include "m_ctype.h" #include "m_ctype.h"
#include "my_sys.h" /* defines errno */ #include "my_sys.h" /* defines errno */
#include <errno.h>
#include "stdarg.h" #include "stdarg.h"
#include "assert.h" #include "assert.h"
...@@ -246,8 +248,6 @@ void my_hash_sort_simple(CHARSET_INFO *cs, ...@@ -246,8 +248,6 @@ void my_hash_sort_simple(CHARSET_INFO *cs,
} }
#define MY_ERRNO(y)
long my_strntol_8bit(CHARSET_INFO *cs, long my_strntol_8bit(CHARSET_INFO *cs,
const char *nptr, uint l, char **endptr, int base) const char *nptr, uint l, char **endptr, int base)
{ {
...@@ -349,14 +349,14 @@ long my_strntol_8bit(CHARSET_INFO *cs, ...@@ -349,14 +349,14 @@ long my_strntol_8bit(CHARSET_INFO *cs,
if (overflow) if (overflow)
{ {
MY_ERRNO(ERANGE); my_errno=(ERANGE);
return negative ? LONG_MIN : LONG_MAX; return negative ? LONG_MIN : LONG_MAX;
} }
return (negative ? -((long) i) : (long) i); return (negative ? -((long) i) : (long) i);
noconv: noconv:
MY_ERRNO(EDOM); my_errno=(EDOM);
if (endptr != NULL) if (endptr != NULL)
*endptr = (char *) nptr; *endptr = (char *) nptr;
return 0L; return 0L;
...@@ -455,14 +455,14 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs, ...@@ -455,14 +455,14 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs,
if (overflow) if (overflow)
{ {
MY_ERRNO(ERANGE); my_errno=(ERANGE);
return ((ulong)~0L); return ((ulong)~0L);
} }
return (negative ? -((long) i) : (long) i); return (negative ? -((long) i) : (long) i);
noconv: noconv:
MY_ERRNO(EDOM); my_errno=(EDOM);
if (endptr != NULL) if (endptr != NULL)
*endptr = (char *) nptr; *endptr = (char *) nptr;
return 0L; return 0L;
...@@ -570,14 +570,14 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), ...@@ -570,14 +570,14 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
if (overflow) if (overflow)
{ {
MY_ERRNO(ERANGE); my_errno=(ERANGE);
return negative ? LONGLONG_MIN : LONGLONG_MAX; return negative ? LONGLONG_MIN : LONGLONG_MAX;
} }
return (negative ? -((longlong) i) : (longlong) i); return (negative ? -((longlong) i) : (longlong) i);
noconv: noconv:
MY_ERRNO(EDOM); my_errno=(EDOM);
if (endptr != NULL) if (endptr != NULL)
*endptr = (char *) nptr; *endptr = (char *) nptr;
return 0L; return 0L;
...@@ -677,14 +677,14 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, ...@@ -677,14 +677,14 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
if (overflow) if (overflow)
{ {
MY_ERRNO(ERANGE); my_errno=(ERANGE);
return (~(ulonglong) 0); return (~(ulonglong) 0);
} }
return (negative ? -((longlong) i) : (longlong) i); return (negative ? -((longlong) i) : (longlong) i);
noconv: noconv:
MY_ERRNO(EDOM); my_errno=(EDOM);
if (endptr != NULL) if (endptr != NULL)
*endptr = (char *) nptr; *endptr = (char *) nptr;
return 0L; return 0L;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment