summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-02-16 10:03:25 +0200
committerunknown <monty@mysql.com>2004-02-16 10:03:25 +0200
commita07e48eca04b1564da9868f229ba5d958994db69 (patch)
tree44dc172194086edaeef7da9c9ed059171579a886 /sql
parent5b2c3126277a8eedab5bcc8a9b0ce7386ccc3dbe (diff)
downloadmariadb-git-a07e48eca04b1564da9868f229ba5d958994db69.tar.gz
After merge fixes
Added more DBUG statements Ensure that we are comparing end space with BINARY strings Use 'any_db' instead of '' to mean any database. (For HANDLER command) Only strip ' ' when comparing CHAR, not other space-like characters (like \t) BitKeeper/deleted/.del-ctype_tis620.result-old~3578ceb0b8284685: Delete: mysql-test/r/ctype_tis620.result-old BitKeeper/deleted/.del-ctype_tis620.test-old~ffb1bbd2935d1aba: Delete: mysql-test/t/ctype_tis620.test-old client/mysqlbinlog.cc: Added DBUG statements Added call of my_end() to free all used memory on exit heap/hp_info.c: After merge fixes heap/hp_open.c: After merge fixes include/heap.h: After merge fixes include/m_ctype.h: Use pchar instead of 'int' for character parameters. Added 'my_binary_compare()' include/m_string.h: Fixed wrong define innobase/ibuf/ibuf0ibuf.c: After merge fixes innobase/srv/srv0start.c: After merge fixes mysql-test/r/alter_table.result: Fixed results after merge mysql-test/r/auto_increment.result: Fixed results after merge mysql-test/r/bdb.result: Fixed results after merge mysql-test/r/binary.result: Fixed results after merge mysql-test/r/create.result: Fixed results after merge mysql-test/r/ctype_mb.result: Fixed results after merge mysql-test/r/ctype_tis620.result: Fixed results after merge mysql-test/r/ctype_utf8.result: Fixed results after merge mysql-test/r/delete.result: Fixed results after merge mysql-test/r/func_compress.result: Fixed results after merge mysql-test/r/func_gconcat.result: Fixed results after merge mysql-test/r/func_group.result: Fixed results after merge mysql-test/r/func_str.result: Fixed results after merge mysql-test/r/innodb.result: Fixed results after merge mysql-test/r/insert.result: Fixed results after merge mysql-test/r/insert_select.result: Fixed results after merge mysql-test/r/key.result: Fixed results after merge mysql-test/r/loaddata.result: Fixed results after merge mysql-test/r/lock.result: Fixed results after merge mysql-test/r/myisam.result: Fixed results after merge mysql-test/r/null.result: Fixed results after merge mysql-test/r/null_key.result: Fixed results after merge mysql-test/r/order_by.result: Fixed results after merge mysql-test/r/query_cache.result: Fixed results after merge mysql-test/r/range.result: Fixed results after merge mysql-test/r/rpl_multi_delete.result: Fixed results after merge mysql-test/r/rpl_until.result: Fixed results after merge mysql-test/r/subselect.result: Fixed results after merge mysql-test/r/subselect_innodb.result: Fixed results after merge mysql-test/r/type_blob.result: Fixed results after merge mysql-test/r/type_datetime.result: Fixed results after merge mysql-test/r/type_decimal.result: Fixed results after merge mysql-test/r/type_enum.result: Fixed results after merge mysql-test/r/type_float.result: Fixed results after merge mysql-test/r/type_ranges.result: Fixed results after merge mysql-test/r/type_time.result: Fixed results after merge mysql-test/r/type_timestamp.result: Fixed results after merge mysql-test/r/type_uint.result: Fixed results after merge mysql-test/r/type_year.result: Fixed results after merge mysql-test/r/variables.result: Fixed results after merge mysql-test/r/warnings.result: Fixed results after merge mysql-test/t/case.test: Fixed shifted error messages mysql-test/t/create.test: Fixed shifted error messages mysql-test/t/ctype_collate.test: Fixed shifted error messages mysql-test/t/ctype_tis620.test: Merge with 4.0 ctype_tis620 test mysql-test/t/delete.test: Fixed shifted error messages mysql-test/t/derived.test: Fixed shifted error messages mysql-test/t/fulltext.test: Fixed shifted error messages mysql-test/t/func_in.test: Fixed shifted error messages mysql-test/t/func_str.test: Fixed shifted error messages mysql-test/t/func_test.test: Fixed shifted error messages mysql-test/t/grant.test: Fixed shifted error messages mysql-test/t/innodb.test: Change to 4.1 syntax mysql-test/t/key_cache.test: Fixed shifted error messages mysql-test/t/myisam.test: New test of blob and end space mysql-test/t/row.test: Fixed shifted error messages mysql-test/t/rpl_until.test: Fixed shifted error messages mysql-test/t/subselect.test: Fixed shifted error messages mysql-test/t/subselect_innodb.test: Fix test to take into account foreign key constraints mysql-test/t/union.test: Fixed shifted error messages mysql-test/t/user_var.test: Fixed shifted error messages mysql-test/t/variables.test: Fixed shifted error messages mysys/my_handler.c: Merge with 4.0 code sql/ha_heap.cc: After merge fixes sql/handler.cc: After merge fixes sql/item.cc: After merge fixes sql/item_cmpfunc.cc: Ensure that we are comparing end space with BINARY strings sql/item_cmpfunc.h: Ensure that we are comparing end space with BINARY strings sql/log_event.cc: More DBUG statements Ensure that we use all options to LOAD DATA in replication sql/opt_range.cc: After merge fixes sql/sql_db.cc: After merge fixes sql/sql_handler.cc: After merge fixes Use 'any_db' instead of '' to mean 'no database comparison' sql/sql_parse.cc: After merge fixes sql/sql_select.cc: After merge fixes Added function comment for setup_group() sql/sql_string.cc: Added stringcmp() for binary comparison. Added function comments for sortcmp() and stringcmp() sql/sql_string.h: Added stringcmp() sql/sql_table.cc: After merge fixes sql/sql_update.cc: After merge fixes sql/sql_yacc.yy: Use 'any_db' instead of '' to mean any database. Using "" causes a 'wrong db name' error. strings/ctype-big5.c: Strip only end space, not other space characters. strings/ctype-bin.c: Removed some not needed functions. Added function comments Don't remove end space in comparisons Change my_wildcmp_bin() to be 'identical' with other similar code strings/ctype-czech.c: Strip only end space, not other space characters. strings/ctype-gbk.c: Strip only end space, not other space characters. strings/ctype-latin1.c: Strip only end space, not other space characters. strings/ctype-mb.c: Strip only end space, not other space characters. strings/ctype-simple.c: Strip only end space, not other space characters. strings/ctype-sjis.c: Strip only end space, not other space characters. strings/ctype-tis620.c: Added usage of my_instr_simple. This needs to be cleaned up! strings/ctype-utf8.c: Strip only end space, not other space characters. strings/ctype-win1250ch.c: Strip only end space, not other space characters. Fixed indentation strings/strto.c: Code cleanup
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_heap.cc4
-rw-r--r--sql/handler.cc4
-rw-r--r--sql/item.cc5
-rw-r--r--sql/item_cmpfunc.cc57
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/log_event.cc140
-rw-r--r--sql/opt_range.cc4
-rw-r--r--sql/sql_db.cc2
-rw-r--r--sql/sql_handler.cc4
-rw-r--r--sql/sql_parse.cc13
-rw-r--r--sql/sql_select.cc28
-rw-r--r--sql/sql_string.cc51
-rw-r--r--sql/sql_string.h1
-rw-r--r--sql/sql_table.cc4
-rw-r--r--sql/sql_update.cc9
-rw-r--r--sql/sql_yacc.yy4
16 files changed, 230 insertions, 102 deletions
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index 656224d4a7a..807b6e35a29 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -38,7 +38,10 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
HA_CREATE_INFO create_info;
bzero(&create_info, sizeof(create_info));
if (!create(name, table, &create_info))
+ {
file= heap_open(name, mode);
+ implicit_emptied= 1;
+ }
}
ref_length= sizeof(HEAP_PTR);
return (file ? 0 : 1);
@@ -174,7 +177,6 @@ void ha_heap::info(uint flag)
index_file_length=info.index_length;
max_data_file_length= info.max_records* info.reclength;
delete_length= info.deleted * info.reclength;
- implicit_emptied= info.implicit_emptied;
if (flag & HA_STATUS_AUTO)
auto_increment_value= info.auto_increment;
}
diff --git a/sql/handler.cc b/sql/handler.cc
index afeec26f034..5aa3967edb6 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -657,7 +657,7 @@ int ha_delete_table(enum db_type table_type, const char *path)
{
/* Ensure that table handler get path in lower case */
strmov(tmp_path, path);
- casedn_str(tmp_path);
+ my_casedn_str(system_charset_info, tmp_path);
path= tmp_path;
}
int error=file->delete_table(path);
@@ -1159,7 +1159,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
{
/* Ensure that handler gets name in lower case */
strmov(name_buff, name);
- casedn_str(name_buff);
+ my_casedn_str(system_charset_info, name_buff);
name= name_buff;
}
diff --git a/sql/item.cc b/sql/item.cc
index 4d06d0d7765..b9a6a164a86 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -175,12 +175,13 @@ bool Item::eq(const Item *item, bool binary_cmp) const
!my_strcasecmp(system_charset_info,name,item->name);
}
+
bool Item_string::eq(const Item *item, bool binary_cmp) const
{
if (type() == item->type())
{
if (binary_cmp)
- return !sortcmp(&str_value, &item->str_value, &my_charset_bin);
+ return !stringcmp(&str_value, &item->str_value);
return !sortcmp(&str_value, &item->str_value, collation.collation);
}
return 0;
@@ -1823,7 +1824,7 @@ bool field_is_equal_to_item(Field *field,Item *item)
if (item->null_value)
return 1; // This must be true
field->val_str(&field_tmp,&field_tmp);
- return !sortcmp(&field_tmp,item_result,&my_charset_bin);
+ return !stringcmp(&field_tmp,item_result);
}
if (res_type == INT_RESULT)
return 1; // Both where of type int
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 4046a4d6414..1bba934cf8f 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -293,6 +293,17 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
return 1;
}
+ if (my_binary_compare(cmp_collation.collation))
+ {
+ /*
+ We are using binary collation, change to compare byte by byte,
+ without removing end space
+ */
+ if (func == &Arg_comparator::compare_string)
+ func= &Arg_comparator::compare_binary_string;
+ else if (func == &Arg_comparator::compare_e_string)
+ func= &Arg_comparator::compare_e_binary_string;
+ }
}
return 0;
}
@@ -313,6 +324,39 @@ int Arg_comparator::compare_string()
return -1;
}
+
+/*
+ Compare strings byte by byte. End spaces are also compared.
+
+ RETURN
+ < 0 *a < *b
+ 0 *b == *b
+ > 0 *a > *b
+*/
+
+int Arg_comparator::compare_binary_string()
+{
+ String *res1,*res2;
+ if ((res1= (*a)->val_str(&owner->tmp_value1)))
+ {
+ if ((res2= (*b)->val_str(&owner->tmp_value2)))
+ {
+ owner->null_value= 0;
+ uint res1_length= res1->length();
+ uint res2_length= res2->length();
+ int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
+ return cmp ? cmp : (int) (res1_length - res2_length);
+ }
+ }
+ owner->null_value= 1;
+ return -1;
+}
+
+
+/*
+ Compare strings, but take into account that NULL == NULL
+*/
+
int Arg_comparator::compare_e_string()
{
String *res1,*res2;
@@ -324,6 +368,17 @@ int Arg_comparator::compare_e_string()
}
+int Arg_comparator::compare_e_binary_string()
+{
+ String *res1,*res2;
+ res1= (*a)->val_str(&owner->tmp_value1);
+ res2= (*b)->val_str(&owner->tmp_value2);
+ if (!res1 || !res2)
+ return test(res1 == res2);
+ return test(stringcmp(res1, res2) == 0);
+}
+
+
int Arg_comparator::compare_real()
{
double val1= (*a)->val();
@@ -2132,7 +2187,7 @@ longlong Item_func_regex::val_int()
null_value=1;
return 0;
}
- if (!regex_compiled || sortcmp(res2,&prev_regexp,&my_charset_bin))
+ if (!regex_compiled || stringcmp(res2,&prev_regexp))
{
prev_regexp.copy(*res2);
if (regex_compiled)
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 4e9628c8db9..3c70a50502a 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -63,10 +63,12 @@ public:
inline int compare() { return (this->*func)(); }
int compare_string(); // compare args[0] & args[1]
+ int compare_binary_string(); // compare args[0] & args[1]
int compare_real(); // compare args[0] & args[1]
int compare_int(); // compare args[0] & args[1]
int compare_row(); // compare args[0] & args[1]
int compare_e_string(); // compare args[0] & args[1]
+ int compare_e_binary_string(); // compare args[0] & args[1]
int compare_e_real(); // compare args[0] & args[1]
int compare_e_int(); // compare args[0] & args[1]
int compare_e_row(); // compare args[0] & args[1]
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 84757a0a1f2..f64f740da30 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (C) 2000-2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -290,6 +290,8 @@ Log_event::Log_event(const char* buf, bool old_format)
int Log_event::exec_event(struct st_relay_log_info* rli)
{
+ DBUG_ENTER("Log_event::exec_event");
+
/*
rli is null when (as far as I (Guilhem) know)
the caller is
@@ -342,7 +344,7 @@ int Log_event::exec_event(struct st_relay_log_info* rli)
rli->last_master_timestamp= when;
}
}
- return 0;
+ DBUG_RETURN(0);
}
@@ -592,11 +594,13 @@ Error in Log_event::read_log_event(): '%s', data_len: %d, event_type: %d",
Log_event* Log_event::read_log_event(const char* buf, int event_len,
const char **error, bool old_format)
{
+ DBUG_ENTER("Log_event::read_log_event");
+
if (event_len < EVENT_LEN_OFFSET ||
(uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
{
*error="Sanity check failed"; // Needed to free buffer
- return NULL; // general sanity check - will fail on a partial read
+ DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
}
Log_event* ev = NULL;
@@ -658,16 +662,16 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len,
if (!force_opt)
{
*error= "Found invalid event in binary log";
- return 0;
+ DBUG_RETURN(0);
}
ev= new Unknown_log_event(buf, old_format);
#else
*error= "Found invalid event in binary log";
- return 0;
+ DBUG_RETURN(0);
#endif
}
ev->cached_event_len = event_len;
- return ev;
+ DBUG_RETURN(ev);
}
#ifdef MYSQL_CLIENT
@@ -1249,38 +1253,21 @@ void Load_log_event::pack_info(Protocol *protocol)
memcpy(pos, table_name, table_name_len);
pos+= table_name_len;
- if (sql_ex.field_term_len)
- {
- pos= strmov(pos, " FIELDS TERMINATED BY ");
- pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
- }
-
- if (sql_ex.enclosed_len)
- {
- if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
- pos= strmov(pos, " OPTIONALLY ");
- pos= strmov(pos, " ENCLOSED BY ");
- pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
- }
+ /* We have to create all optinal fields as the default is not empty */
+ pos= strmov(pos, " FIELDS TERMINATED BY ");
+ pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
+ if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
+ pos= strmov(pos, " OPTIONALLY ");
+ pos= strmov(pos, " ENCLOSED BY ");
+ pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
- if (sql_ex.escaped_len)
- {
- pos= strmov(pos, " ESCAPED BY ");
- pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
- }
-
- bool line_lexem_added= false;
- if (sql_ex.line_term_len)
- {
- pos= strmov(pos, " LINES TERMINATED BY ");
- pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
- line_lexem_added= true;
- }
+ pos= strmov(pos, " ESCAPED BY ");
+ pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
+ pos= strmov(pos, " LINES TERMINATED BY ");
+ pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
if (sql_ex.line_start_len)
{
- if (!line_lexem_added)
- pos= strmov(pos," LINES");
pos= strmov(pos, " STARTING BY ");
pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
}
@@ -1455,9 +1442,10 @@ Load_log_event::Load_log_event(const char *buf, int event_len,
field_lens(0), field_block_len(0),
table_name(0), db(0), fname(0), local_fname(FALSE)
{
- if (!event_len) // derived class, will call copy_log_event() itself
- return;
- copy_log_event(buf, event_len, old_format);
+ DBUG_ENTER("Load_log_event");
+ if (event_len) // derived class, will call copy_log_event() itself
+ copy_log_event(buf, event_len, old_format);
+ DBUG_VOID_RETURN;
}
@@ -1472,6 +1460,8 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
char* buf_end = (char*)buf + event_len;
uint header_len= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
const char* data_head = buf + header_len;
+ DBUG_ENTER("Load_log_event::copy_log_event");
+
slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
@@ -1484,19 +1474,19 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
get_data_body_offset());
if ((int) event_len < body_offset)
- return 1;
+ DBUG_RETURN(1);
/*
Sql_ex.init() on success returns the pointer to the first byte after
the sql_ex structure, which is the start of field lengths array.
*/
if (!(field_lens=(uchar*)sql_ex.init((char*)buf + body_offset,
- buf_end,
- buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
- return 1;
-
+ buf_end,
+ buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
+ DBUG_RETURN(1);
+
data_len = event_len - body_offset;
if (num_fields > data_len) // simple sanity check against corruption
- return 1;
+ DBUG_RETURN(1);
for (uint i = 0; i < num_fields; i++)
field_block_len += (uint)field_lens[i] + 1;
@@ -1506,7 +1496,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
fname = db + db_len + 1;
fname_len = strlen(fname);
// null termination is accomplished by the caller doing buf[event_len]=0
- return 0;
+ DBUG_RETURN(0);
}
@@ -1524,6 +1514,7 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db)
void Load_log_event::print(FILE* file, bool short_form, char* last_db,
bool commented)
{
+ DBUG_ENTER("Load_log_event::print");
if (!short_form)
{
print_header(file);
@@ -1555,42 +1546,26 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db,
fprintf(file," IGNORE ");
fprintf(file, "INTO TABLE %s ", table_name);
- if (sql_ex.field_term)
- {
- fprintf(file, " FIELDS TERMINATED BY ");
- pretty_print_str(file, sql_ex.field_term, sql_ex.field_term_len);
- }
+ fprintf(file, " FIELDS TERMINATED BY ");
+ pretty_print_str(file, sql_ex.field_term, sql_ex.field_term_len);
- if (sql_ex.enclosed)
- {
- if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
- fprintf(file," OPTIONALLY ");
- fprintf(file, " ENCLOSED BY ");
- pretty_print_str(file, sql_ex.enclosed, sql_ex.enclosed_len);
- }
+ if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
+ fprintf(file," OPTIONALLY ");
+ fprintf(file, " ENCLOSED BY ");
+ pretty_print_str(file, sql_ex.enclosed, sql_ex.enclosed_len);
- if (sql_ex.escaped)
- {
- fprintf(file, " ESCAPED BY ");
- pretty_print_str(file, sql_ex.escaped, sql_ex.escaped_len);
- }
+ fprintf(file, " ESCAPED BY ");
+ pretty_print_str(file, sql_ex.escaped, sql_ex.escaped_len);
- bool line_lexem_added= false;
- if (sql_ex.line_term)
- {
- fprintf(file," LINES TERMINATED BY ");
- pretty_print_str(file, sql_ex.line_term, sql_ex.line_term_len);
- line_lexem_added= true;
- }
+ fprintf(file," LINES TERMINATED BY ");
+ pretty_print_str(file, sql_ex.line_term, sql_ex.line_term_len);
+
if (sql_ex.line_start)
{
- if (!line_lexem_added)
- fprintf(file," LINES");
fprintf(file," STARTING BY ");
pretty_print_str(file, sql_ex.line_start, sql_ex.line_start_len);
}
-
if ((long) skip_lines > 0)
fprintf(file, " IGNORE %ld LINES", (long) skip_lines);
@@ -1611,6 +1586,7 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db,
}
fprintf(file, ";\n");
+ DBUG_VOID_RETURN;
}
#endif /* MYSQL_CLIENT */
@@ -1877,8 +1853,11 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
// The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
int header_size = (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
uint ident_offset;
+ DBUG_ENTER("Rotate_log_event");
+
if (event_len < header_size)
- return;
+ DBUG_VOID_RETURN;
+
buf += header_size;
if (old_format)
{
@@ -1897,8 +1876,9 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
ident_offset,
(uint) ident_len,
MYF(MY_WME))))
- return;
+ DBUG_VOID_RETURN;
alloced = 1;
+ DBUG_VOID_RETURN;
}
@@ -2593,7 +2573,9 @@ Create_file_log_event(THD* thd_arg, sql_exchange* ex,
fake_base(0),block(block_arg),block_len(block_len_arg),
file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
{
+ DBUG_ENTER("Create_file_log_event");
sql_ex.force_new_format();
+ DBUG_VOID_RETURN;
}
#endif /* !MYSQL_CLIENT */
@@ -2650,8 +2632,10 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len,
:Load_log_event(buf,0,old_format),fake_base(0),block(0),inited_from_old(0)
{
int block_offset;
+ DBUG_ENTER("Create_file_log_event");
+
if (copy_log_event(buf,len,old_format))
- return;
+ DBUG_VOID_RETURN;
if (!old_format)
{
file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN +
@@ -2669,6 +2653,7 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len,
sql_ex.force_new_format();
inited_from_old = 1;
}
+ DBUG_VOID_RETURN;
}
@@ -2821,11 +2806,13 @@ Append_block_log_event::Append_block_log_event(THD* thd_arg, const char* db_arg,
Append_block_log_event::Append_block_log_event(const char* buf, int len)
:Log_event(buf, 0),block(0)
{
+ DBUG_ENTER("Append_block_log_event");
if ((uint)len < APPEND_BLOCK_EVENT_OVERHEAD)
- return;
+ DBUG_VOID_RETURN;
file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + AB_FILE_ID_OFFSET);
block = (char*)buf + APPEND_BLOCK_EVENT_OVERHEAD;
block_len = len - APPEND_BLOCK_EVENT_OVERHEAD;
+ DBUG_VOID_RETURN;
}
@@ -2888,6 +2875,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
char *p= slave_load_file_stem(fname, file_id, server_id);
int fd;
int error = 1;
+ DBUG_ENTER("Append_block_log_event::exec_event");
memcpy(p, ".data", 6);
if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0)
@@ -2905,7 +2893,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
err:
if (fd >= 0)
my_close(fd, MYF(0));
- return error ? error : Log_event::exec_event(rli);
+ DBUG_RETURN(error ? error : Log_event::exec_event(rli));
}
#endif
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index d1f42ac865e..1dbe883aef4 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1064,8 +1064,8 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
like_error= my_like_range(field->charset(),
res->ptr(), res->length(),
- ((Item_func_like*)(param->cond))->escape
- wild_prefix, wild_one, wild_many,
+ ((Item_func_like*)(param->cond))->escape,
+ wild_one, wild_many,
field_length,
min_str+offset, max_str+offset,
&min_length, &max_length);
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 7a1fd091e7c..0323e90a166 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -363,7 +363,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
{
/* Convert database to lower case */
strmov(tmp_db, db);
- casedn_str(tmp_db);
+ my_casedn_str(system_charset_info, tmp_db);
db= tmp_db;
}
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 6db97ab3c41..d0f241b3291 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -288,12 +288,12 @@ static TABLE **find_table_ptr_by_name(THD *thd, const char *db,
TABLE **ptr;
DBUG_ASSERT(db);
- dblen= *db ? strlen(db)+1 : 0;
+ dblen= strlen(db);
ptr= &(thd->handler_tables);
for (TABLE *table= *ptr; table ; table= *ptr)
{
- if ((!dblen || !memcmp(table->table_cache_key, db, dblen)) &&
+ if ((db == any_db || !memcmp(table->table_cache_key, db, dblen)) &&
!my_strcasecmp(system_charset_info,
(is_alias ? table->table_name : table->real_name),
table_name))
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f7bbfdae2b3..dd68337d5dd 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1451,7 +1451,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
my_casedn_str(files_charset_info, table_list.real_name);
remove_escape(table_list.real_name); // This can't have wildcards
- if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege))
+ if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege,
+ 0, 0))
break;
if (grant_option && check_grant(thd,SELECT_ACL,&table_list,2,0))
break;
@@ -1771,7 +1772,7 @@ mysql_execute_command(THD *thd)
*/
if (table_rules_on && tables && !tables_ok(thd,tables) &&
((lex->sql_command != SQLCOM_DELETE_MULTI) ||
- !tables_ok(thd,(TABLE_LIST *)thd->lex.auxilliary_table_list.first)))
+ !tables_ok(thd,(TABLE_LIST *)thd->lex->auxilliary_table_list.first)))
{
/* we warn the slave SQL thread */
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
@@ -2103,7 +2104,7 @@ mysql_execute_command(THD *thd)
ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
CREATE_TMP_ACL : CREATE_ACL);
- lex->create_info.alias= tables->alias;
+ lex->create_info.alias= create_table->alias;
if (check_access(thd, want_priv, create_table->db,
&create_table->grant.privilege, 0, 0) ||
check_merge_table_access(thd, create_table->db,
@@ -2872,7 +2873,7 @@ mysql_execute_command(THD *thd)
remove_escape(db); // Fix escaped '_'
remove_escape(tables->real_name);
if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,
- &tables->grant.privilege))
+ &tables->grant.privilege, 0, 0))
goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,SELECT_ACL,tables,2,0))
goto error;
@@ -2977,7 +2978,7 @@ mysql_execute_command(THD *thd)
if (check_access(thd,CREATE_ACL,lex->name,0,1,0))
break;
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name),
- lex->create_info.options,0);
+ &lex->create_info, 0);
break;
}
case SQLCOM_DROP_DB:
@@ -3393,7 +3394,7 @@ static int check_one_table_access(THD *thd, ulong privilege,
if (subselects_tables)
{
tables->next= subselects_tables;
- if ((*res= check_table_access(thd, SELECT_ACL, subselects_tables,0)))
+ if ((check_table_access(thd, SELECT_ACL, subselects_tables,0)))
return 1;
}
return 0;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9cb8bb7b768..592820e6e19 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2864,7 +2864,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
If quick_select was used on a part of this key, we know
the maximum number of rows that the key can match.
*/
- if (table->quick_keys & ((key_map) 1 << key) &&
+ if (table->quick_keys.is_set(key) &&
table->quick_key_parts[key] <= max_key_part &&
records > (double) table->quick_rows[key])
tmp= records= (double) table->quick_rows[key];
@@ -6717,8 +6717,11 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
/*
We can remove binary fields and numerical fields except float,
as float comparison isn't 100 % secure
+ We have to keep binary strings to be able to check for end spaces
*/
if (field->binary() &&
+ field->real_type() != FIELD_TYPE_STRING &&
+ field->real_type() != FIELD_TYPE_VAR_STRING &&
(field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0))
{
return !store_val_in_field(field,right_item);
@@ -7931,6 +7934,29 @@ int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
}
+/*
+ Intitialize the GROUP BY list.
+
+ SYNOPSIS
+ setup_group()
+ thd Thread handler
+ ref_pointer_array We store references to all fields that was not in
+ 'fields' here.
+ fields All fields in the select part. Any item in 'order'
+ that is part of these list is replaced by a pointer
+ to this fields.
+ all_fields Total list of all unique fields used by the select.
+ All items in 'order' that was not part of fields will
+ be added first to this list.
+ order The fields we should do GROUP BY on.
+ hidden_group_fields Pointer to flag that is set to 1 if we added any fields
+ to all_fields.
+
+ RETURN
+ 0 ok
+ 1 error (probably out of memory)
+*/
+
int
setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
List<Item> &fields, List<Item> &all_fields, ORDER *order,
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 422b1ec3b4b..83a048297af 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -699,11 +699,56 @@ void String::qs_append(const char &c)
}
-int sortcmp(const String *x,const String *y, CHARSET_INFO *cs)
+/*
+ Compare strings according to collation, without end space.
+
+ SYNOPSIS
+ sortcmp()
+ s First string
+ t Second string
+ cs Collation
+
+ NOTE:
+ Normally this is case sensitive comparison
+
+ RETURN
+ < 0 s < t
+ 0 s == t
+ > 0 s > t
+*/
+
+
+int sortcmp(const String *s,const String *t, CHARSET_INFO *cs)
{
return cs->coll->strnncollsp(cs,
- (unsigned char *) x->ptr(),x->length(),
- (unsigned char *) y->ptr(),y->length());
+ (unsigned char *) s->ptr(),s->length(),
+ (unsigned char *) t->ptr(),t->length());
+}
+
+
+/*
+ Compare strings byte by byte. End spaces are also compared.
+
+ SYNOPSIS
+ stringcmp()
+ s First string
+ t Second string
+
+ NOTE:
+ Strings are compared as a stream of unsigned chars
+
+ RETURN
+ < 0 s < t
+ 0 s == t
+ > 0 s > t
+*/
+
+
+int stringcmp(const String *s,const String *t)
+{
+ uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 163156fdfe2..cdfb00276d4 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -221,6 +221,7 @@ public:
inline void caseup() { my_caseup(str_charset,Ptr,str_length); }
inline void casedn() { my_casedn(str_charset,Ptr,str_length); }
friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
+ friend int stringcmp(const String *a,const String *b);
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
uint32 numchars();
int charpos(int i,uint32 offset=0);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 922775083d5..12494703419 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1152,11 +1152,11 @@ mysql_rename_table(enum db_type base,
{
/* Table handler expects to get all file names as lower case */
strmov(tmp_from, old_name);
- casedn_str(tmp_from);
+ my_casedn_str(system_charset_info, tmp_from);
old_name= tmp_from;
strmov(tmp_to, new_name);
- casedn_str(tmp_to);
+ my_casedn_str(system_charset_info, tmp_to);
new_name= tmp_to;
}
(void) sprintf(from,"%s/%s/%s",mysql_data_home,old_db,old_name);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 1e702a9517c..977dd2595de 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -439,7 +439,14 @@ int mysql_multi_update(THD *thd,
for (tl= table_list ; tl ; tl=tl->next)
{
TABLE *table= tl->table;
- table->grant.want_privilege= (UPDATE_ACL & ~table->grant.privilege);
+ /*
+ Update of derived tables is checked later
+ We don't check privileges here, becasue then we would get error
+ "UPDATE command denided .. for column N" instead of
+ "Target table ... is not updatable"
+ */
+ if (!tl->derived)
+ table->grant.want_privilege= (UPDATE_ACL & ~table->grant.privilege);
}
if (thd->lex->derived_tables)
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index bd51df8810c..7ef5d219f07 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4626,8 +4626,8 @@ table_ident:
;
table_ident_ref:
- ident { LEX_STRING db={"",0}; $$=new Table_ident(db,$1,0); }
- | ident '.' ident { $$=new Table_ident($1,$3,0);}
+ ident { LEX_STRING db={(char*) any_db,3}; $$=new Table_ident(YYTHD, db,$1,0); }
+ | ident '.' ident { $$=new Table_ident(YYTHD, $1,$3,0);}
;
IDENT_sys: