From d01b3b5ab58cf4d05db9c8ca1e6349a7d322ee40 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 5 Mar 2003 23:32:59 +0200 Subject: [PATCH 01/27] calloc replaced with alloc in st_select_lex_node 'new' operator (SCRUM?) --- sql/sql_lex.cc | 21 +++++++++++++-------- sql/sql_lex.h | 3 +-- sql/sql_parse.cc | 2 +- sql/sql_yacc.yy | 1 - 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 94c06d41634..c6514a93053 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -999,6 +999,8 @@ int yylex(void *arg, void *yythd) void st_select_lex_node::init_query() { + options= 0; + linkage= UNSPECIFIED_TYPE; no_table_names_allowed= uncacheable= dependent= 0; ref_pointer_array= 0; } @@ -1016,8 +1018,8 @@ void st_select_lex_node::init_select() void st_select_lex_unit::init_query() { - linkage= GLOBAL_OPTIONS_TYPE; st_select_lex_node::init_query(); + linkage= GLOBAL_OPTIONS_TYPE; global_parameters= this; select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; @@ -1031,11 +1033,10 @@ void st_select_lex_unit::init_query() void st_select_lex::init_query() { st_select_lex_node::init_query(); - table_list.elements= 0; - table_list.first= 0; - table_list.next= (byte**) &table_list.first; + table_list.empty(); item_list.empty(); join= 0; + where= 0; olap= UNSPECIFIED_OLAP_TYPE; having_fix_field= 0; with_wild= 0; @@ -1044,11 +1045,15 @@ void st_select_lex::init_query() void st_select_lex::init_select() { st_select_lex_node::init_select(); - group_list.elements= 0; - group_list.first= 0; - group_list.next= (byte**) &group_list.first; + group_list.empty(); + type= db= db1= table1= db2= table2= 0; + having= 0; + group_list.empty(); + use_index_ptr= ignore_index_ptr= 0; + table_join_options= 0; + in_sum_expr= with_wild= 0; options= 0; - where= having= 0; + braces= 0; when_list.empty(); expr_list.empty(); interval_list.empty(); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index aff3485dbe4..6e03e0441c0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -221,8 +221,7 @@ public: static void *operator new(size_t size) { - // TODO: Change to alloc() and explicitely clear elements in constructors - return (void*) sql_calloc((uint) size); + return (void*) sql_alloc((uint) size); } static void operator delete(void *ptr,size_t size) {} st_select_lex_node(): linkage(UNSPECIFIED_TYPE) {} diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b336f41aa7e..055d144be05 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3316,7 +3316,7 @@ void mysql_init_multi_delete(LEX *lex) lex->select_lex.select_limit= lex->unit.select_limit_cnt= HA_POS_ERROR; lex->auxilliary_table_list= lex->select_lex.table_list; - lex->select_lex.init_query(); + lex->select_lex.table_list.empty(); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e5d94c30521..af964ddbb07 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3361,7 +3361,6 @@ delete: { LEX *lex= Lex; lex->sql_command= SQLCOM_DELETE; - lex->select_lex.options= 0; lex->lock_option= lex->thd->update_lock_default; lex->select_lex.init_order(); } From a2e9bbf2ebecdd0b83bb9b7516cdcd8544f782d5 Mon Sep 17 00:00:00 2001 From: "wax@kishkin.ru" <> Date: Sat, 31 May 2003 15:44:19 +0600 Subject: [PATCH 02/27] URGENT SCRUM BUG correct wrong code in group_concat --- mysql-test/r/func_gconcat.result | 20 ++++++- mysql-test/t/func_gconcat.test | 16 +++++- sql/field.cc | 2 +- sql/field.h | 1 + sql/item_sum.cc | 97 ++++++++++++++++++-------------- sql/item_sum.h | 29 +++++++--- 6 files changed, 111 insertions(+), 54 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 0dc84f090f1..f2246f2e514 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -154,8 +154,26 @@ Warning 1258 1 line(s) was(were) cut by group_concat() show warnings; Level Code Message Warning 1258 1 line(s) was(were) cut by group_concat() +set group_concat_max_len = 1024; +drop table if exists T_URL; +Warnings: +Note 1051 Unknown table 'T_URL' +create table T_URL ( URL_ID int(11), URL varchar(80)); +drop table if exists T_REQUEST; +Warnings: +Note 1051 Unknown table 'T_REQUEST' +create table T_REQUEST ( REQ_ID int(11), URL_ID int(11)); +insert into T_URL values (4,'www.host.com'), (5,'www.google.com'),(5,'www.help.com'); +insert into T_REQUEST values (1,4), (5,4), (5,5); +select REQ_ID, Group_Concat(URL) as URL from T_URL, T_REQUEST where +T_REQUEST.URL_ID = T_URL.URL_ID group by REQ_ID; +REQ_ID URL +1 www.host.com +5 www.host.com,www.google.com,www.help.com +drop table T_URL; +drop table T_REQUEST; select group_concat(sum(a)) from t1 group by grp; Invalid use of group function select grp,group_concat(c order by 2) from t1 group by grp; Unknown column '2' in 'group statement' -drop table if exists t1; +drop table t1; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 0a95410e842..a5a7abe3b01 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -68,6 +68,20 @@ select grp,group_concat(c order by c) from t1 group by grp; set group_concat_max_len = 5; select grp,group_concat(c) from t1 group by grp; show warnings; +set group_concat_max_len = 1024; + +# Test variable length + +drop table if exists T_URL; +create table T_URL ( URL_ID int(11), URL varchar(80)); +drop table if exists T_REQUEST; +create table T_REQUEST ( REQ_ID int(11), URL_ID int(11)); +insert into T_URL values (4,'www.host.com'), (5,'www.google.com'),(5,'www.help.com'); +insert into T_REQUEST values (1,4), (5,4), (5,5); +select REQ_ID, Group_Concat(URL) as URL from T_URL, T_REQUEST where +T_REQUEST.URL_ID = T_URL.URL_ID group by REQ_ID; +drop table T_URL; +drop table T_REQUEST; # Test errors @@ -76,4 +90,4 @@ select group_concat(sum(a)) from t1 group by grp; --error 1054 select grp,group_concat(c order by 2) from t1 group by grp; -drop table if exists t1; +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index 3695268a888..e54986ded22 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -175,7 +175,7 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, field_name(field_name_arg), query_id(0),key_start(0),part_of_key(0),part_of_sortkey(0), unireg_check(unireg_check_arg), - field_length(length_arg),null_bit(null_bit_arg) + field_length(length_arg),null_bit(null_bit_arg),abs_offset(0) { flags=null_ptr ? 0: NOT_NULL_FLAG; comment.str= (char*) ""; diff --git a/sql/field.h b/sql/field.h index 80bfc516ef7..088dae49c6f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -62,6 +62,7 @@ public: uint32 field_length; // Length of field uint16 flags; uchar null_bit; // Bit used to test null bit + uint abs_offset; // use only in group_concat Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 11c850f9d5f..8bd3e36b5db 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1344,27 +1344,28 @@ String *Item_sum_udf_str::val_str(String *str) GROUP_CONCAT(DISTINCT expr,...) */ -static int group_concat_key_cmp_with_distinct(void* arg, byte* key1, - byte* key2) +int group_concat_key_cmp_with_distinct(void* arg, byte* key1, + byte* key2) { Item_func_group_concat* item= (Item_func_group_concat*)arg; + for (uint i= 0; i < item->arg_count_field; i++) { - Item *field_item= item->expr[i]; + Item *field_item= item->args[i]; Field *field= field_item->tmp_table_field(); if (field) { - uint offset= field->offset(); + uint offset= field->abs_offset; int res= field->key_cmp(key1 + offset, key2 + offset); /* if key1 and key2 is not equal than field->key_cmp return offset. This - function must return value 1 for this case. + function must return value 1 for this case. */ if (res) return 1; } - } + } return 0; } @@ -1374,9 +1375,10 @@ static int group_concat_key_cmp_with_distinct(void* arg, byte* key1, GROUP_CONCAT(expr,... ORDER BY col,... ) */ -static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) +int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) { Item_func_group_concat* item= (Item_func_group_concat*)arg; + for (uint i=0; i < item->arg_count_order; i++) { ORDER *order_item= item->order[i]; @@ -1384,14 +1386,14 @@ static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) Field *field= item->tmp_table_field(); if (field) { - uint offset= field->offset(); + uint offset= field->abs_offset; bool dir= order_item->asc; int res= field->key_cmp(key1 + offset, key2 + offset); if (res) return dir ? res : -res; } - } + } /* We can't return 0 because tree class remove this item as double value. */ @@ -1404,9 +1406,8 @@ static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2) GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... ) */ -static int group_concat_key_cmp_with_distinct_and_order(void* arg, - byte* key1, - byte* key2) +int group_concat_key_cmp_with_distinct_and_order(void* arg,byte* key1, + byte* key2) { if (!group_concat_key_cmp_with_distinct(arg,key1,key2)) return 0; @@ -1419,24 +1420,23 @@ static int group_concat_key_cmp_with_distinct_and_order(void* arg, item is pointer to Item_func_group_concat */ -static int dump_leaf_key(byte* key, uint32 count __attribute__((unused)), +int dump_leaf_key(byte* key, uint32 count __attribute__((unused)), Item_func_group_concat *group_concat_item) { char buff[MAX_FIELD_WIDTH]; String tmp((char *)&buff,sizeof(buff),default_charset_info); String tmp2((char *)&buff,sizeof(buff),default_charset_info); - + tmp.length(0); for (uint i= 0; i < group_concat_item->arg_show_fields; i++) { - Item *show_item= group_concat_item->expr[i]; + Item *show_item= group_concat_item->args[i]; if (!show_item->const_item()) { Field *f= show_item->tmp_table_field(); - uint offset= f->offset(); char *sv= f->ptr; - f->ptr= (char *)key + offset; + f->ptr= (char *)key + f->abs_offset; String *res= f->val_str(&tmp,&tmp2); group_concat_item->result.append(*res); f->ptr= sv; @@ -1486,9 +1486,14 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, List *is_select, SQL_LIST *is_order, String *is_separator) - :Item_sum(), tmp_table_param(0), warning_available(false), - separator(is_separator), tree(&tree_base), table(0), - count_cut_values(0), tree_mode(0), distinct(is_distinct) + :Item_sum(), tmp_table_param(0), max_elements_in_tree(0), warning(0), + warning_available(0), key_length(0), rec_offset(0), + tree_mode(0), distinct(is_distinct), warning_for_row(0), + separator(is_separator), tree(&tree_base), table(0), + order(0), tables_list(0), group_concat_max_len(0), + show_elements(0), arg_count_order(0), arg_count_field(0), + arg_show_fields(0), count_cut_values(0) + { original= 0; quick_group= 0; @@ -1504,16 +1509,12 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, We need to allocate: args - arg_count+arg_count_order (for possible order items in temporare tables) - expr - arg_count_field order - arg_count_order */ - args= (Item**) sql_alloc(sizeof(Item*)*(arg_count+arg_count_order+ - arg_count_field)+ + args= (Item**) sql_alloc(sizeof(Item*)*(arg_count+arg_count_order)+ sizeof(ORDER*)*arg_count_order); if (!args) - return; // thd->fatal is set - expr= args; - expr+= arg_count+arg_count_order; + return; /* fill args items of show and sort */ int i= 0; @@ -1521,12 +1522,12 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, Item *item_select; for ( ; (item_select= li++) ; i++) - args[i]= expr[i]= item_select; + args[i]= item_select; if (arg_count_order) { i= 0; - order= (ORDER**)(expr + arg_count_field); + order= (ORDER**)(args + arg_count + arg_count_order); for (ORDER *order_item= (ORDER*) is_order->first; order_item != NULL; order_item= order_item->next) @@ -1587,7 +1588,7 @@ bool Item_func_group_concat::add() bool record_is_null= TRUE; for (uint i= 0; i < arg_show_fields; i++) { - Item *show_item= expr[i]; + Item *show_item= args[i]; if (!show_item->const_item()) { Field *f= show_item->tmp_table_field(); @@ -1603,13 +1604,13 @@ bool Item_func_group_concat::add() null_value= FALSE; if (tree_mode) { - if (!tree_insert(tree, table->record[0], 0,tree->custom_arg)) + if (!tree_insert(tree, table->record[0] + rec_offset, 0, tree->custom_arg)) return 1; } else { if (result.length() <= group_concat_max_len && !warning_for_row) - dump_leaf_key(table->record[0],1, + dump_leaf_key(table->record[0] + rec_offset, 1, (Item_func_group_concat*)this); } return 0; @@ -1642,12 +1643,6 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 1; maybe_null |= args[i]->maybe_null; } - for (i= 0 ; i < arg_count_field ; i++) - { - if (expr[i]->fix_fields(thd, tables, expr + i) || expr[i]->check_cols(1)) - return 1; - maybe_null |= expr[i]->maybe_null; - } /* Fix fields for order clause in function: GROUP_CONCAT(expr,... ORDER BY col,... ) @@ -1712,12 +1707,25 @@ bool Item_func_group_concat::setup(THD *thd) return 1; table->file->extra(HA_EXTRA_NO_ROWS); table->no_rows= 1; - qsort_cmp2 compare_key; - - tree_mode= distinct || arg_count_order; + + + Field** field, **field_end; + field_end = (field = table->field) + table->fields; + uint offset = 0; + for (key_length = 0; field < field_end; ++field) + { + uint32 length= (*field)->pack_length(); + (*field)->abs_offset= offset; + offset+= length; + key_length += length; + } + rec_offset = table->reclength - key_length; + /* choise function of sort */ + tree_mode= distinct || arg_count_order; + qsort_cmp2 compare_key; if (tree_mode) { if (arg_count_order) @@ -1741,9 +1749,9 @@ bool Item_func_group_concat::setup(THD *thd) */ init_tree(tree, min(thd->variables.max_heap_table_size, thd->variables.sortbuff_size/16), 0, - table->reclength, compare_key, 0, NULL, (void*) this); - max_elements_in_tree= ((table->reclength) ? - thd->variables.max_heap_table_size/table->reclength : 1); + key_length, compare_key, 0, NULL, (void*) this); + max_elements_in_tree= ((key_length) ? + thd->variables.max_heap_table_size/key_length : 1); }; item_thd= thd; @@ -1784,3 +1792,6 @@ String* Item_func_group_concat::val_str(String* str) } return &result; } + + + diff --git a/sql/item_sum.h b/sql/item_sum.h index 37d7e7f79d0..e306a42c6bc 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -640,13 +640,28 @@ class Item_func_group_concat : public Item_sum uint max_elements_in_tree; MYSQL_ERROR *warning; bool warning_available; + uint key_length; + int rec_offset; + bool tree_mode; + bool distinct; + bool warning_for_row; + bool always_null; + + friend int group_concat_key_cmp_with_distinct(void* arg, byte* key1, + byte* key2); + friend int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2); + friend int group_concat_key_cmp_with_distinct_and_order(void* arg, + byte* key1, + byte* key2); + friend int dump_leaf_key(byte* key, uint32 count __attribute__((unused)), + Item_func_group_concat *group_concat_item); + public: String result; String *separator; TREE tree_base; TREE *tree; TABLE *table; - Item **expr; ORDER **order; TABLE_LIST *tables_list; ulong group_concat_max_len; @@ -655,9 +670,6 @@ class Item_func_group_concat : public Item_sum uint arg_count_field; uint arg_show_fields; uint count_cut_values; - bool tree_mode, distinct; - bool warning_for_row; - bool always_null; /* Following is 0 normal object and pointer to original one for copy (to correctly free resources) @@ -673,10 +685,14 @@ class Item_func_group_concat : public Item_sum max_elements_in_tree(item.max_elements_in_tree), warning(item.warning), warning_available(item.warning_available), + key_length(item.key_length), + rec_offset(item.rec_offset), + tree_mode(0), + distinct(item.distinct), + warning_for_row(item.warning_for_row), separator(item.separator), tree(item.tree), table(item.table), - expr(item.expr), order(item.order), tables_list(item.tables_list), group_concat_max_len(item.group_concat_max_len), @@ -685,9 +701,6 @@ class Item_func_group_concat : public Item_sum arg_count_field(item.arg_count_field), arg_show_fields(item.arg_show_fields), count_cut_values(item.count_cut_values), - tree_mode(0), - distinct(item.distinct), - warning_for_row(item.warning_for_row), original(&item) { quick_group = 0; From f96200fd1dedaded8d261ad1251bc0e9779203cd Mon Sep 17 00:00:00 2001 From: "wax@kishkin.ru" <> Date: Tue, 3 Jun 2003 17:02:51 +0600 Subject: [PATCH 03/27] BUG correct bug with empty table --- sql/item_sum.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 8bd3e36b5db..60976ab993a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1582,6 +1582,8 @@ void Item_func_group_concat::reset() bool Item_func_group_concat::add() { + if (always_null) + return 0; copy_fields(tmp_table_param); copy_funcs(tmp_table_param->items_to_copy); @@ -1676,6 +1678,7 @@ bool Item_func_group_concat::setup(THD *thd) /* all not constant fields are push to list and create temp table */ + always_null= 0; for (uint i= 0; i < arg_count; i++) { Item *item= args[i]; @@ -1688,6 +1691,8 @@ bool Item_func_group_concat::setup(THD *thd) always_null= 1; } } + if (always_null) + return 0; List all_fields(list); if (arg_count_order) From 354af955bc3b9a3b771eee77d08b4b2c0015470a Mon Sep 17 00:00:00 2001 From: "miguel@hegel.(none)" <> Date: Thu, 19 Jun 2003 12:17:23 -0400 Subject: [PATCH 04/27] Fix error msg. Bug #681 --- BitKeeper/etc/logging_ok | 1 + sql/nt_servc.cc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index c9f82de08d3..6d700cfd6c6 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -52,6 +52,7 @@ jorge@linux.jorge.mysql.com kaj@work.mysql.com lenz@kallisto.mysql.com lenz@mysql.com +miguel@hegel.(none) miguel@hegel.br miguel@hegel.local miguel@light. diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index 93bae6f444d..25fc010d9a5 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -462,7 +462,7 @@ BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType) { /* a remove operation */ if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS ))) - printf("The service doesn't exists!\n"); + printf("The service doesn't exist!\n"); else { SERVICE_STATUS ss; From 528386fc78e0598502dd30f0d5e6d23ab87bf63a Mon Sep 17 00:00:00 2001 From: "ram@mysql.r18.ru" <> Date: Fri, 20 Jun 2003 14:31:47 +0500 Subject: [PATCH 05/27] Added AsWKT() alias for AsText(). Renamed as_text(). --- sql/item_create.cc | 2 +- sql/item_create.h | 2 +- sql/lex.h | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/item_create.cc b/sql/item_create.cc index eb442424ca8..908e74ac808 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -506,7 +506,7 @@ Item *create_func_quote(Item* a) return new Item_func_quote(a); } -Item *create_func_as_text(Item *a) +Item *create_func_as_wkt(Item *a) { return new Item_func_as_text(a); } diff --git a/sql/item_create.h b/sql/item_create.h index b679c639244..4151f59a87f 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -104,7 +104,7 @@ Item *create_func_is_used_lock(Item* a); Item *create_func_quote(Item* a); Item *create_func_geometry_from_text(Item *a); -Item *create_func_as_text(Item *a); +Item *create_func_as_wkt(Item *a); Item *create_func_as_wkb(Item *a); Item *create_func_srid(Item *a); Item *create_func_startpoint(Item *a); diff --git a/sql/lex.h b/sql/lex.h index f7c4418cb8d..bb6e7a81ab4 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -433,8 +433,9 @@ static SYMBOL sql_functions[] = { { "AREA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_area)}, { "ASIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_asin)}, { "ASBINARY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_as_wkb)}, - { "ASTEXT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_as_text)}, + { "ASTEXT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_as_wkt)}, { "ASWKB", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_as_wkb)}, + { "ASWKT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_as_wkt)}, { "ATAN", SYM(ATAN),0,0}, { "ATAN2", SYM(ATAN),0,0}, { "BENCHMARK", SYM(BENCHMARK_SYM),0,0}, From a89a7eb32771b57306cd218ff4746fac1889a9d8 Mon Sep 17 00:00:00 2001 From: "ram@mysql.r18.ru" <> Date: Fri, 20 Jun 2003 14:53:37 +0500 Subject: [PATCH 06/27] Renamed xxx_as_text() and xxx__from_text(). --- sql/item_create.cc | 2 +- sql/item_geofunc.cc | 4 +- sql/item_geofunc.h | 4 +- sql/spatial.cc | 90 ++++++++++++++++++++++----------------------- sql/spatial.h | 42 ++++++++++----------- 5 files changed, 71 insertions(+), 71 deletions(-) diff --git a/sql/item_create.cc b/sql/item_create.cc index 908e74ac808..6956582a8ca 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -508,7 +508,7 @@ Item *create_func_quote(Item* a) Item *create_func_as_wkt(Item *a) { - return new Item_func_as_text(a); + return new Item_func_as_wkt(a); } Item *create_func_as_wkb(Item *a) diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 6db139fdfa6..5ac87a25e67 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -85,7 +85,7 @@ void Item_func_geometry_from_wkb::fix_length_and_dec() } -String *Item_func_as_text::val_str(String *str) +String *Item_func_as_wkt::val_str(String *str) { String arg_val; String *swkb= args[0]->val_str(&arg_val); @@ -104,7 +104,7 @@ String *Item_func_as_text::val_str(String *str) return str; } -void Item_func_as_text::fix_length_and_dec() +void Item_func_as_wkt::fix_length_and_dec() { max_length=MAX_BLOB_WIDTH; } diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 21e94735f31..d86914eb6c5 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -43,10 +43,10 @@ public: void fix_length_and_dec(); }; -class Item_func_as_text: public Item_str_func +class Item_func_as_wkt: public Item_str_func { public: - Item_func_as_text(Item *a): Item_str_func(a) {} + Item_func_as_wkt(Item *a): Item_str_func(a) {} const char *func_name() const { return "astext"; } String *val_str(String *); void fix_length_and_dec(); diff --git a/sql/spatial.cc b/sql/spatial.cc index c8dfb490a39..00db94a07d6 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -5,31 +5,31 @@ /***************************** GClassInfo *******************************/ -#define IMPLEMENT_GEOM(class_name, type_id, name) \ -{ \ - (GF_InitFromText) &class_name::init_from_text, \ - (GF_GetDataAsText) &class_name::get_data_as_text, \ - (GF_GetDataSize) &class_name::get_data_size, \ - (GF_GetMBR) &class_name::get_mbr, \ - (GF_GetD) &class_name::get_x, \ - (GF_GetD) &class_name::get_y, \ - (GF_GetD) &class_name::length, \ - (GF_GetD) &class_name::area, \ - (GF_GetI) &class_name::is_closed, \ - (GF_GetUI) &class_name::num_interior_ring, \ - (GF_GetUI) &class_name::num_points, \ - (GF_GetUI) &class_name::num_geometries, \ - (GF_GetUI) &class_name::dimension, \ - (GF_GetWS) &class_name::start_point, \ - (GF_GetWS) &class_name::end_point, \ - (GF_GetWS) &class_name::exterior_ring, \ - (GF_GetWS) &class_name::centroid, \ - (GF_GetUIWS) &class_name::point_n, \ - (GF_GetUIWS) &class_name::interior_ring_n, \ - (GF_GetUIWS) &class_name::geometry_n, \ - class_name::type_id, \ - name, \ - NULL \ +#define IMPLEMENT_GEOM(class_name, type_id, name) \ +{ \ + (GF_InitFromText) &class_name::init_from_wkt, \ + (GF_GetDataAsText) &class_name::get_data_as_wkt, \ + (GF_GetDataSize) &class_name::get_data_size, \ + (GF_GetMBR) &class_name::get_mbr, \ + (GF_GetD) &class_name::get_x, \ + (GF_GetD) &class_name::get_y, \ + (GF_GetD) &class_name::length, \ + (GF_GetD) &class_name::area, \ + (GF_GetI) &class_name::is_closed, \ + (GF_GetUI) &class_name::num_interior_ring, \ + (GF_GetUI) &class_name::num_points, \ + (GF_GetUI) &class_name::num_geometries, \ + (GF_GetUI) &class_name::dimension, \ + (GF_GetWS) &class_name::start_point, \ + (GF_GetWS) &class_name::end_point, \ + (GF_GetWS) &class_name::exterior_ring, \ + (GF_GetWS) &class_name::centroid, \ + (GF_GetUIWS) &class_name::point_n, \ + (GF_GetUIWS) &class_name::interior_ring_n, \ + (GF_GetUIWS) &class_name::geometry_n, \ + class_name::type_id, \ + name, \ + NULL \ }, @@ -113,7 +113,7 @@ int Geometry::create_from_wkt(GTextReadStream *trs, String *wkt, int init_stream trs->set_error_msg("'(' expected"); return -1; } - if (init_from_text(trs, wkt)) return 1; + if (init_from_wkt(trs, wkt)) return 1; if (trs->get_next_symbol() != ')') { trs->set_error_msg("')' expected"); @@ -161,7 +161,7 @@ size_t GPoint::get_data_size() const return POINT_DATA_SIZE; } -int GPoint::init_from_text(GTextReadStream *trs, String *wkb) +int GPoint::init_from_wkt(GTextReadStream *trs, String *wkb) { double x, y; if (wkb->reserve(sizeof(double)*2)) @@ -176,7 +176,7 @@ int GPoint::init_from_text(GTextReadStream *trs, String *wkb) return 0; } -int GPoint::get_data_as_text(String *txt) const +int GPoint::get_data_as_wkt(String *txt) const { double x, y; if (get_xy(&x, &y)) @@ -207,7 +207,7 @@ size_t GLineString::get_data_size() const return 4 + n_points*POINT_DATA_SIZE; } -int GLineString::init_from_text(GTextReadStream *trs, String *wkb) +int GLineString::init_from_wkt(GTextReadStream *trs, String *wkb) { uint32 n_points = 0; int np_pos = wkb->length(); @@ -220,7 +220,7 @@ int GLineString::init_from_text(GTextReadStream *trs, String *wkb) for (;;) { - if (p.init_from_text(trs, wkb)) + if (p.init_from_wkt(trs, wkb)) return 1; ++n_points; if (trs->get_next_toc_type() == GTextReadStream::comma) @@ -239,7 +239,7 @@ int GLineString::init_from_text(GTextReadStream *trs, String *wkb) return 0; } -int GLineString::get_data_as_text(String *txt) const +int GLineString::get_data_as_wkt(String *txt) const { uint32 n_points; const char *data = m_data; @@ -459,7 +459,7 @@ size_t GPolygon::get_data_size() const return data - m_data; } -int GPolygon::init_from_text(GTextReadStream *trs, String *wkb) +int GPolygon::init_from_wkt(GTextReadStream *trs, String *wkb) { uint32 n_linear_rings = 0; int lr_pos = wkb->length(); @@ -478,7 +478,7 @@ int GPolygon::init_from_text(GTextReadStream *trs, String *wkb) trs->set_error_msg("'(' expected"); return 1; } - if (ls.init_from_text(trs, wkb)) + if (ls.init_from_wkt(trs, wkb)) return 1; if (trs->get_next_symbol() != ')') { @@ -503,7 +503,7 @@ int GPolygon::init_from_text(GTextReadStream *trs, String *wkb) return 0; } -int GPolygon::get_data_as_text(String *txt) const +int GPolygon::get_data_as_wkt(String *txt) const { uint32 n_linear_rings; const char *data= m_data; @@ -783,7 +783,7 @@ size_t GMultiPoint::get_data_size() const return 4 + uint4korr(m_data)*(POINT_DATA_SIZE + WKB_HEADER_SIZE); } -int GMultiPoint::init_from_text(GTextReadStream *trs, String *wkb) +int GMultiPoint::init_from_wkt(GTextReadStream *trs, String *wkb) { uint32 n_points = 0; int np_pos = wkb->length(); @@ -799,7 +799,7 @@ int GMultiPoint::init_from_text(GTextReadStream *trs, String *wkb) return 1; wkb->q_append((char)wkbNDR); wkb->q_append((uint32)wkbPoint); - if (p.init_from_text(trs, wkb)) + if (p.init_from_wkt(trs, wkb)) return 1; ++n_points; if (trs->get_next_toc_type() == GTextReadStream::comma) @@ -812,7 +812,7 @@ int GMultiPoint::init_from_text(GTextReadStream *trs, String *wkb) return 0; } -int GMultiPoint::get_data_as_text(String *txt) const +int GMultiPoint::get_data_as_wkt(String *txt) const { uint32 n_points; const char *data= m_data; @@ -904,7 +904,7 @@ size_t GMultiLineString::get_data_size() const return data - m_data; } -int GMultiLineString::init_from_text(GTextReadStream *trs, String *wkb) +int GMultiLineString::init_from_wkt(GTextReadStream *trs, String *wkb) { uint32 n_line_strings = 0; int ls_pos = wkb->length(); @@ -928,7 +928,7 @@ int GMultiLineString::init_from_text(GTextReadStream *trs, String *wkb) trs->set_error_msg("'(' expected"); return 1; } - if (ls.init_from_text(trs, wkb)) + if (ls.init_from_wkt(trs, wkb)) return 1; if (trs->get_next_symbol() != ')') @@ -947,7 +947,7 @@ int GMultiLineString::init_from_text(GTextReadStream *trs, String *wkb) return 0; } -int GMultiLineString::get_data_as_text(String *txt) const +int GMultiLineString::get_data_as_wkt(String *txt) const { uint32 n_line_strings; const char *data= m_data; @@ -1120,7 +1120,7 @@ size_t GMultiPolygon::get_data_size() const return data - m_data; } -int GMultiPolygon::init_from_text(GTextReadStream *trs, String *wkb) +int GMultiPolygon::init_from_wkt(GTextReadStream *trs, String *wkb) { uint32 n_polygons = 0; int np_pos = wkb->length(); @@ -1143,7 +1143,7 @@ int GMultiPolygon::init_from_text(GTextReadStream *trs, String *wkb) trs->set_error_msg("'(' expected"); return 1; } - if (p.init_from_text(trs, wkb)) + if (p.init_from_wkt(trs, wkb)) return 1; if (trs->get_next_symbol() != ')') { @@ -1160,7 +1160,7 @@ int GMultiPolygon::init_from_text(GTextReadStream *trs, String *wkb) return 0; } -int GMultiPolygon::get_data_as_text(String *txt) const +int GMultiPolygon::get_data_as_wkt(String *txt) const { uint32 n_polygons; const char *data= m_data; @@ -1403,7 +1403,7 @@ size_t GGeometryCollection::get_data_size() const return data - m_data; } -int GGeometryCollection::init_from_text(GTextReadStream *trs, String *wkb) +int GGeometryCollection::init_from_wkt(GTextReadStream *trs, String *wkb) { uint32 n_objects = 0; int no_pos = wkb->length(); @@ -1433,7 +1433,7 @@ int GGeometryCollection::init_from_text(GTextReadStream *trs, String *wkb) return 0; } -int GGeometryCollection::get_data_as_text(String *txt) const +int GGeometryCollection::get_data_as_wkt(String *txt) const { uint32 n_objects; const char *data = m_data; diff --git a/sql/spatial.h b/sql/spatial.h index d9c14afbe30..5fda257f1b1 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -228,8 +228,8 @@ public: class GClassInfo { public: - GF_InitFromText init_from_text; - GF_GetDataAsText get_data_as_text; + GF_InitFromText init_from_wkt; + GF_GetDataAsText get_data_as_wkt; GF_GetDataSize get_data_size; GF_GetMBR get_mbr; GF_GetD get_x; @@ -262,11 +262,11 @@ public: const GClassInfo *get_class_info() const { return m_vmt; } size_t get_data_size() const { return (this->*m_vmt->get_data_size)(); } - int init_from_text(GTextReadStream *trs, String *wkb) - { return (this->*m_vmt->init_from_text)(trs, wkb); } + int init_from_wkt(GTextReadStream *trs, String *wkb) + { return (this->*m_vmt->init_from_wkt)(trs, wkb); } - int get_data_as_text(String *txt) const - { return (this->*m_vmt->get_data_as_text)(txt); } + int get_data_as_wkt(String *txt) const + { return (this->*m_vmt->get_data_as_wkt)(txt); } int get_mbr(MBR *mbr) const { return (this->*m_vmt->get_mbr)(mbr); } int dimension(uint32 *dim) const @@ -324,7 +324,7 @@ public: return 1; wkt->qs_append(get_class_info()->m_name); wkt->qs_append('('); - if (get_data_as_text(wkt)) + if (get_data_as_wkt(wkt)) return 1; wkt->qs_append(')'); return 0; @@ -364,8 +364,8 @@ class GPoint: public Geometry { public: size_t get_data_size() const; - int init_from_text(GTextReadStream *trs, String *wkb); - int get_data_as_text(String *txt) const; + int init_from_wkt(GTextReadStream *trs, String *wkb); + int get_data_as_wkt(String *txt) const; int get_mbr(MBR *mbr) const; int get_xy(double *x, double *y) const @@ -401,8 +401,8 @@ class GLineString: public Geometry { public: size_t get_data_size() const; - int init_from_text(GTextReadStream *trs, String *wkb); - int get_data_as_text(String *txt) const; + int init_from_wkt(GTextReadStream *trs, String *wkb); + int get_data_as_wkt(String *txt) const; int get_mbr(MBR *mbr) const; int length(double *len) const; @@ -420,8 +420,8 @@ class GPolygon: public Geometry { public: size_t get_data_size() const; - int init_from_text(GTextReadStream *trs, String *wkb); - int get_data_as_text(String *txt) const; + int init_from_wkt(GTextReadStream *trs, String *wkb); + int get_data_as_wkt(String *txt) const; int get_mbr(MBR *mbr) const; int area(double *ar) const; @@ -439,8 +439,8 @@ class GMultiPoint: public Geometry { public: size_t get_data_size() const; - int init_from_text(GTextReadStream *trs, String *wkb); - int get_data_as_text(String *txt) const; + int init_from_wkt(GTextReadStream *trs, String *wkb); + int get_data_as_wkt(String *txt) const; int get_mbr(MBR *mbr) const; int num_geometries(uint32 *num) const; @@ -454,8 +454,8 @@ class GMultiLineString: public Geometry { public: size_t get_data_size() const; - int init_from_text(GTextReadStream *trs, String *wkb); - int get_data_as_text(String *txt) const; + int init_from_wkt(GTextReadStream *trs, String *wkb); + int get_data_as_wkt(String *txt) const; int get_mbr(MBR *mbr) const; int num_geometries(uint32 *num) const; @@ -471,8 +471,8 @@ class GMultiPolygon: public Geometry { public: size_t get_data_size() const; - int init_from_text(GTextReadStream *trs, String *wkb); - int get_data_as_text(String *txt) const; + int init_from_wkt(GTextReadStream *trs, String *wkb); + int get_data_as_wkt(String *txt) const; int get_mbr(MBR *mbr) const; int num_geometries(uint32 *num) const; @@ -488,8 +488,8 @@ class GGeometryCollection: public Geometry { public: size_t get_data_size() const; - int init_from_text(GTextReadStream *trs, String *wkb); - int get_data_as_text(String *txt) const; + int init_from_wkt(GTextReadStream *trs, String *wkb); + int get_data_as_wkt(String *txt) const; int get_mbr(MBR *mbr) const; int num_geometries(uint32 *num) const; From 7a6059cc88403a8d7ba25f3fdd2b0f0d7dd34235 Mon Sep 17 00:00:00 2001 From: "lenz@kallisto.local" <> Date: Fri, 20 Jun 2003 13:57:51 +0200 Subject: [PATCH 07/27] - make sure that scripts/*.sql files are being added to the source distribution as well --- scripts/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 6006222992e..ff35170dcf3 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -62,7 +62,7 @@ EXTRA_DIST = $(EXTRA_SCRIPTS) \ mysqlaccess.conf \ mysqlbug -pkgdata_DATA = fill_help_tables.sql mysql_fix_privilege_tables.sql +dist_pkgdata_DATA = fill_help_tables.sql mysql_fix_privilege_tables.sql # mysqlbug should be distributed built so that people can report build # failures with it. From f78a77798c29c8f83d28b5e35bf2146a20cfcb6d Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Fri, 20 Jun 2003 18:45:28 +0500 Subject: [PATCH 08/27] item_cmpfunc.cc: Rewritten in nicer way , --- sql/item_cmpfunc.cc | 69 +++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index d4997f78a9e..e67c742928e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -90,38 +90,51 @@ static bool convert_constant_item(Field *field, Item **item) bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, enum coercion co1, CHARSET_INFO *cs2, enum coercion co2) { - if ((cs1 == &my_charset_bin) || (cs2 == &my_charset_bin)) + if (!my_charset_same(cs1, cs2)) { - cmp_charset= &my_charset_bin; - return 0; - } - - if ((co1 == COER_NOCOLL) || (co2 == COER_NOCOLL)) - return 1; - - if (!my_charset_same(cs1,cs2)) - return 1; - - if (co1 < co2) - cmp_charset= cs1; - else if (co2 < co1) - cmp_charset= cs2; - else // co1==co2 - { - if (cs1 == cs2) + /* + We do allow to use BLOBS together with character strings + BLOBS have more precedance + */ + if ((co1 <= co2) && (cs1==&my_charset_bin)) + { cmp_charset= cs1; + coercibility= co1; + } + else if ((co2 <= co1) && (cs2==&my_charset_bin)) + { + cmp_charset= cs2; + coercibility= co2; + } else { - if (co1 == COER_COERCIBLE) - { - CHARSET_INFO *c; - if ((c= get_charset_by_csname(cs1->csname, MY_CS_PRIMARY, MYF(0)))) - { - cmp_charset= c; - return 0; - } - } - return 1; + cmp_charset= 0; + coercibility= COER_NOCOLL; + return 1; + } + } + else if (co1 < co2) + { + cmp_charset= cs1; + coercibility= co1; + } + else if (co2 < co1) + { + cmp_charset= cs2; + coercibility= co1; + } + else + { + if (cs1 == cs2) + { + cmp_charset= cs1; + coercibility= co1; + } + else + { + coercibility= COER_NOCOLL; + cmp_charset= 0; + return (co1 == COER_EXPLICIT) ? 1 : 0; } } return 0; From 4c7714b7f98a072a20655f029753c648362ac43c Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Fri, 20 Jun 2003 19:05:45 +0500 Subject: [PATCH 09/27] item_cmpfunc.cc: Temporarily fix for test failure ,. --- sql/item_cmpfunc.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e67c742928e..5c2b9ed4682 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -90,6 +90,13 @@ static bool convert_constant_item(Field *field, Item **item) bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, enum coercion co1, CHARSET_INFO *cs2, enum coercion co2) { + if (cs1 == &my_charset_bin || cs2 == &my_charset_bin) + { + cmp_charset= &my_charset_bin; + coercibility= co1 > co2 ? co1 : co2; + return 0; + } + if (!my_charset_same(cs1, cs2)) { /* From 8bd715daa4d98fa24c789ec04c0fd72a7626b5f7 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Tue, 24 Jun 2003 13:37:11 +0500 Subject: [PATCH 10/27] Item character set is stored in Item itself now, not in ITem->str_value --- sql/item.cc | 4 +++- sql/item.h | 18 ++++++++++-------- sql/sql_select.cc | 4 ++-- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 868cf4466a6..d74b9d7454f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -39,7 +39,8 @@ Item::Item(): { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; - coercibility=COER_COERCIBLE; + collation= &my_charset_bin; + coercibility= COER_COERCIBLE; name= 0; decimals= 0; max_length= 0; THD *thd= current_thd; @@ -67,6 +68,7 @@ Item::Item(THD *thd, Item &item): unsigned_flag(item.unsigned_flag), with_sum_func(item.with_sum_func), fixed(item.fixed), + collation(item.collation), coercibility(item.coercibility) { next=thd->free_list; // Put in free list diff --git a/sql/item.h b/sql/item.h index 5cfe8eb3907..df9ada72ce5 100644 --- a/sql/item.h +++ b/sql/item.h @@ -65,6 +65,7 @@ public: my_bool unsigned_flag; my_bool with_sum_func; my_bool fixed; /* If item fixed with fix_fields */ + CHARSET_INFO *collation; /* character set && collation */ enum coercion coercibility; /* Precedence order of collation */ // alloc & destruct is done as start of select using sql_alloc @@ -123,18 +124,17 @@ public: virtual Item *real_item() { return this; } virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); } - virtual bool binary() const - { return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0 ; } CHARSET_INFO *default_charset() const; - CHARSET_INFO *charset() const { return str_value.charset(); }; - void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); } + CHARSET_INFO *charset() const { return collation; }; + void set_charset(CHARSET_INFO *cs) + { collation= cs; } void set_charset(CHARSET_INFO *cs, enum coercion coer) - { - str_value.set_charset(cs); - coercibility= coer; - } + { collation= cs; coercibility= coer; } bool set_charset(CHARSET_INFO *cs1, enum coercion co1, CHARSET_INFO *cs2, enum coercion co2); + bool binary() const + { return charset()->state & MY_CS_BINSORT ? 1 : 0 ; } + virtual void set_outer_resolving() {} // Row emulation @@ -383,6 +383,7 @@ public: Item_string(const char *str,uint length, CHARSET_INFO *cs, enum coercion coer= COER_COERCIBLE) { + set_charset(cs); str_value.set(str,length,cs); coercibility= coer; max_length=length; @@ -392,6 +393,7 @@ public: Item_string(const char *name_par, const char *str, uint length, CHARSET_INFO *cs, enum coercion coer= COER_COERCIBLE) { + set_charset(cs); str_value.set(str,length,cs); coercibility= coer; max_length=length; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a4dcc3d7092..b8eb9e19cc7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4142,10 +4142,10 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case STRING_RESULT: if (item->max_length > 255) new_field= new Field_blob(item->max_length,maybe_null, - item->name,table,item->str_value.charset()); + item->name,table,item->charset()); else new_field= new Field_string(item->max_length,maybe_null, - item->name,table,item->str_value.charset()); + item->name,table,item->charset()); break; case ROW_RESULT: default: From 1bd306ccd49e0ea6b9c91339b78b7b73f4137abd Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Tue, 24 Jun 2003 12:10:35 +0300 Subject: [PATCH 11/27] Fixed some new memory leaks Updated VC++ files --- VC++Files/client/mysql.dsp | 10 +- VC++Files/client/mysqlclient.dsp | 26 +-- .../libmysqld/examples/test_libmysqld.dsp | 24 ++- VC++Files/libmysqld/libmysqld.def | 185 ++++++++++++------ VC++Files/libmysqld/libmysqld.dsp | 50 ++++- VC++Files/myisam/myisam.dsp | 4 + VC++Files/mysql.dsw | 9 - VC++Files/sql/mysqld.dsp | 26 +-- include/mysql.h | 1 + libmysql/libmysql.def | 147 ++++++-------- libmysqld/libmysqld.c | 102 +++++++++- libmysqld/libmysqld.def | 185 ++++++++++++------ myisam/mi_preload.c | 22 +-- scripts/make_win_src_distribution.sh | 5 +- scripts/mysql_create_system_tables.sh | 11 +- scripts/mysql_fix_privilege_tables.sh | 3 + sql-common/client.c | 15 +- sql/item_sum.cc | 3 +- sql/slave.cc | 9 +- sql/sql_client.cc | 2 +- sql/sql_help.cc | 25 ++- 21 files changed, 566 insertions(+), 298 deletions(-) diff --git a/VC++Files/client/mysql.dsp b/VC++Files/client/mysql.dsp index 1cd03ee2fcc..c0fd1e785d5 100644 --- a/VC++Files/client/mysql.dsp +++ b/VC++Files/client/mysql.dsp @@ -87,7 +87,7 @@ LINK32=link.exe # Name "mysql - Win32 Debug" # Begin Source File -SOURCE=..\mysys\my_gethostbyname.c +SOURCE=.\completion_hash.cpp # End Source File # Begin Source File @@ -101,6 +101,14 @@ SOURCE=.\mysql.cpp !ENDIF +# End Source File +# Begin Source File + +SOURCE=.\readline.cpp +# End Source File +# Begin Source File + +SOURCE=.\sql_string.cpp # End Source File # End Target # End Project diff --git a/VC++Files/client/mysqlclient.dsp b/VC++Files/client/mysqlclient.dsp index 2f66d99b33c..0f4c46acd2a 100644 --- a/VC++Files/client/mysqlclient.dsp +++ b/VC++Files/client/mysqlclient.dsp @@ -25,7 +25,7 @@ CFG=mysqlclient - Win32 Debug # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" -CPP=xicl6.exe +CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "mysqlclient - Win32 Release" @@ -48,7 +48,7 @@ RSC=rc.exe BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LIB32=xilink6.exe -lib +LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"..\lib_release\mysqlclient.lib" @@ -72,7 +72,7 @@ LIB32=xilink6.exe -lib BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LIB32=xilink6.exe -lib +LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"..\lib_debug\mysqlclient.lib" @@ -108,14 +108,6 @@ SOURCE=..\libmysql\client.c # End Source File # Begin Source File -SOURCE=.\completion_hash.cpp -# End Source File -# Begin Source File - -SOURCE=.\completion_hash.h -# End Source File -# Begin Source File - SOURCE="..\strings\ctype-big5.c" # End Source File # Begin Source File @@ -426,10 +418,6 @@ SOURCE=..\libmysql\password.c # End Source File # Begin Source File -SOURCE=.\readline.cpp -# End Source File -# Begin Source File - SOURCE=..\mysys\safemalloc.c # End Source File # Begin Source File @@ -438,14 +426,6 @@ SOURCE=..\mysys\sha1.c # End Source File # Begin Source File -SOURCE=.\sql_string.cpp -# End Source File -# Begin Source File - -SOURCE=.\sql_string.h -# End Source File -# Begin Source File - SOURCE=..\strings\str2int.c # End Source File # Begin Source File diff --git a/VC++Files/libmysqld/examples/test_libmysqld.dsp b/VC++Files/libmysqld/examples/test_libmysqld.dsp index d5fd0a0982d..0f4b09d963e 100644 --- a/VC++Files/libmysqld/examples/test_libmysqld.dsp +++ b/VC++Files/libmysqld/examples/test_libmysqld.dsp @@ -7,18 +7,18 @@ CFG=test_libmysqld - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "test_libmysqld.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "test_libmysqld.mak" CFG="test_libmysqld - Win32 Release" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "test_libmysqld - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -55,7 +55,19 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File +SOURCE=..\..\client\completion_hash.cpp +# End Source File +# Begin Source File + SOURCE=..\..\client\mysql.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\client\readline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\client\sql_string.cpp # End Source File # End Group # Begin Source File diff --git a/VC++Files/libmysqld/libmysqld.def b/VC++Files/libmysqld/libmysqld.def index c6615ee971c..c3f757b5f1a 100644 --- a/VC++Files/libmysqld/libmysqld.def +++ b/VC++Files/libmysqld/libmysqld.def @@ -1,65 +1,130 @@ LIBRARY LIBMYSQLD -DESCRIPTION 'MySQL 4.0 Embedded Server Library' -VERSION 4.0 +DESCRIPTION 'MySQL 4.1 Embedded Server Library' +VERSION 4.1 EXPORTS - mysql_server_end - mysql_server_init - mysql_use_result - mysql_thread_safe - mysql_thread_id - mysql_store_result - mysql_stat - mysql_shutdown - mysql_select_db - mysql_row_tell - mysql_row_seek - mysql_real_query - mysql_real_connect - mysql_query - mysql_ping - mysql_options - mysql_num_rows - mysql_num_fields - mysql_list_tables - mysql_list_processes - mysql_list_fields - mysql_list_dbs - mysql_kill - mysql_insert_id - mysql_init - mysql_info - mysql_get_server_info - mysql_get_proto_info - mysql_get_host_info - mysql_get_client_info - mysql_free_result - mysql_field_tell + _dig_vec + bmove_upp + delete_dynamic + free_defaults + getopt_compare_strings + getopt_ull_limit_value + handle_options + init_dynamic_array + insert_dynamic + int2str + is_prefix + list_add + list_delete + load_defaults + max_allowed_packet + my_end + my_getopt_print_errors + my_init + my_malloc + my_memdup + my_no_flags_free + my_path + my_print_help + my_print_variables + my_realloc + my_strdup + my_thread_end + my_thread_init + myodbc_remove_escape + mysql_affected_rows + mysql_autocommit + mysql_change_user + mysql_character_set_name + mysql_close + mysql_commit + mysql_data_seek + mysql_debug + mysql_dump_debug_info + mysql_eof + mysql_errno + mysql_error + mysql_escape_string + mysql_fetch_field + mysql_fetch_field_direct + mysql_fetch_fields + mysql_fetch_lengths + mysql_fetch_row mysql_field_count mysql_field_seek - mysql_fetch_row - mysql_fetch_lengths - mysql_fetch_fields - mysql_fetch_field_direct - mysql_fetch_field - mysql_escape_string - mysql_real_escape_string - mysql_error - mysql_errno - mysql_eof - mysql_dump_debug_info - mysql_drop_db - mysql_debug - mysql_data_seek - mysql_create_db - mysql_character_set_name - mysql_change_user - mysql_connect - mysql_close - mysql_affected_rows - mysql_thread_init - mysql_thread_end - mysql_send_query - mysql_read_query_result - mysql_refresh + mysql_field_tell + mysql_free_result + mysql_get_client_info + mysql_get_host_info + mysql_get_proto_info + mysql_get_server_info + mysql_info + mysql_init + mysql_insert_id + mysql_kill + mysql_list_dbs + mysql_list_fields + mysql_list_processes + mysql_list_tables + mysql_more_results + mysql_next_result + mysql_num_fields + mysql_num_rows mysql_odbc_escape_string - myodbc_remove_escape + mysql_options + mysql_ping + mysql_query + mysql_read_query_result + mysql_real_connect + mysql_real_escape_string + mysql_real_query + mysql_refresh + mysql_rollback + mysql_row_seek + mysql_row_tell + mysql_select_db + mysql_send_query + mysql_shutdown + mysql_ssl_set + mysql_stat + mysql_store_result + mysql_sqlstate + mysql_thread_id + mysql_thread_safe + mysql_use_result + mysql_warning_count + net_buffer_length + set_dynamic + strcend + strcont + strdup_root + strfill + strinstr + strmake + strmov + strxmov + mysql_server_end + mysql_server_init + get_tty_password + sql_protocol_typelib + mysql_get_server_version + mysql_sqlstate + charsets_dir + disabled_my_option + my_charset_latin1 + init_alloc_root + my_progname + get_charset_by_csname + print_defaults + find_type + strxnmov + strend + my_fopen + my_fclose + unpack_filename + str2int + int10_to_str + longlong10_to_str + my_snprintf_8bit + alloc_root + free_root + my_read diff --git a/VC++Files/libmysqld/libmysqld.dsp b/VC++Files/libmysqld/libmysqld.dsp index 4db155e6ee6..691c66a074d 100644 --- a/VC++Files/libmysqld/libmysqld.dsp +++ b/VC++Files/libmysqld/libmysqld.dsp @@ -43,7 +43,8 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBMYSQLD_EXPORTS" /YX /FD /c -# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /D "__WIN__" /FR /FD /mktyplib203 /win32 # ADD BASE MTL /c +# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../sql" /I "../regex" /I "../bdb/build_win32" /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /D "__WIN__" /FR /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x416 /d "NDEBUG" # ADD RSC /l 0x416 /d "NDEBUG" @@ -68,7 +69,8 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBMYSQLD_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MT /W3 /Gm /Zi /Od /I "../include" /I "../sql" /I "../regex" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /D "__WIN__" /FD /GZ /mktyplib203 /win32 # ADD BASE MTL /c +# ADD CPP /nologo /MT /W3 /Gm /Zi /Od /I "../include" /I "../sql" /I "../regex" /I "../bdb/build_win32" /I "../zlib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /D "__WIN__" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x416 /d "_DEBUG" # ADD RSC /l 0x416 /d "_DEBUG" @@ -87,7 +89,11 @@ LINK32=link.exe # Name "libmysqld - Win32 Debug" # Begin Source File -SOURCE=.\client.c +SOURCE="..\strings\ctype-latin1.c" +# End Source File +# Begin Source File + +SOURCE=..\mysys\default.c # End Source File # Begin Source File @@ -111,7 +117,7 @@ SOURCE=..\sql\filesort.cpp # End Source File # Begin Source File -SOURCE=..\libmysql\get_password.c +SOURCE=..\client\get_password.c # End Source File # Begin Source File @@ -159,6 +165,10 @@ SOURCE=..\sql\init.cpp # End Source File # Begin Source File +SOURCE=..\strings\int2str.c +# End Source File +# Begin Source File + SOURCE=..\sql\item.cpp # End Source File # Begin Source File @@ -240,6 +250,14 @@ SOURCE=..\sql\mf_iocache.cpp # End Source File # Begin Source File +SOURCE=..\mysys\my_alloc.c +# End Source File +# Begin Source File + +SOURCE=..\mysys\my_getopt.c +# End Source File +# Begin Source File + SOURCE=..\sql\net_serv.cpp # End Source File # Begin Source File @@ -384,6 +402,10 @@ SOURCE=..\sql\sql_show.cpp # End Source File # Begin Source File +SOURCE=..\sql\sql_state.c +# End Source File +# Begin Source File + SOURCE=..\sql\sql_string.cpp # End Source File # Begin Source File @@ -412,6 +434,26 @@ SOURCE=..\sql\sql_yacc.cpp # End Source File # Begin Source File +SOURCE=..\strings\str2int.c +# End Source File +# Begin Source File + +SOURCE=..\strings\strcend.c +# End Source File +# Begin Source File + +SOURCE=..\strings\strcont.c +# End Source File +# Begin Source File + +SOURCE=..\strings\strinstr.c +# End Source File +# Begin Source File + +SOURCE=..\strings\strxnmov.c +# End Source File +# Begin Source File + SOURCE=..\sql\table.cpp # End Source File # Begin Source File diff --git a/VC++Files/myisam/myisam.dsp b/VC++Files/myisam/myisam.dsp index 40d157a1c75..38cac3a0aba 100644 --- a/VC++Files/myisam/myisam.dsp +++ b/VC++Files/myisam/myisam.dsp @@ -193,6 +193,10 @@ SOURCE=.\mi_panic.c # End Source File # Begin Source File +SOURCE=.\mi_preload.c +# End Source File +# Begin Source File + SOURCE=.\mi_range.c # End Source File # Begin Source File diff --git a/VC++Files/mysql.dsw b/VC++Files/mysql.dsw index 9903c91ba1b..d6903f4dbc7 100644 --- a/VC++Files/mysql.dsw +++ b/VC++Files/mysql.dsw @@ -725,19 +725,10 @@ Package=<5> Package=<4> {{{ - Begin Project Dependency - Project_Dep_Name strings - End Project Dependency - Begin Project Dependency - Project_Dep_Name mysys - End Project Dependency Begin Project Dependency Project_Dep_Name libmysqld End Project Dependency Begin Project Dependency - Project_Dep_Name vio - End Project Dependency - Begin Project Dependency Project_Dep_Name zlib End Project Dependency }}} diff --git a/VC++Files/sql/mysqld.dsp b/VC++Files/sql/mysqld.dsp index 6aab591120a..8192623f957 100644 --- a/VC++Files/sql/mysqld.dsp +++ b/VC++Files/sql/mysqld.dsp @@ -28,7 +28,7 @@ CFG=mysqld - Win32 Release # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" -CPP=xicl6.exe +CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "mysqld - Win32 Release" @@ -45,14 +45,14 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../zlib" /D "NDEBUG" /D "DBUG_OFF" /D "HAVE_INNOBASE_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_DLOPEN" /FD /c +# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../zlib" /I "../include" /I "../regex" /D "NDEBUG" /D "DBUG_OFF" /D "HAVE_INNOBASE_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_DLOPEN" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x410 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=xilink6.exe +LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../client_release/mysqld-opt.exe" # SUBTRACT LINK32 /debug @@ -71,14 +71,14 @@ LINK32=xilink6.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /MTd /W3 /Gm /ZI /Od /I "../include" /I "../regex" /I "../bdb/build_win32" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_DLOPEN" /FD /c +# ADD CPP /nologo /G6 /MTd /W3 /Gm /ZI /Od /I "../bdb/build_win32" /I "../include" /I "../regex" /I "../zlib" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_DLOPEN" /FD /c # SUBTRACT CPP /Fr /YX # ADD BASE RSC /l 0x410 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=xilink6.exe +LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_debug\dbug.lib ..\lib_debug\vio.lib ..\lib_debug\isam.lib ..\lib_debug\merge.lib ..\lib_debug\mysys.lib ..\lib_debug\strings.lib ..\lib_debug\regex.lib ..\lib_debug\heap.lib ..\lib_debug\bdb.lib ..\lib_debug\innodb.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqld.exe" /pdbtype:sept @@ -98,14 +98,14 @@ LINK32=xilink6.exe # PROP Target_Dir "" # ADD BASE CPP /nologo /G5 /MT /W3 /O2 /I "../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__WIN32__" /D "DBUG_OFF" /FD /c # SUBTRACT BASE CPP /YX -# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_DLOPEN" /FD /c +# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../zlib" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_DLOPEN" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x410 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=xilink6.exe +LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\dbug.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib /nologo /subsystem:console /debug /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innodb.lib ..\lib_release\zlib.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-nt.exe" # SUBTRACT LINK32 /pdb:none /debug @@ -126,14 +126,14 @@ LINK32=xilink6.exe # PROP Target_Dir "" # ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /FD /c # SUBTRACT BASE CPP /YX -# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../bdb/build_win32" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "USE_SYMDIR" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_DLOPEN" /FD /c +# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../bdb/build_win32" /I "../include" /I "../regex" /I "../zlib" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "USE_SYMDIR" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_DLOPEN" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=xilink6.exe +LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-nt.exe" # SUBTRACT BASE LINK32 /pdb:none /debug # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys-max.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-max-nt.exe" @@ -155,14 +155,14 @@ LINK32=xilink6.exe # PROP Target_Dir "" # ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /FD /c # SUBTRACT BASE CPP /YX -# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../bdb/build_win32" /D "NDEBUG" /D "DBUG_OFF" /D "USE_SYMDIR" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_DLOPEN" /FD /c +# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../bdb/build_win32" /I "../include" /I "../regex" /I "../zlib" /D "NDEBUG" /D "DBUG_OFF" /D "USE_SYMDIR" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_DLOPEN" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=xilink6.exe +LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /out:"../client_release/mysqld-opt.exe" # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys-max.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib ..\lib_release\zlib.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../client_release/mysqld-max.exe" # SUBTRACT LINK32 /debug @@ -893,6 +893,10 @@ SOURCE=.\sql_class.cpp # End Source File # Begin Source File +SOURCE=.\sql_client.cpp +# End Source File +# Begin Source File + SOURCE=.\sql_crypt.cpp # End Source File # Begin Source File diff --git a/include/mysql.h b/include/mysql.h index 337e080e4cc..bd63a10ba45 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -266,6 +266,7 @@ typedef struct st_mysql my_bool free_me; /* If free in mysql_close */ my_ulonglong insert_id; /* id if insert on table with NEXTNR */ unsigned int last_errno; + unsigned int server_status; char *last_error; /* Used by embedded server */ char sqlstate[SQLSTATE_LENGTH+1]; /* Used by embedded server */ } MYSQL; diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index 8c97ef45aa3..d641ca57274 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -2,8 +2,43 @@ LIBRARY LIBMYSQL DESCRIPTION 'MySQL 4.1 Client Library' VERSION 6.0 EXPORTS + _dig_vec + bmove_upp + delete_dynamic + free_defaults + getopt_compare_strings + getopt_ull_limit_value + handle_options + init_dynamic_array + insert_dynamic + int2str + is_prefix + list_add + list_delete + load_defaults + max_allowed_packet + my_end + my_getopt_print_errors + my_init + my_malloc + my_memdup + my_no_flags_free + my_path + my_print_help + my_print_variables + my_realloc + my_strdup + my_thread_end + my_thread_init + myodbc_remove_escape mysql_affected_rows + mysql_autocommit + mysql_bind_param + mysql_bind_result + mysql_change_user + mysql_character_set_name mysql_close + mysql_commit mysql_data_seek mysql_debug mysql_dump_debug_info @@ -11,6 +46,9 @@ EXPORTS mysql_errno mysql_error mysql_escape_string + mysql_execute + mysql_fetch + mysql_fetch_column mysql_fetch_field mysql_fetch_field_direct mysql_fetch_fields @@ -32,113 +70,54 @@ EXPORTS mysql_list_fields mysql_list_processes mysql_list_tables + mysql_more_results + mysql_next_result mysql_num_fields mysql_num_rows mysql_odbc_escape_string mysql_options + mysql_param_count + mysql_param_result mysql_ping + mysql_prepare + mysql_prepare_result mysql_query + mysql_read_query_result mysql_real_connect + mysql_real_escape_string mysql_real_query mysql_refresh + mysql_rollback mysql_row_seek mysql_row_tell mysql_select_db + mysql_send_long_data + mysql_send_query mysql_shutdown + mysql_ssl_set mysql_stat + mysql_stmt_affected_rows + mysql_stmt_close + mysql_stmt_data_seek + mysql_stmt_errno + mysql_stmt_error + mysql_stmt_free_result + mysql_stmt_num_rows + mysql_stmt_row_seek + mysql_stmt_row_tell + mysql_stmt_store_result mysql_store_result mysql_thread_id + mysql_thread_safe mysql_use_result - bmove_upp - delete_dynamic - _dig_vec - init_dynamic_array - insert_dynamic - int2str - is_prefix - list_add - list_delete - max_allowed_packet - my_init - my_end - my_strdup - my_malloc - my_memdup - my_no_flags_free - my_realloc - my_thread_end - my_thread_init + mysql_warning_count net_buffer_length set_dynamic strcend + strcont strdup_root strfill strinstr strmake strmov strxmov - myodbc_remove_escape - mysql_thread_safe - mysql_character_set_name - mysql_change_user - mysql_send_query - mysql_read_query_result - mysql_real_escape_string - mysql_ssl_set - mysql_real_connect - mysql_master_query - mysql_master_send_query - mysql_slave_query - mysql_slave_send_query - mysql_enable_rpl_parse - mysql_disable_rpl_parse - mysql_rpl_parse_enabled - mysql_enable_reads_from_master - mysql_disable_reads_from_master - mysql_reads_from_master_enabled - mysql_rpl_query_type - mysql_rpl_probe - mysql_set_master - mysql_add_slave - my_getopt_print_errors - handle_options - my_print_help - my_print_variables - getopt_ull_limit_value - getopt_compare_strings - mysql_warning_count - mysql_prepare - mysql_execute - mysql_param_count - mysql_bind_param - mysql_bind_result - mysql_param_result - mysql_prepare_result - mysql_stmt_close - mysql_stmt_free_result - mysql_stmt_error - mysql_stmt_errno - mysql_fetch - mysql_fetch_column - mysql_send_long_data - mysql_next_result - mysql_stmt_affected_rows - mysql_stmt_store_result - mysql_stmt_data_seek - mysql_stmt_row_seek - mysql_stmt_row_tell - mysql_stmt_num_rows - mysql_more_results - mysql_commit - mysql_rollback - mysql_autocommit - load_defaults - free_defaults - my_path - - - - - - - diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index a2d69b30c0d..ba2dfd68c00 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -49,6 +49,8 @@ static my_bool mysql_client_init=0; uint mysql_port=0; my_string mysql_unix_port=0; +const char *not_error_sqlstate= "00000"; + const char *sql_protocol_names_lib[] = { "TCP", "SOCKET", "PIPE", "MEMORY",NullS }; TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"", @@ -516,6 +518,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, client_flag&= ~CLIENT_COMPRESS; if (db) client_flag|=CLIENT_CONNECT_WITH_DB; + mysql->server_status= SERVER_STATUS_AUTOCOMMIT; if (mysql->options.init_commands) { @@ -1040,9 +1043,9 @@ mysql_list_fields(MYSQL *mysql __attribute__((unused)), const char *table __attr /* List all running processes (threads) in server */ MYSQL_RES * STDCALL -mysql_list_processes(MYSQL *mysql) +mysql_list_processes(MYSQL *mysql __attribute__((unused))) { -#ifdef DUMMY +#ifdef FOR_THE_FUTURE MYSQL_DATA *fields; uint field_count; uchar *pos; @@ -1063,7 +1066,7 @@ mysql_list_processes(MYSQL *mysql) mysql->status=MYSQL_STATUS_GET_RESULT; mysql->field_count=field_count; DBUG_RETURN(mysql_store_result(mysql)); -#endif /*DUMMY*/ +#endif /* FOR_THE_FUTURE */ return 0; } @@ -1535,3 +1538,96 @@ myodbc_remove_escape(MYSQL *mysql,char *name) } *to=0; } + + +/******************************************************************** + Transactional APIs +*********************************************************************/ + +/* + Commit the current transaction +*/ + +my_bool STDCALL mysql_commit(MYSQL * mysql) +{ + DBUG_ENTER("mysql_commit"); + DBUG_RETURN((my_bool) mysql_real_query(mysql, "commit", 6)); +} + +/* + Rollback the current transaction +*/ + +my_bool STDCALL mysql_rollback(MYSQL * mysql) +{ + DBUG_ENTER("mysql_rollback"); + DBUG_RETURN((my_bool) mysql_real_query(mysql, "rollback", 8)); +} + + +/* + Set autocommit to either true or false +*/ + +my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode) +{ + DBUG_ENTER("mysql_autocommit"); + DBUG_PRINT("enter", ("mode : %d", auto_mode)); + + if (auto_mode) /* set to true */ + DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=1", 16)); + DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=0", 16)); +} + + +/******************************************************************** + Multi query execution + SPs APIs +*********************************************************************/ + +/* + Returns if there are any more query results exists to be read using + mysql_next_result() +*/ + +my_bool STDCALL mysql_more_results(MYSQL *mysql) +{ + my_bool res; + DBUG_ENTER("mysql_more_results"); + + res= ((mysql->server_status & SERVER_MORE_RESULTS_EXISTS) ? + 1: 0); + DBUG_PRINT("exit",("More results exists ? %d", res)); + DBUG_RETURN(res); +} + + +/* + Reads and returns the next query results +*/ + +my_bool STDCALL mysql_next_result(MYSQL *mysql) +{ + DBUG_ENTER("mysql_next_result"); + + mysql->last_error[0]= 0; + mysql->last_errno= 0; + strmov(mysql->sqlstate, not_error_sqlstate); + mysql->affected_rows= ~(my_ulonglong) 0; + + if (mysql->server_status & SERVER_MORE_RESULTS_EXISTS) + DBUG_RETURN(mysql_read_query_result(mysql)); + + DBUG_RETURN(0); +} + + +my_bool STDCALL +mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , + const char *key __attribute__((unused)), + const char *cert __attribute__((unused)), + const char *ca __attribute__((unused)), + const char *capath __attribute__((unused)), + const char *cipher __attribute__((unused))) +{ + return 0; +} diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index c6615ee971c..c3f757b5f1a 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -1,65 +1,130 @@ LIBRARY LIBMYSQLD -DESCRIPTION 'MySQL 4.0 Embedded Server Library' -VERSION 4.0 +DESCRIPTION 'MySQL 4.1 Embedded Server Library' +VERSION 4.1 EXPORTS - mysql_server_end - mysql_server_init - mysql_use_result - mysql_thread_safe - mysql_thread_id - mysql_store_result - mysql_stat - mysql_shutdown - mysql_select_db - mysql_row_tell - mysql_row_seek - mysql_real_query - mysql_real_connect - mysql_query - mysql_ping - mysql_options - mysql_num_rows - mysql_num_fields - mysql_list_tables - mysql_list_processes - mysql_list_fields - mysql_list_dbs - mysql_kill - mysql_insert_id - mysql_init - mysql_info - mysql_get_server_info - mysql_get_proto_info - mysql_get_host_info - mysql_get_client_info - mysql_free_result - mysql_field_tell + _dig_vec + bmove_upp + delete_dynamic + free_defaults + getopt_compare_strings + getopt_ull_limit_value + handle_options + init_dynamic_array + insert_dynamic + int2str + is_prefix + list_add + list_delete + load_defaults + max_allowed_packet + my_end + my_getopt_print_errors + my_init + my_malloc + my_memdup + my_no_flags_free + my_path + my_print_help + my_print_variables + my_realloc + my_strdup + my_thread_end + my_thread_init + myodbc_remove_escape + mysql_affected_rows + mysql_autocommit + mysql_change_user + mysql_character_set_name + mysql_close + mysql_commit + mysql_data_seek + mysql_debug + mysql_dump_debug_info + mysql_eof + mysql_errno + mysql_error + mysql_escape_string + mysql_fetch_field + mysql_fetch_field_direct + mysql_fetch_fields + mysql_fetch_lengths + mysql_fetch_row mysql_field_count mysql_field_seek - mysql_fetch_row - mysql_fetch_lengths - mysql_fetch_fields - mysql_fetch_field_direct - mysql_fetch_field - mysql_escape_string - mysql_real_escape_string - mysql_error - mysql_errno - mysql_eof - mysql_dump_debug_info - mysql_drop_db - mysql_debug - mysql_data_seek - mysql_create_db - mysql_character_set_name - mysql_change_user - mysql_connect - mysql_close - mysql_affected_rows - mysql_thread_init - mysql_thread_end - mysql_send_query - mysql_read_query_result - mysql_refresh + mysql_field_tell + mysql_free_result + mysql_get_client_info + mysql_get_host_info + mysql_get_proto_info + mysql_get_server_info + mysql_info + mysql_init + mysql_insert_id + mysql_kill + mysql_list_dbs + mysql_list_fields + mysql_list_processes + mysql_list_tables + mysql_more_results + mysql_next_result + mysql_num_fields + mysql_num_rows mysql_odbc_escape_string - myodbc_remove_escape + mysql_options + mysql_ping + mysql_query + mysql_read_query_result + mysql_real_connect + mysql_real_escape_string + mysql_real_query + mysql_refresh + mysql_rollback + mysql_row_seek + mysql_row_tell + mysql_select_db + mysql_send_query + mysql_shutdown + mysql_ssl_set + mysql_stat + mysql_store_result + mysql_sqlstate + mysql_thread_id + mysql_thread_safe + mysql_use_result + mysql_warning_count + net_buffer_length + set_dynamic + strcend + strcont + strdup_root + strfill + strinstr + strmake + strmov + strxmov + mysql_server_end + mysql_server_init + get_tty_password + sql_protocol_typelib + mysql_get_server_version + mysql_sqlstate + charsets_dir + disabled_my_option + my_charset_latin1 + init_alloc_root + my_progname + get_charset_by_csname + print_defaults + find_type + strxnmov + strend + my_fopen + my_fclose + unpack_filename + str2int + int10_to_str + longlong10_to_str + my_snprintf_8bit + alloc_root + free_root + my_read diff --git a/myisam/mi_preload.c b/myisam/mi_preload.c index be45be66ecf..a5d9bec160e 100644 --- a/myisam/mi_preload.c +++ b/myisam/mi_preload.c @@ -42,35 +42,32 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) { uint i; - uint length; - uint block_length= 0; + ulong length, block_length= 0; uchar *buff= NULL; MYISAM_SHARE* share= info->s; uint keys= share->state.header.keys; MI_KEYDEF *keyinfo= share->keyinfo; my_off_t key_file_length= share->state.state.key_file_length; my_off_t pos= share->base.keystart; + DBUG_ENTER("mi_preload"); if (!keys || !key_map || key_file_length == pos) - return 0; + DBUG_RETURN(0); block_length= keyinfo[0].block_length; - if (!key_map) - return 0; - /* Check whether all indexes use the same block size */ for (i= 1 ; i < keys ; i++) { if (keyinfo[i].block_length != block_length) - return (my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE); + DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE); } length= info->preload_buff_size/block_length * block_length; set_if_bigger(length, block_length); if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME)))) - return (my_errno= HA_ERR_OUT_OF_MEM); + DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM); if (flush_key_blocks(share->kfile, FLUSH_RELEASE)) goto err; @@ -78,7 +75,8 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) do { /* Read the next block of index file into the preload buffer */ - set_if_smaller(length, key_file_length-pos); + if ((my_off_t) length > (key_file_length-pos)) + length= (ulong) (key_file_length-pos); if (my_pread(share->kfile, (byte*) buff, length, pos, MYF(MY_FAE))) goto err; @@ -103,16 +101,14 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) goto err; pos+= length; } - } while (pos != key_file_length); my_free(buff, MYF(0)); - - return 0; + DBUG_RETURN(0); err: my_free(buff, MYF(MY_ALLOW_ZERO_PTR)); - return (my_errno= errno); + DBUG_RETURN(my_errno= errno); } diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution.sh index 1be301ee92a..df7ac29ee0d 100755 --- a/scripts/make_win_src_distribution.sh +++ b/scripts/make_win_src_distribution.sh @@ -251,7 +251,7 @@ touch $BASE/innobase/ib_config.h cd $SOURCE for i in COPYING ChangeLog README \ INSTALL-SOURCE INSTALL-WIN \ - INSTALL-WIN-SOURCE + INSTALL-WIN-SOURCE \ Docs/manual_toc.html Docs/manual.html \ Docs/mysqld_error.txt Docs/INSTALL-BINARY @@ -350,7 +350,7 @@ set_tarzip_options() else ZIPFILE1=zip ZIPFILE2="" - OPT="-vr" + OPT="-r" EXT=".zip" NEED_COMPRESS=0 if [ "$SILENT" = "1" ] ; then @@ -382,6 +382,7 @@ print_debug "Using $tar to create archive" cd $TMP +rm -f $SOURCE/$NEW_NAME$EXT $tar $OPT $SOURCE/$NEW_NAME$EXT $NEW_DIR_NAME cd $SOURCE diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index 51fbb8a8097..1f0579f87c2 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -145,20 +145,19 @@ then then i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); - REPLACE INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); INSERT INTO user (host,user) values ('localhost',''); INSERT INTO user (host,user) values ('$hostname','');" else - i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); - REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); - INSERT INTO user (host,user) values ('localhost','');" + i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);" if test "$windows" -eq 0 then i_u="$i_u INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); - REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); INSERT INTO user (host,user) values ('$hostname','');" - fi + INSERT INTO user (host,user) values ('localhost',''); + else + i_u="INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);" + fi fi fi diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index 5d392f719f0..4b6f74eae06 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -57,6 +57,9 @@ then elif test -x @bindir@/mysql_print_defaults then print_defaults="@bindir@/mysql_print_defaults" +elif test -x extra/my_print_defaults +then + print_defaults="extra/my_print_defaults" else print_defaults="my_print_defaults" fi diff --git a/sql-common/client.c b/sql-common/client.c index 33f2b996971..721164c8301 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2022,7 +2022,6 @@ my_bool mysql_reconnect(MYSQL *mysql) } mysql_init(&tmp_mysql); tmp_mysql.options=mysql->options; - bzero((char*) &mysql->options,sizeof(mysql->options)); tmp_mysql.rpl_pivot = mysql->rpl_pivot; if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd, mysql->db, mysql->port, mysql->unix_socket, @@ -2033,7 +2032,9 @@ my_bool mysql_reconnect(MYSQL *mysql) strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate); DBUG_RETURN(1); } - tmp_mysql.free_me=mysql->free_me; + tmp_mysql.free_me= mysql->free_me; + /* Don't free options as these are now used in tmp_mysql */ + bzero((char*) &mysql->options,sizeof(mysql->options)); mysql->free_me=0; mysql_close(mysql); *mysql=tmp_mysql; @@ -2070,9 +2071,6 @@ mysql_select_db(MYSQL *mysql, const char *db) static void mysql_close_free_options(MYSQL *mysql) { - my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.user,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.host,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.password,MYF(MY_ALLOW_ZERO_PTR)); @@ -2099,14 +2097,17 @@ static void mysql_close_free_options(MYSQL *mysql) if (mysql->options.shared_memory_base_name != def_shared_memory_base_name) my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif /* HAVE_SMEM */ - bzero((char*) &mysql->options,sizeof(mysql->options)); + bzero((char*) &mysql->options,sizeof(mysql->options)); } static void mysql_close_free(MYSQL *mysql) { - /* Clear pointers for better safety */ my_free((gptr) mysql->host_info,MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); + /* Clear pointers for better safety */ mysql->host_info=mysql->user=mysql->passwd=mysql->db=0; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 34de672dbdb..6e606d53207 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -57,7 +57,8 @@ Item_sum::Item_sum(THD *thd, Item_sum &item): void Item_sum::mark_as_sum_func() { - current_thd->lex.current_select->with_sum_func= with_sum_func= 1; + current_thd->lex.current_select->with_sum_func= 1; + with_sum_func= 1; } diff --git a/sql/slave.cc b/sql/slave.cc index ccce8077cb8..c45c11f8bef 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2177,7 +2177,7 @@ extern "C" pthread_handler_decl(handle_slave_io,arg) DBUG_ENTER("handle_slave_io"); #ifndef DBUG_OFF -slave_begin: +slave_begin: #endif DBUG_ASSERT(mi->inited); mysql= NULL ; @@ -2218,7 +2218,7 @@ slave_begin: if (!(mi->mysql = mysql = mysql_init(NULL))) { - sql_print_error("Slave I/O thread: error in mc_mysql_init()"); + sql_print_error("Slave I/O thread: error in mysql_init()"); goto err; } @@ -2270,7 +2270,7 @@ dump"); goto err; } - thd->proc_info = "Waiiting to reconnect after a failed dump request"; + thd->proc_info = "Waiting to reconnect after a failed dump request"; end_server(mysql); /* First time retry immediately, assuming that we can recover @@ -3075,7 +3075,8 @@ replication resumed in log '%s' at position %s", mi->user, static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi, bool suppress_warnings) { - return connect_to_master(thd, mysql, mi, 1, suppress_warnings); + DBUG_ENTER("safe_reconnect"); + DBUG_RETURN(connect_to_master(thd, mysql, mi, 1, suppress_warnings)); } diff --git a/sql/sql_client.cc b/sql/sql_client.cc index 464596f0734..1ae9a23a924 100644 --- a/sql/sql_client.cc +++ b/sql/sql_client.cc @@ -18,7 +18,7 @@ This files defines some MySQL C API functions that are server specific */ -#include +#include "mysql_priv.h" /* Function called by my_net_init() to set some check variables diff --git a/sql/sql_help.cc b/sql/sql_help.cc index ba7c08ff15f..02fc8591370 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -22,6 +22,8 @@ struct st_find_field Field *field; }; +static void free_select(SQL_SELECT *sel); + /* Used fields */ static struct st_find_field init_used_fields[]= @@ -62,6 +64,7 @@ enum enum_used_fields help_relation_help_keyword_id }; + /* Fill st_find_field structure with pointers to fields @@ -94,8 +97,8 @@ static bool init_fields(THD *thd, TABLE_LIST *tables, DBUG_RETURN(0); } -/* +/* Returns variants of found topic for help (if it is just single topic, returns description and example, or else returns only names..) @@ -135,7 +138,7 @@ void memorize_variant_topic(THD *thd, TABLE *topics, int count, } else { - if (count==1) + if (count == 1) names->push_back(name); String *new_name= new String; get_field(mem_root,find_fields[help_topic_name].field,new_name); @@ -557,7 +560,7 @@ int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol, String **end= pointers + names->elements; List_iterator it(*names); - for ( pos= pointers; pos!=end; (*pos++= it++)); + for (pos= pointers; pos!=end; (*pos++= it++)); qsort(pointers,names->elements,sizeof(String*),string_ptr_cmp); @@ -627,6 +630,7 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen, return prepare_simple_select(thd,cond,tables,table,error); } + /* Server-side function 'help' @@ -783,6 +787,21 @@ int mysqld_help(THD *thd, const char *mask) res= 0; send_eof(thd); + end: + free_select(select_topics_by_name); + free_select(select_keyword_by_name); + free_select(select_cat_by_name); + free_select(select_topics_by_cat); + free_select(select_cat_by_cat); + free_select(select_root_cats); + DBUG_RETURN(res); } + + +static void free_select(SQL_SELECT *sel) +{ + if (sel) + delete sel->quick; +} From 7371150f2da45eb9bdd1ba001f02a396b0a50bc9 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Tue, 24 Jun 2003 15:11:07 +0500 Subject: [PATCH 12/27] New class DTCollation (SQL:2003 calls it "declared type collation") It's a combination of collation and its derivation (precedence order) --- sql/item.cc | 24 ++++----- sql/item.h | 109 +++++++++++++++++++++++++++---------- sql/item_cmpfunc.cc | 70 ++++++++++++------------ sql/item_cmpfunc.h | 4 +- sql/item_create.cc | 2 +- sql/item_func.cc | 41 +++++++------- sql/item_func.h | 2 +- sql/item_strfunc.cc | 128 ++++++++++++++++++-------------------------- sql/item_strfunc.h | 10 ++-- sql/log_event.cc | 2 +- sql/sql_class.h | 3 +- 11 files changed, 212 insertions(+), 183 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index d74b9d7454f..4c7b30b0410 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -39,8 +39,7 @@ Item::Item(): { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; - collation= &my_charset_bin; - coercibility= COER_COERCIBLE; + set_charset(&my_charset_bin, DERIVATION_COERCIBLE); name= 0; decimals= 0; max_length= 0; THD *thd= current_thd; @@ -68,8 +67,7 @@ Item::Item(THD *thd, Item &item): unsigned_flag(item.unsigned_flag), with_sum_func(item.with_sum_func), fixed(item.fixed), - collation(item.collation), - coercibility(item.coercibility) + collation(item.collation) { next=thd->free_list; // Put in free list thd->free_list= this; @@ -185,12 +183,12 @@ CHARSET_INFO * Item::default_charset() const return current_thd->variables.collation_connection; } -bool Item::set_charset(CHARSET_INFO *cs1, enum coercion co1, - CHARSET_INFO *cs2, enum coercion co2) +bool Item::set_charset(CHARSET_INFO *cs1, Derivation co1, + CHARSET_INFO *cs2, Derivation co2) { if (cs1 == &my_charset_bin || cs2 == &my_charset_bin) { - set_charset(&my_charset_bin, COER_NOCOLL); + set_charset(&my_charset_bin, DERIVATION_NONE); return 0; } @@ -209,7 +207,7 @@ bool Item::set_charset(CHARSET_INFO *cs1, enum coercion co1, { if (cs1 != cs2) { - if (co1 == COER_EXPLICIT) + if (co1 == DERIVATION_EXPLICIT) { return 1; } @@ -218,7 +216,7 @@ bool Item::set_charset(CHARSET_INFO *cs1, enum coercion co1, CHARSET_INFO *bin= get_charset_by_csname(cs1->csname, MY_CS_BINSORT,MYF(0)); if (!bin) return 1; - set_charset(bin, COER_NOCOLL); + set_charset(bin, DERIVATION_NONE); } } else @@ -230,7 +228,7 @@ bool Item::set_charset(CHARSET_INFO *cs1, enum coercion co1, Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name) { set_field(f); - coercibility= COER_IMPLICIT; + set_charset(DERIVATION_IMPLICIT); fixed= 1; // This item is not needed in fix_fields } @@ -239,7 +237,7 @@ Item_field::Item_field(THD *thd, Item_field &item): Item_ident(thd, item), field(item.field), result_field(item.result_field) -{ coercibility= COER_IMPLICIT; } +{ set_charset(DERIVATION_IMPLICIT); } void Item_field::set_field(Field *field_par) { @@ -251,7 +249,7 @@ void Item_field::set_field(Field *field_par) field_name=field_par->field_name; db_name=field_par->table->table_cache_key; unsigned_flag=test(field_par->flags & UNSIGNED_FLAG); - set_charset(field_par->charset(), COER_IMPLICIT); + set_charset(field_par->charset(), DERIVATION_IMPLICIT); } const char *Item_ident::full_name() const @@ -1102,7 +1100,7 @@ Item_varbinary::Item_varbinary(const char *str, uint str_length) str+=2; } *ptr=0; // Keep purify happy - coercibility= COER_COERCIBLE; + set_charset(&my_charset_bin, DERIVATION_COERCIBLE); } longlong Item_varbinary::val_int() diff --git a/sql/item.h b/sql/item.h index df9ada72ce5..ce79e70e5d6 100644 --- a/sql/item.h +++ b/sql/item.h @@ -23,6 +23,63 @@ class Protocol; struct st_table_list; void item_init(void); /* Init item functions */ + +/* + "Declared Type Collation" + A combination of collation and its deriviation. +*/ + +enum Derivation +{ + DERIVATION_COERCIBLE= 3, + DERIVATION_IMPLICIT= 2, + DERIVATION_NONE= 1, + DERIVATION_EXPLICIT= 0 +}; + +class DTCollation { +public: + CHARSET_INFO *collation; + enum Derivation derivation; + + DTCollation() + { + collation= &my_charset_bin; + derivation= DERIVATION_NONE; + } + DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg) + { + collation= collation_arg; + derivation= derivation_arg; + } + void set(DTCollation *dt) + { + collation= dt->collation; + derivation= dt->derivation; + } + void set(CHARSET_INFO *collation_arg, Derivation derivation_arg) + { + collation= collation_arg; + derivation= derivation_arg; + } + void set(CHARSET_INFO *collation_arg) + { collation= collation_arg; } + void set(Derivation derivation_arg) + { derivation= derivation_arg; } + bool aggregate(DTCollation *dt); + const char *derivation_name() const + { + switch(derivation) + { + case DERIVATION_COERCIBLE: return "COERCIBLE"; + case DERIVATION_IMPLICIT: return "IMPLICIT"; + case DERIVATION_EXPLICIT: return "EXPLICIT"; + case DERIVATION_NONE: return "NONE"; + default: return "UNKNOWN"; + } + } +}; + class Item { uint loop_id; /* Used to find selfrefering loops */ Item(const Item &); /* Prevent use of these */ @@ -41,19 +98,6 @@ public: SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM}; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; - enum coercion { COER_COERCIBLE=3, COER_IMPLICIT=2, - COER_NOCOLL=1, COER_EXPLICIT=0 }; - const char *coercion_name(enum coercion coer) const - { - switch(coer) - { - case COER_COERCIBLE: return "COERCIBLE"; - case COER_IMPLICIT: return "IMPLICIT"; - case COER_EXPLICIT: return "EXPLICIT"; - case COER_NOCOLL: return "NO COLLATION"; - default: return "UNKNOWN"; - } - } String str_value; /* used to store value */ my_string name; /* Name from select */ @@ -65,9 +109,8 @@ public: my_bool unsigned_flag; my_bool with_sum_func; my_bool fixed; /* If item fixed with fix_fields */ - CHARSET_INFO *collation; /* character set && collation */ - enum coercion coercibility; /* Precedence order of collation */ - + DTCollation collation; + // alloc & destruct is done as start of select using sql_alloc Item(); /* @@ -125,13 +168,23 @@ public: virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); } CHARSET_INFO *default_charset() const; - CHARSET_INFO *charset() const { return collation; }; + Derivation derivation() const { return collation.derivation; } + CHARSET_INFO *charset() const { return collation.collation; } void set_charset(CHARSET_INFO *cs) - { collation= cs; } - void set_charset(CHARSET_INFO *cs, enum coercion coer) - { collation= cs; coercibility= coer; } - bool set_charset(CHARSET_INFO *cs1, enum coercion co1, - CHARSET_INFO *cs2, enum coercion co2); + { collation.collation= cs; } + void set_charset(Derivation dv) + { collation.derivation= dv; } + void set_charset(CHARSET_INFO *cs, Derivation dv) + { collation.collation= cs; collation.derivation= dv; } + void set_charset(Item &item) + { collation= item.collation; } + void set_charset(DTCollation *collation_arg) + { + collation.collation= collation_arg->collation; + collation.derivation= collation_arg->derivation; + } + bool set_charset(CHARSET_INFO *cs1, Derivation dv1, + CHARSET_INFO *cs2, Derivation dv2); bool binary() const { return charset()->state & MY_CS_BINSORT ? 1 : 0 ; } @@ -180,7 +233,7 @@ public: Item_field(const char *db_par,const char *table_name_par, const char *field_name_par) :Item_ident(db_par,table_name_par,field_name_par),field(0),result_field(0) - { coercibility= COER_IMPLICIT; } + { set_charset(DERIVATION_IMPLICIT); } // Constructor need to process subselect with temporary tables (see Item) Item_field(THD *thd, Item_field &item); Item_field(Field *field); @@ -381,21 +434,19 @@ class Item_string :public Item { public: Item_string(const char *str,uint length, - CHARSET_INFO *cs, enum coercion coer= COER_COERCIBLE) + CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE) { - set_charset(cs); + set_charset(cs, dv); str_value.set(str,length,cs); - coercibility= coer; max_length=length; set_name(str, length, cs); decimals=NOT_FIXED_DEC; } Item_string(const char *name_par, const char *str, uint length, - CHARSET_INFO *cs, enum coercion coer= COER_COERCIBLE) + CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE) { - set_charset(cs); + set_charset(cs, dv); str_value.set(str,length,cs); - coercibility= coer; max_length=length; set_name(name_par,0,cs); decimals=NOT_FIXED_DEC; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5c2b9ed4682..035f85a45ba 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -23,6 +23,15 @@ #include "mysql_priv.h" #include + +static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +{ + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + fname); +} + Item_bool_func2* Item_bool_func2::eq_creator(Item *a, Item *b) { return new Item_func_eq(a, b); @@ -87,13 +96,13 @@ static bool convert_constant_item(Field *field, Item **item) return 0; } -bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, enum coercion co1, - CHARSET_INFO *cs2, enum coercion co2) +bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, Derivation co1, + CHARSET_INFO *cs2, Derivation co2) { if (cs1 == &my_charset_bin || cs2 == &my_charset_bin) { cmp_charset= &my_charset_bin; - coercibility= co1 > co2 ? co1 : co2; + //coercibility= co1 > co2 ? co1 : co2; return 0; } @@ -106,42 +115,42 @@ bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, enum coercion co1, if ((co1 <= co2) && (cs1==&my_charset_bin)) { cmp_charset= cs1; - coercibility= co1; + //coercibility= co1; } else if ((co2 <= co1) && (cs2==&my_charset_bin)) { cmp_charset= cs2; - coercibility= co2; + //coercibility= co2; } else { cmp_charset= 0; - coercibility= COER_NOCOLL; + //coercibility= DERIVATION_NOCOLL; return 1; } } else if (co1 < co2) { cmp_charset= cs1; - coercibility= co1; + //coercibility= co1; } else if (co2 < co1) { cmp_charset= cs2; - coercibility= co1; + //coercibility= co1; } else { if (cs1 == cs2) { cmp_charset= cs1; - coercibility= co1; + //coercibility= co1; } else { - coercibility= COER_NOCOLL; + //coercibility= DERIVATION_NOCOLL; cmp_charset= 0; - return (co1 == COER_EXPLICIT) ? 1 : 0; + return (co1 == DERIVATION_EXPLICIT) ? 1 : 0; } } return 0; @@ -171,13 +180,13 @@ bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables, uint strong= 0; uint weak= 0; - if ((args[0]->coercibility < args[1]->coercibility) && + if ((args[0]->derivation() < args[1]->derivation()) && !my_charset_same(args[0]->charset(), args[1]->charset()) && (args[0]->charset()->state & MY_CS_UNICODE)) { weak= 1; } - else if ((args[1]->coercibility < args[0]->coercibility) && + else if ((args[1]->derivation() < args[0]->derivation()) && !my_charset_same(args[0]->charset(), args[1]->charset()) && (args[1]->charset()->state & MY_CS_UNICODE)) { @@ -194,26 +203,23 @@ bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables, cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), args[strong]->charset()); conv= new Item_string(cstr.ptr(),cstr.length(),cstr.charset(), - args[weak]->coercibility); + args[weak]->derivation()); ((Item_string*)conv)->str_value.copy(); } else { conv= new Item_func_conv_charset(args[weak],args[strong]->charset()); - conv->coercibility= args[weak]->coercibility; + //conv->coercibility= args[weak]->derivation(); } args[weak]= conv ? conv : args[weak]; - set_cmp_charset(args[0]->charset(), args[0]->coercibility, - args[1]->charset(), args[1]->coercibility); + set_cmp_charset(args[0]->charset(), args[0]->derivation(), + args[1]->charset(), args[1]->derivation()); } } if (!cmp_charset) { /* set_cmp_charset() failed */ - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[1]->charset()->name,coercion_name(args[1]->coercibility), - func_name()); + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); return 1; } return 0; @@ -266,8 +272,8 @@ void Item_bool_func2::fix_length_and_dec() We must set cmp_charset here as we may be called from for an automatic generated item, like in natural join */ - set_cmp_charset(args[0]->charset(), args[0]->coercibility, - args[1]->charset(), args[1]->coercibility); + set_cmp_charset(args[0]->charset(), args[0]->derivation(), + args[1]->charset(), args[1]->derivation()); } @@ -744,12 +750,9 @@ Item_func_ifnull::fix_length_and_dec() args[1]->result_type())) != REAL_RESULT) decimals= 0; - if (set_charset(args[0]->charset(),args[0]->coercibility, - args[1]->charset(),args[1]->coercibility)) - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[1]->charset()->name,coercion_name(args[1]->coercibility), - func_name()); + if (set_charset(args[0]->charset(),args[0]->derivation(), + args[1]->charset(),args[1]->derivation())) + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); } @@ -825,13 +828,10 @@ Item_func_if::fix_length_and_dec() else if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT) { cached_result_type = STRING_RESULT; - if (set_charset(args[1]->charset(), args[1]->coercibility, - args[2]->charset(), args[2]->coercibility)) + if (set_charset(args[1]->charset(), args[1]->derivation(), + args[2]->charset(), args[2]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[1]->charset()->name,coercion_name(args[1]->coercibility), - func_name()); + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); return; } } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 549839b4f96..b38248d87e1 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -123,8 +123,8 @@ public: { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1); } - bool set_cmp_charset(CHARSET_INFO *cs1, enum coercion co1, - CHARSET_INFO *cs2, enum coercion co2); + bool set_cmp_charset(CHARSET_INFO *cs1, Derivation co1, + CHARSET_INFO *cs2, Derivation co2); optimize_type select_optimize() const { return OPTIMIZE_OP; } virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; } bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } diff --git a/sql/item_create.cc b/sql/item_create.cc index 6956582a8ca..90f42cee959 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -450,7 +450,7 @@ Item *create_func_version(void) { return new Item_string(NullS,server_version, (uint) strlen(server_version), - system_charset_info, Item::COER_IMPLICIT); + system_charset_info, DERIVATION_IMPLICIT); } Item *create_func_weekday(Item* a) diff --git a/sql/item_func.cc b/sql/item_func.cc index 6482d81f484..170260c6819 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -31,6 +31,14 @@ #include #endif +static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +{ + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + fname); +} + /* return TRUE if item is a constant */ bool @@ -859,14 +867,11 @@ void Item_func_min_max::fix_length_and_dec() maybe_null=0; cmp_type=item_cmp_type(cmp_type,args[i]->result_type()); if (i==0) - set_charset(args[i]->charset(), args[i]->coercibility); - else if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + set_charset(*args[i]); + else if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -1038,7 +1043,7 @@ longlong Item_func_coercibility::val_int() return 0; } null_value= 0; - return (longlong) args[0]->coercibility; + return (longlong) args[0]->derivation(); } longlong Item_func_locate::val_int() @@ -2000,7 +2005,7 @@ Item_func_set_user_var::fix_length_and_dec() void Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type, CHARSET_INFO *cs, - enum coercion coercibility) + Derivation dv) { if ((null_value=args[0]->null_value)) { @@ -2009,8 +2014,7 @@ void Item_func_set_user_var::update_hash(void *ptr, uint length, my_free(entry->value,MYF(0)); entry->value=0; entry->length=0; - entry->var_charset=cs; - entry->var_coercibility= coercibility; + collation.set(cs, dv); } else { @@ -2041,8 +2045,7 @@ void Item_func_set_user_var::update_hash(void *ptr, uint length, memcpy(entry->value,ptr,length); entry->length= length; entry->type=type; - entry->var_charset=cs; - entry->var_coercibility= coercibility; + entry->collation.set(cs, dv); } return; @@ -2085,7 +2088,7 @@ Item_func_set_user_var::val() { double value=args[0]->val(); update_hash((void*) &value,sizeof(value), REAL_RESULT, - &my_charset_bin, COER_NOCOLL); + &my_charset_bin, DERIVATION_NONE); return value; } @@ -2094,7 +2097,7 @@ Item_func_set_user_var::val_int() { longlong value=args[0]->val_int(); update_hash((void*) &value, sizeof(longlong), INT_RESULT, - &my_charset_bin, COER_NOCOLL); + &my_charset_bin, DERIVATION_NONE); return value; } @@ -2103,10 +2106,10 @@ Item_func_set_user_var::val_str(String *str) { String *res=args[0]->val_str(str); if (!res) // Null value - update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin, COER_NOCOLL); + update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin, DERIVATION_NONE); else update_hash((void*) res->ptr(), res->length(), STRING_RESULT, - res->charset(), args[0]->coercibility); + res->charset(), args[0]->derivation()); return res; } @@ -2147,7 +2150,7 @@ Item_func_get_user_var::val_str(String *str) str->set(*(longlong*) entry->value, &my_charset_bin); break; case STRING_RESULT: - if (str->copy(entry->value, entry->length, entry->var_charset)) + if (str->copy(entry->value, entry->length, entry->collation.collation)) { null_value=1; return NULL; @@ -2236,7 +2239,7 @@ void Item_func_get_user_var::fix_length_and_dec() ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)); user_var_event->user_var_event= var_entry; user_var_event->type= var_entry->type; - user_var_event->charset_number= var_entry->var_charset->number; + user_var_event->charset_number= var_entry->collation.collation->number; if (!var_entry->value) { /* NULL value*/ diff --git a/sql/item_func.h b/sql/item_func.h index 8ef2b85de52..4e39833c467 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -943,7 +943,7 @@ public: longlong val_int(); String *val_str(String *str); void update_hash(void *ptr, uint length, enum Item_result type, - CHARSET_INFO *cs, enum coercion coercibility); + CHARSET_INFO *cs, Derivation dv); bool update(); enum Item_result result_type () const { return cached_result_type; } bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 3cc5ac218e3..23df49c81be 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -36,6 +36,14 @@ String empty_string("",default_charset_info); +static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +{ + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + fname); +} + uint nr_of_decimals(const char *str) { if ((str=strchr(str,'.'))) @@ -316,17 +324,14 @@ void Item_func_concat::fix_length_and_dec() bool first_coll= 1; max_length=0; - set_charset(args[0]->charset(),args[0]->coercibility); + set_charset(*args[0]); for (uint i=0 ; i < arg_count ; i++) { max_length+=args[i]->max_length; - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -622,18 +627,15 @@ void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array, void Item_func_concat_ws::fix_length_and_dec() { - set_charset(separator->charset(),separator->coercibility); + set_charset(*separator); max_length=separator->max_length*(arg_count-1); for (uint i=0 ; i < arg_count ; i++) { max_length+=args[i]->max_length; - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -702,7 +704,7 @@ String *Item_func_reverse::val_str(String *str) void Item_func_reverse::fix_length_and_dec() { - set_charset(args[0]->charset(),args[0]->coercibility); + set_charset(*args[0]); max_length = args[0]->max_length; } @@ -826,17 +828,14 @@ void Item_func_replace::fix_length_and_dec() max_length=MAX_BLOB_WIDTH; maybe_null=1; } - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); for (i=1; i<3; i++) { - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -876,13 +875,10 @@ null: void Item_func_insert::fix_length_and_dec() { - if (set_charset(args[0]->charset(), args[0]->coercibility, - args[3]->charset(), args[3]->coercibility)) + if (set_charset(args[0]->charset(), args[0]->derivation(), + args[3]->charset(), args[3]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[3]->charset()->name,coercion_name(args[3]->coercibility), - func_name()); + my_coll_agg_error(args[0]->collation, args[3]->collation, func_name()); } max_length=args[0]->max_length+args[3]->max_length; if (max_length > MAX_BLOB_WIDTH) @@ -963,7 +959,7 @@ void Item_str_func::left_right_max_length() void Item_func_left::fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); left_right_max_length(); } @@ -990,7 +986,7 @@ String *Item_func_right::val_str(String *str) void Item_func_right::fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); left_right_max_length(); } @@ -1024,7 +1020,7 @@ void Item_func_substr::fix_length_and_dec() { max_length=args[0]->max_length; - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); if (args[1]->const_item()) { int32 start=(int32) args[1]->val_int()-1; @@ -1320,18 +1316,15 @@ void Item_func_trim::fix_length_and_dec() max_length= args[0]->max_length; if (arg_count == 1) { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); remove.set_charset(charset()); remove.set_ascii(" ",1); } else - if (set_charset(args[1]->charset(), args[1]->coercibility, - args[0]->charset(), args[0]->coercibility)) + if (set_charset(args[1]->charset(), args[1]->derivation(), + args[0]->charset(), args[0]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[1]->charset()->name,coercion_name(args[1]->coercibility), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - func_name()); + my_coll_agg_error(args[1]->collation, args[0]->collation, func_name()); } } @@ -1545,7 +1538,7 @@ String *Item_func_user::val_str(String *str) void Item_func_soundex::fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); max_length=args[0]->max_length; set_if_bigger(max_length,4); } @@ -1675,16 +1668,13 @@ void Item_func_elt::fix_length_and_dec() set_if_bigger(max_length,args[i]->max_length); set_if_bigger(decimals,args[i]->decimals); if (i == 0) - set_charset(args[i]->charset(),args[i]->coercibility); + set_charset(*args[0]); else { - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -1780,17 +1770,14 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array, void Item_func_make_set::fix_length_and_dec() { max_length=arg_count-1; - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); for (uint i=0 ; i < arg_count ; i++) { max_length+=args[i]->max_length; - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -1916,7 +1903,7 @@ inline String* alloc_buffer(String *res,String *str,String *tmp_value, void Item_func_repeat::fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); if (args[1]->const_item()) { max_length=(long) (args[0]->max_length * args[1]->val_int()); @@ -1976,13 +1963,10 @@ err: void Item_func_rpad::fix_length_and_dec() { - if (set_charset(args[0]->charset(), args[0]->coercibility, - args[2]->charset(), args[2]->coercibility)) + if (set_charset(args[0]->charset(), args[0]->derivation(), + args[2]->charset(), args[2]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[2]->charset()->name,coercion_name(args[2]->coercibility), - func_name()); + my_coll_agg_error(args[0]->collation, args[2]->collation, func_name()); } if (args[1]->const_item()) @@ -2045,13 +2029,10 @@ String *Item_func_rpad::val_str(String *str) void Item_func_lpad::fix_length_and_dec() { - if (set_charset(args[0]->charset(), args[0]->coercibility, - args[2]->charset(), args[2]->coercibility)) + if (set_charset(args[0]->charset(), args[0]->derivation(), + args[2]->charset(), args[2]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[2]->charset()->name,coercion_name(args[2]->coercibility), - func_name()); + my_coll_agg_error(args[0]->collation, args[2]->collation, func_name()); } if (args[1]->const_item()) @@ -2173,7 +2154,7 @@ void Item_func_conv_charset::fix_length_and_dec() { set_charset(conv_charset); max_length = args[0]->max_length*conv_charset->mbmaxlen; - set_charset(conv_charset, COER_IMPLICIT); + set_charset(conv_charset, DERIVATION_IMPLICIT); } @@ -2277,7 +2258,7 @@ void Item_func_set_collation::fix_length_and_dec() colname,args[0]->charset()->csname); return; } - set_charset(set_collation, COER_EXPLICIT); + set_charset(set_collation, DERIVATION_EXPLICIT); max_length= args[0]->max_length; } @@ -2468,16 +2449,13 @@ void Item_func_export_set::fix_length_and_dec() uint sep_length=(arg_count > 3 ? args[3]->max_length : 1); max_length=length*64+sep_length*63; - set_charset(args[1]->charset(), args[1]->coercibility); + set_charset(*args[1]); for (i=2 ; i < 4 && i < arg_count ; i++) { - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 6bb1c510013..3f2860f4b2b 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -153,7 +153,7 @@ public: Item_str_conv(Item *item) :Item_str_func(item) {} void fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); max_length = args[0]->max_length; } }; @@ -335,7 +335,7 @@ public: class Item_func_database :public Item_str_func { public: - Item_func_database() { coercibility= COER_IMPLICIT; } + Item_func_database() { set_charset(DERIVATION_IMPLICIT); } String *val_str(String *); void fix_length_and_dec() { @@ -348,7 +348,7 @@ public: class Item_func_user :public Item_str_func { public: - Item_func_user() { coercibility= COER_IMPLICIT; } + Item_func_user() { set_charset(DERIVATION_IMPLICIT); } String *val_str(String *); void fix_length_and_dec() { @@ -549,7 +549,7 @@ public: const char *func_name() const { return "load_file"; } void fix_length_and_dec() { - set_charset(&my_charset_bin, COER_COERCIBLE); + set_charset(&my_charset_bin, DERIVATION_COERCIBLE); maybe_null=1; max_length=MAX_BLOB_WIDTH; } @@ -586,7 +586,7 @@ public: String *val_str(String *); void fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); max_length= args[0]->max_length * 2 + 2; } }; diff --git a/sql/log_event.cc b/sql/log_event.cc index 98a877616e0..749732384c7 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2230,7 +2230,7 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli) } Item_func_set_user_var e(user_var_name, it); e.fix_fields(thd, 0, 0); - e.update_hash(val, val_len, type, charset, Item::COER_NOCOLL); + e.update_hash(val, val_len, type, charset, DERIVATION_NONE); free_root(&thd->mem_root,0); rli->inc_event_relay_log_pos(get_event_len()); diff --git a/sql/sql_class.h b/sql/sql_class.h index 33767bc4226..db99fb443c8 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -975,8 +975,7 @@ class user_var_entry char *value; ulong length, update_query_id, used_query_id; Item_result type; - CHARSET_INFO *var_charset; - enum Item::coercion var_coercibility; + DTCollation collation; }; /* Class for unique (removing of duplicates) */ From 63235ceeefbde0bf1e0d2979bbab30cfde998199 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Tue, 24 Jun 2003 15:55:39 +0500 Subject: [PATCH 13/27] mysql_create_system_tables.sh: Type fix --- scripts/mysql_create_system_tables.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index 1f0579f87c2..a98e1739260 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -153,8 +153,8 @@ then then i_u="$i_u INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); - INSERT INTO user (host,user) values ('$hostname','');" - INSERT INTO user (host,user) values ('localhost',''); + INSERT INTO user (host,user) values ('$hostname',''); + INSERT INTO user (host,user) values ('localhost','');" else i_u="INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);" fi From cb4539e8de561c7c015bebbed87968d309c84f38 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Tue, 24 Jun 2003 17:12:07 +0500 Subject: [PATCH 14/27] String comparison functions now use the same DTCollation with CONCAT() and other string functions. This allows to reuse a lot if code and to simplify further development. --- sql/item.cc | 77 +++++++++++++++---------- sql/item.h | 12 ++-- sql/item_cmpfunc.cc | 135 ++++++++++++-------------------------------- sql/item_cmpfunc.h | 10 ++-- sql/item_func.cc | 5 +- sql/item_strfunc.cc | 50 +++++++--------- 6 files changed, 116 insertions(+), 173 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 4c7b30b0410..950f27c5d69 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -183,44 +183,61 @@ CHARSET_INFO * Item::default_charset() const return current_thd->variables.collation_connection; } -bool Item::set_charset(CHARSET_INFO *cs1, Derivation co1, - CHARSET_INFO *cs2, Derivation co2) +bool DTCollation::aggregate(DTCollation &dt) { - if (cs1 == &my_charset_bin || cs2 == &my_charset_bin) + if (collation == &my_charset_bin || dt.collation == &my_charset_bin) { - set_charset(&my_charset_bin, DERIVATION_NONE); + collation= &my_charset_bin; + derivation= derivation > dt.derivation ? derivation : dt.derivation; return 0; } - - if (!my_charset_same(cs1,cs2)) - return 1; - - if (co1 < co2) + + if (!my_charset_same(collation, dt.collation)) { - set_charset(cs1, co1); - } - else if (co2 < co1) - { - set_charset(cs2, co2); - } - else // co2 == co1 - { - if (cs1 != cs2) + /* + We do allow to use binary strings (like BLOBS) + together with character strings. + Binaries have more precedance + */ + if ((derivation <= dt.derivation) && (collation == &my_charset_bin)) { - if (co1 == DERIVATION_EXPLICIT) - { - return 1; - } - else - { - CHARSET_INFO *bin= get_charset_by_csname(cs1->csname, MY_CS_BINSORT,MYF(0)); - if (!bin) - return 1; - set_charset(bin, DERIVATION_NONE); - } + // Do nothing + } + else if ((dt.derivation <= derivation) && (dt.collation==&my_charset_bin)) + { + set(dt); } else - set_charset(cs2, co2); + { + set(0, DERIVATION_NONE); + return 1; + } + } + else if (derivation < dt.derivation) + { + // Do nothing + } + else if (dt.derivation < derivation) + { + set(dt); + } + else + { + if (collation == dt.collation) + { + // Do nothing + } + else + { + if (derivation == DERIVATION_EXPLICIT) + { + set(0, DERIVATION_NONE); + return 1; + } + CHARSET_INFO *bin= get_charset_by_csname(collation->csname, + MY_CS_BINSORT,MYF(0)); + set(bin, DERIVATION_NONE); + } } return 0; } diff --git a/sql/item.h b/sql/item.h index ce79e70e5d6..e80648b89de 100644 --- a/sql/item.h +++ b/sql/item.h @@ -52,10 +52,10 @@ public: collation= collation_arg; derivation= derivation_arg; } - void set(DTCollation *dt) + void set(DTCollation &dt) { - collation= dt->collation; - derivation= dt->derivation; + collation= dt.collation; + derivation= dt.derivation; } void set(CHARSET_INFO *collation_arg, Derivation derivation_arg) { @@ -66,7 +66,9 @@ public: { collation= collation_arg; } void set(Derivation derivation_arg) { derivation= derivation_arg; } - bool aggregate(DTCollation *dt); + bool aggregate(DTCollation &dt); + bool set(DTCollation &dt1, DTCollation &dt2) + { set(dt1); return aggregate(dt2); } const char *derivation_name() const { switch(derivation) @@ -183,8 +185,6 @@ public: collation.collation= collation_arg->collation; collation.derivation= collation_arg->derivation; } - bool set_charset(CHARSET_INFO *cs1, Derivation dv1, - CHARSET_INFO *cs2, Derivation dv2); bool binary() const { return charset()->state & MY_CS_BINSORT ? 1 : 0 ; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 035f85a45ba..52bd14ed515 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -96,72 +96,26 @@ static bool convert_constant_item(Field *field, Item **item) return 0; } -bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, Derivation co1, - CHARSET_INFO *cs2, Derivation co2) -{ - if (cs1 == &my_charset_bin || cs2 == &my_charset_bin) - { - cmp_charset= &my_charset_bin; - //coercibility= co1 > co2 ? co1 : co2; - return 0; - } - - if (!my_charset_same(cs1, cs2)) - { - /* - We do allow to use BLOBS together with character strings - BLOBS have more precedance - */ - if ((co1 <= co2) && (cs1==&my_charset_bin)) - { - cmp_charset= cs1; - //coercibility= co1; - } - else if ((co2 <= co1) && (cs2==&my_charset_bin)) - { - cmp_charset= cs2; - //coercibility= co2; - } - else - { - cmp_charset= 0; - //coercibility= DERIVATION_NOCOLL; - return 1; - } - } - else if (co1 < co2) - { - cmp_charset= cs1; - //coercibility= co1; - } - else if (co2 < co1) - { - cmp_charset= cs2; - //coercibility= co1; - } - else - { - if (cs1 == cs2) - { - cmp_charset= cs1; - //coercibility= co1; - } - else - { - //coercibility= DERIVATION_NOCOLL; - cmp_charset= 0; - return (co1 == DERIVATION_EXPLICIT) ? 1 : 0; - } - } - return 0; -} - bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables, Item ** ref) { if (Item_int_func::fix_fields(thd, tables, ref)) return 1; + return 0; +} + + +void Item_bool_func2::fix_length_and_dec() +{ + max_length= 1; // Function returns 0 or 1 + + /* + As some compare functions are generated after sql_yacc, + we have to check for out of memory conditions here + */ + if (!args[0] || !args[1]) + return; /* We allow to convert to Unicode character sets in some cases. @@ -209,35 +163,12 @@ bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables, else { conv= new Item_func_conv_charset(args[weak],args[strong]->charset()); - //conv->coercibility= args[weak]->derivation(); + conv->collation.set(args[weak]->derivation()); } args[weak]= conv ? conv : args[weak]; - set_cmp_charset(args[0]->charset(), args[0]->derivation(), - args[1]->charset(), args[1]->derivation()); } } - if (!cmp_charset) - { - /* set_cmp_charset() failed */ - my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); - return 1; - } - return 0; -} - - -void Item_bool_func2::fix_length_and_dec() -{ - max_length= 1; // Function returns 0 or 1 - - /* - As some compare functions are generated after sql_yacc, - we have to check for out of memory conditions here - */ - if (!args[0] || !args[1]) - return; - - + // Make a special case of compare with fields to get nicer DATE comparisons if (args[0]->type() == FIELD_ITEM) { @@ -248,7 +179,8 @@ void Item_bool_func2::fix_length_and_dec() { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. - cmp_charset= &my_charset_bin; // For test in fix_fields + cmp_collation.set(&my_charset_bin, + DERIVATION_NONE); // For test in fix_fields return; } } @@ -262,7 +194,8 @@ void Item_bool_func2::fix_length_and_dec() { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. - cmp_charset= &my_charset_bin; // For test in fix_fields + cmp_collation.set(&my_charset_bin, + DERIVATION_NONE); // For test in fix_fields return; } } @@ -272,8 +205,12 @@ void Item_bool_func2::fix_length_and_dec() We must set cmp_charset here as we may be called from for an automatic generated item, like in natural join */ - set_cmp_charset(args[0]->charset(), args[0]->derivation(), - args[1]->charset(), args[1]->derivation()); + if (cmp_collation.set(args[0]->collation, args[1]->collation)) + { + /* set_cmp_charset() failed */ + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); + return; + } } @@ -315,7 +252,7 @@ int Arg_comparator::compare_string() if ((res2= (*b)->val_str(&owner->tmp_value2))) { owner->null_value= 0; - return sortcmp(res1,res2,owner->cmp_charset); + return sortcmp(res1,res2,owner->cmp_collation.collation); } } owner->null_value= 1; @@ -329,7 +266,7 @@ int Arg_comparator::compare_e_string() res2= (*b)->val_str(&owner->tmp_value2); if (!res1 || !res2) return test(res1 == res2); - return test(sortcmp(res1, res2, owner->cmp_charset) == 0); + return test(sortcmp(res1, res2, owner->cmp_collation.collation) == 0); } @@ -558,7 +495,7 @@ longlong Item_func_strcmp::val_int() null_value=1; return 0; } - int value= sortcmp(a,b,cmp_charset); + int value= sortcmp(a,b,cmp_collation.collation); null_value=0; return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1); } @@ -750,8 +687,7 @@ Item_func_ifnull::fix_length_and_dec() args[1]->result_type())) != REAL_RESULT) decimals= 0; - if (set_charset(args[0]->charset(),args[0]->derivation(), - args[1]->charset(),args[1]->derivation())) + if (collation.set(args[0]->collation,args[1]->collation)) my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); } @@ -828,8 +764,7 @@ Item_func_if::fix_length_and_dec() else if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT) { cached_result_type = STRING_RESULT; - if (set_charset(args[1]->charset(), args[1]->derivation(), - args[2]->charset(), args[2]->derivation())) + if (collation.set(args[1]->collation, args[2]->collation)) { my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); return; @@ -1944,7 +1879,7 @@ longlong Item_func_like::val_int() null_value=0; if (canDoTurboBM) return turboBM_matches(res->ptr(), res->length()) ? 1 : 0; - return my_wildcmp(cmp_charset, + return my_wildcmp(cmp_collation.collation, res->ptr(),res->ptr()+res->length(), res2->ptr(),res2->ptr()+res2->length(), escape,wild_one,wild_many) ? 0 : 1; @@ -2148,7 +2083,7 @@ void Item_func_like::turboBM_compute_suffixes(int *suff) *splm1 = pattern_len; - if (cmp_charset == &my_charset_bin) + if (cmp_collation.collation == &my_charset_bin) { int i; for (i = pattern_len - 2; i >= 0; i--) @@ -2251,7 +2186,7 @@ void Item_func_like::turboBM_compute_bad_character_shifts() for (i = bmBc; i < end; i++) *i = pattern_len; - if (cmp_charset == &my_charset_bin) + if (cmp_collation.collation == &my_charset_bin) { for (j = 0; j < plm1; j++) bmBc[(uint) (uchar) pattern[j]] = plm1 - j; @@ -2282,7 +2217,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const const int tlmpl= text_len - pattern_len; /* Searching */ - if (cmp_charset == &my_charset_bin) + if (cmp_collation.collation == &my_charset_bin) { while (j <= tlmpl) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index b38248d87e1..70e477402d9 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -112,25 +112,25 @@ class Item_bool_func2 :public Item_int_func protected: Arg_comparator cmp; String tmp_value1,tmp_value2; - CHARSET_INFO *cmp_charset; + DTCollation cmp_collation; public: Item_bool_func2(Item *a,Item *b): - Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), cmp_charset(0) {} + Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1) + { cmp_collation.set(0,DERIVATION_NONE);} bool fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref); void fix_length_and_dec(); void set_cmp_func() { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1); } - bool set_cmp_charset(CHARSET_INFO *cs1, Derivation co1, - CHARSET_INFO *cs2, Derivation co2); optimize_type select_optimize() const { return OPTIMIZE_OP; } virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; } bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } void print(String *str) { Item_func::print_op(str); } bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); } - virtual bool binary() const { return test(cmp_charset->state & MY_CS_BINSORT); } + virtual bool binary() const + { return test(cmp_collation.collation->state & MY_CS_BINSORT); } static Item_bool_func2* eq_creator(Item *a, Item *b); static Item_bool_func2* ne_creator(Item *a, Item *b); diff --git a/sql/item_func.cc b/sql/item_func.cc index 170260c6819..d0362ea9369 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -867,9 +867,8 @@ void Item_func_min_max::fix_length_and_dec() maybe_null=0; cmp_type=item_cmp_type(cmp_type,args[i]->result_type()); if (i==0) - set_charset(*args[i]); - else if (set_charset(charset(), derivation(), - args[i]->charset(), args[i]->derivation())) + collation.set(args[0]->collation); + if (collation.aggregate(args[i]->collation)) { my_coll_agg_error(collation, args[i]->collation, func_name()); break; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 23df49c81be..1c770456793 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -324,12 +324,11 @@ void Item_func_concat::fix_length_and_dec() bool first_coll= 1; max_length=0; - set_charset(*args[0]); + collation.set(args[0]->collation); for (uint i=0 ; i < arg_count ; i++) { max_length+=args[i]->max_length; - if (set_charset(charset(), derivation(), - args[i]->charset(), args[i]->derivation())) + if (collation.aggregate(args[i]->collation)) { my_coll_agg_error(collation, args[i]->collation, func_name()); break; @@ -627,13 +626,12 @@ void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array, void Item_func_concat_ws::fix_length_and_dec() { - set_charset(*separator); + collation.set(separator->collation); max_length=separator->max_length*(arg_count-1); for (uint i=0 ; i < arg_count ; i++) { max_length+=args[i]->max_length; - if (set_charset(charset(), derivation(), - args[i]->charset(), args[i]->derivation())) + if (collation.aggregate(args[i]->collation)) { my_coll_agg_error(collation, args[i]->collation, func_name()); break; @@ -828,12 +826,11 @@ void Item_func_replace::fix_length_and_dec() max_length=MAX_BLOB_WIDTH; maybe_null=1; } - set_charset(*args[0]); + collation.set(args[0]->collation); for (i=1; i<3; i++) { - if (set_charset(charset(), derivation(), - args[i]->charset(), args[i]->derivation())) + if (collation.aggregate(args[i]->collation)) { my_coll_agg_error(collation, args[i]->collation, func_name()); break; @@ -875,10 +872,10 @@ null: void Item_func_insert::fix_length_and_dec() { - if (set_charset(args[0]->charset(), args[0]->derivation(), - args[3]->charset(), args[3]->derivation())) + if (collation.set(args[0]->collation, args[3]->collation)) { my_coll_agg_error(args[0]->collation, args[3]->collation, func_name()); + return; } max_length=args[0]->max_length+args[3]->max_length; if (max_length > MAX_BLOB_WIDTH) @@ -1316,13 +1313,12 @@ void Item_func_trim::fix_length_and_dec() max_length= args[0]->max_length; if (arg_count == 1) { - set_charset(*args[0]); + collation.set(args[0]->collation); remove.set_charset(charset()); remove.set_ascii(" ",1); } else - if (set_charset(args[1]->charset(), args[1]->derivation(), - args[0]->charset(), args[0]->derivation())) + if (collation.set(args[1]->collation, args[0]->collation)) { my_coll_agg_error(args[1]->collation, args[0]->collation, func_name()); } @@ -1668,11 +1664,10 @@ void Item_func_elt::fix_length_and_dec() set_if_bigger(max_length,args[i]->max_length); set_if_bigger(decimals,args[i]->decimals); if (i == 0) - set_charset(*args[0]); + collation.set(args[0]->collation); else { - if (set_charset(charset(), derivation(), - args[i]->charset(), args[i]->derivation())) + if (collation.aggregate(args[i]->collation)) { my_coll_agg_error(collation, args[i]->collation, func_name()); break; @@ -1770,12 +1765,11 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array, void Item_func_make_set::fix_length_and_dec() { max_length=arg_count-1; - set_charset(*args[0]); + collation.set(args[0]->collation); for (uint i=0 ; i < arg_count ; i++) { max_length+=args[i]->max_length; - if (set_charset(charset(), derivation(), - args[i]->charset(), args[i]->derivation())) + if (collation.aggregate(args[i]->collation)) { my_coll_agg_error(collation, args[i]->collation, func_name()); break; @@ -1963,10 +1957,10 @@ err: void Item_func_rpad::fix_length_and_dec() { - if (set_charset(args[0]->charset(), args[0]->derivation(), - args[2]->charset(), args[2]->derivation())) + if (collation.set(args[0]->collation, args[2]->collation)) { my_coll_agg_error(args[0]->collation, args[2]->collation, func_name()); + return; } if (args[1]->const_item()) @@ -2029,10 +2023,10 @@ String *Item_func_rpad::val_str(String *str) void Item_func_lpad::fix_length_and_dec() { - if (set_charset(args[0]->charset(), args[0]->derivation(), - args[2]->charset(), args[2]->derivation())) + if (collation.set(args[0]->collation, args[2]->collation)) { my_coll_agg_error(args[0]->collation, args[2]->collation, func_name()); + return; } if (args[1]->const_item()) @@ -2152,9 +2146,8 @@ String *Item_func_conv_charset::val_str(String *str) void Item_func_conv_charset::fix_length_and_dec() { - set_charset(conv_charset); - max_length = args[0]->max_length*conv_charset->mbmaxlen; set_charset(conv_charset, DERIVATION_IMPLICIT); + max_length = args[0]->max_length*conv_charset->mbmaxlen; } @@ -2449,11 +2442,10 @@ void Item_func_export_set::fix_length_and_dec() uint sep_length=(arg_count > 3 ? args[3]->max_length : 1); max_length=length*64+sep_length*63; - set_charset(*args[1]); + collation.set(args[1]->collation); for (i=2 ; i < 4 && i < arg_count ; i++) { - if (set_charset(charset(), derivation(), - args[i]->charset(), args[i]->derivation())) + if (collation.aggregate(args[i]->collation)) { my_coll_agg_error(collation, args[i]->collation, func_name()); break; From 5788c90d07d97714dd23268fcb1cde31a093e418 Mon Sep 17 00:00:00 2001 From: "venu@myvenu.com" <> Date: Tue, 24 Jun 2003 10:43:57 -0700 Subject: [PATCH 15/27] test for SQL_MODE with PIPES_AS_CONCAT, ANSI and IGNORE_SPACE --- tests/client_test.c | 139 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 4 deletions(-) diff --git a/tests/client_test.c b/tests/client_test.c index d22aa900a4e..2741da1bbba 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -7327,6 +7327,136 @@ static void test_free_store_result() mysql_stmt_close(stmt); } +/******************************************************** + To test SQLmode +*********************************************************/ + +static void test_sqlmode() +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind[2]; + char c1[5], c2[5]; + int rc; + + myheader("test_sqlmode"); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_piping"); + myquery(rc); + + rc = mysql_commit(mysql); + myquery(rc); + + rc = mysql_query(mysql,"CREATE TABLE test_piping(name varchar(10))"); + myquery(rc); + + /* PIPES_AS_CONCAT */ + strcpy(query,"SET SQL_MODE=\"PIPES_AS_CONCAT\""); + fprintf(stdout,"\n With %s", query); + rc = mysql_query(mysql,query); + myquery(rc); + + strcpy(query, "INSERT INTO test_piping VALUES(?||?)"); + fprintf(stdout,"\n query: %s", query); + stmt = mysql_prepare(mysql, query, strlen(query)); + mystmt_init(stmt); + + fprintf(stdout,"\n total parameters: %ld", mysql_param_count(stmt)); + + bind[0].buffer_type= MYSQL_TYPE_STRING; + bind[0].buffer= (char *)c1; + bind[0].buffer_length= 2; + bind[0].is_null= 0; + bind[0].length= 0; + + bind[1].buffer_type= MYSQL_TYPE_STRING; + bind[1].buffer= (char *)c2; + bind[1].buffer_length= 3; + bind[1].is_null= 0; + bind[1].length= 0; + + rc = mysql_bind_param(stmt, bind); + mystmt(stmt,rc); + + strcpy(c1,"My"); strcpy(c2, "SQL"); + rc = mysql_execute(stmt); + mystmt(stmt,rc); + + mysql_stmt_close(stmt); + verify_col_data("test_piping","name","MySQL"); + + rc = mysql_query(mysql,"DELETE FROM test_piping"); + myquery(rc); + + strcpy(query, "SELECT connection_id ()"); + fprintf(stdout,"\n query: %s", query); + stmt = mysql_prepare(mysql, query, 70); + mystmt_init_r(stmt); + + /* ANSI */ + strcpy(query,"SET SQL_MODE=\"ANSI\""); + fprintf(stdout,"\n With %s", query); + rc = mysql_query(mysql,query); + myquery(rc); + + strcpy(query, "INSERT INTO test_piping VALUES(?||?)"); + fprintf(stdout,"\n query: %s", query); + stmt = mysql_prepare(mysql, query, strlen(query)); + mystmt_init(stmt); + fprintf(stdout,"\n total parameters: %ld", mysql_param_count(stmt)); + + rc = mysql_bind_param(stmt, bind); + mystmt(stmt,rc); + + strcpy(c1,"My"); strcpy(c2, "SQL"); + rc = mysql_execute(stmt); + mystmt(stmt,rc); + + mysql_stmt_close(stmt); + verify_col_data("test_piping","name","MySQL"); + + /* ANSI mode spaces ... */ + strcpy(query, "SELECT connection_id ()"); + fprintf(stdout,"\n query: %s", query); + stmt = mysql_prepare(mysql, query, 70); + mystmt_init(stmt); + + rc = mysql_execute(stmt); + mystmt(stmt,rc); + + rc = mysql_fetch(stmt); + mystmt(stmt,rc); + + rc = mysql_fetch(stmt); + myassert(rc == MYSQL_NO_DATA); + fprintf(stdout,"\n returned 1 row\n"); + + mysql_stmt_close(stmt); + + /* IGNORE SPACE MODE */ + strcpy(query,"SET SQL_MODE=\"IGNORE_SPACE\""); + fprintf(stdout,"\n With %s", query); + rc = mysql_query(mysql,query); + myquery(rc); + + strcpy(query, "SELECT connection_id ()"); + fprintf(stdout,"\n query: %s", query); + stmt = mysql_prepare(mysql, query, 70); + mystmt_init(stmt); + + rc = mysql_execute(stmt); + mystmt(stmt,rc); + + rc = mysql_fetch(stmt); + mystmt(stmt,rc); + + rc = mysql_fetch(stmt); + myassert(rc == MYSQL_NO_DATA); + fprintf(stdout,"\n returned 1 row"); + + mysql_stmt_close(stmt); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -7467,10 +7597,6 @@ int main(int argc, char **argv) start_time= time((time_t *)0); client_query(); /* simple client query test */ - test_mem_overun(); - test_list_fields(); - test_fetch_offset(); /* to test mysql_fetch_column with offset */ - test_fetch_column(); /* to test mysql_fetch_column */ #if NOT_YET_WORKING /* Used for internal new development debugging */ test_drop_temp(); /* to test DROP TEMPORARY TABLE Access checks */ @@ -7572,6 +7698,11 @@ int main(int argc, char **argv) test_free_result(); /* test mysql_stmt_free_result() */ test_free_store_result(); /* test to make sure stmt results are cleared during stmt_free_result() */ + test_mem_overun(); /* memory ovverun bug */ + test_list_fields(); /* list_fields test */ + test_fetch_offset(); /* to test mysql_fetch_column with offset */ + test_fetch_column(); /* to test mysql_fetch_column */ + test_sqlmode(); /* test for SQL_MODE */ end_time= time((time_t *)0); total_time+= difftime(end_time, start_time); From c6c4e8b8e1a74e3b4ae701da3f20b61a76214229 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Wed, 25 Jun 2003 15:07:20 +0500 Subject: [PATCH 16/27] LOCATE(), INSTR(), POSITION(), FIND_IN_SET(), SUBSTRING_INDEX() now process arguments according to standard SQL collation determation rules. --- mysql-test/r/func_str.result | 27 +++++++++++++++++++++++++++ mysql-test/t/func_str.test | 27 +++++++++++++++++++++++++++ sql/item_func.cc | 20 +++++++++++++++----- sql/item_func.h | 9 +++------ sql/item_strfunc.cc | 11 +++++++++++ sql/item_strfunc.h | 2 +- 6 files changed, 84 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 6ee452764c2..96c23ab1e22 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -249,6 +249,33 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf'); SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password"); 1 DROP TABLE t1; +select POSITION(_latin1'B' IN _latin1'abcd'); +POSITION(_latin1'B' IN _latin1'abcd') +2 +select POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin); +POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin) +0 +select POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd'); +POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd') +0 +select POSITION(_latin1'B' COLLATE latin1_general_ci IN _latin1'abcd' COLLATE latin1_bin); +ERROR HY000: Illegal mix of collations (latin1_bin,EXPLICIT) and (latin1_general_ci,EXPLICIT) for operation 'locate' +select POSITION(_latin1'B' IN _latin2'abcd'); +ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'locate' +select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d'); +FIND_IN_SET(_latin1'B',_latin1'a,b,c,d') +2 +select FIND_IN_SET(_latin1'B' COLLATE latin1_general_ci,_latin1'a,b,c,d' COLLATE latin1_bin); +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'find_in_set' +select FIND_IN_SET(_latin1'B',_latin2'a,b,c,d'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'find_in_set' +select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2); +SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2) +abcdabc +select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'substr_index' +select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2); +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'substr_index' select collation(bin(130)), coercibility(bin(130)); collation(bin(130)) coercibility(bin(130)) latin1_swedish_ci 3 diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 83d49743a4a..7e6d2648e1e 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -136,6 +136,33 @@ DROP TABLE t1; # # Test collation and coercibility # +select POSITION(_latin1'B' IN _latin1'abcd'); +select POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin); +select POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd'); +--error 1265 +select POSITION(_latin1'B' COLLATE latin1_general_ci IN _latin1'abcd' COLLATE latin1_bin); +--error 1265 +select POSITION(_latin1'B' IN _latin2'abcd'); + +select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d'); +--fix this: +--select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d' COLLATE latin1_bin); +--select FIND_IN_SET(_latin1'B' COLLATE latin1_bin,_latin1'a,b,c,d'); +--error 1265 +select FIND_IN_SET(_latin1'B' COLLATE latin1_general_ci,_latin1'a,b,c,d' COLLATE latin1_bin); +--error 1265 +select FIND_IN_SET(_latin1'B',_latin2'a,b,c,d'); + +select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2); +--fix this: +--select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_bin,_latin1'd',2); +--select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd' COLLATE latin1_bin,2); +--error 1265 +select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2); +--error 1265 +select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2); + + select collation(bin(130)), coercibility(bin(130)); select collation(oct(130)), coercibility(oct(130)); select collation(conv(130,16,10)), coercibility(conv(130,16,10)); diff --git a/sql/item_func.cc b/sql/item_func.cc index d0362ea9369..dc979cea2f8 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1045,10 +1045,18 @@ longlong Item_func_coercibility::val_int() return (longlong) args[0]->derivation(); } +void Item_func_locate::fix_length_and_dec() +{ + maybe_null=0; max_length=11; + if (cmp_collation.set(args[0]->collation, args[1]->collation)) + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); +} + longlong Item_func_locate::val_int() { String *a=args[0]->val_str(&value1); String *b=args[1]->val_str(&value2); + bool binary_cmp= (cmp_collation.collation->state & MY_CS_BINSORT) ? 1 : 0; if (!a || !b) { null_value=1; @@ -1063,7 +1071,7 @@ longlong Item_func_locate::val_int() { start=(uint) args[2]->val_int()-1; #ifdef USE_MB - if (use_mb(a->charset())) + if (use_mb(cmp_collation.collation)) { start0=start; if (!binary_cmp) @@ -1076,7 +1084,7 @@ longlong Item_func_locate::val_int() if (!b->length()) // Found empty string at start return (longlong) (start+1); #ifdef USE_MB - if (use_mb(a->charset()) && !binary_cmp) + if (use_mb(cmp_collation.collation) && !binary_cmp) { const char *ptr=a->ptr()+start; const char *search=b->ptr(); @@ -1095,7 +1103,7 @@ longlong Item_func_locate::val_int() return (longlong) start0+1; } skipp: - if ((l=my_ismbchar(a->charset(),ptr,strend))) + if ((l=my_ismbchar(cmp_collation.collation,ptr,strend))) ptr+=l; else ++ptr; ++start0; @@ -1201,6 +1209,8 @@ void Item_func_find_in_set::fix_length_and_dec() } } } + if (cmp_collation.set(args[0]->collation, args[1]->collation)) + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); } static const char separator=','; @@ -1228,7 +1238,6 @@ longlong Item_func_find_in_set::val_int() null_value=0; int diff; - CHARSET_INFO *charset= find->charset(); if ((diff=buffer->length() - find->length()) >= 0) { const char *f_pos=find->ptr(); @@ -1242,7 +1251,8 @@ longlong Item_func_find_in_set::val_int() const char *pos= f_pos; while (pos != f_end) { - if (my_toupper(charset,*str) != my_toupper(charset,*pos)) + if (my_toupper(cmp_collation.collation,*str) != + my_toupper(cmp_collation.collation,*pos)) goto not_found; str++; pos++; diff --git a/sql/item_func.h b/sql/item_func.h index 4e39833c467..9ba5bea8b87 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -610,17 +610,13 @@ public: class Item_func_locate :public Item_int_func { String value1,value2; - bool binary_cmp; + DTCollation cmp_collation; public: Item_func_locate(Item *a,Item *b) :Item_int_func(a,b) {} Item_func_locate(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {} const char *func_name() const { return "locate"; } longlong val_int(); - void fix_length_and_dec() - { - maybe_null=0; max_length=11; - binary_cmp = args[0]->binary() || args[1]->binary(); - } + void fix_length_and_dec(); }; @@ -684,6 +680,7 @@ class Item_func_find_in_set :public Item_int_func String value,value2; uint enum_value; ulonglong enum_bit; + DTCollation cmp_collation; public: Item_func_find_in_set(Item *a,Item *b) :Item_int_func(a,b),enum_value(0) {} longlong val_int(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 1c770456793..a57800c89d1 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1037,6 +1037,15 @@ void Item_func_substr::fix_length_and_dec() } +void Item_func_substr_index::fix_length_and_dec() +{ + max_length= args[0]->max_length; + if (collation.set(args[0]->collation, args[1]->collation) || + (collation.derivation == DERIVATION_NONE)) + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); +} + + String *Item_func_substr_index::val_str(String *str) { String *res =args[0]->val_str(str); @@ -1054,6 +1063,8 @@ String *Item_func_substr_index::val_str(String *str) if (!res->length() || !delimeter_length || !count) return &empty_string; // Wrong parameters + res->set_charset(collation.collation); + #ifdef USE_MB if (use_mb(res->charset())) { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 3f2860f4b2b..6cc6d730627 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -215,7 +215,7 @@ class Item_func_substr_index :public Item_str_func public: Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {} String *val_str(String *); - void fix_length_and_dec() { max_length= args[0]->max_length; } + void fix_length_and_dec(); const char *func_name() const { return "substr_index"; } }; From 39fb96c662edfa9aa1e3b63818f0855b6eb03b2b Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 25 Jun 2003 16:51:00 +0300 Subject: [PATCH 17/27] fixed mistyping (BUG #699) --- sql/sql_select.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b8eb9e19cc7..cc80f80739b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1227,7 +1227,7 @@ JOIN::exec() { // Some tables may have been const curr_join->tmp_having->update_used_tables(); - JOIN_TAB *table= &curr_join->join_tab[const_tables]; + JOIN_TAB *table= &curr_join->join_tab[curr_join->const_tables]; table_map used_tables= curr_join->const_table_map | table->table->map; Item* sort_table_cond= make_cond_for_table(curr_join->tmp_having, @@ -1263,7 +1263,7 @@ JOIN::exec() We can abort sorting after thd->select_limit rows if we there is no WHERE clause for any tables after the sorted one. */ - JOIN_TAB *table= &curr_join->join_tab[const_tables+1]; + JOIN_TAB *table= &curr_join->join_tab[curr_join->const_tables+1]; JOIN_TAB *end_table= &curr_join->join_tab[tables]; for (; table < end_table ; table++) { From e009dce0c380d87430b03bdaef90374c1aa8e8eb Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Wed, 25 Jun 2003 19:50:27 +0500 Subject: [PATCH 18/27] item_func.cc: My stupid typo fix --- sql/item_func.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_func.cc b/sql/item_func.cc index dc979cea2f8..cabffdfc7c2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2023,7 +2023,7 @@ void Item_func_set_user_var::update_hash(void *ptr, uint length, my_free(entry->value,MYF(0)); entry->value=0; entry->length=0; - collation.set(cs, dv); + entry->collation.set(cs, dv); } else { From 36a75d26f2442ca6374e90a507fc8012af35ad7a Mon Sep 17 00:00:00 2001 From: "paul@teton.kitebird.com" <> Date: Wed, 25 Jun 2003 16:25:03 -0500 Subject: [PATCH 19/27] modify error message --- sql/share/czech/errmsg.txt | 2 +- sql/share/danish/errmsg.txt | 2 +- sql/share/dutch/errmsg.txt | 2 +- sql/share/english/errmsg.txt | 2 +- sql/share/estonian/errmsg.txt | 2 +- sql/share/french/errmsg.txt | 2 +- sql/share/german/errmsg.txt | 2 +- sql/share/greek/errmsg.txt | 2 +- sql/share/hungarian/errmsg.txt | 2 +- sql/share/italian/errmsg.txt | 2 +- sql/share/japanese/errmsg.txt | 2 +- sql/share/korean/errmsg.txt | 2 +- sql/share/norwegian-ny/errmsg.txt | 2 +- sql/share/norwegian/errmsg.txt | 2 +- sql/share/polish/errmsg.txt | 2 +- sql/share/portuguese/errmsg.txt | 2 +- sql/share/romanian/errmsg.txt | 2 +- sql/share/russian/errmsg.txt | 2 +- sql/share/serbian/errmsg.txt | 2 +- sql/share/slovak/errmsg.txt | 2 +- sql/share/spanish/errmsg.txt | 2 +- sql/share/swedish/errmsg.txt | 2 +- sql/share/ukrainian/errmsg.txt | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 273dfa0fcf5..b08e52fb745 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -259,7 +259,7 @@ v/* "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 1d39a328154..ad5afb5c5f1 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -253,7 +253,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 5b79f06b621..75092f8a28f 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -261,7 +261,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index f15e063c487..5f30141fa34 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -250,7 +250,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Client does not support authentication protocol requested by server; consider upgrading MySQL client" "All parts of a SPATIAL KEY must be NOT NULL" "COLLATION '%s' is not valid for CHARACTER SET '%s'" "The slave was already running" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 506b5fc0188..6c2ff6af902 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -255,7 +255,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 8882e4dceda..029bb06c295 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -250,7 +250,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 1e8f5bb2c05..29dd448ea1c 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -259,7 +259,7 @@ "Für jede abgeleitete Tabelle muss ein eigener Alias angegeben werden.", "Select %u wurde während der Optimierung reduziert.", "Tabelle '%-.64s', die in einem der SELECT-Befehle verwendet wurde kann nicht in %-.32s verwendet werden", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index d322f3fbd6a..ee173d890f4 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -250,7 +250,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 162bfc5509c..52ce503dd22 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -252,7 +252,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 26d916a968d..5e6ded532bb 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -250,7 +250,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index a01a2b7ff6f..d5cff6baad1 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -252,7 +252,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 5f5526be04b..d0354e40c19 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -250,7 +250,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index bf1019d3d87..940f4144a94 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -252,7 +252,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 68c95bbf22b..2c9e5ff58a9 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -252,7 +252,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 5b93403c757..3f6b0a5e0c5 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -254,7 +254,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index edd3e3b813f..acb461163f8 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -250,7 +250,7 @@ "Cada tabela derivada deve ter seu próprio alias", "Select %u foi reduzido durante otimização", "Tabela '%-.64s' de um dos SELECT's não pode ser usada em %-.32s", -"Cliente não suporta o protocolo de autenticação exigido pelo servidor. Considere a atualização deo cliente MySQL", +"Cliente não suporta o protocolo de autenticação exigido pelo servidor; considere a atualização deo cliente MySQL", "Todas as partes de uma SPATIAL KEY devem ser NOT NULL", "COLLATION '%s' não é válida para CHARACTER SET '%s'", "O slave já está rodando", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 873a708fa7b..ed90efd8445 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -254,7 +254,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index a05ecde6808..45a52690c00 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -252,7 +252,7 @@ "Every derived table must have it's own alias", "Select %u ÂÙÌ ÕÐÒÁÚÄÎÅÎ × ÐÒÏÃÅÓÓÅ ÏÐÔÉÍÉÚÁÃÉÉ", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index c1c0de779c7..3acf3553501 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -246,7 +246,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 26d673b847c..fb34c8841a3 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -258,7 +258,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 99a92f63c4e..dd9ad6fe499 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -251,7 +251,7 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index c613d205947..65482ed7d42 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -250,7 +250,7 @@ "Varje 'derived table' måste ha sitt eget alias", "Select %u reducerades vid optimiering", "Tabell '%-.64s' från en SELECT kan inte användas i %-.32s", -"Klienten stöder inte autentiseringsprotokollet som begärts av servern. Överväg uppgradering av klientprogrammet.", +"Klienten stöder inte autentiseringsprotokollet som begärts av servern; överväg uppgradering av klientprogrammet.", "Alla delar av en SPATIAL KEY måste vara NOT NULL", "COLLATION '%s' är inte tillåtet för CHARACTER SET '%s'", "Slaven har redan startat", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 6505c3c9cac..5effbba170a 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -255,7 +255,7 @@ "Every derived table must have it's own alias", "Select %u was ÓËÁÓÏ×ÁÎÏ ÐÒÉ ÏÐÔÉÍiÚÁÃii", "Table '%-.64s' from one of SELECT's can not be used in %-.32s", -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client", +"Client does not support authentication protocol requested by server; consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL", "COLLATION '%s' is not valid for CHARACTER SET '%s'", "The slave was already running", From 7455759f11c3229f45c4f3215e839cc287bf3f86 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Thu, 26 Jun 2003 09:39:23 +0500 Subject: [PATCH 20/27] Bug fixed: mysql-test failure on rpl tests --- scripts/mysql_create_system_tables.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index a98e1739260..2739c45e750 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -145,6 +145,7 @@ then then i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); + REPLACE INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); INSERT INTO user (host,user) values ('localhost',''); INSERT INTO user (host,user) values ('$hostname','');" else From 65335d37ff9d8ae046c70dcb16c7662b049fc456 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Thu, 26 Jun 2003 15:45:04 +0500 Subject: [PATCH 21/27] New messages for 3-adic and N-adic operations REPLACE() now processed arguments collations according to standard --- include/mysqld_error.h | 6 ++++-- sql/item_cmpfunc.cc | 20 ++++++++++++------- sql/item_cmpfunc.h | 2 +- sql/item_func.cc | 2 +- sql/item_strfunc.cc | 32 ++++++++++++++++++++----------- sql/share/czech/errmsg.txt | 2 ++ sql/share/danish/errmsg.txt | 2 ++ sql/share/dutch/errmsg.txt | 2 ++ sql/share/english/errmsg.txt | 2 ++ sql/share/estonian/errmsg.txt | 2 ++ sql/share/french/errmsg.txt | 2 ++ sql/share/german/errmsg.txt | 2 ++ sql/share/greek/errmsg.txt | 2 ++ sql/share/hungarian/errmsg.txt | 2 ++ sql/share/italian/errmsg.txt | 2 ++ sql/share/japanese/errmsg.txt | 2 ++ sql/share/korean/errmsg.txt | 2 ++ sql/share/norwegian-ny/errmsg.txt | 2 ++ sql/share/norwegian/errmsg.txt | 2 ++ sql/share/polish/errmsg.txt | 2 ++ sql/share/portuguese/errmsg.txt | 2 ++ sql/share/romanian/errmsg.txt | 2 ++ sql/share/russian/errmsg.txt | 2 ++ sql/share/serbian/errmsg.txt | 2 ++ sql/share/slovak/errmsg.txt | 2 ++ sql/share/spanish/errmsg.txt | 2 ++ sql/share/swedish/errmsg.txt | 2 ++ sql/share/ukrainian/errmsg.txt | 2 ++ 28 files changed, 86 insertions(+), 22 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index ccccb188037..565c2812c50 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -281,7 +281,9 @@ #define ER_WARN_DATA_OUT_OF_RANGE 1262 #define ER_WARN_DATA_TRUNCATED 1263 #define ER_WARN_USING_OTHER_HANDLER 1264 -#define ER_CANT_AGGREGATE_COLLATIONS 1265 +#define ER_CANT_AGGREGATE_2COLLATIONS 1265 #define ER_DROP_USER 1266 #define ER_REVOKE_GRANTS 1267 -#define ER_ERROR_MESSAGES 266 +#define ER_CANT_AGGREGATE_3COLLATIONS 1268 +#define ER_CANT_AGGREGATE_NCOLLATIONS 1269 +#define ER_ERROR_MESSAGES 270 diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 52bd14ed515..ca3f55a9804 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -26,7 +26,7 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), c1.collation->name,c1.derivation_name(), c2.collation->name,c2.derivation_name(), fname); @@ -1968,7 +1968,12 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func; max_length= 1; decimals= 0; - binary_cmp= (args[0]->binary() || args[1]->binary()); + + if (cmp_collation.set(args[0]->collation, args[1]->collation)) + { + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); + return 1; + } used_tables_cache=args[0]->used_tables() | args[1]->used_tables(); const_item_cache=args[0]->const_item() && args[1]->const_item(); @@ -1984,9 +1989,10 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } int error; if ((error=regcomp(&preg,res->c_ptr(), - binary_cmp ? REG_EXTENDED | REG_NOSUB : + (cmp_collation.collation->state & MY_CS_BINSORT) ? + REG_EXTENDED | REG_NOSUB : REG_EXTENDED | REG_NOSUB | REG_ICASE, - res->charset()))) + cmp_collation.collation))) { (void) regerror(error,&preg,buff,sizeof(buff)); my_printf_error(ER_REGEXP_ERROR,ER(ER_REGEXP_ERROR),MYF(0),buff); @@ -2033,10 +2039,10 @@ longlong Item_func_regex::val_int() regex_compiled=0; } if (regcomp(&preg,res2->c_ptr(), - binary_cmp ? REG_EXTENDED | REG_NOSUB : + (cmp_collation.collation->state & MY_CS_BINSORT) ? + REG_EXTENDED | REG_NOSUB : REG_EXTENDED | REG_NOSUB | REG_ICASE, - res->charset())) - + cmp_collation.collation)) { null_value=1; return 0; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 70e477402d9..1221e316a72 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -747,7 +747,7 @@ class Item_func_regex :public Item_bool_func bool regex_compiled; bool regex_is_const; String prev_regexp; - bool binary_cmp; + DTCollation cmp_collation; public: Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b), regex_compiled(0),regex_is_const(0) {} diff --git a/sql/item_func.cc b/sql/item_func.cc index cabffdfc7c2..d7237f55522 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -33,7 +33,7 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), c1.collation->name,c1.derivation_name(), c2.collation->name,c2.derivation_name(), fname); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index a57800c89d1..ae63ac85d4d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -38,12 +38,24 @@ String empty_string("",default_charset_info); static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), c1.collation->name,c1.derivation_name(), c2.collation->name,c2.derivation_name(), fname); } +static void my_coll_agg3_error(DTCollation &c1, + DTCollation &c2, + DTCollation &c3, + const char *fname) +{ + my_error(ER_CANT_AGGREGATE_3COLLATIONS,MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + c3.collation->name,c3.derivation_name(), + fname); +} + uint nr_of_decimals(const char *str) { if ((str=strchr(str,'.'))) @@ -733,6 +745,8 @@ String *Item_func_replace::val_str(String *str) if (args[1]->null_value) goto null; + res->set_charset(collation.collation); + #ifdef USE_MB binary_cmp = (args[0]->binary() || args[1]->binary() || !use_mb(res->charset())); #endif @@ -813,7 +827,6 @@ null: void Item_func_replace::fix_length_and_dec() { - uint i; max_length=args[0]->max_length; int diff=(int) (args[2]->max_length - args[1]->max_length); if (diff > 0 && args[1]->max_length) @@ -828,14 +841,12 @@ void Item_func_replace::fix_length_and_dec() } collation.set(args[0]->collation); - for (i=1; i<3; i++) - { - if (collation.aggregate(args[i]->collation)) - { - my_coll_agg_error(collation, args[i]->collation, func_name()); - break; - } - } + if (!collation.aggregate(args[1]->collation)) + collation.aggregate(args[2]->collation); + + if (collation.derivation == DERIVATION_NONE) + my_coll_agg3_error(args[0]->collation, args[1]->collation, + args[2]->collation, func_name()); } @@ -931,7 +942,6 @@ String *Item_func_left::val_str(String *str) if (!res->alloced_length()) { // Don't change const str str_value= *res; // Not malloced string - set_charset(res->charset()); res= &str_value; } res->length((uint) length); diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 273dfa0fcf5..190d208a033 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -273,3 +273,5 @@ v/* "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 1d39a328154..909f69617a0 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -267,3 +267,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 5b79f06b621..8d8da1840fb 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -275,3 +275,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index f15e063c487..9e22377ce77 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -269,3 +269,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 506b5fc0188..c3b5fa7a2ec 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -269,3 +269,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 8882e4dceda..6c34663021c 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -264,3 +264,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 1e8f5bb2c05..2741d1e5a25 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -273,3 +273,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index d322f3fbd6a..b643e465846 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -264,3 +264,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 162bfc5509c..86fbb4dce6f 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -266,3 +266,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 26d916a968d..71c5d7f2c95 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -264,3 +264,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index a01a2b7ff6f..a9aa0747a59 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -266,3 +266,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 5f5526be04b..a6cf0a35dd0 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -264,3 +264,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index bf1019d3d87..062fd8dd8f7 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -266,3 +266,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 68c95bbf22b..d5268237ee4 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -266,3 +266,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 5b93403c757..e6861f7f8bb 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -268,3 +268,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index edd3e3b813f..f389084514b 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -264,3 +264,5 @@ "Combinação ilegal de collations (%s,%s) e (%s,%s) para operação '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 873a708fa7b..32b0e0bcd03 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -268,3 +268,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index a05ecde6808..d8c5cac08d5 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -266,3 +266,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index c1c0de779c7..40a2e4cac95 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -260,3 +260,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 26d673b847c..9f3cc7ce877 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -272,3 +272,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 99a92f63c4e..56d246b9032 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -265,3 +265,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index c613d205947..84b648f5eca 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -264,3 +264,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 6505c3c9cac..1d46b125c8c 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -269,3 +269,5 @@ "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", "Can't drop one or more of the requested users" "Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", From 52a7f956784ec147cdaf6b09419919fd901bf243 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Fri, 27 Jun 2003 12:02:08 +0500 Subject: [PATCH 22/27] BETWEEN now works according to collation rules --- mysql-test/r/func_str.result | 20 +++++++++++++++++++ mysql-test/t/func_str.test | 12 ++++++++++++ sql/item_cmpfunc.cc | 38 +++++++++++++++++++++++++++--------- sql/item_cmpfunc.h | 2 +- 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 96c23ab1e22..959cedeeb0d 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -276,6 +276,26 @@ select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2); ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'substr_index' select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2); ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'substr_index' +select _latin1'B' between _latin1'a' and _latin1'c'; +_latin1'B' between _latin1'a' and _latin1'c' +1 +select _latin1'B' collate latin1_bin between _latin1'a' and _latin1'c'; +_latin1'B' collate latin1_bin between _latin1'a' and _latin1'c' +0 +select _latin1'B' between _latin1'a' collate latin1_bin and _latin1'c'; +_latin1'B' between _latin1'a' collate latin1_bin and _latin1'c' +0 +select _latin1'B' between _latin1'a' and _latin1'c' collate latin1_bin; +_latin1'B' between _latin1'a' and _latin1'c' collate latin1_bin +0 +select _latin2'B' between _latin1'a' and _latin1'b'; +ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'between' +select _latin1'B' between _latin2'a' and _latin1'b'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'between' +select _latin1'B' between _latin1'a' and _latin2'b'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE) for operation 'between' +select _latin1'B' collate latin1_general_ci between _latin1'a' collate latin1_bin and _latin1'b'; +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_bin,EXPLICIT), (latin1_swedish_ci,COERCIBLE) for operation 'between' select collation(bin(130)), coercibility(bin(130)); collation(bin(130)) coercibility(bin(130)) latin1_swedish_ci 3 diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 7e6d2648e1e..41a37c0f7ab 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -162,6 +162,18 @@ select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2); --error 1265 select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2); +select _latin1'B' between _latin1'a' and _latin1'c'; +select _latin1'B' collate latin1_bin between _latin1'a' and _latin1'c'; +select _latin1'B' between _latin1'a' collate latin1_bin and _latin1'c'; +select _latin1'B' between _latin1'a' and _latin1'c' collate latin1_bin; +--error 1268 +select _latin2'B' between _latin1'a' and _latin1'b'; +--error 1268 +select _latin1'B' between _latin2'a' and _latin1'b'; +--error 1268 +select _latin1'B' between _latin1'a' and _latin2'b'; +--error 1268 +select _latin1'B' collate latin1_general_ci between _latin1'a' collate latin1_bin and _latin1'b'; select collation(bin(130)), coercibility(bin(130)); select collation(oct(130)), coercibility(oct(130)); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index ca3f55a9804..b764bb322d3 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -32,6 +32,18 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fnam fname); } +static void my_coll_agg3_error(DTCollation &c1, + DTCollation &c2, + DTCollation &c3, + const char *fname) +{ + my_error(ER_CANT_AGGREGATE_3COLLATIONS,MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + c3.collation->name,c3.derivation_name(), + fname); +} + Item_bool_func2* Item_bool_func2::eq_creator(Item *a, Item *b) { return new Item_func_eq(a, b); @@ -575,11 +587,19 @@ void Item_func_between::fix_length_and_dec() cmp_type=item_cmp_type(args[0]->result_type(), item_cmp_type(args[1]->result_type(), args[2]->result_type())); - /* QQ: COERCIBILITY */ - if (args[0]->binary() | args[1]->binary() | args[2]->binary()) - cmp_charset= &my_charset_bin; - else - cmp_charset= args[0]->charset(); + + if (cmp_type == STRING_RESULT) + { + cmp_collation.set(args[0]->collation); + if (!cmp_collation.aggregate(args[1]->collation)) + cmp_collation.aggregate(args[2]->collation); + if (cmp_collation.derivation == DERIVATION_NONE) + { + my_coll_agg3_error(args[0]->collation, args[1]->collation, + args[2]->collation, func_name()); + return; + } + } /* Make a special case of compare with date/time and longlong fields. @@ -611,17 +631,17 @@ longlong Item_func_between::val_int() a=args[1]->val_str(&value1); b=args[2]->val_str(&value2); if (!args[1]->null_value && !args[2]->null_value) - return (sortcmp(value,a,cmp_charset) >= 0 && - sortcmp(value,b,cmp_charset) <= 0) ? 1 : 0; + return (sortcmp(value,a,cmp_collation.collation) >= 0 && + sortcmp(value,b,cmp_collation.collation) <= 0) ? 1 : 0; if (args[1]->null_value && args[2]->null_value) null_value=1; else if (args[1]->null_value) { - null_value= sortcmp(value,b,cmp_charset) <= 0; // not null if false range. + null_value= sortcmp(value,b,cmp_collation.collation) <= 0; // not null if false range. } else { - null_value= sortcmp(value,a,cmp_charset) >= 0; // not null if false range. + null_value= sortcmp(value,a,cmp_collation.collation) >= 0; // not null if false range. } } else if (cmp_type == INT_RESULT) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 1221e316a72..792f2e2411c 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -245,7 +245,7 @@ public: class Item_func_between :public Item_int_func { - CHARSET_INFO *cmp_charset; + DTCollation cmp_collation; public: Item_result cmp_type; String value0,value1,value2; From 382e1ad064b46c76b3ea0b2519712fccb98ac089 Mon Sep 17 00:00:00 2001 From: "lenz@kallisto.local" <> Date: Fri, 27 Jun 2003 10:07:22 +0200 Subject: [PATCH 23/27] - fixed typo (dbl -> dnl) in acinclude.m4 --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 269b505386c..5a48e9840d2 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1113,7 +1113,7 @@ AC_DEFUN([MYSQL_CHECK_BDB_VERSION], [ # mysql_bdb=a # fi -dbl RAM: +dnl RAM: want_bdb_version="4.1.24" bdb_version_ok=yes From d31de6979526a5610c3eb1c59398f128f1738e77 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Fri, 27 Jun 2003 13:52:38 +0500 Subject: [PATCH 24/27] str0 IN (str1, str2, ...) now works according to collation rules --- mysql-test/r/func_str.result | 22 +++++++++++++++++ mysql-test/t/func_str.test | 15 ++++++++++++ sql/item_cmpfunc.cc | 47 ++++++++++++++++++------------------ sql/item_cmpfunc.h | 15 +++++++----- 4 files changed, 69 insertions(+), 30 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 959cedeeb0d..34c7752798d 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -296,6 +296,28 @@ select _latin1'B' between _latin1'a' and _latin2'b'; ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE) for operation 'between' select _latin1'B' collate latin1_general_ci between _latin1'a' collate latin1_bin and _latin1'b'; ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_bin,EXPLICIT), (latin1_swedish_ci,COERCIBLE) for operation 'between' +select _latin1'B' in (_latin1'a',_latin1'b'); +_latin1'B' in (_latin1'a',_latin1'b') +1 +select _latin1'B' collate latin1_bin in (_latin1'a',_latin1'b'); +_latin1'B' collate latin1_bin in (_latin1'a',_latin1'b') +0 +select _latin1'B' in (_latin1'a' collate latin1_bin,_latin1'b'); +_latin1'B' in (_latin1'a' collate latin1_bin,_latin1'b') +0 +select _latin1'B' in (_latin1'a',_latin1'b' collate latin1_bin); +_latin1'B' in (_latin1'a',_latin1'b' collate latin1_bin) +0 +select _latin2'B' in (_latin1'a',_latin1'b'); +ERROR HY000: Illegal mix of collations for operation ' IN ' +select _latin1'B' in (_latin2'a',_latin1'b'); +ERROR HY000: Illegal mix of collations for operation ' IN ' +select _latin1'B' in (_latin1'a',_latin2'b'); +ERROR HY000: Illegal mix of collations for operation ' IN ' +select _latin1'B' COLLATE latin1_general_ci in (_latin1'a' COLLATE latin1_bin,_latin1'b'); +ERROR HY000: Illegal mix of collations for operation ' IN ' +select _latin1'B' COLLATE latin1_general_ci in (_latin1'a',_latin1'b' COLLATE latin1_bin); +ERROR HY000: Illegal mix of collations for operation ' IN ' select collation(bin(130)), coercibility(bin(130)); collation(bin(130)) coercibility(bin(130)) latin1_swedish_ci 3 diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 41a37c0f7ab..a898d3551d7 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -175,6 +175,21 @@ select _latin1'B' between _latin1'a' and _latin2'b'; --error 1268 select _latin1'B' collate latin1_general_ci between _latin1'a' collate latin1_bin and _latin1'b'; +select _latin1'B' in (_latin1'a',_latin1'b'); +select _latin1'B' collate latin1_bin in (_latin1'a',_latin1'b'); +select _latin1'B' in (_latin1'a' collate latin1_bin,_latin1'b'); +select _latin1'B' in (_latin1'a',_latin1'b' collate latin1_bin); +--error 1269 +select _latin2'B' in (_latin1'a',_latin1'b'); +--error 1269 +select _latin1'B' in (_latin2'a',_latin1'b'); +--error 1269 +select _latin1'B' in (_latin1'a',_latin2'b'); +--error 1269 +select _latin1'B' COLLATE latin1_general_ci in (_latin1'a' COLLATE latin1_bin,_latin1'b'); +--error 1269 +select _latin1'B' COLLATE latin1_general_ci in (_latin1'a',_latin1'b' COLLATE latin1_bin); + select collation(bin(130)), coercibility(bin(130)); select collation(oct(130)), coercibility(oct(130)); select collation(conv(130,16,10)), coercibility(conv(130,16,10)); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b764bb322d3..f9c2228b33d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1196,17 +1196,17 @@ void Item_func_coalesce::fix_length_and_dec() Classes and function for the IN operator ****************************************************************************/ -static int cmp_longlong(longlong *a,longlong *b) +static int cmp_longlong(void *cmp_arg, longlong *a,longlong *b) { return *a < *b ? -1 : *a == *b ? 0 : 1; } -static int cmp_double(double *a,double *b) +static int cmp_double(void *cmp_arg, double *a,double *b) { return *a < *b ? -1 : *a == *b ? 0 : 1; } -static int cmp_row(cmp_item_row* a, cmp_item_row* b) +static int cmp_row(void *cmp_arg, cmp_item_row* a, cmp_item_row* b) { return a->compare(b); } @@ -1223,18 +1223,18 @@ int in_vector::find(Item *item) { uint mid=(start+end+1)/2; int res; - if ((res=(*compare)(base+mid*size,result)) == 0) + if ((res=(*compare)(collation, base+mid*size, result)) == 0) return 1; if (res < 0) start=mid; else end=mid-1; } - return (int) ((*compare)(base+start*size,result) == 0); + return (int) ((*compare)(collation, base+start*size, result) == 0); } -in_string::in_string(uint elements,qsort_cmp cmp_func) - :in_vector(elements, sizeof(String), cmp_func), +in_string::in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs) + :in_vector(elements, sizeof(String), cmp_func, cs), tmp(buff, sizeof(buff), &my_charset_bin) {} @@ -1273,7 +1273,7 @@ in_row::in_row(uint elements, Item * item) { base= (char*) new cmp_item_row[count= elements]; size= sizeof(cmp_item_row); - compare= (qsort_cmp) cmp_row; + compare= (qsort2_cmp) cmp_row; tmp.store_value(item); } @@ -1298,7 +1298,7 @@ void in_row::set(uint pos, Item *item) } in_longlong::in_longlong(uint elements) - :in_vector(elements,sizeof(longlong),(qsort_cmp) cmp_longlong) + :in_vector(elements,sizeof(longlong),(qsort2_cmp) cmp_longlong, 0) {} void in_longlong::set(uint pos,Item *item) @@ -1315,7 +1315,7 @@ byte *in_longlong::get_value(Item *item) } in_double::in_double(uint elements) - :in_vector(elements,sizeof(double),(qsort_cmp) cmp_double) + :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0) {} void in_double::set(uint pos,Item *item) @@ -1462,17 +1462,8 @@ bool Item_func_in::nulls_in_row() return 0; } -static int srtcmp_in(const String *x,const String *y) +static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y) { - CHARSET_INFO *cs= x->charset(); - return cs->coll->strnncollsp(cs, - (unsigned char *) x->ptr(),x->length(), - (unsigned char *) y->ptr(),y->length()); -} - -static int bincmp_in(const String *x,const String *y) -{ - CHARSET_INFO *cs= &my_charset_bin; return cs->coll->strnncollsp(cs, (unsigned char *) x->ptr(),x->length(), (unsigned char *) y->ptr(),y->length()); @@ -1488,10 +1479,18 @@ void Item_func_in::fix_length_and_dec() { switch (item->result_type()) { case STRING_RESULT: - if (item->binary()) - array=new in_string(arg_count,(qsort_cmp) srtcmp_in); - else - array=new in_string(arg_count,(qsort_cmp) bincmp_in); + uint i; + cmp_collation.set(item->collation); + for (i=0 ; icollation)) + break; + if (cmp_collation.derivation == DERIVATION_NONE) + { + my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),func_name()); + return; + } + array=new in_string(arg_count,(qsort2_cmp) srtcmp_in, + cmp_collation.collation); break; case INT_RESULT: array= new in_longlong(arg_count); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 792f2e2411c..1311cae335f 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -382,21 +382,23 @@ class in_vector :public Sql_alloc protected: char *base; uint size; - qsort_cmp compare; + qsort2_cmp compare; + CHARSET_INFO *collation; uint count; public: uint used_count; in_vector() {} - in_vector(uint elements,uint element_length,qsort_cmp cmp_func) + in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, + CHARSET_INFO *cmp_coll) :base((char*) sql_calloc(elements*element_length)), - size(element_length), compare(cmp_func), count(elements), - used_count(elements) {} + size(element_length), compare(cmp_func), collation(cmp_coll), + count(elements), used_count(elements) {} virtual ~in_vector() {} virtual void set(uint pos,Item *item)=0; virtual byte *get_value(Item *item)=0; void sort() { - qsort(base,used_count,size,compare); + qsort2(base,used_count,size,compare,collation); } int find(Item *item); }; @@ -406,7 +408,7 @@ class in_string :public in_vector char buff[80]; String tmp; public: - in_string(uint elements,qsort_cmp cmp_func); + in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs); ~in_string(); void set(uint pos,Item *item); byte *get_value(Item *item); @@ -605,6 +607,7 @@ class Item_func_in :public Item_int_func in_vector *array; cmp_item *in_item; bool have_null; + DTCollation cmp_collation; public: Item_func_in(Item *a,List &list) :Item_int_func(list), item(a), array(0), in_item(0), have_null(0) From b528745dcec81a7c93822323f87fff3beb7268a3 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Fri, 27 Jun 2003 16:08:52 +0500 Subject: [PATCH 25/27] When unifying arguments for comparion, binary strings won character strings, and comparison was done binary. Now, a binary string wins a character sting taking in account their derivation. That means a character field wins a binary literal and comparison is done according to the character field collation, not binary. --- mysql-test/r/ctype_latin1_de.result | 10 +++++----- mysql-test/t/ctype_latin1_de.test | 13 ++++++++----- sql/item.cc | 23 +++++++++++------------ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result index 630fef9b679..e0cb7008899 100644 --- a/mysql-test/r/ctype_latin1_de.result +++ b/mysql-test/r/ctype_latin1_de.result @@ -215,21 +215,21 @@ drop table t1; create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word)); insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae'); update t1 set word2=word; -select word, word=0xdf as t from t1 having t > 0; +select word, word=binary 0xdf as t from t1 having t > 0; word t ß 1 select word, word=cast(0xdf AS CHAR) as t from t1 having t > 0; word t ss 1 ß 1 -select * from t1 where word=0xDF; +select * from t1 where word=binary 0xDF; word word2 ß ß select * from t1 where word=CAST(0xDF as CHAR); word word2 ss ss ß ß -select * from t1 where word2=0xDF; +select * from t1 where word2=binary 0xDF; word word2 ß ß select * from t1 where word2=CAST(0xDF as CHAR); @@ -244,7 +244,7 @@ select * from t1 where word= 0xe4 or word=CAST(0xe4 as CHAR); word word2 ä ä ae ae -select * from t1 where word between 0xDF and 0xDF; +select * from t1 where word between binary 0xDF and binary 0xDF; word word2 ß ß select * from t1 where word between CAST(0xDF AS CHAR) and CAST(0xDF AS CHAR); @@ -257,7 +257,7 @@ ae ae select * from t1 where word like 'AE'; word word2 ae ae -select * from t1 where word like 0xDF; +select * from t1 where word like binary 0xDF; word word2 ß ß select * from t1 where word like CAST(0xDF as CHAR); diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test index b63af87601b..22a4e14158d 100644 --- a/mysql-test/t/ctype_latin1_de.test +++ b/mysql-test/t/ctype_latin1_de.test @@ -52,21 +52,24 @@ drop table t1; # Test bug report #152 (problem with index on latin1_de) # +# +# The below checks both binary and character comparisons. +# create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word)); insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae'); update t1 set word2=word; -select word, word=0xdf as t from t1 having t > 0; +select word, word=binary 0xdf as t from t1 having t > 0; select word, word=cast(0xdf AS CHAR) as t from t1 having t > 0; -select * from t1 where word=0xDF; +select * from t1 where word=binary 0xDF; select * from t1 where word=CAST(0xDF as CHAR); -select * from t1 where word2=0xDF; +select * from t1 where word2=binary 0xDF; select * from t1 where word2=CAST(0xDF as CHAR); select * from t1 where word='ae'; select * from t1 where word= 0xe4 or word=CAST(0xe4 as CHAR); -select * from t1 where word between 0xDF and 0xDF; +select * from t1 where word between binary 0xDF and binary 0xDF; select * from t1 where word between CAST(0xDF AS CHAR) and CAST(0xDF AS CHAR); select * from t1 where word like 'ae'; select * from t1 where word like 'AE'; -select * from t1 where word like 0xDF; +select * from t1 where word like binary 0xDF; select * from t1 where word like CAST(0xDF as CHAR); drop table t1; diff --git a/sql/item.cc b/sql/item.cc index 950f27c5d69..fea68837014 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -39,7 +39,7 @@ Item::Item(): { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; - set_charset(&my_charset_bin, DERIVATION_COERCIBLE); + set_charset(default_charset(), DERIVATION_COERCIBLE); name= 0; decimals= 0; max_length= 0; THD *thd= current_thd; @@ -185,13 +185,6 @@ CHARSET_INFO * Item::default_charset() const bool DTCollation::aggregate(DTCollation &dt) { - if (collation == &my_charset_bin || dt.collation == &my_charset_bin) - { - collation= &my_charset_bin; - derivation= derivation > dt.derivation ? derivation : dt.derivation; - return 0; - } - if (!my_charset_same(collation, dt.collation)) { /* @@ -199,13 +192,19 @@ bool DTCollation::aggregate(DTCollation &dt) together with character strings. Binaries have more precedance */ - if ((derivation <= dt.derivation) && (collation == &my_charset_bin)) + if (collation == &my_charset_bin) { - // Do nothing + if (derivation <= dt.derivation) + ; // Do nothing + else + set(dt); } - else if ((dt.derivation <= derivation) && (dt.collation==&my_charset_bin)) + else if (dt.collation == &my_charset_bin) { - set(dt); + if (dt.derivation <= derivation) + set(dt); + else + ; // Do nothing } else { From 28b2fcba277f4cbe652d172e6b8a941d6faf5de3 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Fri, 27 Jun 2003 16:09:53 +0500 Subject: [PATCH 26/27] item.cc: A better comment --- sql/item.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/item.cc b/sql/item.cc index fea68837014..c99493ff689 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -190,7 +190,8 @@ bool DTCollation::aggregate(DTCollation &dt) /* We do allow to use binary strings (like BLOBS) together with character strings. - Binaries have more precedance + Binaries have more precedance than a character + string of the same derivation. */ if (collation == &my_charset_bin) { From 541b0d53226b20fe52f88b30bfefcfe72aecbd82 Mon Sep 17 00:00:00 2001 From: "jani@rhols221.adsl.netsonic.fi" <> Date: Fri, 27 Jun 2003 18:51:39 +0300 Subject: [PATCH 27/27] Added support for structured options (WL task ID 947). --- include/my_getopt.h | 9 ++- mysys/my_getopt.c | 140 +++++++++++++++++++++++++++++++------------- sql/mysqld.cc | 12 +++- 3 files changed, 119 insertions(+), 42 deletions(-) diff --git a/include/my_getopt.h b/include/my_getopt.h index 3b4551b445e..213c8c3570e 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -17,7 +17,12 @@ C_MODE_START enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_INT, GET_UINT, GET_LONG, - GET_ULONG, GET_LL, GET_ULL, GET_STR, GET_STR_ALLOC }; + GET_ULONG, GET_LL, GET_ULL, GET_STR, GET_STR_ALLOC + }; + +#define GET_ASK_ADDR 128 +#define GET_TYPE_MASK 127 + enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG }; struct my_option @@ -48,6 +53,8 @@ extern int handle_options (int *argc, char ***argv, char *)); extern void my_print_help(const struct my_option *options); extern void my_print_variables(const struct my_option *options); +extern void my_getopt_register_get_addr(gptr* (*func_addr)(char *, uint, + const struct my_option *)); ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp); my_bool getopt_compare_strings(const char *s, const char *t, uint length); diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 759c96462f6..07f4f306198 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -34,6 +34,7 @@ static ulonglong getopt_ull(char *arg, const struct my_option *optp, static void init_variables(const struct my_option *options); static int setval(const struct my_option *opts, char *argument, my_bool set_maximum_value); +static char *check_struct_option(char *cur_arg, char *key_name); /* The following three variables belong to same group and the number and @@ -67,6 +68,14 @@ my_bool my_getopt_print_errors= 1; one. Call function 'get_one_option()' once for each option. */ +static gptr* (*getopt_get_addr)(char *, uint, const struct my_option *); + +void my_getopt_register_get_addr(gptr* (*func_addr)(char *, uint, + const struct my_option *)) +{ + getopt_get_addr= func_addr; +} + int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_bool (*get_one_option)(int, @@ -76,8 +85,10 @@ int handle_options(int *argc, char ***argv, uint opt_found, argvpos= 0, length, i; my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used, option_is_loose; - char *progname= *(*argv), **pos, **pos_end, *optend, *prev_found; + char **pos, **pos_end, *optend, *prev_found, + *opt_str, key_name[FN_REFLEN]; const struct my_option *optp; + gptr *value; int error; LINT_INIT(opt_found); @@ -110,7 +121,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) fprintf(stderr, "%s: Option '-O' requires an argument\n", - progname); + my_progname); return EXIT_ARGUMENT_REQUIRED; } cur_arg= *pos; @@ -128,7 +139,7 @@ int handle_options(int *argc, char ***argv, if (my_getopt_print_errors) fprintf(stderr, "%s: Option '--set-variable' requires an argument\n", - progname); + my_progname); return EXIT_ARGUMENT_REQUIRED; } } @@ -142,7 +153,7 @@ int handle_options(int *argc, char ***argv, if (my_getopt_print_errors) fprintf(stderr, "%s: Option '--set-variable' requires an argument\n", - progname); + my_progname); return EXIT_ARGUMENT_REQUIRED; } cur_arg= *pos; @@ -159,19 +170,20 @@ int handle_options(int *argc, char ***argv, continue; } } - optend= strcend(cur_arg, '='); - length= optend - cur_arg; + opt_str= check_struct_option(cur_arg, key_name); + optend= strcend(opt_str, '='); + length= optend - opt_str; if (*optend == '=') optend++; else - optend=0; + optend= 0; /* Find first the right option. Return error in case of an ambiguous, or unknown option */ optp= longopts; - if (!(opt_found= findopt(cur_arg, length, &optp, &prev_found))) + if (!(opt_found= findopt(opt_str, length, &optp, &prev_found))) { /* Didn't find any matching option. Let's see if someone called @@ -183,18 +195,18 @@ int handle_options(int *argc, char ***argv, must_be_var= 1; /* option is followed by an argument */ for (i= 0; special_opt_prefix[i]; i++) { - if (!getopt_compare_strings(special_opt_prefix[i], cur_arg, + if (!getopt_compare_strings(special_opt_prefix[i], opt_str, special_opt_prefix_lengths[i]) && - cur_arg[special_opt_prefix_lengths[i]] == '-') + opt_str[special_opt_prefix_lengths[i]] == '-') { /* We were called with a special prefix, we can reuse opt_found */ special_used= 1; - cur_arg+= (special_opt_prefix_lengths[i] + 1); + opt_str+= (special_opt_prefix_lengths[i] + 1); if (i == OPT_LOOSE) option_is_loose= 1; - if ((opt_found= findopt(cur_arg, length - + if ((opt_found= findopt(opt_str, length - (special_opt_prefix_lengths[i] + 1), &optp, &prev_found))) { @@ -203,7 +215,7 @@ int handle_options(int *argc, char ***argv, if (my_getopt_print_errors) fprintf(stderr, "%s: ambiguous option '--%s-%s' (--%s-%s)\n", - progname, special_opt_prefix[i], cur_arg, + my_progname, special_opt_prefix[i], opt_str, special_opt_prefix[i], prev_found); return EXIT_AMBIGUOUS_OPTION; } @@ -237,8 +249,8 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) fprintf(stderr, - "%s: %s: unknown variable '%s'\n", progname, - option_is_loose ? "WARNING" : "ERROR", cur_arg); + "%s: %s: unknown variable '%s'\n", my_progname, + option_is_loose ? "WARNING" : "ERROR", opt_str); if (!option_is_loose) return EXIT_UNKNOWN_VARIABLE; } @@ -246,8 +258,8 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) fprintf(stderr, - "%s: %s: unknown option '--%s'\n", progname, - option_is_loose ? "WARNING" : "ERROR", cur_arg); + "%s: %s: unknown option '--%s'\n", my_progname, + option_is_loose ? "WARNING" : "ERROR", opt_str); if (!option_is_loose) return EXIT_UNKNOWN_OPTION; } @@ -264,57 +276,61 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) fprintf(stderr, "%s: variable prefix '%s' is not unique\n", - progname, cur_arg); + my_progname, opt_str); return EXIT_VAR_PREFIX_NOT_UNIQUE; } else { if (my_getopt_print_errors) fprintf(stderr, "%s: ambiguous option '--%s' (%s, %s)\n", - progname, cur_arg, prev_found, optp->name); + my_progname, opt_str, prev_found, optp->name); return EXIT_AMBIGUOUS_OPTION; } } - if (must_be_var && optp->var_type == GET_NO_ARG) + if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG) { if (my_getopt_print_errors) fprintf(stderr, "%s: option '%s' cannot take an argument\n", - progname, optp->name); + my_progname, optp->name); return EXIT_NO_ARGUMENT_ALLOWED; } + value= optp->var_type & GET_ASK_ADDR ? + (*getopt_get_addr)(key_name, strlen(key_name), optp) : optp->value; + if (optp->arg_type == NO_ARG) { - if (optend && optp->var_type != GET_BOOL) + if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL) { if (my_getopt_print_errors) fprintf(stderr, "%s: option '--%s' cannot take an argument\n", - progname, optp->name); + my_progname, optp->name); return EXIT_NO_ARGUMENT_ALLOWED; } - if (optp->var_type == GET_BOOL) + if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL) { /* Set bool to 1 if no argument or if the user has used --enable-'option-name'. *optend was set to '0' if one used --disable-option */ - *((my_bool*) optp->value)= (my_bool) (!optend || *optend == '1'); + *((my_bool*) value)= (my_bool) (!optend || *optend == '1'); (*argc)--; get_one_option(optp->id, optp, argument); continue; } argument= optend; } - else if (optp->arg_type == OPT_ARG && optp->var_type == GET_BOOL) + else if (optp->arg_type == OPT_ARG && + (optp->var_type & GET_TYPE_MASK) == GET_BOOL) { if (optend == disabled_my_option) - *((my_bool*) optp->value)= (my_bool) 0; + *((my_bool*) value)= (my_bool) 0; else { if (!optend) /* No argument -> enable option */ - *((my_bool*) optp->value)= (my_bool) 1; + *((my_bool*) value)= (my_bool) 1; else /* If argument differs from 0, enable option, else disable */ - *((my_bool*) optp->value)= (my_bool) atoi(optend) != 0; + *((my_bool*) value)= (my_bool) atoi(optend) != 0; } (*argc)--; continue; @@ -326,7 +342,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) fprintf(stderr, "%s: option '--%s' requires an argument\n", - progname, optp->name); + my_progname, optp->name); return EXIT_ARGUMENT_REQUIRED; } argument= *pos; @@ -346,7 +362,8 @@ int handle_options(int *argc, char ***argv, { /* Option recognized. Find next what to do with it */ opt_found= 1; - if (optp->var_type == GET_BOOL && optp->arg_type == NO_ARG) + if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL && + optp->arg_type == NO_ARG) { *((my_bool*) optp->value)= (my_bool) 1; get_one_option(optp->id, optp, argument); @@ -370,7 +387,7 @@ int handle_options(int *argc, char ***argv, if (my_getopt_print_errors) fprintf(stderr, "%s: option '-%c' requires an argument\n", - progname, optp->id); + my_progname, optp->id); return EXIT_ARGUMENT_REQUIRED; } argument= *pos; @@ -382,7 +399,7 @@ int handle_options(int *argc, char ***argv, { fprintf(stderr, "%s: Error while setting value '%s' to '%s'\n", - progname, argument, optp->name); + my_progname, argument, optp->name); return error; } get_one_option(optp->id, optp, argument); @@ -393,7 +410,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) fprintf(stderr, - "%s: unknown option '-%c'\n", progname, *optend); + "%s: unknown option '-%c'\n", my_progname, *optend); return EXIT_UNKNOWN_OPTION; } } @@ -404,7 +421,7 @@ int handle_options(int *argc, char ***argv, { fprintf(stderr, "%s: Error while setting value '%s' to '%s'\n", - progname, argument, optp->name); + my_progname, argument, optp->name); return error; } get_one_option(optp->id, optp, argument); @@ -424,6 +441,47 @@ int handle_options(int *argc, char ***argv, return 0; } + +/* + function: check_struct_option + + Arguments: Current argument under processing from argv and a variable + where to store the possible key name. + + Return value: In case option is a struct option, returns a pointer to + the current argument at the position where the struct option (key_name) + ends, the next character after the dot. In case argument is not a struct + option, returns a pointer to the argument. + + key_name will hold the name of the key, or 0 if not found. +*/ + +static char *check_struct_option(char *cur_arg, char *key_name) +{ + char *ptr, *ptr2; + + ptr= strcend(cur_arg, '.'); + ptr2= strcend(cur_arg, '='); + + /* + Minimum length for a struct option is 3 (--a.b) + If the (first) dot is after an equal sign, then it is part + of a variable value and the option is not a struct option. + */ + if (strlen(ptr) >= 3 && ptr2 - ptr > 0) + { + uint len= ptr - cur_arg; + strnmov(key_name, cur_arg, len); + key_name[len]= '\0'; + return ++ptr; + } + else + { + key_name= 0; + return cur_arg; + } +} + /* function: setval @@ -444,7 +502,7 @@ static int setval(const struct my_option *opts, char *argument, if (!result_pos) return EXIT_NO_PTR_TO_VARIABLE; - switch (opts->var_type) { + switch ((opts->var_type & GET_TYPE_MASK)) { case GET_INT: case GET_UINT: /* fall through */ *((int*) result_pos)= (int) getopt_ll(argument, opts, &err); @@ -634,7 +692,7 @@ static void init_variables(const struct my_option *options) { if (options->value) { - switch (options->var_type) { + switch ((options->var_type & GET_TYPE_MASK)) { case GET_BOOL: if (options->u_max_value) *((my_bool*) options->u_max_value)= (my_bool) options->max_value; @@ -706,13 +764,15 @@ void my_print_help(const struct my_option *options) { printf("--%s", optp->name); col+= 2 + strlen(optp->name); - if (optp->var_type == GET_STR || optp->var_type == GET_STR_ALLOC) + if ((optp->var_type & GET_TYPE_MASK) == GET_STR || + (optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC) { printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "", optp->arg_type == OPT_ARG ? "]" : ""); col+= (optp->arg_type == OPT_ARG) ? 8 : 6; } - else if (optp->var_type == GET_NO_ARG || optp->var_type == GET_BOOL) + else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG || + (optp->var_type & GET_TYPE_MASK) == GET_BOOL) { putchar(' '); col++; @@ -775,7 +835,7 @@ void my_print_variables(const struct my_option *options) length= strlen(optp->name); for (; length < name_space; length++) putchar(' '); - switch (optp->var_type) { + switch ((optp->var_type & GET_TYPE_MASK)) { case GET_STR: case GET_STR_ALLOC: /* fall through */ printf("%s\n", *((char**) optp->value) ? *((char**) optp->value) : diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 68fa0cca2d5..72ee3e30c63 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4092,7 +4092,8 @@ replicating a LOAD DATA INFILE command.", IO_SIZE, 0}, {"key_buffer_size", OPT_KEY_BUFFER_SIZE, "The size of the buffer used for index blocks. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.", - (gptr*) &keybuff_size, (gptr*) &keybuff_size, 0, GET_ULL, + (gptr*) &keybuff_size, (gptr*) &keybuff_size, 0, + (enum get_opt_var_type) (GET_ULL | GET_ASK_ADDR), REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE, 0}, {"long_query_time", OPT_LONG_QUERY_TIME, @@ -5298,10 +5299,19 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } /* Initiates DEBUG - but no debugging here ! */ + +extern "C" gptr * +mysql_getopt_value(char *keyname, uint key_length, + const struct my_option *option) +{ + return option->value; +} + static void get_options(int argc,char **argv) { int ho_error; + my_getopt_register_get_addr(mysql_getopt_value); if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) exit(ho_error); if (argc > 0)