From e07c92cd95e7a1613d28a6f1cc0926fc451d184e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Feb 2002 15:32:11 +0200 Subject: small bug fix for 2.95.4 --- sql/sql_yacc.yy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 91cf0ae5fc9..742c39ce901 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -776,7 +776,7 @@ opt_table_options: table_options: table_option { $$=$1; } - | table_option table_options { $$= $1 | $2 } + | table_option table_options { $$= $1 | $2; } table_option: TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; } -- cgit v1.2.1 From 2224fe96801f110aace07e73baacceea40ad007e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Feb 2002 14:10:11 +0200 Subject: Fixing some bugs in UNION's --- sql/sql_select.cc | 299 ++++++++++++++++++++++++++++++------------------------ sql/sql_union.cc | 6 ++ 2 files changed, 174 insertions(+), 131 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e2e5e4bf55a..4d2a72c7784 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -144,7 +144,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab); static void init_sum_functions(Item_sum **func); static bool update_sum_func(Item_sum **func); static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, - bool distinct); + bool distinct, const char *message=NullS); static void describe_info(THD *thd, const char *info); /* @@ -195,6 +195,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, Procedure *procedure; List all_fields(fields); bool select_distinct; + SELECT_LEX *select_lex = &(thd->lex.select_lex); DBUG_ENTER("mysql_select"); /* Check that all tables, fields, conds and order are ok */ @@ -350,10 +351,13 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } if (cond_value == Item::COND_FALSE || !thd->select_limit) { /* Impossible cond */ - error=return_zero_rows(result, tables, fields, - join.tmp_table_param.sum_func_count != 0 && !group, - select_options,"Impossible WHERE",having, - procedure); + if (select_options & SELECT_DESCRIBE && select_lex->next) + select_describe(&join,false,false,false,"Impossible WHERE"); + else + error=return_zero_rows(result, tables, fields, + join.tmp_table_param.sum_func_count != 0 && !group, + select_options,"Impossible WHERE",having, + procedure); delete procedure; DBUG_RETURN(error); } @@ -366,17 +370,23 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, { if (res < 0) { - error=return_zero_rows(result, tables, fields, !group, - select_options,"No matching min/max row", - having,procedure); + if (select_options & SELECT_DESCRIBE && select_lex->next) + select_describe(&join,false,false,false,"No matching min/max row"); + else + error=return_zero_rows(result, tables, fields, !group, + select_options,"No matching min/max row", + having,procedure); delete procedure; DBUG_RETURN(error); } if (select_options & SELECT_DESCRIBE) { - describe_info(thd,"Select tables optimized away"); + if (select_lex->next) + select_describe(&join,false,false,false,"Select tables optimized away"); + else + describe_info(thd,"Select tables optimized away"); delete procedure; - DBUG_RETURN(0); + DBUG_RETURN(error); } tables=0; // All tables resolved } @@ -385,7 +395,12 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, { // Only test of functions error=0; if (select_options & SELECT_DESCRIBE) - describe_info(thd,"No tables used"); + { + if (select_lex->next) + select_describe(&join,false,false,false,"No tables used"); + else + describe_info(thd,"No tables used"); + } else { result->send_fields(fields,1); @@ -463,11 +478,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } if (make_join_select(&join,select,conds)) { - error=return_zero_rows(result,tables,fields, - join.tmp_table_param.sum_func_count != 0 && !group, - select_options, - "Impossible WHERE noticed after reading const tables", - having,procedure); + if (select_options & SELECT_DESCRIBE && select_lex->next) + select_describe(&join,false,false,false,"Impossible WHERE noticed after reading const tables"); + else + error=return_zero_rows(result,tables,fields, + join.tmp_table_param.sum_func_count != 0 && !group, + select_options, + "Impossible WHERE noticed after reading const tables", + having,procedure); goto err; } @@ -535,7 +553,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, make_join_readinfo(&join, (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | - (thd->lex.select_lex.ftfunc_list.elements ? SELECT_NO_JOIN_CACHE : 0)); + (select_lex->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE : 0)); /* Need to tell Innobase that to play it safe, it should fetch all columns of the tables: this is because MySQL @@ -2516,6 +2534,7 @@ static void make_join_readinfo(JOIN *join,uint options) { uint i; + SELECT_LEX *select_lex = &(join->thd->lex.select_lex); DBUG_ENTER("make_join_readinfo"); for (i=join->const_tables ; i < join->tables ; i++) @@ -2598,7 +2617,7 @@ make_join_readinfo(JOIN *join,uint options) /* These init changes read_record */ if (tab->use_quick == 2) { - join->thd->lex.select_lex.options|=QUERY_NO_GOOD_INDEX_USED; + select_lex->options|=QUERY_NO_GOOD_INDEX_USED; tab->read_first_record= join_init_quick_read_record; statistic_increment(select_range_check_count, &LOCK_status); } @@ -2613,7 +2632,7 @@ make_join_readinfo(JOIN *join,uint options) } else { - join->thd->lex.select_lex.options|=QUERY_NO_INDEX_USED; + select_lex->options|=QUERY_NO_INDEX_USED; statistic_increment(select_scan_count, &LOCK_status); } } @@ -2625,7 +2644,7 @@ make_join_readinfo(JOIN *join,uint options) } else { - join->thd->lex.select_lex.options|=QUERY_NO_INDEX_USED; + select_lex->options|=QUERY_NO_INDEX_USED; statistic_increment(select_full_join_count, &LOCK_status); } } @@ -2913,7 +2932,7 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List &fields, DBUG_ENTER("return_zero_rows"); if (select_options & SELECT_DESCRIBE) - { + { describe_info(current_thd, info); DBUG_RETURN(0); } @@ -6940,16 +6959,17 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) ****************************************************************************/ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, - bool distinct) + bool distinct,const char *message) { List field_list; Item *item; THD *thd=join->thd; + SELECT_LEX *select_lex = &(join->thd->lex.select_lex); DBUG_ENTER("select_describe"); /* Don't log this into the slow query log */ - join->thd->lex.select_lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED); - if (join->thd->lex.select == &join->thd->lex.select_lex) + select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED); + if (join->thd->lex.select == select_lex) { field_list.push_back(new Item_empty_string("table",NAME_LEN)); field_list.push_back(new Item_empty_string("type",10)); @@ -6970,133 +6990,150 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } char buff[512],*buff_ptr; String tmp(buff,sizeof(buff)),*packet= &thd->packet; - table_map used_tables=0; - for (uint i=0 ; i < join->tables ; i++) + if (message) { - JOIN_TAB *tab=join->join_tab+i; - TABLE *table=tab->table; - - if (tab->type == JT_ALL && tab->select && tab->select->quick) - tab->type= JT_RANGE; packet->length(0); - net_store_data(packet,table->table_name); - net_store_data(packet,join_type_str[tab->type]); - tmp.length(0); - key_map bits; - uint j; - for (j=0,bits=tab->keys ; bits ; j++,bits>>=1) - { - if (bits & 1) - { - if (tmp.length()) - tmp.append(','); - tmp.append(table->key_info[j].name); - } - } - if (tmp.length()) - net_store_data(packet,tmp.ptr(),tmp.length()); - else - net_store_null(packet); - if (tab->ref.key_parts) + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_data(packet,message,strlen(message)); + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) + DBUG_VOID_RETURN; + } + else + { + table_map used_tables=0; + for (uint i=0 ; i < join->tables ; i++) { - net_store_data(packet,table->key_info[tab->ref.key].name); - net_store_data(packet,(uint32) tab->ref.key_length); + JOIN_TAB *tab=join->join_tab+i; + TABLE *table=tab->table; + + if (tab->type == JT_ALL && tab->select && tab->select->quick) + tab->type= JT_RANGE; + packet->length(0); + net_store_data(packet,table->table_name); + net_store_data(packet,join_type_str[tab->type]); tmp.length(0); - for (store_key **ref=tab->ref.key_copy ; *ref ; ref++) + key_map bits; + uint j; + for (j=0,bits=tab->keys ; bits ; j++,bits>>=1) { - if (tmp.length()) - tmp.append(','); - tmp.append((*ref)->name()); + if (bits & 1) + { + if (tmp.length()) + tmp.append(','); + tmp.append(table->key_info[j].name); + } } - net_store_data(packet,tmp.ptr(),tmp.length()); - } - else if (tab->type == JT_NEXT) - { - net_store_data(packet,table->key_info[tab->index].name); - net_store_data(packet,(uint32) table->key_info[tab->index].key_length); - net_store_null(packet); - } - else if (tab->select && tab->select->quick) - { - net_store_data(packet,table->key_info[tab->select->quick->index].name);; - net_store_data(packet,(uint32) tab->select->quick->max_used_key_length); - net_store_null(packet); - } - else - { - net_store_null(packet); - net_store_null(packet); - net_store_null(packet); - } - sprintf(buff,"%.0f",join->best_positions[i].records_read); - net_store_data(packet,buff); - my_bool key_read=table->key_read; - if (tab->type == JT_NEXT && - ((table->used_keys & ((key_map) 1 << tab->index)))) - key_read=1; - - buff_ptr=buff; - if (tab->info) - net_store_data(packet,tab->info); - else if (tab->select) - { - if (tab->use_quick == 2) + if (tmp.length()) + net_store_data(packet,tmp.ptr(),tmp.length()); + else + net_store_null(packet); + if (tab->ref.key_parts) { - sprintf(buff_ptr,"range checked for each record (index map: %u)", - tab->keys); - buff_ptr=strend(buff_ptr); + net_store_data(packet,table->key_info[tab->ref.key].name); + net_store_data(packet,(uint32) tab->ref.key_length); + tmp.length(0); + for (store_key **ref=tab->ref.key_copy ; *ref ; ref++) + { + if (tmp.length()) + tmp.append(','); + tmp.append((*ref)->name()); + } + net_store_data(packet,tmp.ptr(),tmp.length()); + } + else if (tab->type == JT_NEXT) + { + net_store_data(packet,table->key_info[tab->index].name); + net_store_data(packet,(uint32) table->key_info[tab->index].key_length); + net_store_null(packet); + } + else if (tab->select && tab->select->quick) + { + net_store_data(packet,table->key_info[tab->select->quick->index].name);; + net_store_data(packet,(uint32) tab->select->quick->max_used_key_length); + net_store_null(packet); } else - buff_ptr=strmov(buff_ptr,"where used"); - } - if (key_read) - { - if (buff != buff_ptr) { - buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); } - buff_ptr=strmov(buff_ptr,"Using index"); - } - if (table->reginfo.not_exists_optimize) - { - if (buff != buff_ptr) + sprintf(buff,"%.0f",join->best_positions[i].records_read); + net_store_data(packet,buff); + my_bool key_read=table->key_read; + if (tab->type == JT_NEXT && + ((table->used_keys & ((key_map) 1 << tab->index)))) + key_read=1; + + buff_ptr=buff; + if (tab->info) + net_store_data(packet,tab->info); + else if (tab->select) { - buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + if (tab->use_quick == 2) + { + sprintf(buff_ptr,"range checked for each record (index map: %u)", + tab->keys); + buff_ptr=strend(buff_ptr); + } + else + buff_ptr=strmov(buff_ptr,"where used"); } - buff_ptr=strmov(buff_ptr,"Not exists"); - } - if (need_tmp_table) - { - need_tmp_table=0; - if (buff != buff_ptr) + if (key_read) { - buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Using index"); } - buff_ptr=strmov(buff_ptr,"Using temporary"); - } - if (need_order) - { - need_order=0; - if (buff != buff_ptr) + if (table->reginfo.not_exists_optimize) { - buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Not exists"); } - buff_ptr=strmov(buff_ptr,"Using filesort"); - } - if (distinct & test_all_bits(used_tables,thd->used_tables)) - { - if (buff != buff_ptr) + if (need_tmp_table) { - buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + need_tmp_table=0; + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Using temporary"); } - buff_ptr=strmov(buff_ptr,"Distinct"); - } - net_store_data(packet,buff,(uint) (buff_ptr - buff)); - if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) - DBUG_VOID_RETURN; /* purecov: inspected */ + if (need_order) + { + need_order=0; + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Using filesort"); + } + if (distinct & test_all_bits(used_tables,thd->used_tables)) + { + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Distinct"); + } + net_store_data(packet,buff,(uint) (buff_ptr - buff)); + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) + DBUG_VOID_RETURN; /* Purecov: Inspected */ - // For next iteration - used_tables|=table->map; + // For next iteration + used_tables|=table->map; + } } if (!join->thd->lex.select->next) send_eof(&thd->net); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 0d8a41e9966..51ad2425022 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -76,6 +76,12 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) for (sl= &lex->select_lex; sl; sl=sl->next) { lex->select=sl; + thd->offset_limit=sl->offset_limit; + thd->select_limit=sl->select_limit+sl->offset_limit; + if (thd->select_limit < sl->select_limit) + thd->select_limit= HA_POS_ERROR; // no limit + if (thd->select_limit == HA_POS_ERROR) + sl->options&= ~OPTION_FOUND_ROWS; res=mysql_select(thd, (TABLE_LIST*) sl->table_list.first, sl->item_list, sl->where, -- cgit v1.2.1 From 32a08516c974045bfc16fb30fcac18bb7ad8fbb8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Feb 2002 15:24:42 +0400 Subject: Added GIS extension BitKeeper/etc/ignore: Added myisam/rt_test myisam/sp_test to the ignore list --- sql/Makefile.am | 3 +- sql/field.cc | 57 +- sql/field.h | 32 +- sql/gstream.cc | 137 +++++ sql/gstream.h | 61 +++ sql/ha_myisam.cc | 8 +- sql/item.h | 1 + sql/item_cmpfunc.cc | 81 +++ sql/item_cmpfunc.h | 79 +++ sql/item_create.cc | 155 ++++++ sql/item_create.h | 38 ++ sql/item_func.cc | 129 +++++ sql/item_func.h | 87 +++- sql/item_strfunc.cc | 330 ++++++++++++ sql/item_strfunc.h | 193 +++++++ sql/lex.h | 43 ++ sql/opt_range.cc | 120 ++++- sql/opt_range.h | 9 +- sql/opt_sum.cc | 2 +- sql/spatial.cc | 1435 +++++++++++++++++++++++++++++++++++++++++++++++++++ sql/spatial.h | 476 +++++++++++++++++ sql/sql_class.h | 7 +- sql/sql_show.cc | 6 + sql/sql_string.cc | 40 ++ sql/sql_string.h | 45 ++ sql/sql_table.cc | 57 +- sql/sql_yacc.yy | 61 ++- sql/structs.h | 1 + sql/table.cc | 24 +- 29 files changed, 3670 insertions(+), 47 deletions(-) create mode 100644 sql/gstream.cc create mode 100644 sql/gstream.h create mode 100644 sql/spatial.cc create mode 100644 sql/spatial.h (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index e1ed9ad8915..c83b5388ca0 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -81,7 +81,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ slave.cc sql_repl.cc sql_union.cc \ mini_client.cc mini_client_errors.c \ - stacktrace.c repl_failsafe.h repl_failsafe.cc + stacktrace.c repl_failsafe.h repl_failsafe.cc \ + gstream.cc spatial.cc gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) diff --git a/sql/field.cc b/sql/field.cc index 2a0d0160d00..5d398d0ae5f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3712,7 +3712,7 @@ Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, :Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg), - packlength(blob_pack_length),binary_flag(binary_arg) + packlength(blob_pack_length),binary_flag(binary_arg), geom_flag(true) { flags|= BLOB_FLAG; if (binary_arg) @@ -3954,8 +3954,30 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr, /* The following is used only when comparing a key */ -void Field_blob::get_key_image(char *buff,uint length) +void Field_blob::get_key_image(char *buff,uint length, imagetype type) { + if(type == itMBR) + { + length-=HA_KEY_BLOB_LENGTH; + ulong blob_length=get_length(ptr); + char *blob; + get_ptr(&blob); + if(!blob_length) + { + return; + } + + MBR mbr; + Geometry gobj; + gobj.create_from_wkb(blob,blob_length); + gobj.get_mbr(&mbr); + float8store(buff, mbr.xmin); + float8store(buff+8, mbr.xmax); + float8store(buff+16, mbr.ymin); + float8store(buff+24, mbr.ymax); + return; + } + length-=HA_KEY_BLOB_LENGTH; uint32 blob_length=get_length(ptr); char *blob; @@ -3977,6 +3999,31 @@ void Field_blob::set_key_image(char *buff,uint length) Field_blob::store(buff+2,length); } +void Field_geom::get_key_image(char *buff,uint length, imagetype type) +{ + length-=HA_KEY_BLOB_LENGTH; + ulong blob_length=get_length(ptr); + char *blob; + get_ptr(&blob); + memcpy(buff+2,blob,length); + + MBR mbr; + Geometry gobj; + gobj.create_from_wkb(blob,blob_length); + gobj.get_mbr(&mbr); + float8store(buff, mbr.xmin); + float8store(buff+8, mbr.xmax); + float8store(buff+16, mbr.ymin); + float8store(buff+24, mbr.ymax); + return; +} + +void Field_geom::set_key_image(char *buff,uint length) +{ +} + + + int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length) { char *blob1; @@ -4606,6 +4653,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length) case FIELD_TYPE_LONG_BLOB: return 4+portable_sizeof_char_ptr; case FIELD_TYPE_SET: case FIELD_TYPE_ENUM: abort(); return 0; // This shouldn't happen + default: return 0; } return 0; // This shouldn't happen } @@ -4652,6 +4700,11 @@ Field *make_field(char *ptr, uint32 field_length, return new Field_blob(ptr,null_pos,null_bit, unireg_check, field_name, table, pack_length,f_is_binary(pack_flag) != 0); + if (f_is_geom(pack_flag)) + return new Field_geom(ptr,null_pos,null_bit, + unireg_check, field_name, table, + pack_length,f_is_binary(pack_flag) != 0); + if (interval) { if (f_is_enum(pack_flag)) diff --git a/sql/field.h b/sql/field.h index a9b257f0c3a..422e91768e6 100644 --- a/sql/field.h +++ b/sql/field.h @@ -47,6 +47,9 @@ public: enum utype { NONE,DATE,SHIELD,NOEMPTY,CASEUP,PNR,BGNR,PGNR,YES,NO,REL, CHECK,EMPTY,UNKNOWN_FIELD,CASEDN,NEXT_NUMBER,INTERVAL_FIELD, BIT_FIELD, TIMESTAMP_FIELD,CAPITALIZE,BLOB_FIELD}; + + enum imagetype { itRAW, itMBR}; + utype unireg_check; uint32 field_length; // Length of field uint16 flags; @@ -137,7 +140,7 @@ public: { memcpy(buff,ptr,length); } inline void set_image(char *buff,uint length) { memcpy(ptr,buff,length); } - virtual void get_key_image(char *buff,uint length) + virtual void get_key_image(char *buff,uint length, imagetype type) { get_image(buff,length); } virtual void set_key_image(char *buff,uint length) { set_image(buff,length); } @@ -825,6 +828,7 @@ class Field_blob :public Field_str { uint packlength; String value; // For temporaries bool binary_flag; + bool geom_flag; public: Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, @@ -834,7 +838,7 @@ public: struct st_table *table_arg, bool binary_arg) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, table_arg), - packlength(3),binary_flag(binary_arg) + packlength(3),binary_flag(binary_arg), geom_flag(true) { flags|= BLOB_FLAG; if (binary_arg) @@ -881,7 +885,7 @@ public: store_length(length); memcpy_fixed(ptr+packlength,&data,sizeof(char*)); } - void get_key_image(char *buff,uint length); + void get_key_image(char *buff,uint length, imagetype type); void set_key_image(char *buff,uint length); void sql_type(String &str) const; inline bool copy() @@ -910,6 +914,25 @@ public: }; +class Field_geom :public Field_blob { +public: + Field_geom(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg, + enum utype unireg_check_arg, const char *field_name_arg, + struct st_table *table_arg,uint blob_pack_length, + bool binary_arg) + :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, + field_name_arg, table_arg, blob_pack_length,binary_arg) {} + Field_geom(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, + struct st_table *table_arg, bool binary_arg) + :Field_blob(len_arg, maybe_null_arg, field_name_arg, + table_arg, binary_arg) {} + enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; } + + void get_key_image(char *buff,uint length, imagetype type); + void set_key_image(char *buff,uint length); +}; + + class Field_enum :public Field_str { protected: uint packlength; @@ -1059,6 +1082,8 @@ bool test_if_int(const char *str,int length); #define FIELDFLAG_INTERVAL 256 #define FIELDFLAG_BITFIELD 512 // mangled with dec! #define FIELDFLAG_BLOB 1024 // mangled with dec! +#define FIELDFLAG_GEOM 2048 + #define FIELDFLAG_LEFT_FULLSCREEN 8192 #define FIELDFLAG_RIGHT_FULLSCREEN 16384 #define FIELDFLAG_FORMAT_NUMBER 16384 // predit: ###,,## in output @@ -1085,6 +1110,7 @@ bool test_if_int(const char *str,int length); #define f_is_enum(x) ((x) & FIELDFLAG_INTERVAL) #define f_is_bitfield(x) ((x) & FIELDFLAG_BITFIELD) #define f_is_blob(x) (((x) & (FIELDFLAG_BLOB | FIELDFLAG_NUMBER)) == FIELDFLAG_BLOB) +#define f_is_geom(x) ((x) & FIELDFLAG_GEOM) #define f_is_equ(x) ((x) & (1+2+FIELDFLAG_PACK+31*256)) #define f_settype(x) (((int) x) << FIELDFLAG_PACK_SHIFT) #define f_maybe_null(x) (x & FIELDFLAG_MAYBE_NULL) diff --git a/sql/gstream.cc b/sql/gstream.cc new file mode 100644 index 00000000000..5a58fef6744 --- /dev/null +++ b/sql/gstream.cc @@ -0,0 +1,137 @@ +#include "mysql_priv.h" + +int GTextReadStream::get_next_toc_type() const +{ + const char *cur = m_cur; + while((*cur)&&(strchr(" \t\r\n",*cur))) + { + cur++; + } + if(!(*cur)) + { + return eostream; + } + + if(((*cur>='a') && (*cur<='z')) || ((*cur>='A') && (*cur<='Z')) || (*cur=='_')) + { + return word; + } + + if(((*cur>='0') && (*cur<='9')) || (*cur=='-') || (*cur=='+') || (*cur=='.')) + { + return numeric; + } + + if(*cur == '(') + { + return l_bra; + } + + if(*cur == ')') + { + return r_bra; + } + + if(*cur == ',') + { + return comma; + } + + return unknown; +} + +const char *GTextReadStream::get_next_word(int *word_len) +{ + const char *cur = m_cur; + while((*cur)&&(strchr(" \t\r\n",*cur))) + { + cur++; + } + m_last_text_position = cur; + + if(!(*cur)) + { + return 0; + } + + const char *wd_start = cur; + + if(((*cur<'a') || (*cur>'z')) && ((*cur<'A') || (*cur>'Z')) && (*cur!='_')) + { + return NULL; + } + + ++cur; + + while(((*cur>='a') && (*cur<='z')) || ((*cur>='A') && (*cur<='Z')) || (*cur=='_') || + ((*cur>='0') && (*cur<='9'))) + { + ++cur; + } + + *word_len = cur - wd_start; + + m_cur = cur; + + return wd_start; +} + +int GTextReadStream::get_next_number(double *d) +{ + const char *cur = m_cur; + while((*cur)&&(strchr(" \t\r\n",*cur))) + { + cur++; + } + + m_last_text_position = cur; + if(!(*cur)) + { + set_error_msg("Numeric constant expected"); + return 1; + } + + if(((*cur<'0') || (*cur>'9')) && (*cur!='-') && (*cur!='+') && (*cur!='.')) + { + set_error_msg("Numeric constant expected"); + return 1; + } + + char *endptr; + + *d = strtod(cur, &endptr); + + if(endptr) + { + m_cur = endptr; + } + + return 0; +} + +char GTextReadStream::get_next_symbol() +{ + const char *cur = m_cur; + while((*cur)&&(strchr(" \t\r\n",*cur))) + { + cur++; + } + if(!(*cur)) + { + return 0; + } + + m_cur = cur + 1; + m_last_text_position = cur; + + return *cur; +} + +void GTextReadStream::set_error_msg(const char *msg) +{ + size_t len = strlen(msg); + m_err_msg = (char *)my_realloc(m_err_msg, len + 1, MYF(MY_ALLOW_ZERO_PTR)); + memcpy(m_err_msg, msg, len + 1); +} + + diff --git a/sql/gstream.h b/sql/gstream.h new file mode 100644 index 00000000000..f8df6e337b0 --- /dev/null +++ b/sql/gstream.h @@ -0,0 +1,61 @@ +#ifndef GSTREAM_H +#define GSTREAM_H + +#ifdef WITHOUT_MYSQL + #include ".\rtree\myisamdef.h" +#else + #include "mysql_priv.h" +#endif + +class GTextReadStream +{ +public: + enum TokTypes + { + unknown, + eostream, + word, + numeric, + l_bra, + r_bra, + comma, + }; + GTextReadStream(const char *buffer, int size) : + m_cur(buffer), m_limit(buffer + size), m_last_text_position(buffer), m_err_msg(NULL) {} + GTextReadStream() : m_cur(NULL), m_limit(NULL), m_err_msg(NULL) {} + + ~GTextReadStream() + { + my_free(m_err_msg, MYF(MY_ALLOW_ZERO_PTR)); + } + + int get_next_toc_type() const; + const char *get_next_word(int *word_len); + int get_next_number(double *d); + char get_next_symbol(); + + const char *get_last_text_position() const + { + return m_last_text_position; + } + + void set_error_msg(const char *msg); + +// caller should free this pointer + char *get_error_msg() + { + char *err_msg = m_err_msg; + m_err_msg = NULL; + return err_msg; + } +protected: + const char *m_cur; + const char *m_limit; + const char *m_last_text_position; + char *m_err_msg; +}; + +#endif + + + diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 78ac9f3b309..05bc8901c5b 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -28,6 +28,7 @@ #include "../srclib/myisam/myisamdef.h" #else #include "../myisam/myisamdef.h" +#include "../myisam/rt_index.h" #endif ulong myisam_sort_buffer_size; @@ -763,7 +764,7 @@ int ha_myisam::index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag) { statistic_increment(ha_read_key_count,&LOCK_status); - int error=mi_rkey(file,buf,active_index, key, key_len, find_flag); + int error=mi_rkey(file,buf,active_index, key, key_len, (enum ha_rkey_function)find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; } @@ -772,7 +773,7 @@ int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key, uint key_len, enum ha_rkey_function find_flag) { statistic_increment(ha_read_key_count,&LOCK_status); - int error=mi_rkey(file,buf,index, key, key_len, find_flag); + int error=mi_rkey(file,buf,index, key, key_len, (enum ha_rkey_function)find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; } @@ -1008,7 +1009,8 @@ int ha_myisam::create(const char *name, register TABLE *table, pos=table->key_info; for (i=0; i < table->keys ; i++, pos++) { - keydef[i].flag= (pos->flags & (HA_NOSAME | HA_FULLTEXT)); + keydef[i].flag= (pos->flags & (HA_NOSAME | HA_FULLTEXT | HA_SPATIAL)); + keydef[i].key_alg=pos->key_alg; // +BAR keydef[i].seg=keyseg; keydef[i].keysegs=pos->key_parts; for (j=0 ; j < pos->key_parts ; j++) diff --git a/sql/item.h b/sql/item.h index 5028f25c6b8..247b3d7081d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -357,6 +357,7 @@ public: }; +#include "spatial.h" #include "item_sum.h" #include "item_func.h" #include "item_cmpfunc.h" diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0c83698e60a..1de398177b5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -24,6 +24,7 @@ #include "mysql_priv.h" #include + /* ** Test functions ** These returns 0LL if false and 1LL if true and null if some arg is null @@ -1348,3 +1349,83 @@ Item_func_regex::~Item_func_regex() } #endif /* USE_REGEX */ + + +/**************************************************************** + Classes and functions for spatial relations +*****************************************************************/ + +longlong Item_func_spatial_rel::val_int() +{ + String *res1=args[0]->val_str(&tmp_value1); + String *res2=args[1]->val_str(&tmp_value2); + Geometry g1, g2; + MBR mbr1,mbr2; + + if ((null_value=(args[0]->null_value || + args[1]->null_value || + g1.create_from_wkb(res1->ptr(),res1->length()) || + g2.create_from_wkb(res2->ptr(),res2->length()) || + g1.get_mbr(&mbr1) || + g2.get_mbr(&mbr2)))) + return 0; + + switch (spatial_rel) + { + case SP_CONTAINS_FUNC: + return mbr1.contains(&mbr2); + case SP_WITHIN_FUNC: + return mbr1.within(&mbr2); + case SP_EQUALS_FUNC: + return mbr1.equals(&mbr2); + case SP_DISJOINT_FUNC: + return mbr1.disjoint(&mbr2); + case SP_INTERSECTS_FUNC: + return mbr1.intersects(&mbr2); + case SP_TOUCHES_FUNC: + return mbr1.touches(&mbr2); + case SP_OVERLAPS_FUNC: + return mbr1.overlaps(&mbr2); + case SP_CROSSES_FUNC: + return 0; + default: + break; + } + + null_value=1; + return 0; +} + +longlong Item_func_isempty::val_int() +{ + String tmp; + null_value=0; + return args[0]->null_value ? 1 : 0; +} + +longlong Item_func_issimple::val_int() +{ + String tmp; + String *wkb=args[0]->val_str(&tmp); + + if ((null_value= (!wkb || args[0]->null_value ))) + return 0; + /* TODO: Ramil or Holyfoot, add real IsSimple calculation */ + return 0; +} + +longlong Item_func_isclosed::val_int() +{ + String tmp; + String *wkb=args[0]->val_str(&tmp); + Geometry geom; + int isclosed; + + null_value= (!wkb || + args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + !GEOM_METHOD_PRESENT(geom,is_closed) || + geom.is_closed(&isclosed)); + + return (longlong) isclosed; +} diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index c9c7d5654d6..b8f21f21008 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -570,3 +570,82 @@ inline Item *and_conds(Item *a,Item *b) cond->update_used_tables(); return cond; } + + +/************************************************************** +Spatial relations +***************************************************************/ + +class Item_func_spatial_rel :public Item_bool_func2 +{ + enum Functype spatial_rel; +public: + Item_func_spatial_rel(Item *a,Item *b, enum Functype sp_rel) : + Item_bool_func2(a,b) { spatial_rel = sp_rel; } + longlong val_int(); + enum Functype functype() const + { + switch (spatial_rel) + { + case SP_CONTAINS_FUNC: + return SP_WITHIN_FUNC; + case SP_WITHIN_FUNC: + return SP_CONTAINS_FUNC; + default: + return spatial_rel; + } + } + enum Functype rev_functype() const { return spatial_rel; } + const char *func_name() const + { + switch (spatial_rel) + { + case SP_CONTAINS_FUNC: + return "contains"; + case SP_WITHIN_FUNC: + return "within"; + case SP_EQUALS_FUNC: + return "equals"; + case SP_DISJOINT_FUNC: + return "disjoint"; + case SP_INTERSECTS_FUNC: + return "intersects"; + case SP_TOUCHES_FUNC: + return "touches"; + case SP_CROSSES_FUNC: + return "crosses"; + case SP_OVERLAPS_FUNC: + return "overlaps"; + default: + return "sp_unknown"; + } + } +}; + + +class Item_func_isempty :public Item_bool_func +{ +public: + Item_func_isempty(Item *a) :Item_bool_func(a) {} + longlong val_int(); + optimize_type select_optimize() const { return OPTIMIZE_NONE; } + const char *func_name() const { return "isempty"; } +}; + +class Item_func_issimple :public Item_bool_func +{ +public: + Item_func_issimple(Item *a) :Item_bool_func(a) {} + longlong val_int(); + optimize_type select_optimize() const { return OPTIMIZE_NONE; } + const char *func_name() const { return "issimple"; } +}; + +class Item_func_isclosed :public Item_bool_func +{ +public: + Item_func_isclosed(Item *a) :Item_bool_func(a) {} + longlong val_int(); + optimize_type select_optimize() const { return OPTIMIZE_NONE; } + const char *func_name() const { return "isclosed"; } +}; diff --git a/sql/item_create.cc b/sql/item_create.cc index 6f64e9517ba..79d7fcfe230 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -413,3 +413,158 @@ Item *create_func_cast(Item *a, Item_cast cast_type) } return res; } + +Item *create_func_geometry_from_text(Item* a) +{ + return new Item_func_geometry_from_text(a); +} + +Item *create_func_as_text(Item* a) +{ + return new Item_func_as_text(a); +} + +Item *create_func_startpoint(Item* a) +{ + return new Item_func_spatial_decomp(a, Item_func::SP_STARTPOINT); +} + +Item *create_func_endpoint(Item* a) +{ + return new Item_func_spatial_decomp(a, Item_func::SP_ENDPOINT); +} + +Item *create_func_exteriorring(Item* a) +{ + return new Item_func_spatial_decomp(a, Item_func::SP_EXTERIORRING); +} + +Item *create_func_pointn(Item* a, Item* b) +{ + return new Item_func_spatial_decomp_n(a,b,Item_func::SP_POINTN); +} + +Item *create_func_interiorringn(Item* a, Item* b) +{ + return new Item_func_spatial_decomp_n(a,b,Item_func::SP_INTERIORRINGN); +} + +Item *create_func_geometryn(Item* a, Item* b) +{ + return new Item_func_spatial_decomp_n(a,b,Item_func::SP_GEOMETRYN); +} + +Item *create_func_centroid(Item* a) +{ + return new Item_func_centroid(a); +} + +Item *create_func_envelope(Item* a) +{ + return new Item_func_envelope(a); +} + +Item *create_func_equals(Item* a, Item* b) +{ + return new Item_func_spatial_rel(a, b, Item_func::SP_EQUALS_FUNC); +} + +Item *create_func_disjoint(Item* a, Item* b) +{ + return new Item_func_spatial_rel(a, b, Item_func::SP_DISJOINT_FUNC); +} + +Item *create_func_intersects(Item* a, Item* b) +{ + return new Item_func_spatial_rel(a, b, Item_func::SP_INTERSECTS_FUNC); +} + +Item *create_func_touches(Item* a, Item* b) +{ + return new Item_func_spatial_rel(a, b, Item_func::SP_TOUCHES_FUNC); +} + +Item *create_func_crosses(Item* a, Item* b) +{ + return new Item_func_spatial_rel(a, b, Item_func::SP_CROSSES_FUNC); +} + +Item *create_func_within(Item* a, Item* b) +{ + return new Item_func_spatial_rel(a, b, Item_func::SP_WITHIN_FUNC); +} + +Item *create_func_contains(Item* a, Item* b) +{ + return new Item_func_spatial_rel(a, b, Item_func::SP_CONTAINS_FUNC); +} + +Item *create_func_overlaps(Item* a, Item* b) +{ + return new Item_func_spatial_rel(a, b, Item_func::SP_OVERLAPS_FUNC); +} + +Item *create_func_isempty(Item* a) +{ + return new Item_func_isempty(a); +} + +Item *create_func_issimple(Item* a) +{ + return new Item_func_issimple(a); +} + +Item *create_func_isclosed(Item* a) +{ + return new Item_func_isclosed(a); +} + +Item *create_func_geometry_type(Item* a) +{ + return new Item_func_geometry_type(a); +} + +Item *create_func_dimension(Item* a) +{ + return new Item_func_dimension(a); +} + +Item *create_func_x(Item* a) +{ + return new Item_func_x(a); +} + +Item *create_func_y(Item* a) +{ + return new Item_func_y(a); +} + +Item *create_func_numpoints(Item* a) +{ + return new Item_func_numpoints(a); +} + +Item *create_func_numinteriorring(Item* a) +{ + return new Item_func_numinteriorring(a); +} + +Item *create_func_numgeometries(Item* a) +{ + return new Item_func_numgeometries(a); +} + +Item *create_func_area(Item* a) +{ + return new Item_func_area(a); +} + +Item *create_func_glength(Item* a) +{ + return new Item_func_glength(a); +} + +Item *create_func_point(Item* a, Item* b) +{ + return new Item_func_point(a,b); +} diff --git a/sql/item_create.h b/sql/item_create.h index 580596505da..6f7e8ebf89a 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -88,3 +88,41 @@ Item *create_func_version(void); Item *create_func_weekday(Item* a); Item *create_load_file(Item* a); Item *create_wait_for_master_pos(Item* a, Item* b); + +Item *create_func_geometry_from_text(Item* a); +Item *create_func_as_text(Item* a); +Item *create_func_startpoint(Item* a); +Item *create_func_endpoint(Item* a); +Item *create_func_exteriorring(Item* a); +Item *create_func_centroid(Item* a); +Item *create_func_envelope(Item* a); +Item *create_func_pointn(Item* a, Item* b); +Item *create_func_interiorringn(Item* a, Item* b); +Item *create_func_geometryn(Item* a, Item* b); + +Item *create_func_equals(Item* a, Item* b); +Item *create_func_disjoint(Item* a, Item* b); +Item *create_func_intersects(Item* a, Item* b); +Item *create_func_touches(Item* a, Item* b); +Item *create_func_crosses(Item* a, Item* b); +Item *create_func_within(Item* a, Item* b); +Item *create_func_contains(Item* a, Item* b); +Item *create_func_overlaps(Item* a, Item* b); + +Item *create_func_isempty(Item* a); +Item *create_func_issimple(Item* a); +Item *create_func_isclosed(Item* a); + +Item *create_func_geometry_type(Item* a); +Item *create_func_dimension(Item* a); +Item *create_func_x(Item* a); +Item *create_func_y(Item* a); +Item *create_func_area(Item* a); +Item *create_func_glength(Item* a); + +Item *create_func_numpoints(Item* a); +Item *create_func_numinteriorring(Item* a); +Item *create_func_numgeometries(Item* a); + +Item *create_func_point(Item* a,Item* b); + diff --git a/sql/item_func.cc b/sql/item_func.cc index 1818a755a43..65d4413b484 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -27,6 +27,8 @@ #include #include #include "slave.h" // for wait_for_master_pos +#include "gstream.h" + /* return TRUE if item is a constant */ @@ -2252,3 +2254,130 @@ Item *get_system_var(LEX_STRING name) my_error(ER_UNKNOWN_SYSTEM_VARIABLE,MYF(0),name); return 0; } + + +/************************************************************************** +Spatial functions +***************************************************************************/ + +longlong Item_func_dimension::val_int() +{ + uint32 dim; + String *wkb=args[0]->val_str(&value); + Geometry geom; + + null_value= (!wkb || + args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + geom.dimension(&dim)); + + return (longlong) dim; +} + +longlong Item_func_numinteriorring::val_int() +{ + uint32 num; + String *wkb=args[0]->val_str(&value); + Geometry geom; + + null_value= (!wkb || + args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + !GEOM_METHOD_PRESENT(geom,num_interior_ring) || + geom.num_interior_ring(&num)); + + return (longlong) num; +} + +longlong Item_func_numgeometries::val_int() +{ + uint32 num; + String *wkb=args[0]->val_str(&value); + Geometry geom; + + null_value= (!wkb || + args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + !GEOM_METHOD_PRESENT(geom,num_geometries) || + geom.num_geometries(&num)); + + return (longlong) num; +} + +longlong Item_func_numpoints::val_int() +{ + uint32 num; + String *wkb=args[0]->val_str(&value); + Geometry geom; + + null_value= (!wkb || + args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + !GEOM_METHOD_PRESENT(geom,num_points) || + geom.num_points(&num)); + + return (longlong) num; +} + + +double Item_func_x::val() +{ + double res; + String *wkb=args[0]->val_str(&value); + Geometry geom; + + null_value= (!wkb || + args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + !GEOM_METHOD_PRESENT(geom,get_x) || + geom.get_x(&res)); + + return res; +} + + +double Item_func_y::val() +{ + double res; + String *wkb=args[0]->val_str(&value); + Geometry geom; + + null_value= (!wkb || + args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + !GEOM_METHOD_PRESENT(geom,get_y) || + geom.get_y(&res)); + + return res; +} + + +double Item_func_area::val() +{ + double res; + String *wkb=args[0]->val_str(&value); + Geometry geom; + + null_value= (!wkb || + args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + !GEOM_METHOD_PRESENT(geom,area) || + geom.area(&res)); + + return res; +} + + +double Item_func_glength::val() +{ + double res; + String *wkb=args[0]->val_str(&value); + Geometry geom; + + null_value= (!wkb || + args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + !GEOM_METHOD_PRESENT(geom,length) || + geom.length(&res)); + return res; +} diff --git a/sql/item_func.h b/sql/item_func.h index 823bfb44a96..41df0a63c1c 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -39,7 +39,12 @@ public: enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC, GE_FUNC,GT_FUNC,FT_FUNC, LIKE_FUNC,NOTLIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC, - COND_AND_FUNC,COND_OR_FUNC,BETWEEN,IN_FUNC,INTERVAL_FUNC}; + COND_AND_FUNC,COND_OR_FUNC,BETWEEN,IN_FUNC,INTERVAL_FUNC, + SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC, + SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC, + SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC, + SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING, + SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN}; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL }; enum Type type() const { return FUNC_ITEM; } virtual enum Functype functype() const { return UNKNOWN_FUNC; } @@ -944,6 +949,86 @@ public: void init_search(bool no_order); }; + +class Item_func_dimension :public Item_int_func +{ + String value; +public: + Item_func_dimension(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "dimension"; } + void fix_length_and_dec() { max_length=10; } +}; + + +class Item_func_x :public Item_real_func +{ + String value; +public: + Item_func_x(Item *a) :Item_real_func(a) {} + double val(); + const char *func_name() const { return "x"; } +}; + + +class Item_func_y :public Item_real_func +{ + String value; +public: + Item_func_y(Item *a) :Item_real_func(a) {} + double val(); + const char *func_name() const { return "y"; } +}; + + +class Item_func_numgeometries :public Item_int_func +{ + String value; +public: + Item_func_numgeometries(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "numgeometries"; } + void fix_length_and_dec() { max_length=10; } +}; + +class Item_func_numinteriorring :public Item_int_func +{ + String value; +public: + Item_func_numinteriorring(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "numinteriorring"; } + void fix_length_and_dec() { max_length=10; } +}; + +class Item_func_numpoints :public Item_int_func +{ + String value; +public: + Item_func_numpoints(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "numpoints"; } + void fix_length_and_dec() { max_length=10; } +}; + +class Item_func_area :public Item_real_func +{ + String value; +public: + Item_func_area(Item *a) :Item_real_func(a) {} + double val(); + const char *func_name() const { return "area"; } +}; + +class Item_func_glength :public Item_real_func +{ + String value; +public: + Item_func_glength(Item *a) :Item_real_func(a) {} + double val(); + const char *func_name() const { return "glength"; } +}; + class Item_func_match_nl :public Item_func_match { public: diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index c64fdc7a049..cdf909e8c4d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1953,3 +1953,333 @@ String* Item_func_inet_ntoa::val_str(String* str) str->length(str->length()-1); // Remove last '.'; return str; } + +/******************************************************* +General functions for spatial objects +********************************************************/ + +#include "gstream.h" + +String *Item_func_geometry_from_text::val_str(String *str) +{ + Geometry geom; + String *wkt = args[0]->val_str(str); + GTextReadStream trs(wkt->ptr(), wkt->length()); + + str->length(0); + if ((null_value=(args[0]->null_value || geom.create_from_wkt(&trs, str, 0)))) + return 0; + return str; +} + + +void Item_func_geometry_from_text::fix_length_and_dec() +{ + max_length=MAX_BLOB_WIDTH; +} + + +String *Item_func_as_text::val_str(String *str) +{ + String *wkt = args[0]->val_str(str); + Geometry geom; + + str->length(0); + if ((null_value=(args[0]->null_value || + geom.create_from_wkb(wkt->ptr(),wkt->length()) || + geom.as_wkt(str)))) + return 0; + return str; +} + +void Item_func_as_text::fix_length_and_dec() +{ + max_length=MAX_BLOB_WIDTH; +} + +String *Item_func_geometry_type::val_str(String *str) +{ + String *wkt = args[0]->val_str(str); + Geometry geom; + + if ((null_value=(args[0]->null_value || + geom.create_from_wkb(wkt->ptr(),wkt->length())))) + return 0; + str->copy(geom.get_class_info()->m_name); + return str; +} + + +String *Item_func_envelope::val_str(String *str) +{ + String *wkb = args[0]->val_str(str); + Geometry geom; + + null_value = args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + geom.envelope(str); + + return null_value ? 0 : str; +} + + +String *Item_func_centroid::val_str(String *str) +{ + String *wkb = args[0]->val_str(str); + Geometry geom; + + null_value = args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) || + !GEOM_METHOD_PRESENT(geom,centroid) || + geom.centroid(str); + + return null_value ? 0: str; +} + + +/*********************************************** + Spatial decomposition functions +***********************************************/ + +String *Item_func_spatial_decomp::val_str(String *str) +{ + String *wkb = args[0]->val_str(str); + Geometry geom; + + if ((null_value = (args[0]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length())))) + return 0; + + null_value=1; + switch(decomp_func) + { + case SP_STARTPOINT: + if (!GEOM_METHOD_PRESENT(geom,start_point) || geom.start_point(str)) + goto ret; + break; + + case SP_ENDPOINT: + if (!GEOM_METHOD_PRESENT(geom,end_point) || geom.end_point(str)) + goto ret; + break; + + case SP_EXTERIORRING: + if (!GEOM_METHOD_PRESENT(geom,exterior_ring) || geom.exterior_ring(str)) + goto ret; + break; + + default: + goto ret; + } + null_value=0; + +ret: + return null_value ? 0 : str; +} + + +String *Item_func_spatial_decomp_n::val_str(String *str) +{ + String *wkb = args[0]->val_str(str); + long n = (long) args[1]->val_int(); + Geometry geom; + + if ((null_value = (args[0]->null_value || + args[1]->null_value || + geom.create_from_wkb(wkb->ptr(),wkb->length()) ))) + return 0; + + null_value=1; + + switch(decomp_func_n) + { + case SP_POINTN: + if (!GEOM_METHOD_PRESENT(geom,point_n) || + geom.point_n(n,str)) + goto ret; + break; + + case SP_GEOMETRYN: + if (!GEOM_METHOD_PRESENT(geom,geometry_n) || + geom.geometry_n(n,str)) + goto ret; + break; + + case SP_INTERIORRINGN: + if (!GEOM_METHOD_PRESENT(geom,interior_ring_n) || + geom.interior_ring_n(n,str)) + goto ret; + break; + + default: + goto ret; + } + null_value=0; + +ret: + return null_value ? 0 : str; +} + + + +/*********************************************** +Functions to concatinate various spatial objects +************************************************/ + + +/* +* Concatinate doubles into Point +*/ + + +String *Item_func_point::val_str(String *str) +{ + if ( (null_value = (args[0]->null_value || + args[1]->null_value || + str->realloc(1+4+8+8)))) + return 0; + + str->length(0); + str->q_append((char)Geometry::wkbNDR); + str->q_append((uint32)Geometry::wkbPoint); + str->q_append((double)args[0]->val()); + str->q_append((double)args[1]->val()); + return str; +} + + +/* + Concatinates various items into various collections + with checkings for valid wkb type of items. + For example, MultiPoint can be a collection of Points only. + coll_type contains wkb type of target collection. + item_type contains a valid wkb type of items. + In the case when coll_type is wkbGeometryCollection, + we do not check wkb type of items, any is valid. +*/ + +String *Item_func_spatial_collection::val_str(String *str) +{ + uint i; + + null_value=1; + + str->length(0); + if(str->reserve(9,512)) + return 0; + + str->q_append((char)Geometry::wkbNDR); + str->q_append((uint32)coll_type); + str->q_append((uint32)arg_count); + + for (i = 0; i < arg_count; ++i) + { + if (args[i]->null_value) + goto ret; + + String *res = args[i]->val_str(str); + + if ( coll_type == Geometry::wkbGeometryCollection ) + { + /* + In the case of GeometryCollection we don't need + any checkings for item types, so just copy them + into target collection + */ + if ((null_value=(str->reserve(res->length(),512)))) + goto ret; + + str->q_append(res->ptr(),res->length()); + } + else + { + uint32 wkb_type, len=res->length(); + const char *data=res->ptr()+1; + + /* + In the case of named collection we must to + check that items are of specific type, let's + do this checking now + */ + + if (len<5) + goto ret; + wkb_type=uint4korr(data); + data+=4; + len-=5; + if ( wkb_type != item_type ) + goto ret; + + switch(coll_type) + { + case Geometry::wkbMultiPoint: + case Geometry::wkbMultiLineString: + case Geometry::wkbMultiPolygon: + if (lenreserve(len,512)) + goto ret; + str->q_append(data,len); + break; + + case Geometry::wkbLineString: + if (str->reserve(POINT_DATA_SIZE,512)) + goto ret; + str->q_append(data,POINT_DATA_SIZE); + break; + + case Geometry::wkbPolygon: + { + uint32 n_points; + double x1, y1, x2, y2; + + if (len < WKB_HEADER_SIZE + 4 + 8 + 8) + goto ret; + data+=WKB_HEADER_SIZE; + len-=WKB_HEADER_SIZE; + + uint32 llen=len; + const char *ldata=data; + + n_points=uint4korr(data); + data+=4; + float8get(x1,data); + data+=8; + float8get(y1,data); + data+=8; + + len-= 4 + 8 + 8; + + if (len < n_points * POINT_DATA_SIZE) + goto ret; + data+=(n_points-2) * POINT_DATA_SIZE; + + float8get(x2,data); + float8get(y2,data+8); + + if ((x1 != x2) || (y1 != y2)) + goto ret; + + if (str->reserve(llen,512)) + goto ret; + str->q_append(ldata, llen); + } + break; + + default: + goto ret; + } + } + } + + if (str->length() > max_allowed_packet) + goto ret; + + null_value = 0; + +ret: + return null_value ? 0 : str; +} diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 1279a5099d5..a8768e62f98 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -475,3 +475,196 @@ public: const char *func_name() const { return "inet_ntoa"; } void fix_length_and_dec() { decimals = 0; max_length=3*8+7; } }; + + +/******************************************************* +Spatial functions +********************************************************/ + +class Item_func_geometry_from_text :public Item_str_func +{ +public: + Item_func_geometry_from_text(Item *a) :Item_str_func(a) {} + const char *func_name() const { return "geometryfromtext"; } + String *val_str(String *); + void fix_length_and_dec(); +}; + +class Item_func_as_text :public Item_str_func +{ +public: + Item_func_as_text(Item *a) :Item_str_func(a) {} + const char *func_name() const { return "astext"; } + String *val_str(String *); + void fix_length_and_dec(); +}; + +class Item_func_geometry_type :public Item_str_func +{ +public: + Item_func_geometry_type(Item *a) :Item_str_func(a) {} + String *val_str(String *); + const char *func_name() const { return "geometrytype"; } + void fix_length_and_dec() + { + max_length=20; // "GeometryCollection" is the most long + }; +}; + +class Item_func_centroid :public Item_str_func +{ +public: + Item_func_centroid(Item *a) :Item_str_func(a) {} + const char *func_name() const { return "centroid"; } + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} +}; + +class Item_func_envelope :public Item_str_func +{ +public: + Item_func_envelope(Item *a) :Item_str_func(a) {} + const char *func_name() const { return "envelope"; } + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} +}; + +class Item_func_point :public Item_str_func +{ +public: + Item_func_point(Item *a,Item *b) :Item_str_func(a,b) {} + const char *func_name() const { return "point"; } + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} +}; + +class Item_func_spatial_decomp :public Item_str_func +{ + enum Functype decomp_func; +public: + Item_func_spatial_decomp(Item *a, Item_func::Functype ft) : + Item_str_func(a) { decomp_func = ft; } + const char *func_name() const + { + switch (decomp_func) + { + case SP_STARTPOINT: + return "startpoint"; + case SP_ENDPOINT: + return "endpoint"; + case SP_EXTERIORRING: + return "exteriorring"; + default: + return "spatial_decomp_unknown"; + } + } + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} +}; + +class Item_func_spatial_decomp_n :public Item_str_func +{ + enum Functype decomp_func_n; +public: + Item_func_spatial_decomp_n(Item *a, Item *b, Item_func::Functype ft) : + Item_str_func(a, b) { decomp_func_n = ft; } + const char *func_name() const + { + switch (decomp_func_n) + { + case SP_POINTN: + return "pointn"; + case SP_GEOMETRYN: + return "geometryn"; + case SP_INTERIORRINGN: + return "interiorringn"; + default: + return "spatial_decomp_n_unknown"; + } + } + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} +}; + + +class Item_func_spatial_collection :public Item_str_func +{ + String tmp_value; + enum Geometry::wkbType coll_type; + enum Geometry::wkbType item_type; +public: + Item_func_spatial_collection( + List &list, enum Geometry::wkbType ct, enum Geometry::wkbType it) : + Item_str_func(list) + { + coll_type=ct; + item_type=it; + } + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} + const char *func_name() const { return "multipoint"; } +}; + + +/* +class Item_func_multipoint :public Item_str_func +{ + String tmp_value; +public: + Item_func_multipoint(List &list) :Item_str_func(list) {} + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} + const char *func_name() const { return "multipoint"; } +}; + +class Item_func_linestring :public Item_str_func +{ + String tmp_value; +public: + Item_func_linestring(List &list) :Item_str_func(list) {} + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} + const char *func_name() const { return "linestring"; } +}; + +class Item_func_multilinestring :public Item_str_func +{ + String tmp_value; +public: + Item_func_multilinestring(List &list) :Item_str_func(list) {} + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} + const char *func_name() const { return "multilinestring"; } +}; + +class Item_func_polygon :public Item_str_func +{ + String tmp_value; +public: + Item_func_polygon(List &list) :Item_str_func(list) {} + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} + const char *func_name() const { return "polygon"; } +}; + +class Item_func_multipolygon :public Item_str_func +{ + String tmp_value; +public: + Item_func_multipolygon(List &list) :Item_str_func(list) {} + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} + const char *func_name() const { return "multipolygon"; } +}; + +class Item_func_geometrycollection :public Item_str_func +{ + String tmp_value; +public: + Item_func_geometrycollection(List &list) :Item_str_func(list) {} + String *val_str(String *); + void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;} + const char *func_name() const { return "geometrycollection"; } +}; + +*/ diff --git a/sql/lex.h b/sql/lex.h index 6bee4152e48..04edaf217b9 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -75,6 +75,7 @@ static SYMBOL symbols[] = { { "BOOL", SYM(BOOL_SYM),0,0}, { "BOOLEAN", SYM(BOOLEAN_SYM),0,0}, { "BOTH", SYM(BOTH),0,0}, + { "BTREE", SYM(BTREE_SYM),0,0}, { "BY", SYM(BY),0,0}, { "CACHE", SYM(CACHE_SYM),0,0}, { "CASCADE", SYM(CASCADE),0,0}, @@ -158,12 +159,14 @@ static SYMBOL symbols[] = { { "FULL", SYM(FULL),0,0}, { "FULLTEXT", SYM(FULLTEXT_SYM),0,0}, { "FUNCTION", SYM(UDF_SYM),0,0}, + { "GEOM", SYM(GEOM_SYM),0,0}, { "GLOBAL", SYM(GLOBAL_SYM),0,0}, { "GRANT", SYM(GRANT),0,0}, { "GRANTS", SYM(GRANTS),0,0}, { "GROUP", SYM(GROUP),0,0}, { "HAVING", SYM(HAVING),0,0}, { "HANDLER", SYM(HANDLER_SYM),0,0}, + { "HASH", SYM(HASH_SYM),0,0}, { "HEAP", SYM(HEAP_SYM),0,0}, { "HIGH_PRIORITY", SYM(HIGH_PRIORITY),0,0}, { "HOUR", SYM(HOUR_SYM),0,0}, @@ -296,6 +299,7 @@ static SYMBOL symbols[] = { { "ROLLBACK", SYM(ROLLBACK_SYM),0,0}, { "ROW", SYM(ROW_SYM),0,0}, { "ROWS", SYM(ROWS_SYM),0,0}, + { "RTREE", SYM(RTREE_SYM),0,0}, { "SECOND", SYM(SECOND_SYM),0,0}, { "SELECT", SYM(SELECT_SYM),0,0}, { "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0}, @@ -308,6 +312,7 @@ static SYMBOL symbols[] = { { "SLAVE", SYM(SLAVE),0,0}, { "SMALLINT", SYM(SMALLINT),0,0}, { "SONAME", SYM(UDF_SONAME_SYM),0,0}, + { "SPATIAL", SYM(SPATIAL_SYM),0,0}, { "SQL_AUTO_IS_NULL", SYM(SQL_AUTO_IS_NULL),0,0}, { "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT),0,0}, { "SQL_BIG_SELECTS", SYM(SQL_BIG_SELECTS),0,0}, @@ -384,8 +389,10 @@ static SYMBOL sql_functions[] = { { "ABS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_abs)}, { "ACOS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_acos)}, { "ADDDATE", SYM(DATE_ADD_INTERVAL),0,0}, + { "AREA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_area)}, { "ASCII", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ascii)}, { "ASIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_asin)}, + { "ASTEXT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_as_text)}, { "ATAN", SYM(ATAN),0,0}, { "ATAN2", SYM(ATAN),0,0}, { "BENCHMARK", SYM(BENCHMARK_SYM),0,0}, @@ -396,17 +403,20 @@ static SYMBOL sql_functions[] = { { "CAST", SYM(CAST_SYM),0,0}, { "CEILING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)}, { "BIT_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)}, + { "CENTROID", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_centroid)}, { "CHAR_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, { "CHARACTER_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, { "COALESCE", SYM(COALESCE),0,0}, { "CONCAT", SYM(CONCAT),0,0}, { "CONCAT_WS", SYM(CONCAT_WS),0,0}, { "CONNECTION_ID", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)}, + { "CONTAINS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_contains)}, { "CONV", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)}, { "CONVERT", SYM(CONVERT_SYM),0,0}, { "COUNT", SYM(COUNT_SYM),0,0}, { "COS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)}, { "COT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)}, + { "CROSSES", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_crosses)}, { "CURDATE", SYM(CURDATE),0,0}, { "CURTIME", SYM(CURTIME),0,0}, { "DATE_ADD", SYM(DATE_ADD_INTERVAL),0,0}, @@ -420,9 +430,15 @@ static SYMBOL sql_functions[] = { { "DEGREES", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_degrees)}, { "DES_ENCRYPT", SYM(DES_ENCRYPT_SYM),0,0}, { "DES_DECRYPT", SYM(DES_DECRYPT_SYM),0,0}, + { "DIMENSION", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dimension)}, + { "DISJOINT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_disjoint)}, { "ELT", SYM(ELT_FUNC),0,0}, { "ENCODE", SYM(ENCODE_SYM),0,0}, { "ENCRYPT", SYM(ENCRYPT),0,0}, + { "ENDPOINT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_endpoint)}, + { "ENVELOPE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_envelope)}, + { "EQUALS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_equals)}, + { "EXTERIORRING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_exteriorring)}, { "EXTRACT", SYM(EXTRACT_SYM),0,0}, { "EXP", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_exp)}, { "EXPORT_SET", SYM(EXPORT_SET),0,0}, @@ -434,6 +450,11 @@ static SYMBOL sql_functions[] = { { "FROM_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_from_days)}, { "FROM_UNIXTIME", SYM(FROM_UNIXTIME),0,0}, { "GET_LOCK", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_get_lock)}, + { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION),0,0}, + { "GEOMETRYN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_geometryn)}, + { "GEOMETRYTYPE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_geometry_type)}, + { "GEOMFROMTEXT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_geometry_from_text)}, + { "GLENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_glength)}, { "GREATEST", SYM(GREATEST_SYM),0,0}, { "GROUP_UNIQUE_USERS", SYM(GROUP_UNIQUE_USERS),0,0}, { "HEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_hex)}, @@ -441,10 +462,16 @@ static SYMBOL sql_functions[] = { { "INET_ATON", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_aton)}, { "INET_NTOA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_ntoa)}, { "INSTR", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_instr)}, + { "INTERIORRINGN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_interiorringn)}, + { "INTERSECTS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_intersects)}, + { "ISCLOSED", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isclosed)}, + { "ISEMPTY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isempty)}, { "ISNULL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)}, + { "ISSIMPLE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_issimple)}, { "LCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)}, { "LEAST", SYM(LEAST_SYM),0,0}, { "LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)}, + { "LINESTRING", SYM(LINESTRING),0,0}, { "LOAD_FILE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_load_file)}, { "LOCATE", SYM(LOCATE),0,0}, { "LOG", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log)}, @@ -460,15 +487,25 @@ static SYMBOL sql_functions[] = { { "MID", SYM(SUBSTRING),0,0}, /* unireg function */ { "MIN", SYM(MIN_SYM),0,0}, { "MOD", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_mod)}, + { "MULTILINESTRING", SYM(MULTILINESTRING),0,0}, + { "MULTIPOINT", SYM(MULTIPOINT),0,0}, + { "MULTIPOLYGON", SYM(MULTIPOLYGON),0,0}, { "MONTHNAME", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_monthname)}, { "NOW", SYM(NOW_SYM),0,0}, { "NULLIF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_nullif)}, + { "NUMGEOMETRIES", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numgeometries)}, + { "NUMINTERIORRING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numinteriorring)}, + { "NUMPOINTS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numpoints)}, { "OCTET_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)}, { "OCT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_oct)}, { "ORD", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ord)}, + { "OVERLAPS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_overlaps)}, { "PERIOD_ADD", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_add)}, { "PERIOD_DIFF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_diff)}, { "PI", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_pi)}, + { "POINT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_point)}, + { "POINTN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pointn)}, + { "POLYGON", SYM(POLYGON),0,0}, { "POSITION", SYM(POSITION_SYM),0,0}, { "POW", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, { "POWER", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, @@ -489,6 +526,7 @@ static SYMBOL sql_functions[] = { { "SOUNDEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_soundex)}, { "SPACE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_space)}, { "SQRT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sqrt)}, + { "STARTPOINT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_startpoint)}, { "STD", SYM(STD_SYM),0,0}, { "STDDEV", SYM(STD_SYM),0,0}, { "STRCMP", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_strcmp)}, @@ -501,6 +539,7 @@ static SYMBOL sql_functions[] = { { "TIME_FORMAT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_time_format)}, { "TIME_TO_SEC", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_time_to_sec)}, { "TO_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_to_days)}, + { "TOUCHES", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_touches)}, { "TRIM", SYM(TRIM),0,0}, { "UCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, { "UNIQUE_USERS", SYM(UNIQUE_USERS),0,0}, @@ -510,5 +549,9 @@ static SYMBOL sql_functions[] = { { "VERSION", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)}, { "WEEK", SYM(WEEK_SYM),0,0}, { "WEEKDAY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)}, + { "WITHIN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_within)}, + { "X", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_x)}, + { "Y", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_y)}, { "YEARWEEK", SYM(YEARWEEK),0,0} + }; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index c3f4c91b718..34ee34ecc79 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -172,8 +172,9 @@ public: void store(uint length,char **min_key,uint min_key_flag, char **max_key, uint max_key_flag) { - if (!(min_flag & NO_MIN_RANGE) && - !(min_key_flag & (NO_MIN_RANGE | NEAR_MIN))) + if ((min_flag & GEOM_FLAG) || + (!(min_flag & NO_MIN_RANGE) && + !(min_key_flag & (NO_MIN_RANGE | NEAR_MIN)))) { if (maybe_null && *min_value) { @@ -659,6 +660,8 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, key_parts->null_bit= key_info->key_part[part].null_bit; if (key_parts->field->type() == FIELD_TYPE_BLOB) key_parts->part_length+=HA_KEY_BLOB_LENGTH; + key_parts->image_type = + (key_info->flags & HA_SPATIAL) ? Field::itMBR : Field::itRAW; } param.real_keynr[param.keys++]=idx; } @@ -676,6 +679,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, { SEL_ARG **key,**end,**best_key=0; + for (idx=0,key=tree->keys, end=key+param.keys ; key != end ; key++,idx++) @@ -1042,7 +1046,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, DBUG_RETURN(0); if (maybe_null) *str=0; // Not NULL - field->get_key_image(str+maybe_null,key_part->part_length); + field->get_key_image(str+maybe_null,key_part->part_length, key_part->image_type); if (!(tree=new SEL_ARG(field,str,str))) DBUG_RETURN(0); @@ -1067,6 +1071,41 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, case Item_func::GE_FUNC: tree->max_flag=NO_MAX_RANGE; break; + case Item_func::SP_EQUALS_FUNC: + tree->min_flag=GEOM_FLAG | HA_READ_MBR_EQUAL;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; + case Item_func::SP_DISJOINT_FUNC: + tree->min_flag=GEOM_FLAG | HA_READ_MBR_DISJOINT;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; + case Item_func::SP_INTERSECTS_FUNC: + tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; + case Item_func::SP_TOUCHES_FUNC: + tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; + + case Item_func::SP_CROSSES_FUNC: + tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; + case Item_func::SP_WITHIN_FUNC: + tree->min_flag=GEOM_FLAG | HA_READ_MBR_WITHIN;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; + + case Item_func::SP_CONTAINS_FUNC: + tree->min_flag=GEOM_FLAG | HA_READ_MBR_CONTAIN;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; + case Item_func::SP_OVERLAPS_FUNC: + tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; + default: break; } @@ -2187,18 +2226,30 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, !memcmp(param->min_key,param->max_key,min_key_length)) tmp=1; // Max one record else + { + if(tmp_min_flag & GEOM_FLAG) + { + tmp=param->table->file-> + records_in_range((int) keynr,(byte*)(param->min_key + 1), + min_key_length, (ha_rkey_function)(tmp_min_flag ^ GEOM_FLAG), + (byte *)NullS,0,HA_READ_KEY_EXACT); + } + else + { tmp=param->table->file-> records_in_range((int) keynr, (byte*) (!min_key_length ? NullS : param->min_key), min_key_length, - (tmp_min_flag & NEAR_MIN ? - HA_READ_AFTER_KEY : HA_READ_KEY_EXACT), + tmp_min_flag & NEAR_MIN ? + HA_READ_AFTER_KEY : HA_READ_KEY_EXACT, (byte*) (!max_key_length ? NullS : param->max_key), max_key_length, (tmp_max_flag & NEAR_MAX ? HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY)); + } + } end: if (tmp == HA_POS_ERROR) // Impossible range return tmp; @@ -2294,19 +2345,24 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key, } } else - flag=key_tree->min_flag | key_tree->max_flag; + { + flag = (key_tree->min_flag & GEOM_FLAG) ? + key_tree->min_flag : key_tree->min_flag | key_tree->max_flag; + } /* Ensure that some part of min_key and max_key are used. If not, regard this as no lower/upper range */ - if (tmp_min_key != param->min_key) - flag&= ~NO_MIN_RANGE; - else - flag|= NO_MIN_RANGE; - if (tmp_max_key != param->max_key) - flag&= ~NO_MAX_RANGE; - else - flag|= NO_MAX_RANGE; - + if((flag & GEOM_FLAG) == 0) + { + if (tmp_min_key != param->min_key) + flag&= ~NO_MIN_RANGE; + else + flag|= NO_MIN_RANGE; + if (tmp_max_key != param->max_key) + flag&= ~NO_MAX_RANGE; + else + flag|= NO_MAX_RANGE; + } if (flag == 0) { uint length= (uint) (tmp_min_key - param->min_key); @@ -2439,13 +2495,19 @@ int QUICK_SELECT::get_next() int result; if (range) { // Already read through key - result=((range->flag & EQ_RANGE) ? +/* result=((range->flag & EQ_RANGE) ? file->index_next_same(record, (byte*) range->min_key, range->min_length) : file->index_next(record)); +*/ + result=((range->flag & (EQ_RANGE | GEOM_FLAG) ) ? + file->index_next_same(record, (byte*) range->min_key, + range->min_length) : + file->index_next(record)); + if (!result) { - if (!cmp_next(*it.ref())) + if ((range->flag & GEOM_FLAG) || !cmp_next(*it.ref())) DBUG_RETURN(0); } else if (result != HA_ERR_END_OF_FILE) @@ -2454,6 +2516,23 @@ int QUICK_SELECT::get_next() if (!(range=it++)) DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used + + if(range->flag & GEOM_FLAG) + { + if ((result = file->index_read(record, + (byte*) (range->min_key + ((range->flag & GEOM_FLAG) > 0)), + range->min_length, + (ha_rkey_function)(range->flag ^ GEOM_FLAG)))) + + { + if (result != HA_ERR_KEY_NOT_FOUND) + DBUG_RETURN(result); + range=0; // Not found, to next range + continue; + } + DBUG_RETURN(0); + } + if (range->flag & NO_MIN_RANGE) // Read first record { int error; @@ -2464,13 +2543,14 @@ int QUICK_SELECT::get_next() range=0; // No matching records; go to next range continue; } - if ((result = file->index_read(record,(byte*) range->min_key, + if ((result = file->index_read(record, + (byte*) (range->min_key + ((range->flag & GEOM_FLAG) > 0)), range->min_length, - ((range->flag & NEAR_MIN) ? + (range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY: (range->flag & EQ_RANGE) ? HA_READ_KEY_EXACT : - HA_READ_KEY_OR_NEXT)))) + HA_READ_KEY_OR_NEXT))) { if (result != HA_ERR_KEY_NOT_FOUND) diff --git a/sql/opt_range.h b/sql/opt_range.h index 83eb10235ea..86df6121042 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -31,11 +31,14 @@ #define UNIQUE_RANGE 16 #define EQ_RANGE 32 #define NULL_RANGE 64 +#define GEOM_FLAG 128 + typedef struct st_key_part { - uint16 key,part,part_length; - uint8 null_bit; - Field *field; + uint16 key,part,part_length; + uint8 null_bit; + Field *field; + Field::imagetype image_type; } KEY_PART; class QUICK_RANGE :public Sql_alloc { diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 78878c40b37..b7b2552ef52 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -343,7 +343,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond) // Save found constant if (part->null_bit) *key_ptr++= (byte) test(part->field->is_null()); - part->field->get_key_image((char*) key_ptr,part->length); + part->field->get_key_image((char*) key_ptr,part->length, Field::itRAW); key_ptr+=part->store_length - test(part->null_bit); left_length-=part->store_length; } diff --git a/sql/spatial.cc b/sql/spatial.cc new file mode 100644 index 00000000000..32942a70dc2 --- /dev/null +++ b/sql/spatial.cc @@ -0,0 +1,1435 @@ +#include "mysql_priv.h" + + +#define MAX_DIGITS_IN_DOUBLE 16 + +/***************************** 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 \ +}, + + +static Geometry::GClassInfo ci_collection[] = +{ + IMPLEMENT_GEOM(GPoint, wkbPoint, "POINT") + IMPLEMENT_GEOM(GLineString, wkbLineString, "LINESTRING") + IMPLEMENT_GEOM(GPolygon, wkbPolygon, "POLYGON") + IMPLEMENT_GEOM(GMultiPoint, wkbMultiPoint, "MULTIPOINT") + IMPLEMENT_GEOM(GMultiLineString, wkbMultiLineString, "MULTILINESTRING") + IMPLEMENT_GEOM(GMultiPolygon, wkbMultiPolygon, "MULTIPOLYGON") + IMPLEMENT_GEOM(GGeometryCollection, wkbGeometryCollection, "GEOMETRYCOLLECTION") +}; + +static Geometry::GClassInfo *ci_collection_end = ci_collection + sizeof(ci_collection); + +/***************************** Geometry *******************************/ + +Geometry::GClassInfo *Geometry::find_class(int type_id) +{ + for (GClassInfo *cur_rt = ci_collection; cur_rt < ci_collection_end; ++cur_rt) + { + if (cur_rt->m_type_id == type_id) + { + return cur_rt; + } + } + return NULL; +} + +Geometry::GClassInfo *Geometry::find_class(const char *name, size_t len) +{ + for (GClassInfo *cur_rt = ci_collection; + cur_rt < ci_collection_end; ++cur_rt) + { + if ((cur_rt->m_name[len] == 0) && + (strncmp(cur_rt->m_name, name, len) == 0)) + { + return cur_rt; + } + } + return NULL; +} + +int Geometry::create_from_wkb(const char *data, uint32 data_len) +{ + uint32 geom_type; + + if (data_len < 1+4) + return 1; + data += sizeof(char); + +//FIXME: check byte ordering + geom_type = uint4korr(data); + data += 4; + m_vmt = find_class(geom_type); + if (!m_vmt) return -1; + m_data = data; + m_data_end = data + data_len; + return 0; +} + +int Geometry::create_from_wkt(GTextReadStream *trs, String *wkt, int init_stream) +{ + int name_len; + const char *name = trs->get_next_word(&name_len); + if (!name) + { + trs->set_error_msg("Geometry name expected"); + return -1; + } + if (!(m_vmt = find_class(name, name_len))) + return -1; + if (wkt->reserve(1 + 4, 512)) + return 1; + wkt->q_append((char)wkbNDR); + wkt->q_append((uint32)get_class_info()->m_type_id); + if (trs->get_next_symbol() != '(') + { + trs->set_error_msg("'(' expected"); + return -1; + } + if (init_from_text(trs, wkt)) return 1; + if (trs->get_next_symbol() != ')') + { + trs->set_error_msg("')' expected"); + return -1; + } + if (init_stream) + { + init_from_wkb(wkt->ptr(), wkt->length()); + shift_wkb_header(); + } + return 0; +} + +int Geometry::envelope(String *result) const +{ + MBR mbr; + + get_mbr(&mbr); + + if (result->reserve(1+4*3+sizeof(double)*10)) + return 1; + + result->q_append((char)wkbNDR); + result->q_append((uint32)wkbPolygon); + result->q_append((uint32)1); + result->q_append((uint32)5); + result->q_append(mbr.xmin); + result->q_append(mbr.ymin); + result->q_append(mbr.xmax); + result->q_append(mbr.ymin); + result->q_append(mbr.xmax); + result->q_append(mbr.ymax); + result->q_append(mbr.xmin); + result->q_append(mbr.ymax); + result->q_append(mbr.xmin); + result->q_append(mbr.ymin); + + return 0; +} + +/***************************** Point *******************************/ + +size_t GPoint::get_data_size() const +{ + return POINT_DATA_SIZE; +} + +int GPoint::init_from_text(GTextReadStream *trs, String *wkb) +{ + double x, y; + if (wkb->reserve(sizeof(double)*2)) + return 1; + if (trs->get_next_number(&x)) + return 1; + if (trs->get_next_number(&y)) + return 1; + wkb->q_append(x); + wkb->q_append(y); + + return 0; +} + +int GPoint::get_data_as_text(String *txt) const +{ + double x, y; + if (get_xy(&x, &y)) + return 1; + if (txt->reserve(MAX_DIGITS_IN_DOUBLE * 2 + 1)) + return 1; + txt->qs_append(x); + txt->qs_append(' '); + txt->qs_append(y); + return 0; +} + +int GPoint::get_mbr(MBR *mbr) const +{ + double x, y; + if (get_xy(&x, &y)) + return 1; + mbr->add_xy(x, y); + return 0; +} + +/***************************** LineString *******************************/ + +size_t GLineString::get_data_size() const +{ + uint32 n_points = uint4korr(m_data); + + return 4 + n_points*POINT_DATA_SIZE; +} + +int GLineString::init_from_text(GTextReadStream *trs, String *wkb) +{ + uint32 n_points = 0; + int np_pos = wkb->length(); + GPoint p; + + if (wkb->reserve(4, 512)) + return 1; + + wkb->q_append((uint32)n_points); + + for (;;) + { + if (p.init_from_text(trs, wkb)) + return 1; + ++n_points; + if (trs->get_next_toc_type() == GTextReadStream::comma) + trs->get_next_symbol(); + else break; + } + + if (n_points<2) + { + trs->set_error_msg("Too few points in LINESTRING"); + return 1; + } + + wkb->WriteAtPosition(np_pos, n_points); + + return 0; +} + +int GLineString::get_data_as_text(String *txt) const +{ + uint32 n_points; + const char *data = m_data; + + if (no_data(data, 4)) + return 1; + + n_points = uint4korr(data); + data += 4; + + if (no_data(data, sizeof(double) * 2 * n_points)) + return 1; + + if (txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points)) + return 1; + for (; n_points>0; --n_points) + { + double x, y; + float8get(x, data); + data += sizeof(double); + float8get(y, data); + data += sizeof(double); + txt->qs_append(x); + txt->qs_append(' '); + txt->qs_append(y); + txt->qs_append(','); + } + txt->length(txt->length() - 1); + return 0; +} + +int GLineString::get_mbr(MBR *mbr) const +{ + uint32 n_points; + const char *data = m_data; + + if (no_data(data, 4)) + return 1; + + n_points = uint4korr(data); + data += 4; + + if (no_data(data, sizeof(double) * 2 * n_points)) + return 1; + for (; n_points>0; --n_points) + { + mbr->add_xy((double *)data, (double *)(data + 8)); + data += 8+8; + } + + return 0; +} + +int GLineString::length(double *len) const +{ + uint32 n_points; + double prev_x, prev_y; + const char *data = m_data; + + *len=0; + if (no_data(data, 4)) + return 1; + n_points = uint4korr(data); + data += 4; + + if (no_data(data, sizeof(double) * 2 * n_points)) + return 1; + + --n_points; + float8get(prev_x, data); + data += 8; + float8get(prev_y, data); + data += 8; + + for (; n_points>0; --n_points) + { + double x, y; + float8get(x, data); + data += 8; + float8get(y, data); + data += 8; + *len+=sqrt(pow(prev_x-x,2)+pow(prev_y-y,2)); + prev_x=x; + prev_y=y; + } + return 0; +} + +int GLineString::is_closed(int *closed) const + +{ + uint32 n_points; + double x1, y1, x2, y2; + + const char *data = m_data; + + if (no_data(data, 4)) + return 1; + n_points = uint4korr(data); + data += 4; + if (no_data(data, (8+8) * n_points)) + return 1; + float8get(x1, data); + data += 8; + float8get(y1, data); + data += 8 + (n_points-2)*POINT_DATA_SIZE; + float8get(x2, data); + data += 8; + float8get(y2, data); + + *closed=(x1==x2)&&(y1==y2); + + return 0; +} + +int GLineString::num_points(uint32 *n_points) const +{ + *n_points = uint4korr(m_data); + return 0; +} + +int GLineString::start_point(String *result) const +{ + const char *data = m_data + 4; + if (no_data(data, 8+8)) + return 1; + + if (result->reserve(1 + 4 + sizeof(double) * 2)) + return 1; + + result->q_append((char)wkbNDR); + result->q_append((uint32)wkbPoint); + result->q_append((double *)data); + result->q_append((double *)(data + 8)); + + return 0; +} + +int GLineString::end_point(String *result) const +{ + const char *data = m_data; + uint32 n_points; + + if (no_data(data, 4)) + return 1; + n_points = uint4korr(data); + + data += 4 + (n_points-1)*POINT_DATA_SIZE; + + if (no_data(data, 8+8)) + return 1; + + if (result->reserve(1 + 4 + sizeof(double) * 2)) + return 1; + result->q_append((char)wkbNDR); + result->q_append((uint32)wkbPoint); + result->q_append((double *)data); + result->q_append((double *)(data + 8)); + + return 0; +} + + +int GLineString::point_n(uint32 num, String *result) const +{ + const char *data = m_data; + uint32 n_points; + + if (no_data(data, 4)) + return 1; + n_points = uint4korr(data); + + if ((uint32)(num-1) >= n_points) // really means (num > n_points || num < 1) + return 1; + + data += 4 + (num - 1)*POINT_DATA_SIZE; + + if (no_data(data, 8+8)) + return 1; + if (result->reserve(1 + 4 + sizeof(double) * 2)) + return 1; + + result->q_append((char)wkbNDR); + result->q_append((uint32)wkbPoint); + result->q_append((double *)data); + result->q_append((double *)(data + 8)); + + return 0; +} + +/***************************** Polygon *******************************/ + +size_t GPolygon::get_data_size() const +{ + uint32 n_linear_rings = 0; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + + n_linear_rings = uint4korr(data); + data += 4; + for (; n_linear_rings>0; --n_linear_rings) + { + if (no_data(data, 4)) + return 1; + data += 4 + uint4korr(data)*POINT_DATA_SIZE; + } + return data - m_data; +} + +int GPolygon::init_from_text(GTextReadStream *trs, String *wkb) +{ + uint32 n_linear_rings = 0; + int lr_pos = wkb->length(); + + if (wkb->reserve(4, 512)) + return 1; + + wkb->q_append((uint32)n_linear_rings); + + for (;;) + { + GLineString ls; + size_t ls_pos=wkb->length(); + if (trs->get_next_symbol() != '(') + { + trs->set_error_msg("'(' expected"); + return 1; + } + if (ls.init_from_text(trs, wkb)) + return 1; + if (trs->get_next_symbol() != ')') + { + trs->set_error_msg("')' expected"); + return 1; + } + ls.init_from_wkb(wkb->ptr()+ls_pos, wkb->length()-ls_pos); + int closed; + ls.is_closed(&closed); + if (!closed) + { + trs->set_error_msg("POLYGON's linear ring isn't closed"); + return 1; + } + ++n_linear_rings; + if (trs->get_next_toc_type() == GTextReadStream::comma) + trs->get_next_symbol(); + else + break; + } + wkb->WriteAtPosition(lr_pos, n_linear_rings); + return 0; +} + +int GPolygon::get_data_as_text(String *txt) const +{ + uint32 n_linear_rings; + const char *data = m_data; + + if (no_data(data, 4)) + return 1; + + n_linear_rings = uint4korr(data); + data += 4; + + for (; n_linear_rings>0; --n_linear_rings) + { + if(no_data(data, 4)) + return 1; + uint32 n_points = uint4korr(data); + data += 4; + if (no_data(data, (8+8) * n_points)) + return 1; + + if (txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points)) + return 1; + txt->qs_append('('); + for (; n_points>0; --n_points) + { + txt->qs_append((double *)data); + txt->qs_append(' '); + txt->qs_append((double *)(data + 8)); + txt->qs_append(','); + + data += 8+8; + } + (*txt)[txt->length()-1] = ')'; + txt->qs_append(','); + } + txt->length(txt->length() - 1); + return 0; +} + +int GPolygon::get_mbr(MBR *mbr) const +{ + uint32 n_linear_rings; + + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_linear_rings = uint4korr(data); + data += 4; + for (; n_linear_rings>0; --n_linear_rings) + { + if (no_data(data, 4)) + return 1; + uint32 n_points = uint4korr(data); + data += 4; + if (no_data(data, (8+8) * n_points)) + return 1; + for (; n_points>0; --n_points) + { + mbr->add_xy((double *)data, (double *)(data + 8)); + data += 8+8; + } + } + return 0; +} + +int GPolygon::area(double *ar) const +{ + uint32 n_linear_rings; + double result = -1.0; + + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_linear_rings = uint4korr(data); + data += 4; + for (; n_linear_rings>0; --n_linear_rings) + { + double prev_x, prev_y; + double lr_area=0; + if (no_data(data, 4)) + return 1; + uint32 n_points = uint4korr(data); + if (no_data(data, (8+8) * n_points)) + return 1; + float8get(prev_x, data+4); + float8get(prev_y, data+(4+8)); + data += (4+8+8); + + --n_points; + for (; n_points>0; --n_points) + { + double x, y; + float8get(x, data); + float8get(y, data + 8); + lr_area+=(prev_x+x)*(prev_y-y); + prev_x=x; + prev_y=y; + data += (8+8); + } + lr_area=fabs(lr_area)/2; + if(result==-1) result=lr_area; + else result-=lr_area; + } + *ar=fabs(result); + return 0; +} + + +int GPolygon::exterior_ring(String *result) const +{ + uint32 n_points; + const char *data = m_data + 4; // skip n_linerings + + if (no_data(data, 4)) + return 1; + n_points = uint4korr(data); + data += 4; + if (no_data(data, n_points * POINT_DATA_SIZE)) + return 1; + + if (result->reserve(1+4+4+ n_points * POINT_DATA_SIZE)) + return 1; + + result->q_append((char)wkbNDR); + result->q_append((uint32)wkbLineString); + result->q_append(n_points); + result->q_append(data, n_points * POINT_DATA_SIZE); + + return 0; +} + +int GPolygon::num_interior_ring(uint32 *n_int_rings) const +{ + const char *data = m_data; + if (no_data(data, 4)) + return 1; + *n_int_rings = uint4korr(data); + --(*n_int_rings); + + return 0; +} + +int GPolygon::interior_ring_n(uint32 num, String *result) const +{ + const char *data = m_data; + uint32 n_linear_rings; + uint32 n_points; + + if (no_data(data, 4)) + return 1; + + n_linear_rings = uint4korr(data); + data += 4; + if ((num >= n_linear_rings) || (num < 1)) + return -1; + + for (; num > 0; --num) + { + if (no_data(data, 4)) + return 1; + data += 4 + uint4korr(data) * POINT_DATA_SIZE; + } + if (no_data(data, 4)) + return 1; + n_points = uint4korr(data); + int points_size = n_points * POINT_DATA_SIZE; + data += 4; + if (no_data(data, points_size)) + return 1; + + if (result->reserve(1+4+4+ points_size)) + return 1; + + result->q_append((char)wkbNDR); + result->q_append((uint32)wkbLineString); + result->q_append(n_points); + result->q_append(data, points_size); + + return 0; +} + +int GPolygon::centroid_xy(double *x, double *y) const +{ + uint32 n_linear_rings; + uint32 i; + double res_area, res_cx, res_cy; + const char *data = m_data; + + if (no_data(data, 4)) + return 1; + n_linear_rings = uint4korr(data); + data += 4; + + for(i = 0; i < n_linear_rings; ++i) + { + if (no_data(data, 4)) + return 1; + uint32 n_points = uint4korr(data); + double prev_x, prev_y; + double cur_area = 0; + double cur_cx = 0; + double cur_cy = 0; + + data += 4; + if (no_data(data, (8+8) * n_points)) + return 1; + float8get(prev_x, data); + float8get(prev_y, data+8); + data += (8+8); + + uint32 n = n_points - 1; + for (; n > 0; --n) + { + double x, y; + float8get(x, data); + float8get(y, data + 8); + + cur_area += (prev_x + x) * (prev_y - y); + cur_cx += x; + cur_cy += y; + prev_x = x; + prev_y = y; + data += (8+8); + } + cur_area = fabs(cur_area) / 2; + cur_cx = cur_cx / (n_points - 1); + cur_cy = cur_cy / (n_points - 1); + if(i) + { + double d_area = res_area - cur_area; + if (d_area <= 0) + return 1; + res_cx = (res_area * res_cx - cur_area * cur_cx) / d_area; + res_cy = (res_area * res_cy - cur_area * cur_cy) / d_area; + } + else + { + res_area = cur_area; + res_cx = cur_cx; + res_cy = cur_cy; + } + } + + *x = res_cx; + *y = res_cy; + + return 0; +} + +int GPolygon::centroid(String *result) const +{ + double x, y; + + this->centroid_xy(&x, &y); + if (result->reserve(1 + 4 + sizeof(double) * 2)) + return 1; + + result->q_append((char)wkbNDR); + result->q_append((uint32)wkbPoint); + result->q_append(x); + result->q_append(y); + + return 0; +} + + +/***************************** MultiPoint *******************************/ + +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) +{ + uint32 n_points = 0; + int np_pos = wkb->length(); + GPoint p; + + if (wkb->reserve(4, 512)) + return 1; + wkb->q_append((uint32)n_points); + + for (;;) + { + if (wkb->reserve(1+4, 512)) + return 1; + wkb->q_append((char)wkbNDR); + wkb->q_append((uint32)wkbPoint); + if (p.init_from_text(trs, wkb)) + return 1; + ++n_points; + if (trs->get_next_toc_type() == GTextReadStream::comma) + trs->get_next_symbol(); + else + break; + } + wkb->WriteAtPosition(np_pos, n_points); + + return 0; +} + +int GMultiPoint::get_data_as_text(String *txt) const +{ + uint32 n_points; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + + n_points = uint4korr(data); + data += 4; + if (no_data(data, n_points * (8+8+WKB_HEADER_SIZE))) + return 1; + + if (txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points)) + return 1; + + for (; n_points>0; --n_points) + { + txt->qs_append((double *)(data + WKB_HEADER_SIZE)); + txt->qs_append(' '); + txt->qs_append((double *)(data + (8 + WKB_HEADER_SIZE))); + txt->qs_append(','); + data += 8+8+WKB_HEADER_SIZE; + } + txt->length(txt->length()-1); + return 0; +} + +int GMultiPoint::get_mbr(MBR *mbr) const +{ + uint32 n_points; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_points = uint4korr(data); + data += 4; + if (no_data(data, n_points * (8+8+WKB_HEADER_SIZE))) + return 1; + for (; n_points>0; --n_points) + { + mbr->add_xy((double *)(data + WKB_HEADER_SIZE), + (double *)(data + 8 + WKB_HEADER_SIZE)); + data += (8+8+WKB_HEADER_SIZE); + } + return 0; +} + +/***************************** MultiLineString *******************************/ + +size_t GMultiLineString::get_data_size() const +{ + uint32 n_line_strings = 0; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_line_strings = uint4korr(data); + data += 4; + + for (; n_line_strings>0; --n_line_strings) + { + if (no_data(data, WKB_HEADER_SIZE + 4)) + return 1; + data += WKB_HEADER_SIZE + 4 + uint4korr(data + WKB_HEADER_SIZE) * POINT_DATA_SIZE; + } + return data - m_data; +} + +int GMultiLineString::init_from_text(GTextReadStream *trs, String *wkb) +{ + uint32 n_line_strings = 0; + int ls_pos = wkb->length(); + + if (wkb->reserve(4, 512)) + return 1; + + wkb->q_append((uint32)n_line_strings); + + for (;;) + { + GLineString ls; + + if (wkb->reserve(1+4, 512)) + return 1; + wkb->q_append((char)wkbNDR); + wkb->q_append((uint32)wkbLineString); + + if (trs->get_next_symbol() != '(') + { + trs->set_error_msg("'(' expected"); + return 1; + } + if (ls.init_from_text(trs, wkb)) + return 1; + + if (trs->get_next_symbol() != ')') + { + trs->set_error_msg("')' expected"); + return 1; + } + ++n_line_strings; + if (trs->get_next_toc_type() == GTextReadStream::comma) + trs->get_next_symbol(); + else + break; + } + wkb->WriteAtPosition(ls_pos, n_line_strings); + + return 0; +} + +int GMultiLineString::get_data_as_text(String *txt) const +{ + uint32 n_line_strings; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_line_strings = uint4korr(data); + data += 4; + for (; n_line_strings>0; --n_line_strings) + { + if (no_data(data, (WKB_HEADER_SIZE + 4))) + return 1; + uint32 n_points = uint4korr(data + WKB_HEADER_SIZE); + data += WKB_HEADER_SIZE + 4; + if (no_data(data, n_points * (8+8))) + return 1; + + if (txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points)) + return 1; + txt->qs_append('('); + for (; n_points>0; --n_points) + { + txt->qs_append((double *)data); + txt->qs_append(' '); + txt->qs_append((double *)(data + 8)); + txt->qs_append(','); + data += 8+8; + } + (*txt)[txt->length()-1] = ')'; + txt->qs_append(','); + } + txt->length(txt->length() - 1); + return 0; +} + +int GMultiLineString::get_mbr(MBR *mbr) const +{ + uint32 n_line_strings; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_line_strings = uint4korr(data); + data += 4; + + for (; n_line_strings>0; --n_line_strings) + { + if (no_data(data, WKB_HEADER_SIZE + 4)) + return 1; + uint32 n_points = uint4korr(data + WKB_HEADER_SIZE); + data += 4+WKB_HEADER_SIZE; + if (no_data(data, (8+8)*n_points)) + return 1; + + for (; n_points>0; --n_points) + { + mbr->add_xy((double *)data, (double *)(data + 8)); + data += 8+8; + } + } + return 0; +} + +int GMultiLineString::length(double *len) const +{ + uint32 n_line_strings; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_line_strings = uint4korr(data); + data += 4; + *len=0; + for (; n_line_strings>0; --n_line_strings) + { + double ls_len; + GLineString ls; + data += WKB_HEADER_SIZE; + ls.init_from_wkb(data, m_data_end - data); + if (ls.length(&ls_len)) + return 1; + *len+=ls_len; + data += ls.get_data_size(); + } + return 0; +} + +int GMultiLineString::is_closed(int *closed) const +{ + uint32 n_line_strings; + const char *data = m_data; + if (no_data(data, 1)) + return 1; + n_line_strings = uint4korr(data); + data += 4 + WKB_HEADER_SIZE; + for (; n_line_strings>0; --n_line_strings) + { + GLineString ls; + ls.init_from_wkb(data, m_data_end - data); + if (ls.is_closed(closed)) + return 1; + if (!*closed) + return 0; + data += ls.get_data_size() + WKB_HEADER_SIZE; + } + return 0; +} + +/***************************** MultiPolygon *******************************/ + +size_t GMultiPolygon::get_data_size() const +{ + uint32 n_polygons; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_polygons = uint4korr(data); + data += 4; + + for (; n_polygons>0; --n_polygons) + { + if (no_data(data, 4 + WKB_HEADER_SIZE)) + return 1; + uint32 n_linear_rings = uint4korr(data + WKB_HEADER_SIZE); + data += 4 + WKB_HEADER_SIZE; + + for (; n_linear_rings > 0; --n_linear_rings) + { + data += 4 + uint4korr(data) * POINT_DATA_SIZE; + } + } + return data - m_data; +} + +int GMultiPolygon::init_from_text(GTextReadStream *trs, String *wkb) +{ + uint32 n_polygons = 0; + int np_pos = wkb->length(); + GPolygon p; + + if (wkb->reserve(4, 512)) + return 1; + + wkb->q_append((uint32)n_polygons); + + for (;;) + { + if (wkb->reserve(1+4, 512)) + return 1; + wkb->q_append((char)wkbNDR); + wkb->q_append((uint32)wkbPolygon); + + if (trs->get_next_symbol() != '(') + { + trs->set_error_msg("'(' expected"); + return 1; + } + if (p.init_from_text(trs, wkb)) + return 1; + if (trs->get_next_symbol() != ')') + { + trs->set_error_msg("')' expected"); + return 1; + } + ++n_polygons; + if (trs->get_next_toc_type() == GTextReadStream::comma) + trs->get_next_symbol(); + else + break; + } + wkb->WriteAtPosition(np_pos, n_polygons); + return 0; +} + +int GMultiPolygon::get_data_as_text(String *txt) const +{ + uint32 n_polygons; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_polygons = uint4korr(data); + data += 4; + + for (; n_polygons>0; --n_polygons) + { + if (no_data(data, 4 + WKB_HEADER_SIZE)) + return 1; + data += WKB_HEADER_SIZE; + uint32 n_linear_rings = uint4korr(data); + data += 4; + + if (txt->reserve(1, 512)) + return 1; + txt->q_append('('); + for (; n_linear_rings>0; --n_linear_rings) + { + if (no_data(data, 4)) + return 1; + uint32 n_points = uint4korr(data); + data += 4; + if (no_data(data, (8+8)*n_points)) return 1; + + if (txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points, + 512)) return 1; + txt->qs_append('('); + for (; n_points>0; --n_points) + { + txt->qs_append((double *)data); + txt->qs_append(' '); + txt->qs_append((double *)(data + 8)); + txt->qs_append(','); + data += 8+8; + } + (*txt)[txt->length()-1] = ')'; + txt->qs_append(','); + } + (*txt)[txt->length()-1] = ')'; + txt->qs_append(','); + } + txt->length(txt->length() - 1); + return 0; +} + +int GMultiPolygon::get_mbr(MBR *mbr) const +{ + uint32 n_polygons; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_polygons = uint4korr(data); + data += 4; + + for (; n_polygons>0; --n_polygons) + { + if (no_data(data, 4+WKB_HEADER_SIZE)) + return 1; + uint32 n_linear_rings = uint4korr(data + WKB_HEADER_SIZE); + data += WKB_HEADER_SIZE + 4; + + for (; n_linear_rings>0; --n_linear_rings) + { + if (no_data(data, 4)) + return 1; + uint32 n_points = uint4korr(data); + data += 4; + if (no_data(data, (8+8)*n_points)) + return 1; + + for (; n_points>0; --n_points) + { + mbr->add_xy((double *)data, (double *)(data + 8)); + data += 8+8; + } + } + } + return 0; +} + + +int GMultiPolygon::area(double *ar) const +{ + uint32 n_polygons; + const char *data = m_data; + double result = 0; + if (no_data(data, 4)) + return 1; + n_polygons = uint4korr(data); + data += 4; + + for (; n_polygons>0; --n_polygons) + { + double p_area; + + GPolygon p; + data += WKB_HEADER_SIZE; + p.init_from_wkb(data, m_data_end - data); + if (p.area(&p_area)) + return 1; + result += p_area; + data += p.get_data_size(); + } + *ar = result; + return 0; +} + +int GMultiPolygon::centroid(String *result) const +{ + uint32 n_polygons; + uint i; + GPolygon p; + double res_area, res_cx, res_cy; + double cur_area, cur_cx, cur_cy; + + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_polygons = uint4korr(data); + data += 4; + + for (i = 0; i < n_polygons; ++i) + { + data += WKB_HEADER_SIZE; + p.init_from_wkb(data, m_data_end - data); + if (p.area(&cur_area)) + return 1; + + if (p.centroid_xy(&cur_cx, &cur_cy)) + return 1; + + if(i) + { + double sum_area = res_area + cur_area; + res_cx = (res_area * res_cx + cur_area * cur_cx) / sum_area; + res_cy = (res_area * res_cy + cur_area * cur_cy) / sum_area; + } + else + { + res_area = cur_area; + res_cx = cur_cx; + res_cy = cur_cy; + } + + data += p.get_data_size(); + } + + if (result->reserve(1 + 4 + sizeof(double) * 2)) + return 1; + result->q_append((char)wkbNDR); + result->q_append((uint32)wkbPoint); + result->q_append(res_cx); + result->q_append(res_cy); + + return 0; +} + +/***************************** GeometryCollection *******************************/ + +size_t GGeometryCollection::get_data_size() const +{ + uint32 n_objects; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_objects = uint4korr(data); + data += 4; + + for (; n_objects>0; --n_objects) + { + if (no_data(data, WKB_HEADER_SIZE)) + return 1; + uint32 wkb_type = uint4korr(data + sizeof(char)); + data += WKB_HEADER_SIZE; + + Geometry geom; + + if (geom.init(wkb_type)) + return 0; + + geom.init_from_wkb(data, m_data_end - data); + size_t object_size=geom.get_data_size(); + data += object_size; + } + return data - m_data; +} + +int GGeometryCollection::init_from_text(GTextReadStream *trs, String *wkb) +{ + uint32 n_objects = 0; + int no_pos = wkb->length(); + Geometry g; + + if (wkb->reserve(4, 512)) + return 1; + wkb->q_append((uint32)n_objects); + + for (;;) + { + if (g.create_from_wkt(trs, wkb)) + return 1; + + if (g.get_class_info()->m_type_id==wkbGeometryCollection) + { + trs->set_error_msg("Unexpected GEOMETRYCOLLECTION"); + return 1; + } + ++n_objects; + if (trs->get_next_toc_type() == GTextReadStream::comma) + trs->get_next_symbol(); + else break; + } + wkb->WriteAtPosition(no_pos, n_objects); + + return 0; +} + +int GGeometryCollection::get_data_as_text(String *txt) const +{ + uint32 n_objects; + const char *data = m_data; + Geometry geom; + if (no_data(data, 4)) + return 1; + n_objects = uint4korr(data); + data += 4; + + for (; n_objects>0; --n_objects) + { + if (no_data(data, WKB_HEADER_SIZE)) + return 1; + uint32 wkb_type = uint4korr(data + sizeof(char)); + data += WKB_HEADER_SIZE; + + if (geom.init(wkb_type)) + return 1; + geom.init_from_wkb(data, m_data_end - data); + if (geom.as_wkt(txt)) + return 1; + data += geom.get_data_size(); + txt->reserve(1, 512); + txt->q_append(','); + } + txt->length(txt->length() - 1); + return 0; +} + +int GGeometryCollection::get_mbr(MBR *mbr) const +{ + uint32 n_objects; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_objects = uint4korr(data); + data += 4; + for (; n_objects>0; --n_objects) + { + if(no_data(data, WKB_HEADER_SIZE)) + return 1; + uint32 wkb_type = uint4korr(data + sizeof(char)); + data += WKB_HEADER_SIZE; + Geometry geom; + + if (geom.init(wkb_type)) + return 1; + geom.init_from_wkb(data, m_data_end - data); + geom.get_mbr(mbr); + data += geom.get_data_size(); + } + return 0; +} + +int GGeometryCollection::num_geometries(uint32 *num) const +{ + *num = uint4korr(m_data); + return 0; +} + +int GGeometryCollection::geometry_n(uint32 num, String *result) const +{ + const char *data = m_data; + uint32 n_objects; + if (no_data(data, 4)) + return 1; + n_objects = uint4korr(data); + data += 4; + + if ((num > n_objects) || (num < 1)) + { + return -1; + } + for (; num > 0; --num) + { + if (no_data(data, WKB_HEADER_SIZE)) + return 1; + uint32 wkb_type = uint4korr(data + sizeof(char)); + data += WKB_HEADER_SIZE; + + Geometry geom; + if (geom.init(wkb_type)) + return 1; + geom.init_from_wkb(data, m_data_end - data); + if (num == 1) + { + if (result->reserve(1+4+geom.get_data_size())) + return 1; + result->q_append((char)wkbNDR); + result->q_append((uint32)wkb_type); + result->q_append(data, geom.get_data_size()); + break; + } + else + { + data += geom.get_data_size(); + } + } + return 0; +} + +int GGeometryCollection::dimension(uint32 *dim) const +{ + uint32 n_objects; + *dim = 0; + const char *data = m_data; + if (no_data(data, 4)) + return 1; + n_objects = uint4korr(data); + data += 4; + + for (; n_objects > 0; --n_objects) + { + if (no_data(data, WKB_HEADER_SIZE)) + return 1; + uint32 wkb_type = uint4korr(data + sizeof(char)); + data += WKB_HEADER_SIZE; + + uint32 d; + + Geometry geom; + if (geom.init(wkb_type)) + return 1; + geom.init_from_wkb(data, m_data_end - data); + if (geom.dimension(&d)) + return 1; + + if (d > *dim) + *dim = d; + data += geom.get_data_size(); + } + return 0; +} + +/***************************** /objects *******************************/ diff --git a/sql/spatial.h b/sql/spatial.h new file mode 100644 index 00000000000..09e8722a85e --- /dev/null +++ b/sql/spatial.h @@ -0,0 +1,476 @@ +#ifndef _spatial_h +#define _spatial_h + +#include "gstream.h" + +const int POINT_DATA_SIZE = 8+8; +const int WKB_HEADER_SIZE = 1+4; + +struct stPoint2D +{ + double x; + double y; +}; + +struct stLinearRing +{ + size_t n_points; + stPoint2D points; +}; + +/***************************** MBR *******************************/ + +struct MBR +{ + MBR() + { + xmin=DBL_MAX; + ymin=DBL_MAX; + xmax=-DBL_MAX; + ymax=-DBL_MAX; + } + + MBR(const double &_xmin, const double &_ymin, const double &_xmax, const double &_ymax) + { + xmin=_xmin; + ymin=_ymin; + xmax=_xmax; + ymax=_ymax; + } + + MBR(const stPoint2D &min, const stPoint2D &max) + { + xmin=min.x; + ymin=min.y; + xmax=max.x; + ymax=max.y; + } + + double xmin; + double ymin; + double xmax; + double ymax; + + void add_xy(double x, double y) + { /* Not using "else" for proper one point MBR calculation */ + if (xxmax) + { + xmax=x; + } + if (yymax) + { + ymax=y; + } + } + + void add_xy(double *px, double *py) + { /* Not using "else" for proper one point MBR calculation */ + double x, y; + float8get(x, px); + float8get(y, py); + if (xxmax) + { + xmax=x; + } + if (yymax) + { + ymax=y; + } + } + + void add_mbr(const MBR *mbr) + { + if (mbr->xminxmin; + } + if (mbr->xmax>xmax) + { + xmax=mbr->xmax; + } + if (mbr->yminymin; + } + if (mbr->ymax>ymax) + { + ymax=mbr->ymax; + } + } + + int equals(const MBR *mbr) + { + return (mbr->xmin==xmin)&&(mbr->ymin==ymin)&&(mbr->xmax==xmax)&&(mbr->ymax==ymax); + } + + int disjoint(const MBR *mbr) + { + return (mbr->xmin>xmax)||(mbr->ymin>ymax)||(mbr->xmaxymaxxmin==xmax) || (mbr->xmax==xmin)) && + ((mbr->ymin>=ymin) && (mbr->ymin<=ymax) || + (mbr->ymax>=ymin) && (mbr->ymax<=ymax))) || + (((mbr->ymin==ymax) || (mbr->ymax==ymin)) && + ((mbr->xmin>=xmin) && (mbr->xmin<=xmax) || + (mbr->xmax>=xmin)&&(mbr->xmax<=xmax))); + } + + int within(const MBR *mbr) + { + return (mbr->xmin<=xmin) && (mbr->ymin<=ymin) && + (mbr->xmax>=xmax) && (mbr->ymax>=ymax); + } + + int contains(const MBR *mbr) + { + return (mbr->xmin>=xmin) && (mbr->ymin>=ymin) && + (mbr->xmax<=xmax) && (mbr->ymax<=ymax); + } + + bool inner_point(double x, double y) const + { + return (xminx) && (yminx); + } + + int overlaps(const MBR *mbr) + { + int lb = mbr->inner_point(xmin, ymin); + int rb = mbr->inner_point(xmax, ymin); + int rt = mbr->inner_point(xmax, ymax); + int lt = mbr->inner_point(xmin, ymax); + + int a = lb+rb+rt+lt; + return (a>0) && (a<4) && (!within(mbr)); + } +}; + + +/***************************** Geometry *******************************/ + +class Geometry; + +typedef int (Geometry::*GF_InitFromText)(GTextReadStream *, String *); +typedef int (Geometry::*GF_GetDataAsText)(String *) const; +typedef size_t (Geometry::*GF_GetDataSize)() const; +typedef int (Geometry::*GF_GetMBR)(MBR *) const; + +typedef int (Geometry::*GF_GetD)(double *) const; +typedef int (Geometry::*GF_GetI)(int *) const; +typedef int (Geometry::*GF_GetUI)(uint32 *) const; +typedef int (Geometry::*GF_GetWS)(String *) const; +typedef int (Geometry::*GF_GetUIWS)(uint32, String *) const; + +#define GEOM_METHOD_PRESENT(geom_obj, method)\ + (geom_obj.m_vmt->method != &Geometry::method) + +class Geometry +{ +public: + enum wkbType + { + wkbPoint = 1, + wkbLineString = 2, + wkbPolygon = 3, + wkbMultiPoint = 4, + wkbMultiLineString = 5, + wkbMultiPolygon = 6, + wkbGeometryCollection = 7 + }; + enum wkbByteOrder + { + wkbXDR = 0, /* Big Endian */ + wkbNDR = 1 /* Little Endian */ + }; + + + class GClassInfo + { + public: + GF_InitFromText init_from_text; + GF_GetDataAsText get_data_as_text; + GF_GetDataSize get_data_size; + GF_GetMBR get_mbr; + GF_GetD get_x; + GF_GetD get_y; + GF_GetD length; + GF_GetD area; + + GF_GetI is_closed; + + GF_GetUI num_interior_ring; + GF_GetUI num_points; + GF_GetUI num_geometries; + GF_GetUI dimension; + + GF_GetWS start_point; + GF_GetWS end_point; + GF_GetWS exterior_ring; + GF_GetWS centroid; + + GF_GetUIWS point_n; + GF_GetUIWS interior_ring_n; + GF_GetUIWS geometry_n; + + int m_type_id; + const char *m_name; + GClassInfo *m_next_rt; + }; + GClassInfo *m_vmt; + + 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 get_data_as_text(String *txt) const + { return (this->*m_vmt->get_data_as_text)(txt); } + + int get_mbr(MBR *mbr) const { return (this->*m_vmt->get_mbr)(mbr); } + int dimension(uint32 *dim) const + { return (this->*m_vmt->dimension)(dim); } + + int get_x(double *x) const { return (this->*m_vmt->get_x)(x); } + int get_y(double *y) const { return (this->*m_vmt->get_y)(y); } + int length(double *len) const { return (this->*m_vmt->length)(len); } + int area(double *ar) const { return (this->*m_vmt->area)(ar); } + + int is_closed(int *closed) const { return (this->*m_vmt->is_closed)(closed); } + + int num_interior_ring(uint32 *n_int_rings) const + { return (this->*m_vmt->num_interior_ring)(n_int_rings); } + int num_points(uint32 *n_points) const + { return (this->*m_vmt->num_points)(n_points); } + + int num_geometries(uint32 *num) const + { return (this->*m_vmt->num_geometries)(num); } + + int start_point(String *point) const + { return (this->*m_vmt->start_point)(point); } + int end_point(String *point) const + { return (this->*m_vmt->end_point)(point); } + int exterior_ring(String *ring) const + { return (this->*m_vmt->exterior_ring)(ring); } + int centroid(String *point) const + { return (this->*m_vmt->centroid)(point); } + + int point_n(uint32 num, String *result) const + { return (this->*m_vmt->point_n)(num, result); } + int interior_ring_n(uint32 num, String *result) const + { return (this->*m_vmt->interior_ring_n)(num, result); } + int geometry_n(uint32 num, String *result) const + { return (this->*m_vmt->geometry_n)(num, result); } + +public: + int create_from_wkb(const char *data, uint32 data_len); + int create_from_wkt(GTextReadStream *trs, String *wkt, int init_stream=1); + int init(int type_id) + { + m_vmt = find_class(type_id); + return !m_vmt; + } + int new_geometry(const char *name, size_t len) + { + m_vmt = find_class(name, len); + return !m_vmt; + } + + int as_wkt(String *wkt) const + { + if(wkt->reserve(strlen(get_class_info()->m_name) + 2, 512)) + return 1; + wkt->qs_append(get_class_info()->m_name); + wkt->qs_append('('); + if(get_data_as_text(wkt)) + return 1; + wkt->qs_append(')'); + return 0; + } + + void init_from_wkb(const char *data, uint32 data_len) + { + m_data = data; + m_data_end = data + data_len; + } + + void shift_wkb_header() + { + m_data += WKB_HEADER_SIZE; + } + + int envelope(String *result) const; + +protected: + static GClassInfo *find_class(int type_id); + static GClassInfo *find_class(const char *name, size_t len); + + bool no_data(const char *cur_data, uint32 data_amount) const + { + return cur_data + data_amount > m_data_end; + } + + const char *m_data; + const char *m_data_end; +}; + +/***************************** Point *******************************/ + +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 get_mbr(MBR *mbr) const; + + int get_xy(double *x, double *y) const + { + const char *data = m_data; + if(no_data(data, sizeof(double)) * 2) return 1; + float8get(*x, data); + float8get(*y, data + sizeof(double)); + return 0; + } + + int get_x(double *x) const + { + if(no_data(m_data, sizeof(double))) return 1; + float8get(*x, m_data); + return 0; + } + + int get_y(double *y) const + { + const char *data = m_data; + if(no_data(data, sizeof(double)) * 2) return 1; + float8get(*y, data + sizeof(double)); + return 0; + } + + int dimension(uint32 *dim) const { *dim = 0; return 0; } +}; + +/***************************** LineString *******************************/ + +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 get_mbr(MBR *mbr) const; + + int length(double *len) const; + int is_closed(int *closed) const; + int num_points(uint32 *n_points) const; + int start_point(String *point) const; + int end_point(String *point) const; + int point_n(uint32 n, String *result) const; + int dimension(uint32 *dim) const { *dim = 1; return 0; } +// IsRing +}; + +/***************************** Polygon *******************************/ + +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 get_mbr(MBR *mbr) const; + + int area(double *ar) const; + int exterior_ring(String *result) const; + int num_interior_ring(uint32 *n_int_rings) const; + int interior_ring_n(uint32 num, String *result) const; + int centroid_xy(double *x, double *y) const; + int centroid(String *result) const; + int dimension(uint32 *dim) const { *dim = 2; return 0; } +// PointOnSurface +}; + +/***************************** MultiPoint *******************************/ + +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 get_mbr(MBR *mbr) const; + int dimension(uint32 *dim) const { *dim = 0; return 0; } +}; + +/***************************** MultiLineString *******************************/ + +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 get_mbr(MBR *mbr) const; + + int length(double *len) const; + int is_closed(int *closed) const; + int dimension(uint32 *dim) const { *dim = 1; return 0; } +}; + +/***************************** MultiPolygon *******************************/ + +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 get_mbr(MBR *mbr) const; + + int area(double *ar) const; + int centroid(String *result) const; + int dimension(uint32 *dim) const { *dim = 2; return 0; } +// PointOnSurface +}; + +/***************************** GeometryCollection *******************************/ + +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 get_mbr(MBR *mbr) const; + + int num_geometries(uint32 *num) const; + int geometry_n(uint32 num, String *result) const; + + int dimension(uint32 *dim) const; +}; + +#endif diff --git a/sql/sql_class.h b/sql/sql_class.h index a1423cfcdf1..355987c259e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -198,13 +198,18 @@ public: class Key :public Sql_alloc { public: - enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT }; + enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL }; enum Keytype type; + enum ha_key_alg alg; // +BAR List columns; const char *Name; Key(enum Keytype type_par,const char *name_arg,List &cols) :type(type_par), columns(cols),Name(name_arg) {} + + Key(enum Keytype type_par, enum ha_key_alg alg_par, const char *name_arg,List &cols) + :type(type_par),alg(alg_par), columns(cols),Name(name_arg){} //+BAR + ~Key() {} const char *name() { return Name; } }; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 131266a11d6..52541ffe50f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -880,11 +880,17 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append("UNIQUE ", 7); else if (key_info->flags & HA_FULLTEXT) packet->append("FULLTEXT ", 9); + else if (key_info->flags & HA_SPATIAL) + packet->append("SPATIAL ", 8); packet->append("KEY ", 4); if (!found_primary) append_identifier(thd,packet,key_info->name); + // +BAR: send USING only in non-default case: non-spatial rtree + if((key_info->key_alg == HA_KEY_ALG_RTREE) && !(key_info->flags & HA_SPATIAL)) + packet->append(" USING RTREE",12); + packet->append(" (", 2); for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 8fe84947ac2..f0cfd590072 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -459,6 +459,44 @@ bool String::replace(uint32 offset,uint32 arg_length,const String &to) return FALSE; } +// added by Holyfoot for "geometry" needs +int String::reserve(uint32 space_needed, uint32 grow_by) +{ + if (Alloced_length < str_length + space_needed) + { + if (realloc(Alloced_length + max(space_needed, grow_by) - 1)) + return TRUE; + } + return FALSE; +} + +void String::qs_append(const char *str) +{ + int len = strlen(str); + memcpy(Ptr + str_length, str, len + 1); + str_length += len; +} + +void String::qs_append(double d) +{ + char *buff = Ptr + str_length; + sprintf(buff,"%.14g", d); + str_length += strlen(buff); +} + +void String::qs_append(double *d) +{ + double ld; + float8get(ld, d); + qs_append(ld); +} + +void String::qs_append(const char &c) +{ + Ptr[str_length] = c; + str_length += sizeof(c); +} + int sortcmp(const String *x,const String *y) { @@ -805,3 +843,5 @@ int wild_compare(String &match,String &wild, char escape) DBUG_RETURN(wild_compare(match.ptr(),match.ptr()+match.length(), wild.ptr(), wild.ptr()+wild.length(),escape)); } + + diff --git a/sql/sql_string.h b/sql/sql_string.h index ad7455ecbf1..ac579cd752d 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -188,4 +188,49 @@ public: friend int wild_compare(String &match,String &wild,char escape); uint32 numchars(); int charpos(int i,uint32 offset=0); + +// added by Holyfoot for "geometry" needs + int reserve(uint32 space_needed) + { + return realloc(str_length + space_needed); + } + int reserve(uint32 space_needed, uint32 grow_by); + +// these append operations do NOT check alloced memory +// q_*** methods writes values of parameters itself +// qs_*** methods writes string representation of value + void q_append(const char &c) + { + Ptr[str_length++] = c; + } + void q_append(const uint32 &n) + { + int4store(Ptr + str_length, n); + str_length += 4; + } + void q_append(double d) + { + float8store(Ptr + str_length, d); + str_length += 8; + } + void q_append(double *d) + { + float8store(Ptr + str_length, *d); + str_length += 8; + } + void q_append(const char *data, uint32 data_len) + { + memcpy(Ptr + str_length, data, data_len); + str_length += data_len; + } + + void WriteAtPosition(int position, uint32 value) + { + int4store(Ptr + position,value); + } + + void qs_append(const char *str); + void qs_append(double d); + void qs_append(double *d); + void qs_append(const char &c); }; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0335c6f49cf..fa1879b33ff 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -438,8 +438,21 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, uint key_length=0; key_part_spec *column; - key_info->flags= (key->type == Key::MULTIPLE) ? 0 : - (key->type == Key::FULLTEXT) ? HA_FULLTEXT : HA_NOSAME; + switch(key->type){ + case Key::MULTIPLE: + key_info->flags = 0; + break; + case Key::FULLTEXT: + key_info->flags = HA_FULLTEXT; + break; + case Key::SPATIAL: + key_info->flags = HA_SPATIAL; + break; + default: + key_info->flags = HA_NOSAME; + } + + key_info->key_alg = key->alg; key_info->key_parts=(uint8) key->columns.elements; key_info->key_part=key_part_info; key_info->usable_key_parts= key_number; @@ -452,7 +465,31 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } } - + /* + Make SPATIAL to be RTREE by default + SPATIAL only on BLOB or at least BINARY, this + actually should be replaced by special GEOM type + in near future when new frm file is ready + checking for proper key parts number: + */ + + if(key_info->flags == HA_SPATIAL){ + if(key_info->key_parts!=1){ + my_printf_error(ER_WRONG_ARGUMENTS, + ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX"); + DBUG_RETURN(-1); + } + }else + { + if(key_info->key_alg == HA_KEY_ALG_RTREE){ + if((key_info->key_parts&1)==1){ + my_printf_error(ER_WRONG_ARGUMENTS, + ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); + DBUG_RETURN(-1); + } + } + } + List_iterator cols(key->columns); for (uint column_nr=0 ; (column=cols++) ; column_nr++) { @@ -480,6 +517,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { if (key->type == Key::FULLTEXT) column->length=1; /* ft-code ignores it anyway :-) */ + else if (key->type == Key::SPATIAL) + { + /* + BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case + Lately we'll extend this code to support more dimensions + */ + column->length=4*sizeof(double); + } else { my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, @@ -1471,11 +1516,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, key_part_length)); } if (key_parts.elements) - key_list.push_back(new Key(key_info->flags & HA_NOSAME ? + key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL : + (key_info->flags & HA_NOSAME ? (!my_strcasecmp(key_name, "PRIMARY") ? Key::PRIMARY : Key::UNIQUE) : (key_info->flags & HA_FULLTEXT ? - Key::FULLTEXT : Key::MULTIPLE), + Key::FULLTEXT : Key::MULTIPLE)), + key_info->key_alg, key_name,key_parts)); } key_it.rewind(); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 742c39ce901..62b1e1841ff 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -54,6 +54,7 @@ inline Item *or_or_concat(Item* A, Item* B) List *item_list; List *string_list; Key::Keytype key_type; + enum ha_key_alg key_alg; enum db_type db_type; enum row_type row_type; enum ha_rkey_function ha_rkey_mode; @@ -154,6 +155,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token BOOL_SYM %token BOOLEAN_SYM %token BOTH +%token BTREE_SYM %token BY %token CACHE_SYM %token CASCADE @@ -200,6 +202,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token GREATEST_SYM %token GROUP %token HAVING +%token HASH_SYM %token HEAP_SYM %token HEX_NUM %token HIGH_PRIORITY @@ -291,10 +294,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ROWS_SYM %token ROW_FORMAT_SYM %token ROW_SYM +%token RTREE_SYM %token SET %token SERIALIZABLE_SYM %token SESSION_SYM %token SHUTDOWN +%token SPATIAL_SYM %token SQL_CACHE_SYM %token SQL_NO_CACHE_SYM %token SSL_SYM @@ -344,6 +349,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ENUM %token FAST_SYM %token FLOAT_SYM +%token GEOM_SYM %token INT_SYM %token LIMIT %token LONGBLOB @@ -401,6 +407,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token FORMAT_SYM %token FOR_SYM %token FROM_UNIXTIME +%token GEOMETRYCOLLECTION %token GROUP_UNIQUE_USERS %token HOUR_MINUTE_SYM %token HOUR_SECOND_SYM @@ -412,6 +419,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token INTERVAL_SYM %token LAST_INSERT_ID %token LEFT +%token LINESTRING %token LOCATE %token MAKE_SET_SYM %token MINUTE_SECOND_SYM @@ -419,8 +427,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token MODE_SYM %token MODIFY_SYM %token MONTH_SYM +%token MULTILINESTRING +%token MULTIPOINT +%token MULTIPOLYGON %token NOW_SYM %token PASSWORD +%token POLYGON %token POSITION_SYM %token PROCEDURE %token RAND @@ -527,6 +539,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type key_type opt_unique_or_fulltext +%type + key_alg opt_btree_or_rtree + %type key_usage_list @@ -713,21 +728,22 @@ create: } create2 - | CREATE opt_unique_or_fulltext INDEX ident ON table_ident + | CREATE opt_unique_or_fulltext INDEX ident key_alg ON table_ident { LEX *lex=Lex; lex->sql_command= SQLCOM_CREATE_INDEX; - if (!add_table_to_list($6,NULL,1)) + if (!add_table_to_list($7,NULL,1)) YYABORT; lex->create_list.empty(); lex->key_list.empty(); lex->col_list.empty(); lex->change=NullS; } - '(' key_list ')' + '(' key_list ')' { LEX *lex=Lex; - lex->key_list.push_back(new Key($2,$4.str,lex->col_list)); + + lex->key_list.push_back(new Key($2,$5,$4.str,lex->col_list)); lex->col_list.empty(); } | CREATE DATABASE opt_if_not_exists ident @@ -874,10 +890,10 @@ field_list_item: { Lex->col_list.empty(); /* Alloced by sql_alloc */ } - | key_type opt_ident '(' key_list ')' + | key_type opt_ident key_alg '(' key_list ')' { LEX *lex=Lex; - lex->key_list.push_back(new Key($1,$2,lex->col_list)); + lex->key_list.push_back(new Key($1,$3,$2,lex->col_list)); lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references @@ -942,6 +958,8 @@ type: $$=FIELD_TYPE_TINY_BLOB; } | BLOB_SYM { Lex->type|=BINARY_FLAG; $$=FIELD_TYPE_BLOB; } + | GEOM_SYM { Lex->type|=BINARY_FLAG; + $$=FIELD_TYPE_GEOMETRY; } | MEDIUMBLOB { Lex->type|=BINARY_FLAG; $$=FIELD_TYPE_MEDIUM_BLOB; } | LONGBLOB { Lex->type|=BINARY_FLAG; @@ -1083,6 +1101,8 @@ key_type: | key_or_index { $$= Key::MULTIPLE; } | FULLTEXT_SYM { $$= Key::FULLTEXT; } | FULLTEXT_SYM key_or_index { $$= Key::FULLTEXT; } + | SPATIAL_SYM { $$= Key::SPATIAL; } + | SPATIAL_SYM key_or_index { $$= Key::SPATIAL; } | opt_constraint UNIQUE_SYM { $$= Key::UNIQUE; } | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; } @@ -1099,6 +1119,16 @@ opt_unique_or_fulltext: /* empty */ { $$= Key::MULTIPLE; } | UNIQUE_SYM { $$= Key::UNIQUE; } | FULLTEXT_SYM { $$= Key::FULLTEXT; } + | SPATIAL_SYM { $$= Key::SPATIAL; } + +key_alg: + /* empty */ { $$= HA_KEY_ALG_BTREE; } + | USING opt_btree_or_rtree { $$= $2 } + +opt_btree_or_rtree: + BTREE_SYM { $$= HA_KEY_ALG_BTREE; } + | RTREE_SYM { $$= HA_KEY_ALG_RTREE; } + | HASH_SYM { $$= HA_KEY_ALG_HASH; } key_list: key_list ',' key_part order_dir { Lex->col_list.push_back($3); } @@ -1684,6 +1714,10 @@ simple_expr: } | FIELD_FUNC '(' expr ',' expr_list ')' { $$= new Item_func_field($3, *$5); } + | GEOMETRYCOLLECTION '(' expr_list ')' + { $$= new Item_func_spatial_collection(* $3, + Geometry::wkbGeometryCollection, + Geometry::wkbPoint); } | HOUR_SYM '(' expr ')' { $$= new Item_func_hour($3); } | IF '(' expr ',' expr ',' expr ')' @@ -1708,6 +1742,9 @@ simple_expr: } | LEFT '(' expr ',' expr ')' { $$= new Item_func_left($3,$5); } + | LINESTRING '(' expr_list ')' + { $$= new Item_func_spatial_collection(* $3, + Geometry::wkbLineString, Geometry::wkbPoint); } | LOCATE '(' expr ',' expr ')' { $$= new Item_func_locate($5,$3); } | LOCATE '(' expr ',' expr ',' expr ')' @@ -1720,6 +1757,15 @@ simple_expr: { $$= new Item_func_minute($3); } | MONTH_SYM '(' expr ')' { $$= new Item_func_month($3); } + | MULTILINESTRING '(' expr_list ')' + { $$= new Item_func_spatial_collection(* $3, + Geometry::wkbMultiLineString, Geometry::wkbLineString); } + | MULTIPOINT '(' expr_list ')' + { $$= new Item_func_spatial_collection(* $3, + Geometry::wkbMultiPoint, Geometry::wkbPoint); } + | MULTIPOLYGON '(' expr_list ')' + { $$= new Item_func_spatial_collection(* $3, + Geometry::wkbMultiPolygon, Geometry::wkbPolygon ); } | NOW_SYM optional_braces { $$= new Item_func_now(); current_thd->safe_to_cache_query=0;} | NOW_SYM '(' expr ')' @@ -1728,6 +1774,9 @@ simple_expr: { $$= new Item_func_password($3); } + | POLYGON '(' expr_list ')' + { $$= new Item_func_spatial_collection(* $3, + Geometry::wkbPolygon, Geometry::wkbLineString); } | POSITION_SYM '(' no_in_expr IN_SYM expr ')' { $$ = new Item_func_locate($5,$3); } | RAND '(' expr ')' diff --git a/sql/structs.h b/sql/structs.h index 9e577128c8d..3ee4680f4a4 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -64,6 +64,7 @@ typedef struct st_key_part_info { /* Info about a key part */ typedef struct st_key { uint key_length; /* Tot length of key */ uint flags; /* dupp key and pack flags */ + enum ha_key_alg key_alg; /* +BAR Algorithm BTREE or RTREE */ uint key_parts; /* How many key_parts */ uint extra_length; uint usable_key_parts; /* Should normally be = key_parts */ diff --git a/sql/table.cc b/sql/table.cc index 9aae9e17e5a..9e6283d6ad4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -153,7 +153,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, { keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME; keyinfo->key_length= (uint) uint2korr(strpos+1); - keyinfo->key_parts= (uint) strpos[3]; strpos+=4; + keyinfo->key_parts= (uint) strpos[3]; + strpos+=4; + keyinfo->key_part= key_part; keyinfo->rec_per_key= rec_per_key; for (j=keyinfo->key_parts ; j-- ; key_part++) @@ -395,6 +397,26 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, } } + keyinfo->key_alg=HA_KEY_ALG_BTREE; // BAR : btree by default + +#define BAR_DIRTY_HACK +#ifdef BAR_DIRTY_HACK + // BAR FIXME: Dirty hack while waiting for new .frm format + switch(keyinfo->name[0]){ + case 'R': + keyinfo->key_alg=HA_KEY_ALG_RTREE; + break; + case 'S': + keyinfo->key_alg = HA_KEY_ALG_RTREE; + keyinfo->flags |= HA_SPATIAL; + break; + case 'B': + default: + keyinfo->key_alg=HA_KEY_ALG_BTREE; + break; + } +#endif + for (i=0 ; i < keyinfo->key_parts ; key_part++,i++) { if (new_field_pack_flag <= 1) -- cgit v1.2.1 From b9aebaa0aced6e22a84b86dd02481b4a4f56a32e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 23 Feb 2002 14:18:41 +0200 Subject: Small addition to SHOW GRANTS --- sql/sql_acl.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 577084a650a..c5782f65798 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2687,6 +2687,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) #endif /* HAVE_OPENSSL */ if (want_access & GRANT_ACL) global.append(" WITH GRANT OPTION",18); + else if (acl_user->questions) + { + char buff[65], *p; // just as in int2str + global.append(" WITH MAX_QUERIES_PER_HOUR = ",29); + p=int2str(acl_user->questions,buff,10); + global.append(buff,p-buff); + } thd->packet.length(0); net_store_data(&thd->packet,global.ptr(),global.length()); if (my_net_write(&thd->net,(char*) thd->packet.ptr(), -- cgit v1.2.1 From 143a179f3c1c4cca5b61979bb1a24b2053057ae0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 28 Feb 2002 14:05:47 +0200 Subject: Porting surgical changes from 4.0 to 4.1 --- sql/sql_select.cc | 108 ++++++++++++++++++++++++++++-------------------------- sql/sql_union.cc | 58 ++++++++++++++--------------- 2 files changed, 85 insertions(+), 81 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ae6c38a874e..3135fe050dc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6963,13 +6963,16 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, { List field_list; Item *item; + List item_list; THD *thd=join->thd; + MYSQL_LOCK *save_lock; SELECT_LEX *select_lex = &(join->thd->lex.select_lex); + select_result *result=join->result; DBUG_ENTER("select_describe"); /* Don't log this into the slow query log */ select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED); - if (join->thd->lex.select == select_lex) + if (thd->lex.select == select_lex) { field_list.push_back(new Item_empty_string("table",NAME_LEN)); field_list.push_back(new Item_empty_string("type",10)); @@ -6985,24 +6988,22 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item->maybe_null=1; field_list.push_back(new Item_real("rows",0.0,0,10)); field_list.push_back(new Item_empty_string("Extra",255)); - if (send_fields(thd,field_list,1)) + if (result->send_fields(field_list,1)) return; } - char buff[512],*buff_ptr; - String tmp(buff,sizeof(buff)),*packet= &thd->packet; + if (message) { - packet->length(0); - net_store_null(packet); - net_store_null(packet); - net_store_null(packet); - net_store_null(packet); - net_store_null(packet); - net_store_null(packet); - net_store_null(packet); - net_store_data(packet,message,strlen(message)); - if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) - DBUG_VOID_RETURN; + item_list.push_back(new Item_empty_string("",0)); + item_list.push_back(new Item_empty_string("",0)); + item_list.push_back(new Item_empty_string("",0)); + item_list.push_back(new Item_empty_string("",0)); + item_list.push_back(new Item_empty_string("",0)); + item_list.push_back(new Item_empty_string("",0)); + item_list.push_back(new Item_empty_string("",0)); + item_list.push_back(new Item_string(message,strlen(message))); + if (result->send_data(item_list)) + result->send_error(0,NullS); } else { @@ -7011,69 +7012,70 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, { JOIN_TAB *tab=join->join_tab+i; TABLE *table=tab->table; - + char buff[512],*buff_ptr=buff; + char buff1[512], buff2[512], bufff[512]; + String tmp1(buff1,sizeof(buff1)); + String tmp2(buff2,sizeof(buff2)); + item_list.empty(); if (tab->type == JT_ALL && tab->select && tab->select->quick) tab->type= JT_RANGE; - packet->length(0); - net_store_data(packet,table->table_name); - net_store_data(packet,join_type_str[tab->type]); - tmp.length(0); + item_list.push_back(new Item_string(table->table_name,strlen(table->table_name))); + item_list.push_back(new Item_string(join_type_str[tab->type],strlen(join_type_str[tab->type]))); + tmp1.length(0); tmp2.length(0); key_map bits; uint j; for (j=0,bits=tab->keys ; bits ; j++,bits>>=1) { if (bits & 1) { - if (tmp.length()) - tmp.append(','); - tmp.append(table->key_info[j].name); + if (tmp1.length()) + tmp1.append(','); + tmp1.append(table->key_info[j].name); } } - if (tmp.length()) - net_store_data(packet,tmp.ptr(),tmp.length()); + if (tmp1.length()) + item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length())); else - net_store_null(packet); + item_list.push_back(new Item_null()); if (tab->ref.key_parts) { - net_store_data(packet,table->key_info[tab->ref.key].name); - net_store_data(packet,(uint32) tab->ref.key_length); - tmp.length(0); + item_list.push_back(new Item_string(table->key_info[tab->ref.key].name,strlen(table->key_info[tab->ref.key].name))); + item_list.push_back(new Item_int((int) tab->ref.key_length)); for (store_key **ref=tab->ref.key_copy ; *ref ; ref++) { - if (tmp.length()) - tmp.append(','); - tmp.append((*ref)->name()); + if (tmp2.length()) + tmp2.append(','); + tmp2.append((*ref)->name()); } - net_store_data(packet,tmp.ptr(),tmp.length()); + item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length())); } else if (tab->type == JT_NEXT) { - net_store_data(packet,table->key_info[tab->index].name); - net_store_data(packet,(uint32) table->key_info[tab->index].key_length); - net_store_null(packet); + item_list.push_back(new Item_string(table->key_info[tab->index].name,strlen(table->key_info[tab->index].name))); + item_list.push_back(new Item_int((int) table->key_info[tab->index].key_length)); + item_list.push_back(new Item_null()); } else if (tab->select && tab->select->quick) { - net_store_data(packet,table->key_info[tab->select->quick->index].name);; - net_store_data(packet,(uint32) tab->select->quick->max_used_key_length); - net_store_null(packet); + item_list.push_back(new Item_string(table->key_info[tab->select->quick->index].name,strlen(table->key_info[tab->select->quick->index].name))); + item_list.push_back(new Item_int((int) tab->select->quick->max_used_key_length)); + item_list.push_back(new Item_null()); } else { - net_store_null(packet); - net_store_null(packet); - net_store_null(packet); + item_list.push_back(new Item_null()); + item_list.push_back(new Item_null()); + item_list.push_back(new Item_null()); } - sprintf(buff,"%.0f",join->best_positions[i].records_read); - net_store_data(packet,buff); + sprintf(bufff,"%.0f",join->best_positions[i].records_read); + item_list.push_back(new Item_string(bufff,strlen(bufff))); my_bool key_read=table->key_read; if (tab->type == JT_NEXT && ((table->used_keys & ((key_map) 1 << tab->index)))) key_read=1; - buff_ptr=buff; if (tab->info) - net_store_data(packet,tab->info); + item_list.push_back(new Item_string(tab->info,strlen(tab->info))); else if (tab->select) { if (tab->use_quick == 2) @@ -7127,16 +7129,20 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } buff_ptr=strmov(buff_ptr,"Distinct"); } - net_store_data(packet,buff,(uint) (buff_ptr - buff)); - if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) - DBUG_VOID_RETURN; /* Purecov: Inspected */ - + item_list.push_back(new Item_string(buff,(uint) (buff_ptr - buff))); // For next iteration used_tables|=table->map; + if (result->send_data(item_list)) + result->send_error(0,NullS); } } if (!join->thd->lex.select->next) - send_eof(&thd->net); + { + save_lock=thd->lock; + thd->lock=(MYSQL_LOCK *)0; + result->send_eof(); + thd->lock=save_lock; + } DBUG_VOID_RETURN; } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 51ad2425022..60155e0ce8d 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -31,10 +31,11 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ORDER *order; List item_list; TABLE *table; + int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0; + int res; TABLE_LIST result_table_list; TMP_TABLE_PARAM tmp_table_param; select_union *union_result; - int res; DBUG_ENTER("mysql_union"); /* Fix tables 'to-be-unioned-from' list to point at opened tables */ @@ -70,33 +71,26 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) lex_sl=0; order=0; } - - if (lex->select_lex.options & SELECT_DESCRIBE) + + if (describe) { - for (sl= &lex->select_lex; sl; sl=sl->next) - { - lex->select=sl; - thd->offset_limit=sl->offset_limit; - thd->select_limit=sl->select_limit+sl->offset_limit; - if (thd->select_limit < sl->select_limit) - thd->select_limit= HA_POS_ERROR; // no limit - if (thd->select_limit == HA_POS_ERROR) - sl->options&= ~OPTION_FOUND_ROWS; - res=mysql_select(thd, (TABLE_LIST*) sl->table_list.first, - sl->item_list, - sl->where, - ((sl->braces) ? - (ORDER *) sl->order_list.first : (ORDER *) 0), - (ORDER*) sl->group_list.first, - sl->having, - (ORDER*) NULL, - (sl->options | thd->options | SELECT_NO_UNLOCK | - SELECT_DESCRIBE), - result); - } - DBUG_RETURN(0); + Item *item; + item_list.push_back(new Item_empty_string("table",NAME_LEN)); + item_list.push_back(new Item_empty_string("type",10)); + item_list.push_back(item=new Item_empty_string("possible_keys", + NAME_LEN*MAX_KEY)); + item->maybe_null=1; + item_list.push_back(item=new Item_empty_string("key",NAME_LEN)); + item->maybe_null=1; + item_list.push_back(item=new Item_int("key_len",0,3)); + item->maybe_null=1; + item_list.push_back(item=new Item_empty_string("ref", + NAME_LEN*MAX_REF_PARTS)); + item->maybe_null=1; + item_list.push_back(new Item_real("rows",0.0,0,10)); + item_list.push_back(new Item_empty_string("Extra",255)); } - + else { Item *item; List_iterator it(lex->select_lex.item_list); @@ -113,7 +107,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) bzero((char*) &tmp_table_param,sizeof(tmp_table_param)); tmp_table_param.field_count=item_list.elements; if (!(table=create_tmp_table(thd, &tmp_table_param, item_list, - (ORDER*) 0, !lex->union_option, + (ORDER*) 0, !describe & !lex->union_option, 1, 0, (lex->select_lex.options | thd->options | TMP_TABLE_ALL_COLUMNS)))) @@ -130,7 +124,9 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) res= -1; goto exit; } - for (sl= &lex->select_lex; sl; sl=sl->next) + union_result->save_time_stamp=!describe; + + for (sl=&lex->select_lex;sl;sl=sl->next) { thd->offset_limit=sl->offset_limit; thd->select_limit=sl->select_limit+sl->offset_limit; @@ -146,7 +142,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) (ORDER*) sl->group_list.first, sl->having, (ORDER*) NULL, - sl->options | thd->options | SELECT_NO_UNLOCK, + sl->options | thd->options | SELECT_NO_UNLOCK | ((describe) ? SELECT_DESCRIBE : 0), union_result); if (res) goto exit; @@ -187,6 +183,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) if (thd->select_limit == HA_POS_ERROR) thd->options&= ~OPTION_FOUND_ROWS; } + if (describe) + thd->select_limit= HA_POS_ERROR; // no limit res=mysql_select(thd,&result_table_list, item_list, NULL, /*ftfunc_list,*/ order, (ORDER*) NULL, NULL, (ORDER*) NULL, @@ -222,7 +220,7 @@ select_union::~select_union() int select_union::prepare(List &list) { - if (list.elements != table->fields) + if (save_time_stamp && list.elements != table->fields) { my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0)); -- cgit v1.2.1 From 94958d062b460449c1f249abfa0766b7d7554eb9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 28 Feb 2002 17:28:36 +0400 Subject: Several new OpenGIS functions Fixes in GeomFromText() to accept an new optional argument respobsible for SRID. This is for more OpenGIS conformance and PostGIS compatibility to simplify migrating from PgSQL to MySQL sql/gen_lex_hash.cc: Changed max_allowed_array sql/lex.h: Added several symbols for new OpenGIS SQL functions sql/sql_yacc.yy: new OpenGIS functions (spatial constructors) --- sql/gen_lex_hash.cc | 2 +- sql/lex.h | 11 +++++++++-- sql/sql_yacc.yy | 50 +++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 55 insertions(+), 8 deletions(-) (limited to 'sql') diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 7ebdbcd8ba8..918ec753f68 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -30,7 +30,7 @@ bool opt_search=0; int opt_verbose=0; ulong opt_count=100000; -#define max_allowed_array 8000 // Don't generate bigger arrays than this +#define max_allowed_array 16000 // Don't generate bigger arrays than this #define max_symbol 32767 // Use this for 'not found' #define how_much_for_plus 8 // 2-8 #define type_count 1 // 1-5 diff --git a/sql/lex.h b/sql/lex.h index 04edaf217b9..c720a308f7d 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -159,7 +159,7 @@ static SYMBOL symbols[] = { { "FULL", SYM(FULL),0,0}, { "FULLTEXT", SYM(FULLTEXT_SYM),0,0}, { "FUNCTION", SYM(UDF_SYM),0,0}, - { "GEOM", SYM(GEOM_SYM),0,0}, + { "GEOMETRY", SYM(GEOMETRY_SYM),0,0}, { "GLOBAL", SYM(GLOBAL_SYM),0,0}, { "GRANT", SYM(GRANT),0,0}, { "GRANTS", SYM(GRANTS),0,0}, @@ -453,7 +453,8 @@ static SYMBOL sql_functions[] = { { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION),0,0}, { "GEOMETRYN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_geometryn)}, { "GEOMETRYTYPE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_geometry_type)}, - { "GEOMFROMTEXT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_geometry_from_text)}, + { "GEOMCOLLFROMTEXT", SYM(GEOMCOLLFROMTEXT),0,0}, + { "GEOMFROMTEXT", SYM(GEOMFROMTEXT),0,0}, { "GLENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_glength)}, { "GREATEST", SYM(GREATEST_SYM),0,0}, { "GROUP_UNIQUE_USERS", SYM(GROUP_UNIQUE_USERS),0,0}, @@ -471,6 +472,7 @@ static SYMBOL sql_functions[] = { { "LCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)}, { "LEAST", SYM(LEAST_SYM),0,0}, { "LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)}, + { "LINEFROMTEXT", SYM(LINEFROMTEXT),0,0}, { "LINESTRING", SYM(LINESTRING),0,0}, { "LOAD_FILE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_load_file)}, { "LOCATE", SYM(LOCATE),0,0}, @@ -487,6 +489,9 @@ static SYMBOL sql_functions[] = { { "MID", SYM(SUBSTRING),0,0}, /* unireg function */ { "MIN", SYM(MIN_SYM),0,0}, { "MOD", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_mod)}, + { "MLINEFROMTEXT", SYM(MLINEFROMTEXT),0,0}, + { "MPOINTFROMTEXT", SYM(MPOINTFROMTEXT),0,0}, + { "MPOLYFROMTEXT", SYM(MPOLYFROMTEXT),0,0}, { "MULTILINESTRING", SYM(MULTILINESTRING),0,0}, { "MULTIPOINT", SYM(MULTIPOINT),0,0}, { "MULTIPOLYGON", SYM(MULTIPOLYGON),0,0}, @@ -504,7 +509,9 @@ static SYMBOL sql_functions[] = { { "PERIOD_DIFF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_diff)}, { "PI", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_pi)}, { "POINT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_point)}, + { "POINTFROMTEXT", SYM(POINTFROMTEXT),0,0}, { "POINTN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pointn)}, + { "POLYFROMTEXT", SYM(POLYFROMTEXT),0,0}, { "POLYGON", SYM(POLYGON),0,0}, { "POSITION", SYM(POSITION_SYM),0,0}, { "POW", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 857d7a245f0..b8b56a72657 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -349,7 +349,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ENUM %token FAST_SYM %token FLOAT_SYM -%token GEOM_SYM +%token GEOMETRY_SYM %token INT_SYM %token LIMIT %token LONGBLOB @@ -407,6 +407,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token FORMAT_SYM %token FOR_SYM %token FROM_UNIXTIME +%token GEOMCOLLFROMTEXT +%token GEOMFROMTEXT %token GEOMETRYCOLLECTION %token GROUP_UNIQUE_USERS %token HOUR_MINUTE_SYM @@ -419,6 +421,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token INTERVAL_SYM %token LAST_INSERT_ID %token LEFT +%token LINEFROMTEXT %token LINESTRING %token LOCATE %token MAKE_SET_SYM @@ -427,11 +430,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token MODE_SYM %token MODIFY_SYM %token MONTH_SYM +%token MLINEFROMTEXT +%token MPOINTFROMTEXT +%token MPOLYFROMTEXT %token MULTILINESTRING %token MULTIPOINT %token MULTIPOLYGON %token NOW_SYM %token PASSWORD +%token POINTFROMTEXT +%token POLYFROMTEXT %token POLYGON %token POSITION_SYM %token PROCEDURE @@ -966,7 +974,7 @@ type: $$=FIELD_TYPE_TINY_BLOB; } | BLOB_SYM { Lex->type|=BINARY_FLAG; $$=FIELD_TYPE_BLOB; } - | GEOM_SYM { Lex->type|=BINARY_FLAG; + | GEOMETRY_SYM { Lex->type|=BINARY_FLAG; $$=FIELD_TYPE_GEOMETRY; } | MEDIUMBLOB { Lex->type|=BINARY_FLAG; $$=FIELD_TYPE_MEDIUM_BLOB; } @@ -1722,6 +1730,10 @@ simple_expr: } | FIELD_FUNC '(' expr ',' expr_list ')' { $$= new Item_func_field($3, *$5); } + | GEOMFROMTEXT '(' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | GEOMFROMTEXT '(' expr ',' expr ')' + { $$= new Item_func_geometry_from_text($3) } | GEOMETRYCOLLECTION '(' expr_list ')' { $$= new Item_func_spatial_collection(* $3, Geometry::wkbGeometryCollection, @@ -1757,10 +1769,18 @@ simple_expr: { $$= new Item_func_locate($5,$3); } | LOCATE '(' expr ',' expr ',' expr ')' { $$= new Item_func_locate($5,$3,$7); } - | GREATEST_SYM '(' expr ',' expr_list ')' + | GEOMCOLLFROMTEXT '(' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | GEOMCOLLFROMTEXT '(' expr ',' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | GREATEST_SYM '(' expr ',' expr_list ')' { $5->push_front($3); $$= new Item_func_max(*$5); } | LEAST_SYM '(' expr ',' expr_list ')' { $5->push_front($3); $$= new Item_func_min(*$5); } + | LINEFROMTEXT '(' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | LINEFROMTEXT '(' expr ',' expr ')' + { $$= new Item_func_geometry_from_text($3) } | MINUTE_SYM '(' expr ')' { $$= new Item_func_minute($3); } | MONTH_SYM '(' expr ')' @@ -1768,7 +1788,19 @@ simple_expr: | MULTILINESTRING '(' expr_list ')' { $$= new Item_func_spatial_collection(* $3, Geometry::wkbMultiLineString, Geometry::wkbLineString); } - | MULTIPOINT '(' expr_list ')' + | MLINEFROMTEXT '(' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | MLINEFROMTEXT '(' expr ',' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | MPOINTFROMTEXT '(' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | MPOINTFROMTEXT '(' expr ',' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | MPOLYFROMTEXT '(' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | MPOLYFROMTEXT '(' expr ',' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | MULTIPOINT '(' expr_list ')' { $$= new Item_func_spatial_collection(* $3, Geometry::wkbMultiPoint, Geometry::wkbPoint); } | MULTIPOLYGON '(' expr_list ')' @@ -1782,7 +1814,15 @@ simple_expr: { $$= new Item_func_password($3); } - | POLYGON '(' expr_list ')' + | POINTFROMTEXT '(' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | POINTFROMTEXT '(' expr ',' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | POLYFROMTEXT '(' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | POLYFROMTEXT '(' expr ',' expr ')' + { $$= new Item_func_geometry_from_text($3) } + | POLYGON '(' expr_list ')' { $$= new Item_func_spatial_collection(* $3, Geometry::wkbPolygon, Geometry::wkbLineString); } | POSITION_SYM '(' no_in_expr IN_SYM expr ')' -- cgit v1.2.1 From f739974c5e5b4dbf68c5000b8231f554d9ffd40d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 28 Feb 2002 22:01:41 +0200 Subject: Porting from mysql-4.0. Read comments there if you are interested .. BitKeeper/etc/ignore: Added sql/sql_yacc.yy.orig to the ignore list --- sql/sql_yacc.yy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 857d7a245f0..3c0d476ac83 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1977,7 +1977,7 @@ opt_else: | ELSE expr { $$= $2; } when_list: - { Select->when_list.push_front(new List) } + { Select->when_list.push_front(new List); } when_list2 { $$= Select->when_list.pop(); } @@ -2080,7 +2080,7 @@ opt_key_definition: } key_usage_list: - key_or_index { Select->interval_list.empty() } '(' key_usage_list2 ')' + key_or_index { Select->interval_list.empty(); } '(' key_usage_list2 ')' { $$= &Select->interval_list; } key_usage_list2: @@ -2686,7 +2686,7 @@ describe: YYABORT; } opt_describe_column - | describe_command select { Lex->select_lex.options|= SELECT_DESCRIBE }; + | describe_command select { Lex->select_lex.options|= SELECT_DESCRIBE; } describe_command: @@ -3126,7 +3126,7 @@ set: lex->select->select_limit=lex->thd->default_select_limit; lex->tx_isolation=lex->thd->tx_isolation; lex->option_type=0; - lex->option_list.empty() + lex->option_list.empty(); } option_value_list -- cgit v1.2.1 From c66afc4d7c238cdb63cda9c06286afb4ac981de9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Mar 2002 15:31:22 +0400 Subject: New armscii8 charset configure.in: Added armscii8 sql/share/charsets/Index: A --- sql/share/charsets/Index | 1 + sql/share/charsets/armscii8.conf | 74 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 sql/share/charsets/armscii8.conf (limited to 'sql') diff --git a/sql/share/charsets/Index b/sql/share/charsets/Index index 5cf30682cc0..9781b516f97 100644 --- a/sql/share/charsets/Index +++ b/sql/share/charsets/Index @@ -36,3 +36,4 @@ gbk 28 cp1257 29 latin5 30 latin1_de 31 +armscii8 32 diff --git a/sql/share/charsets/armscii8.conf b/sql/share/charsets/armscii8.conf new file mode 100644 index 00000000000..15c232c7e94 --- /dev/null +++ b/sql/share/charsets/armscii8.conf @@ -0,0 +1,74 @@ +# Configuration file for the armscii8 (armenian) character set + +# ctype array (must have 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 10 10 01 02 01 02 01 02 01 02 01 02 01 02 01 02 + 01 02 01 02 01 02 01 02 01 02 01 02 01 02 01 02 + 01 02 01 02 01 02 01 02 01 02 01 02 01 02 01 02 + 01 02 01 02 01 02 01 02 01 02 01 02 01 02 01 02 + 01 02 01 02 01 02 01 02 01 02 01 02 01 02 10 10 + +# to_lower array (must have 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 B8 A9 AA AB AC AD AE AF + B0 B1 B3 B3 B5 B5 B7 B7 B9 B9 BB BB BD BD BF BF + C1 C1 C3 C3 C5 C5 C7 C7 C9 C9 CB CB CD CD CF CF + D1 D1 D3 D3 D5 D5 D7 D7 D9 D9 DB DB DD DD DF DF + E1 E1 E3 E3 E5 E5 E7 E7 E9 E9 EB EB ED ED EF EF + F1 F1 F3 F3 F5 F5 F7 F7 F9 F9 FB FB FD FD FE FF + +# to_upper array (must have 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B2 B4 B4 B6 B6 B8 B8 BA BA BC BC BE BE + C0 C0 C2 C2 C4 C4 C6 C6 C8 C8 CA CA CC CC CE CE + D0 D0 D2 D2 D4 D4 D6 D6 D8 D8 DA DA DC DC DE DE + E0 E0 E2 E2 E4 E4 E6 E6 E8 E8 EA EA EC EC EE EE + F0 F0 F2 F2 F4 F4 F6 F6 F8 F8 FA FA FC FC FE FF + +# sort_order array (must have 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF -- cgit v1.2.1 From 1a7c7d763cb34b52c723c526b2e8b38432e7dec1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Mar 2002 16:12:11 +0200 Subject: Fixes done in 4.0 repository. For comments see the corresponding ones in 4.0. --- sql/sql_select.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3135fe050dc..14feb12c769 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -187,7 +187,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, TABLE *tmp_table; int error, tmp_error; bool need_tmp,hidden_group_fields; - bool simple_order,simple_group,no_order, skip_sort_order; + bool simple_order,simple_group,no_order, skip_sort_order, buffer_result; Item::cond_result cond_value; SQL_SELECT *select; DYNAMIC_ARRAY keyuse; @@ -201,6 +201,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, /* Check that all tables, fields, conds and order are ok */ select_distinct=test(select_options & SELECT_DISTINCT); + buffer_result=test(select_options & OPTION_BUFFER_RESULT) && !test(select_options & OPTION_FOUND_ROWS); tmp_table=0; select=0; no_order=skip_sort_order=0; @@ -546,8 +547,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, need_tmp= (join.const_tables != join.tables && ((select_distinct || !simple_order || !simple_group) || - (group && order) || - test(select_options & OPTION_BUFFER_RESULT))); + (group && order) || buffer_result)); // No cache for MATCH make_join_readinfo(&join, -- cgit v1.2.1 From 654db69b8247a7e6be4e039a558f635af9abae57 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Mar 2002 20:04:13 +0400 Subject: Regex library is switched to use new ctype tools to allow usage of many character sets at a time. include/m_ctype.h: Added condition to simplify migrating from old ctype Added new style toupper, tolower which accepts charset in first argument regex/debug.c: Added charset argument regex/debug.ih: added charset argument regex/engine.c: added charset argument regex/engine.ih: added charset arguent regex/main.c: added charset argument regex/regcomp.c: added CHARSET_INFO field regex/regcomp.ih: Added charset argument regex/regex.h: Added #include for CHARSET_INFO Added charset argument for regcomp() regex/regex2.h: New charset argument for ISWORD() regex/regexec.c: New charset argument regex/reginit.c: Move to new style ctype. However still needs fixes: instead of single static cclass variable, each charset must have it's own variable. sql/item_cmpfunc.cc: Pass charset field into regcomp() This will be fixed tommorow to use String->charset instead of default_charset_info --- sql/item_cmpfunc.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 1de398177b5..a09c503e3d5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1278,7 +1278,8 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) int error; if ((error=regcomp(&preg,res->c_ptr(), binary ? REG_EXTENDED | REG_NOSUB : - REG_EXTENDED | REG_NOSUB | REG_ICASE))) + REG_EXTENDED | REG_NOSUB | REG_ICASE, + default_charset_info))) { (void) regerror(error,&preg,buff,sizeof(buff)); my_printf_error(ER_REGEXP_ERROR,ER(ER_REGEXP_ERROR),MYF(0),buff); @@ -1325,7 +1326,8 @@ longlong Item_func_regex::val_int() } if (regcomp(&preg,res2->c_ptr(), binary ? REG_EXTENDED | REG_NOSUB : - REG_EXTENDED | REG_NOSUB | REG_ICASE)) + REG_EXTENDED | REG_NOSUB | REG_ICASE, + default_charset_info)) { null_value=1; -- cgit v1.2.1 From 220eeadc3d623ceede6990570e67bc5fab15d1ec Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Mar 2002 15:23:24 +0400 Subject: Extend String class with CHARSET_INFO field --- sql/item_cmpfunc.cc | 4 ++-- sql/sql_string.h | 35 +++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index a09c503e3d5..d4ab03003ce 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1279,7 +1279,7 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) if ((error=regcomp(&preg,res->c_ptr(), binary ? REG_EXTENDED | REG_NOSUB : REG_EXTENDED | REG_NOSUB | REG_ICASE, - default_charset_info))) + res->charset()))) { (void) regerror(error,&preg,buff,sizeof(buff)); my_printf_error(ER_REGEXP_ERROR,ER(ER_REGEXP_ERROR),MYF(0),buff); @@ -1327,7 +1327,7 @@ longlong Item_func_regex::val_int() if (regcomp(&preg,res2->c_ptr(), binary ? REG_EXTENDED | REG_NOSUB : REG_EXTENDED | REG_NOSUB | REG_ICASE, - default_charset_info)) + res->charset())) { null_value=1; diff --git a/sql/sql_string.h b/sql/sql_string.h index ac579cd752d..6e8fefb079a 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -36,26 +36,45 @@ class String char *Ptr; uint32 str_length,Alloced_length; bool alloced; + CHARSET_INFO *str_charset; public: String() - { Ptr=0; str_length=Alloced_length=0; alloced=0; } + { + Ptr=0; str_length=Alloced_length=0; alloced=0; + str_charset=default_charset_info; + } String(uint32 length_arg) - { alloced=0; Alloced_length=0; (void) real_alloc(length_arg); } + { + alloced=0; Alloced_length=0; (void) real_alloc(length_arg); + str_charset=default_charset_info; + } String(const char *str) - { Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;} + { + Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0; + str_charset=default_charset_info; + } String(const char *str,uint32 len) - { Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;} + { + Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0; + str_charset=default_charset_info; + } String(char *str,uint32 len) - { Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;} + { + Ptr=(char*) str; Alloced_length=str_length=len; alloced=0; + str_charset=default_charset_info; + } String(const String &str) - { Ptr=str.Ptr ; str_length=str.str_length ; - Alloced_length=str.Alloced_length; alloced=0; } - + { + Ptr=str.Ptr ; str_length=str.str_length ; + Alloced_length=str.Alloced_length; alloced=0; + str_charset=str.str_charset; + } static void *operator new(size_t size) { return (void*) sql_alloc((uint) size); } static void operator delete(void *ptr_arg,size_t size) /*lint -e715 */ { sql_element_free(ptr_arg); } ~String() { free(); } + inline CHARSET_INFO *charset() const { return str_charset; } inline uint32 length() const { return str_length;} inline uint32 alloced_length() const { return Alloced_length;} inline char& operator [] (uint32 i) const { return Ptr[i]; } -- cgit v1.2.1 From 6265e94c350650b43d8b8002ea1dde527c44b7af Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Mar 2002 14:19:18 +0200 Subject: Same patches as for 4.0. See there for details --- sql/sql_yacc.yy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f91d6a48d50..41e56328613 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1652,7 +1652,7 @@ simple_expr: | BINARY expr %prec NEG { $$= new Item_func_binary($2); } | CAST_SYM '(' expr AS cast_type ')' { $$= create_func_cast($3, $5); } | CASE_SYM opt_expr WHEN_SYM when_list opt_else END - { $$= new Item_func_case(* $4, $2, $5 ) } + { $$= new Item_func_case(* $4, $2, $5 ); } | CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); } | FUNC_ARG0 '(' ')' { $$= ((Item*(*)(void))($1.symbol->create_func))();} @@ -1969,7 +1969,7 @@ sum_expr: { $$=new Item_sum_sum($3); } in_sum_expr: - { Select->in_sum_expr++ } + { Select->in_sum_expr++; } expr { Select->in_sum_expr--; @@ -2042,7 +2042,7 @@ opt_pad: join_table_list: '(' join_table_list ')' { $$=$2; } | join_table { $$=$1; } - | join_table_list normal_join join_table { $$=$3 } + | join_table_list normal_join join_table { $$=$3; } | join_table_list STRAIGHT_JOIN join_table { $$=$3 ; $$->straight=1; } | join_table_list INNER_SYM JOIN_SYM join_table ON expr { add_join_on($4,$6); $$=$4; } -- cgit v1.2.1 From c10827ba04cd417010beacfc5da972de65817574 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 9 Mar 2002 14:21:34 +0200 Subject: Take a look at comments in 4.0 --- sql/mysqld.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 187a4732aa0..5e4fc654320 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2456,6 +2456,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) struct request_info req; signal(SIGCHLD, SIG_DFL); request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL); +#ifndef __linux__ fromhost(&req); if (!hosts_access(&req)) { @@ -2465,6 +2466,12 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) clean_exit() - same stupid thing ... */ syslog(deny_severity, "refused connect from %s", eval_client(&req)); +#else + fromhost(); + if (!hosts_access()) + { + syslog(deny_severity, "refused connect from %s", eval_client()); +#endif if (req.sink) ((void (*)(int))req.sink)(req.fd); -- cgit v1.2.1 From 68375e0f008d109f574491bd3b0eb2184e6f3ad2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Mar 2002 21:37:58 +0400 Subject: New ctype functions/macros to support many charsets at a time client/mysql.cc: new ctypes client/mysqldump.c: new ctypes client/mysqltest.c: new ctypes client/sql_string.cc: new ctypes client/sql_string.h: new ctypes extra/mysql_install.c: new ctypes extra/replace.c: new ctypes extra/resolve_stack_dump.c: new ctypes extra/resolveip.c: new ctypes heap/hp_hash.c: new ctypes include/m_ctype.h: new ctypes include/my_sys.h: new ctypes isam/_key.c: new ctypes isam/_search.c: new ctypes libmysql/Makefile.shared: new ctypes libmysql/libmysql.c: new ctypes myisam/ft_dump.c: new ctypes myisam/ft_parser.c: new ctypes myisam/mi_test1.c: new ctypes mysys/charset.c: new ctypes mysys/default.c: new ctypes mysys/getvar.c: new ctypes mysys/hash.c: new ctypes mysys/mf_casecnv.c: new ctypes mysys/mf_dirname.c: new ctypes mysys/mf_format.c: new ctypes mysys/mf_iocache2.c: new ctypes mysys/mf_soundex.c: new ctypes mysys/mf_wfile.c: new ctypes mysys/my_error.c: new ctypes mysys/my_getwd.c: new ctypes mysys/my_init.c: new ctypes mysys/my_vsnprintf.c: new ctypes mysys/typelib.c: new ctypes sql/convert.cc: new ctypes sql/des_key_file.cc: new ctypes sql/field.cc: new ctypes sql/field.h: new ctypes sql/field_conv.cc: new ctypes sql/filesort.cc: new ctypes sql/ha_innodb.cc: new ctypes sql/hostname.cc: new ctypes sql/init.cc: new ctypes sql/item.cc: new ctypes sql/item_func.cc: new ctypes sql/item_strfunc.cc: new ctypes sql/item_sum.cc: new ctypes sql/item_timefunc.cc: new ctypes sql/key.cc: new ctypes sql/log.cc: new ctypes sql/mysql_priv.h: new ctypes sql/mysqld.cc: new ctypes sql/opt_range.cc: new ctypes sql/procedure.cc: new ctypes sql/slave.cc: new ctypes sql/sql_acl.cc: new ctypes sql/sql_analyse.cc: new ctypes sql/sql_base.cc: new ctypes sql/sql_cache.cc: new ctypes sql/sql_db.cc: new ctypes sql/sql_handler.cc: new ctypes sql/sql_lex.cc: new ctypes sql/sql_parse.cc: new ctypes sql/sql_show.cc: new ctypes sql/sql_string.cc: new ctypes sql/sql_string.h: new ctypes sql/sql_table.cc: new ctypes sql/sql_yacc.yy: new ctypes sql/table.cc: new ctypes sql/time.cc: new ctypes strings/Makefile.am: new ctypes strings/ctype-big5.c: new ctypes strings/ctype-czech.c: new ctypes strings/ctype-gbk.c: new ctypes strings/ctype-latin1_de.c: new ctypes strings/ctype-sjis.c: new ctypes strings/ctype-tis620.c: new ctypes strings/ctype.c: new ctypes strings/str2int.c: new ctypes strings/strto.c: new ctypes tools/mysqlmanager.c: new ctypes --- sql/convert.cc | 12 +++++- sql/des_key_file.cc | 5 ++- sql/field.cc | 114 +++++++++++++++++++++++++++------------------------ sql/field.h | 19 +++++---- sql/field_conv.cc | 2 +- sql/filesort.cc | 11 +++-- sql/ha_innodb.cc | 5 ++- sql/hostname.cc | 4 +- sql/init.cc | 14 ++++--- sql/item.cc | 4 +- sql/item_func.cc | 3 +- sql/item_strfunc.cc | 16 ++++---- sql/item_sum.cc | 3 +- sql/item_timefunc.cc | 8 ++-- sql/key.cc | 5 ++- sql/log.cc | 4 +- sql/mysql_priv.h | 6 +-- sql/mysqld.cc | 11 ++--- sql/opt_range.cc | 3 +- sql/procedure.cc | 3 +- sql/slave.cc | 9 ++-- sql/sql_acl.cc | 46 ++++++++++++--------- sql/sql_analyse.cc | 10 ++--- sql/sql_base.cc | 21 ++++++---- sql/sql_cache.cc | 5 ++- sql/sql_db.cc | 6 ++- sql/sql_handler.cc | 2 +- sql/sql_lex.cc | 78 ++++++++++++++++++----------------- sql/sql_parse.cc | 15 ++++--- sql/sql_show.cc | 10 +++-- sql/sql_string.cc | 74 +++++++++++++++++---------------- sql/sql_string.h | 4 +- sql/sql_table.cc | 33 +++++++++------ sql/sql_yacc.yy | 3 +- sql/table.cc | 14 ++++--- sql/time.cc | 53 ++++++++++++++---------- 36 files changed, 359 insertions(+), 276 deletions(-) (limited to 'sql') diff --git a/sql/convert.cc b/sql/convert.cc index 7a06208759c..1b9a94462c7 100644 --- a/sql/convert.cc +++ b/sql/convert.cc @@ -433,7 +433,17 @@ CONVERT *get_convert_set(const char *name) { for (CONVERT **ptr=convert_tables ; *ptr ; ptr++) { - if (!my_strcasecmp((*ptr)->name,name)) + /* + BAR TODO: Monty's comments: + Why is this using system_charset_info ? + Isn't the character-set string given in the users default charset? + Please add a TODO note to the code that this has to be fixed when the user + will be able to cast strings to different character sets... + The current code will also not work if/when we introduce support for + 16 bit characters... + (I know that there is a LOT of changes to do if we ever want do this...) + */ + if (!my_strcasecmp(system_charset_info,(*ptr)->name,name)) return (*ptr); } return 0; diff --git a/sql/des_key_file.cc b/sql/des_key_file.cc index d9c924b5a3c..ca92e38279b 100644 --- a/sql/des_key_file.cc +++ b/sql/des_key_file.cc @@ -70,9 +70,10 @@ load_des_key_file(const char *file_name) { offset=(char) (offset - '0'); // Remove newline and possible other control characters - for (start=buf+1 ; isspace(*start) ; start++) ; + for (start=buf+1 ; my_isspace(system_charset_info, *start) ; start++) ; end=buf+length; - for (end=strend(buf) ; end > start && !isgraph(end[-1]) ; end--) ; + for (end=strend(buf) ; + end > start && !my_isgraph(system_charset_info, end[-1]) ; end--) ; if (start != end) { diff --git a/sql/field.cc b/sql/field.cc index 5d398d0ae5f..f2d9f51283a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -68,7 +68,8 @@ const char field_separator=','; */ static bool -number_dec(struct st_decstr *sdec, const char *str, const char *end) +number_dec(CHARSET_INFO *cs, struct st_decstr *sdec, + const char *str, const char *end) { sdec->sign=sdec->extra=0; if (str == end) @@ -86,7 +87,7 @@ number_dec(struct st_decstr *sdec, const char *str, const char *end) str++; } const char *start=str; - while (str != end && isdigit(*str)) + while (str != end && my_isdigit(cs,*str)) str++; if (!(sdec->nr_length=(uint) (str-start))) sdec->extra=1; // We must put one 0 before . @@ -95,13 +96,13 @@ number_dec(struct st_decstr *sdec, const char *str, const char *end) { str++; start=str; - while (str != end && isdigit(*str)) + while (str != end && my_isdigit(cs,*str)) str++; } sdec->nr_dec=(uint) (str-start); if (current_thd->count_cuted_fields) { - while (str != end && isspace(*str)) + while (str != end && my_isspace(cs,*str)) str++; /* purecov: inspected */ if (str != end) { @@ -135,7 +136,8 @@ bool test_if_int(const char *str,int length) { const char *end=str+length; - while (str != end && isspace(*str)) // Allow start space + // Allow start space + while (str != end && my_isspace(system_charset_info,*str)) str++; /* purecov: inspected */ if (str != end && (*str == '-' || *str == '+')) str++; @@ -143,7 +145,7 @@ bool test_if_int(const char *str,int length) return 0; // Error: Empty string for ( ; str != end ; str++) { - if (!isdigit(*str)) + if (!my_isdigit(system_charset_info,*str)) { if (*str == '.') { // Allow '.0000' @@ -151,10 +153,10 @@ bool test_if_int(const char *str,int length) if (str == end) return 1; } - if (!isspace(*str)) + if (!my_isspace(system_charset_info,*str)) return 0; for (str++ ; str != end ; str++) - if (!isspace(*str)) + if (!my_isspace(system_charset_info,*str)) return 0; return 1; } @@ -165,7 +167,7 @@ bool test_if_int(const char *str,int length) static bool test_if_real(const char *str,int length) { - while (length && isspace(*str)) + while (length && my_isspace(system_charset_info,*str)) { // Allow start space length--; str++; } @@ -174,10 +176,10 @@ static bool test_if_real(const char *str,int length) if (*str == '+' || *str == '-') { length--; str++; - if (!length || !(isdigit(*str) || *str == '.')) + if (!length || !(my_isdigit(system_charset_info,*str) || *str == '.')) return 0; } - while (length && isdigit(*str)) + while (length && my_isdigit(system_charset_info,*str)) { length--; str++; } @@ -186,7 +188,7 @@ static bool test_if_real(const char *str,int length) if (*str == '.') { length--; str++; - while (length && isdigit(*str)) + while (length && my_isdigit(system_charset_info,*str)) { length--; str++; } @@ -195,18 +197,19 @@ static bool test_if_real(const char *str,int length) return 1; if (*str == 'E' || *str == 'e') { - if (length < 3 || (str[1] != '+' && str[1] != '-') || !isdigit(str[2])) + if (length < 3 || (str[1] != '+' && str[1] != '-') || + !my_isdigit(system_charset_info,str[2])) return 0; length-=3; str+=3; - while (length && isdigit(*str)) + while (length && my_isdigit(system_charset_info,*str)) { length--; str++; } } for ( ; length ; length--, str++) { // Allow end space - if (!isspace(*str)) + if (!my_isspace(system_charset_info,*str)) return 0; } return 1; @@ -405,7 +408,7 @@ void Field_decimal::store(const char *from,uint len) if ((tmp_dec= dec)) tmp_dec++; // Calculate pos of '.' - while (from != end && isspace(*from)) + while (from != end && my_isspace(system_charset_info,*from)) from++; if (zerofill) { @@ -416,7 +419,7 @@ void Field_decimal::store(const char *from,uint len) } else fyllchar=' '; - error=number_dec(&decstr,from,end); + error=number_dec(system_charset_info,&decstr,from,end); if (decstr.sign) { from++; @@ -479,7 +482,7 @@ void Field_decimal::store(const char *from,uint len) { if (*from != '0') { - if (!isspace(*from)) // Space is ok + if (!my_isspace(system_charset_info,*from)) // Space is ok current_thd->cuted_fields++; break; } @@ -603,8 +606,10 @@ int Field_decimal::cmp(const char *a_ptr,const char *b_ptr) for (end=a_ptr+field_length; a_ptr != end && (*a_ptr == *b_ptr || - ((isspace(*a_ptr) || *a_ptr == '+' || *a_ptr == '0') && - (isspace(*b_ptr) || *b_ptr == '+' || *b_ptr == '0'))); + ((my_isspace(system_charset_info,*a_ptr) || *a_ptr == '+' || + *a_ptr == '0') && + (my_isspace(system_charset_info,*b_ptr) || *b_ptr == '+' || + *b_ptr == '0'))); a_ptr++,b_ptr++) { if (*a_ptr == '-') // If both numbers are negative @@ -631,7 +636,7 @@ void Field_decimal::sort_string(char *to,uint length) char *str,*end; for (str=ptr,end=ptr+length; str != end && - ((isspace(*str) || *str == '+' || *str == '0')) ; + ((my_isspace(system_charset_info,*str) || *str == '+' || *str == '0')) ; str++) *to++=' '; @@ -643,7 +648,7 @@ void Field_decimal::sort_string(char *to,uint length) *to++=1; // Smaller than any number str++; while (str != end) - if (isdigit(*str)) + if (my_isdigit(system_charset_info,*str)) *to++= (char) ('9' - *str++); else *to++= *str++; @@ -1265,7 +1270,7 @@ void Field_medium::sql_type(String &res) const void Field_long::store(const char *from,uint len) { - while (len && isspace(*from)) + while (len && my_isspace(system_charset_info,*from)) { len--; from++; } @@ -1493,7 +1498,7 @@ void Field_long::sql_type(String &res) const void Field_longlong::store(const char *from,uint len) { - while (len && isspace(*from)) + while (len && my_isspace(system_charset_info,*from)) { // For easy error check len--; from++; } @@ -3306,7 +3311,7 @@ void Field_string::store(const char *from,uint length) const char *end=from+length; for (from+=field_length ; from != end ; from++) { - if (!isspace(*from)) + if (!my_isspace(field_charset,*from)) { current_thd->cuted_fields++; break; @@ -3377,7 +3382,7 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) if (binary_flag) return memcmp(a_ptr,b_ptr,field_length); else - return my_sortcmp(a_ptr,b_ptr,field_length); + return my_sortcmp(field_charset,a_ptr,b_ptr,field_length); } void Field_string::sort_string(char *to,uint length) @@ -3387,17 +3392,17 @@ void Field_string::sort_string(char *to,uint length) else { #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info)) { - uint tmp=my_strnxfrm(default_charset_info, - (unsigned char *)to, (unsigned char *) ptr, - length, field_length); + if (use_strcoll(field_charset)) { + uint tmp=my_strnxfrm(field_charset, + (unsigned char *)to, length, + (unsigned char *) ptr, field_length); if (tmp < length) bzero(to + tmp, length - tmp); } else #endif for (char *from=ptr,*end=ptr+length ; from != end ;) - *to++=(char) my_sort_order[(uint) (uchar) *from++]; + *to++=(char) field_charset->sort_order[(uint) (uchar) *from++]; } } @@ -3446,7 +3451,7 @@ int Field_string::pack_cmp(const char *a, const char *b, uint length) int cmp= memcmp(a,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(a,a_length, b,b_length); + return my_sortncmp(field_charset, a,a_length, b,b_length); } @@ -3463,7 +3468,7 @@ int Field_string::pack_cmp(const char *b, uint length) int cmp= memcmp(ptr,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(ptr,a_length, b, b_length); + return my_sortncmp(field_charset, ptr,a_length, b, b_length); } @@ -3568,7 +3573,7 @@ int Field_varstring::cmp(const char *a_ptr, const char *b_ptr) if (binary_flag) diff=memcmp(a_ptr+2,b_ptr+2,min(a_length,b_length)); else - diff=my_sortcmp(a_ptr+2,b_ptr+2,min(a_length,b_length)); + diff=my_sortcmp(field_charset, a_ptr+2,b_ptr+2,min(a_length,b_length)); return diff ? diff : (int) (a_length - b_length); } @@ -3580,10 +3585,10 @@ void Field_varstring::sort_string(char *to,uint length) else { #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info)) - tot_length=my_strnxfrm(default_charset_info, - (unsigned char *) to, (unsigned char *)ptr+2, - length, tot_length); + if (use_strcoll(field_charset)) + tot_length=my_strnxfrm(field_charset, + (unsigned char *) to, length, + (unsigned char *)ptr+2, tot_length); else { #endif @@ -3591,7 +3596,7 @@ void Field_varstring::sort_string(char *to,uint length) if (tot_length > length) tot_length=length; for (char *from=ptr+2,*end=from+tot_length ; from != end ;) - *tmp++=(char) my_sort_order[(uint) (uchar) *from++]; + *tmp++=(char) field_charset->sort_order[(uint) (uchar) *from++]; #ifdef USE_STRCOLL } #endif @@ -3662,7 +3667,7 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length) int cmp= memcmp(a,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(a,a_length, b,b_length); + return my_sortncmp(field_charset, a,a_length, b,b_length); } int Field_varstring::pack_cmp(const char *b, uint key_length) @@ -3683,7 +3688,7 @@ int Field_varstring::pack_cmp(const char *b, uint key_length) int cmp= memcmp(a,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(a,a_length, b,b_length); + return my_sortncmp(field_charset, a,a_length, b,b_length); } uint Field_varstring::packed_col_length(const char *ptr, uint length) @@ -3906,7 +3911,7 @@ int Field_blob::cmp(const char *a,uint32 a_length, const char *b, if (binary_flag) diff=memcmp(a,b,min(a_length,b_length)); else - diff=my_sortcmp(a,b,min(a_length,b_length)); + diff=my_sortcmp(field_charset, a,b,min(a_length,b_length)); return diff ? diff : (int) (a_length - b_length); } @@ -4063,11 +4068,11 @@ void Field_blob::sort_string(char *to,uint length) else { #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info)) + if (use_strcoll(field_charset)) { - blob_length=my_strnxfrm(default_charset_info, - (unsigned char *)to,(unsigned char *)blob, - length,blob_org_length); + blob_length=my_strnxfrm(field_charset, + (unsigned char *)to, length, + (unsigned char *)blob, blob_org_length); if (blob_length >= length) return; to+=blob_length; @@ -4075,7 +4080,7 @@ void Field_blob::sort_string(char *to,uint length) else #endif for (char *end=blob+blob_length ; blob != end ;) - *to++=(char) my_sort_order[(uint) (uchar) *blob++]; + *to++=(char) field_charset->sort_order[(uint) (uchar) *blob++]; } bzero(to,length-blob_length); } @@ -4153,7 +4158,7 @@ int Field_blob::pack_cmp(const char *a, const char *b, uint key_length) int cmp= memcmp(a,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(a,a_length, b,b_length); + return my_sortncmp(field_charset, a,a_length, b,b_length); } @@ -4179,7 +4184,7 @@ int Field_blob::pack_cmp(const char *b, uint key_length) int cmp= memcmp(a,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(a,a_length, b,b_length); + return my_sortncmp(field_charset, a,a_length, b,b_length); } /* Create a packed key that will be used for storage from a MySQL row */ @@ -4290,14 +4295,16 @@ void Field_enum::store_type(ulonglong value) uint find_enum(TYPELIB *lib,const char *x, uint length) { const char *end=x+length; - while (end > x && isspace(end[-1])) + while (end > x && my_isspace(system_charset_info,end[-1])) end--; const char *i; const char *j; for (uint pos=0 ; (j=lib->type_names[pos]) ; pos++) { - for (i=x ; i != end && toupper(*i) == toupper(*j) ; i++, j++) ; + for (i=x ; i != end && + my_toupper(system_charset_info,*i) == + my_toupper(system_charset_info,*j) ; i++, j++) ; if (i == end && ! *j) return(pos+1); } @@ -4474,7 +4481,7 @@ void Field_enum::sql_type(String &res) const ulonglong find_set(TYPELIB *lib,const char *x,uint length) { const char *end=x+length; - while (end > x && isspace(end[-1])) + while (end > x && my_isspace(system_charset_info, end[-1])) end--; ulonglong found=0; @@ -4600,7 +4607,8 @@ bool Field_enum::eq_def(Field *field) if (typelib->count < from_lib->count) return 0; for (uint i=0 ; i < from_lib->count ; i++) - if (my_strcasecmp(typelib->type_names[i],from_lib->type_names[i])) + if (my_strcasecmp(field_charset, + typelib->type_names[i],from_lib->type_names[i])) return 0; return 1; } diff --git a/sql/field.h b/sql/field.h index 422e91768e6..cd1697fcf44 100644 --- a/sql/field.h +++ b/sql/field.h @@ -145,12 +145,7 @@ public: virtual void set_key_image(char *buff,uint length) { set_image(buff,length); } inline int cmp_image(char *buff,uint length) - { - if (binary()) - return memcmp(ptr,buff,length); - else - return my_casecmp(ptr,buff,length); - } + { return memcmp(ptr,buff,length); } inline longlong val_int_offset(uint row_offset) { ptr+=row_offset; @@ -241,6 +236,8 @@ public: class Field_str :public Field { +protected: + CHARSET_INFO *field_charset; public: Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, @@ -248,12 +245,20 @@ public: struct st_table *table_arg) :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg) - {} + { field_charset=default_charset_info; } Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } friend class create_field; void make_field(Send_field *); uint size_of() const { return sizeof(*this); } + inline int cmp_image(char *buff,uint length) + { + if (binary()) + return memcmp(ptr,buff,length); + else + return my_strncasecmp(field_charset,ptr,buff,length); + } + }; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index c7a6d778953..02be0365002 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -276,7 +276,7 @@ static void do_cut_string(Copy_field *copy) ptr != end ; ptr++) { - if (!isspace(*ptr)) + if (!my_isspace(system_charset_info, *ptr)) { current_thd->cuted_fields++; // Give a warning break; diff --git a/sql/filesort.cc b/sql/filesort.cc index a5f42d5731e..675cc294de4 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -513,9 +513,8 @@ static void make_sortkey(register SORTPARAM *param, from=param->tmp_buffer; } uint tmp_length=my_strnxfrm(default_charset_info, - to,(unsigned char *) from, - sort_field->length, - length); + to,sort_field->length, + (unsigned char *) from, length); if (tmp_length < sort_field->length) bzero((char*) to+tmp_length,sort_field->length-tmp_length); } @@ -527,7 +526,7 @@ static void make_sortkey(register SORTPARAM *param, memcpy(to,res->ptr(),length); bzero((char *)to+length,diff); if (!item->binary) - case_sort((char*) to,length); + case_sort(default_charset_info, (char*) to,length); #ifdef USE_STRCOLL } #endif @@ -925,7 +924,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length) sortorder->length=sortorder->field->pack_length(); #ifdef USE_STRCOLL if (use_strcoll(default_charset_info) && !sortorder->field->binary()) - sortorder->length= sortorder->length*MY_STRXFRM_MULTIPLY; + sortorder->length= sortorder->length*default_charset_info->strxfrm_multiply; #endif } if (sortorder->field->maybe_null()) @@ -938,7 +937,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length) sortorder->length=sortorder->item->max_length; #ifdef USE_STRCOLL if (use_strcoll(default_charset_info) && !sortorder->item->binary) - sortorder->length= sortorder->length*MY_STRXFRM_MULTIPLY; + sortorder->length= sortorder->length*default_charset_info->strxfrm_multiply; #endif break; case INT_RESULT: diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 4cf06dfb731..d53b027a415 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1194,7 +1194,10 @@ innobase_mysql_cmp( case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: - ret = my_sortncmp((const char*) a, a_length, + // BAR TODO: Discuss with heikki.tuuri@innodb.com + // so that he sends CHARSET_INFO for the field to this function. + ret = my_sortncmp(default_charset_info, + (const char*) a, a_length, (const char*) b, b_length); if (ret < 0) { return(-1); diff --git a/sql/hostname.cc b/sql/hostname.cc index 7d4e4a8ca75..0b35f970c42 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -213,10 +213,10 @@ my_string ip_to_hostname(struct in_addr *in, uint *errors) /* Don't accept hostnames that starts with digits because they may be false ip:s */ - if (isdigit(name[0])) + if (my_isdigit(system_charset_info,name[0])) { char *pos; - for (pos= name+1 ; isdigit(*pos); pos++) ; + for (pos= name+1 ; my_isdigit(system_charset_info,*pos); pos++) ; if (*pos == '.') { DBUG_PRINT("error",("mysqld doesn't accept hostnames that starts with a number followed by a '.'")); diff --git a/sql/init.cc b/sql/init.cc index df06ddd41ef..fe80c282563 100644 --- a/sql/init.cc +++ b/sql/init.cc @@ -24,6 +24,7 @@ void unireg_init(ulong options) { uint i; double nr; + CHARSET_INFO *cs; DBUG_ENTER("unireg_init"); MYSYS_PROGRAM_DONT_USE_CURSES(); @@ -54,13 +55,16 @@ void unireg_init(ulong options) // The following is needed because of like optimization in select.cc - uchar max_char=my_sort_order[(uchar) max_sort_char]; - for (i = 0; i < 256; i++) + for (cs=compiled_charsets; cs->number; cs++) { - if ((uchar) my_sort_order[i] > max_char) + uchar max_char=cs->sort_order[(uchar) cs->max_sort_char]; + for (i = 0; i < 256; i++) { - max_char=(uchar) my_sort_order[i]; - max_sort_char= (char) i; + if ((uchar) cs->sort_order[i] > max_char) + { + max_char=(uchar) cs->sort_order[i]; + cs->max_sort_char= (char) i; + } } } thread_stack_min=thread_stack - STACK_MIN_SIZE; diff --git a/sql/item.cc b/sql/item.cc index c081fd9dd5f..0c241684474 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -50,7 +50,7 @@ void Item::set_name(char *str,uint length) name=str; // Used by AS else { - while (length && !isgraph(*str)) + while (length && !my_isgraph(system_charset_info,*str)) { // Fix problem with yacc length--; str++; @@ -62,7 +62,7 @@ void Item::set_name(char *str,uint length) bool Item::eq(const Item *item) const // Only doing this on conds { return type() == item->type() && name && item->name && - !my_strcasecmp(name,item->name); + !my_strcasecmp(system_charset_info,name,item->name); } /* diff --git a/sql/item_func.cc b/sql/item_func.cc index 65d4413b484..09e3aab08c6 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -991,7 +991,8 @@ longlong Item_func_find_in_set::val_int() const char *pos= f_pos; while (pos != f_end) { - if (toupper(*str) != toupper(*pos)) + if (my_toupper(find->charset(),*str) != + my_toupper(find->charset(),*pos)) goto not_found; str++; pos++; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index cdf909e8c4d..de07f5b1ee7 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -42,7 +42,7 @@ uint nr_of_decimals(const char *str) if ((str=strchr(str,'.'))) { const char *start= ++str; - for ( ; isdigit(*str) ; str++) ; + for ( ; my_isdigit(system_charset_info,*str) ; str++) ; return (uint) (str-start); } return 0; @@ -1268,9 +1268,9 @@ extern "C" { extern const char *soundex_map; // In mysys/static.c } -static char get_scode(char *ptr) +static char get_scode(CHARSET_INFO *cs,char *ptr) { - uchar ch=toupper(*ptr); + uchar ch=my_toupper(cs,*ptr); if (ch < 'A' || ch > 'Z') { // Thread extended alfa (country spec) @@ -1292,21 +1292,21 @@ String *Item_func_soundex::val_str(String *str) char *to= (char *) tmp_value.ptr(); char *from= (char *) res->ptr(), *end=from+res->length(); - while (from != end && isspace(*from)) // Skip pre-space + while (from != end && my_isspace(str->charset(),*from)) // Skip pre-space from++; /* purecov: inspected */ if (from == end) return &empty_string; // No alpha characters. - *to++ = toupper(*from); // Copy first letter - last_ch = get_scode(from); // code of the first letter + *to++ = my_toupper(str->charset(),*from);// Copy first letter + last_ch = get_scode(str->charset(),from);// code of the first letter // for the first 'double-letter check. // Loop on input letters until // end of input (null) or output // letter code count = 3 for (from++ ; from < end ; from++) { - if (!isalpha(*from)) + if (!my_isalpha(str->charset(),*from)) continue; - ch=get_scode(from); + ch=get_scode(str->charset(),from); if ((ch != '0') && (ch != last_ch)) // if not skipped or double { *to++ = ch; // letter, copy to output diff --git a/sql/item_sum.cc b/sql/item_sum.cc index e8f16e3ed56..7ebeda19993 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -864,7 +864,8 @@ static int simple_raw_key_cmp(void* arg, byte* key1, byte* key2) static int simple_str_key_cmp(void* arg, byte* key1, byte* key2) { - return my_sortcmp((char*) key1, (char*) key2, *(uint*) arg); + /* BAR TODO: remove default_charset_info */ + return my_sortcmp(default_charset_info,(char*) key1, (char*) key2, *(uint*) arg); } /* diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 8f55a02b020..b10054e11d2 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -49,16 +49,16 @@ bool get_interval_info(const char *str,uint length,uint count, { const char *end=str+length; uint i; - while (str != end && !isdigit(*str)) + while (str != end && !my_isdigit(system_charset_info,*str)) str++; for (i=0 ; i < count ; i++) { long value; - for (value=0; str != end && isdigit(*str) ; str++) + for (value=0; str != end && my_isdigit(system_charset_info,*str) ; str++) value=value*10L + (long) (*str - '0'); values[i]= value; - while (str != end && !isdigit(*str)) + while (str != end && !my_isdigit(system_charset_info,*str)) str++; if (str == end && i != count-1) { @@ -289,7 +289,7 @@ static bool get_interval_value(Item *args,interval_type int_type, /* record negative intervalls in t->neg */ str=res->ptr(); const char *end=str+res->length(); - while (str != end && isspace(*str)) + while (str != end && my_isspace(system_charset_info,*str)) str++; if (str != end && *str == '-') { diff --git a/sql/key.cc b/sql/key.cc index d2f483e3d73..a5d3d0a65b9 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -192,8 +192,9 @@ int key_cmp(TABLE *table,const byte *key,uint idx,uint key_length) if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+ FIELDFLAG_PACK))) { - if (my_sortcmp((char*) key,(char*) table->record[0]+key_part->offset, - length)) + /* BAR TODO: I'm not sure this should be system_charset_info */ + if (my_sortcmp(system_charset_info,(char*) key, + (char*) table->record[0]+key_part->offset,length)) return 1; } else if (memcmp(key,table->record[0]+key_part->offset,length)) diff --git a/sql/log.cc b/sql/log.cc index 892780d3882..1a315ea9f9c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1208,7 +1208,7 @@ static bool test_if_number(register const char *str, while (*str++ == ' ') ; if (*--str == '-' || *str == '+') str++; - while (isdigit(*str) || (allow_wildcards && + while (my_isdigit(system_charset_info,*str) || (allow_wildcards && (*str == wild_many || *str == wild_one))) { flag=1; @@ -1217,7 +1217,7 @@ static bool test_if_number(register const char *str, if (*str == '.') { for (str++ ; - isdigit(*str) || + my_isdigit(system_charset_info,*str) || (allow_wildcards && (*str == wild_many || *str == wild_one)) ; str++, flag=1) ; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 924f85b0a89..728d6d7a35f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -549,7 +549,7 @@ void open_log(MYSQL_LOG *log, const char *hostname, extern uint32 server_id; extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], - max_sort_char, mysql_real_data_home[]; + mysql_real_data_home[]; extern my_string mysql_tmpdir; extern const char *first_keyword, *localhost, *delayed_user; extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables, @@ -708,10 +708,10 @@ bool check_db_name(const char *db); bool check_column_name(const char *name); bool check_table_name(const char *name, uint length); char *get_field(MEM_ROOT *mem,TABLE *table,uint fieldnr); -int wild_case_compare(const char *str,const char *wildstr); +int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr); int wild_compare(const char *str,const char *str_end, const char *wildstr,const char *wildend,char escape); -int wild_case_compare(const char *str,const char *str_end, +int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end, const char *wildstr,const char *wildend,char escape); /* from hostname.cc */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5e4fc654320..40b9ab24831 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -863,7 +863,7 @@ static void set_user(const char *user) { // allow a numeric uid to be used const char *pos; - for (pos=user; isdigit(*pos); pos++) ; + for (pos=user; my_isdigit(system_charset_info,*pos); pos++) ; if (*pos) // Not numeric id { fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user); @@ -3769,7 +3769,7 @@ static void get_options(int argc,char **argv) exit(1); } val = p--; - while(isspace(*p) && p > optarg) *p-- = 0; + while(my_isspace(system_charset_info,*p) && p > optarg) *p-- = 0; if(p == optarg) { fprintf(stderr, @@ -3778,7 +3778,7 @@ static void get_options(int argc,char **argv) } *val = 0; val += 2; - while(*val && isspace(*val)) *val++; + while(*val && my_isspace(system_charset_info,*val)) *val++; if (!*val) { fprintf(stderr, @@ -3937,7 +3937,7 @@ static void get_options(int argc,char **argv) have_symlink=SHOW_OPTION_DISABLED; break; case (int) OPT_BIND_ADDRESS: - if (optarg && isdigit(optarg[0])) + if (optarg && my_isdigit(system_charset_info,optarg[0])) { my_bind_addr = (ulong) inet_addr(optarg); } @@ -4409,7 +4409,8 @@ static ulong find_bit_type(const char *x, TYPELIB *bit_lib) j=pos; while (j != end) { - if (toupper(*i++) != toupper(*j++)) + if (my_toupper(system_charset_info,*i++) != + my_toupper(system_charset_info,*j++)) goto skipp; } found_int=bit; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 34ee34ecc79..8bd47913b7b 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -985,7 +985,8 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, like_error=like_range(res->ptr(),res->length(),wild_prefix, field_length, min_str+offset,max_str+offset, - max_sort_char,&min_length,&max_length); + default_charset_info->max_sort_char, + &min_length,&max_length); } if (like_error) // Can't optimize with LIKE DBUG_RETURN(0); diff --git a/sql/procedure.cc b/sql/procedure.cc index 437bd82d6e5..7779f5ce085 100644 --- a/sql/procedure.cc +++ b/sql/procedure.cc @@ -57,7 +57,8 @@ setup_procedure(THD *thd,ORDER *param,select_result *result, DBUG_RETURN(0); for (i=0 ; i < array_elements(sql_procs) ; i++) { - if (!my_strcasecmp((*param->item)->name,sql_procs[i].name)) + if (!my_strcasecmp(system_charset_info, + (*param->item)->name,sql_procs[i].name)) { Procedure *proc=(*sql_procs[i].init)(thd,param,result,field_list); *error= !proc; diff --git a/sql/slave.cc b/sql/slave.cc index 100e305530f..9630cf6aa0e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -237,9 +237,9 @@ void init_slave_skip_errors(char* arg) exit(1); } use_slave_mask = 1; - for (;isspace(*arg);++arg) + for (;my_isspace(system_charset_info,*arg);++arg) /* empty */; - if (!my_casecmp(arg,"all",3)) + if (!my_strncasecmp(system_charset_info,arg,"all",3)) { bitmap_set_all(&slave_error_mask); return; @@ -251,7 +251,7 @@ void init_slave_skip_errors(char* arg) break; if (err_code < MAX_SLAVE_ERROR) bitmap_set_bit(&slave_error_mask,(uint)err_code); - while (!isdigit(*p) && *p) + while (!my_isdigit(system_charset_info,*p) && *p) p++; } } @@ -492,7 +492,8 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len) { TABLE_RULE_ENT* e ; get_dynamic(a, (gptr)&e, i); - if (!wild_case_compare(key, key_end, (const char*)e->db, + if (!wild_case_compare(system_charset_info, key, key_end, + (const char*)e->db, (const char*)(e->db + e->key_len),'\\')) return e; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index c5782f65798..198569cec3c 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -381,7 +381,7 @@ static uint get_access(TABLE *form,uint fieldnr) for (pos=form->field+fieldnr,bit=1 ; *pos ; pos++ , bit<<=1) { (*pos)->val_str(&res,&res); - if (toupper(res[0]) == 'Y') + if (my_toupper(system_charset_info, res[0]) == 'Y') access_bits|=bit; } return access_bits; @@ -729,7 +729,7 @@ uint acl_get(const char *host, const char *ip, const char *bin_ip, end=strmov((tmp_db=strmov(key+sizeof(struct in_addr),user)+1),db); if (lower_case_table_names) { - casedn_str(tmp_db); + my_casedn_str(system_charset_info, tmp_db); db=tmp_db; } key_length=(uint) (end-key); @@ -793,7 +793,7 @@ exit: } -int wild_case_compare(const char *str,const char *wildstr) +int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) { reg3 int flag; DBUG_ENTER("wild_case_compare"); @@ -804,7 +804,8 @@ int wild_case_compare(const char *str,const char *wildstr) { if (*wildstr == wild_prefix && wildstr[1]) wildstr++; - if (toupper(*wildstr++) != toupper(*str++)) DBUG_RETURN(1); + if (my_toupper(cs, *wildstr++) != + my_toupper(cs, *str++)) DBUG_RETURN(1); } if (! *wildstr ) DBUG_RETURN (*str != 0); if (*wildstr++ == wild_one) @@ -822,12 +823,12 @@ int wild_case_compare(const char *str,const char *wildstr) char cmp; if ((cmp= *wildstr) == wild_prefix && wildstr[1]) cmp=wildstr[1]; - cmp=toupper(cmp); - while (*str && toupper(*str) != cmp) + cmp=my_toupper(cs, cmp); + while (*str && my_toupper(cs, *str) != cmp) str++; if (!*str) DBUG_RETURN (1); } - if (wild_case_compare(str,wildstr) == 0) DBUG_RETURN (0); + if (wild_case_compare(cs, str,wildstr) == 0) DBUG_RETURN (0); } while (*str++); DBUG_RETURN(1); } @@ -862,7 +863,8 @@ static void init_check_host(void) { // Check if host already exists acl_host_and_ip *acl=dynamic_element(&acl_wild_hosts,j, acl_host_and_ip *); - if (!my_strcasecmp(acl_user->host.hostname,acl->hostname)) + if (!my_strcasecmp(system_charset_info, + acl_user->host.hostname, acl->hostname)) break; // already stored } if (j == acl_wild_hosts.elements) // If new @@ -940,7 +942,8 @@ bool change_password(THD *thd, const char *host, const char *user, new_password[length & 16]=0; if (!thd || (!thd->slave_thread && ( strcmp(thd->user,user) || - my_strcasecmp(host,thd->host ? thd->host : thd->ip)))) + my_strcasecmp(system_charset_info, + host, (thd->host ? thd->host : thd->ip))))) { if (check_access(thd, UPDATE_ACL, "mysql",0,1)) DBUG_RETURN(1); @@ -1061,7 +1064,8 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, return (tmp & host->ip_mask) == host->ip; } return (!host->hostname || - (hostname && !wild_case_compare(hostname,host->hostname)) || + (hostname && !wild_case_compare(system_charset_info, + hostname,host->hostname)) || (ip && !wild_compare(ip,host->hostname))); } @@ -1414,8 +1418,8 @@ public: tname= strdup_root(&memex,t); if (lower_case_table_names) { - casedn_str(db); - casedn_str(tname); + my_casedn_str(system_charset_info, db); + my_casedn_str(system_charset_info, tname); } key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3; hash_key = (char*) alloc_root(&memex,key_length); @@ -1440,8 +1444,8 @@ public: } if (lower_case_table_names) { - casedn_str(db); - casedn_str(tname); + my_casedn_str(system_charset_info, db); + my_casedn_str(system_charset_info, tname); } key_length = ((uint) strlen(db) + (uint) strlen(user) + (uint) strlen(tname) + 3); @@ -1534,8 +1538,10 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, } else { - if ((host && !wild_case_compare(host,grant_table->host)) || - (ip && !wild_case_compare(ip,grant_table->host))) + if ((host && !wild_case_compare(system_charset_info, + host,grant_table->host)) || + (ip && !wild_case_compare(system_charset_info, + ip,grant_table->host))) found=grant_table; // Host ok } } @@ -2051,7 +2057,7 @@ int mysql_grant (THD *thd, const char *db, List &list, uint rights, if (lower_case_table_names && db) { strmov(tmp_db,db); - casedn_str(tmp_db); + my_casedn_str(system_charset_info, tmp_db); db=tmp_db; } @@ -2476,8 +2482,10 @@ bool check_grant_db(THD *thd,const char *db) GRANT_TABLE *grant_table = (GRANT_TABLE*) hash_element(&hash_tables,idx); if (len < grant_table->key_length && !memcmp(grant_table->hash_key,helping,len) && - (thd->host && !wild_case_compare(thd->host,grant_table->host) || - (thd->ip && !wild_case_compare(thd->ip,grant_table->host)))) + (thd->host && !wild_case_compare(system_charset_info, + thd->host,grant_table->host) || + (thd->ip && !wild_case_compare(system_charset_info, + thd->ip,grant_table->host)))) { error=0; // Found match break; diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index df8a8f1fdde..fc764333916 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -163,7 +163,7 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len) // MySQL removes any endspaces of a string, so we must take care only of // spaces in front of a string - for (; str != end && isspace(*str); str++) ; + for (; str != end && my_isspace(system_charset_info, *str); str++) ; if (str == end) return 0; @@ -176,10 +176,10 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len) else info->negative = 0; begin = str; - for (; str != end && isdigit(*str); str++) + for (; str != end && my_isdigit(system_charset_info,*str); str++) { if (!info->integers && *str == '0' && (str + 1) != end && - isdigit(*(str + 1))) + my_isdigit(system_charset_info,*(str + 1))) info->zerofill = 1; // could be a postnumber for example info->integers++; } @@ -205,7 +205,7 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len) str++; if (*str != '-' && *str != '+') return 0; - for (str++; str != end && isdigit(*str); str++) ; + for (str++; str != end && my_isdigit(system_charset_info,*str); str++) ; if (str == end) { info->is_float = 1; // we can't use variable decimals here @@ -220,7 +220,7 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len) info->ullval = (ulonglong) strtoull(begin, NULL, 10); return 1; } - for (; str != end && isdigit(*str); str++) + for (; str != end && my_isdigit(system_charset_info,*str); str++) info->decimals++; if (str == end) { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index f4a70db2e5d..e73a0c63fa6 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -50,7 +50,8 @@ static byte *cache_key(const byte *record,uint *length, void table_cache_init(void) { - VOID(hash_init(&open_cache,table_cache_size+16,0,0,cache_key, + VOID(hash_init(&open_cache, + table_cache_size+16,0,0,cache_key, (void (*)(void*)) free_cache_entry,0)); mysql_rm_tmp_tables(); } @@ -780,7 +781,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, { if (table->key_length == key_length && !memcmp(table->table_cache_key,key,key_length) && - !my_strcasecmp(table->table_name,alias)) + !my_strcasecmp(system_charset_info,table->table_name,alias)) goto reset; } my_printf_error(ER_TABLE_NOT_LOCKED,ER(ER_TABLE_NOT_LOCKED),MYF(0),alias); @@ -1559,11 +1560,12 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, Field **ptr=table->field; while ((field = *ptr++)) { - if (!my_strcasecmp(field->field_name, name)) + if (!my_strcasecmp(system_charset_info, field->field_name, name)) goto found; } } - if (allow_rowid && !my_strcasecmp(name,"_rowid") && + if (allow_rowid && + !my_strcasecmp(system_charset_info, name, "_rowid") && (field=table->rowid_field)) goto found; return (Field*) 0; @@ -1686,7 +1688,8 @@ find_item_in_list(Item *find,List &items) { if (field_name && item->type() == Item::FIELD_ITEM) { - if (!my_strcasecmp(((Item_field*) item)->name,field_name)) + if (!my_strcasecmp(system_charset_info, + ((Item_field*) item)->name,field_name)) { if (!table_name) { @@ -1709,8 +1712,9 @@ find_item_in_list(Item *find,List &items) } } else if (!table_name && (item->eq(find) || - find->name && - !my_strcasecmp(item->name,find->name))) + find->name && + !my_strcasecmp(system_charset_info, + item->name,find->name))) { found=li.ref(); break; @@ -1938,7 +1942,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) // TODO: This could be optimized to use hashed names if t2 had a hash for (j=0 ; j < t2->fields ; j++) { - if (!my_strcasecmp(t1->field[i]->field_name, + if (!my_strcasecmp(system_charset_info, + t1->field[i]->field_name, t2->field[j]->field_name)) { Item_func_eq *tmp=new Item_func_eq(new Item_field(t1->field[i]), diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index c5ebeead05a..72ac20d8818 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -896,8 +896,9 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) Test if the query is a SELECT (pre-space is removed in dispatch_command) */ - if (toupper(sql[0]) != 'S' || toupper(sql[1]) != 'E' || - toupper(sql[2]) !='L') + if (my_toupper(system_charset_info, sql[0]) != 'S' || + my_toupper(system_charset_info, sql[1]) != 'E' || + my_toupper(system_charset_info,sql[2]) !='L') { DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached")); goto err; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index dd8ed634011..30e7262cae0 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -218,7 +218,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, DBUG_PRINT("info",("Examining: %s", file->name)); /* Check if file is a raid directory */ - if (isdigit(file->name[0]) && isdigit(file->name[1]) && + if (my_isdigit(system_charset_info,file->name[0]) && + my_isdigit(system_charset_info,file->name[1]) && !file->name[2] && !level) { char newpath[FN_REFLEN]; @@ -243,7 +244,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, continue; } strxmov(filePath,org_path,"/",file->name,NullS); - if (db && !my_strcasecmp(fn_ext(file->name), reg_ext)) + if (db && !my_strcasecmp(system_charset_info, + fn_ext(file->name), reg_ext)) { /* Drop the table nicely */ *fn_ext(file->name)=0; // Remove extension diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 8f9d3474ce2..f4d6f3416a6 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -270,7 +270,7 @@ static TABLE **find_table_ptr_by_name(THD *thd, const char *db, for (TABLE *table=*ptr; table ; table=*ptr) { if (!memcmp(table->table_cache_key, db, dblen) && - !my_strcasecmp(table->table_name,table_name)) + !my_strcasecmp(system_charset_info,table->table_name,table_name)) break; ptr=&(table->next); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7995e7701e5..9371eb00b79 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -92,15 +92,15 @@ void lex_init(void) /* Fill state_map with states to get a faster parser */ for (i=0; i < 256 ; i++) { - if (isalpha(i)) + if (my_isalpha(system_charset_info,i)) state_map[i]=(uchar) STATE_IDENT; - else if (isdigit(i)) + else if (my_isdigit(system_charset_info,i)) state_map[i]=(uchar) STATE_NUMBER_IDENT; #if defined(USE_MB) && defined(USE_MB_IDENT) - else if (use_mb(default_charset_info) && my_ismbhead(default_charset_info, i)) + else if (use_mb(system_charset_info) && my_ismbhead(system_charset_info, i)) state_map[i]=(uchar) STATE_IDENT; #endif - else if (!isgraph(i)) + else if (!my_isgraph(system_charset_info,i)) state_map[i]=(uchar) STATE_SKIP; else state_map[i]=(uchar) STATE_CHAR; @@ -220,8 +220,8 @@ static char *get_text(LEX *lex) c = yyGet(); #ifdef USE_MB int l; - if (use_mb(default_charset_info) && - (l = my_ismbchar(default_charset_info, + if (use_mb(system_charset_info) && + (l = my_ismbchar(system_charset_info, (const char *)lex->ptr-1, (const char *)lex->end_of_query))) { lex->ptr += l-1; @@ -265,8 +265,8 @@ static char *get_text(LEX *lex) { #ifdef USE_MB int l; - if (use_mb(default_charset_info) && - (l = my_ismbchar(default_charset_info, + if (use_mb(system_charset_info) && + (l = my_ismbchar(system_charset_info, (const char *)str, (const char *)end))) { while (l--) *to++ = *str++; @@ -471,11 +471,11 @@ int yylex(void *arg) break; } #if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(default_charset_info)) + if (use_mb(system_charset_info)) { - if (my_ismbhead(default_charset_info, yyGetLast())) + if (my_ismbhead(system_charset_info, yyGetLast())) { - int l = my_ismbchar(default_charset_info, + int l = my_ismbchar(system_charset_info, (const char *)lex->ptr-1, (const char *)lex->end_of_query); if (l == 0) { @@ -487,10 +487,10 @@ int yylex(void *arg) while (state_map[c=yyGet()] == STATE_IDENT || state_map[c] == STATE_NUMBER_IDENT) { - if (my_ismbhead(default_charset_info, c)) + if (my_ismbhead(system_charset_info, c)) { int l; - if ((l = my_ismbchar(default_charset_info, + if ((l = my_ismbchar(system_charset_info, (const char *)lex->ptr-1, (const char *)lex->end_of_query)) == 0) break; @@ -533,7 +533,7 @@ int yylex(void *arg) return((int) c); case STATE_NUMBER_IDENT: // number or ident which num-start - while (isdigit((c = yyGet()))) ; + while (my_isdigit(system_charset_info,(c = yyGet()))) ; if (state_map[c] != STATE_IDENT) { // Can't be identifier state=STATE_INT_OR_REAL; @@ -542,12 +542,13 @@ int yylex(void *arg) if (c == 'e' || c == 'E') { // The following test is written this way to allow numbers of type 1e1 - if (isdigit(yyPeek()) || (c=(yyGet())) == '+' || c == '-') + if (my_isdigit(system_charset_info,yyPeek()) || + (c=(yyGet())) == '+' || c == '-') { // Allow 1E+10 - if (isdigit(yyPeek())) // Number must have digit after sign + if (my_isdigit(system_charset_info,yyPeek())) // Number must have digit after sign { yySkip(); - while (isdigit(yyGet())) ; + while (my_isdigit(system_charset_info,yyGet())) ; yylval->lex_str=get_token(lex,yyLength()); return(FLOAT_NUM); } @@ -557,7 +558,7 @@ int yylex(void *arg) else if (c == 'x' && (lex->ptr - lex->tok_start) == 2 && lex->tok_start[0] == '0' ) { // Varbinary - while (isxdigit((c = yyGet()))) ; + while (my_isxdigit(system_charset_info,(c = yyGet()))) ; if ((lex->ptr - lex->tok_start) >= 4 && state_map[c] != STATE_IDENT) { yylval->lex_str=get_token(lex,yyLength()); @@ -571,11 +572,11 @@ int yylex(void *arg) // fall through case STATE_IDENT_START: // Incomplete ident #if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(default_charset_info)) + if (use_mb(system_charset_info)) { - if (my_ismbhead(default_charset_info, yyGetLast())) + if (my_ismbhead(system_charset_info, yyGetLast())) { - int l = my_ismbchar(default_charset_info, + int l = my_ismbchar(system_charset_info, (const char *)lex->ptr-1, (const char *)lex->end_of_query); if (l == 0) @@ -588,10 +589,10 @@ int yylex(void *arg) while (state_map[c=yyGet()] == STATE_IDENT || state_map[c] == STATE_NUMBER_IDENT) { - if (my_ismbhead(default_charset_info, c)) + if (my_ismbhead(system_charset_info, c)) { int l; - if ((l = my_ismbchar(default_charset_info, + if ((l = my_ismbchar(system_charset_info, (const char *)lex->ptr-1, (const char *)lex->end_of_query)) == 0) break; @@ -618,15 +619,15 @@ int yylex(void *arg) case STATE_USER_VARIABLE_DELIMITER: lex->tok_start=lex->ptr; // Skip first ` #ifdef USE_MB - if (use_mb(default_charset_info)) + if (use_mb(system_charset_info)) { while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER && c != (uchar) NAMES_SEP_CHAR) { - if (my_ismbhead(default_charset_info, c)) + if (my_ismbhead(system_charset_info, c)) { int l; - if ((l = my_ismbchar(default_charset_info, + if ((l = my_ismbchar(system_charset_info, (const char *)lex->ptr-1, (const char *)lex->end_of_query)) == 0) break; @@ -651,17 +652,18 @@ int yylex(void *arg) if (prev_state == STATE_OPERATOR_OR_IDENT) { if (c == '-' && yyPeek() == '-' && - (isspace(yyPeek2()) || iscntrl(yyPeek2()))) + (my_isspace(system_charset_info,yyPeek2()) || + my_iscntrl(system_charset_info,yyPeek2()))) state=STATE_COMMENT; else state= STATE_CHAR; // Must be operator break; } - if (!isdigit(c=yyGet()) || yyPeek() == 'x') + if (!my_isdigit(system_charset_info,c=yyGet()) || yyPeek() == 'x') { if (c != '.') { - if (c == '-' && isspace(yyPeek())) + if (c == '-' && my_isspace(system_charset_info,yyPeek())) state=STATE_COMMENT; else state = STATE_CHAR; // Return sign as single char @@ -669,9 +671,9 @@ int yylex(void *arg) } yyUnget(); // Fix for next loop } - while (isdigit(c=yyGet())) ; // Incomplete real or int number + while (my_isdigit(system_charset_info,c=yyGet())) ; // Incomplete real or int number if ((c == 'e' || c == 'E') && - (yyPeek() == '+' || yyPeek() == '-' || isdigit(yyPeek()))) + (yyPeek() == '+' || yyPeek() == '-' || my_isdigit(system_charset_info,yyPeek()))) { // Real number yyUnget(); c= '.'; // Fool next test @@ -685,19 +687,19 @@ int yylex(void *arg) } // fall through case STATE_REAL: // Incomplete real number - while (isdigit(c = yyGet())) ; + while (my_isdigit(system_charset_info,c = yyGet())) ; if (c == 'e' || c == 'E') { c = yyGet(); if (c == '-' || c == '+') c = yyGet(); // Skip sign - if (!isdigit(c)) + if (!my_isdigit(system_charset_info,c)) { // No digit after sign state= STATE_CHAR; break; } - while (isdigit(yyGet())) ; + while (my_isdigit(system_charset_info,yyGet())) ; yylval->lex_str=get_token(lex,yyLength()); return(FLOAT_NUM); } @@ -706,7 +708,7 @@ int yylex(void *arg) case STATE_HEX_NUMBER: // Found x'hexstring' yyGet(); // Skip ' - while (isxdigit((c = yyGet()))) ; + while (my_isxdigit(system_charset_info,(c = yyGet()))) ; length=(lex->ptr - lex->tok_start); // Length of hexnum+3 if (!(length & 1) || c != '\'') { @@ -786,7 +788,7 @@ int yylex(void *arg) ulong version=MYSQL_VERSION_ID; yySkip(); state=STATE_START; - if (isdigit(yyPeek())) + if (my_isdigit(system_charset_info,yyPeek())) { // Version number version=strtol((char*) lex->ptr,(char**) &lex->ptr,10); } @@ -841,7 +843,7 @@ int yylex(void *arg) // Actually real shouldn't start // with . but allow them anyhow case STATE_REAL_OR_POINT: - if (isdigit(yyPeek())) + if (my_isdigit(system_charset_info,yyPeek())) state = STATE_REAL; // Real else { @@ -868,7 +870,7 @@ int yylex(void *arg) return((int) '@'); case STATE_HOSTNAME: // end '@' of user@hostname for (c=yyGet() ; - isalnum(c) || c == '.' || c == '_' || c == '$'; + my_isalnum(system_charset_info,c) || c == '.' || c == '_' || c == '$'; c= yyGet()) ; yylval->lex_str=get_token(lex,yyLength()); return(LEX_HOSTNAME); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e649f109a0d..ef6c0eb2a5d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -692,7 +692,8 @@ pthread_handler_decl(handle_bootstrap,arg) while (fgets(buff, thd->net.max_packet, file)) { uint length=(uint) strlen(buff); - while (length && (isspace(buff[length-1]) || buff[length-1] == ';')) + while (length && (my_isspace(system_charset_info, buff[length-1]) || + buff[length-1] == ';')) length--; buff[length]=0; thd->current_tablenr=0; @@ -917,13 +918,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { packet_length--; // Remove end null /* Remove garage at start and end of query */ - while (isspace(packet[0]) && packet_length > 0) + while (my_isspace(system_charset_info,packet[0]) && packet_length > 0) { packet++; packet_length--; } char *pos=packet+packet_length; // Point at end null - while (packet_length > 0 && (pos[-1] == ';' || isspace(pos[-1]))) + while (packet_length > 0 && + (pos[-1] == ';' || my_isspace(system_charset_info,pos[-1]))) { pos--; packet_length--; @@ -2261,7 +2263,8 @@ mysql_execute_command(void) if (user->password.str && (strcmp(thd->user,user->user.str) || user->host.str && - my_strcasecmp(user->host.str, thd->host_or_ip))) + my_strcasecmp(system_charset_info, + user->host.str, thd->host_or_ip))) { if (check_access(thd, UPDATE_ACL, "mysql",0,1)) goto error; @@ -3112,8 +3115,8 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, ptr->name=alias_str; if (lower_case_table_names) { - casedn_str(ptr->db); - casedn_str(table->table.str); + my_casedn_str(system_charset_info,ptr->db); + my_casedn_str(system_charset_info,table->table.str); } ptr->real_name=table->table.str; ptr->lock_type=flags; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 52541ffe50f..3e7b8f13844 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -209,7 +209,7 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, else { // Return only .frm files which aren't temp files. - if (my_strcasecmp(ext=fn_ext(file->name),reg_ext) || + if (my_strcasecmp(system_charset_info, ext=fn_ext(file->name),reg_ext) || is_prefix(file->name,tmp_file_prefix)) continue; *ext=0; @@ -217,7 +217,7 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, { if (lower_case_table_names) { - if (wild_case_compare(file->name,wild)) + if (wild_case_compare(system_charset_info,file->name,wild)) continue; } else if (wild_compare(file->name,wild)) @@ -472,7 +472,8 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, String *packet= &thd->packet; for (ptr=table->field; (field= *ptr) ; ptr++) { - if (!wild || !wild[0] || !wild_case_compare(field->field_name,wild)) + if (!wild || !wild[0] || + !wild_case_compare(system_charset_info, field->field_name,wild)) { #ifdef NOT_USED if (thd->col_access & TABLE_ACLS || @@ -744,7 +745,8 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) Field **ptr,*field; for (ptr=table->field ; (field= *ptr); ptr++) { - if (!wild || !wild[0] || !wild_case_compare(field->field_name,wild)) + if (!wild || !wild[0] || + !wild_case_compare(system_charset_info, field->field_name,wild)) field_list.push_back(new Item_field(field)); } restore_record(table,2); // Get empty record diff --git a/sql/sql_string.cc b/sql/sql_string.cc index f0cfd590072..62b1812afb3 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -234,7 +234,7 @@ bool String::fill(uint32 max_length,char fill_char) void String::strip_sp() { - while (str_length && isspace(Ptr[str_length-1])) + while (str_length && my_isspace(str_charset,Ptr[str_length-1])) str_length--; } @@ -296,10 +296,10 @@ uint32 String::numchars() register uint32 n=0,mblen; register const char *mbstr=Ptr; register const char *end=mbstr+str_length; - if (use_mb(default_charset_info)) + if (use_mb(str_charset)) { while (mbstr < end) { - if ((mblen=my_ismbchar(default_charset_info, mbstr,end))) mbstr+=mblen; + if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen; else ++mbstr; ++n; } @@ -316,11 +316,11 @@ int String::charpos(int i,uint32 offset) register uint32 mblen; register const char *mbstr=Ptr+offset; register const char *end=Ptr+str_length; - if (use_mb(default_charset_info)) + if (use_mb(str_charset)) { if (i<=0) return i; while (i && mbstr < end) { - if ((mblen=my_ismbchar(default_charset_info, mbstr,end))) mbstr+=mblen; + if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen; else ++mbstr; --i; } @@ -380,12 +380,14 @@ int String::strstr_case(const String &s,uint32 offset) skipp: while (str != end) { - if (my_sort_order[*str++] == my_sort_order[*search]) + if (str_charset->sort_order[*str++] == str_charset->sort_order[*search]) { register char *i,*j; i=(char*) str; j=(char*) search+1; while (j != search_end) - if (my_sort_order[*i++] != my_sort_order[*j++]) goto skipp; + if (str_charset->sort_order[*i++] != + str_charset->sort_order[*j++]) + goto skipp; return (int) (str-Ptr) -1; } } @@ -505,15 +507,15 @@ int sortcmp(const String *x,const String *y) uint32 x_len=x->length(),y_len=y->length(),len=min(x_len,y_len); #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info)) + if (use_strcoll(x->str_charset)) { #ifndef CMP_ENDSPACE - while (x_len && isspace(s[x_len-1])) + while (x_len && my_isspace(x->str_charset,s[x_len-1])) x_len--; - while (y_len && isspace(t[y_len-1])) + while (y_len && my_isspace(x->str_charset,t[y_len-1])) y_len--; #endif - return my_strnncoll(default_charset_info, + return my_strnncoll(x->str_charset, (unsigned char *)s,x_len,(unsigned char *)t,y_len); } else @@ -523,9 +525,10 @@ int sortcmp(const String *x,const String *y) y_len-=len; while (len--) { - if (my_sort_order[(uchar) *s++] != my_sort_order[(uchar) *t++]) - return ((int) my_sort_order[(uchar) s[-1]] - - (int) my_sort_order[(uchar) t[-1]]); + if (x->str_charset->sort_order[(uchar) *s++] != + x->str_charset->sort_order[(uchar) *t++]) + return ((int) x->str_charset->sort_order[(uchar) s[-1]] - + (int) x->str_charset->sort_order[(uchar) t[-1]]); } #ifndef CMP_ENDSPACE /* Don't compare end space in strings */ @@ -534,14 +537,14 @@ int sortcmp(const String *x,const String *y) { const char *end=t+y_len; for (; t != end ; t++) - if (!isspace(*t)) + if (!my_isspace(x->str_charset,*t)) return -1; } else { const char *end=s+x_len; for (; s != end ; s++) - if (!isspace(*s)) + if (!my_isspace(x->str_charset,*s)) return 1; } return 0; @@ -589,11 +592,10 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) /* Make it easier to handle different charactersets */ #ifdef USE_MB -#define INC_PTR(A,B) A+=((use_mb_flag && \ - my_ismbchar(default_charset_info,A,B)) ? \ - my_ismbchar(default_charset_info,A,B) : 1) +#define INC_PTR(cs,A,B) A+=((use_mb_flag && \ + my_ismbchar(cs,A,B)) ? my_ismbchar(cs,A,B) : 1) #else -#define INC_PTR(A,B) A++ +#define INC_PTR(cs,A,B) A++ #endif /* @@ -604,12 +606,12 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) */ #ifdef LIKE_CMP_TOUPPER -#define likeconv(A) (uchar) toupper(A) +#define likeconv(s,A) (uchar) my_toupper(s,A) #else -#define likeconv(A) (uchar) my_sort_order[(uchar) (A)] +#define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)] #endif -int wild_case_compare(const char *str,const char *str_end, +int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end, const char *wildstr,const char *wildend, char escape) { @@ -626,7 +628,7 @@ int wild_case_compare(const char *str,const char *str_end, #ifdef USE_MB int l; if (use_mb_flag && - (l = my_ismbchar(default_charset_info, wildstr, wildend))) + (l = my_ismbchar(cs, wildstr, wildend))) { if (str+l > str_end || memcmp(str, wildstr, l) != 0) return 1; @@ -635,7 +637,7 @@ int wild_case_compare(const char *str,const char *str_end, } else #endif - if (str == str_end || likeconv(*wildstr++) != likeconv(*str++)) + if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++)) return(1); // No match if (wildstr == wildend) return (str != str_end); // Match if both are at end @@ -647,7 +649,7 @@ int wild_case_compare(const char *str,const char *str_end, { if (str == str_end) // Skip one char if possible return (result); - INC_PTR(str,str_end); + INC_PTR(cs,str,str_end); } while (++wildstr < wildend && *wildstr == wild_one); if (wildstr == wildend) break; @@ -664,7 +666,7 @@ int wild_case_compare(const char *str,const char *str_end, { if (str == str_end) return (-1); - INC_PTR(str,str_end); + INC_PTR(cs,str,str_end); continue; } break; // Not a wild character @@ -682,10 +684,10 @@ int wild_case_compare(const char *str,const char *str_end, int mblen; LINT_INIT(mblen); if (use_mb_flag) - mblen = my_ismbchar(default_charset_info, wildstr, wildend); + mblen = my_ismbchar(cs, wildstr, wildend); #endif - INC_PTR(wildstr,wildend); // This is compared trough cmp - cmp=likeconv(cmp); + INC_PTR(cs,wildstr,wildend); // This is compared trough cmp + cmp=likeconv(cs,cmp); do { #ifdef USE_MB @@ -703,26 +705,26 @@ int wild_case_compare(const char *str,const char *str_end, break; } } - else if (!my_ismbchar(default_charset_info, str, str_end) && - likeconv(*str) == cmp) + else if (!my_ismbchar(cs, str, str_end) && + likeconv(cs,*str) == cmp) { str++; break; } - INC_PTR(str, str_end); + INC_PTR(cs,str, str_end); } } else { #endif /* USE_MB */ - while (str != str_end && likeconv(*str) != cmp) + while (str != str_end && likeconv(cs,*str) != cmp) str++; if (str++ == str_end) return (-1); #ifdef USE_MB } #endif { - int tmp=wild_case_compare(str,str_end,wildstr,wildend,escape); + int tmp=wild_case_compare(cs,str,str_end,wildstr,wildend,escape); if (tmp <= 0) return (tmp); } @@ -739,7 +741,7 @@ int wild_case_compare(String &match,String &wild, char escape) DBUG_ENTER("wild_case_compare"); DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'" ,match.ptr(),wild.ptr(),escape)); - DBUG_RETURN(wild_case_compare(match.ptr(),match.ptr()+match.length(), + DBUG_RETURN(wild_case_compare(match.str_charset,match.ptr(),match.ptr()+match.length(), wild.ptr(), wild.ptr()+wild.length(),escape)); } diff --git a/sql/sql_string.h b/sql/sql_string.h index 6e8fefb079a..811e49a0d02 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -198,8 +198,8 @@ public: } bool fill(uint32 max_length,char fill); void strip_sp(); - inline void caseup() { ::caseup(Ptr,str_length); } - inline void casedn() { ::casedn(Ptr,str_length); } + inline void caseup() { my_caseup(str_charset,Ptr,str_length); } + inline void casedn() { my_casedn(str_charset,Ptr,str_length); } friend int sortcmp(const String *a,const String *b); friend int stringcmp(const String *a,const String *b); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4b849fd850d..7e679f59fc0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -302,7 +302,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, null_fields++; while ((dup_field=it2++) != sql_field) { - if (my_strcasecmp(sql_field->field_name, dup_field->field_name) == 0) + if (my_strcasecmp(system_charset_info, + sql_field->field_name, + dup_field->field_name) == 0) { my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name); DBUG_RETURN(-1); @@ -496,7 +498,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, it.rewind(); field=0; while ((sql_field=it++) && - my_strcasecmp(column->field_name,sql_field->field_name)) + my_strcasecmp(system_charset_info, + column->field_name, + sql_field->field_name)) field++; if (!sql_field) { @@ -727,7 +731,7 @@ static bool check_if_keyname_exists(const char *name, KEY *start, KEY *end) { for (KEY *key=start ; key != end ; key++) - if (!my_strcasecmp(name,key->name)) + if (!my_strcasecmp(system_charset_info,name,key->name)) return 1; return 0; } @@ -1235,9 +1239,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, strmov(new_name_buff,new_name); fn_same(new_name_buff,table_name,3); if (lower_case_table_names) - casedn_str(new_name); + my_casedn_str(system_charset_info,new_name); if ((lower_case_table_names && - !my_strcasecmp(new_name_buff,table_name)) || + !my_strcasecmp(system_charset_info, new_name_buff,table_name)) || (!lower_case_table_names && !strcmp(new_name_buff,table_name))) new_name=table_name; // No. Make later check easier @@ -1348,7 +1352,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, while ((drop=drop_it++)) { if (drop->type == Alter_drop::COLUMN && - !my_strcasecmp(field->field_name, drop->name)) + !my_strcasecmp(system_charset_info,field->field_name, drop->name)) { /* Reset auto_increment value if it was dropped */ if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && @@ -1369,7 +1373,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, def_it.rewind(); while ((def=def_it++)) { - if (def->change && !my_strcasecmp(field->field_name, def->change)) + if (def->change && + !my_strcasecmp(system_charset_info,field->field_name, def->change)) break; } if (def) @@ -1393,7 +1398,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, Alter_column *alter; while ((alter=alter_it++)) { - if (!my_strcasecmp(field->field_name, alter->name)) + if (!my_strcasecmp(system_charset_info,field->field_name, alter->name)) break; } if (alter) @@ -1427,7 +1432,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, find_it.rewind(); while ((find=find_it++)) // Add new columns { - if (!my_strcasecmp(def->after, find->field_name)) + if (!my_strcasecmp(system_charset_info,def->after, find->field_name)) break; } if (!find) @@ -1473,7 +1478,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, while ((drop=drop_it++)) { if (drop->type == Alter_drop::KEY && - !my_strcasecmp(key_name, drop->name)) + !my_strcasecmp(system_charset_info,key_name, drop->name)) break; } if (drop) @@ -1495,10 +1500,11 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (cfield->change) { - if (!my_strcasecmp(key_part_name, cfield->change)) + if (!my_strcasecmp(system_charset_info,key_part_name, cfield->change)) break; } - else if (!my_strcasecmp(key_part_name, cfield->field_name)) + else if (!my_strcasecmp(system_charset_info, + key_part_name, cfield->field_name)) break; } if (!cfield) @@ -1518,7 +1524,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (key_parts.elements) key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL : (key_info->flags & HA_NOSAME ? - (!my_strcasecmp(key_name, "PRIMARY") ? + (!my_strcasecmp(system_charset_info, + key_name, "PRIMARY") ? Key::PRIMARY : Key::UNIQUE) : (key_info->flags & HA_FULLTEXT ? Key::FULLTEXT : Key::MULTIPLE)), diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 41e56328613..d762c8784a3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3654,7 +3654,8 @@ column_list_id: LEX *lex=Lex; while ((point=iter++)) { - if (!my_strcasecmp(point->column.ptr(),new_str->ptr())) + if (!my_strcasecmp(system_charset_info, + point->column.ptr(), new_str->ptr())) break; } lex->grant_tot_col|= lex->which_columns; diff --git a/sql/table.cc b/sql/table.cc index 9e6283d6ad4..2fa5d41f1ba 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1067,9 +1067,10 @@ bool check_db_name(const char *name) while (*name) { #if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(default_charset_info)) + if (use_mb(system_charset_info)) { - int len=my_ismbchar(default_charset_info, name, name+MBMAXLEN); + int len=my_ismbchar(system_charset_info, name, + name+system_charset_info->mbmaxlen); if (len) { name += len; @@ -1099,9 +1100,9 @@ bool check_table_name(const char *name, uint length) while (name != end) { #if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(default_charset_info)) + if (use_mb(system_charset_info)) { - int len=my_ismbchar(default_charset_info, name, end); + int len=my_ismbchar(system_charset_info, name, end); if (len) { name += len; @@ -1121,9 +1122,10 @@ bool check_column_name(const char *name) while (*name) { #if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(default_charset_info)) + if (use_mb(system_charset_info)) { - int len=my_ismbchar(default_charset_info, name, name+MBMAXLEN); + int len=my_ismbchar(system_charset_info, name, + name+system_charset_info->mbmaxlen); if (len) { name += len; diff --git a/sql/time.cc b/sql/time.cc index aab886648e3..2a791ccc30e 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -268,13 +268,13 @@ void find_date(string pos,uint *vek,uint flag) DBUG_PRINT("enter",("pos: '%s' flag: %d",pos,flag)); bzero((char*) vek,sizeof(int)*4); - while (*pos && !isdigit(*pos)) + while (*pos && !my_isdigit(system_charset_info,*pos)) pos++; length=(uint) strlen(pos); for (uint i=0 ; i< 3; i++) { start=pos; value=0; - while (isdigit(pos[0]) && + while (my_isdigit(system_charset_info,pos[0]) && ((pos-start) < 2 || ((pos-start) < 4 && length >= 8 && !(flag & 3)))) { @@ -282,7 +282,8 @@ void find_date(string pos,uint *vek,uint flag) pos++; } vek[flag & 3]=value; flag>>=2; - while (*pos && (ispunct(*pos) || isspace(*pos))) + while (*pos && (my_ispunct(system_charset_info,*pos) || + my_isspace(system_charset_info,*pos))) pos++; } DBUG_PRINT("exit",("year: %d month: %d day: %d",vek[0],vek[1],vek[2])); @@ -434,7 +435,8 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) DBUG_ENTER("str_to_TIME"); DBUG_PRINT("enter",("str: %.*s",length,str)); - for (; str != end && !isdigit(*str) ; str++) ; // Skip garbage + // Skip garbage + for (; str != end && !my_isdigit(system_charset_info, *str) ; str++) ; if (str == end) DBUG_RETURN(TIMESTAMP_NONE); /* @@ -442,14 +444,14 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) ** If length= 8 or >= 14 then year is of format YYYY. (YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS) */ - for (pos=str; pos != end && isdigit(*pos) ; pos++) ; + for (pos=str; pos != end && my_isdigit(system_charset_info,*pos) ; pos++) ; digits= (uint) (pos-str); year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2; field_length=year_length-1; - for (i=0 ; i < 6 && str != end && isdigit(*str) ; i++) + for (i=0 ; i < 6 && str != end && my_isdigit(system_charset_info,*str) ; i++) { uint tmp_value=(uint) (uchar) (*str++ - '0'); - while (str != end && isdigit(str[0]) && field_length--) + while (str != end && my_isdigit(system_charset_info,str[0]) && field_length--) { tmp_value=tmp_value*10 + (uint) (uchar) (*str - '0'); str++; @@ -459,10 +461,12 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) str++; // ISO8601: CCYYMMDDThhmmss else if ( i != 5 ) // Skip inter-field delimiters { - while (str != end && (ispunct(*str) || isspace(*str))) + while (str != end && + (my_ispunct(system_charset_info,*str) || + my_isspace(system_charset_info,*str))) { // Only allow space between days and hours - if (isspace(*str) && i != 2) + if (my_isspace(system_charset_info,*str) && i != 2) DBUG_RETURN(TIMESTAMP_NONE); str++; } @@ -470,12 +474,13 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) field_length=1; // Rest fields can only be 2 } /* Handle second fractions */ - if (i == 6 && (uint) (end-str) >= 2 && *str == '.' && isdigit(str[1])) + if (i == 6 && (uint) (end-str) >= 2 && *str == '.' && + my_isdigit(system_charset_info,str[1])) { str++; uint tmp_value=(uint) (uchar) (*str - '0'); field_length=3; - while (str++ != end && isdigit(str[0]) && field_length--) + while (str++ != end && my_isdigit(system_charset_info,str[0]) && field_length--) tmp_value=tmp_value*10 + (uint) (uchar) (*str - '0'); date[6]=tmp_value; } @@ -498,7 +503,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) { for ( ; str != end ; str++) { - if (!isspace(*str)) + if (!my_isspace(system_charset_info,*str)) { current_thd->cuted_fields++; break; @@ -559,7 +564,8 @@ bool str_to_time(const char *str,uint length,TIME *l_time) uint state; l_time->neg=0; - for (; str != end && !isdigit(*str) && *str != '-' ; str++) + for (; str != end && + !my_isdigit(system_charset_info,*str) && *str != '-' ; str++) length--; if (str != end && *str == '-') { @@ -578,7 +584,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time) } /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */ - for (value=0; str != end && isdigit(*str) ; str++) + for (value=0; str != end && my_isdigit(system_charset_info,*str) ; str++) value=value*10L + (long) (*str - '0'); if (*str == ' ') @@ -589,14 +595,16 @@ bool str_to_time(const char *str,uint length,TIME *l_time) LINT_INIT(state); found_days=found_hours=0; - if ((uint) (end-str) > 1 && (*str == ' ' && isdigit(str[1]))) + if ((uint) (end-str) > 1 && (*str == ' ' && + my_isdigit(system_charset_info,str[1]))) { // days ! date[0]=value; state=1; // Assume next is hours found_days=1; str++; // Skip space; } - else if ((end-str) > 1 && *str == ':' && isdigit(str[1])) + else if ((end-str) > 1 && *str == ':' && + my_isdigit(system_charset_info,str[1])) { date[0]=0; // Assume we found hours date[1]=value; @@ -618,10 +626,11 @@ bool str_to_time(const char *str,uint length,TIME *l_time) /* Read hours, minutes and seconds */ for (;;) { - for (value=0; str != end && isdigit(*str) ; str++) + for (value=0; str != end && my_isdigit(system_charset_info,*str) ; str++) value=value*10L + (long) (*str - '0'); date[state++]=value; - if (state == 4 || (end-str) < 2 || *str != ':' || !isdigit(str[1])) + if (state == 4 || (end-str) < 2 || *str != ':' || + !my_isdigit(system_charset_info,str[1])) break; str++; // Skip ':' } @@ -641,11 +650,13 @@ bool str_to_time(const char *str,uint length,TIME *l_time) fractional: /* Get fractional second part */ - if ((end-str) >= 2 && *str == '.' && isdigit(str[1])) + if ((end-str) >= 2 && *str == '.' && my_isdigit(system_charset_info,str[1])) { uint field_length=3; str++; value=(uint) (uchar) (*str - '0'); - while (++str != end && isdigit(str[0]) && field_length--) + while (++str != end && + my_isdigit(system_charset_info,str[0]) && + field_length--) value=value*10 + (uint) (uchar) (*str - '0'); date[4]=value; } @@ -670,7 +681,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time) { do { - if (!isspace(*str)) + if (!my_isspace(system_charset_info,*str)) { current_thd->cuted_fields++; break; -- cgit v1.2.1 From ee1ef8c58c9df9a62f7a0cc3dee6c2f705c8eb44 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Mar 2002 20:52:48 +0400 Subject: use String->charset instead of default_charset_info client/mysql.cc: default_charset_info -> system_charset_info include/m_ctype.h: Remove old ctype mysys/charset.c: Initialize fields after dynamic charset loading sql/sql_parse.cc: default_charset_info -> system_charset_info --- sql/item_func.cc | 11 +++++------ sql/item_strfunc.cc | 37 ++++++++++++++++++++----------------- sql/sql_parse.cc | 4 ++-- sql/sql_string.cc | 2 +- 4 files changed, 28 insertions(+), 26 deletions(-) (limited to 'sql') diff --git a/sql/item_func.cc b/sql/item_func.cc index 09e3aab08c6..587388d6159 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -830,7 +830,7 @@ longlong Item_func_locate::val_int() { start=(uint) args[2]->val_int()-1; #ifdef USE_MB - if (use_mb(default_charset_info)) + if (use_mb(a->str_charset)) { start0=start; if (!binary_str) @@ -843,7 +843,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(default_charset_info) && !binary_str) + if (use_mb(a->str_charset) && !binary_str) { const char *ptr=a->ptr()+start; const char *search=b->ptr(); @@ -862,7 +862,7 @@ longlong Item_func_locate::val_int() return (longlong) start0+1; } skipp: - if ((l=my_ismbchar(default_charset_info,ptr,strend))) ptr+=l; + if ((l=my_ismbchar(a->str_charset,ptr,strend))) ptr+=l; else ++ptr; ++start0; } @@ -913,11 +913,10 @@ longlong Item_func_ord::val_int() null_value=0; if (!res->length()) return 0; #ifdef USE_MB - if (use_mb(default_charset_info) && !args[0]->binary) + if (use_mb(res->str_charset) && !args[0]->binary) { register const char *str=res->ptr(); - register uint32 n=0, l=my_ismbchar(default_charset_info, - str,str+res->length()); + register uint32 n=0, l=my_ismbchar(res->str_charset,str,str+res->length()); if (!l) return (longlong)((uchar) *str); while (l--) n=(n<<8)|(uint32)((uchar) *str++); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index de07f5b1ee7..a9ba3526e1c 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -510,7 +510,7 @@ String *Item_func_reverse::val_str(String *str) ptr = (char *) res->ptr(); end=ptr+res->length(); #ifdef USE_MB - if (use_mb(default_charset_info) && !binary) + if (use_mb(res->str_charset) && !binary) { String tmpstr; tmpstr.copy(*res); @@ -518,7 +518,7 @@ String *Item_func_reverse::val_str(String *str) register uint32 l; while (ptr < end) { - if ((l=my_ismbchar(default_charset_info, ptr,end))) + if ((l=my_ismbchar(res->str_charset, ptr,end))) tmp-=l, memcpy(tmp,ptr,l), ptr+=l; else *--tmp=*ptr++; @@ -561,8 +561,7 @@ String *Item_func_replace::val_str(String *str) #ifdef USE_MB const char *ptr,*end,*strend,*search,*search_end; register uint32 l; - bool binary_str = (args[0]->binary || args[1]->binary || - !use_mb(default_charset_info)); + bool binary_str; #endif null_value=0; @@ -573,6 +572,10 @@ String *Item_func_replace::val_str(String *str) if (args[1]->null_value) goto null; +#ifdef USE_MB + binary_str = (args[0]->binary || args[1]->binary || !use_mb(res->str_charset)); +#endif + if (res2->length() == 0) return res; #ifndef USE_MB @@ -618,7 +621,7 @@ redo: goto redo; } skipp: - if ((l=my_ismbchar(default_charset_info, ptr,strend))) ptr+=l; + if ((l=my_ismbchar(res->str_charset, ptr,strend))) ptr+=l; else ++ptr; } } @@ -676,7 +679,7 @@ String *Item_func_insert::val_str(String *str) args[3]->null_value) goto null; /* purecov: inspected */ #ifdef USE_MB - if (use_mb(default_charset_info) && !args[0]->binary) + if (use_mb(res->str_charset) && !args[0]->binary) { start=res->charpos(start); length=res->charpos(length,start); @@ -748,7 +751,7 @@ String *Item_func_left::val_str(String *str) if (length <= 0) return &empty_string; #ifdef USE_MB - if (use_mb(default_charset_info) && !binary) + if (use_mb(res->str_charset) && !binary) length = res->charpos(length); #endif if (res->length() > (ulong) length) @@ -796,7 +799,7 @@ String *Item_func_right::val_str(String *str) if (res->length() <= (uint) length) return res; /* purecov: inspected */ #ifdef USE_MB - if (use_mb(default_charset_info) && !binary) + if (use_mb(res->str_charset) && !binary) { uint start=res->numchars()-(uint) length; if (start<=0) return res; @@ -829,7 +832,7 @@ String *Item_func_substr::val_str(String *str) (arg_count == 3 && args[2]->null_value)))) return 0; /* purecov: inspected */ #ifdef USE_MB - if (use_mb(default_charset_info) && !binary) + if (use_mb(res->str_charset) && !binary) { start=res->charpos(start); length=res->charpos(length,start); @@ -889,7 +892,7 @@ String *Item_func_substr_index::val_str(String *str) return &empty_string; // Wrong parameters #ifdef USE_MB - if (use_mb(default_charset_info) && !binary) + if (use_mb(res->str_charset) && !binary) { const char *ptr=res->ptr(); const char *strend = ptr+res->length(); @@ -914,7 +917,7 @@ String *Item_func_substr_index::val_str(String *str) continue; } skipp: - if ((l=my_ismbchar(default_charset_info, ptr,strend))) ptr+=l; + if ((l=my_ismbchar(res->str_charset, ptr,strend))) ptr+=l; else ++ptr; } /* either not found or got total number when count<0 */ if (pass == 0) /* count<0 */ @@ -1043,11 +1046,11 @@ String *Item_func_rtrim::val_str(String *str) { char chr=(*remove_str)[0]; #ifdef USE_MB - if (use_mb(default_charset_info) && !binary) + if (use_mb(res->str_charset) && !binary) { while (ptr < end) { - if ((l=my_ismbchar(default_charset_info, ptr,end))) ptr+=l,p=ptr; + if ((l=my_ismbchar(res->str_charset, ptr,end))) ptr+=l,p=ptr; else ++ptr; } ptr=p; @@ -1060,12 +1063,12 @@ String *Item_func_rtrim::val_str(String *str) { const char *r_ptr=remove_str->ptr(); #ifdef USE_MB - if (use_mb(default_charset_info) && !binary) + if (use_mb(res->str_charset) && !binary) { loop: while (ptr + remove_length < end) { - if ((l=my_ismbchar(default_charset_info, ptr,end))) ptr+=l; + if ((l=my_ismbchar(res->str_charset, ptr,end))) ptr+=l; else ++ptr; } if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length)) @@ -1111,14 +1114,14 @@ String *Item_func_trim::val_str(String *str) while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length)) ptr+=remove_length; #ifdef USE_MB - if (use_mb(default_charset_info) && !binary) + if (use_mb(res->str_charset) && !binary) { char *p=ptr; register uint32 l; loop: while (ptr + remove_length < end) { - if ((l=my_ismbchar(default_charset_info, ptr,end))) ptr+=l; + if ((l=my_ismbchar(res->str_charset, ptr,end))) ptr+=l; else ++ptr; } if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length)) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ef6c0eb2a5d..c47d6ddd4bb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3043,8 +3043,8 @@ static void remove_escape(char *name) #ifdef USE_MB int l; /* if ((l = ismbchar(name, name+MBMAXLEN))) { Wei He: I think it's wrong */ - if (use_mb(default_charset_info) && - (l = my_ismbchar(default_charset_info, name, strend))) + if (use_mb(system_charset_info) && + (l = my_ismbchar(system_charset_info, name, strend))) { while (l--) *to++ = *name++; diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 62b1812afb3..cf9e9f62507 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -617,7 +617,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end, { int result= -1; // Not found, using wildcards #ifdef USE_MB - bool use_mb_flag=use_mb(default_charset_info); + bool use_mb_flag=use_mb(cs); #endif while (wildstr != wildend) { -- cgit v1.2.1 From 8959b690fe796a44ddda440290b3fe9a9cf89ca5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Mar 2002 21:44:42 +0400 Subject: Hash now supports several charsets --- sql/ha_berkeley.cc | 2 +- sql/ha_innodb.cc | 2 +- sql/hash_filo.h | 4 ++-- sql/item_func.cc | 3 ++- sql/repl_failsafe.cc | 2 +- sql/slave.cc | 2 +- sql/sql_acl.cc | 11 +++++++---- sql/sql_base.cc | 2 +- sql/sql_cache.cc | 4 ++-- sql/sql_class.cc | 2 +- sql/sql_parse.cc | 3 ++- sql/sql_select.cc | 6 ++++-- sql/sql_udf.cc | 3 ++- sql/table.cc | 1 + 14 files changed, 28 insertions(+), 19 deletions(-) (limited to 'sql') diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 614d1b5abf5..58a090a8aed 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -168,7 +168,7 @@ bool berkeley_init(void) db_env=0; /* purecov: inspected */ } - (void) hash_init(&bdb_open_tables,32,0,0, + (void) hash_init(&bdb_open_tables,system_charset_info,32,0,0, (hash_get_key) bdb_get_key,0,0); pthread_mutex_init(&bdb_mutex,MY_MUTEX_INIT_FAST); DBUG_RETURN(db_env == 0); diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index d53b027a415..fd2dcf4dfb6 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -666,7 +666,7 @@ innobase_init(void) DBUG_RETURN(1); } - (void) hash_init(&innobase_open_tables,32,0,0, + (void) hash_init(&innobase_open_tables,system_charset_info,32,0,0, (hash_get_key) innobase_get_key,0,0); pthread_mutex_init(&innobase_mutex,MY_MUTEX_INIT_FAST); DBUG_RETURN(0); diff --git a/sql/hash_filo.h b/sql/hash_filo.h index b8d45f0d3be..4d746d9b9bd 100644 --- a/sql/hash_filo.h +++ b/sql/hash_filo.h @@ -75,8 +75,8 @@ public: if (!locked) (void) pthread_mutex_lock(&lock); (void) hash_free(&cache); - (void) hash_init(&cache,size,key_offset, key_length, get_key, free_element, - 0); + (void) hash_init(&cache,system_charset_info,size,key_offset, + key_length, get_key, free_element,0); if (!locked) (void) pthread_mutex_unlock(&lock); first_link=last_link=0; diff --git a/sql/item_func.cc b/sql/item_func.cc index 587388d6159..e25f4c6e94a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1421,7 +1421,8 @@ char *ull_get_key(const ULL *ull,uint *length, void item_user_lock_init(void) { pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW); - hash_init(&hash_user_locks,16,0,0,(hash_get_key) ull_get_key,NULL,0); + hash_init(&hash_user_locks,system_charset_info, + 16,0,0,(hash_get_key) ull_get_key,NULL,0); } void item_user_lock_free(void) diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 257418d1682..3f16880c18e 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -184,7 +184,7 @@ static void slave_info_free(void *s) void init_slave_list() { - hash_init(&slave_list, SLAVE_LIST_CHUNK, 0, 0, + hash_init(&slave_list, system_charset_info, SLAVE_LIST_CHUNK, 0, 0, (hash_get_key) slave_list_key, slave_info_free, 0); pthread_mutex_init(&LOCK_slave_list, MY_MUTEX_INIT_FAST); } diff --git a/sql/slave.cc b/sql/slave.cc index 9630cf6aa0e..52f04ef8675 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -470,7 +470,7 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start, void init_table_rule_hash(HASH* h, bool* h_inited) { - hash_init(h, TABLE_RULE_HASH_SIZE,0,0, + hash_init(h, system_charset_info,TABLE_RULE_HASH_SIZE,0,0, (hash_get_key) get_table_key, (void (*)(void*)) free_table_ent, 0); *h_inited = 1; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 198569cec3c..32630a9537e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -847,7 +847,7 @@ static void init_check_host(void) DBUG_ENTER("init_check_host"); VOID(init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), acl_users.elements,1)); - VOID(hash_init(&acl_check_hosts,acl_users.elements,0,0, + VOID(hash_init(&acl_check_hosts,system_charset_info,acl_users.elements,0,0, (hash_get_key) check_get_key,0,HASH_CASE_INSENSITIVE)); if (!allow_all_hosts) { @@ -1424,7 +1424,8 @@ public: key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3; hash_key = (char*) alloc_root(&memex,key_length); strmov(strmov(strmov(hash_key,user)+1,db)+1,tname); - (void) hash_init(&hash_columns,0,0,0, (hash_get_key) get_key_column,0, + (void) hash_init(&hash_columns,system_charset_info, + 0,0,0, (hash_get_key) get_key_column,0, HASH_CASE_INSENSITIVE); } @@ -1456,7 +1457,8 @@ public: privs = fix_rights_for_table(privs); cols = fix_rights_for_column(cols); - (void) hash_init(&hash_columns,0,0,0, (hash_get_key) get_key_column,0, + (void) hash_init(&hash_columns,system_charset_info, + 0,0,0, (hash_get_key) get_key_column,0, HASH_CASE_INSENSITIVE); if (cols) { @@ -2143,7 +2145,8 @@ int grant_init (void) DBUG_ENTER("grant_init"); grant_option = FALSE; - (void) hash_init(&hash_tables,0,0,0, (hash_get_key) get_grant_table, + (void) hash_init(&hash_tables,system_charset_info, + 0,0,0, (hash_get_key) get_grant_table, (hash_free_key) free_grant_table,0); init_sql_alloc(&memex,1024,0); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e73a0c63fa6..d2d38d9a7c4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -50,7 +50,7 @@ static byte *cache_key(const byte *record,uint *length, void table_cache_init(void) { - VOID(hash_init(&open_cache, + VOID(hash_init(&open_cache,system_charset_info, table_cache_size+16,0,0,cache_key, (void (*)(void*)) free_cache_entry,0)); mysql_rm_tmp_tables(); diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 72ac20d8818..78d82f9b420 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1330,9 +1330,9 @@ ulong Query_cache::init_cache() DUMP(this); - VOID(hash_init(&queries,def_query_hash_size, 0, 0, + VOID(hash_init(&queries,system_charset_info,def_query_hash_size, 0, 0, query_cache_query_get_key, 0, 0)); - VOID(hash_init(&tables,def_table_hash_size, 0, 0, + VOID(hash_init(&tables,system_charset_info,def_table_hash_size, 0, 0, query_cache_table_get_key, 0, 0)); queries_in_cache = 0; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f6f66b0b7da..d0caa4e7b8c 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -137,7 +137,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), /* Initialize sub structures */ bzero((char*) &mem_root,sizeof(mem_root)); user_connect=(UC *)0; - hash_init(&user_vars, USER_VARS_HASH_SIZE, 0, 0, + hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, (void (*)(void*)) free_var,0); #ifdef USING_TRANSACTIONS diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c47d6ddd4bb..7fd3db1fe21 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -269,7 +269,8 @@ static void free_user(struct user_conn *uc) void init_max_user_conn(void) { - (void) hash_init(&hash_user_connections,max_connections,0,0, + (void) hash_init(&hash_user_connections,system_charset_info,max_connections, + 0,0, (hash_get_key) get_key_conn, (void (*)(void*)) free_user, 0); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 14feb12c769..1ea85984bcc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5874,8 +5874,10 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, (uint) (field_count*sizeof(*field_lengths)), NullS)) DBUG_RETURN(1); - if (hash_init(&hash, (uint) file->records, 0, key_length, - (hash_get_key) 0, 0, 0)) + + // BAR TODO: this must be fixed to use charset from "table" argument + if (hash_init(&hash, default_charset_info, (uint) file->records, 0, + key_length,(hash_get_key) 0, 0, 0)) { my_free((char*) key_buffer,MYF(0)); DBUG_RETURN(1); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 9493f969802..f44fa3b7321 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -127,7 +127,8 @@ void udf_init() init_sql_alloc(&mem, 1024,0); THD *new_thd = new THD; if (!new_thd || - hash_init(&udf_hash,32,0,0,get_hash_key, NULL, HASH_CASE_INSENSITIVE)) + hash_init(&udf_hash,system_charset_info, + 32,0,0,get_hash_key, NULL, HASH_CASE_INSENSITIVE)) { sql_print_error("Can't allocate memory for udf structures"); hash_free(&udf_hash); diff --git a/sql/table.cc b/sql/table.cc index 2fa5d41f1ba..eeda172c65d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -319,6 +319,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, use_hash= outparam->fields >= MAX_FIELDS_BEFORE_HASH; if (use_hash) use_hash= !hash_init(&outparam->name_hash, + system_charset_info, outparam->fields,0,0, (hash_get_key) get_field_name,0, HASH_CASE_INSENSITIVE); -- cgit v1.2.1 From 1b7471a4313c852618fb10710923ef9b131cb4de Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Mar 2002 23:03:15 +0400 Subject: remove default_charset_info sql/field.h: New function to get charset --- sql/field.h | 1 + sql/filesort.cc | 26 +++++++++++++++++--------- sql/opt_range.cc | 7 ++++--- 3 files changed, 22 insertions(+), 12 deletions(-) (limited to 'sql') diff --git a/sql/field.h b/sql/field.h index cd1697fcf44..e66865b6fb1 100644 --- a/sql/field.h +++ b/sql/field.h @@ -251,6 +251,7 @@ public: friend class create_field; void make_field(Send_field *); uint size_of() const { return sizeof(*this); } + inline CHARSET_INFO *charset() const { return field_charset; } inline int cmp_image(char *buff,uint length) { if (binary()) diff --git a/sql/filesort.cc b/sql/filesort.cc index 675cc294de4..54bd0543886 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -205,7 +205,7 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length, err: #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info)) + if (param.tmp_buffer) x_free(param.tmp_buffer); #endif x_free((gptr) sort_keys); @@ -470,6 +470,9 @@ static void make_sortkey(register SORTPARAM *param, switch (sort_field->result_type) { case STRING_RESULT: { + // BAR TODO: need checking that it is really Field_str based class + CHARSET_INFO *cs=((Field_str*)(sort_field->field))->charset(); + if (item->maybe_null) *to++=1; /* All item->str() to use some extra byte for end null.. */ @@ -495,7 +498,7 @@ static void make_sortkey(register SORTPARAM *param, length=sort_field->length; } #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info)) + if(use_strcoll(cs)) { if (item->binary) { @@ -512,8 +515,7 @@ static void make_sortkey(register SORTPARAM *param, memcpy(param->tmp_buffer,from,length); from=param->tmp_buffer; } - uint tmp_length=my_strnxfrm(default_charset_info, - to,sort_field->length, + uint tmp_length=my_strnxfrm(cs,to,sort_field->length, (unsigned char *) from, length); if (tmp_length < sort_field->length) bzero((char*) to+tmp_length,sort_field->length-tmp_length); @@ -526,7 +528,7 @@ static void make_sortkey(register SORTPARAM *param, memcpy(to,res->ptr(),length); bzero((char *)to+length,diff); if (!item->binary) - case_sort(default_charset_info, (char*) to,length); + case_sort(cs, (char*) to,length); #ifdef USE_STRCOLL } #endif @@ -923,8 +925,10 @@ sortlength(SORT_FIELD *sortorder, uint s_length) { sortorder->length=sortorder->field->pack_length(); #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info) && !sortorder->field->binary()) - sortorder->length= sortorder->length*default_charset_info->strxfrm_multiply; + // BAR TODO: need checking that it is really Field_str based class + CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); + if (use_strcoll(cs) && !sortorder->field->binary()) + sortorder->length= sortorder->length*cs->strxfrm_multiply; #endif } if (sortorder->field->maybe_null()) @@ -932,12 +936,16 @@ sortlength(SORT_FIELD *sortorder, uint s_length) } else { +#ifdef USE_STRCOLL + // BAR TODO: need checking that it is really Field_str based class + CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); +#endif switch ((sortorder->result_type=sortorder->item->result_type())) { case STRING_RESULT: sortorder->length=sortorder->item->max_length; #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info) && !sortorder->item->binary) - sortorder->length= sortorder->length*default_charset_info->strxfrm_multiply; + if (use_strcoll(cs) && !sortorder->item->binary) + sortorder->length= sortorder->length*cs->strxfrm_multiply; #endif break; case INT_RESULT: diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 8bd47913b7b..9c8b7da6960 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -974,9 +974,10 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, &min_length,&max_length); else { + CHARSET_INFO *charset=((Field_str*)(field))->charset(); #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info)) - like_error= my_like_range(default_charset_info, + if (use_strcoll(charset)) + like_error= my_like_range(charset, res->ptr(),res->length(),wild_prefix, field_length, min_str+maybe_null, max_str+maybe_null,&min_length,&max_length); @@ -985,7 +986,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, like_error=like_range(res->ptr(),res->length(),wild_prefix, field_length, min_str+offset,max_str+offset, - default_charset_info->max_sort_char, + charset->max_sort_char, &min_length,&max_length); } if (like_error) // Can't optimize with LIKE -- cgit v1.2.1 From 53bd33c676a4b87e3170ea06f9ff75cdbff48507 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Mar 2002 14:21:06 +0200 Subject: making full-text working with UNION's --- sql/sql_base.cc | 8 ++++---- sql/sql_select.cc | 5 +++-- sql/sql_union.cc | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e73a0c63fa6..69de3393820 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2180,8 +2180,8 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, int setup_ftfuncs(THD *thd) { - List_iterator li(thd->lex.select_lex.ftfunc_list), - lj(thd->lex.select_lex.ftfunc_list); + List_iterator li(thd->lex.select->ftfunc_list), + lj(thd->lex.select->ftfunc_list); Item_func_match *ftf, *ftf2; while ((ftf=li++)) @@ -2201,9 +2201,9 @@ int setup_ftfuncs(THD *thd) int init_ftfuncs(THD *thd, bool no_order) { - if (thd->lex.select_lex.ftfunc_list.elements) + if (thd->lex.select->ftfunc_list.elements) { - List_iterator li(thd->lex.select_lex.ftfunc_list); + List_iterator li(thd->lex.select->ftfunc_list); Item_func_match *ifm; DBUG_PRINT("info",("Performing FULLTEXT search")); thd->proc_info="FULLTEXT initialization"; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 14feb12c769..50ca1d71314 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -196,6 +196,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, List all_fields(fields); bool select_distinct; SELECT_LEX *select_lex = &(thd->lex.select_lex); + SELECT_LEX *cur_sel = thd->lex.select; DBUG_ENTER("mysql_select"); /* Check that all tables, fields, conds and order are ok */ @@ -553,7 +554,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, make_join_readinfo(&join, (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | - (select_lex->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE : 0)); + (cur_sel->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE : 0)); /* Need to tell Innobase that to play it safe, it should fetch all columns of the tables: this is because MySQL @@ -1615,7 +1616,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, add_key_part(keyuse,field); } - if (thd->lex.select_lex.ftfunc_list.elements) + if (thd->lex.select->ftfunc_list.elements) { add_ft_keys(keyuse,join_tab,cond,normal_tables); } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 60155e0ce8d..7d921d6e598 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -126,7 +126,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) } union_result->save_time_stamp=!describe; - for (sl=&lex->select_lex;sl;sl=sl->next) + for (sl=lex->select=&lex->select_lex;sl;sl=lex->select=sl->next) { thd->offset_limit=sl->offset_limit; thd->select_limit=sl->select_limit+sl->offset_limit; @@ -155,6 +155,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) delete union_result; /* Send result to 'result' */ + lex->select = &lex->select_lex; res =-1; { /* Create a list of fields in the temporary table */ -- cgit v1.2.1 From af87d92aa29ebaabf3aa78d8c7a0e8afc53db2d8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Mar 2002 14:23:11 +0200 Subject: Some changes from 4.0. Take a look their for details --- sql/sql_union.cc | 2 ++ sql/sql_yacc.yy | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 7d921d6e598..7532f43a663 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -184,6 +184,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) if (thd->select_limit == HA_POS_ERROR) thd->options&= ~OPTION_FOUND_ROWS; } + else + thd->select_limit= HA_POS_ERROR; // no limit if (describe) thd->select_limit= HA_POS_ERROR; // no limit res=mysql_select(thd,&result_table_list, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d762c8784a3..3c9c005fb48 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1441,22 +1441,22 @@ select_option_list: select_option: STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; } - | HIGH_PRIORITY { Lex->lock_option= TL_READ_HIGH_PRIORITY; } + | HIGH_PRIORITY { if (Select != &Lex->select_lex) YYABORT; Lex->lock_option= TL_READ_HIGH_PRIORITY; } | DISTINCT { Select->options|= SELECT_DISTINCT; } | SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; } | SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; } - | SQL_BUFFER_RESULT { Select->options|= OPTION_BUFFER_RESULT; } - | SQL_CALC_FOUND_ROWS { Select->options|= OPTION_FOUND_ROWS; } - | SQL_NO_CACHE_SYM { current_thd->safe_to_cache_query=0; } - | SQL_CACHE_SYM { Select->options |= OPTION_TO_QUERY_CACHE; } + | SQL_BUFFER_RESULT { if (Select != &Lex->select_lex) YYABORT; Select->options|= OPTION_BUFFER_RESULT; } + | SQL_CALC_FOUND_ROWS { if (Select != &Lex->select_lex) YYABORT; Select->options|= OPTION_FOUND_ROWS; } + | SQL_NO_CACHE_SYM { if (Select != &Lex->select_lex) YYABORT; current_thd->safe_to_cache_query=0; } + | SQL_CACHE_SYM { if (Select != &Lex->select_lex) YYABORT; Select->options |= OPTION_TO_QUERY_CACHE; } | ALL {} select_lock_type: /* empty */ | FOR_SYM UPDATE_SYM - { Lex->lock_option= TL_WRITE; current_thd->safe_to_cache_query=0; } + { if (Select != &Lex->select_lex) YYABORT; Lex->lock_option= TL_WRITE; current_thd->safe_to_cache_query=0; } | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM - { Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; current_thd->safe_to_cache_query=0; } + { if (Select != &Lex->select_lex) YYABORT; Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; current_thd->safe_to_cache_query=0; } select_item_list: select_item_list ',' select_item -- cgit v1.2.1 From 1fd84d347762c2db01427b8c159072c5e14161a5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Mar 2002 20:03:10 +0400 Subject: Configure.in/Makefile.in charset related things are now earier to maintain Fixes in charset related C++ code configure.in: Make things to be easier managable include/m_ctype.h: Hide some functions under conditional compilation libmysql/Makefile.shared: Make things to be easier managable sql/item_func.cc: Fixed that private member is not available in this context sql/item_strfunc.cc: Fixed that private member is not available in this context strings/Makefile.am: Make charset things to be easier managable Some fixes in charset C++ code strings/ctype-big5.c: Hide some functions under conditional compilation strings/ctype-czech.c: Hide some functions under conditional compilation strings/ctype-euc_kr.c: Hide some functions under conditional compilation strings/ctype-gb2312.c: Hide some functions under conditional compilation strings/ctype-gbk.c: Hide some functions under conditional compilation strings/ctype-latin1_de.c: Hide some functions under conditional compilation strings/ctype-mb.c: Hide some functions under conditional compilation strings/ctype-sjis.c: Hide some functions under conditional compilation strings/ctype-tis620.c: Hide some functions under conditional compilation strings/ctype-ujis.c: Hide some functions under conditional compilation --- sql/item_func.cc | 10 +++++----- sql/item_strfunc.cc | 32 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'sql') diff --git a/sql/item_func.cc b/sql/item_func.cc index e25f4c6e94a..488fe1314a8 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -830,7 +830,7 @@ longlong Item_func_locate::val_int() { start=(uint) args[2]->val_int()-1; #ifdef USE_MB - if (use_mb(a->str_charset)) + if (use_mb(a->charset())) { start0=start; if (!binary_str) @@ -843,7 +843,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->str_charset) && !binary_str) + if (use_mb(a->charset()) && !binary_str) { const char *ptr=a->ptr()+start; const char *search=b->ptr(); @@ -862,7 +862,7 @@ longlong Item_func_locate::val_int() return (longlong) start0+1; } skipp: - if ((l=my_ismbchar(a->str_charset,ptr,strend))) ptr+=l; + if ((l=my_ismbchar(a->charset(),ptr,strend))) ptr+=l; else ++ptr; ++start0; } @@ -913,10 +913,10 @@ longlong Item_func_ord::val_int() null_value=0; if (!res->length()) return 0; #ifdef USE_MB - if (use_mb(res->str_charset) && !args[0]->binary) + if (use_mb(res->charset()) && !args[0]->binary) { register const char *str=res->ptr(); - register uint32 n=0, l=my_ismbchar(res->str_charset,str,str+res->length()); + register uint32 n=0, l=my_ismbchar(res->charset(),str,str+res->length()); if (!l) return (longlong)((uchar) *str); while (l--) n=(n<<8)|(uint32)((uchar) *str++); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index a9ba3526e1c..cfbfda97148 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -510,7 +510,7 @@ String *Item_func_reverse::val_str(String *str) ptr = (char *) res->ptr(); end=ptr+res->length(); #ifdef USE_MB - if (use_mb(res->str_charset) && !binary) + if (use_mb(res->charset()) && !binary) { String tmpstr; tmpstr.copy(*res); @@ -518,7 +518,7 @@ String *Item_func_reverse::val_str(String *str) register uint32 l; while (ptr < end) { - if ((l=my_ismbchar(res->str_charset, ptr,end))) + if ((l=my_ismbchar(res->charset(), ptr,end))) tmp-=l, memcpy(tmp,ptr,l), ptr+=l; else *--tmp=*ptr++; @@ -573,7 +573,7 @@ String *Item_func_replace::val_str(String *str) goto null; #ifdef USE_MB - binary_str = (args[0]->binary || args[1]->binary || !use_mb(res->str_charset)); + binary_str = (args[0]->binary || args[1]->binary || !use_mb(res->charset())); #endif if (res2->length() == 0) @@ -621,7 +621,7 @@ redo: goto redo; } skipp: - if ((l=my_ismbchar(res->str_charset, ptr,strend))) ptr+=l; + if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l; else ++ptr; } } @@ -679,7 +679,7 @@ String *Item_func_insert::val_str(String *str) args[3]->null_value) goto null; /* purecov: inspected */ #ifdef USE_MB - if (use_mb(res->str_charset) && !args[0]->binary) + if (use_mb(res->charset()) && !args[0]->binary) { start=res->charpos(start); length=res->charpos(length,start); @@ -751,7 +751,7 @@ String *Item_func_left::val_str(String *str) if (length <= 0) return &empty_string; #ifdef USE_MB - if (use_mb(res->str_charset) && !binary) + if (use_mb(res->charset()) && !binary) length = res->charpos(length); #endif if (res->length() > (ulong) length) @@ -799,7 +799,7 @@ String *Item_func_right::val_str(String *str) if (res->length() <= (uint) length) return res; /* purecov: inspected */ #ifdef USE_MB - if (use_mb(res->str_charset) && !binary) + if (use_mb(res->charset()) && !binary) { uint start=res->numchars()-(uint) length; if (start<=0) return res; @@ -832,7 +832,7 @@ String *Item_func_substr::val_str(String *str) (arg_count == 3 && args[2]->null_value)))) return 0; /* purecov: inspected */ #ifdef USE_MB - if (use_mb(res->str_charset) && !binary) + if (use_mb(res->charset()) && !binary) { start=res->charpos(start); length=res->charpos(length,start); @@ -892,7 +892,7 @@ String *Item_func_substr_index::val_str(String *str) return &empty_string; // Wrong parameters #ifdef USE_MB - if (use_mb(res->str_charset) && !binary) + if (use_mb(res->charset()) && !binary) { const char *ptr=res->ptr(); const char *strend = ptr+res->length(); @@ -917,7 +917,7 @@ String *Item_func_substr_index::val_str(String *str) continue; } skipp: - if ((l=my_ismbchar(res->str_charset, ptr,strend))) ptr+=l; + if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l; else ++ptr; } /* either not found or got total number when count<0 */ if (pass == 0) /* count<0 */ @@ -1046,11 +1046,11 @@ String *Item_func_rtrim::val_str(String *str) { char chr=(*remove_str)[0]; #ifdef USE_MB - if (use_mb(res->str_charset) && !binary) + if (use_mb(res->charset()) && !binary) { while (ptr < end) { - if ((l=my_ismbchar(res->str_charset, ptr,end))) ptr+=l,p=ptr; + if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l,p=ptr; else ++ptr; } ptr=p; @@ -1063,12 +1063,12 @@ String *Item_func_rtrim::val_str(String *str) { const char *r_ptr=remove_str->ptr(); #ifdef USE_MB - if (use_mb(res->str_charset) && !binary) + if (use_mb(res->charset()) && !binary) { loop: while (ptr + remove_length < end) { - if ((l=my_ismbchar(res->str_charset, ptr,end))) ptr+=l; + if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l; else ++ptr; } if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length)) @@ -1114,14 +1114,14 @@ String *Item_func_trim::val_str(String *str) while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length)) ptr+=remove_length; #ifdef USE_MB - if (use_mb(res->str_charset) && !binary) + if (use_mb(res->charset()) && !binary) { char *p=ptr; register uint32 l; loop: while (ptr + remove_length < end) { - if ((l=my_ismbchar(res->str_charset, ptr,end))) ptr+=l; + if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l; else ++ptr; } if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length)) -- cgit v1.2.1 From bbde41e9f79b7461da9795bd9ccb9fb314ff5ada Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Mar 2002 17:33:10 +0400 Subject: Fix for crash in the case of non-string fields --- sql/filesort.cc | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'sql') diff --git a/sql/filesort.cc b/sql/filesort.cc index 54bd0543886..69279040643 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -925,10 +925,13 @@ sortlength(SORT_FIELD *sortorder, uint s_length) { sortorder->length=sortorder->field->pack_length(); #ifdef USE_STRCOLL - // BAR TODO: need checking that it is really Field_str based class - CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); - if (use_strcoll(cs) && !sortorder->field->binary()) - sortorder->length= sortorder->length*cs->strxfrm_multiply; + if (!sortorder->field->binary()) + { + // BAR TODO: need checking that it is really Field_str based class + CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); + if (use_strcoll(cs)) + sortorder->length= sortorder->length*cs->strxfrm_multiply; + } #endif } if (sortorder->field->maybe_null()) @@ -937,15 +940,19 @@ sortlength(SORT_FIELD *sortorder, uint s_length) else { #ifdef USE_STRCOLL - // BAR TODO: need checking that it is really Field_str based class - CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); + #endif switch ((sortorder->result_type=sortorder->item->result_type())) { case STRING_RESULT: sortorder->length=sortorder->item->max_length; #ifdef USE_STRCOLL - if (use_strcoll(cs) && !sortorder->item->binary) - sortorder->length= sortorder->length*cs->strxfrm_multiply; + if (!sortorder->item->binary) + { + // BAR TODO: need checking that it is really Field_str based class + CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); + if (use_strcoll(cs)) + sortorder->length= sortorder->length*cs->strxfrm_multiply; + } #endif break; case INT_RESULT: -- cgit v1.2.1 From 9f09ae660bcd27b4c19d85b4515b8566722c9eec Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Mar 2002 20:52:23 +0400 Subject: Added new method to set string's charset sql/item_cmpfunc.cc: Fix for IN, when String->charset is empty --- sql/item_cmpfunc.cc | 3 +++ sql/sql_string.h | 1 + 2 files changed, 4 insertions(+) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index d4ab03003ce..f1af89cfefc 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -890,6 +890,9 @@ void in_string::set(uint pos,Item *item) String *res=item->val_str(str); if (res && res != str) *str= *res; + // BAR TODO: I'm not sure this is absolutely correct + if (!str->charset()) + str->set_charset(default_charset_info); } byte *in_string::get_value(Item *item) diff --git a/sql/sql_string.h b/sql/sql_string.h index 811e49a0d02..9bf13b93628 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -74,6 +74,7 @@ public: { sql_element_free(ptr_arg); } ~String() { free(); } + inline void set_charset(CHARSET_INFO *charset) { str_charset=charset; } inline CHARSET_INFO *charset() const { return str_charset; } inline uint32 length() const { return str_length;} inline uint32 alloced_length() const { return Alloced_length;} -- cgit v1.2.1 From ac44fe1f1248138dfe22b0caa50c21e4d627d394 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Mar 2002 16:06:14 +0400 Subject: filesort.cc: Fixed that i mixed Field and Item in some cases sql/filesort.cc: Fixed that i mixed Field and Item in some cases --- sql/filesort.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/filesort.cc b/sql/filesort.cc index 69279040643..99eceb64703 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -470,8 +470,7 @@ static void make_sortkey(register SORTPARAM *param, switch (sort_field->result_type) { case STRING_RESULT: { - // BAR TODO: need checking that it is really Field_str based class - CHARSET_INFO *cs=((Field_str*)(sort_field->field))->charset(); + CHARSET_INFO *cs=item->str_value.charset(); if (item->maybe_null) *to++=1; @@ -947,9 +946,8 @@ sortlength(SORT_FIELD *sortorder, uint s_length) sortorder->length=sortorder->item->max_length; #ifdef USE_STRCOLL if (!sortorder->item->binary) - { - // BAR TODO: need checking that it is really Field_str based class - CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); + { + CHARSET_INFO *cs=sortorder->item->str_value.charset(); if (use_strcoll(cs)) sortorder->length= sortorder->length*cs->strxfrm_multiply; } -- cgit v1.2.1 From 2ec108107db299b3984a06746388798acbd95b0b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 26 Mar 2002 15:06:05 +0200 Subject: Derived tables ! mysql-test/r/union.result: small bug fixes in unions BitKeeper/etc/ignore: Added Docs/manual.texi.orig Docs/manual.texi.rej to the ignore list mysql-test/t/union.test: test for a bug fix in union's sql/sql_union.cc: bug fix for unions --- sql/mysql_priv.h | 1 + sql/sql_class.h | 6 ++- sql/sql_derived.cc | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++ sql/sql_lex.h | 8 ++-- sql/sql_parse.cc | 18 ++++++-- sql/sql_union.cc | 8 +++- sql/sql_yacc.yy | 24 +++++++++++ sql/table.h | 1 + 8 files changed, 175 insertions(+), 12 deletions(-) create mode 100644 sql/sql_derived.cc (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 728d6d7a35f..9f9ec229236 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -335,6 +335,7 @@ int mysql_select(THD *thd,TABLE_LIST *tables,List &list,COND *conds, ORDER *order, ORDER *group,Item *having,ORDER *proc_param, ulong select_type,select_result *result); int mysql_union(THD *thd,LEX *lex,select_result *result); +int mysql_derived(THD *thd,LEX *lex,SELECT_LEX *s, TABLE_LIST *t); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item_result_field ***copy_func, Field **from_field, bool group,bool modify_item); diff --git a/sql/sql_class.h b/sql/sql_class.h index 355987c259e..2c945ce7331 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -659,15 +659,17 @@ class Table_ident :public Sql_alloc { public: LEX_STRING db; LEX_STRING table; + SELECT_LEX *sel; inline Table_ident(LEX_STRING db_arg,LEX_STRING table_arg,bool force) - :table(table_arg) + :table(table_arg), sel((SELECT_LEX *)0) { if (!force && (current_thd->client_capabilities & CLIENT_NO_SCHEMA)) db.str=0; else db= db_arg; } - inline Table_ident(LEX_STRING table_arg) :table(table_arg) {db.str=0;} + inline Table_ident(LEX_STRING table_arg) :table(table_arg), sel((SELECT_LEX *)0) {db.str=0;} + inline Table_ident(SELECT_LEX *s) : sel(s) {db.str=0; table.str=(char *)""; table.length=0;} inline void change_db(char *db_name) { db.str= db_name; db.length=(uint) strlen(db_name); } }; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc new file mode 100644 index 00000000000..f1b60dd9b84 --- /dev/null +++ b/sql/sql_derived.cc @@ -0,0 +1,121 @@ +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +/* + Derived tables + These were introduced by Monty and Sinisa +*/ + + +#include "mysql_priv.h" +#include "sql_select.h" +#include "sql_acl.h" + +static const char *any_db="*any*"; // Special symbol for check_access + + +int mysql_derived(THD *thd, LEX *lex,SELECT_LEX *s, TABLE_LIST *t) +{ + SELECT_LEX *sl=s; + List item_list; + TABLE *table; + int res; + select_union *derived_result; + TABLE_LIST *tables=(TABLE_LIST *)sl->table_list.first; + TMP_TABLE_PARAM tmp_table_param; + DBUG_ENTER("mysql_derived"); + + if (tables) + res=check_table_access(thd,SELECT_ACL, tables); + else + res=check_access(thd, SELECT_ACL, any_db); + if (res) + DBUG_RETURN(-1); + + for (TABLE_LIST *cursor= (TABLE_LIST *)tables; + cursor; + cursor=cursor->next) + { + if (cursor->derived) + { + res=mysql_derived(thd,lex,(SELECT_LEX *)cursor->derived,cursor); + if (res) DBUG_RETURN(res); + } + } + Item *item; + List_iterator it(sl->item_list); + + while ((item= it++)) + item_list.push_back(item); + + if (!(res=open_and_lock_tables(thd,tables))) + { + if (tables && setup_fields(thd,tables,item_list,0,0,1)) + { + res=-1; + goto exit; + } + bzero((char*) &tmp_table_param,sizeof(tmp_table_param)); + tmp_table_param.field_count=item_list.elements; + if (!(table=create_tmp_table(thd, &tmp_table_param, sl->item_list, + (ORDER*) 0, 0, 1, 0, + (sl->options | thd->options | TMP_TABLE_ALL_COLUMNS)))) + { + res=-1; + goto exit; + } + + if ((derived_result=new select_union(table))) + { + thd->offset_limit=sl->offset_limit; + thd->select_limit=sl->select_limit+sl->offset_limit; + if (thd->select_limit < sl->select_limit) + thd->select_limit= HA_POS_ERROR; + if (thd->select_limit == HA_POS_ERROR) + sl->options&= ~OPTION_FOUND_ROWS; + + res=mysql_select(thd, tables, sl->item_list, + sl->where, (ORDER *) sl->order_list.first, + (ORDER*) sl->group_list.first, + sl->having, (ORDER*) NULL, + sl->options | thd->options | SELECT_NO_UNLOCK, + derived_result); + if (!res) + { +// Here we entirely fix both TABLE_LIST and list of SELECT's as there were no derived tables + if (derived_result->flush()) + res=1; + else + { + t->real_name=table->real_name; + t->table=table; + sl->prev->next=sl->next; + t->derived=(SELECT_LEX *)0; // just in case ... + if (!sl->next) lex->last_select = sl; + } + } + delete derived_result; + } + if (res) + free_tmp_table(thd,table); +exit: + close_thread_tables(thd); + if (res > 0) + send_error(&thd->net, ER_UNKNOWN_COM_ERROR); // temporary only ... + } + DBUG_RETURN(res); +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index c0ede015eb8..5a4cabbfb9c 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -101,7 +101,7 @@ typedef struct st_lex_master_info } LEX_MASTER_INFO; -enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, NOT_A_SELECT}; +enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, NOT_A_SELECT, DERIVED_TABLE_TYPE}; /* The state of the lex parsing for selects */ @@ -120,7 +120,7 @@ typedef struct st_select_lex { List ftfunc_list; uint in_sum_expr, sort_default; bool create_refs, braces; - st_select_lex *next; + st_select_lex *next, *prev; } SELECT_LEX; @@ -141,7 +141,7 @@ public: typedef struct st_lex { uint yylineno,yytoklen; /* Simulate lex */ LEX_YYSTYPE yylval; - SELECT_LEX select_lex, *select; + SELECT_LEX select_lex, *select, *last_select; uchar *ptr,*tok_start,*tok_end,*end_of_query; char *length,*dec,*change,*name; char *backup_dir; /* For RESTORE/BACKUP */ @@ -185,7 +185,7 @@ typedef struct st_lex { uint grant,grant_tot_col,which_columns, union_option, mqh; thr_lock_type lock_option; bool drop_primary,drop_if_exists,local_file; - bool in_comment,ignore_space,verbose,simple_alter, option_type; + bool in_comment,ignore_space,verbose,simple_alter, option_type, derived_tables; } LEX; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7fd3db1fe21..b916122ee7f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1226,6 +1226,14 @@ mysql_execute_command(void) Skip if we are in the slave thread, some table rules have been given and the table list says the query should not be replicated */ + if (lex->derived_tables) + { + for (TABLE_LIST *cursor= tables; + cursor; + cursor=cursor->next) + if (cursor->derived && mysql_derived(thd,lex,(SELECT_LEX *)cursor->derived,cursor)) + DBUG_VOID_RETURN; + } if ((lex->select_lex.next && create_total_list(thd,lex,&tables)) || (table_rules_on && tables && thd->slave_thread && !tables_ok(thd,tables))) @@ -2648,7 +2656,7 @@ mysql_init_query(THD *thd) thd->lex.value_list.empty(); thd->lex.select_lex.table_list.elements=0; thd->free_list=0; thd->lex.union_option=0; - thd->lex.select = &thd->lex.select_lex; + thd->lex.select = thd->lex.last_select = &thd->lex.select_lex; thd->lex.select_lex.table_list.first=0; thd->lex.select_lex.table_list.next= (byte**) &thd->lex.select_lex.table_list.first; thd->lex.select_lex.next=0; @@ -2675,7 +2683,7 @@ mysql_init_select(LEX *lex) select_lex->order_list.next= (byte**) &select_lex->order_list.first; select_lex->group_list.first=0; select_lex->group_list.next= (byte**) &select_lex->group_list.first; - select_lex->next = (SELECT_LEX *)NULL; + select_lex->next = select_lex->prev = (SELECT_LEX *)NULL; } bool @@ -2684,8 +2692,9 @@ mysql_new_select(LEX *lex) SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX)); if (!select_lex) return 1; + lex->select=lex->last_select; lex->select->next=select_lex; - lex->select=select_lex; + lex->select=lex->last_select=select_lex; select_lex->table_list.next= (byte**) &select_lex->table_list.first; select_lex->item_list.empty(); select_lex->when_list.empty(); @@ -3099,7 +3108,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, DBUG_RETURN(0); // End of memory alias_str= alias ? alias->str : table->table.str; if (table->table.length > NAME_LEN || - check_table_name(table->table.str,table->table.length) || + (table->table.length && check_table_name(table->table.str,table->table.length)) || table->db.str && check_db_name(table->db.str)) { net_printf(&thd->net,ER_WRONG_TABLE_NAME,table->table.str); @@ -3122,6 +3131,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, ptr->real_name=table->table.str; ptr->lock_type=flags; ptr->updating=updating; + ptr->derived=(SELECT_LEX *)table->sel; if (use_index) ptr->use_index=(List *) thd->memdup((gptr) use_index, sizeof(*use_index)); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 7532f43a663..1658fa701c5 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -126,8 +126,9 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) } union_result->save_time_stamp=!describe; - for (sl=lex->select=&lex->select_lex;sl;sl=lex->select=sl->next) + for (sl= &lex->select_lex; sl; sl=sl->next) { + lex->select=sl; thd->offset_limit=sl->offset_limit; thd->select_limit=sl->select_limit+sl->offset_limit; if (thd->select_limit < sl->select_limit) @@ -185,7 +186,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) thd->options&= ~OPTION_FOUND_ROWS; } else - thd->select_limit= HA_POS_ERROR; // no limit + { + thd->offset_limit= 0; + thd->select_limit= thd->default_select_limit; + } if (describe) thd->select_limit= HA_POS_ERROR; // no limit res=mysql_select(thd,&result_table_list, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3c9c005fb48..ee31e726eb1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2099,6 +2099,30 @@ join_table: } | '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}' { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; } + | '(' SELECT_SYM select_part3 ')' opt_table_alias + { + LEX *lex=Lex; + lex->select=lex->select->prev; + if (!($$=add_table_to_list(new Table_ident(Lex->last_select),$5,0,TL_UNLOCK))) + YYABORT; + } + +select_part3: + { + LEX *lex=Lex; + lex->derived_tables=true; + SELECT_LEX *tmp=lex->select; + if (lex->select->linkage == NOT_A_SELECT || mysql_new_select(lex)) + YYABORT; + mysql_init_select(lex); + lex->select->linkage=DERIVED_TABLE_TYPE; + lex->select->prev=tmp; + } + select_options select_item_list select_intoto + +select_intoto: + limit_clause {} + | select_from opt_outer: /* empty */ {} diff --git a/sql/table.h b/sql/table.h index 259c34030b2..211a8ea816e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -147,6 +147,7 @@ typedef struct st_table_list { bool straight; /* optimize with prev table */ bool updating; /* for replicate-do/ignore table */ bool shared; /* Used twice in union */ + void *derived; } TABLE_LIST; typedef struct st_open_table_list -- cgit v1.2.1 From 437b0b0e871350b8937c8d37c9c2b2f05299bfb7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 28 Mar 2002 17:31:46 +0400 Subject: New UTF8 charset strings/ctype-big5.c: New format for mb char functions strings/ctype-euc_kr.c: New format for mb char functions strings/ctype-gb2312.c: New format for mb char functions strings/ctype-gbk.c: New format for mb char functions strings/ctype-sjis.c: New format for mb char functions strings/ctype-ujis.c: New format for mb char functions --- sql/init.cc | 5 ++++- sql/share/charsets/Index | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/init.cc b/sql/init.cc index fe80c282563..eea10e51bd8 100644 --- a/sql/init.cc +++ b/sql/init.cc @@ -57,7 +57,10 @@ void unireg_init(ulong options) for (cs=compiled_charsets; cs->number; cs++) { - uchar max_char=cs->sort_order[(uchar) cs->max_sort_char]; + uchar max_char; + if (!cs->sort_order) + continue; + cs->sort_order[(uchar) cs->max_sort_char]; for (i = 0; i < 256; i++) { if ((uchar) cs->sort_order[i] > max_char) diff --git a/sql/share/charsets/Index b/sql/share/charsets/Index index 9781b516f97..565b98a1c60 100644 --- a/sql/share/charsets/Index +++ b/sql/share/charsets/Index @@ -37,3 +37,4 @@ cp1257 29 latin5 30 latin1_de 31 armscii8 32 +utf8 33 -- cgit v1.2.1 From f29e7f5726a5982d87bf1be1f273a24a0c1f1c19 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Mar 2002 18:22:21 +0400 Subject: Charset convertion operator CONVERT( string USING charset) --- sql/item_strfunc.cc | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ sql/item_strfunc.h | 13 +++++++++++ sql/sql_yacc.yy | 10 ++++++++ 3 files changed, 90 insertions(+) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index cfbfda97148..90f27148578 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1776,6 +1776,73 @@ String *Item_func_conv::val_str(String *str) } +String *Item_func_conv_charset::val_str(String *str) +{ + my_wc_t wc; + int cnvres; + const uchar *s, *se; + uchar *d, *d0, *de; + uint dmaxlen; + String *arg= args[0]->val_str(str); + CHARSET_INFO *from,*to; + + if (!arg) + { + null_value=1; + return 0; + } + + from=arg->charset(); + to=conv_charset; + + s=(const uchar*)arg->ptr(); + se=s+arg->length(); + + dmaxlen=arg->length()*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1)+1; + str->alloc(dmaxlen); + d0=d=(unsigned char*)str->ptr(); + de=d+dmaxlen; + + while( s < se && d < de){ + + cnvres=from->mb_wc(from,&wc,s,se); + if (cnvres>0) + { + s+=cnvres; + } + else if (cnvres==MY_CS_ILSEQ) + { + s++; + wc='?'; + } + else + break; + +outp: + cnvres=to->wc_mb(to,wc,d,de); + if (cnvres>0) + { + d+=cnvres; + } + else if (cnvres==MY_CS_ILUNI && wc!='?') + { + wc='?'; + goto outp; + } + else + break; + }; + + str->length((uint) (d-d0)); + str->set_charset(to); + return str; +} + +void Item_func_conv_charset::fix_length_and_dec() +{ + /* BAR TODO: What to do here??? */ +} + String *Item_func_hex::val_str(String *str) { if (args[0]->result_type() != STRING_RESULT) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index a8768e62f98..5dcf24cfef6 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -476,6 +476,19 @@ public: void fix_length_and_dec() { decimals = 0; max_length=3*8+7; } }; +class Item_func_conv_charset :public Item_str_func +{ + CHARSET_INFO *conv_charset; +public: + Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) + { + conv_charset=cs; + } + String *val_str(String *); + void fix_length_and_dec(); + const char *func_name() const { return "conv_charset"; } +}; + /******************************************************* Spatial functions diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ee31e726eb1..9ca5b44aa64 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1654,6 +1654,16 @@ simple_expr: | CASE_SYM opt_expr WHEN_SYM when_list opt_else END { $$= new Item_func_case(* $4, $2, $5 ); } | CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); } + | CONVERT_SYM '(' expr USING IDENT ')' + { + CHARSET_INFO *cs=find_compiled_charset_by_name($5.str); + if (!cs) + { + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$5); + YYABORT; + } + $$= new Item_func_conv_charset($3,cs); + } | FUNC_ARG0 '(' ')' { $$= ((Item*(*)(void))($1.symbol->create_func))();} | FUNC_ARG1 '(' expr ')' -- cgit v1.2.1 From 19bc62c86563b5a880c4db6828d0d1fca0dbc4d7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Mar 2002 19:11:06 +0400 Subject: Now this syntax works too: CONVERT(string,charset_to,charset_from) where charset_to and charset_from are expressions. For example: CONVERT('test','latin2','cp1250') sql/item_strfunc.cc: Now this syntax works too: CONVERT(string,charset_to,charset_from) sql/item_strfunc.h: Now this syntax works too: CONVERT(string,charset_to,charset_from) sql/sql_yacc.yy: Now this syntax works too: CONVERT(string,charset_to,charset_from) --- sql/item_strfunc.cc | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++ sql/item_strfunc.h | 10 ++++++++ sql/sql_yacc.yy | 4 +++ 3 files changed, 87 insertions(+) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 90f27148578..df238a6c331 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1843,6 +1843,79 @@ void Item_func_conv_charset::fix_length_and_dec() /* BAR TODO: What to do here??? */ } + +String *Item_func_conv_charset3::val_str(String *str) +{ + my_wc_t wc; + int cnvres; + const uchar *s, *se; + uchar *d, *d0, *de; + uint dmaxlen; + String *arg= args[0]->val_str(str); + String *to_cs= args[1]->val_str(str); + String *from_cs= args[2]->val_str(str); + CHARSET_INFO *from_charset; + CHARSET_INFO *to_charset; + + if (!arg || args[0]->null_value || + !to_cs || args[1]->null_value || + !from_cs || args[2]->null_value || + !(from_charset=find_compiled_charset_by_name(from_cs->ptr())) || + !(to_charset=find_compiled_charset_by_name(to_cs->ptr()))) + { + null_value=1; + return 0; + } + + s=(const uchar*)arg->ptr(); + se=s+arg->length(); + + dmaxlen=arg->length()*(to_charset->mbmaxlen?to_charset->mbmaxlen:1)+1; + str->alloc(dmaxlen); + d0=d=(unsigned char*)str->ptr(); + de=d+dmaxlen; + + while( s < se && d < de){ + + cnvres=from_charset->mb_wc(from_charset,&wc,s,se); + if (cnvres>0) + { + s+=cnvres; + } + else if (cnvres==MY_CS_ILSEQ) + { + s++; + wc='?'; + } + else + break; + +outp: + cnvres=to_charset->wc_mb(to_charset,wc,d,de); + if (cnvres>0) + { + d+=cnvres; + } + else if (cnvres==MY_CS_ILUNI && wc!='?') + { + wc='?'; + goto outp; + } + else + break; + }; + + str->length((uint) (d-d0)); + str->set_charset(to_charset); + return str; +} + +void Item_func_conv_charset3::fix_length_and_dec() +{ + /* BAR TODO: What to do here??? */ +} + + String *Item_func_hex::val_str(String *str) { if (args[0]->result_type() != STRING_RESULT) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 5dcf24cfef6..091289fd040 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -489,6 +489,16 @@ public: const char *func_name() const { return "conv_charset"; } }; +class Item_func_conv_charset3 :public Item_str_func +{ +public: + Item_func_conv_charset3(Item *arg1,Item *arg2,Item *arg3) + :Item_str_func(arg1,arg2,arg3) {} + String *val_str(String *); + void fix_length_and_dec(); + const char *func_name() const { return "conv_charset3"; } +}; + /******************************************************* Spatial functions diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9ca5b44aa64..90ecb4c92fc 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1664,6 +1664,10 @@ simple_expr: } $$= new Item_func_conv_charset($3,cs); } + | CONVERT_SYM '(' expr ',' expr ',' expr ')' + { + $$= new Item_func_conv_charset3($3,$5,$7); + } | FUNC_ARG0 '(' ')' { $$= ((Item*(*)(void))($1.symbol->create_func))();} | FUNC_ARG1 '(' expr ')' -- cgit v1.2.1 From 4206cf1289ac489ca2cbbf135096f3324fb2407d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Mar 2002 19:27:21 +0400 Subject: add sql_derived.cc into compilation --- sql/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index c83b5388ca0..f58075358b6 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -79,7 +79,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \ sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ - slave.cc sql_repl.cc sql_union.cc \ + slave.cc sql_repl.cc sql_union.cc sql_derived.cc \ mini_client.cc mini_client_errors.c \ stacktrace.c repl_failsafe.h repl_failsafe.cc \ gstream.cc spatial.cc -- cgit v1.2.1 From b68daf5c8348599df38ef5a692e405f161dae094 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Mar 2002 19:54:21 +0400 Subject: Big5 conversion routines include/m_ctype.h: Add conversion routines prototypes sql/init.cc: Fix for small bug --- sql/init.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/init.cc b/sql/init.cc index eea10e51bd8..ac0ff701649 100644 --- a/sql/init.cc +++ b/sql/init.cc @@ -60,7 +60,7 @@ void unireg_init(ulong options) uchar max_char; if (!cs->sort_order) continue; - cs->sort_order[(uchar) cs->max_sort_char]; + max_char=cs->sort_order[(uchar) cs->max_sort_char]; for (i = 0; i < 256; i++) { if ((uchar) cs->sort_order[i] > max_char) -- cgit v1.2.1 From ad494a211ca565bcb6b7a64a9f7f41d4fbc5c4d4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Mar 2002 20:27:53 +0400 Subject: item_strfunc.cc: Fix for possible bug when string length is more than 64K sql/item_strfunc.cc: Fix for possible bug when string length is more than 64K --- sql/item_strfunc.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index df238a6c331..9c1daf2edb3 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1782,7 +1782,7 @@ String *Item_func_conv_charset::val_str(String *str) int cnvres; const uchar *s, *se; uchar *d, *d0, *de; - uint dmaxlen; + uint32 dmaxlen; String *arg= args[0]->val_str(str); CHARSET_INFO *from,*to; @@ -1833,7 +1833,7 @@ outp: break; }; - str->length((uint) (d-d0)); + str->length((uint32) (d-d0)); str->set_charset(to); return str; } @@ -1850,7 +1850,7 @@ String *Item_func_conv_charset3::val_str(String *str) int cnvres; const uchar *s, *se; uchar *d, *d0, *de; - uint dmaxlen; + uint32 dmaxlen; String *arg= args[0]->val_str(str); String *to_cs= args[1]->val_str(str); String *from_cs= args[2]->val_str(str); @@ -1905,7 +1905,7 @@ outp: break; }; - str->length((uint) (d-d0)); + str->length((uint32) (d-d0)); str->set_charset(to_charset); return str; } -- cgit v1.2.1 From 32ac1ef044428947f6396a47c275d06975133c8c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 16 Apr 2002 18:21:53 +0500 Subject: Some fixes after merging changes from 4.0 include/hash.h: Monty forgot to add H in left part of macros mysys/hash.c: I wonder how it happened that my_bool disappeared sql/sql_acl.cc: Somebody forgot ) sql/sql_class.h: I wonder how it happened that this line disappeared sql/sql_table.cc: small typo sql/sql_yacc.yy: Having ; is more compatible --- sql/sql_acl.cc | 2 +- sql/sql_class.h | 1 + sql/sql_table.cc | 2 +- sql/sql_yacc.yy | 34 +++++++++++++++++----------------- 4 files changed, 20 insertions(+), 19 deletions(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 403d08ad0ab..1398b2ce84f 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -941,7 +941,7 @@ bool change_password(THD *thd, const char *host, const char *user, if (!thd->slave_thread && (strcmp(thd->user,user) || - my_strcasecmp(system_charset_info, host,thd->host_or_ip)) + my_strcasecmp(system_charset_info, host,thd->host_or_ip))) { if (check_access(thd, UPDATE_ACL, "mysql",0,1)) DBUG_RETURN(1); diff --git a/sql/sql_class.h b/sql/sql_class.h index d111ff3df8e..1b1340c07a2 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -222,6 +222,7 @@ public: const char *Name; Key(enum Keytype type_par,const char *name_arg,List &cols) + :type(type_par), columns(cols),Name(name_arg) {} Key(enum Keytype type_par, enum ha_key_alg alg_par, const char *name_arg, List &cols) :type(type_par), algorithm(alg_par), columns(cols), Name(name_arg) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b88db94c767..19fcf5970c2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -454,7 +454,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, key_info->flags = HA_NOSAME; } - key_info->key_alg = key->alg; + key_info->key_alg = key->algorithm; key_info->key_parts=(uint8) key->columns.elements; key_info->key_part=key_part_info; key_info->usable_key_parts= key_number; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 18b8e5bb824..77a70093036 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1154,7 +1154,7 @@ opt_unique_or_fulltext: key_alg: /* empty */ { $$= HA_KEY_ALG_BTREE; } - | USING opt_btree_or_rtree { $$= $2 } + | USING opt_btree_or_rtree { $$= $2; } opt_btree_or_rtree: BTREE_SYM { $$= HA_KEY_ALG_BTREE; } @@ -1784,9 +1784,9 @@ simple_expr: | FIELD_FUNC '(' expr ',' expr_list ')' { $$= new Item_func_field($3, *$5); } | GEOMFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | GEOMFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | GEOMETRYCOLLECTION '(' expr_list ')' { $$= new Item_func_spatial_collection(* $3, Geometry::wkbGeometryCollection, @@ -1823,17 +1823,17 @@ simple_expr: | LOCATE '(' expr ',' expr ',' expr ')' { $$= new Item_func_locate($5,$3,$7); } | GEOMCOLLFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | GEOMCOLLFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | GREATEST_SYM '(' expr ',' expr_list ')' { $5->push_front($3); $$= new Item_func_max(*$5); } | LEAST_SYM '(' expr ',' expr_list ')' { $5->push_front($3); $$= new Item_func_min(*$5); } | LINEFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | LINEFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | MINUTE_SYM '(' expr ')' { $$= new Item_func_minute($3); } | MONTH_SYM '(' expr ')' @@ -1842,17 +1842,17 @@ simple_expr: { $$= new Item_func_spatial_collection(* $3, Geometry::wkbMultiLineString, Geometry::wkbLineString); } | MLINEFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | MLINEFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | MPOINTFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | MPOINTFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | MPOLYFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | MPOLYFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | MULTIPOINT '(' expr_list ')' { $$= new Item_func_spatial_collection(* $3, Geometry::wkbMultiPoint, Geometry::wkbPoint); } @@ -1868,13 +1868,13 @@ simple_expr: $$= new Item_func_password($3); } | POINTFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | POINTFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | POLYFROMTEXT '(' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | POLYFROMTEXT '(' expr ',' expr ')' - { $$= new Item_func_geometry_from_text($3) } + { $$= new Item_func_geometry_from_text($3); } | POLYGON '(' expr_list ')' { $$= new Item_func_spatial_collection(* $3, Geometry::wkbPolygon, Geometry::wkbLineString); } -- cgit v1.2.1 From 08665a17e0642b1a7103ac5ff39b7a7ab3894356 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 17 Apr 2002 14:16:26 +0500 Subject: New win1250ch charset --- sql/share/charsets/Index | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/share/charsets/Index b/sql/share/charsets/Index index 565b98a1c60..075cdc9872b 100644 --- a/sql/share/charsets/Index +++ b/sql/share/charsets/Index @@ -38,3 +38,4 @@ latin5 30 latin1_de 31 armscii8 32 utf8 33 +win1250ch 34 -- cgit v1.2.1 From e8b6c9646eb44a3fd000a7e7996f8e6bf4de7da6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Apr 2002 11:53:59 +0500 Subject: Fix for AsText() spatial function sql/item_strfunc.cc: Fix for the case when argument args[0] and result str are the same strings --- sql/item_strfunc.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 4a7e5dfe33f..9c791453fd8 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2128,12 +2128,16 @@ String *Item_func_as_text::val_str(String *str) { String *wkt = args[0]->val_str(str); Geometry geom; - - str->length(0); + if ((null_value=(args[0]->null_value || - geom.create_from_wkb(wkt->ptr(),wkt->length()) || - geom.as_wkt(str)))) + geom.create_from_wkb(wkt->ptr(),wkt->length())))) + return 0; + + str->length(0); + + if ((null_value=geom.as_wkt(str))) return 0; + return str; } -- cgit v1.2.1 From c7e72e8d55067b2638a7e8ee6561b0b42008d6de Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Apr 2002 14:08:38 +0500 Subject: Fix to use Monty's changes in frm format Enable latin1 by default configure.in: Always compile latin1 sql/ha_myisam.cc: Fix for "SHOW KEYS FROM table" and various key types sql/sql_show.cc: Fix to use Monty's changes in frm format sql/sql_table.cc: Fix to use Monty's changes in frm format sql/structs.h: Fix to use Monty's changes in frm format sql/table.cc: Fix to use Monty's changes in frm format --- sql/ha_myisam.cc | 8 ++++++-- sql/sql_show.cc | 2 +- sql/sql_table.cc | 11 +++++++---- sql/structs.h | 1 - sql/table.cc | 13 +++++++++++-- 5 files changed, 25 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index df4de96b6c5..eabf9536fd0 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -124,8 +124,12 @@ const char **ha_myisam::bas_ext() const const char *ha_myisam::index_type(uint key_number) { - return ((table->key_info[key_number].flags & HA_FULLTEXT) ? + return ((table->key_info[key_number].flags & HA_FULLTEXT) ? "FULLTEXT" : + (table->key_info[key_number].flags & HA_SPATIAL) ? + "SPATIAL" : + (table->key_info[key_number].algorithm == HA_KEY_ALG_RTREE) ? + "RTREE" : "BTREE"); } @@ -1006,7 +1010,7 @@ int ha_myisam::create(const char *name, register TABLE *table, for (i=0; i < table->keys ; i++, pos++) { keydef[i].flag= (pos->flags & (HA_NOSAME | HA_FULLTEXT | HA_SPATIAL)); - keydef[i].key_alg=pos->key_alg; // +BAR + keydef[i].key_alg=pos->algorithm; keydef[i].seg=keyseg; keydef[i].keysegs=pos->key_parts; for (j=0 ; j < pos->key_parts ; j++) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 0aa0c643ba9..95705c19d68 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -890,7 +890,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) append_identifier(thd,packet,key_info->name); // +BAR: send USING only in non-default case: non-spatial rtree - if((key_info->key_alg == HA_KEY_ALG_RTREE) && !(key_info->flags & HA_SPATIAL)) + if((key_info->algorithm == HA_KEY_ALG_RTREE) && !(key_info->flags & HA_SPATIAL)) packet->append(" USING RTREE",12); packet->append(" (", 2); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 19fcf5970c2..f5cb9a07a41 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -454,7 +454,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, key_info->flags = HA_NOSAME; } - key_info->key_alg = key->algorithm; + key_info->algorithm = key->algorithm; key_info->key_parts=(uint8) key->columns.elements; key_info->key_part=key_part_info; key_info->usable_key_parts= key_number; @@ -476,7 +476,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, in near future when new frm file is ready checking for proper key parts number: */ - + +printf("key_info->flags=%d key_info->algorithm=%d\n", + key_info->flags,key_info->algorithm); + if(key_info->flags == HA_SPATIAL){ if(key_info->key_parts!=1){ my_printf_error(ER_WRONG_ARGUMENTS, @@ -485,7 +488,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } }else { - if(key_info->key_alg == HA_KEY_ALG_RTREE){ + if(key_info->algorithm == HA_KEY_ALG_RTREE){ if((key_info->key_parts&1)==1){ my_printf_error(ER_WRONG_ARGUMENTS, ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); @@ -1584,7 +1587,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, Key::PRIMARY : Key::UNIQUE) : (key_info->flags & HA_FULLTEXT ? Key::FULLTEXT : Key::MULTIPLE)), - key_info->key_alg, + key_info->algorithm, key_name,key_parts)); } key_it.rewind(); diff --git a/sql/structs.h b/sql/structs.h index 978a523df7f..2250ea784f2 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -64,7 +64,6 @@ typedef struct st_key_part_info { /* Info about a key part */ typedef struct st_key { uint key_length; /* Tot length of key */ uint flags; /* dupp key and pack flags */ - enum ha_key_alg key_alg; /* +BAR Algorithm BTREE or RTREE */ uint key_parts; /* How many key_parts */ uint extra_length; uint usable_key_parts; /* Should normally be = key_parts */ diff --git a/sql/table.cc b/sql/table.cc index 122357a1fb1..7e4faa1ba7c 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -201,6 +201,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, for (i=0 ; i < keys ; i++, keyinfo++) keyinfo->algorithm= (enum ha_key_alg) *(strpos++); } + else + { + /* Set key types to BTREE, BAR TODO: how to be with HASH/RBTREE? */ + keyinfo=outparam->key_info; + for (i=0 ; i < keys ; i++, keyinfo++) + keyinfo->algorithm= HA_KEY_ALG_BTREE; + } outparam->reclength = uint2korr((head+16)); if (*(head+26) == 1) outparam->system=1; /* one-record-database */ @@ -408,10 +415,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, } } - keyinfo->key_alg=HA_KEY_ALG_BTREE; // BAR : btree by default + if (keyinfo->name[0]=='S') + keyinfo->flags |= HA_SPATIAL; -#define BAR_DIRTY_HACK #ifdef BAR_DIRTY_HACK + keyinfo->key_alg=HA_KEY_ALG_BTREE; // BAR : btree by default + // BAR FIXME: Dirty hack while waiting for new .frm format switch(keyinfo->name[0]){ case 'R': -- cgit v1.2.1 From 139a73cade4827ca2a41d6cfc9db379b2c696fa3 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Apr 2002 13:36:55 +0500 Subject: RB-Tree indexes support in HEAP tables Renamed _hp_func -> hp_func mi_key_cmp moved to /mysys/my_handler.c New tests for HEAP tables heap/_check.c: RB-tree index Renamed _hp_func -> hp_func heap/_rectest.c: RB-tree index Renamed _hp_func -> hp_func heap/heapdef.h: RB-tree index Renamed _hp_func -> hp_func heap/hp_block.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_clear.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_close.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_create.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_delete.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_hash.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_open.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_panic.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_rename.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_rfirst.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_rkey.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_rlast.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_rnext.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_rprev.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_rrnd.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_rsame.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_scan.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_test1.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_test2.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_update.c: RB-tree index Renamed _hp_func -> hp_func heap/hp_write.c: RB-tree index Renamed _hp_func -> hp_func include/Makefile.am: New include include/heap.h: RB-Tree index include/my_tree.h: new search functions new custom_arg argument include/myisam.h: Removed MI_KEYSEG isam/isamlog.c: Add custom_arg isam/pack_isam.c: Add custom_arg myisam/ft_nlq_search.c: Add custom_arg myisam/ft_parser.c: Add custom_arg myisam/ft_stopwords.c: Add custom_arg myisam/mi_search.c: Remove mi_key_cmp myisam/mi_write.c: Add custom_arg myisam/myisamdef.h: Remove mi_key_cmp myisam/myisamlog.c: Add custom_arg myisam/myisampack.c: Add custom_arg mysys/Makefile.am: New file my_handler.c mysys/tree.c: custom_arg new search functions sql/ha_heap.cc: RBTree sql/ha_myisam.cc: RBTree sql/item_sum.cc: custom_arg sql/sql_analyse.cc: custom_arg sql/sql_class.h: custom_arg sql/sql_table.cc: Remove duplicate code sql/sql_yacc.yy: UNDEF by default sql/table.cc: Remove dirty hack --- sql/ha_heap.cc | 103 ++++++++++++++++++++++++++++++++++------------------- sql/ha_myisam.cc | 3 +- sql/item_sum.cc | 2 +- sql/sql_analyse.cc | 10 +++--- sql/sql_class.h | 2 +- sql/sql_table.cc | 1 - sql/sql_yacc.yy | 2 +- sql/table.cc | 22 ------------ 8 files changed, 77 insertions(+), 68 deletions(-) (limited to 'sql') diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 5f482bca1e8..8a4758aa558 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -36,42 +36,59 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) uint key,parts,mem_per_row=0; ulong max_rows; HP_KEYDEF *keydef; - HP_KEYSEG *seg; + MI_KEYSEG *seg; for (key=parts=0 ; key < table->keys ; key++) + { parts+=table->key_info[key].key_parts; + if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE) + { + parts++; /* additional HA_KEYTYPE_END keyseg */ + } + } if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+ - parts*sizeof(HP_KEYSEG),MYF(MY_WME)))) + parts*sizeof(MI_KEYSEG),MYF(MY_WME)))) return my_errno; - seg=my_reinterpret_cast(HP_KEYSEG*) (keydef+table->keys); + seg=my_reinterpret_cast(MI_KEYSEG*) (keydef+table->keys); for (key=0 ; key < table->keys ; key++) { KEY *pos=table->key_info+key; KEY_PART_INFO *key_part= pos->key_part; KEY_PART_INFO *key_part_end= key_part+pos->key_parts; - mem_per_row += (pos->key_length + (sizeof(char*) * 2)); + mem_per_row+= (pos->key_length + (sizeof(char*) * 2)); - keydef[key].keysegs=(uint) pos->key_parts; - keydef[key].flag = (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); - keydef[key].seg=seg; + keydef[key].keysegs= (uint) pos->key_parts; + keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); + keydef[key].seg= seg; + keydef[key].algorithm= pos->algorithm == HA_KEY_ALG_UNDEF ? + HA_KEY_ALG_HASH : pos->algorithm; for (; key_part != key_part_end ; key_part++, seg++) { - uint flag=key_part->key_type; - Field *field=key_part->field; - if (!f_is_packed(flag) && - f_packtype(flag) == (int) FIELD_TYPE_DECIMAL && - !(flag & FIELDFLAG_BINARY)) - seg->type= (int) HA_KEYTYPE_TEXT; + uint flag= key_part->key_type; + Field *field= key_part->field; + if (pos->algorithm == HA_KEY_ALG_BTREE) + { + seg->type= field->key_type(); + } else - seg->type= (int) HA_KEYTYPE_BINARY; - seg->start=(uint) key_part->offset; - seg->length=(uint) key_part->length; + { + if (!f_is_packed(flag) && + f_packtype(flag) == (int) FIELD_TYPE_DECIMAL && + !(flag & FIELDFLAG_BINARY)) + seg->type= (int) HA_KEYTYPE_TEXT; + else + seg->type= (int) HA_KEYTYPE_BINARY; + } + seg->start= (uint) key_part->offset; + seg->length= (uint) key_part->length; + seg->flag = 0; + seg->charset= default_charset_info; if (field->null_ptr) { - seg->null_bit=field->null_bit; + seg->null_bit= field->null_bit; seg->null_pos= (uint) (field->null_ptr- (uchar*) table->record[0]); } @@ -81,6 +98,16 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) seg->null_pos=0; } } + if (pos->algorithm == HA_KEY_ALG_BTREE) + { + /* additional HA_KEYTYPE_END keyseg */ + keydef[key].keysegs++; + seg->type= HA_KEYTYPE_END; + seg->length= sizeof(byte*); + seg->flag= 0; + seg->null_bit= 0; + seg++; + } } mem_per_row += MY_ALIGN(table->reclength+1, sizeof(char*)); max_rows = (ulong) (max_heap_table_size / mem_per_row); @@ -124,25 +151,21 @@ int ha_heap::delete_row(const byte * buf) return heap_delete(file,buf); } -int ha_heap::index_read(byte * buf, const byte * key, - uint key_len __attribute__((unused)), - enum ha_rkey_function find_flag - __attribute__((unused))) +int ha_heap::index_read(byte * buf, const byte * key, uint key_len, + enum ha_rkey_function find_flag) { - statistic_increment(ha_read_key_count,&LOCK_status); - int error=heap_rkey(file,buf,active_index, key); - table->status=error ? STATUS_NOT_FOUND: 0; + statistic_increment(ha_read_key_count, &LOCK_status); + int error = heap_rkey(file,buf,active_index, key, key_len, find_flag); + table->status = error ? STATUS_NOT_FOUND : 0; return error; } int ha_heap::index_read_idx(byte * buf, uint index, const byte * key, - uint key_len __attribute__((unused)), - enum ha_rkey_function find_flag - __attribute__((unused))) + uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(ha_read_key_count,&LOCK_status); - int error=heap_rkey(file, buf, index, key); - table->status=error ? STATUS_NOT_FOUND: 0; + statistic_increment(ha_read_key_count, &LOCK_status); + int error = heap_rkey(file, buf, index, key, key_len, find_flag); + table->status = error ? STATUS_NOT_FOUND : 0; return error; } @@ -279,12 +302,20 @@ ha_rows ha_heap::records_in_range(int inx, enum ha_rkey_function end_search_flag) { KEY *pos=table->key_info+inx; - if (start_key_len != end_key_len || - start_key_len != pos->key_length || - start_search_flag != HA_READ_KEY_EXACT || - end_search_flag != HA_READ_AFTER_KEY) - return HA_POS_ERROR; // Can't only use exact keys - return 10; // Good guess + if (pos->algorithm == HA_KEY_ALG_BTREE) + { + return hp_rb_records_in_range(file, inx, start_key, start_key_len, + start_search_flag, end_key, end_key_len, end_search_flag); + } + else + { + if (start_key_len != end_key_len || + start_key_len != pos->key_length || + start_search_flag != HA_READ_KEY_EXACT || + end_search_flag != HA_READ_AFTER_KEY) + return HA_POS_ERROR; // Can't only use exact keys + return 10; // Good guess + } } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index eabf9536fd0..3def79dc67f 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1010,7 +1010,8 @@ int ha_myisam::create(const char *name, register TABLE *table, for (i=0; i < table->keys ; i++, pos++) { keydef[i].flag= (pos->flags & (HA_NOSAME | HA_FULLTEXT | HA_SPATIAL)); - keydef[i].key_alg=pos->algorithm; + keydef[i].key_alg=pos->algorithm == HA_KEY_ALG_UNDEF ? + HA_KEY_ALG_BTREE : pos->algorithm; keydef[i].seg=keyseg; keydef[i].keysegs=pos->key_parts; for (j=0 ; j < pos->key_parts ; j++) diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 7ebeda19993..83bc2272515 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1106,7 +1106,7 @@ bool Item_sum_count_distinct::add() if(tree_to_myisam()) return 1; } - else if (!tree_insert(&tree, table->record[0] + rec_offset, 0)) + else if (!tree_insert(&tree, table->record[0] + rec_offset, 0, tree.custom_arg)) return 1; } else if ((error=table->file->write_row(table->record[0]))) diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index fc764333916..8f086863a4e 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -309,10 +309,10 @@ void field_str::add() { if (res != &s) s.copy(*res); - if (!tree_search(&tree, (void*) &s)) // If not in tree + if (!tree_search(&tree, (void*) &s, tree.custom_arg)) // If not in tree { s.copy(); // slow, when SAFE_MALLOC is in use - if (!tree_insert(&tree, (void*) &s, 0)) + if (!tree_insert(&tree, (void*) &s, 0, tree.custom_arg)) { room_in_tree = 0; // Remove tree, out of RAM ? delete_tree(&tree); @@ -411,7 +411,7 @@ void field_real::add() if (room_in_tree) { - if (!(element = tree_insert(&tree, (void*) &num, 0))) + if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg))) { room_in_tree = 0; // Remove tree, out of RAM ? delete_tree(&tree); @@ -464,7 +464,7 @@ void field_longlong::add() if (room_in_tree) { - if (!(element = tree_insert(&tree, (void*) &num, 0))) + if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg))) { room_in_tree = 0; // Remove tree, out of RAM ? delete_tree(&tree); @@ -518,7 +518,7 @@ void field_ulonglong::add() if (room_in_tree) { - if (!(element = tree_insert(&tree, (void*) &num, 0))) + if (!(element = tree_insert(&tree, (void*) &num, 0, tree.custom_arg))) { room_in_tree = 0; // Remove tree, out of RAM ? delete_tree(&tree); diff --git a/sql/sql_class.h b/sql/sql_class.h index 1b1340c07a2..3ffac72c1db 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -751,7 +751,7 @@ public: { if (tree.elements_in_tree > max_elements && flush()) return 1; - return !tree_insert(&tree,ptr,0); + return !tree_insert(&tree, ptr, 0, tree.custom_arg); } bool get(TABLE *table); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f5cb9a07a41..782caa8fa51 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -454,7 +454,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, key_info->flags = HA_NOSAME; } - key_info->algorithm = key->algorithm; key_info->key_parts=(uint8) key->columns.elements; key_info->key_part=key_part_info; key_info->usable_key_parts= key_number; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 77a70093036..6317b21a603 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1153,7 +1153,7 @@ opt_unique_or_fulltext: | SPATIAL_SYM { $$= Key::SPATIAL; } key_alg: - /* empty */ { $$= HA_KEY_ALG_BTREE; } + /* empty */ { $$= HA_KEY_ALG_UNDEF; } | USING opt_btree_or_rtree { $$= $2; } opt_btree_or_rtree: diff --git a/sql/table.cc b/sql/table.cc index 7e4faa1ba7c..3c217ced03c 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -415,28 +415,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, } } - if (keyinfo->name[0]=='S') - keyinfo->flags |= HA_SPATIAL; - -#ifdef BAR_DIRTY_HACK - keyinfo->key_alg=HA_KEY_ALG_BTREE; // BAR : btree by default - - // BAR FIXME: Dirty hack while waiting for new .frm format - switch(keyinfo->name[0]){ - case 'R': - keyinfo->key_alg=HA_KEY_ALG_RTREE; - break; - case 'S': - keyinfo->key_alg = HA_KEY_ALG_RTREE; - keyinfo->flags |= HA_SPATIAL; - break; - case 'B': - default: - keyinfo->key_alg=HA_KEY_ALG_BTREE; - break; - } -#endif - for (i=0 ; i < keyinfo->key_parts ; key_part++,i++) { if (new_field_pack_flag <= 1) -- cgit v1.2.1 From 3adee5046d70aa91fead16c289dd2a1b098b3dfd Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Apr 2002 15:10:29 +0500 Subject: MI_KEYSEG -> HA_KEYSEG _mi_key_cmp -> ha_key_cmp BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/ha_heap.cc | 6 +++--- sql/ha_myisam.cc | 4 ++-- sql/sql_select.cc | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 8a4758aa558..1abaa63de68 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -36,7 +36,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) uint key,parts,mem_per_row=0; ulong max_rows; HP_KEYDEF *keydef; - MI_KEYSEG *seg; + HA_KEYSEG *seg; for (key=parts=0 ; key < table->keys ; key++) { @@ -48,9 +48,9 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) } if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+ - parts*sizeof(MI_KEYSEG),MYF(MY_WME)))) + parts*sizeof(HA_KEYSEG),MYF(MY_WME)))) return my_errno; - seg=my_reinterpret_cast(MI_KEYSEG*) (keydef+table->keys); + seg=my_reinterpret_cast(HA_KEYSEG*) (keydef+table->keys); for (key=0 ; key < table->keys ; key++) { KEY *pos=table->key_info+key; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 3def79dc67f..a8bbc03aa91 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -993,7 +993,7 @@ int ha_myisam::create(const char *name, register TABLE *table, KEY *pos; MI_KEYDEF *keydef; MI_COLUMNDEF *recinfo,*recinfo_pos; - MI_KEYSEG *keyseg; + HA_KEYSEG *keyseg; uint options=table->db_options_in_use; DBUG_ENTER("ha_myisam::create"); @@ -1002,7 +1002,7 @@ int ha_myisam::create(const char *name, register TABLE *table, &recinfo,(table->fields*2+2)*sizeof(MI_COLUMNDEF), &keydef, table->keys*sizeof(MI_KEYDEF), &keyseg, - ((table->key_parts + table->keys) * sizeof(MI_KEYSEG)), + ((table->key_parts + table->keys) * sizeof(HA_KEYSEG)), 0))) DBUG_RETURN(1); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2abefe0aac5..2599fe216c5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3942,7 +3942,7 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, if (table->keys) { // Get keys for ni_create bool using_unique_constraint=0; - MI_KEYSEG *seg= (MI_KEYSEG*) sql_calloc(sizeof(*seg) * + HA_KEYSEG *seg= (HA_KEYSEG*) sql_calloc(sizeof(*seg) * keyinfo->key_parts); if (!seg) goto err; -- cgit v1.2.1 From 234dc3a35e8ae7f63aa6d3b7891b72e735728639 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Apr 2002 13:53:29 +0500 Subject: Index number argument Fix in test results heap/hp_rfirst.c: Index number argument heap/hp_rlast.c: Index number argument heap/hp_test2.c: Index number argument include/heap.h: Index number argument mysql-test/r/heap_btree.result: Test results fix sql/ha_heap.cc: Index number argument --- sql/ha_heap.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 1abaa63de68..43485a97fe3 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -189,7 +189,7 @@ int ha_heap::index_prev(byte * buf) int ha_heap::index_first(byte * buf) { statistic_increment(ha_read_first_count,&LOCK_status); - int error=heap_rfirst(file, buf); + int error=heap_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; } @@ -197,7 +197,7 @@ int ha_heap::index_first(byte * buf) int ha_heap::index_last(byte * buf) { statistic_increment(ha_read_last_count,&LOCK_status); - int error=heap_rlast(file, buf); + int error=heap_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; } -- cgit v1.2.1 From d822b0d5222b5522598608c495330901b98a9fb2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 May 2002 22:47:57 +0300 Subject: fixed bug in derived tables if derived tables more than 1 mysql-test/r/derived.result: added test of found bug in derived tables mysql-test/t/derived.test: added test of found bug in derived tables --- sql/sql_yacc.yy | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6317b21a603..24321dbdb53 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2155,8 +2155,10 @@ join_table: | '(' SELECT_SYM select_part3 ')' opt_table_alias { LEX *lex=Lex; + SELECT_LEX *select_to_execute= lex->select; lex->select=lex->select->prev; - if (!($$=add_table_to_list(new Table_ident(Lex->last_select),$5,0,TL_UNLOCK))) + if (!($$=add_table_to_list(new Table_ident(select_to_execute), + $5,0,TL_UNLOCK))) YYABORT; } -- cgit v1.2.1 From 2c62a868a60058a8664dcf3e45cdd86b41635ddd Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 May 2002 00:04:16 +0300 Subject: new SELECT_LEX structure mysql-test/r/derived.result: derived table bug test mysql-test/t/derived.test: derived table bug test sql/mysql_priv.h: new mysql_new_select call & layout fixing sql/sql_class.h: passing unit as parameter of Table_ident constructor sql/sql_lex.cc: new SELECT_LEX structure methods sql/sql_lex.h: new SELECT_LEX structure definition sql/table.h: fixed layout --- sql/mysql_priv.h | 6 +-- sql/sql_class.h | 21 +++++--- sql/sql_derived.cc | 19 ++++--- sql/sql_lex.cc | 115 +++++++++++++++++++++++++++++++++++++++++ sql/sql_lex.h | 149 +++++++++++++++++++++++++++++++++++++++++++++++------ sql/sql_parse.cc | 88 +++++++++++++++---------------- sql/sql_union.cc | 28 +++++----- sql/sql_yacc.yy | 24 +++++---- sql/table.h | 16 +++--- 9 files changed, 359 insertions(+), 107 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 4c71e845207..a0dad53b4e2 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -291,7 +291,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list); bool mysql_change_db(THD *thd,const char *name); void mysql_parse(THD *thd,char *inBuf,uint length); void mysql_init_select(LEX *lex); -bool mysql_new_select(LEX *lex); +bool mysql_new_select(LEX *lex, bool move_down); void mysql_init_multi_delete(LEX *lex); void init_max_user_conn(void); void free_max_user_conn(void); @@ -360,8 +360,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result); int mysql_select(THD *thd,TABLE_LIST *tables,List &list,COND *conds, ORDER *order, ORDER *group,Item *having,ORDER *proc_param, ulong select_type,select_result *result); -int mysql_union(THD *thd,LEX *lex,select_result *result); -int mysql_derived(THD *thd,LEX *lex,SELECT_LEX *s, TABLE_LIST *t); +int mysql_union(THD *thd, LEX *lex,select_result *result); +int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item_result_field ***copy_func, Field **from_field, bool group,bool modify_item); diff --git a/sql/sql_class.h b/sql/sql_class.h index 3ffac72c1db..56a0d6a44df 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -706,19 +706,28 @@ class Table_ident :public Sql_alloc { public: LEX_STRING db; LEX_STRING table; - SELECT_LEX *sel; - inline Table_ident(LEX_STRING db_arg,LEX_STRING table_arg,bool force) - :table(table_arg), sel((SELECT_LEX *)0) + SELECT_LEX_UNIT *sel; + inline Table_ident(LEX_STRING db_arg, LEX_STRING table_arg, bool force) + :table(table_arg), sel((SELECT_LEX_UNIT *)0) { if (!force && (current_thd->client_capabilities & CLIENT_NO_SCHEMA)) db.str=0; else db= db_arg; } - inline Table_ident(LEX_STRING table_arg) :table(table_arg), sel((SELECT_LEX *)0) {db.str=0;} - inline Table_ident(SELECT_LEX *s) : sel(s) {db.str=0; table.str=(char *)""; table.length=0;} + inline Table_ident(LEX_STRING table_arg) + :table(table_arg), sel((SELECT_LEX_UNIT *)0) + { + db.str=0; + } + inline Table_ident(SELECT_LEX_UNIT *s) : sel(s) + { + db.str=0; table.str=(char *)""; table.length=0; + } inline void change_db(char *db_name) - { db.str= db_name; db.length=(uint) strlen(db_name); } + { + db.str= db_name; db.length= (uint) strlen(db_name); + } }; // this is needed for user_vars hash diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index f1b60dd9b84..79343ef4ae0 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -28,21 +28,25 @@ static const char *any_db="*any*"; // Special symbol for check_access -int mysql_derived(THD *thd, LEX *lex,SELECT_LEX *s, TABLE_LIST *t) +int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t) { - SELECT_LEX *sl=s; + /* + TODO: make derived tables with union inside (now only 1 SELECT may be + procesed) + */ + SELECT_LEX *sl= (SELECT_LEX*)s->slave; List item_list; TABLE *table; int res; select_union *derived_result; - TABLE_LIST *tables=(TABLE_LIST *)sl->table_list.first; + TABLE_LIST *tables= (TABLE_LIST *)sl->table_list.first; TMP_TABLE_PARAM tmp_table_param; DBUG_ENTER("mysql_derived"); if (tables) - res=check_table_access(thd,SELECT_ACL, tables); + res= check_table_access(thd,SELECT_ACL, tables); else - res=check_access(thd, SELECT_ACL, any_db); + res= check_access(thd, SELECT_ACL, any_db); if (res) DBUG_RETURN(-1); @@ -52,7 +56,7 @@ int mysql_derived(THD *thd, LEX *lex,SELECT_LEX *s, TABLE_LIST *t) { if (cursor->derived) { - res=mysql_derived(thd,lex,(SELECT_LEX *)cursor->derived,cursor); + res=mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, cursor); if (res) DBUG_RETURN(res); } } @@ -103,9 +107,8 @@ int mysql_derived(THD *thd, LEX *lex,SELECT_LEX *s, TABLE_LIST *t) { t->real_name=table->real_name; t->table=table; - sl->prev->next=sl->next; + sl->exclude(); t->derived=(SELECT_LEX *)0; // just in case ... - if (!sl->next) lex->last_select = sl; } } delete derived_result; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 31ec6d1cecc..3b17c8d498a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -879,3 +879,118 @@ int yylex(void *arg) } } } + +/* + st_select_lex structures initialisations +*/ + +void st_select_lex_node::init_query() +{ + next= master= slave= link_next= 0; + prev= link_prev= 0; +} + +void st_select_lex_node::init_select() +{ + order_list.elements= 0; + order_list.first= 0; + order_list.next= (byte**) &order_list.first; + select_limit= offset_limit= 0; +} + +void st_select_lex_unit::init_query() +{ + st_select_lex_node::init_query(); + global_parameters= this; + select_limit_cnt= offset_limit_cnt= 0; +} + +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; + item_list.empty(); +} + +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; + options= 0; + where= having= 0; + when_list.empty(); + expr_list.empty(); + interval_list.empty(); + use_index.empty(); + ftfunc_list.empty(); + linkage=UNSPECIFIED_TYPE; +} + +/* + st_select_lex structures linking +*/ + +/* include on level down */ +void st_select_lex_node::include_down(st_select_lex_node *upper) +{ + if ((next= upper->slave)) + next->prev= &next; + prev= &upper->slave; + upper->slave= this; + master= upper; +} + +/* include neighbour (on same level) */ +void st_select_lex_node::include_neighbour(st_select_lex_node *before) +{ + if ((next= before->next)) + next->prev= &next; + prev= &before->next; + before->next= this; + master= before->master; +} + +/* including in global SELECT_LEX list */ +void st_select_lex_node::include_global(st_select_lex_node **plink) +{ + if ((link_next= *plink)) + link_next->link_prev= &link_next; + link_prev= plink; + *plink= this; +} + +//excluding from global list (internal function) +void st_select_lex_node::fast_exclude() +{ + if(link_prev) + { + if ((*link_prev= link_next)) + link_next->link_prev= link_prev; + // Remove slave structure + for (; slave; slave= slave->next) + slave->fast_exclude(); + } +} + +/* + excluding select_lex structure (except first (first select can't be + deleted, because it is most upper select)) +*/ +void st_select_lex_node::exclude() +{ + //exclude from global list + fast_exclude(); + //exclude from other structures + if ((*prev= next)) + next->prev= prev; + /* + We do not need following statements, because prev pointer of first + list element point to master->slave + if (master->slave == this) + master->slave= next; + */ +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 53422b050a3..7603157f66d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -103,28 +103,143 @@ typedef struct st_lex_master_info } LEX_MASTER_INFO; -enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, NOT_A_SELECT, DERIVED_TABLE_TYPE}; +enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, + EXCEPT_TYPE, GLOBAL_OPTIONS_TYPE, DERIVED_TABLE_TYPE}; -/* The state of the lex parsing for selects */ +/* + The state of the lex parsing for selects + + All select describing structures linked with following pointers: + - list of neighbors (next/prev) (prev of first element point to slave + pointer of upper structure) + - one level units for unit (union) structure + - member of one union(unit) for ordinary select_lex + - pointer to master + - outer select_lex for unit (union) + - unit structure for ordinary select_lex + - pointer to slave + - first list element of select_lex belonged to this unit for unit + - first unit in list of units that belong to this select_lex (as + subselects or derived tables) for ordinary select_lex + - list of all select_lex (for group operation like correcting list of opened + tables) + for example for following query: -typedef struct st_select_lex { + select * + from table1 + where table1.field IN (select * from table1_1_1 union + select * from table1_1_2) + union + select * + from table2 + where table2.field=(select (select f1 from table2_1_1_1_1 + where table2_1_1_1_1.f2=table2_1_1.f3) + from table2_1_1 + where table2_1_1.f1=table2.f2) + union + select * from table3; + + we will have following structure: + + + main unit + select1 select2 select3 + |^^ |^ + s||| ||master + l||| |+---------------------------------+ + a||| +---------------------------------+| + v|||master slave || + e||+-------------------------+ || + V| neighbor | V| + unit 1.1<==================>unit1.2 unit2.1 + select1.1.1 select 1.1.2 select1.2.1 select2.1.1 select2.1.2 + |^ + || + V| + unit2.1.1.1 + select2.1.1.1.1 + + + relation in main unit will be following: + + main unit + |^^^ + |||| + |||+------------------------------+ + ||+--------------+ | + slave||master | | + V| neighbor | neighbor | + select1<========>select2<========>select3 + + list of all select_lex will be following (as it will be constructed by + parser): + + select1->select2->select3->select2.1.1->select 2.1.2->select2.1.1.1.1-+ + | + +---------------------------------------------------------------------+ + | + +->select1.1.1->select1.1.2 + +*/ + +/* + Base class for st_select_lex (SELECT_LEX) & + st_select_lex_unit (SELECT_LEX_UNIT) +*/ +struct st_select_lex_node { enum sub_select_type linkage; - char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */ - Item *where,*having; - ha_rows select_limit,offset_limit; + st_select_lex_node *next, **prev, /* neighbor list */ + *master, *slave, /* vertical links */ + *link_next, **link_prev; /* list of whole SELECT_LEX */ + SQL_LIST order_list; /* ORDER clause */ + ha_rows select_limit, offset_limit; /* LIMIT clause parameters */ + void init_query(); + void init_select(); + void include_down(st_select_lex_node *upper); + void include_neighbour(st_select_lex_node *before); + void include_global(st_select_lex_node **plink); + void exclude(); +private: + void fast_exclude(); +}; + +/* + SELECT_LEX_UNIT - unit of selects (UNION, INTERSECT, ...) group + SELECT_LEXs +*/ +struct st_select_lex_unit: public st_select_lex_node { + /* + Pointer to 'last' select or pointer to unit where stored + global parameters for union + */ + st_select_lex_node *global_parameters; + /* LIMIT clause runtime counters */ + ha_rows select_limit_cnt, offset_limit_cnt; + void init_query(); +}; +typedef struct st_select_lex_unit SELECT_LEX_UNIT; + +/* + SELECT_LEX - store information of parsed SELECT_LEX statment +*/ +struct st_select_lex: public st_select_lex_node { + char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */ + Item *where, *having; /* WHERE & HAVING clauses */ ulong options; List expr_list; - List when_list; - SQL_LIST order_list,table_list,group_list; - List item_list; - List interval_list,use_index, *use_index_ptr, + List when_list; /* WHEN clause */ + SQL_LIST table_list, group_list; /* FROM & GROUP BY clauses */ + List item_list; /* list of fields & expressions */ + List interval_list, use_index, *use_index_ptr, ignore_index, *ignore_index_ptr; List ftfunc_list; uint in_sum_expr, sort_default; - bool create_refs, braces; - st_select_lex *next, *prev; -} SELECT_LEX; - + bool create_refs, + braces; /* SELECT ... UNION (SELECT ... ) <- this braces */ + void init_query(); + void init_select(); +}; +typedef struct st_select_lex SELECT_LEX; class Set_option :public Sql_alloc { public: @@ -137,13 +252,15 @@ public: :name(par_name), item(par_item), name_length(length), type(par_type) {} }; - /* The state of the lex parsing. This is saved in the THD struct */ typedef struct st_lex { uint yylineno,yytoklen; /* Simulate lex */ LEX_YYSTYPE yylval; - SELECT_LEX select_lex, *select, *last_select; + SELECT_LEX_UNIT unit; /* most upper unit */ + SELECT_LEX select_lex, /* first SELECT_LEX */ + /* current SELECT_LEX in parsing */ + *select; uchar *ptr,*tok_start,*tok_end,*end_of_query; char *length,*dec,*change,*name; char *backup_dir; /* For RESTORE/BACKUP */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 06431124356..4d03701e4f8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1240,8 +1240,10 @@ mysql_execute_command(void) { for (TABLE_LIST *cursor= tables; cursor; - cursor=cursor->next) - if (cursor->derived && mysql_derived(thd,lex,(SELECT_LEX *)cursor->derived,cursor)) + cursor= cursor->next) + if (cursor->derived && mysql_derived(thd, lex, + (SELECT_LEX_UNIT *)cursor->derived, + cursor)) DBUG_VOID_RETURN; } if ((lex->select_lex.next && create_total_list(thd,lex,&tables)) || @@ -2664,18 +2666,19 @@ static void mysql_init_query(THD *thd) { DBUG_ENTER("mysql_init_query"); - thd->lex.select_lex.item_list.empty(); + thd->lex.unit.init_query(); + thd->lex.select_lex.init_query(); + thd->lex.unit.slave= &thd->lex.select_lex; + thd->lex.select_lex.master= &thd->lex.unit; + thd->lex.select_lex.prev= &thd->lex.unit.slave; thd->lex.value_list.empty(); - thd->lex.select_lex.table_list.elements=0; - thd->free_list=0; thd->lex.union_option=0; - thd->lex.select = thd->lex.last_select = &thd->lex.select_lex; - thd->lex.select_lex.table_list.first=0; - thd->lex.select_lex.table_list.next= (byte**) &thd->lex.select_lex.table_list.first; - thd->lex.select_lex.next=0; - thd->fatal_error=0; // Safety - thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0; - thd->sent_row_count=thd->examined_row_count=0; - thd->safe_to_cache_query=1; + thd->free_list= 0; + thd->lex.union_option= 0; + thd->lex.select= &thd->lex.select_lex; + thd->fatal_error= 0; // Safety + thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; + thd->sent_row_count= thd->examined_row_count= 0; + thd->safe_to_cache_query= 1; DBUG_VOID_RETURN; } @@ -2683,53 +2686,52 @@ void mysql_init_select(LEX *lex) { SELECT_LEX *select_lex = lex->select; - select_lex->where=select_lex->having=0; + select_lex->init_select(); select_lex->select_limit=lex->thd->default_select_limit; select_lex->offset_limit=0; - select_lex->options=0; - select_lex->linkage=UNSPECIFIED_TYPE; lex->exchange = 0; lex->proc_list.first=0; - select_lex->order_list.elements=select_lex->group_list.elements=0; - select_lex->order_list.first=0; - select_lex->order_list.next= (byte**) &select_lex->order_list.first; - select_lex->group_list.first=0; - select_lex->group_list.next= (byte**) &select_lex->group_list.first; - select_lex->next = select_lex->prev = (SELECT_LEX *)NULL; } bool -mysql_new_select(LEX *lex) +mysql_new_select(LEX *lex, bool move_down) { SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX)); if (!select_lex) return 1; - lex->select=lex->last_select; - lex->select->next=select_lex; - lex->select=lex->last_select=select_lex; - select_lex->table_list.next= (byte**) &select_lex->table_list.first; - select_lex->item_list.empty(); - select_lex->when_list.empty(); - select_lex->expr_list.empty(); - select_lex->interval_list.empty(); - select_lex->use_index.empty(); - select_lex->ftfunc_list.empty(); + select_lex->init_query(); + select_lex->init_select(); + if (move_down) + { + /* first select_lex of subselect or derived table */ + SELECT_LEX_UNIT *unit= + (SELECT_LEX_UNIT *) lex->thd->calloc(sizeof(SELECT_LEX_UNIT)); + if (!unit) + return 1; + unit->init_query(); + unit->init_select(); + unit->include_down(lex->select); + select_lex->include_down(unit); + } + else + select_lex->include_neighbour(lex->select); + + select_lex->include_global(&lex->select->link_next); + lex->select= select_lex; return 0; } void mysql_init_multi_delete(LEX *lex) { - lex->sql_command = SQLCOM_DELETE_MULTI; + lex->sql_command= SQLCOM_DELETE_MULTI; mysql_init_select(lex); - lex->select->select_limit=HA_POS_ERROR; - lex->auxilliary_table_list=lex->select_lex.table_list; - lex->select->table_list.elements=0; - lex->select->table_list.first=0; - lex->select->table_list.next= (byte**) &(lex->select->table_list.first); + lex->select->select_limit= HA_POS_ERROR; + lex->auxilliary_table_list= lex->select_lex.table_list; + lex->select->init_query(); } void -mysql_parse(THD *thd,char *inBuf,uint length) +mysql_parse(THD *thd, char *inBuf, uint length) { DBUG_ENTER("mysql_parse"); @@ -3159,7 +3161,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, ptr->real_name_length=table->table.length; ptr->lock_type=flags; ptr->updating=updating; - ptr->derived=(SELECT_LEX *)table->sel; + ptr->derived= (SELECT_LEX_UNIT *) table->sel; if (use_index) ptr->use_index=(List *) thd->memdup((gptr) use_index, sizeof(*use_index)); @@ -3204,8 +3206,8 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) SELECT_LEX *sl; TABLE_LIST **new_table_list= result, *aux; - *new_table_list=0; // end result list - for (sl= &lex->select_lex; sl; sl=sl->next) + *new_table_list= 0; // end result list + for (sl= &lex->select_lex; sl; sl= (SELECT_LEX *) sl->next) { if (sl->order_list.first && sl->next && !sl->braces) { diff --git a/sql/sql_union.cc b/sql/sql_union.cc index c8237f3ae9b..7178b857bbc 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -43,8 +43,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) /* Fix tables 'to-be-unioned-from' list to point at opened tables */ last_sl= &lex->select_lex; for (sl= last_sl; - sl && sl->linkage != NOT_A_SELECT; - last_sl=sl, sl=sl->next) + sl && sl->linkage != GLOBAL_OPTIONS_TYPE; + last_sl= sl, sl= (SELECT_LEX *) sl->next) { for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; cursor; @@ -133,7 +133,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) } union_result->save_time_stamp=!describe; - for (sl= &lex->select_lex; sl; sl=sl->next) + for (sl= &lex->select_lex; sl; sl= (SELECT_LEX*) sl->next) { lex->select=sl; thd->offset_limit=sl->offset_limit; @@ -143,15 +143,19 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) if (thd->select_limit == HA_POS_ERROR) sl->options&= ~OPTION_FOUND_ROWS; - res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ? first_table : (TABLE_LIST*) sl->table_list.first, - sl->item_list, - sl->where, - (sl->braces) ? (ORDER *)sl->order_list.first : (ORDER *) 0, - (ORDER*) sl->group_list.first, - sl->having, - (ORDER*) NULL, - sl->options | thd->options | SELECT_NO_UNLOCK | ((describe) ? SELECT_DESCRIBE : 0), - union_result); + res= mysql_select(thd, + (describe && sl->linkage==GLOBAL_OPTIONS_TYPE) ? + first_table : (TABLE_LIST*) sl->table_list.first, + sl->item_list, + sl->where, + (sl->braces) ? + (ORDER *)sl->order_list.first : (ORDER *) 0, + (ORDER*) sl->group_list.first, + sl->having, + (ORDER*) NULL, + sl->options | thd->options | + SELECT_NO_UNLOCK | ((describe) ? SELECT_DESCRIBE : 0), + union_result); if (res) goto exit; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6317b21a603..f9d075b75b3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2155,21 +2155,22 @@ join_table: | '(' SELECT_SYM select_part3 ')' opt_table_alias { LEX *lex=Lex; - lex->select=lex->select->prev; - if (!($$=add_table_to_list(new Table_ident(Lex->last_select),$5,0,TL_UNLOCK))) + SELECT_LEX_UNIT *unit= (SELECT_LEX_UNIT*) lex->select->master; + lex->select= (SELECT_LEX*) unit->master; + if (!($$= add_table_to_list(new Table_ident(unit), + $5,0,TL_UNLOCK))) YYABORT; } select_part3: { - LEX *lex=Lex; - lex->derived_tables=true; - SELECT_LEX *tmp=lex->select; - if (lex->select->linkage == NOT_A_SELECT || mysql_new_select(lex)) + LEX *lex= Lex; + lex->derived_tables= true; + if (lex->select->linkage == GLOBAL_OPTIONS_TYPE || + mysql_new_select(lex, 1)) YYABORT; mysql_init_select(lex); - lex->select->linkage=DERIVED_TABLE_TYPE; - lex->select->prev=tmp; + lex->select->linkage= DERIVED_TABLE_TYPE; } select_options select_item_list select_intoto @@ -3809,7 +3810,8 @@ union_list: net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO"); YYABORT; } - if (lex->select->linkage == NOT_A_SELECT || mysql_new_select(lex)) + if (lex->select->linkage == GLOBAL_OPTIONS_TYPE || + mysql_new_select(lex, 0)) YYABORT; lex->select->linkage=UNION_TYPE; } @@ -3824,10 +3826,10 @@ optional_order_or_limit: | { LEX *lex=Lex; - if (!lex->select->braces || mysql_new_select(lex)) + if (!lex->select->braces || mysql_new_select(lex, 0)) YYABORT; mysql_init_select(lex); - lex->select->linkage=NOT_A_SELECT; + lex->select->linkage= GLOBAL_OPTIONS_TYPE; lex->select->select_limit=lex->thd->default_select_limit; } opt_order_clause limit_clause diff --git a/sql/table.h b/sql/table.h index 59cb28038bf..e30e29ddd3f 100644 --- a/sql/table.h +++ b/sql/table.h @@ -139,18 +139,18 @@ typedef struct st_table_list { struct st_table_list *next; char *db,*name,*real_name; uint32 db_length, real_name_length; - Item *on_expr; /* Used with outer join */ - struct st_table_list *natural_join; /* natural join on this table*/ + Item *on_expr; /* Used with outer join */ + struct st_table_list *natural_join; /* natural join on this table*/ /* ... join ... USE INDEX ... IGNORE INDEX */ - List *use_index,*ignore_index; + List *use_index, *ignore_index; TABLE *table; GRANT_INFO grant; thr_lock_type lock_type; - uint outer_join; /* Which join type */ - bool straight; /* optimize with prev table */ - bool updating; /* for replicate-do/ignore table */ - bool shared; /* Used twice in union */ - void *derived; + uint outer_join; /* Which join type */ + bool straight; /* optimize with prev table */ + bool updating; /* for replicate-do/ignore table */ + bool shared; /* Used twice in union */ + void *derived; /* SELECT_LEX_UNIT of derived table */ } TABLE_LIST; typedef struct st_changed_table_list { -- cgit v1.2.1 From 6ff06df2333d90021cb10a27f9285586908ee542 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 May 2002 23:14:40 +0300 Subject: new SELECT_LEX structures used for storing global ORDER BY, global LIMIT & limit counters mysql-test/r/union.result: correct result of union explain command --- sql/item_sum.cc | 8 +++-- sql/mysql_priv.h | 3 +- sql/sql_class.cc | 19 +++++----- sql/sql_class.h | 23 +++++++----- sql/sql_delete.cc | 3 +- sql/sql_derived.cc | 24 +++++++------ sql/sql_insert.cc | 14 ++++---- sql/sql_lex.cc | 6 ++-- sql/sql_parse.cc | 55 ++++++++++++++++------------- sql/sql_select.cc | 93 ++++++++++++++++++++++++++---------------------- sql/sql_select.h | 5 ++- sql/sql_union.cc | 102 +++++++++++++++++++++-------------------------------- sql/sql_update.cc | 13 ++++--- sql/sql_yacc.yy | 20 ++++++++--- 14 files changed, 208 insertions(+), 180 deletions(-) (limited to 'sql') diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 83bc2272515..ecb908a797b 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -940,6 +940,7 @@ bool Item_sum_count_distinct::fix_fields(THD *thd,TABLE_LIST *tables) bool Item_sum_count_distinct::setup(THD *thd) { List list; + SELECT_LEX *select_lex= current_lex->select; /* Create a table with an unique key over all parameters */ for (uint i=0; i < arg_count ; i++) { @@ -961,9 +962,10 @@ bool Item_sum_count_distinct::setup(THD *thd) free_tmp_table(thd, table); tmp_table_param->cleanup(); } - if (!(table=create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1, - 0, 0, - current_lex->select->options | thd->options))) + if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1, + 0, 0, + select_lex->options | thd->options, + (SELECT_LEX_UNIT*) select_lex->master))) return 1; table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows table->no_rows=1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index a0dad53b4e2..1719fe69b17 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -359,7 +359,8 @@ int setup_order(THD *thd,TABLE_LIST *tables, List &fields, int handle_select(THD *thd, LEX *lex, select_result *result); int mysql_select(THD *thd,TABLE_LIST *tables,List &list,COND *conds, ORDER *order, ORDER *group,Item *having,ORDER *proc_param, - ulong select_type,select_result *result); + ulong select_type,select_result *result, + SELECT_LEX_UNIT *unit); int mysql_union(THD *thd, LEX *lex,select_result *result); int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 29cdaa676d6..6be0e46679b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -389,9 +389,9 @@ bool select_send::send_data(List &items) String *packet= &thd->packet; DBUG_ENTER("send_data"); - if (thd->offset_limit) + if (unit->offset_limit_cnt) { // using limit offset,count - thd->offset_limit--; + unit->offset_limit_cnt--; DBUG_RETURN(0); } packet->length(0); // Reset packet @@ -439,11 +439,12 @@ select_export::~select_export() } int -select_export::prepare(List &list) +select_export::prepare(List &list, SELECT_LEX_UNIT *u) { char path[FN_REFLEN]; uint option=4; bool blob_flag=0; + unit= u; #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS option|=1; // Force use of db directory #endif @@ -510,9 +511,9 @@ bool select_export::send_data(List &items) String tmp(buff,sizeof(buff)),*res; tmp.length(0); - if (thd->offset_limit) + if (unit->offset_limit_cnt) { // using limit offset,count - thd->offset_limit--; + unit->offset_limit_cnt--; DBUG_RETURN(0); } row_count++; @@ -678,9 +679,11 @@ select_dump::~select_dump() } int -select_dump::prepare(List &list __attribute__((unused))) +select_dump::prepare(List &list __attribute__((unused)), + SELECT_LEX_UNIT *u) { uint option=4; + unit= u; #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS option|=1; // Force use of db directory #endif @@ -719,9 +722,9 @@ bool select_dump::send_data(List &items) Item *item; DBUG_ENTER("send_data"); - if (thd->offset_limit) + if (unit->offset_limit_cnt) { // using limit offset,count - thd->offset_limit--; + unit->offset_limit_cnt--; DBUG_RETURN(0); } if (row_count++ > 1) diff --git a/sql/sql_class.h b/sql/sql_class.h index 56a0d6a44df..d4bd65674f1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -382,7 +382,7 @@ public: #endif ulonglong next_insert_id,last_insert_id,current_insert_id, limit_found_rows; - ha_rows select_limit,offset_limit,default_select_limit,cuted_fields, + ha_rows default_select_limit,cuted_fields, max_join_size, sent_row_count, examined_row_count; table_map used_tables; UC *user_connect; @@ -551,10 +551,15 @@ void send_error(NET *net,uint sql_errno=0, const char *err=0); class select_result :public Sql_alloc { protected: THD *thd; + SELECT_LEX_UNIT *unit; public: select_result(); virtual ~select_result() {}; - virtual int prepare(List &list) { return 0; } + virtual int prepare(List &list, SELECT_LEX_UNIT *u) + { + unit= u; + return 0; + } virtual bool send_fields(List &list,uint flag)=0; virtual bool send_data(List &items)=0; virtual void initialize_tables (JOIN *join=0) {} @@ -587,7 +592,7 @@ class select_export :public select_result { public: select_export(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) {} ~select_export(); - int prepare(List &list); + int prepare(List &list, SELECT_LEX_UNIT *u); bool send_fields(List &list, uint flag) { return 0; } bool send_data(List &items); @@ -606,7 +611,7 @@ public: select_dump(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) { path[0]=0; } ~select_dump(); - int prepare(List &list); + int prepare(List &list, SELECT_LEX_UNIT *u); bool send_fields(List &list, uint flag) { return 0; } bool send_data(List &items); @@ -629,7 +634,7 @@ class select_insert :public select_result { info.handle_duplicates=duplic; } ~select_insert(); - int prepare(List &list); + int prepare(List &list, SELECT_LEX_UNIT *u); bool send_fields(List &list, uint flag) { return 0; } bool send_data(List &items); @@ -658,7 +663,7 @@ public: create_info(create_info_par), lock(0) {} - int prepare(List &list); + int prepare(List &list, SELECT_LEX_UNIT *u); bool send_data(List &values); bool send_eof(); void abort(); @@ -672,7 +677,7 @@ class select_union :public select_result { select_union(TABLE *table_par); ~select_union(); - int prepare(List &list); + int prepare(List &list, SELECT_LEX_UNIT *u); bool send_fields(List &list, uint flag) { return 0; } bool send_data(List &items); @@ -787,7 +792,7 @@ public: multi_delete(THD *thd, TABLE_LIST *dt, thr_lock_type lock_option_arg, uint num_of_tables); ~multi_delete(); - int prepare(List &list); + int prepare(List &list, SELECT_LEX_UNIT *u); bool send_fields(List &list, uint flag) { return 0; } bool send_data(List &items); @@ -816,7 +821,7 @@ public: enum enum_duplicates handle_duplicates, thr_lock_type lock_option_arg, uint num); ~multi_update(); - int prepare(List &list); + int prepare(List &list, SELECT_LEX_UNIT *u); bool send_fields(List &list, uint flag) { return 0; } bool send_data(List &items); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index f5a5a684fc0..2e565a59ca0 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -232,9 +232,10 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, int -multi_delete::prepare(List &values) +multi_delete::prepare(List &values, SELECT_LEX_UNIT *u) { DBUG_ENTER("multi_delete::prepare"); + unit= u; do_delete = true; thd->proc_info="deleting from main table"; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 79343ef4ae0..41f166c6ad0 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -28,13 +28,13 @@ static const char *any_db="*any*"; // Special symbol for check_access -int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t) +int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) { /* TODO: make derived tables with union inside (now only 1 SELECT may be procesed) */ - SELECT_LEX *sl= (SELECT_LEX*)s->slave; + SELECT_LEX *sl= (SELECT_LEX*)unit->slave; List item_list; TABLE *table; int res; @@ -75,9 +75,11 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t) } bzero((char*) &tmp_table_param,sizeof(tmp_table_param)); tmp_table_param.field_count=item_list.elements; - if (!(table=create_tmp_table(thd, &tmp_table_param, sl->item_list, - (ORDER*) 0, 0, 1, 0, - (sl->options | thd->options | TMP_TABLE_ALL_COLUMNS)))) + if (!(table= create_tmp_table(thd, &tmp_table_param, sl->item_list, + (ORDER*) 0, 0, 1, 0, + (sl->options | thd->options | + TMP_TABLE_ALL_COLUMNS), + unit))) { res=-1; goto exit; @@ -85,11 +87,11 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t) if ((derived_result=new select_union(table))) { - thd->offset_limit=sl->offset_limit; - thd->select_limit=sl->select_limit+sl->offset_limit; - if (thd->select_limit < sl->select_limit) - thd->select_limit= HA_POS_ERROR; - if (thd->select_limit == HA_POS_ERROR) + unit->offset_limit_cnt= sl->offset_limit; + unit->select_limit_cnt= sl->select_limit+sl->offset_limit; + if (unit->select_limit_cnt < sl->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; + if (unit->select_limit_cnt == HA_POS_ERROR) sl->options&= ~OPTION_FOUND_ROWS; res=mysql_select(thd, tables, sl->item_list, @@ -97,7 +99,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t) (ORDER*) sl->group_list.first, sl->having, (ORDER*) NULL, sl->options | thd->options | SELECT_NO_UNLOCK, - derived_result); + derived_result, unit); if (!res) { // Here we entirely fix both TABLE_LIST and list of SELECT's as there were no derived tables diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 69fc7c00955..2e6c009741e 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1266,10 +1266,11 @@ bool delayed_insert::handle_inserts(void) ***************************************************************************/ int -select_insert::prepare(List &values) +select_insert::prepare(List &values, SELECT_LEX_UNIT *u) { DBUG_ENTER("select_insert::prepare"); + unit= u; save_time_stamp=table->time_stamp; if (check_insert_fields(thd,table,*fields,values,1)) DBUG_RETURN(1); @@ -1302,9 +1303,9 @@ select_insert::~select_insert() bool select_insert::send_data(List &values) { - if (thd->offset_limit) + if (unit->offset_limit_cnt) { // using limit offset,count - thd->offset_limit--; + unit->offset_limit_cnt--; return 0; } if (fields->elements) @@ -1380,10 +1381,11 @@ bool select_insert::send_eof() ***************************************************************************/ int -select_create::prepare(List &values) +select_create::prepare(List &values, SELECT_LEX_UNIT *u) { DBUG_ENTER("select_create::prepare"); + unit= u; table=create_table_from_items(thd, create_info, db, name, extra_fields, keys, &values, &lock); if (!table) @@ -1413,9 +1415,9 @@ select_create::prepare(List &values) bool select_create::send_data(List &values) { - if (thd->offset_limit) + if (unit->offset_limit_cnt) { // using limit offset,count - thd->offset_limit--; + unit->offset_limit_cnt--; return 0; } fill_record(field,values); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 3b17c8d498a..bfa06353e30 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -895,14 +895,16 @@ void st_select_lex_node::init_select() order_list.elements= 0; order_list.first= 0; order_list.next= (byte**) &order_list.first; - select_limit= offset_limit= 0; + select_limit= HA_POS_ERROR; + offset_limit= 0; } void st_select_lex_unit::init_query() { st_select_lex_node::init_query(); global_parameters= this; - select_limit_cnt= offset_limit_cnt= 0; + select_limit_cnt= HA_POS_ERROR; + offset_limit_cnt= 0; } void st_select_lex::init_query() diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4d03701e4f8..4313259aaf3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1203,11 +1203,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, void mysql_execute_command(void) { - int res=0; - THD *thd=current_thd; + int res= 0; + THD *thd= current_thd; LEX *lex= &thd->lex; - TABLE_LIST *tables=(TABLE_LIST*) lex->select_lex.table_list.first; - SELECT_LEX *select_lex = lex->select; + TABLE_LIST *tables= (TABLE_LIST*) lex->select_lex.table_list.first; + SELECT_LEX *select_lex= lex->select; + SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); if (thd->slave_thread) @@ -1274,11 +1275,11 @@ mysql_execute_command(void) break; // Error message is given } - thd->offset_limit=select_lex->offset_limit; - thd->select_limit=select_lex->select_limit+select_lex->offset_limit; - if (thd->select_limit < select_lex->select_limit) - thd->select_limit= HA_POS_ERROR; // no limit - if (thd->select_limit == HA_POS_ERROR) + unit->offset_limit_cnt =select_lex->offset_limit; + unit->select_limit_cnt =select_lex->select_limit+select_lex->offset_limit; + if (unit->select_limit_cnt < select_lex->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; // no limit + if (unit->select_limit_cnt == HA_POS_ERROR) select_lex->options&= ~OPTION_FOUND_ROWS; if (lex->exchange) @@ -1503,10 +1504,11 @@ mysql_execute_command(void) for (table = tables->next ; table ; table=table->next) table->lock_type= lex->lock_option; } - thd->offset_limit=select_lex->offset_limit; - thd->select_limit=select_lex->select_limit+select_lex->offset_limit; - if (thd->select_limit < select_lex->select_limit) - thd->select_limit= HA_POS_ERROR; // No limit + unit->offset_limit_cnt= select_lex->offset_limit; + unit->select_limit_cnt= select_lex->select_limit+ + select_lex->offset_limit; + if (unit->select_limit_cnt < select_lex->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; // No limit /* Skip first table, which is the table we are creating */ lex->select_lex.table_list.first= @@ -1788,13 +1790,13 @@ mysql_execute_command(void) while ((item=value_list++)) total_list.push_back(item); - res=mysql_select(thd,tables,total_list, - select_lex->where, - (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL, - (ORDER *)NULL, - select_lex->options | thd->options | - SELECT_NO_JOIN_CACHE, - result); + res= mysql_select(thd, tables, total_list, + select_lex->where, + (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL, + (ORDER *)NULL, + select_lex->options | thd->options | + SELECT_NO_JOIN_CACHE, + result, unit); delete result; } else @@ -1844,10 +1846,10 @@ mysql_execute_command(void) } select_result *result; - thd->offset_limit=select_lex->offset_limit; - thd->select_limit=select_lex->select_limit+select_lex->offset_limit; - if (thd->select_limit < select_lex->select_limit) - thd->select_limit= HA_POS_ERROR; // No limit + unit->offset_limit_cnt= select_lex->offset_limit; + unit->select_limit_cnt= select_lex->select_limit+select_lex->offset_limit; + if (unit->select_limit_cnt < select_lex->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; // No limit if (check_dup(tables->db, tables->real_name, tables->next)) { @@ -1963,7 +1965,7 @@ mysql_execute_command(void) (ORDER *)NULL, select_lex->options | thd->options | SELECT_NO_JOIN_CACHE, - result); + result, unit); delete result; } else @@ -2667,8 +2669,10 @@ mysql_init_query(THD *thd) { DBUG_ENTER("mysql_init_query"); thd->lex.unit.init_query(); + thd->lex.unit.init_select(); thd->lex.select_lex.init_query(); thd->lex.unit.slave= &thd->lex.select_lex; + thd->lex.unit.select_limit= thd->default_select_limit; //Global limit thd->lex.select_lex.master= &thd->lex.unit; thd->lex.select_lex.prev= &thd->lex.unit.slave; thd->lex.value_list.empty(); @@ -2716,6 +2720,7 @@ mysql_new_select(LEX *lex, bool move_down) else select_lex->include_neighbour(lex->select); + ((SELECT_LEX_UNIT*)select_lex->master)->global_parameters= select_lex; select_lex->include_global(&lex->select->link_next); lex->select= select_lex; return 0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2599fe216c5..d8d9c854652 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -65,7 +65,8 @@ static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond, static int return_zero_rows(select_result *res,TABLE_LIST *tables, List &fields, bool send_row, uint select_options, const char *info, - Item *having, Procedure *proc); + Item *having, Procedure *proc, + SELECT_LEX_UNIT *unit); static COND *optimize_cond(COND *conds,Item::cond_result *cond_value); static COND *remove_eq_conds(COND *cond,Item::cond_result *cond_value); static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item); @@ -166,7 +167,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) select_lex->having, (ORDER*) lex->proc_list.first, select_lex->options | thd->options, - result); + result, &(lex->unit)); if (res && result) result->abort(); delete result; @@ -182,7 +183,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result) int mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, ORDER *order, ORDER *group,Item *having,ORDER *proc_param, - ulong select_options,select_result *result) + ulong select_options,select_result *result, + SELECT_LEX_UNIT *unit) { TABLE *tmp_table; int error, tmp_error; @@ -195,8 +197,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, Procedure *procedure; List all_fields(fields); bool select_distinct; - SELECT_LEX *select_lex = &(thd->lex.select_lex); - SELECT_LEX *cur_sel = thd->lex.select; + SELECT_LEX *select_lex= &(thd->lex.select_lex); + SELECT_LEX *cur_sel= thd->lex.select; DBUG_ENTER("mysql_select"); /* Check that all tables, fields, conds and order are ok */ @@ -312,7 +314,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, join.do_send_rows = 1; join.group= group != 0; join.row_limit= ((select_distinct || order || group) ? HA_POS_ERROR : - thd->select_limit); + unit->select_limit_cnt); + join.unit= unit; #ifdef RESTRICTED_GROUP if (join.sum_func_count && !group && (join.func_count || join.field_count)) @@ -322,7 +325,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, DBUG_RETURN(-1); } #endif - if (!procedure && result->prepare(fields)) + if (!procedure && result->prepare(fields, unit)) { /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */ } @@ -351,7 +354,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, delete procedure; DBUG_RETURN(0); } - if (cond_value == Item::COND_FALSE || !thd->select_limit) + if (cond_value == Item::COND_FALSE || !unit->select_limit_cnt) { /* Impossible cond */ if (select_options & SELECT_DESCRIBE && select_lex->next) select_describe(&join,false,false,false,"Impossible WHERE"); @@ -359,7 +362,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, error=return_zero_rows(result, tables, fields, join.tmp_table_param.sum_func_count != 0 && !group, select_options,"Impossible WHERE",having, - procedure); + procedure, unit); delete procedure; DBUG_RETURN(error); } @@ -376,8 +379,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, select_describe(&join,false,false,false,"No matching min/max row"); else error=return_zero_rows(result, tables, fields, !group, - select_options,"No matching min/max row", - having,procedure); + select_options, "No matching min/max row", + having, procedure, unit); delete procedure; DBUG_RETURN(error); } @@ -435,9 +438,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, if (join.const_table_map != join.found_const_table_map && !(select_options & SELECT_DESCRIBE)) { - error=return_zero_rows(result,tables,fields, - join.tmp_table_param.sum_func_count != 0 && - !group,0,"",having,procedure); + error= return_zero_rows(result, tables, fields, + join.tmp_table_param.sum_func_count != 0 && + !group, 0, "", having, procedure, unit); goto err; } if (!(thd->options & OPTION_BIG_SELECTS) && @@ -483,11 +486,12 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, if (select_options & SELECT_DESCRIBE && select_lex->next) select_describe(&join,false,false,false,"Impossible WHERE noticed after reading const tables"); else - error=return_zero_rows(result,tables,fields, - join.tmp_table_param.sum_func_count != 0 && !group, - select_options, - "Impossible WHERE noticed after reading const tables", - having,procedure); + error= return_zero_rows(result,tables,fields, + join.tmp_table_param.sum_func_count != 0 && + !group, + select_options, + "Impossible WHERE noticed after reading const tables", + having, procedure, unit); goto err; } @@ -501,12 +505,12 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, select_distinct=0; } else if (select_distinct && join.tables - join.const_tables == 1 && - (thd->select_limit == HA_POS_ERROR || + (unit->select_limit_cnt == HA_POS_ERROR || (join.select_options & OPTION_FOUND_ROWS) || order && !(skip_sort_order= test_if_skip_sort_order(&join.join_tab[join.const_tables], - order, thd->select_limit,1)))) + order, unit->select_limit_cnt,1)))) { if ((group=create_distinct_group(order,fields))) { @@ -593,7 +597,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, ((group && join.const_tables != join.tables && (!simple_group || !test_if_skip_sort_order(&join.join_tab[join.const_tables], group, - thd->select_limit,0))) || + unit->select_limit_cnt, 0))) || select_distinct) && join.tmp_table_param.quick_group && !procedure) { @@ -610,7 +614,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, test_if_skip_sort_order(&join.join_tab[join.const_tables], order, (join.const_tables != join.tables - 1 || (join.select_options & OPTION_FOUND_ROWS)) ? - HA_POS_ERROR : thd->select_limit,0)))) + HA_POS_ERROR : unit->select_limit_cnt, 0)))) order=0; select_describe(&join,need_tmp, order != 0 && !skip_sort_order, @@ -637,7 +641,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, group && simple_group, (order == 0 || skip_sort_order) && !(join.select_options & OPTION_FOUND_ROWS), - join.select_options))) + join.select_options, unit))) goto err; /* purecov: inspected */ if (having && (join.sort_and_group || (tmp_table->distinct && !group))) @@ -690,7 +694,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, if (order && skip_sort_order) { (void) test_if_skip_sort_order(&join.join_tab[join.const_tables], - order, thd->select_limit,0); + order, unit->select_limit_cnt, 0); order=0; } } @@ -760,7 +764,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, (ORDER*) 0, select_distinct && !group, 1, 0, - join.select_options))) + join.select_options, unit))) goto err; /* purecov: inspected */ if (group) { @@ -817,9 +821,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, if (procedure) { if (procedure->change_columns(fields) || - result->prepare(fields)) + result->prepare(fields, unit)) goto err; - count_field_types(&join.tmp_table_param,all_fields,0); + count_field_types(&join.tmp_table_param, all_fields, 0); } if (join.group || join.tmp_table_param.sum_func_count || (procedure && (procedure->flags & PROC_GROUP))) @@ -864,7 +868,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, (having || group || join.const_tables != join.tables - 1 || (join.select_options & OPTION_FOUND_ROWS)) ? - HA_POS_ERROR : thd->select_limit)) + HA_POS_ERROR : unit->select_limit_cnt)) goto err; /* purecov: inspected */ } join.having=having; // Actually a parameter @@ -2480,7 +2484,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if ((tab->keys & ~ tab->const_keys && i > 0) || (tab->const_keys && i == join->const_tables && - join->thd->select_limit < join->best_positions[i].records_read && + join->unit->select_limit_cnt < + join->best_positions[i].records_read && !(join->select_options & OPTION_FOUND_ROWS))) { /* Join with outer join condition */ @@ -2491,7 +2496,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) (join->select_options & OPTION_FOUND_ROWS ? HA_POS_ERROR : - join->thd->select_limit)) < 0) + join->unit->select_limit_cnt)) < 0) DBUG_RETURN(1); // Impossible range sel->cond=orig_cond; } @@ -2929,7 +2934,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order) static int return_zero_rows(select_result *result,TABLE_LIST *tables,List &fields, bool send_row, uint select_options,const char *info, - Item *having, Procedure *procedure) + Item *having, Procedure *procedure, SELECT_LEX_UNIT *unit) { DBUG_ENTER("return_zero_rows"); @@ -2940,7 +2945,7 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List &fields, } if (procedure) { - if (result->prepare(fields)) // This hasn't been done yet + if (result->prepare(fields, unit)) // This hasn't been done yet DBUG_RETURN(-1); } if (send_row) @@ -3475,7 +3480,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, TABLE * create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, ORDER *group, bool distinct, bool save_sum_fields, - bool allow_distinct_limit, ulong select_options) + bool allow_distinct_limit, ulong select_options, + SELECT_LEX_UNIT *unit) { TABLE *table; uint i,field_count,reclength,null_count,null_pack_length, @@ -3846,8 +3852,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, test(null_pack_length)); if (allow_distinct_limit) { - set_if_smaller(table->max_rows,thd->select_limit); - param->end_write_records=thd->select_limit; + set_if_smaller(table->max_rows, unit->select_limit_cnt); + param->end_write_records= unit->select_limit_cnt; } else param->end_write_records= HA_POS_ERROR; @@ -4892,7 +4898,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), error=join->result->send_data(*join->fields); if (error) DBUG_RETURN(-1); /* purecov: inspected */ - if (++join->send_records >= join->thd->select_limit && join->do_send_rows) + if (++join->send_records >= join->unit->select_limit_cnt && + join->do_send_rows) { if (join->select_options & OPTION_FOUND_ROWS) { @@ -4907,8 +4914,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } else { - join->do_send_rows=0; - join->thd->select_limit = HA_POS_ERROR; + join->do_send_rows= 0; + join->unit->select_limit= HA_POS_ERROR; DBUG_RETURN(0); } } @@ -4969,13 +4976,13 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), DBUG_RETURN(-1); /* purecov: inspected */ if (end_of_records) DBUG_RETURN(0); - if (!error && ++join->send_records >= join->thd->select_limit && + if (!error && ++join->send_records >= join->unit->select_limit_cnt && join->do_send_rows) { if (!(join->select_options & OPTION_FOUND_ROWS)) DBUG_RETURN(-3); // Abort nicely join->do_send_rows=0; - join->thd->select_limit = HA_POS_ERROR; + join->unit->select_limit_cnt = HA_POS_ERROR; } } } @@ -5056,7 +5063,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (!(join->select_options & OPTION_FOUND_ROWS)) DBUG_RETURN(-3); join->do_send_rows=0; - join->thd->select_limit = HA_POS_ERROR; + join->unit->select_limit_cnt = HA_POS_ERROR; DBUG_RETURN(0); } } @@ -5755,7 +5762,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List &fields, Item *having) if (!field_count) { // only const items - join->thd->select_limit=1; // Only send first row + join->unit->select_limit_cnt= 1; // Only send first row DBUG_RETURN(0); } Field **first_field=entry->field+entry->fields - field_count; diff --git a/sql/sql_select.h b/sql/sql_select.h index befa1efde53..5466974f587 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -173,6 +173,8 @@ class JOIN { select_result *result; TMP_TABLE_PARAM tmp_table_param; MYSQL_LOCK *lock; + // unit structure (with global parameters) for this select + SELECT_LEX_UNIT *unit; }; @@ -187,7 +189,8 @@ void TEST_join(JOIN *join); bool store_val_in_field(Field *field,Item *val); TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, ORDER *group, bool distinct, bool save_sum_fields, - bool allow_distinct_limit, ulong select_options); + bool allow_distinct_limit, ulong select_options, + SELECT_LEX_UNIT *unit); void free_tmp_table(THD *thd, TABLE *entry); void count_field_types(TMP_TABLE_PARAM *param, List &fields, bool reset_with_sum_func); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 7178b857bbc..2eae37a70eb 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -27,8 +27,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) { - SELECT_LEX *sl, *last_sl, *lex_sl; - ORDER *order; + SELECT_LEX *sl; + SELECT_LEX_UNIT *unit= &(lex->unit); List item_list; TABLE *table; int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0; @@ -39,12 +39,12 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) TMP_TABLE_PARAM tmp_table_param; select_union *union_result; DBUG_ENTER("mysql_union"); + st_select_lex_node * global; /* Fix tables 'to-be-unioned-from' list to point at opened tables */ - last_sl= &lex->select_lex; - for (sl= last_sl; - sl && sl->linkage != GLOBAL_OPTIONS_TYPE; - last_sl= sl, sl= (SELECT_LEX *) sl->next) + for (sl= &lex->select_lex; + sl; + sl= (SELECT_LEX *) sl->next) { for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; cursor; @@ -52,31 +52,13 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) cursor->table= ((TABLE_LIST*) cursor->table)->table; } - /* last_sel now points at the last select where the ORDER BY is stored */ - if (sl) + /* Global option */ + if (((void*)(global= unit->global_parameters)) == ((void*)unit)) { - /* - The found SL is an extra SELECT_LEX argument that contains - the ORDER BY and LIMIT parameter for the whole UNION - */ - lex_sl= sl; - order= (ORDER *) lex_sl->order_list.first; - found_rows_for_union = lex->select_lex.options & OPTION_FOUND_ROWS && !describe && sl->select_limit; + found_rows_for_union = lex->select_lex.options & OPTION_FOUND_ROWS && + !describe && global->select_limit; if (found_rows_for_union) lex->select_lex.options ^= OPTION_FOUND_ROWS; -// This is done to eliminate unnecessary slowing down of the first query - if (!order || !describe) - last_sl->next=0; // Remove this extra element - } - else if (!last_sl->braces) - { - lex_sl= last_sl; // ORDER BY is here - order= (ORDER *) lex_sl->order_list.first; - } - else - { - lex_sl=0; - order=0; } if (describe) @@ -113,11 +95,12 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) bzero((char*) &tmp_table_param,sizeof(tmp_table_param)); tmp_table_param.field_count=item_list.elements; - if (!(table=create_tmp_table(thd, &tmp_table_param, item_list, - (ORDER*) 0, !describe & !lex->union_option, - 1, 0, - (lex->select_lex.options | thd->options | - TMP_TABLE_ALL_COLUMNS)))) + if (!(table= create_tmp_table(thd, &tmp_table_param, item_list, + (ORDER*) 0, !describe & !lex->union_option, + 1, 0, + (lex->select_lex.options | thd->options | + TMP_TABLE_ALL_COLUMNS), + unit))) DBUG_RETURN(-1); table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); @@ -136,11 +119,11 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) for (sl= &lex->select_lex; sl; sl= (SELECT_LEX*) sl->next) { lex->select=sl; - thd->offset_limit=sl->offset_limit; - thd->select_limit=sl->select_limit+sl->offset_limit; - if (thd->select_limit < sl->select_limit) - thd->select_limit= HA_POS_ERROR; // no limit - if (thd->select_limit == HA_POS_ERROR) + unit->offset_limit_cnt= sl->offset_limit; + unit->select_limit_cnt= sl->select_limit+sl->offset_limit; + if (unit->select_limit_cnt < sl->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; // no limit + if (unit->select_limit_cnt == HA_POS_ERROR) sl->options&= ~OPTION_FOUND_ROWS; res= mysql_select(thd, @@ -155,7 +138,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) (ORDER*) NULL, sl->options | thd->options | SELECT_NO_UNLOCK | ((describe) ? SELECT_DESCRIBE : 0), - union_result); + union_result, unit); if (res) goto exit; } @@ -187,26 +170,20 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) } if (!thd->fatal_error) // Check if EOM { - if (lex_sl) - { - thd->offset_limit=lex_sl->offset_limit; - thd->select_limit=lex_sl->select_limit+lex_sl->offset_limit; - if (thd->select_limit < lex_sl->select_limit) - thd->select_limit= HA_POS_ERROR; // no limit - if (thd->select_limit == HA_POS_ERROR) - thd->options&= ~OPTION_FOUND_ROWS; - } - else - { - thd->offset_limit= 0; - thd->select_limit= thd->default_select_limit; - } + st_select_lex_node * global= unit->global_parameters; + unit->offset_limit_cnt= global->offset_limit; + unit->select_limit_cnt= global->select_limit+global->offset_limit; + if (unit->select_limit_cnt < global->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; // no limit + if (unit->select_limit_cnt == HA_POS_ERROR) + thd->options&= ~OPTION_FOUND_ROWS; if (describe) - thd->select_limit= HA_POS_ERROR; // no limit - res=mysql_select(thd,&result_table_list, - item_list, NULL, (describe) ? 0 : order, - (ORDER*) NULL, NULL, (ORDER*) NULL, - thd->options, result); + unit->select_limit_cnt= HA_POS_ERROR; // no limit + res= mysql_select(thd,&result_table_list, + item_list, NULL, + (describe) ? 0 : (ORDER*)global->order_list.first, + (ORDER*) NULL, NULL, (ORDER*) NULL, + thd->options, result, unit); if (found_rows_for_union && !res) thd->limit_found_rows = (ulonglong)table->file->records; } @@ -230,7 +207,7 @@ select_union::select_union(TABLE *table_par) We can always use DUP_IGNORE because the temporary table will only contain a unique key if we are using not using UNION ALL */ - info.handle_duplicates=DUP_IGNORE; + info.handle_duplicates= DUP_IGNORE; } select_union::~select_union() @@ -238,8 +215,9 @@ select_union::~select_union() } -int select_union::prepare(List &list) +int select_union::prepare(List &list, SELECT_LEX_UNIT *u) { + unit= u; if (save_time_stamp && list.elements != table->fields) { my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, @@ -251,9 +229,9 @@ int select_union::prepare(List &list) bool select_union::send_data(List &values) { - if (thd->offset_limit) + if (unit->offset_limit_cnt) { // using limit offset,count - thd->offset_limit--; + unit->offset_limit_cnt--; return 0; } fill_record(table->field,values); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index db520af61c1..7e3d10ee202 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -379,9 +379,10 @@ multi_update::multi_update(THD *thd_arg, TABLE_LIST *ut, List &fs, } int -multi_update::prepare(List &values) +multi_update::prepare(List &values, SELECT_LEX_UNIT *u) { DBUG_ENTER("multi_update::prepare"); + unit= u; do_update = true; thd->count_cuted_fields=1; thd->cuted_fields=0L; @@ -466,15 +467,19 @@ multi_update::prepare(List &values) } if (counter) { - Field_string offset(table_ref->table->file->ref_length,false,"offset",table_ref->table,true); + Field_string offset(table_ref->table->file->ref_length, false, + "offset", table_ref->table, true); temp_fields->push_front(new Item_field(((Field *)&offset))); // Here I make tmp tables int cnt=counter-1; TMP_TABLE_PARAM tmp_table_param; bzero((char*) &tmp_table_param,sizeof(tmp_table_param)); tmp_table_param.field_count=temp_fields->elements; - if (!(tmp_tables[cnt]=create_tmp_table(thd, &tmp_table_param, *temp_fields, - (ORDER*) 0, 1, 0, 0, TMP_TABLE_ALL_COLUMNS))) + if (!(tmp_tables[cnt]=create_tmp_table(thd, &tmp_table_param, + *temp_fields, + (ORDER*) 0, 1, 0, 0, + TMP_TABLE_ALL_COLUMNS, + unit))) { error = 1; // A proper error message is due here DBUG_RETURN(1); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f9d075b75b3..bd7a5ff3b48 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1449,7 +1449,14 @@ select: select_init: SELECT_SYM select_part2 { Select->braces=false; } union | - '(' SELECT_SYM select_part2 ')' { Select->braces=true;} union_opt + '(' SELECT_SYM select_part2 ')' + { + SELECT_LEX * sel=Select; + sel->braces=true; + /* select in braces, can't contain global parameters */ + ((SELECT_LEX_UNIT*)sel->master)->global_parameters= + sel->master; + } union_opt select_part2: @@ -3826,10 +3833,15 @@ optional_order_or_limit: | { LEX *lex=Lex; - if (!lex->select->braces || mysql_new_select(lex, 0)) + if (!lex->select->braces) YYABORT; - mysql_init_select(lex); - lex->select->linkage= GLOBAL_OPTIONS_TYPE; + ((SELECT_LEX_UNIT*)lex->select->master)->global_parameters= + lex->select->master; + /* + Following type conversion looks like hack, but all that need SELECT_LEX + fields always check linkage type. + */ + lex->select= (SELECT_LEX*)lex->select->master; lex->select->select_limit=lex->thd->default_select_limit; } opt_order_clause limit_clause -- cgit v1.2.1 From 510a4d1da1578c240a37328e82f2dbaae1a7bfc3 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 May 2002 12:12:17 +0300 Subject: removed fake description (EXPLAIN) of first table for last SELECT_LEX with global parameters, because now it is absent --- sql/sql_union.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 2eae37a70eb..d821c6f6641 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -35,7 +35,6 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) int res; bool found_rows_for_union=false; TABLE_LIST result_table_list; - TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first; TMP_TABLE_PARAM tmp_table_param; select_union *union_result; DBUG_ENTER("mysql_union"); @@ -127,8 +126,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) sl->options&= ~OPTION_FOUND_ROWS; res= mysql_select(thd, - (describe && sl->linkage==GLOBAL_OPTIONS_TYPE) ? - first_table : (TABLE_LIST*) sl->table_list.first, + (TABLE_LIST*) sl->table_list.first, sl->item_list, sl->where, (sl->braces) ? -- cgit v1.2.1 From b69d8dab20811845e41c9f5c770125fd2f3b1a2f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 May 2002 15:23:57 +0300 Subject: total table list managment is changed sql/sql_lex.cc: tabllist creation routine moved to SELECT_LEX_UNION class & made recursive sql/sql_lex.h: list creation routine moved to SELECT_LEX_UNION class sql/sql_parse.cc: list creation routine moved to SELECT_LEX_UNION class anonymous union used for storing TABLE*/TABLE_LIST* sql/sql_union.cc: anonymous union used for storing TABLE*/TABLE_LIST* sql/table.h: anonymous union used for storing TABLE*/TABLE_LIST* --- sql/sql_lex.cc | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sql/sql_lex.h | 5 ++++ sql/sql_parse.cc | 70 +++------------------------------------------------ sql/sql_union.cc | 2 +- sql/table.h | 10 +++++++- 5 files changed, 95 insertions(+), 68 deletions(-) (limited to 'sql') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index bfa06353e30..dfa60918665 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -996,3 +996,79 @@ void st_select_lex_node::exclude() master->slave= next; */ } + +/* + This is used for UNION & subselect to create a new table list of all used + tables. + The table_list->table entry in all used tables are set to point + to the entries in this list. +*/ + +// interface +bool st_select_lex_unit::create_total_list(THD *thd, st_lex *lex, + TABLE_LIST **result) +{ + *result= 0; + return create_total_list_n_last_return(thd, lex, &result); +} + +// list creator +bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex, + TABLE_LIST ***result) +{ + TABLE_LIST *slave_list_first=0, **slave_list_last= &slave_list_first; + TABLE_LIST **new_table_list= *result, *aux; + SELECT_LEX *sl= (SELECT_LEX*)slave; + for (; sl; sl= (SELECT_LEX*)sl->next) + { + // check usage of ORDER BY in union + if (sl->order_list.first && sl->next && !sl->braces) + { + net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY"); + return 1; + } + if (sl->slave) + if (((SELECT_LEX_UNIT *) + sl->slave)->create_total_list_n_last_return(thd, lex, + &slave_list_last)) + return 1; + if ((aux= (TABLE_LIST*) sl->table_list.first)) + { + TABLE_LIST *next; + for (; aux; aux= next) + { + TABLE_LIST *cursor; + next= aux->next; + for (cursor= **result; cursor; cursor= cursor->next) + if (!strcmp(cursor->db, aux->db) && + !strcmp(cursor->real_name, aux->real_name) && + !strcmp(cursor->name, aux->name)) + break; + if (!cursor) + { + /* Add not used table to the total table list */ + aux->lock_type= lex->lock_option; + if (!(cursor= (TABLE_LIST *) thd->memdup((char*) aux, + sizeof(*aux)))) + { + send_error(&thd->net,0); + return 1; + } + *new_table_list= cursor; + new_table_list= &cursor->next; + *new_table_list= 0; // end result list + } + else + aux->shared= 1; // Mark that it's used twice + aux->table_list= cursor; + } + } + } + if (slave_list_first) + { + *new_table_list= slave_list_first; + new_table_list= slave_list_last; + } + *result= new_table_list; + return 0; +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 7603157f66d..876b9aa2743 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -207,6 +207,7 @@ private: SELECT_LEX_UNIT - unit of selects (UNION, INTERSECT, ...) group SELECT_LEXs */ +struct st_lex; struct st_select_lex_unit: public st_select_lex_node { /* Pointer to 'last' select or pointer to unit where stored @@ -216,6 +217,10 @@ struct st_select_lex_unit: public st_select_lex_node { /* LIMIT clause runtime counters */ ha_rows select_limit_cnt, offset_limit_cnt; void init_query(); + bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result); +private: + bool create_total_list_n_last_return(THD *thd, st_lex *lex, + TABLE_LIST ***result); }; typedef struct st_select_lex_unit SELECT_LEX_UNIT; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4313259aaf3..e9a8ef2f449 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -70,7 +70,6 @@ static void remove_escape(char *name); static void refresh_status(void); static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name); -static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result); const char *any_db="*any*"; // Special symbol for check_access @@ -1247,7 +1246,8 @@ mysql_execute_command(void) cursor)) DBUG_VOID_RETURN; } - if ((lex->select_lex.next && create_total_list(thd,lex,&tables)) || + if ((lex->select_lex.link_next && + lex->unit.create_total_list(thd, lex, &tables)) || (table_rules_on && tables && thd->slave_thread && !tables_ok(thd,tables))) DBUG_VOID_RETURN; @@ -1942,7 +1942,7 @@ mysql_execute_command(void) goto error; } auxi->lock_type=walk->lock_type=TL_WRITE; - auxi->table= (TABLE *) walk; // Remember corresponding table + auxi->table_list= walk; // Remember corresponding table } tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); if (add_item_to_list(new Item_null())) @@ -1955,7 +1955,7 @@ mysql_execute_command(void) break; /* Fix tables-to-be-deleted-from list to point at opened tables */ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) - auxi->table= ((TABLE_LIST*) auxi->table)->table; + auxi->table= auxi->table_list->table; if (!thd->fatal_error && (result=new multi_delete(thd,aux_tables, lex->lock_option,table_count))) { @@ -3193,68 +3193,6 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, } -/* -** This is used for UNION to create a new table list of all used tables -** The table_list->table entry in all used tables are set to point -** to the entries in this list. -*/ - -static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) -{ - /* Handle the case when we are not using union */ - if (!lex->select_lex.next) - { - *result= (TABLE_LIST*) lex->select_lex.table_list.first; - return 0; - } - - SELECT_LEX *sl; - TABLE_LIST **new_table_list= result, *aux; - - *new_table_list= 0; // end result list - for (sl= &lex->select_lex; sl; sl= (SELECT_LEX *) sl->next) - { - if (sl->order_list.first && sl->next && !sl->braces) - { - net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY"); - return 1; - } - if ((aux= (TABLE_LIST*) sl->table_list.first)) - { - TABLE_LIST *next; - for (; aux; aux=next) - { - TABLE_LIST *cursor; - next= aux->next; - for (cursor= *result; cursor; cursor=cursor->next) - if (!strcmp(cursor->db,aux->db) && - !strcmp(cursor->real_name,aux->real_name) && - !strcmp(cursor->name, aux->name)) - break; - if (!cursor) - { - /* Add not used table to the total table list */ - aux->lock_type= lex->lock_option; - if (!(cursor = (TABLE_LIST *) thd->memdup((char*) aux, - sizeof(*aux)))) - { - send_error(&thd->net,0); - return 1; - } - *new_table_list= cursor; - new_table_list= &cursor->next; - *new_table_list=0; // end result list - } - else - aux->shared=1; // Mark that it's used twice - aux->table=(TABLE *) cursor; - } - } - } - return 0; -} - - void add_join_on(TABLE_LIST *b,Item *expr) { if (!b->on_expr) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index d821c6f6641..ef34af6fe1e 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -48,7 +48,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; cursor; cursor=cursor->next) - cursor->table= ((TABLE_LIST*) cursor->table)->table; + cursor->table= cursor->table_list->table; } /* Global option */ diff --git a/sql/table.h b/sql/table.h index e30e29ddd3f..1c65c2a7ce2 100644 --- a/sql/table.h +++ b/sql/table.h @@ -143,7 +143,15 @@ typedef struct st_table_list { struct st_table_list *natural_join; /* natural join on this table*/ /* ... join ... USE INDEX ... IGNORE INDEX */ List *use_index, *ignore_index; - TABLE *table; + /* + Usually hold reference on opened table, but may hold reference + to node of complete list of tables used in UNION & subselect. + */ + union + { + TABLE *table; /* opened table */ + st_table_list *table_list; /* pointer to node of list of all tables */ + }; GRANT_INFO grant; thr_lock_type lock_type; uint outer_join; /* Which join type */ -- cgit v1.2.1 From 044cbe42ac583969f8339f6974f90e4430371536 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 12 May 2002 23:46:42 +0300 Subject: simple subselects ported to new select_lex structures include/mysqld_error.h: simple subselects libmysqld/Makefile.am: simple subselects sql/Makefile.am: simple subselects sql/item.h: simple subselects sql/item_strfunc.h: simple subselects sql/share/czech/errmsg.txt: simple subselects sql/share/danish/errmsg.txt: simple subselects sql/share/dutch/errmsg.txt: simple subselects sql/share/english/errmsg.txt: simple subselects sql/share/estonian/errmsg.txt: simple subselects sql/share/french/errmsg.txt: simple subselects sql/share/german/errmsg.txt: simple subselects sql/share/greek/errmsg.txt: simple subselects sql/share/hungarian/errmsg.txt: simple subselects sql/share/italian/errmsg.txt: simple subselects sql/share/japanese/errmsg.txt: simple subselects sql/share/korean/errmsg.txt: simple subselects sql/share/norwegian-ny/errmsg.txt: simple subselects sql/share/norwegian/errmsg.txt: simple subselects sql/share/polish/errmsg.txt: simple subselects sql/share/portuguese/errmsg.txt: simple subselects sql/share/romanian/errmsg.txt: simple subselects sql/share/russian/errmsg.txt: simple subselects sql/share/slovak/errmsg.txt: simple subselects sql/share/spanish/errmsg.txt: simple subselects sql/share/swedish/errmsg.txt: simple subselects sql/share/ukrainian/errmsg.txt: simple subselects sql/sql_class.cc: simple subselects sql/sql_class.h: simple subselects sql/sql_lex.cc: simple subselects sql/sql_select.cc: simple subselects sql/sql_select.h: simple subselects sql/sql_union.cc: simple subselects sql/sql_yacc.yy: simple subselects --- sql/Makefile.am | 4 +- sql/item.h | 6 +- sql/item_strfunc.h | 4 +- sql/item_subselect.cc | 136 ++++ sql/item_subselect.h | 79 ++ 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/slovak/errmsg.txt | 2 + sql/share/spanish/errmsg.txt | 2 + sql/share/swedish/errmsg.txt | 2 + sql/share/ukrainian/errmsg.txt | 2 + sql/sql_class.cc | 27 + sql/sql_class.h | 13 + sql/sql_lex.cc | 1 + sql/sql_select.cc | 732 +++++++++-------- sql/sql_select.cc.rej | 1576 +++++++++++++++++++++++++++++++++++++ sql/sql_select.h | 67 +- sql/sql_select.h.rej | 96 +++ sql/sql_union.cc | 11 - sql/sql_yacc.yy | 36 +- 36 files changed, 2486 insertions(+), 346 deletions(-) create mode 100644 sql/item_subselect.cc create mode 100644 sql/item_subselect.h create mode 100644 sql/sql_select.cc.rej create mode 100644 sql/sql_select.h.rej (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index f58075358b6..bd626ea10b7 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -46,7 +46,7 @@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ item_strfunc.h item_timefunc.h item_uniq.h \ - item_create.h mysql_priv.h \ + item_create.h item_subselect.h mysql_priv.h \ procedure.h sql_class.h sql_lex.h sql_list.h \ sql_manager.h sql_map.h sql_string.h unireg.h \ field.h handler.h \ @@ -60,7 +60,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ - thr_malloc.cc item_create.cc \ + thr_malloc.cc item_create.cc item_subselect.cc\ field.cc key.cc sql_class.cc sql_list.cc \ net_serv.cc net_pkg.cc lock.cc my_lock.c \ sql_string.cc sql_manager.cc sql_map.cc \ diff --git a/sql/item.h b/sql/item.h index 97f2862bb8b..2bd1cb99bf5 100644 --- a/sql/item.h +++ b/sql/item.h @@ -32,7 +32,8 @@ public: enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM, INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM, COPY_STR_ITEM,FIELD_AVG_ITEM, - PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, CONST_ITEM}; + PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, CONST_ITEM, + SUBSELECT_ITEM}; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; String str_value; /* used to store value */ @@ -46,7 +47,6 @@ public: my_bool unsigned_flag; my_bool with_sum_func; - // alloc & destruct is done as start of select using sql_alloc Item(); virtual ~Item() { name=0; } /*lint -e1509 */ @@ -371,6 +371,7 @@ public: #include "item_strfunc.h" #include "item_timefunc.h" #include "item_uniq.h" +#include "item_subselect.h" class Item_copy_string :public Item { @@ -458,3 +459,4 @@ extern Item_result item_cmp_type(Item_result a,Item_result b); extern Item *resolve_const_item(Item *item,Item *cmp_item); extern bool field_is_equal_to_item(Field *field,Item *item); Item *get_system_var(LEX_STRING name); + diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 091289fd040..350c4b3d793 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -38,7 +38,9 @@ public: Field *tmp_table_field(TABLE *t_arg) { if (!t_arg) return result_field; - return (max_length > 255) ? (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) : (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary); + return (max_length > 255) ? + (Field *) new Field_blob(max_length,maybe_null, name,t_arg, binary) : + (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary); } }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc new file mode 100644 index 00000000000..286c29fec7a --- /dev/null +++ b/sql/item_subselect.cc @@ -0,0 +1,136 @@ +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + subselect Item + +SUBSELECT TODO: + - add function from mysql_select that use JOIN* as parameter to JOIN methods + (sql_select.h/sql_select.cc) + - remove double 'having' & 'having_list' from JOIN + (sql_select.h/sql_select.cc) + + - add subselect union select (sql_union.cc) + - depended from outer select subselects + +*/ + +#ifdef __GNUC__ +#pragma implementation // gcc: Class implementation +#endif + +#include "mysql_priv.h" +#include "sql_select.h" + +Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex): + executed(0) +{ + DBUG_ENTER("Item_subselect::Item_subselect"); + DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex)); + result= new select_subselect(this); + join= new JOIN(thd, select_lex->item_list, select_lex->options, result); + this->select_lex= select_lex; + maybe_null= 1; + /* + item value is NULL if select_subselect not changed this value + (i.e. some rows will be found returned) + */ + assign_null(); + DBUG_VOID_RETURN; +} + +Item::Type Item_subselect::type() const +{ + return SUBSELECT_ITEM; +} + +double Item_subselect::val () +{ + if (exec()) + return 0; + return real_value; +} + +longlong Item_subselect::val_int () +{ + if (exec()) + return 0; + return int_value; +} + +String *Item_subselect::val_str (String *str) +{ + if (exec() || null_value) + return 0; + return &str_value; +} + +void Item_subselect::make_field (Send_field *tmp_field) +{ + if (null_value) + { + init_make_field(tmp_field,FIELD_TYPE_NULL); + tmp_field->length=4; + } else { + init_make_field(tmp_field, ((result_type() == STRING_RESULT) ? + FIELD_TYPE_VAR_STRING : + (result_type() == INT_RESULT) ? + FIELD_TYPE_LONGLONG : FIELD_TYPE_DOUBLE)); + } +} + +bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables) +{ + // Is it one field subselect? + if (select_lex->item_list.elements != 1) + { + my_printf_error(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0)); + return 1; + } + SELECT_LEX *save_select= thd->lex.select; + thd->lex.select= select_lex; + if(join->prepare((TABLE_LIST*) select_lex->table_list.first, + select_lex->where, + (ORDER*) select_lex->order_list.first, + (ORDER*) select_lex->group_list.first, + select_lex->having, + (ORDER*) 0, select_lex, + (SELECT_LEX_UNIT*) select_lex->master)) + return 1; + if (join->optimize()) + { + executed= 1; + return 1; + } + thd->lex.select= save_select; + return 0; +} + +int Item_subselect::exec() +{ + if (!executed) + { + SELECT_LEX *save_select= join->thd->lex.select; + join->thd->lex.select= select_lex; + join->exec(); + join->thd->lex.select= save_select; + if (!executed) + //No rows returned => value is null (returned as inited) + executed= 1; + return join->error; + } + return 0; +} diff --git a/sql/item_subselect.h b/sql/item_subselect.h new file mode 100644 index 00000000000..096da68600c --- /dev/null +++ b/sql/item_subselect.h @@ -0,0 +1,79 @@ +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* subselect Item */ + +#ifdef __GNUC__ +#pragma interface /* gcc class implementation */ +#endif + +struct st_select_lex; +class JOIN; +class select_subselect; + +/* simple (not depended of covered select ) subselect */ + +class Item_subselect :public Item +{ +protected: + my_bool executed; /* simple subselect is executed */ + longlong int_value; + double real_value; + enum Item_result res_type; + + int exec(); + void assign_null() + { + null_value= 1; + int_value= 0; + real_value= 0; + max_length= 4; + res_type= STRING_RESULT; + } +public: + st_select_lex *select_lex; + JOIN *join; + select_subselect *result; + + Item_subselect(THD *thd, st_select_lex *select_lex); + Item_subselect(Item_subselect *item) + { + null_value= item->null_value; + int_value= item->int_value; + real_value= item->real_value; + max_length= item->max_length; + decimals= item->decimals; + res_type= item->res_type; + executed= item->executed; + select_lex= item->select_lex; + join= item->join; + result= item->result; + name= item->name; + } + enum Type type() const; + double val (); + longlong val_int (); + String *val_str (String *); + bool is_null() { return null_value; } + void make_field (Send_field *); + bool fix_fields(THD *thd, TABLE_LIST *tables); + Item *new_item() { return new Item_subselect(this); } + enum Item_result result_type() const { return res_type; } + + friend class select_subselect; +}; + + diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 950ca4f6623..f654f2a2240 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -237,3 +237,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index d87ed4ee629..cb9912d5783 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -231,3 +231,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index c8b47cb3c19..be4cd7d7896 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -236,3 +236,5 @@ "Het combineren van transactionele en niet-transactionele tabellen is uitgeschakeld.", "Optie '%s' tweemaal gebruikt in opdracht", "Gebruiker '%-64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 5033449c266..533a305cd1d 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -228,3 +228,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 6a83468eae5..d303cf22102 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -233,3 +233,5 @@ "Transaktsioone toetavate ning mittetoetavate tabelite kooskasutamine ei ole lubatud", "Määrangut '%s' on lauses kasutatud topelt", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index cf3e3e845e4..cae31a7c799 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -228,3 +228,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 19d46fabab8..8f3b59da035 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -231,3 +231,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index f9b4f137f82..f6c92f7c27c 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -228,3 +228,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 38877371243..1dd72efc63a 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -230,3 +230,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index e8cfd5a63a9..e658bc2975e 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -228,3 +228,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 98bc099954f..55fe7d79768 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -230,3 +230,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index f6cc890cb39..38d9416edc9 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -228,3 +228,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index adffc27949f..c84e8242778 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -230,3 +230,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 09a1ea4684c..dae9cf927c5 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -230,3 +230,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 12a9bd358b5..312ae153cbe 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -232,3 +232,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index b7feb0a7b0d..6dca23872e2 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -228,3 +228,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 8e48cabfc39..6e89a0119e2 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -232,3 +232,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 8ed33ec21a0..5df743b0dbf 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -231,3 +231,5 @@ "ïÄÎÏ×ÒÅÍÅÎÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ transactional É non-transactional ÔÁÂÌÉà ÏÔËÌÀÞÅÎÏ", "ïÐÃÉÑ '%s' ÉÓÐÏÌØÚÏ×ÁÎÁ Ä×ÁÖÄÙ", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"ðÏÄÚÁÐÒÏÓ ×ÏÚ×ÒÁÝÁÅÔ ÂÏÌÅÅ ÏÄÎÏÇÏ ÐÏÌÑ", +"ðÏÄÚÁÐÒÏÓ ×ÏÚ×ÒÁÝÁÅÔ ÂÏÌÅÅ ÏÄÎÏÊ ÚÁÐÉÓÉ", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 06503cdf69e..37a2d30e1ae 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -236,3 +236,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 4240581c5b8..2e371e75cbd 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -229,3 +229,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index e774f4a2c5c..58c8e5af54f 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -228,3 +228,5 @@ "Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat", "Option '%s' användes två gånger", "Användare '%-64s' har överskridit '%s' (nuvarande värde: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index c4c89433331..4dad29345e5 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -233,3 +233,5 @@ "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"ðiÄÚÁÐÉÔ ÐÏ×ÅÒÔÁ¤ ÂiÌØÛ ÎiÖ 1 ÓÔÏ×ÂÅÃØ", +"ðiÄÚÁÐÉÔ ÐÏ×ÅÒÔÁ¤ ÂiÌØÛ ÎiÖ 1 ÚÁÐÉÓ", diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 6be0e46679b..95c10112a9b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -774,3 +774,30 @@ bool select_dump::send_eof() file= -1; return error; } + +select_subselect::select_subselect(Item_subselect *item) +{ + this->item=item; +} + +bool select_subselect::send_data(List &items) +{ + if (item->executed){ + my_printf_error(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0)); + return 1; + } + Item *val_item= (Item *)item->select_lex->item_list.head(); + if ((item->null_value= val_item->is_null())) + { + item->assign_null(); + } else { + item->max_length= val_item->max_length; + item->decimals= val_item->decimals; + item->binary= val_item->binary; + val_item->val_str(&item->str_value); + item->int_value= val_item->val_int(); + item->real_value= val_item->val(); + item->res_type= val_item->result_type(); + } + return 0; +} diff --git a/sql/sql_class.h b/sql/sql_class.h index d4bd65674f1..10d6bf84b22 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -685,6 +685,19 @@ class select_union :public select_result { bool flush(); }; +/* Single value subselect interface class */ +class select_subselect :public select_result +{ + Item_subselect *item; +public: + select_subselect(Item_subselect *item); + bool send_fields(List &list, uint flag) { return 0; }; + bool send_data(List &items); + bool send_eof() { return 0; }; + + friend class Ttem_subselect; +}; + /* Structs used when sorting */ typedef struct st_sort_field { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index dfa60918665..134e776a15a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -901,6 +901,7 @@ void st_select_lex_node::init_select() void st_select_lex_unit::init_query() { + linkage= GLOBAL_OPTIONS_TYPE; st_select_lex_node::init_query(); global_parameters= this; select_limit_cnt= HA_POS_ERROR; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d8d9c854652..c5e5e971e33 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -156,6 +156,19 @@ int handle_select(THD *thd, LEX *lex, select_result *result) { int res; register SELECT_LEX *select_lex = &lex->select_lex; + if (select_lex->link_next) + { + /* Fix tables 'to-be-unioned-from' list to point at opened tables */ + for (SELECT_LEX *sl= select_lex; + sl; + sl= (SELECT_LEX*)sl->link_next) + { + for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; + cursor; + cursor=cursor->next) + cursor->table= cursor->table_list->table; + } + } if (select_lex->next) res=mysql_union(thd,lex,result); else @@ -180,50 +193,42 @@ int handle_select(THD *thd, LEX *lex, select_result *result) ** mysql_select assumes that all tables are already opened *****************************************************************************/ +/* + Prepare of whole select (including subselect in future). + return -1 on error + 0 on success +*/ int -mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, - ORDER *order, ORDER *group,Item *having,ORDER *proc_param, - ulong select_options,select_result *result, - SELECT_LEX_UNIT *unit) +JOIN::prepare(TABLE_LIST *tables_init, + COND *conds_init, ORDER *order_init, ORDER *group_init, + Item *having_init, + ORDER *proc_param_init, SELECT_LEX *select, SELECT_LEX_UNIT *unit) { - TABLE *tmp_table; - int error, tmp_error; - bool need_tmp,hidden_group_fields; - bool simple_order,simple_group,no_order, skip_sort_order, buffer_result; - Item::cond_result cond_value; - SQL_SELECT *select; - DYNAMIC_ARRAY keyuse; - JOIN join; - Procedure *procedure; - List all_fields(fields); - bool select_distinct; - SELECT_LEX *select_lex= &(thd->lex.select_lex); - SELECT_LEX *cur_sel= thd->lex.select; - DBUG_ENTER("mysql_select"); + DBUG_ENTER("JOIN::prepare"); - /* Check that all tables, fields, conds and order are ok */ + conds= conds_init; + order= order_init; + group_list= group_init; + having= having_init; + proc_param= proc_param_init; + tables_list= tables_init; + select_lex= select; - select_distinct=test(select_options & SELECT_DISTINCT); - buffer_result=test(select_options & OPTION_BUFFER_RESULT) && !test(select_options & OPTION_FOUND_ROWS); - tmp_table=0; - select=0; - no_order=skip_sort_order=0; - bzero((char*) &keyuse,sizeof(keyuse)); - thd->proc_info="init"; - thd->used_tables=0; // Updated by setup_fields + /* Check that all tables, fields, conds and order are ok */ - if (setup_tables(tables) || - setup_fields(thd,tables,fields,1,&all_fields,1) || - setup_conds(thd,tables,&conds) || - setup_order(thd,tables,fields,all_fields,order) || - setup_group(thd,tables,fields,all_fields,group,&hidden_group_fields)) + if (setup_tables(tables_list) || + setup_fields(thd,tables_list,fields_list,1,&all_fields,1) || + setup_conds(thd,tables_list,&conds) || + setup_order(thd,tables_list,fields_list,all_fields,order) || + setup_group(thd,tables_list,fields_list,all_fields,group_list, + &hidden_group_fields)) DBUG_RETURN(-1); /* purecov: inspected */ if (having) { thd->where="having clause"; thd->allow_sum_func=1; - if (having->fix_fields(thd,tables) || thd->fatal_error) + if (having->fix_fields(thd,tables_list) || thd->fatal_error) DBUG_RETURN(-1); /* purecov: inspected */ if (having->with_sum_func) having->split_sum_func(all_fields); @@ -236,13 +241,11 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, TODO: Add check of calculation of GROUP functions and fields: SELECT COUNT(*)+table.col1 from table1; */ - join.table=0; - join.tables=0; { - if (!group) + if (!group_list) { uint flag=0; - List_iterator_fast it(fields); + List_iterator_fast it(fields_list); Item *item; while ((item= it++)) { @@ -258,22 +261,23 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } } TABLE_LIST *table; - for (table=tables ; table ; table=table->next) - join.tables++; + for (table=tables_list ; table ; table=table->next) + tables++; } - procedure=setup_procedure(thd,proc_param,result,fields,&error); + procedure=setup_procedure(thd,proc_param,result,fields_list,&error); if (error) DBUG_RETURN(-1); /* purecov: inspected */ if (procedure) { - if (setup_new_fields(thd,tables,fields,all_fields,procedure->param_fields)) + if (setup_new_fields(thd, tables_list, fields_list, all_fields, + procedure->param_fields)) { /* purecov: inspected */ delete procedure; /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */ } if (procedure->group) { - if (!test_if_subpart(procedure->group,group)) + if (!test_if_subpart(procedure->group,group_list)) { /* purecov: inspected */ my_message(0,"Can't handle procedures with differents groups yet", MYF(0)); /* purecov: inspected */ @@ -282,7 +286,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } } #ifdef NOT_NEEDED - else if (!group && procedure->flags & PROC_GROUP) + else if (!group_list && procedure->flags & PROC_GROUP) { my_message(0,"Select must have a group with this procedure",MYF(0)); delete procedure; @@ -298,52 +302,54 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } /* Init join struct */ - join.thd=thd; - join.lock=thd->lock; - join.join_tab=0; - join.tmp_table_param.copy_field=0; - join.sum_funcs=0; - join.send_records=join.found_records=join.examined_rows=0; - join.tmp_table_param.end_write_records= HA_POS_ERROR; - join.first_record=join.sort_and_group=0; - join.select_options=select_options; - join.result=result; - count_field_types(&join.tmp_table_param,all_fields,0); - join.const_tables=0; - join.having=0; - join.do_send_rows = 1; - join.group= group != 0; - join.row_limit= ((select_distinct || order || group) ? HA_POS_ERROR : - unit->select_limit_cnt); - join.unit= unit; + count_field_types(&tmp_table_param, all_fields, 0); + this->group= group_list != 0; + row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR : + unit->select_limit_cnt); + this->unit= unit; #ifdef RESTRICTED_GROUP - if (join.sum_func_count && !group && (join.func_count || join.field_count)) + if (sum_func_count && !group_list && (func_count || field_count)) { my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0)); delete procedure; DBUG_RETURN(-1); } #endif - if (!procedure && result->prepare(fields, unit)) + if (!procedure && result->prepare(fields_list, unit)) { /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */ } + DBUG_RETURN(0); // All OK +} + +/* + global select optimisation. + return 0 - success + 1 - go out + -1 - go out with cleaning + error code saved in field 'error' +*/ +int +JOIN::optimize() +{ + DBUG_ENTER("JOIN::optimize"); + SELECT_LEX *select_lex = &(thd->lex.select_lex); #ifdef HAVE_REF_TO_FIELDS // Not done yet /* Add HAVING to WHERE if possible */ - if (having && !group && ! join.sum_func_count) + if (having && !group_list && ! sum_func_count) { if (!conds) { - conds=having; - having=0; + conds= having; + having= 0; } else if ((conds=new Item_cond_and(conds,having))) { - conds->fix_fields(thd,tables); - conds->change_ref_to_fields(thd,tables); - having=0; + conds->fix_fields(thd, tables_list); + conds->change_ref_to_fields(thd, tables_list); + having= 0; } } #endif @@ -352,110 +358,76 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, if (thd->fatal_error) // Out of memory { delete procedure; - DBUG_RETURN(0); + error = 0; + DBUG_RETURN(1); } if (cond_value == Item::COND_FALSE || !unit->select_limit_cnt) { /* Impossible cond */ - if (select_options & SELECT_DESCRIBE && select_lex->next) - select_describe(&join,false,false,false,"Impossible WHERE"); - else - error=return_zero_rows(result, tables, fields, - join.tmp_table_param.sum_func_count != 0 && !group, - select_options,"Impossible WHERE",having, - procedure, unit); - delete procedure; - DBUG_RETURN(error); + zero_result_cause= "Impossible WHERE"; + DBUG_RETURN(0); } /* Optimize count(*), min() and max() */ - if (tables && join.tmp_table_param.sum_func_count && ! group) + if (tables_list && tmp_table_param.sum_func_count && ! group_list) { int res; - if ((res=opt_sum_query(tables, all_fields, conds))) + if ((res=opt_sum_query(tables_list, all_fields, conds))) { if (res < 0) { - if (select_options & SELECT_DESCRIBE && select_lex->next) - select_describe(&join,false,false,false,"No matching min/max row"); - else - error=return_zero_rows(result, tables, fields, !group, - select_options, "No matching min/max row", - having, procedure, unit); - delete procedure; - DBUG_RETURN(error); + zero_result_cause= "No matching min/max row"; + DBUG_RETURN(0); } if (select_options & SELECT_DESCRIBE) { if (select_lex->next) - select_describe(&join,false,false,false,"Select tables optimized away"); + select_describe(this, false, false, false, + "Select tables optimized away"); else - describe_info(thd,"Select tables optimized away"); + describe_info(thd, "Select tables optimized away"); delete procedure; - DBUG_RETURN(error); + DBUG_RETURN(1); } - tables=0; // All tables resolved + tables_list= 0; // All tables resolved } } - if (!tables) - { // Only test of functions - error=0; - if (select_options & SELECT_DESCRIBE) - { - if (select_lex->next) - select_describe(&join,false,false,false,"No tables used"); - else - describe_info(thd,"No tables used"); - } - else - { - result->send_fields(fields,1); - if (!having || having->val_int()) - { - if (join.do_send_rows && result->send_data(fields)) - { - result->send_error(0,NullS); /* purecov: inspected */ - error=1; - } - else - error=(int) result->send_eof(); - } - else - error=(int) result->send_eof(); - } - delete procedure; - DBUG_RETURN(error); + + if (!tables_list) + { + test_function_query= 1; + DBUG_RETURN(0); } - error = -1; - join.sort_by_table=get_sort_by_table(order,group,tables); + error= -1; + sort_by_table= get_sort_by_table(order, group_list, tables_list); /* Calculate how to do the join */ - thd->proc_info="statistics"; - if (make_join_statistics(&join,tables,conds,&keyuse) || thd->fatal_error) - goto err; - thd->proc_info="preparing"; - result->initialize_tables(&join); - if (join.const_table_map != join.found_const_table_map && + thd->proc_info= "statistics"; + if (make_join_statistics(this, tables_list, conds, &keyuse) || + thd->fatal_error) + DBUG_RETURN(-1); + thd->proc_info= "preparing"; + result->initialize_tables(this); + if (const_table_map != found_const_table_map && !(select_options & SELECT_DESCRIBE)) { - error= return_zero_rows(result, tables, fields, - join.tmp_table_param.sum_func_count != 0 && - !group, 0, "", having, procedure, unit); - goto err; + zero_result_cause= ""; + select_options= 0; //TODO why option in return_zero_rows was droped + DBUG_RETURN(0); } if (!(thd->options & OPTION_BIG_SELECTS) && - join.best_read > (double) thd->max_join_size && + best_read > (double) thd->max_join_size && !(select_options & SELECT_DESCRIBE)) { /* purecov: inspected */ result->send_error(ER_TOO_BIG_SELECT,ER(ER_TOO_BIG_SELECT)); /* purecov: inspected */ error= 1; /* purecov: inspected */ - goto err; /* purecov: inspected */ + DBUG_RETURN(-1); } - if (join.const_tables && !thd->locked_tables && + if (const_tables && !thd->locked_tables && !(select_options & SELECT_NO_UNLOCK)) { TABLE **table, **end; - for (table=join.table, end=table + join.const_tables ; + for (table=this->table, end=table + const_tables ; table != end; table++) { @@ -467,98 +439,94 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } (*table)->file->index_end(); } - mysql_unlock_some_tables(thd, join.table,join.const_tables); + mysql_unlock_some_tables(thd, this->table, const_tables); } - if (!conds && join.outer_join) + if (!conds && outer_join) { /* Handle the case where we have an OUTER JOIN without a WHERE */ conds=new Item_int((longlong) 1,1); // Always true } - select=make_select(*join.table, join.const_table_map, - join.const_table_map,conds,&error); + select=make_select(*table, const_table_map, + const_table_map, conds, &error); if (error) { /* purecov: inspected */ error= -1; /* purecov: inspected */ - goto err; /* purecov: inspected */ + DBUG_RETURN(-1); } - if (make_join_select(&join,select,conds)) + if (make_join_select(this, select, conds)) { - if (select_options & SELECT_DESCRIBE && select_lex->next) - select_describe(&join,false,false,false,"Impossible WHERE noticed after reading const tables"); - else - error= return_zero_rows(result,tables,fields, - join.tmp_table_param.sum_func_count != 0 && - !group, - select_options, - "Impossible WHERE noticed after reading const tables", - having, procedure, unit); - goto err; + zero_result_cause= + "Impossible WHERE noticed after reading const tables"; + DBUG_RETURN(0); } error= -1; /* if goto err */ /* Optimize distinct away if possible */ - order=remove_const(&join,order,conds,&simple_order); - if (group || join.tmp_table_param.sum_func_count) + order= remove_const(this, order, conds, &simple_order); + if (group_list || tmp_table_param.sum_func_count) { if (! hidden_group_fields) select_distinct=0; } - else if (select_distinct && join.tables - join.const_tables == 1 && + else if (select_distinct && tables - const_tables == 1 && (unit->select_limit_cnt == HA_POS_ERROR || - (join.select_options & OPTION_FOUND_ROWS) || + (select_options & OPTION_FOUND_ROWS) || order && !(skip_sort_order= - test_if_skip_sort_order(&join.join_tab[join.const_tables], - order, unit->select_limit_cnt,1)))) + test_if_skip_sort_order(&join_tab[const_tables], + order, + unit->select_limit_cnt, + 1)))) { - if ((group=create_distinct_group(order,fields))) + if ((group_list= create_distinct_group(order, fields_list))) { - select_distinct=0; + select_distinct= 0; no_order= !order; - join.group=1; // For end_write_group + group= 1; // For end_write_group } else if (thd->fatal_error) // End of memory - goto err; + DBUG_RETURN(-1); } - group=remove_const(&join,group,conds,&simple_group); - if (!group && join.group) + group_list= remove_const(this, group_list, conds, &simple_group); + if (!group_list && group) { order=0; // The output has only one row simple_order=1; } - calc_group_buffer(&join,group); - join.send_group_parts=join.tmp_table_param.group_parts; /* Save org parts */ + calc_group_buffer(this, group_list); + send_group_parts= tmp_table_param.group_parts; /* Save org parts */ if (procedure && procedure->group) { - group=procedure->group=remove_const(&join,procedure->group,conds, - &simple_group); - calc_group_buffer(&join,group); + group_list= procedure->group= remove_const(this, procedure->group, conds, + &simple_group); + calc_group_buffer(this, group_list); } - if (test_if_subpart(group,order) || - (!group && join.tmp_table_param.sum_func_count)) + if (test_if_subpart(group_list, order) || + (!group_list && tmp_table_param.sum_func_count)) order=0; // Can't use sort on head table if using row cache - if (join.full_join) + if (full_join) { - if (group) + if (group_list) simple_group=0; if (order) simple_order=0; } - need_tmp= (join.const_tables != join.tables && + need_tmp= (const_tables != tables && ((select_distinct || !simple_order || !simple_group) || - (group && order) || buffer_result)); + (group_list && order) || buffer_result)); // No cache for MATCH - make_join_readinfo(&join, + make_join_readinfo(this, (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | - (cur_sel->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE : 0)); + (thd->lex.select->ftfunc_list.elements ? + SELECT_NO_JOIN_CACHE : 0)); /* Need to tell Innobase that to play it safe, it should fetch all columns of the tables: this is because MySQL @@ -567,60 +535,132 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, by MySQL. */ #ifdef HAVE_INNOBASE_DB - if (need_tmp || select_distinct || group || order) + if (need_tmp || select_distinct || group_list || order) { - for (uint i_h = join.const_tables; i_h < join.tables; i_h++) + for (uint i_h = const_tables; i_h < tables; i_h++) { - TABLE* table_h = join.join_tab[i_h].table; + TABLE* table_h = join_tab[i_h].table; if (table_h->db_type == DB_TYPE_INNODB) table_h->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE); } } #endif - DBUG_EXECUTE("info",TEST_join(&join);); + DBUG_EXECUTE("info",TEST_join(this);); /* Because filesort always does a full table scan or a quick range scan we must add the removed reference to the select for the table. We only need to do this when we have a simple_order or simple_group as in other cases the join is done before the sort. */ - if ((order || group) && join.join_tab[join.const_tables].type != JT_ALL && - join.join_tab[join.const_tables].type != JT_FT && - (order && simple_order || group && simple_group)) + if ((order || group_list) && join_tab[const_tables].type != JT_ALL && + join_tab[const_tables].type != JT_FT && + (order && simple_order || group_list && simple_group)) { - if (add_ref_to_table_cond(thd,&join.join_tab[join.const_tables])) - goto err; + if (add_ref_to_table_cond(thd,&join_tab[const_tables])) + DBUG_RETURN(-1); } if (!(select_options & SELECT_BIG_RESULT) && - ((group && join.const_tables != join.tables && + ((group_list && const_tables != tables && (!simple_group || - !test_if_skip_sort_order(&join.join_tab[join.const_tables], group, - unit->select_limit_cnt, 0))) || + !test_if_skip_sort_order(&join_tab[const_tables], group_list, + unit->select_limit_cnt, + 0))) || select_distinct) && - join.tmp_table_param.quick_group && !procedure) + tmp_table_param.quick_group && !procedure) { need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort } + DBUG_RETURN(0); +} + +/* + global uptimisation (with subselect) must be here (TODO) +*/ + +int +JOIN::global_optimize() +{ + return 0; +} + +/* + exec select +*/ +void +JOIN::exec() +{ + int tmp_error; + + DBUG_ENTER("JOIN::exec"); + + if (test_function_query) + { // Only test of functions + error=0; + if (select_options & SELECT_DESCRIBE) + { + if (select_lex->next) + select_describe(this, false, false, false, "No tables used"); + else + describe_info(thd, "No tables used"); + } + else + { + result->send_fields(fields_list,1); + if (!having || having->val_int()) + { + if (do_send_rows && result->send_data(fields_list)) + { + result->send_error(0,NullS); /* purecov: inspected */ + error=1; + } + else + error=(int) result->send_eof(); + } + else + error=(int) result->send_eof(); + } + delete procedure; + DBUG_VOID_RETURN; + } + + if (zero_result_cause) + { + if (select_options & SELECT_DESCRIBE && select_lex->next) + select_describe(this, false, false, false, zero_result_cause); + else + error=return_zero_rows(result, tables_list, fields_list, + tmp_table_param.sum_func_count != 0 && + !group_list, + select_options, + zero_result_cause, + having,procedure, + unit); + DBUG_VOID_RETURN; + } + + Item *having_list = having; + having = 0; if (select_options & SELECT_DESCRIBE) { if (!order && !no_order) - order=group; + order=group_list; if (order && - (join.const_tables == join.tables || + (const_tables == tables || (simple_order && - test_if_skip_sort_order(&join.join_tab[join.const_tables], order, - (join.const_tables != join.tables - 1 || - (join.select_options & OPTION_FOUND_ROWS)) ? - HA_POS_ERROR : unit->select_limit_cnt, 0)))) + test_if_skip_sort_order(&join_tab[const_tables], order, + (const_tables != tables - 1 || + (select_options & OPTION_FOUND_ROWS)) ? + HA_POS_ERROR : unit->select_limit_cnt, + 0)))) order=0; - select_describe(&join,need_tmp, + select_describe(this, need_tmp, order != 0 && !skip_sort_order, select_distinct); error=0; - goto err; + DBUG_VOID_RETURN; } /* Perform FULLTEXT search before all regular searches */ @@ -632,44 +672,45 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, DBUG_PRINT("info",("Creating tmp table")); thd->proc_info="Creating tmp table"; - if (!(tmp_table = - create_tmp_table(thd,&join.tmp_table_param,all_fields, + if (!(exec_tmp_table = + create_tmp_table(thd, &tmp_table_param, all_fields, ((!simple_group && !procedure && !(test_flags & TEST_NO_KEY_GROUP)) ? - group : (ORDER*) 0), - group ? 0 : select_distinct, - group && simple_group, + group_list : (ORDER*) 0), + group_list ? 0 : select_distinct, + group_list && simple_group, (order == 0 || skip_sort_order) && - !(join.select_options & OPTION_FOUND_ROWS), - join.select_options, unit))) - goto err; /* purecov: inspected */ + !(select_options & OPTION_FOUND_ROWS), + select_options, unit))) + DBUG_VOID_RETURN; - if (having && (join.sort_and_group || (tmp_table->distinct && !group))) - join.having=having; + if (having_list && + (sort_and_group || (exec_tmp_table->distinct && !group_list))) + having=having_list; /* if group or order on first table, sort first */ - if (group && simple_group) + if (group_list && simple_group) { DBUG_PRINT("info",("Sorting for group")); thd->proc_info="Sorting for group"; - if (create_sort_index(&join.join_tab[join.const_tables],group, + if (create_sort_index(&join_tab[const_tables], group_list, HA_POS_ERROR) || - make_sum_func_list(&join,all_fields) || - alloc_group_fields(&join,group)) - goto err; - group=0; + make_sum_func_list(this, all_fields) || + alloc_group_fields(this, group_list)) + DBUG_VOID_RETURN; + group_list=0; } else { - if (make_sum_func_list(&join,all_fields)) - goto err; - if (!group && ! tmp_table->distinct && order && simple_order) + if (make_sum_func_list(this, all_fields)) + DBUG_VOID_RETURN; + if (!group_list && ! exec_tmp_table->distinct && order && simple_order) { DBUG_PRINT("info",("Sorting for order")); thd->proc_info="Sorting for order"; - if (create_sort_index(&join.join_tab[join.const_tables],order, - HA_POS_ERROR)) - goto err; /* purecov: inspected */ + if (create_sort_index(&join_tab[const_tables], order, + HA_POS_ERROR)) + DBUG_VOID_RETURN; order=0; } } @@ -680,58 +721,58 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, In this case we can stop scanning t2 when we have found one t1.a */ - if (tmp_table->distinct) + if (exec_tmp_table->distinct) { table_map used_tables= thd->used_tables; - JOIN_TAB *join_tab=join.join_tab+join.tables-1; + JOIN_TAB *join_tab= this->join_tab+tables-1; do { if (used_tables & join_tab->table->map) break; join_tab->not_used_in_distinct=1; - } while (join_tab-- != join.join_tab); + } while (join_tab-- != this->join_tab); /* Optimize "select distinct b from t1 order by key_part_1 limit #" */ if (order && skip_sort_order) { - (void) test_if_skip_sort_order(&join.join_tab[join.const_tables], + (void) test_if_skip_sort_order(&this->join_tab[const_tables], order, unit->select_limit_cnt, 0); order=0; } } /* Copy data to the temporary table */ - thd->proc_info="Copying to tmp table"; - if ((tmp_error=do_select(&join,(List *) 0,tmp_table,0))) + thd->proc_info= "Copying to tmp table"; + if ((tmp_error= do_select(this, (List *) 0, exec_tmp_table, 0))) { - error=tmp_error; - goto err; /* purecov: inspected */ + error= tmp_error; + DBUG_VOID_RETURN; } - if (join.having) - join.having=having=0; // Allready done + if (having) + having= having_list= 0; // Allready done /* Change sum_fields reference to calculated fields in tmp_table */ - if (join.sort_and_group || tmp_table->group) + if (sort_and_group || exec_tmp_table->group) { if (change_to_use_tmp_fields(all_fields)) - goto err; - join.tmp_table_param.field_count+=join.tmp_table_param.sum_func_count+ - join.tmp_table_param.func_count; - join.tmp_table_param.sum_func_count=join.tmp_table_param.func_count=0; + DBUG_VOID_RETURN; + tmp_table_param.field_count+= tmp_table_param.sum_func_count+ + tmp_table_param.func_count; + tmp_table_param.sum_func_count= tmp_table_param.func_count= 0; } else { if (change_refs_to_tmp_fields(thd,all_fields)) - goto err; - join.tmp_table_param.field_count+=join.tmp_table_param.func_count; - join.tmp_table_param.func_count=0; + DBUG_VOID_RETURN; + tmp_table_param.field_count+= tmp_table_param.func_count; + tmp_table_param.func_count= 0; } if (procedure) procedure->update_refs(); - if (tmp_table->group) + if (exec_tmp_table->group) { // Already grouped if (!order && !no_order) - order=group; /* order by group */ - group=0; + order= group_list; /* order by group */ + group_list= 0; } /* @@ -742,153 +783,196 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, ** like SEC_TO_TIME(SUM(...)). */ - if (group && (!test_if_subpart(group,order) || select_distinct) || + if (group_list && (!test_if_subpart(group_list,order) || + select_distinct) || (select_distinct && - join.tmp_table_param.using_indirect_summary_function)) + tmp_table_param.using_indirect_summary_function)) { /* Must copy to another table */ TABLE *tmp_table2; DBUG_PRINT("info",("Creating group table")); /* Free first data from old join */ - join_free(&join); - if (make_simple_join(&join,tmp_table)) - goto err; - calc_group_buffer(&join,group); - count_field_types(&join.tmp_table_param,all_fields, - select_distinct && !group); - join.tmp_table_param.hidden_field_count=(all_fields.elements- - fields.elements); + join_free(this); + if (make_simple_join(this, exec_tmp_table)) + DBUG_VOID_RETURN; + calc_group_buffer(this, group_list); + count_field_types(&tmp_table_param, all_fields, + select_distinct && !group_list); + tmp_table_param.hidden_field_count= (all_fields.elements- + fields_list.elements); /* group data to new table */ - if (!(tmp_table2 = create_tmp_table(thd,&join.tmp_table_param,all_fields, + if (!(tmp_table2 = create_tmp_table(thd, &tmp_table_param, all_fields, (ORDER*) 0, - select_distinct && !group, + select_distinct && !group_list, 1, 0, - join.select_options, unit))) - goto err; /* purecov: inspected */ - if (group) + select_options, unit))) + DBUG_VOID_RETURN; + if (group_list) { thd->proc_info="Creating sort index"; - if (create_sort_index(join.join_tab,group,HA_POS_ERROR) || - alloc_group_fields(&join,group)) + if (create_sort_index(join_tab, group_list, HA_POS_ERROR) || + alloc_group_fields(this, group_list)) { free_tmp_table(thd,tmp_table2); /* purecov: inspected */ - goto err; /* purecov: inspected */ + DBUG_VOID_RETURN; } - group=0; + group_list= 0; } thd->proc_info="Copying to group table"; tmp_error= -1; - if (make_sum_func_list(&join,all_fields) || - (tmp_error=do_select(&join,(List *) 0,tmp_table2,0))) + if (make_sum_func_list(this, all_fields) || + (tmp_error=do_select(this, (List *) 0,tmp_table2,0))) { error=tmp_error; free_tmp_table(thd,tmp_table2); - goto err; /* purecov: inspected */ + DBUG_VOID_RETURN; } - end_read_record(&join.join_tab->read_record); - free_tmp_table(thd,tmp_table); - join.const_tables=join.tables; // Mark free for join_free() - tmp_table=tmp_table2; - join.join_tab[0].table=0; // Table is freed + end_read_record(&join_tab->read_record); + free_tmp_table(thd,exec_tmp_table); + const_tables= tables; // Mark free for join_free() + exec_tmp_table= tmp_table2; + join_tab[0].table= 0; // Table is freed if (change_to_use_tmp_fields(all_fields)) // No sum funcs anymore - goto err; - join.tmp_table_param.field_count+=join.tmp_table_param.sum_func_count; - join.tmp_table_param.sum_func_count=0; + DBUG_VOID_RETURN; + tmp_table_param.field_count+= tmp_table_param.sum_func_count; + tmp_table_param.sum_func_count= 0; } - if (tmp_table->distinct) + if (exec_tmp_table->distinct) select_distinct=0; /* Each row is unique */ - join_free(&join); /* Free quick selects */ - if (select_distinct && ! group) + join_free(this); /* Free quick selects */ + if (select_distinct && ! group_list) { thd->proc_info="Removing duplicates"; - if (having) - having->update_used_tables(); - if (remove_duplicates(&join,tmp_table,fields, having)) - goto err; /* purecov: inspected */ - having=0; + if (having_list) + having_list->update_used_tables(); + if (remove_duplicates(this, exec_tmp_table, fields_list, having_list)) + DBUG_VOID_RETURN; + having_list=0; select_distinct=0; } - tmp_table->reginfo.lock_type=TL_UNLOCK; - if (make_simple_join(&join,tmp_table)) - goto err; - calc_group_buffer(&join,group); - count_field_types(&join.tmp_table_param,all_fields,0); + exec_tmp_table->reginfo.lock_type=TL_UNLOCK; + if (make_simple_join(this, exec_tmp_table)) + DBUG_VOID_RETURN; + calc_group_buffer(this, group_list); + count_field_types(&tmp_table_param, all_fields, 0); } if (procedure) { - if (procedure->change_columns(fields) || - result->prepare(fields, unit)) - goto err; - count_field_types(&join.tmp_table_param, all_fields, 0); + if (procedure->change_columns(fields_list) || + result->prepare(fields_list, unit)) + DBUG_VOID_RETURN; + count_field_types(&tmp_table_param, all_fields, 0); } - if (join.group || join.tmp_table_param.sum_func_count || + if (group || tmp_table_param.sum_func_count || (procedure && (procedure->flags & PROC_GROUP))) { - alloc_group_fields(&join,group); - setup_copy_fields(thd, &join.tmp_table_param,all_fields); - if (make_sum_func_list(&join,all_fields) || thd->fatal_error) - goto err; /* purecov: inspected */ + alloc_group_fields(this, group_list); + setup_copy_fields(thd, &tmp_table_param,all_fields); + if (make_sum_func_list(this, all_fields) || thd->fatal_error) + DBUG_VOID_RETURN; } - if (group || order) + if (group_list || order) { DBUG_PRINT("info",("Sorting for send_fields")); thd->proc_info="Sorting result"; /* If we have already done the group, add HAVING to sorted table */ - if (having && ! group && ! join.sort_and_group) + if (having_list && ! group_list && ! sort_and_group) { - having->update_used_tables(); // Some tables may have been const - JOIN_TAB *table=&join.join_tab[join.const_tables]; - table_map used_tables= join.const_table_map | table->table->map; + having_list->update_used_tables(); // Some tables may have been const + JOIN_TAB *table= &join_tab[const_tables]; + table_map used_tables= const_table_map | table->table->map; - Item* sort_table_cond=make_cond_for_table(having,used_tables,used_tables); + Item* sort_table_cond= make_cond_for_table(having_list, used_tables, + used_tables); if (sort_table_cond) { if (!table->select) if (!(table->select=new SQL_SELECT)) - goto err; + DBUG_VOID_RETURN; if (!table->select->cond) table->select->cond=sort_table_cond; else // This should never happen if (!(table->select->cond=new Item_cond_and(table->select->cond, sort_table_cond))) - goto err; + DBUG_VOID_RETURN; table->select_cond=table->select->cond; DBUG_EXECUTE("where",print_where(table->select->cond, "select and having");); - having=make_cond_for_table(having,~ (table_map) 0,~used_tables); + having_list= make_cond_for_table(having_list, ~ (table_map) 0, + ~used_tables); DBUG_EXECUTE("where",print_where(conds,"having after sort");); } } - if (create_sort_index(&join.join_tab[join.const_tables], - group ? group : order, - (having || group || - join.const_tables != join.tables - 1 || - (join.select_options & OPTION_FOUND_ROWS)) ? - HA_POS_ERROR : unit->select_limit_cnt)) - goto err; /* purecov: inspected */ + if (create_sort_index(&join_tab[const_tables], + group_list ? group_list : order, + (having_list || group_list || + const_tables != tables - 1 || + (select_options & OPTION_FOUND_ROWS)) ? + HA_POS_ERROR : unit->select_limit_cnt)) + DBUG_VOID_RETURN; } - join.having=having; // Actually a parameter + having=having_list; // Actually a parameter thd->proc_info="Sending data"; - error=do_select(&join,&fields,NULL,procedure); + error=do_select(this, &fields_list, NULL, procedure); + DBUG_VOID_RETURN; +} -err: - thd->limit_found_rows = join.send_records; - thd->examined_row_count = join.examined_rows; - thd->proc_info="end"; - join.lock=0; // It's faster to unlock later - join_free(&join); - thd->proc_info="end2"; // QQ - if (tmp_table) - free_tmp_table(thd,tmp_table); - thd->proc_info="end3"; // QQ +/* + Clean up join. Return error that hold JOIN. +*/ + +int +JOIN::cleanup(THD *thd) +{ + lock=0; // It's faster to unlock later + join_free(this); + if (exec_tmp_table) + free_tmp_table(thd, exec_tmp_table); delete select; delete_dynamic(&keyuse); delete procedure; - thd->proc_info="end4"; // QQ + return error; +} + +int +mysql_select(THD *thd, TABLE_LIST *tables, List &fields, COND *conds, + ORDER *order, ORDER *group,Item *having, ORDER *proc_param, + ulong select_options, select_result *result, SELECT_LEX_UNIT *unit) +{ + JOIN *join = new JOIN(thd, fields, select_options, result); + + DBUG_ENTER("mysql_select"); + thd->proc_info="init"; + thd->used_tables=0; // Updated by setup_fields + + if (join->prepare(tables, conds, order, group, having, proc_param, + &(thd->lex.select_lex), unit)) + { + DBUG_RETURN(-1); + } + switch(join->optimize()) + { + case 1: + DBUG_RETURN(join->error); + case -1: + goto err; + } + + if(join->global_optimize()) + goto err; + + join->exec(); + +err: + thd->limit_found_rows = join->send_records; + thd->examined_row_count = join->examined_rows; + thd->proc_info="end"; + int error= join->cleanup(thd); + delete join; DBUG_RETURN(error); } @@ -2538,7 +2622,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) static void -make_join_readinfo(JOIN *join,uint options) +make_join_readinfo(JOIN *join, uint options) { uint i; SELECT_LEX *select_lex = &(join->thd->lex.select_lex); diff --git a/sql/sql_select.cc.rej b/sql/sql_select.cc.rej new file mode 100644 index 00000000000..e5be98e9859 --- /dev/null +++ b/sql/sql_select.cc.rej @@ -0,0 +1,1576 @@ +*************** +*** 65,71 **** + static int return_zero_rows(select_result *res,TABLE_LIST *tables, + List &fields, bool send_row, + uint select_options, const char *info, +- Item *having, Procedure *proc); + static COND *optimize_cond(COND *conds,Item::cond_result *cond_value); + static COND *remove_eq_conds(COND *cond,Item::cond_result *cond_value); + static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item); +--- 65,72 ---- + static int return_zero_rows(select_result *res,TABLE_LIST *tables, + List &fields, bool send_row, + uint select_options, const char *info, ++ Item *having, Procedure *proc, ++ SELECT_LEX *select_lex); + static COND *optimize_cond(COND *conds,Item::cond_result *cond_value); + static COND *remove_eq_conds(COND *cond,Item::cond_result *cond_value); + static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item); +*************** +*** 180,228 **** + ** mysql_select assumes that all tables are already opened + *****************************************************************************/ + + int +- mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, +- ORDER *order, ORDER *group,Item *having,ORDER *proc_param, +- ulong select_options,select_result *result) +- { +- TABLE *tmp_table; +- int error, tmp_error; +- bool need_tmp,hidden_group_fields; +- bool simple_order,simple_group,no_order, skip_sort_order, buffer_result; +- Item::cond_result cond_value; +- SQL_SELECT *select; +- DYNAMIC_ARRAY keyuse; +- JOIN join; +- Procedure *procedure; +- List all_fields(fields); +- bool select_distinct; +- SELECT_LEX *select_lex = &(thd->lex.select_lex); +- SELECT_LEX *cur_sel = thd->lex.select; +- DBUG_ENTER("mysql_select"); + +- /* Check that all tables, fields, conds and order are ok */ + +- select_distinct=test(select_options & SELECT_DISTINCT); +- buffer_result=test(select_options & OPTION_BUFFER_RESULT) && !test(select_options & OPTION_FOUND_ROWS); +- tmp_table=0; +- select=0; +- no_order=skip_sort_order=0; +- bzero((char*) &keyuse,sizeof(keyuse)); +- thd->proc_info="init"; +- thd->used_tables=0; // Updated by setup_fields + +- if (setup_tables(tables) || +- setup_fields(thd,tables,fields,1,&all_fields,1) || +- setup_conds(thd,tables,&conds) || +- setup_order(thd,tables,fields,all_fields,order) || +- setup_group(thd,tables,fields,all_fields,group,&hidden_group_fields)) + DBUG_RETURN(-1); /* purecov: inspected */ + + if (having) + { + thd->where="having clause"; + thd->allow_sum_func=1; +- if (having->fix_fields(thd,tables) || thd->fatal_error) + DBUG_RETURN(-1); /* purecov: inspected */ + if (having->with_sum_func) + having->split_sum_func(all_fields); +--- 195,237 ---- + ** mysql_select assumes that all tables are already opened + *****************************************************************************/ + ++ /* ++ Prepare of whole select (including subselect in future). ++ return -1 on error ++ 0 on success ++ */ + int + ++ JOIN::prepare(TABLE_LIST *tables_init, ++ COND *conds_init, ORDER *order_init, ORDER *group_init, ++ Item *having_init, ++ ORDER *proc_param_init, SELECT_LEX *select) ++ { ++ DBUG_ENTER("JOIN::prepare"); ++ ++ conds= conds_init; ++ order= order_init; ++ group_list= group_init; ++ having= having_init; ++ proc_param= proc_param_init; ++ tables_list= tables_init; ++ select_lex= select; + ++ /* Check that all tables, fields, conds and order are ok */ + ++ if (setup_tables(tables_list) || ++ setup_fields(thd,tables_list,fields_list,1,&all_fields,1) || ++ setup_conds(thd,tables_list,&conds) || ++ setup_order(thd,tables_list,fields_list,all_fields,order) || ++ setup_group(thd,tables_list,fields_list,all_fields,group_list, ++ &hidden_group_fields)) + DBUG_RETURN(-1); /* purecov: inspected */ + + if (having) + { + thd->where="having clause"; + thd->allow_sum_func=1; ++ if (having->fix_fields(thd,tables_list) || thd->fatal_error) + DBUG_RETURN(-1); /* purecov: inspected */ + if (having->with_sum_func) + having->split_sum_func(all_fields); +*************** +*** 297,347 **** + } + + /* Init join struct */ +- join.thd=thd; +- join.lock=thd->lock; +- join.join_tab=0; +- join.tmp_table_param.copy_field=0; +- join.sum_funcs=0; +- join.send_records=join.found_records=join.examined_rows=0; +- join.tmp_table_param.end_write_records= HA_POS_ERROR; +- join.first_record=join.sort_and_group=0; +- join.select_options=select_options; +- join.result=result; +- count_field_types(&join.tmp_table_param,all_fields,0); +- join.const_tables=0; +- join.having=0; +- join.do_send_rows = 1; +- join.group= group != 0; +- join.row_limit= ((select_distinct || order || group) ? HA_POS_ERROR : +- thd->select_limit); + + #ifdef RESTRICTED_GROUP +- if (join.sum_func_count && !group && (join.func_count || join.field_count)) + { + my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0)); + delete procedure; + DBUG_RETURN(-1); + } + #endif +- if (!procedure && result->prepare(fields)) + { /* purecov: inspected */ + DBUG_RETURN(-1); /* purecov: inspected */ + } + + #ifdef HAVE_REF_TO_FIELDS // Not done yet + /* Add HAVING to WHERE if possible */ +- if (having && !group && ! join.sum_func_count) + { + if (!conds) + { +- conds=having; +- having=0; + } + else if ((conds=new Item_cond_and(conds,having))) + { +- conds->fix_fields(thd,tables); +- conds->change_ref_to_fields(thd,tables); +- having=0; + } + } + #endif +--- 305,358 ---- + } + + /* Init join struct */ ++ count_field_types(&tmp_table_param, all_fields, 0); ++ this->group= group_list != 0; ++ row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR : ++ select_lex->first_in_union->select_limit_cnt); + + #ifdef RESTRICTED_GROUP ++ if (sum_func_count && !group_list && (func_count || field_count)) + { + my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0)); + delete procedure; + DBUG_RETURN(-1); + } + #endif ++ if (!procedure && result->prepare(fields_list, select_lex->first_in_union)) + { /* purecov: inspected */ + DBUG_RETURN(-1); /* purecov: inspected */ + } ++ DBUG_RETURN(0); // All OK ++ } ++ ++ /* ++ global select optimisation. ++ return 0 - success ++ 1 - go out ++ -1 - go out with cleaning ++ ++ error code saved in field 'error' ++ */ ++ int ++ JOIN::optimize() ++ { ++ DBUG_ENTER("JOIN::optimize"); ++ SELECT_LEX *select_lex = &(thd->lex.select_lex); + + #ifdef HAVE_REF_TO_FIELDS // Not done yet + /* Add HAVING to WHERE if possible */ ++ if (having && !group_list && ! sum_func_count) + { + if (!conds) + { ++ conds= having; ++ having= 0; + } + else if ((conds=new Item_cond_and(conds,having))) + { ++ conds->fix_fields(thd, tables_list); ++ conds->change_ref_to_fields(thd, tables_list); ++ having= 0; + } + } + #endif +*************** +*** 350,459 **** + if (thd->fatal_error) // Out of memory + { + delete procedure; +- DBUG_RETURN(0); + } +- if (cond_value == Item::COND_FALSE || !thd->select_limit) + { /* Impossible cond */ +- if (select_options & SELECT_DESCRIBE && select_lex->next) +- select_describe(&join,false,false,false,"Impossible WHERE"); +- else +- error=return_zero_rows(result, tables, fields, +- join.tmp_table_param.sum_func_count != 0 && !group, +- select_options,"Impossible WHERE",having, +- procedure); +- delete procedure; +- DBUG_RETURN(error); + } + + /* Optimize count(*), min() and max() */ +- if (tables && join.tmp_table_param.sum_func_count && ! group) + { + int res; +- if ((res=opt_sum_query(tables, all_fields, conds))) + { + if (res < 0) + { +- if (select_options & SELECT_DESCRIBE && select_lex->next) +- select_describe(&join,false,false,false,"No matching min/max row"); +- else +- error=return_zero_rows(result, tables, fields, !group, +- select_options,"No matching min/max row", +- having,procedure); +- delete procedure; +- DBUG_RETURN(error); + } + if (select_options & SELECT_DESCRIBE) + { + if (select_lex->next) +- select_describe(&join,false,false,false,"Select tables optimized away"); + else +- describe_info(thd,"Select tables optimized away"); + delete procedure; +- DBUG_RETURN(error); + } +- tables=0; // All tables resolved + } + } +- if (!tables) +- { // Only test of functions +- error=0; +- if (select_options & SELECT_DESCRIBE) +- { +- if (select_lex->next) +- select_describe(&join,false,false,false,"No tables used"); +- else +- describe_info(thd,"No tables used"); +- } +- else +- { +- result->send_fields(fields,1); +- if (!having || having->val_int()) +- { +- if (join.do_send_rows && result->send_data(fields)) +- { +- result->send_error(0,NullS); /* purecov: inspected */ +- error=1; +- } +- else +- error=(int) result->send_eof(); +- } +- else +- error=(int) result->send_eof(); +- } +- delete procedure; +- DBUG_RETURN(error); + } + +- error = -1; +- join.sort_by_table=get_sort_by_table(order,group,tables); + + /* Calculate how to do the join */ +- thd->proc_info="statistics"; +- if (make_join_statistics(&join,tables,conds,&keyuse) || thd->fatal_error) +- goto err; +- thd->proc_info="preparing"; +- result->initialize_tables(&join); +- if (join.const_table_map != join.found_const_table_map && + !(select_options & SELECT_DESCRIBE)) + { +- error=return_zero_rows(result,tables,fields, +- join.tmp_table_param.sum_func_count != 0 && +- !group,0,"",having,procedure); +- goto err; + } + if (!(thd->options & OPTION_BIG_SELECTS) && +- join.best_read > (double) thd->max_join_size && + !(select_options & SELECT_DESCRIBE)) + { /* purecov: inspected */ + result->send_error(ER_TOO_BIG_SELECT,ER(ER_TOO_BIG_SELECT)); /* purecov: inspected */ + error= 1; /* purecov: inspected */ +- goto err; /* purecov: inspected */ + } +- if (join.const_tables && !thd->locked_tables && + !(select_options & SELECT_NO_UNLOCK)) + { + TABLE **table, **end; +- for (table=join.table, end=table + join.const_tables ; + table != end; + table++) + { +--- 361,436 ---- + if (thd->fatal_error) // Out of memory + { + delete procedure; ++ error = 0; ++ DBUG_RETURN(1); + } ++ if (cond_value == Item::COND_FALSE || ++ !select_lex->first_in_union->select_limit_cnt) + { /* Impossible cond */ ++ zero_result_cause= "Impossible WHERE"; ++ DBUG_RETURN(0); + } + + /* Optimize count(*), min() and max() */ ++ if (tables_list && tmp_table_param.sum_func_count && ! group_list) + { + int res; ++ if ((res=opt_sum_query(tables_list, all_fields, conds))) + { + if (res < 0) + { ++ zero_result_cause= "No matching min/max row"; ++ DBUG_RETURN(0); + } + if (select_options & SELECT_DESCRIBE) + { + if (select_lex->next) ++ select_describe(this, false, false, false, ++ "Select tables optimized away"); + else ++ describe_info(thd, "Select tables optimized away"); + delete procedure; ++ DBUG_RETURN(1); + } ++ tables_list=0; // All tables resolved + } + } ++ if (!tables_list) ++ { ++ test_function_query= 1; ++ DBUG_RETURN(0); + } + ++ error= -1; ++ sort_by_table= get_sort_by_table(order, group_list, tables_list); + + /* Calculate how to do the join */ ++ thd->proc_info= "statistics"; ++ if (make_join_statistics(this, tables_list, conds, &keyuse) || ++ thd->fatal_error) ++ DBUG_RETURN(-1); ++ thd->proc_info= "preparing"; ++ result->initialize_tables(this); ++ if (const_table_map != found_const_table_map && + !(select_options & SELECT_DESCRIBE)) + { ++ zero_result_cause= ""; ++ select_options= 0; //TODO why option in return_zero_rows was droped ++ DBUG_RETURN(0); + } + if (!(thd->options & OPTION_BIG_SELECTS) && ++ best_read > (double) thd->max_join_size && + !(select_options & SELECT_DESCRIBE)) + { /* purecov: inspected */ + result->send_error(ER_TOO_BIG_SELECT,ER(ER_TOO_BIG_SELECT)); /* purecov: inspected */ + error= 1; /* purecov: inspected */ ++ DBUG_RETURN(-1); + } ++ if (const_tables && !thd->locked_tables && + !(select_options & SELECT_NO_UNLOCK)) + { + TABLE **table, **end; ++ for (table=this->table, end=table + const_tables ; + table != end; + table++) + { +*************** +*** 465,561 **** + } + (*table)->file->index_end(); + } +- mysql_unlock_some_tables(thd, join.table,join.const_tables); + } +- if (!conds && join.outer_join) + { + /* Handle the case where we have an OUTER JOIN without a WHERE */ + conds=new Item_int((longlong) 1,1); // Always true + } +- select=make_select(*join.table, join.const_table_map, +- join.const_table_map,conds,&error); + if (error) + { /* purecov: inspected */ + error= -1; /* purecov: inspected */ +- goto err; /* purecov: inspected */ + } +- if (make_join_select(&join,select,conds)) + { +- if (select_options & SELECT_DESCRIBE && select_lex->next) +- select_describe(&join,false,false,false,"Impossible WHERE noticed after reading const tables"); +- else +- error=return_zero_rows(result,tables,fields, +- join.tmp_table_param.sum_func_count != 0 && !group, +- select_options, +- "Impossible WHERE noticed after reading const tables", +- having,procedure); +- goto err; + } + + error= -1; /* if goto err */ + + /* Optimize distinct away if possible */ +- order=remove_const(&join,order,conds,&simple_order); +- if (group || join.tmp_table_param.sum_func_count) + { + if (! hidden_group_fields) + select_distinct=0; + } +- else if (select_distinct && join.tables - join.const_tables == 1 && +- (thd->select_limit == HA_POS_ERROR || +- (join.select_options & OPTION_FOUND_ROWS) || + order && + !(skip_sort_order= +- test_if_skip_sort_order(&join.join_tab[join.const_tables], +- order, thd->select_limit,1)))) + { +- if ((group=create_distinct_group(order,fields))) + { + select_distinct=0; + no_order= !order; +- join.group=1; // For end_write_group + } + else if (thd->fatal_error) // End of memory +- goto err; + } +- group=remove_const(&join,group,conds,&simple_group); +- if (!group && join.group) + { + order=0; // The output has only one row + simple_order=1; + } + +- calc_group_buffer(&join,group); +- join.send_group_parts=join.tmp_table_param.group_parts; /* Save org parts */ + if (procedure && procedure->group) + { +- group=procedure->group=remove_const(&join,procedure->group,conds, +- &simple_group); +- calc_group_buffer(&join,group); + } + +- if (test_if_subpart(group,order) || +- (!group && join.tmp_table_param.sum_func_count)) + order=0; + + // Can't use sort on head table if using row cache +- if (join.full_join) + { +- if (group) + simple_group=0; + if (order) + simple_order=0; + } + +- need_tmp= (join.const_tables != join.tables && + ((select_distinct || !simple_order || !simple_group) || +- (group && order) || buffer_result)); + + // No cache for MATCH +- make_join_readinfo(&join, + (select_options & (SELECT_DESCRIBE | + SELECT_NO_JOIN_CACHE)) | +- (cur_sel->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE : 0)); + + /* Need to tell Innobase that to play it safe, it should fetch all + columns of the tables: this is because MySQL +--- 442,535 ---- + } + (*table)->file->index_end(); + } ++ mysql_unlock_some_tables(thd, this->table, const_tables); + } ++ if (!conds && outer_join) + { + /* Handle the case where we have an OUTER JOIN without a WHERE */ + conds=new Item_int((longlong) 1,1); // Always true + } ++ select=make_select(*table, const_table_map, ++ const_table_map, conds, &error); + if (error) + { /* purecov: inspected */ + error= -1; /* purecov: inspected */ ++ DBUG_RETURN(-1); + } ++ if (make_join_select(this, select, conds)) + { ++ zero_result_cause= ++ "Impossible WHERE noticed after reading const tables"; ++ DBUG_RETURN(0); + } + + error= -1; /* if goto err */ + + /* Optimize distinct away if possible */ ++ order=remove_const(this,order,conds,&simple_order); ++ if (group_list || tmp_table_param.sum_func_count) + { + if (! hidden_group_fields) + select_distinct=0; + } ++ else if (select_distinct && tables - const_tables == 1 && ++ (select_lex->first_in_union->select_limit_cnt == HA_POS_ERROR || ++ (select_options & OPTION_FOUND_ROWS) || + order && + !(skip_sort_order= ++ test_if_skip_sort_order(&join_tab[const_tables], ++ order, ++ select_lex->first_in_union->select_limit_cnt, ++ 1)))) + { ++ if ((group_list=create_distinct_group(order, fields_list))) + { + select_distinct=0; + no_order= !order; ++ group=1; // For end_write_group + } + else if (thd->fatal_error) // End of memory ++ DBUG_RETURN(-1); + } ++ group_list= remove_const(this, group_list, conds, &simple_group); ++ if (!group_list && group) + { + order=0; // The output has only one row + simple_order=1; + } + ++ calc_group_buffer(this, group_list); ++ send_group_parts=tmp_table_param.group_parts; /* Save org parts */ + if (procedure && procedure->group) + { ++ group_list= procedure->group= remove_const(this, procedure->group, conds, ++ &simple_group); ++ calc_group_buffer(this, group_list); + } + ++ if (test_if_subpart(group_list, order) || ++ (!group_list && tmp_table_param.sum_func_count)) + order=0; + + // Can't use sort on head table if using row cache ++ if (full_join) + { ++ if (group_list) + simple_group=0; + if (order) + simple_order=0; + } + ++ need_tmp= (const_tables != tables && + ((select_distinct || !simple_order || !simple_group) || ++ (group_list && order) || buffer_result)); + + // No cache for MATCH ++ make_join_readinfo(this, + (select_options & (SELECT_DESCRIBE | + SELECT_NO_JOIN_CACHE)) | ++ (thd->lex.select->ftfunc_list.elements ? ++ SELECT_NO_JOIN_CACHE : 0)); + + /* Need to tell Innobase that to play it safe, it should fetch all + columns of the tables: this is because MySQL +*************** +*** 564,624 **** + by MySQL. */ + + #ifdef HAVE_INNOBASE_DB +- if (need_tmp || select_distinct || group || order) + { +- for (uint i_h = join.const_tables; i_h < join.tables; i_h++) + { +- TABLE* table_h = join.join_tab[i_h].table; + if (table_h->db_type == DB_TYPE_INNODB) + table_h->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE); + } + } + #endif + +- DBUG_EXECUTE("info",TEST_join(&join);); + /* + Because filesort always does a full table scan or a quick range scan + we must add the removed reference to the select for the table. + We only need to do this when we have a simple_order or simple_group + as in other cases the join is done before the sort. + */ +- if ((order || group) && join.join_tab[join.const_tables].type != JT_ALL && +- join.join_tab[join.const_tables].type != JT_FT && +- (order && simple_order || group && simple_group)) + { +- if (add_ref_to_table_cond(thd,&join.join_tab[join.const_tables])) +- goto err; + } + + if (!(select_options & SELECT_BIG_RESULT) && +- ((group && join.const_tables != join.tables && + (!simple_group || +- !test_if_skip_sort_order(&join.join_tab[join.const_tables], group, +- thd->select_limit,0))) || + select_distinct) && +- join.tmp_table_param.quick_group && !procedure) + { + need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort + } + + if (select_options & SELECT_DESCRIBE) + { + if (!order && !no_order) +- order=group; + if (order && +- (join.const_tables == join.tables || + (simple_order && +- test_if_skip_sort_order(&join.join_tab[join.const_tables], order, +- (join.const_tables != join.tables - 1 || +- (join.select_options & OPTION_FOUND_ROWS)) ? +- HA_POS_ERROR : thd->select_limit,0)))) + order=0; +- select_describe(&join,need_tmp, + (order != 0 && +- (!need_tmp || order != group || simple_group)), + select_distinct); + error=0; +- goto err; + } + + /* Perform FULLTEXT search before all regular searches */ +--- 538,672 ---- + by MySQL. */ + + #ifdef HAVE_INNOBASE_DB ++ if (need_tmp || select_distinct || group_list || order) + { ++ for (uint i_h = const_tables; i_h < tables; i_h++) + { ++ TABLE* table_h = join_tab[i_h].table; + if (table_h->db_type == DB_TYPE_INNODB) + table_h->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE); + } + } + #endif + ++ DBUG_EXECUTE("info",TEST_join(this);); + /* + Because filesort always does a full table scan or a quick range scan + we must add the removed reference to the select for the table. + We only need to do this when we have a simple_order or simple_group + as in other cases the join is done before the sort. + */ ++ if ((order || group_list) && join_tab[const_tables].type != JT_ALL && ++ join_tab[const_tables].type != JT_FT && ++ (order && simple_order || group_list && simple_group)) + { ++ if (add_ref_to_table_cond(thd,&join_tab[const_tables])) ++ DBUG_RETURN(-1); + } + + if (!(select_options & SELECT_BIG_RESULT) && ++ ((group_list && const_tables != tables && + (!simple_group || ++ !test_if_skip_sort_order(&join_tab[const_tables], group_list, ++ select_lex->first_in_union->select_limit_cnt, ++ 0))) || + select_distinct) && ++ tmp_table_param.quick_group && !procedure) + { + need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort + } ++ DBUG_RETURN(0); ++ } ++ ++ /* ++ global uptimisation (with subselect) must be here (TODO) ++ */ ++ ++ int ++ JOIN::global_optimize() ++ { ++ return 0; ++ } ++ ++ /* ++ exec select ++ */ ++ ++ void ++ JOIN::exec() ++ { ++ int tmp_error; ++ ++ DBUG_ENTER("JOIN::exec"); ++ ++ if (test_function_query) ++ { // Only test of functions ++ error=0; ++ if (select_options & SELECT_DESCRIBE) ++ { ++ if (select_lex->next) ++ select_describe(this, false, false, false, "No tables used"); ++ else ++ describe_info(thd, "No tables used"); ++ } ++ else ++ { ++ result->send_fields(fields_list,1); ++ if (!having || having->val_int()) ++ { ++ if (do_send_rows && result->send_data(fields_list)) ++ { ++ result->send_error(0,NullS); /* purecov: inspected */ ++ error=1; ++ } ++ else ++ error=(int) result->send_eof(); ++ } ++ else ++ error=(int) result->send_eof(); ++ } ++ delete procedure; ++ DBUG_VOID_RETURN; ++ } ++ ++ if (zero_result_cause) ++ { ++ if (select_options & SELECT_DESCRIBE && select_lex->next) ++ select_describe(this, false, false, false, zero_result_cause); ++ else ++ error=return_zero_rows(result, tables_list, fields_list, ++ tmp_table_param.sum_func_count != 0 && ++ !group_list, ++ select_options, ++ zero_result_cause, ++ having,procedure, ++ select_lex->first_in_union); ++ DBUG_VOID_RETURN; ++ } ++ ++ Item *having_list = having; ++ having = 0; + + if (select_options & SELECT_DESCRIBE) + { + if (!order && !no_order) ++ order=group_list; + if (order && ++ (const_tables == tables || + (simple_order && ++ test_if_skip_sort_order(&join_tab[const_tables], order, ++ (const_tables != tables - 1 || ++ (select_options & OPTION_FOUND_ROWS)) ? ++ HA_POS_ERROR : ++ select_lex->first_in_union->select_limit_cnt, ++ 0)))) + order=0; ++ select_describe(this, need_tmp, + (order != 0 && ++ (!need_tmp || order != group_list || simple_group)), + select_distinct); + error=0; ++ DBUG_VOID_RETURN; + } + + /* Perform FULLTEXT search before all regular searches */ +*************** +*** 630,673 **** + DBUG_PRINT("info",("Creating tmp table")); + thd->proc_info="Creating tmp table"; + +- if (!(tmp_table = +- create_tmp_table(thd,&join.tmp_table_param,all_fields, + ((!simple_group && !procedure && + !(test_flags & TEST_NO_KEY_GROUP)) ? +- group : (ORDER*) 0), +- group ? 0 : select_distinct, +- group && simple_group, + (order == 0 || skip_sort_order) && +- !(join.select_options & OPTION_FOUND_ROWS), +- join.select_options))) +- goto err; /* purecov: inspected */ +- +- if (having && (join.sort_and_group || (tmp_table->distinct && !group))) +- join.having=having; + + /* if group or order on first table, sort first */ +- if (group && simple_group) + { + DBUG_PRINT("info",("Sorting for group")); + thd->proc_info="Sorting for group"; +- if (create_sort_index(&join.join_tab[join.const_tables],group, + HA_POS_ERROR) || +- make_sum_func_list(&join,all_fields) || +- alloc_group_fields(&join,group)) +- goto err; +- group=0; + } + else + { +- if (make_sum_func_list(&join,all_fields)) +- goto err; +- if (!group && ! tmp_table->distinct && order && simple_order) + { + DBUG_PRINT("info",("Sorting for order")); + thd->proc_info="Sorting for order"; +- if (create_sort_index(&join.join_tab[join.const_tables],order, + HA_POS_ERROR)) +- goto err; /* purecov: inspected */ + order=0; + } + } +--- 678,722 ---- + DBUG_PRINT("info",("Creating tmp table")); + thd->proc_info="Creating tmp table"; + ++ if (!(exec_tmp_table = ++ create_tmp_table(thd,&tmp_table_param,all_fields, + ((!simple_group && !procedure && + !(test_flags & TEST_NO_KEY_GROUP)) ? ++ group_list : (ORDER*) 0), ++ group_list ? 0 : select_distinct, ++ group_list && simple_group, + (order == 0 || skip_sort_order) && ++ !(select_options & OPTION_FOUND_ROWS), ++ select_options, select_lex->first_in_union))) ++ DBUG_VOID_RETURN; ++ ++ if (having_list && ++ (sort_and_group || (exec_tmp_table->distinct && !group_list))) ++ having=having_list; + + /* if group or order on first table, sort first */ ++ if (group_list && simple_group) + { + DBUG_PRINT("info",("Sorting for group")); + thd->proc_info="Sorting for group"; ++ if (create_sort_index(&join_tab[const_tables],group_list, + HA_POS_ERROR) || ++ make_sum_func_list(this, all_fields) || ++ alloc_group_fields(this, group_list)) ++ DBUG_VOID_RETURN; ++ group_list=0; + } + else + { ++ if (make_sum_func_list(this, all_fields)) ++ DBUG_VOID_RETURN; ++ if (!group_list && ! exec_tmp_table->distinct && order && simple_order) + { + DBUG_PRINT("info",("Sorting for order")); + thd->proc_info="Sorting for order"; ++ if (create_sort_index(&join_tab[const_tables], order, + HA_POS_ERROR)) ++ DBUG_VOID_RETURN; + order=0; + } + } +*************** +*** 678,735 **** + In this case we can stop scanning t2 when we have found one t1.a + */ + +- if (tmp_table->distinct) + { + table_map used_tables= thd->used_tables; +- JOIN_TAB *join_tab=join.join_tab+join.tables-1; + do + { + if (used_tables & join_tab->table->map) + break; + join_tab->not_used_in_distinct=1; +- } while (join_tab-- != join.join_tab); + /* Optimize "select distinct b from t1 order by key_part_1 limit #" */ + if (order && skip_sort_order) + { +- (void) test_if_skip_sort_order(&join.join_tab[join.const_tables], +- order, thd->select_limit,0); + order=0; + } + } + + /* Copy data to the temporary table */ + thd->proc_info="Copying to tmp table"; +- if ((tmp_error=do_select(&join,(List *) 0,tmp_table,0))) + { +- error=tmp_error; +- goto err; /* purecov: inspected */ + } +- if (join.having) +- join.having=having=0; // Allready done + + /* Change sum_fields reference to calculated fields in tmp_table */ +- if (join.sort_and_group || tmp_table->group) + { + if (change_to_use_tmp_fields(all_fields)) +- goto err; +- join.tmp_table_param.field_count+=join.tmp_table_param.sum_func_count+ +- join.tmp_table_param.func_count; +- join.tmp_table_param.sum_func_count=join.tmp_table_param.func_count=0; + } + else + { + if (change_refs_to_tmp_fields(thd,all_fields)) +- goto err; +- join.tmp_table_param.field_count+=join.tmp_table_param.func_count; +- join.tmp_table_param.func_count=0; + } + if (procedure) + procedure->update_refs(); +- if (tmp_table->group) + { // Already grouped + if (!order && !no_order) +- order=group; /* order by group */ +- group=0; + } + + /* +--- 727,786 ---- + In this case we can stop scanning t2 when we have found one t1.a + */ + ++ if (exec_tmp_table->distinct) + { + table_map used_tables= thd->used_tables; ++ JOIN_TAB *join_tab= this->join_tab+tables-1; + do + { + if (used_tables & join_tab->table->map) + break; + join_tab->not_used_in_distinct=1; ++ } while (join_tab-- != this->join_tab); + /* Optimize "select distinct b from t1 order by key_part_1 limit #" */ + if (order && skip_sort_order) + { ++ (void) test_if_skip_sort_order(&this->join_tab[const_tables], ++ order, ++ select_lex->first_in_union->select_limit_cnt, ++ 0); + order=0; + } + } + + /* Copy data to the temporary table */ + thd->proc_info="Copying to tmp table"; ++ if ((tmp_error=do_select(this, (List *) 0, exec_tmp_table, 0))) + { ++ error= tmp_error; ++ DBUG_VOID_RETURN; + } ++ if (having) ++ having= having_list= 0; // Allready done + + /* Change sum_fields reference to calculated fields in tmp_table */ ++ if (sort_and_group || exec_tmp_table->group) + { + if (change_to_use_tmp_fields(all_fields)) ++ DBUG_VOID_RETURN; ++ tmp_table_param.field_count+= tmp_table_param.sum_func_count+ ++ tmp_table_param.func_count; ++ tmp_table_param.sum_func_count= tmp_table_param.func_count= 0; + } + else + { + if (change_refs_to_tmp_fields(thd,all_fields)) ++ DBUG_VOID_RETURN; ++ tmp_table_param.field_count+= tmp_table_param.func_count; ++ tmp_table_param.func_count= 0; + } + if (procedure) + procedure->update_refs(); ++ if (exec_tmp_table->group) + { // Already grouped + if (!order && !no_order) ++ order= group_list; /* order by group */ ++ group_list= 0; + } + + /* +*************** +*** 740,892 **** + ** like SEC_TO_TIME(SUM(...)). + */ + +- if (group && (!test_if_subpart(group,order) || select_distinct) || + (select_distinct && +- join.tmp_table_param.using_indirect_summary_function)) + { /* Must copy to another table */ + TABLE *tmp_table2; + DBUG_PRINT("info",("Creating group table")); + + /* Free first data from old join */ +- join_free(&join); +- if (make_simple_join(&join,tmp_table)) +- goto err; +- calc_group_buffer(&join,group); +- count_field_types(&join.tmp_table_param,all_fields, +- select_distinct && !group); +- join.tmp_table_param.hidden_field_count=(all_fields.elements- +- fields.elements); + + /* group data to new table */ +- if (!(tmp_table2 = create_tmp_table(thd,&join.tmp_table_param,all_fields, + (ORDER*) 0, +- select_distinct && !group, + 1, 0, +- join.select_options))) +- goto err; /* purecov: inspected */ +- if (group) + { + thd->proc_info="Creating sort index"; +- if (create_sort_index(join.join_tab,group,HA_POS_ERROR) || +- alloc_group_fields(&join,group)) + { + free_tmp_table(thd,tmp_table2); /* purecov: inspected */ +- goto err; /* purecov: inspected */ + } +- group=0; + } + thd->proc_info="Copying to group table"; + tmp_error= -1; +- if (make_sum_func_list(&join,all_fields) || +- (tmp_error=do_select(&join,(List *) 0,tmp_table2,0))) + { + error=tmp_error; + free_tmp_table(thd,tmp_table2); +- goto err; /* purecov: inspected */ + } +- end_read_record(&join.join_tab->read_record); +- free_tmp_table(thd,tmp_table); +- join.const_tables=join.tables; // Mark free for join_free() +- tmp_table=tmp_table2; +- join.join_tab[0].table=0; // Table is freed + + if (change_to_use_tmp_fields(all_fields)) // No sum funcs anymore +- goto err; +- join.tmp_table_param.field_count+=join.tmp_table_param.sum_func_count; +- join.tmp_table_param.sum_func_count=0; + } + +- if (tmp_table->distinct) + select_distinct=0; /* Each row is unique */ + +- join_free(&join); /* Free quick selects */ +- if (select_distinct && ! group) + { + thd->proc_info="Removing duplicates"; +- if (having) +- having->update_used_tables(); +- if (remove_duplicates(&join,tmp_table,fields, having)) +- goto err; /* purecov: inspected */ +- having=0; + select_distinct=0; + } +- tmp_table->reginfo.lock_type=TL_UNLOCK; +- if (make_simple_join(&join,tmp_table)) +- goto err; +- calc_group_buffer(&join,group); +- count_field_types(&join.tmp_table_param,all_fields,0); + } + if (procedure) + { +- if (procedure->change_columns(fields) || +- result->prepare(fields)) +- goto err; +- count_field_types(&join.tmp_table_param,all_fields,0); + } +- if (join.group || join.tmp_table_param.sum_func_count || + (procedure && (procedure->flags & PROC_GROUP))) + { +- alloc_group_fields(&join,group); +- setup_copy_fields(thd, &join.tmp_table_param,all_fields); +- if (make_sum_func_list(&join,all_fields) || thd->fatal_error) +- goto err; /* purecov: inspected */ + } +- if (group || order) + { + DBUG_PRINT("info",("Sorting for send_fields")); + thd->proc_info="Sorting result"; + /* If we have already done the group, add HAVING to sorted table */ +- if (having && ! group && ! join.sort_and_group) + { +- having->update_used_tables(); // Some tables may have been const +- JOIN_TAB *table=&join.join_tab[join.const_tables]; +- table_map used_tables= join.const_table_map | table->table->map; + +- Item* sort_table_cond=make_cond_for_table(having,used_tables,used_tables); + if (sort_table_cond) + { + if (!table->select) + if (!(table->select=new SQL_SELECT)) +- goto err; + if (!table->select->cond) + table->select->cond=sort_table_cond; + else // This should never happen + if (!(table->select->cond=new Item_cond_and(table->select->cond, + sort_table_cond))) +- goto err; + table->select_cond=table->select->cond; + DBUG_EXECUTE("where",print_where(table->select->cond, + "select and having");); +- having=make_cond_for_table(having,~ (table_map) 0,~used_tables); + DBUG_EXECUTE("where",print_where(conds,"having after sort");); + } + } +- if (create_sort_index(&join.join_tab[join.const_tables], +- group ? group : order, +- (having || group || +- join.const_tables != join.tables - 1 || +- (join.select_options & OPTION_FOUND_ROWS)) ? +- HA_POS_ERROR : thd->select_limit)) +- goto err; /* purecov: inspected */ + } +- join.having=having; // Actually a parameter + thd->proc_info="Sending data"; +- error=do_select(&join,&fields,NULL,procedure); + +- err: +- thd->limit_found_rows = join.send_records; +- thd->examined_row_count = join.examined_rows; +- thd->proc_info="end"; +- join.lock=0; // It's faster to unlock later +- join_free(&join); +- thd->proc_info="end2"; // QQ +- if (tmp_table) +- free_tmp_table(thd,tmp_table); +- thd->proc_info="end3"; // QQ + delete select; + delete_dynamic(&keyuse); + delete procedure; +- thd->proc_info="end4"; // QQ + DBUG_RETURN(error); + } + +--- 791,987 ---- + ** like SEC_TO_TIME(SUM(...)). + */ + ++ if (group_list && (!test_if_subpart(group_list,order) || select_distinct) || + (select_distinct && ++ tmp_table_param.using_indirect_summary_function)) + { /* Must copy to another table */ + TABLE *tmp_table2; + DBUG_PRINT("info",("Creating group table")); + + /* Free first data from old join */ ++ join_free(this); ++ if (make_simple_join(this, exec_tmp_table)) ++ DBUG_VOID_RETURN; ++ calc_group_buffer(this, group_list); ++ count_field_types(&tmp_table_param, all_fields, ++ select_distinct && !group_list); ++ tmp_table_param.hidden_field_count= (all_fields.elements- ++ fields_list.elements); + + /* group data to new table */ ++ if (!(tmp_table2 = create_tmp_table(thd,&tmp_table_param, all_fields, + (ORDER*) 0, ++ select_distinct && !group_list, + 1, 0, ++ select_options, ++ select_lex->first_in_union))) ++ DBUG_VOID_RETURN; ++ if (group_list) + { + thd->proc_info="Creating sort index"; ++ if (create_sort_index(join_tab,group_list,HA_POS_ERROR) || ++ alloc_group_fields(this, group_list)) + { + free_tmp_table(thd,tmp_table2); /* purecov: inspected */ ++ DBUG_VOID_RETURN; + } ++ group_list=0; + } + thd->proc_info="Copying to group table"; + tmp_error= -1; ++ if (make_sum_func_list(this, all_fields) || ++ (tmp_error=do_select(this, (List *) 0,tmp_table2,0))) + { + error=tmp_error; + free_tmp_table(thd,tmp_table2); ++ DBUG_VOID_RETURN; + } ++ end_read_record(&join_tab->read_record); ++ free_tmp_table(thd,exec_tmp_table); ++ const_tables= tables; // Mark free for join_free() ++ exec_tmp_table= tmp_table2; ++ join_tab[0].table= 0; // Table is freed + + if (change_to_use_tmp_fields(all_fields)) // No sum funcs anymore ++ DBUG_VOID_RETURN; ++ tmp_table_param.field_count+= tmp_table_param.sum_func_count; ++ tmp_table_param.sum_func_count=0; + } + ++ if (exec_tmp_table->distinct) + select_distinct=0; /* Each row is unique */ + ++ join_free(this); /* Free quick selects */ ++ if (select_distinct && ! group_list) + { + thd->proc_info="Removing duplicates"; ++ if (having_list) ++ having_list->update_used_tables(); ++ if (remove_duplicates(this, exec_tmp_table, fields_list, having_list)) ++ DBUG_VOID_RETURN; ++ having_list=0; + select_distinct=0; + } ++ exec_tmp_table->reginfo.lock_type=TL_UNLOCK; ++ if (make_simple_join(this, exec_tmp_table)) ++ DBUG_VOID_RETURN; ++ calc_group_buffer(this, group_list); ++ count_field_types(&tmp_table_param, all_fields, 0); + } + if (procedure) + { ++ if (procedure->change_columns(fields_list) || ++ result->prepare(fields_list, select_lex->first_in_union)) ++ DBUG_VOID_RETURN; ++ count_field_types(&tmp_table_param,all_fields,0); + } ++ if (group || tmp_table_param.sum_func_count || + (procedure && (procedure->flags & PROC_GROUP))) + { ++ alloc_group_fields(this, group_list); ++ setup_copy_fields(thd, &tmp_table_param,all_fields); ++ if (make_sum_func_list(this, all_fields) || thd->fatal_error) ++ DBUG_VOID_RETURN; + } ++ if (group_list || order) + { + DBUG_PRINT("info",("Sorting for send_fields")); + thd->proc_info="Sorting result"; + /* If we have already done the group, add HAVING to sorted table */ ++ if (having_list && ! group_list && ! sort_and_group) + { ++ having_list->update_used_tables(); // Some tables may have been const ++ JOIN_TAB *table=&join_tab[const_tables]; ++ table_map used_tables= const_table_map | table->table->map; + ++ Item* sort_table_cond=make_cond_for_table(having_list, used_tables, ++ used_tables); + if (sort_table_cond) + { + if (!table->select) + if (!(table->select=new SQL_SELECT)) ++ DBUG_VOID_RETURN; + if (!table->select->cond) + table->select->cond=sort_table_cond; + else // This should never happen + if (!(table->select->cond=new Item_cond_and(table->select->cond, + sort_table_cond))) ++ DBUG_VOID_RETURN; + table->select_cond=table->select->cond; + DBUG_EXECUTE("where",print_where(table->select->cond, + "select and having");); ++ having_list= make_cond_for_table(having_list, ~ (table_map) 0, ++ ~used_tables); + DBUG_EXECUTE("where",print_where(conds,"having after sort");); + } + } ++ if (create_sort_index(&join_tab[const_tables], ++ group_list ? group_list : order, ++ (having_list || group_list || ++ const_tables != tables - 1 || ++ (select_options & OPTION_FOUND_ROWS)) ? ++ HA_POS_ERROR : ++ select_lex->first_in_union->select_limit_cnt)) ++ DBUG_VOID_RETURN; + } ++ having=having_list; // Actually a parameter + thd->proc_info="Sending data"; ++ error=do_select(this, &fields_list, NULL, procedure); ++ DBUG_VOID_RETURN; ++ } + ++ /* ++ Clean up join. Return error that hold JOIN. ++ */ ++ ++ int ++ JOIN::cleanup(THD *thd) ++ { ++ lock=0; // It's faster to unlock later ++ join_free(this); ++ if (exec_tmp_table) ++ free_tmp_table(thd, exec_tmp_table); + delete select; + delete_dynamic(&keyuse); + delete procedure; ++ return error; ++ } ++ ++ int ++ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, ++ ORDER *order, ORDER *group,Item *having,ORDER *proc_param, ++ ulong select_options,select_result *result) ++ { ++ JOIN *join = new JOIN(thd, fields, select_options, result); ++ ++ DBUG_ENTER("mysql_select"); ++ thd->proc_info="init"; ++ thd->used_tables=0; // Updated by setup_fields ++ ++ if (join->prepare(tables, conds, order, group, having, proc_param, ++ &(thd->lex.select_lex))) ++ { ++ DBUG_RETURN(-1); ++ } ++ switch(join->optimize()) ++ { ++ case 1: ++ DBUG_RETURN(join->error); ++ case -1: ++ goto err; ++ } ++ ++ if(join->global_optimize()) ++ goto err; ++ ++ join->exec(); ++ ++ err: ++ thd->limit_found_rows = join->send_records; ++ thd->examined_row_count = join->examined_rows; ++ thd->proc_info="end"; ++ int error= join->cleanup(thd); ++ delete join; + DBUG_RETURN(error); + } + +*************** +*** 2480,2486 **** + + if ((tab->keys & ~ tab->const_keys && i > 0) || + (tab->const_keys && i == join->const_tables && +- join->thd->select_limit < join->best_positions[i].records_read && + !(join->select_options & OPTION_FOUND_ROWS))) + { + /* Join with outer join condition */ +--- 2575,2582 ---- + + if ((tab->keys & ~ tab->const_keys && i > 0) || + (tab->const_keys && i == join->const_tables && ++ join->select_lex->first_in_union->select_limit_cnt < ++ join->best_positions[i].records_read && + !(join->select_options & OPTION_FOUND_ROWS))) + { + /* Join with outer join condition */ +*************** +*** 2491,2497 **** + (join->select_options & + OPTION_FOUND_ROWS ? + HA_POS_ERROR : +- join->thd->select_limit)) < 0) + DBUG_RETURN(1); // Impossible range + sel->cond=orig_cond; + } +--- 2587,2593 ---- + (join->select_options & + OPTION_FOUND_ROWS ? + HA_POS_ERROR : ++ join->select_lex->first_in_union->select_limit_cnt)) < 0) + DBUG_RETURN(1); // Impossible range + sel->cond=orig_cond; + } +*************** +*** 2933,2939 **** + static int + return_zero_rows(select_result *result,TABLE_LIST *tables,List &fields, + bool send_row, uint select_options,const char *info, +- Item *having, Procedure *procedure) + { + DBUG_ENTER("return_zero_rows"); + +--- 3029,3035 ---- + static int + return_zero_rows(select_result *result,TABLE_LIST *tables,List &fields, + bool send_row, uint select_options,const char *info, ++ Item *having, Procedure *procedure, SELECT_LEX *select_lex) + { + DBUG_ENTER("return_zero_rows"); + +*************** +*** 2944,2950 **** + } + if (procedure) + { +- if (result->prepare(fields)) // This hasn't been done yet + DBUG_RETURN(-1); + } + if (send_row) +--- 3040,3047 ---- + } + if (procedure) + { ++ if (result->prepare(fields, ++ select_lex->first_in_union))//This hasn't been done yet + DBUG_RETURN(-1); + } + if (send_row) +*************** +*** 3479,3485 **** + TABLE * + create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, + ORDER *group, bool distinct, bool save_sum_fields, +- bool allow_distinct_limit, ulong select_options) + { + TABLE *table; + uint i,field_count,reclength,null_count,null_pack_length, +--- 3576,3583 ---- + TABLE * + create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, + ORDER *group, bool distinct, bool save_sum_fields, ++ bool allow_distinct_limit, ulong select_options, ++ SELECT_LEX *first_select) + { + TABLE *table; + uint i,field_count,reclength,null_count,null_pack_length, +*************** +*** 3850,3857 **** + test(null_pack_length)); + if (allow_distinct_limit) + { +- set_if_smaller(table->max_rows,thd->select_limit); +- param->end_write_records=thd->select_limit; + } + else + param->end_write_records= HA_POS_ERROR; +--- 3948,3955 ---- + test(null_pack_length)); + if (allow_distinct_limit) + { ++ set_if_smaller(table->max_rows,first_select->select_limit_cnt); ++ param->end_write_records=first_select->select_limit_cnt; + } + else + param->end_write_records= HA_POS_ERROR; +*************** +*** 4896,4902 **** + error=join->result->send_data(*join->fields); + if (error) + DBUG_RETURN(-1); /* purecov: inspected */ +- if (++join->send_records >= join->thd->select_limit && join->do_send_rows) + { + if (join->select_options & OPTION_FOUND_ROWS) + { +--- 4994,5002 ---- + error=join->result->send_data(*join->fields); + if (error) + DBUG_RETURN(-1); /* purecov: inspected */ ++ if (++join->send_records >= ++ join->select_lex->first_in_union->select_limit_cnt && ++ join->do_send_rows) + { + if (join->select_options & OPTION_FOUND_ROWS) + { +*************** +*** 4912,4918 **** + else + { + join->do_send_rows=0; +- join->thd->select_limit = HA_POS_ERROR; + DBUG_RETURN(0); + } + } +--- 5012,5018 ---- + else + { + join->do_send_rows=0; ++ join->select_lex->first_in_union->select_limit_cnt = HA_POS_ERROR; + DBUG_RETURN(0); + } + } +*************** +*** 4973,4985 **** + DBUG_RETURN(-1); /* purecov: inspected */ + if (end_of_records) + DBUG_RETURN(0); +- if (!error && ++join->send_records >= join->thd->select_limit && + join->do_send_rows) + { + if (!(join->select_options & OPTION_FOUND_ROWS)) + DBUG_RETURN(-3); // Abort nicely + join->do_send_rows=0; +- join->thd->select_limit = HA_POS_ERROR; + } + } + } +--- 5073,5086 ---- + DBUG_RETURN(-1); /* purecov: inspected */ + if (end_of_records) + DBUG_RETURN(0); ++ if (!error && ++join->send_records >= ++ join->select_lex->first_in_union->select_limit_cnt && + join->do_send_rows) + { + if (!(join->select_options & OPTION_FOUND_ROWS)) + DBUG_RETURN(-3); // Abort nicely + join->do_send_rows=0; ++ join->select_lex->first_in_union->select_limit_cnt = HA_POS_ERROR; + } + } + } +*************** +*** 5060,5066 **** + if (!(join->select_options & OPTION_FOUND_ROWS)) + DBUG_RETURN(-3); + join->do_send_rows=0; +- join->thd->select_limit = HA_POS_ERROR; + DBUG_RETURN(0); + } + } +--- 5161,5167 ---- + if (!(join->select_options & OPTION_FOUND_ROWS)) + DBUG_RETURN(-3); + join->do_send_rows=0; ++ join->select_lex->first_in_union->select_limit_cnt = HA_POS_ERROR; + DBUG_RETURN(0); + } + } +*************** +*** 5743,5749 **** + + if (!field_count) + { // only const items +- join->thd->select_limit=1; // Only send first row + DBUG_RETURN(0); + } + Field **first_field=entry->field+entry->fields - field_count; +--- 5844,5850 ---- + + if (!field_count) + { // only const items ++ join->select_lex->first_in_union->select_limit_cnt=1;// Only send first row + DBUG_RETURN(0); + } + Field **first_field=entry->field+entry->fields - field_count; diff --git a/sql/sql_select.h b/sql/sql_select.h index 5466974f587..ba27c5b4b3b 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -149,8 +149,7 @@ class TMP_TABLE_PARAM { } }; - -class JOIN { +class JOIN :public Sql_alloc{ public: JOIN_TAB *join_tab,**best_ref,**map2table; TABLE **table,**all_tables,*sort_by_table; @@ -175,6 +174,70 @@ class JOIN { MYSQL_LOCK *lock; // unit structure (with global parameters) for this select SELECT_LEX_UNIT *unit; + // select that processed + SELECT_LEX *select_lex; + + bool select_distinct, //Is select distinct? + no_order, simple_order, simple_group, + skip_sort_order, need_tmp, + hidden_group_fields, + buffer_result; + DYNAMIC_ARRAY keyuse; + Item::cond_result cond_value; + List all_fields; + List & fields_list; // hold field list passed to mysql_select + int error; + + ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select + COND *conds; // ---"--- + TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_selec + SQL_SELECT *select; //created in optimisation phase + TABLE *exec_tmp_table; //used in 'exec' to hold temporary + + my_bool test_function_query; // need to return select items 1 row + const char *zero_result_cause; // not 0 if exec must return zero result + + JOIN(THD *thd, List &fields, + ulong select_options, select_result *result): + join_tab(0), + table(0), + tables(0), const_tables(0), + sort_and_group(0), first_record(0), + do_send_rows(1), + send_records(0), found_records(0), examined_rows(0), + thd(thd), + sum_funcs(0), + having(0), + select_options(select_options), + result(result), + lock(thd->lock), + select_lex(0), //for safety + select_distinct(test(select_options & SELECT_DISTINCT)), + no_order(0), simple_order(0), simple_group(0), skip_sort_order(0), + need_tmp(0), + hidden_group_fields (0), /*safety*/ + buffer_result(test(select_options & OPTION_BUFFER_RESULT) && + !test(select_options & OPTION_FOUND_ROWS)), + all_fields(fields), + fields_list(fields), + select(0), + exec_tmp_table(0), + test_function_query(0), + zero_result_cause(0) + { + fields_list = fields; + bzero((char*) &keyuse,sizeof(keyuse)); + tmp_table_param.copy_field=0; + tmp_table_param.end_write_records= HA_POS_ERROR; + } + + int prepare(TABLE_LIST *tables, + COND *conds, ORDER *order, ORDER *group, Item *having, + ORDER *proc_param, SELECT_LEX *select, SELECT_LEX_UNIT *unit); + int optimize(); + int global_optimize(); + void exec(); + int cleanup(THD *thd); }; diff --git a/sql/sql_select.h.rej b/sql/sql_select.h.rej new file mode 100644 index 00000000000..07b1c4403f9 --- /dev/null +++ b/sql/sql_select.h.rej @@ -0,0 +1,96 @@ +*************** +*** 173,178 **** + select_result *result; + TMP_TABLE_PARAM tmp_table_param; + MYSQL_LOCK *lock; + }; + + +--- 172,240 ---- + select_result *result; + TMP_TABLE_PARAM tmp_table_param; + MYSQL_LOCK *lock; ++ ++ bool select_distinct, //Is select distinct? ++ no_order, simple_order, simple_group, ++ skip_sort_order, need_tmp, ++ hidden_group_fields, ++ buffer_result; ++ DYNAMIC_ARRAY keyuse; ++ Item::cond_result cond_value; ++ List all_fields; ++ List & fields_list; // hold field list passed to mysql_select ++ int error; ++ ++ ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select ++ COND *conds; // ---"--- ++ TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_select ++ SQL_SELECT *select; //created in optimisation phase ++ TABLE *exec_tmp_table; //used in 'exec' to hold temporary table ++ SELECT_LEX *select_lex; //corresponding select_lex ++ ++ my_bool test_function_query; // need to return select items 1 row ++ const char *zero_result_cause; // not 0 if exec must return zero result ++ ++ JOIN(THD *thd, List &fields, ++ ulong select_options, select_result *result): ++ join_tab(0), ++ table(0), ++ tables(0), const_tables(0), ++ sort_and_group(0), first_record(0), ++ do_send_rows(1), ++ send_records(0), found_records(0), examined_rows(0), ++ thd(thd), ++ sum_funcs(0), ++ having(0), ++ select_options(select_options), ++ result(result), ++ lock(thd->lock), ++ select_distinct(test(select_options & SELECT_DISTINCT)), ++ no_order(0), simple_order(0), simple_group(0), skip_sort_order(0), ++ need_tmp(0), ++ hidden_group_fields (0), /*safety*/ ++ buffer_result(test(select_options & OPTION_BUFFER_RESULT) && ++ !test(select_options & OPTION_FOUND_ROWS)), ++ all_fields(fields), ++ fields_list(fields), ++ select(0), ++ exec_tmp_table(0), ++ select_lex(0), //for safety ++ test_function_query(0), ++ zero_result_cause(0) ++ { ++ fields_list = fields; ++ bzero((char*) &keyuse,sizeof(keyuse)); ++ tmp_table_param.copy_field=0; ++ tmp_table_param.end_write_records= HA_POS_ERROR; ++ } ++ ++ int prepare(TABLE_LIST *tables, ++ COND *conds, ORDER *order, ORDER *group, Item *having, ++ ORDER *proc_param, SELECT_LEX *select); ++ int optimize(); ++ int global_optimize(); ++ void exec(); ++ int cleanup(THD *thd); + }; + + +*************** +*** 187,193 **** + bool store_val_in_field(Field *field,Item *val); + TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, + ORDER *group, bool distinct, bool save_sum_fields, +- bool allow_distinct_limit, ulong select_options); + void free_tmp_table(THD *thd, TABLE *entry); + void count_field_types(TMP_TABLE_PARAM *param, List &fields, + bool reset_with_sum_func); +--- 249,256 ---- + bool store_val_in_field(Field *field,Item *val); + TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, + ORDER *group, bool distinct, bool save_sum_fields, ++ bool allow_distinct_limit, ulong select_options, ++ SELECT_LEX *first_select); + void free_tmp_table(THD *thd, TABLE *entry); + void count_field_types(TMP_TABLE_PARAM *param, List &fields, + bool reset_with_sum_func); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index ef34af6fe1e..b5db593a234 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -40,17 +40,6 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) DBUG_ENTER("mysql_union"); st_select_lex_node * global; - /* Fix tables 'to-be-unioned-from' list to point at opened tables */ - for (sl= &lex->select_lex; - sl; - sl= (SELECT_LEX *) sl->next) - { - for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; - cursor; - cursor=cursor->next) - cursor->table= cursor->table_list->table; - } - /* Global option */ if (((void*)(global= unit->global_parameters)) == ((void*)unit)) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bd7a5ff3b48..8d981f05a1f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -544,7 +544,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); literal text_literal insert_ident order_ident simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr - using_list + using_list subselect subselect_init %type expr_list udf_expr_list when_list ident_list ident_list_arg @@ -612,7 +612,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild union union_list - precision union_option + precision union_option subselect_start subselect_end END_OF_INPUT %type @@ -1547,8 +1547,8 @@ optional_braces: | '(' ')' {} /* all possible expressions */ -expr: expr_expr {$$ = $1; } - | simple_expr {$$ = $1; } +expr: expr_expr { $$= $1; } + | simple_expr { $$= $1; } /* expressions that begin with 'expr' */ expr_expr: @@ -1688,6 +1688,7 @@ simple_expr: | NOT expr %prec NEG { $$= new Item_func_not($2); } | '!' expr %prec NEG { $$= new Item_func_not($2); } | '(' expr ')' { $$= $2; } + | subselect { $$= $1; } | '{' ident expr '}' { $$= $3; } | MATCH ident_list_arg AGAINST '(' expr ')' { Select->ftfunc_list.push_back((Item_func_match *) @@ -3849,3 +3850,30 @@ optional_order_or_limit: union_option: /* empty */ {} | ALL {Lex->union_option=1;} + +subselect: + subselect_start subselect_init + subselect_end + { + $$= $2; + } + +subselect_init: + select_init + { + $$= new Item_subselect(current_thd, Lex->select); + } + +subselect_start: + '(' + { + if (mysql_new_select(Lex, 1)) + YYABORT; + } + +subselect_end: + ')' + { + LEX *lex=Lex; + lex->select = (SELECT_LEX*)lex->select->master->master; + } -- cgit v1.2.1 From 9017573d1d5992e89bb8e80a0f51778d109bce13 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 May 2002 18:18:27 +0500 Subject: New Serbian error.txt --- sql/share/serbian/errmsg.txt | 234 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 sql/share/serbian/errmsg.txt (limited to 'sql') diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt new file mode 100644 index 00000000000..051924f799f --- /dev/null +++ b/sql/share/serbian/errmsg.txt @@ -0,0 +1,234 @@ +/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Serbian Translation, version 1.0: + Copyright 2002 Vladimir Kraljevic, vladimir_kraljevic@yahoo.com + This file is public domain and comes with NO WARRANTY of any kind */ + +"hashchk", +"isamchk", +"NE", +"DA", +"Ne mogu da kreiram file '%-.64s' (errno: %d)", +"Ne mogu da kreiram tabelu '%-.64s' (errno: %d)", +"Ne mogu da kreiram bazu '%-.64s'. (errno: %d)", +"Ne mogu da kreiram bazu '%-.64s'. Baza veæ postoji.", +"Ne mogu da izbrišem bazu '%-.64s'. Baza ne postoji.", +"Ne mogu da izbrišem bazu (ne mogu da izbrišem '%-.64s', errno: %d)", +"Ne mogu da izbrišem bazu (ne mogu da izbrišem direktorijum '%-.64s', errno: %d)", +"Greška pri brisanju '%-.64s' (errno: %d)", +"Ne mogu da proèitam slog iz sistemske tabele", +"Ne mogu da dobijem stanje file-a '%-.64s' (errno: %d)", +"Ne mogu da dobijem trenutni direktorijum (errno: %d)", +"Ne mogu da zakljuèam file (errno: %d)", +"Ne mogu da otvorim file: '%-.64s'. (errno: %d)", +"Ne mogu da pronaðem file: '%-.64s' (errno: %d)", +"Ne mogu da proèitam direktorijum '%-.64s' (errno: %d)", +"Ne mogu da promenim direktorijum na '%-.64s' (errno: %d)", +"Slog je promenjen od zadnjeg èitanja tabele '%-.64s'", +"Disk je pun (%s). Èekam nekoga da doðe i oslobodi nešto mesta....", +"Ne mogu da pišem pošto postoji duplirani kljuè u tabeli '%-.64s'", +"Greška pri zatvaranju '%-.64s' (errno: %d)", +"Greška pri èitanju file-a '%-.64s' (errno: %d)", +"Greška pri promeni imena '%-.64s' na '%-.64s' (errno: %d)", +"Greška pri upisu '%-.64s' (errno: %d)", +"'%-.64s' je zakljuèan za upis", +"Sortiranje je prekinuto", +"View '%-.64s' ne postoji za '%-.64s'", +"Handler tabela je vratio grešku %d", +"Handler tabela za '%-.64s' nema ovu opciju", +"Ne mogu da pronaðem slog u '%-.64s'", +"Pogrešna informacija u file-u: '%-.64s'", +"Pogrešan key file za tabelu: '%-.64s'. Probajte da ga ispravite", +"Zastareo key file za tabelu '%-.64s'; Ispravite ga", +"Tabelu '%-.64s' je dozvoljeno samo èitati", +"Nema memorije. Restartujte MySQL server i probajte ponovo (potrebno je %d byte-ova)", +"Nema memorije za sortiranje. Poveæajte velièinu sort buffer-a MySQL server-u", +"Neoèekivani kraj pri èitanju file-a '%-.64s' (errno: %d)", +"Previše konekcija", +"Nema memorije; Proverite da li MySQL server ili neki drugi proces koristi svu slobodnu memoriju. (UNIX: Ako ne, probajte da upotrebite 'ulimit' komandu da biste dozvolili daemon-u da koristi više memorije ili probajte da dodate više swap memorije)", +"Ne mogu da dobijem ime host-a za vašu IP adresu", +"Loš poèetak komunikacije (handshake)", +"Pristup je zabranjen korisniku '%-.32s@%-.64s' za bazu '%-.64s'", +"Pristup je zabranjen korisniku '%-.32s@%-.64s' (koristi lozinku: '%s')", +"Ni jedna baza nije selektovana", +"Nepoznata komanda", +"Kolona '%-.64s' ne može biti NULL", +"Nepoznata baza '%-.64s'", +"Tabela '%-.64s' veæ postoji", +"Nepoznata tabela '%-.64s'", +"Kolona '%-.64s' u %-.64s nije jedinstvena u kontekstu", +"Gašenje servera je u toku", +"Nepoznata kolona '%-.64s' u '%-.64s'", +"Entitet '%-.64s' nije naveden u komandi 'GROUP BY'", +"Ne mogu da grupišem po '%-.64s'", +"Izraz ima 'SUM' agregatnu funkciju i kolone u isto vreme", +"Broj kolona ne odgovara broju vrednosti", +"Ime '%-.100s' je predugaèko", +"Duplirano ime kolone '%-.64s'", +"Duplirano ime kljuèa '%-.64s'", +"Dupliran unos '%-.64s' za kljuè '%d'", +"Pogrešan naziv kolone za kolonu '%-.64s'", +"'%s' u iskazu '%-.80s' na liniji %d", +"Upit je bio prazan", +"Tabela ili alias nisu bili jedinstveni: '%-.64s'", +"Loša default vrednost za '%-.64s'", +"Definisani višestruki primarni kljuèevi", +"Navedeno je previše kljuèeva. Maksimum %d kljuèeva je dozvoljeno", +"Navedeno je previše delova kljuèa. Maksimum %d delova je dozvoljeno", +"Navedeni kljuè je predug. Maksimalna dužina kljuèa je %d", +"Kljuèna kolona '%-.64s' ne postoji u tabeli", +"BLOB kolona '%-.64s' ne može biti upotrebljena za navoðenje kljuèa sa tipom tabele koji se trenutno koristi", +"Previše podataka za kolonu '%-.64s' (maksimum je %d). Upotrebite BLOB polje", +"Pogrešna definicija tabele; U tabeli može postojati samo jedna 'AUTO' kolona i ona mora biti istovremeno definisana kao kolona kljuèa", +"%s: Spreman za konekcije\n", +"%s: Normalno gašenje\n", +"%s: Dobio signal %d. Prekidam!\n", +"%s: Gašenje završeno\n", +"%s: Usiljeno gašenje thread-a %ld koji pripada korisniku: '%-.32s'\n", +"Ne mogu da kreiram IP socket", +"Tabela '%-.64s' nema isti indeks kao onaj upotrebljen pri komandi 'CREATE INDEX'. Napravite tabelu ponovo", +"Argument separatora polja nije ono što se oèekivalo. Proverite uputstvo MySQL server-a", +"Ne možete koristiti fiksnu velièinu sloga kada imate BLOB polja. Molim koristite 'fields terminated by' opciju.", +"File '%-.64s' mora biti u direktorijumu gde su file-ovi baze i mora imati odgovarajuæa prava pristupa", +"File '%-.80s' veæ postoji", +"Slogova: %ld Izbrisano: %ld Preskoèeno: %ld Upozorenja: %ld", +"Slogova: %ld Duplikata: %ld", +"Pogrešan pod-kljuè dela kljuèa. Upotrebljeni deo kljuèa nije string, upotrebljena dužina je veæa od dela kljuèa ili handler tabela ne podržava jedinstvene pod-kljuèeve", +"Ne možete da izbrišete sve kolone pomoæu komande 'ALTER TABLE'. Upotrebite komandu 'DROP TABLE' ako želite to da uradite", +"Ne mogu da izvršim komandu drop 'DROP' na '%-.64s'. Proverite da li ta kolona (odnosno kljuè) postoji", +"Slogova: %ld Duplikata: %ld Upozorenja: %ld", +"Komanda 'INSERT TABLE' na '%-.64s' nije dozvoljena u listi 'FROM' tabela", +"Nepoznat thread identifikator: %lu", +"Vi niste vlasnik thread-a %lu", +"Nema upotrebljenih tabela", +"Previše string-ova za kolonu '%-.64s' i komandu 'SET'", +"Ne mogu da generišem jedinstveno ime log-file-a: '%-.64s.(1-999)'\n", +"Tabela '%-.64s' je zakljuèana READ lock-om; iz nje se može samo èitati ali u nju se ne može pisati", +"Tabela '%-.64s' nije bila zakljuèana komandom 'LOCK TABLES'", +"BLOB kolona '%-.64s' ne može imati default vrednost", +"Pogrešno ime baze '%-.100s'", +"Pogrešno ime tabele '%-.100s'", +"Komanda 'SELECT' æe ispitati previše slogova i potrošiti previše vremena. Proverite vaš 'WHERE' filter i upotrebite 'SET OPTION SQL_BIG_SELECTS=1' ako želite baš ovakvu komandu", +"Nepoznata greška", +"Nepoznata procedura '%-.64s'", +"Pogrešan broj parametara za proceduru '%-.64s'", +"Pogrešni parametri prosleðeni proceduri '%-.64s'", +"Nepoznata tabela '%-.64s' u '%-.32s'", +"Kolona '%-.64s' je navedena dva puta", +"Pogrešna upotreba 'GROUP' funkcije", +"Tabela '%-.64s' koristi ekstenziju koje ne postoji u ovoj verziji MySQL-a", +"Tabela mora imati najmanje jednu kolonu", +"Tabela '%-.64s' je popunjena do kraja", +"Nepoznati karakter-set: '%-.64s'", +"Previše tabela. MySQL može upotrebiti maksimum %d tabela pri 'JOIN' operaciji", +"Previše kolona", +"Prevelik slog. Maksimalna velièina sloga, ne raèunajuæi BLOB polja, je %d. Trebali bi da promenite tip nekih polja u BLOB", +"Prepisivanje thread stack-a: Upotrebljeno: %ld od %ld stack memorije. Upotrebite 'mysqld -O thread_stack=#' da navedete veæi stack ako je potrebno", +"Unakrsna zavisnost pronaðena u komandi 'OUTER JOIN'. Istražite vaše 'ON' uslove", +"Kolona '%-.64s' je upotrebljena kao 'UNIQUE' ili 'INDEX' ali nije definisana kao 'NOT NULL'", +"Ne mogu da uèitam funkciju '%-.64s'", +"Ne mogu da inicijalizujem funkciju '%-.64s'; %-.80s", +"Ne postoje dozvoljene putanje do share-ovane biblioteke", +"Funkcija '%-.64s' veæ postoji", +"Ne mogu da otvorim share-ovanu biblioteku '%-.64s' (errno: %d %-.64s)", +"Ne mogu da pronadjem funkciju '%-.64s' u biblioteci", +"Funkcija '%-.64s' nije definisana", +"Host '%-.64s' je blokiran zbog previše grešaka u konekciji. Možete ga odblokirati pomoæu komande 'mysqladmin flush-hosts'", +"Host-u '%-.64s' nije dozvoljeno da se konektuje na ovaj MySQL server", +"Vi koristite MySQL kao anonimni korisnik a anonimnim korisnicima nije dozvoljeno da menjaju lozinke", +"Morate imati privilegije da možete da update-ujete odreðene tabele ako želite da menjate lozinke za druge korisnike", +"Ne mogu da pronaðem odgovarajuæi slog u 'user' tabeli", +"Odgovarajuæih slogova: %ld Promenjeno: %ld Upozorenja: %ld", +"Ne mogu da kreiram novi thread (errno %d). Ako imate još slobodne memorije, trebali biste da pogledate u priruèniku da li je ovo specifièna greška vašeg operativnog sistema", +"Broj kolona ne odgovara broju vrednosti u slogu %ld", +"Ne mogu da ponovo otvorim tabelu '%-.64s'", +"Pogrešna upotreba vrednosti NULL", +"Funkcija regexp je vratila grešku '%-.64s'", +"Upotreba agregatnih funkcija (MIN(),MAX(),COUNT()...) bez 'GROUP' kolona je pogrešna ako ne postoji 'GROUP BY' iskaz", +"Ne postoji odobrenje za pristup korisniku '%-.32s' na host-u '%-.64s'", +"%-.16s komanda zabranjena za korisnika '%-.32s@%-.64s' za tabelu '%-.64s'", +"%-.16s komanda zabranjena za korisnika '%-.32s@%-.64s' za kolonu '%-.64s' iz tabele '%-.64s'", +"Pogrešna 'GRANT' odnosno 'REVOKE' komanda. Molim Vas pogledajte u priruèniku koje vrednosti mogu biti upotrebljene.", +"Argument 'host' ili 'korisnik' prosleðen komandi 'GRANT' je predugaèak", +"Tabela '%-.64s.%-.64s' ne postoji", +"Ne postoji odobrenje za pristup korisniku '%-.32s' na host-u '%-.64s' tabeli '%-.64s'", +"Upotrebljena komanda nije dozvoljena sa ovom verzijom MySQL servera", +"Imate grešku u vašoj SQL sintaksi", +"Prolongirani 'INSERT' thread nije mogao da dobije traženo zakljuèavanje tabele '%-.64s'", +"Previše prolongiranih thread-ova je u upotrebi", +"Prekinuta konekcija broj %ld ka bazi: '%-.64s' korisnik je bio: '%-.32s' (%-.64s)", +"Primio sam mrežni paket veæi od definisane vrednosti 'max_allowed_packet'", +"Greška pri èitanju podataka sa pipe-a", +"Greška pri izvršavanju funkcije fcntl()", +"Primio sam mrežne pakete van reda", +"Ne mogu da dekompresujem mrežne pakete", +"Greška pri primanju mrežnih paketa", +"Vremenski limit za èitanje mrežnih paketa je istekao", +"Greška pri slanju mrežnih paketa", +"Vremenski limit za slanje mrežnih paketa je istekao", +"Rezultujuèi string je duži nego što to dozvoljava parametar servera 'max_allowed_packet'", +"Iskorišteni tip tabele ne podržava kolone tipa 'BLOB' odnosno 'TEXT'", +"Iskorišteni tip tabele ne podržava kolone tipa 'AUTO_INCREMENT'", +"Komanda 'INSERT DELAYED' ne može biti iskorištena u tabeli '%-.64s', zbog toga što je zakljuèana komandom 'LOCK TABLES'", +"Pogrešno ime kolone '%-.100s'", +"Handler tabele ne može da indeksira kolonu '%-.64s'", +"Tabele iskorištene u 'MERGE' tabeli nisu definisane na isti naèin", +"Zbog provere jedinstvenosti ne mogu da upišem podatke u tabelu '%-.64s'", +"BLOB kolona '%-.64s' je upotrebljena u specifikaciji kljuèa bez navoðenja dužine kljuèa", +"Svi delovi primarnog kljuèa moraju biti razlièiti od NULL; Ako Vam ipak treba NULL vrednost u kljuèu, upotrebite 'UNIQUE'", +"Rezultat je saèinjen od više slogova", +"Ovaj tip tabele zahteva da imate definisan primarni kljuè", +"Ova verzija MySQL servera nije kompajlirana sa podrškom za RAID ureðaje", +"Vi koristite safe update mod servera, a probali ste da promenite podatke bez 'WHERE' komande koja koristi kolonu kljuèa", +"Kljuè '%-.64s' ne postoji u tabeli '%-.64s'", +"Ne mogu da otvorim tabelu", +"Handler za ovu tabelu ne dozvoljava 'check' odnosno 'repair' komande", +"Nije Vam dozvoljeno da izvršite ovu komandu u transakciji", +"Greška %d za vreme izvršavanja komande 'COMMIT'", +"Greška %d za vreme izvršavanja komande 'ROLLBACK'", +"Greška %d za vreme izvršavanja komande 'FLUSH_LOGS'", +"Greška %d za vreme izvršavanja komande 'CHECKPOINT'", +"Prekinuta konekcija broj %ld ka bazi: '%-.64s' korisnik je bio: '%-.32s' a host: `%-.64s' (%-.64s)", +"Handler tabele ne podržava binarni dump tabele", +"Binarni log file zatvoren, ne mogu da izvršim komandu 'RESET MASTER'", +"Izgradnja indeksa dump-ovane tabele '%-.64s' nije uspela", +"Greška iz glavnog servera '%-.64s' u klasteru", +"Greška u primanju mrežnih paketa sa glavnog servera u klasteru", +"Greška u slanju mrežnih paketa na glavni server u klasteru", +"Ne mogu da pronaðem 'FULLTEXT' indeks koli odgovara listi kolona", +"Ne mogu da izvršim datu komandu zbog toga što su tabele zakljuèane ili je transakcija u toku", +"Nepoznata sistemska promenljiva '%-.64'", +"Tabela '%-.64s' je markirana kao ošteæena i trebala bi biti popravljena", +"Tabela '%-.64s' je markirana kao ošteæena, a zadnja (automatska?) popravka je bila neuspela", +"Upozorenje: Neke izmenjene tabele ne podržavaju komandu 'ROLLBACK'", +"Transakcija sa više stavki zahtevala je više od 'max_binlog_cache_size' bajtova skladišnog prostora. Uveæajte ovu promenljivu servera i pokušajte ponovo', +"Ova operacija ne može biti izvršena dok je aktivan podreðeni server. Zadajte prvo komandu 'SLAVE STOP' da zaustavite podreðeni server.", +"Ova operacija zahteva da je aktivan podreðeni server. Konfigurišite prvo podreðeni server i onda izvršite komandu 'SLAVE START'", +"Server nije konfigurisan kao podreðeni server, ispravite konfiguracioni file ili na njemu izvršite komandu 'CHANGE MASTER TO'", +"Nisam mogao da inicijalizujem informacionu strukturu glavnog servera, proverite da li imam privilegije potrebne za pristup file-u 'master.info'", +"Nisam mogao da startujem thread za podreðeni server, proverite sistemske resurse", +"Korisnik %-.64s veæ ima više aktivnih konekcija nego što je to odreðeno 'max_user_connections' promenljivom", +"Možete upotrebiti samo konstantan iskaz sa komandom 'SET'", +"Vremenski limit za zakljuèavanje tabele je istekao; Probajte da ponovo startujete transakciju", +"Broj totalnih zakljuèavanja tabele premašuje velièinu tabele zakljuèavanja", +"Zakljuèavanja izmena ne mogu biti realizovana sve dok traje 'READ UNCOMMITTED' transakcija", +"Komanda 'DROP DATABASE' nije dozvoljena dok thread globalno zakljuèava èitanje podataka", +"Komanda 'CREATE DATABASE' nije dozvoljena dok thread globalno zakljuèava èitanje podataka", +"Pogrešni argumenti prosleðeni na %s", +"Korisniku %-.32s@%-.64s nije dozvoljeno da kreira nove korisnike", +"Pogrešna definicija tabele; Sve 'MERGE' tabele moraju biti u istoj bazi podataka", +"Unakrsno zakljuèavanje pronaðeno kada sam pokušao da dobijem pravo na zakljuèavanje; Probajte da restartujete transakciju", +"Upotrebljeni tip tabele ne podržava 'FULLTEXT' indekse", +"Ne mogu da dodam proveru spoljnog kljuèa", +"Ne mogu da dodam slog: provera spoljnog kljuèa je neuspela", +"Ne mogu da izbrišem roditeljski slog: provera spoljnog kljuèa je neuspela", +"Greška pri povezivanju sa glavnim serverom u klasteru: %-.128s", +"Greška pri izvršavanju upita na glavnom serveru u klasteru: %-.128s", +"Greška pri izvršavanju komande %s: %-.128s", +"Pogrešna upotreba %s i %s", +"Upotrebljene 'SELECT' komande adresiraju razlièit broj kolona", +"Ne mogu da izvršim upit zbog toga što imate zakljuèavanja èitanja podataka u konfliktu", +"Mešanje tabela koje podržavaju transakcije i onih koje ne podržavaju transakcije je iskljuèeno", +"Opcija '%s' je upotrebljena dva puta u istom iskazu", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", -- cgit v1.2.1 From 492611f16575bd4f05a7ccd844fa27742ac1f0c5 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 May 2002 18:24:42 +0500 Subject: Added charset information --- sql/share/serbian/errmsg.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 051924f799f..105860f0e4b 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -3,7 +3,9 @@ /* Serbian Translation, version 1.0: Copyright 2002 Vladimir Kraljevic, vladimir_kraljevic@yahoo.com - This file is public domain and comes with NO WARRANTY of any kind */ + This file is public domain and comes with NO WARRANTY of any kind. + Charset: cp1250 +*/ "hashchk", "isamchk", -- cgit v1.2.1 From 3a6483fe4bfc53293b4b7e03f6fda7515bcf9b7f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 May 2002 20:53:09 +0300 Subject: new error messages in new translation --- sql/share/serbian/errmsg.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sql') diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 105860f0e4b..8e3b6e2a318 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -234,3 +234,5 @@ "Mešanje tabela koje podržavaju transakcije i onih koje ne podržavaju transakcije je iskljuèeno", "Opcija '%s' je upotrebljena dva puta u istom iskazu", "User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"Subselect return more than 1 field", +"Subselect return more than 1 record", -- cgit v1.2.1 From b043f06666c278a4277e7d35b1bff418d45708c2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 May 2002 20:58:38 +0500 Subject: Now several character sets can live in the same table, However some hacks were used while waiting for new FRM file sql/field.h: Added function to set Field charset sql/filesort.cc: Temporarily workaround, It seems charset should be passed in argument sql/ha_heap.cc: Set correct key charset from Field information sql/table.cc: Dirty hack to distinguish columns charsets while waiting for Monty to rewrite FRM file sql/table.h: New field: table default character set --- sql/field.h | 1 + sql/filesort.cc | 10 +++++++++- sql/ha_heap.cc | 2 +- sql/table.cc | 21 +++++++++++++++++++++ sql/table.h | 1 + 5 files changed, 33 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/field.h b/sql/field.h index baedf9e78e7..91bb39dd338 100644 --- a/sql/field.h +++ b/sql/field.h @@ -252,6 +252,7 @@ public: void make_field(Send_field *); uint size_of() const { return sizeof(*this); } inline CHARSET_INFO *charset() const { return field_charset; } + inline void set_charset(CHARSET_INFO *charset) { field_charset=charset; } inline int cmp_image(char *buff,uint length) { if (binary()) diff --git a/sql/filesort.cc b/sql/filesort.cc index 3bde4eeae14..c087e65172e 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -77,10 +77,18 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length, SORTPARAM param; DBUG_ENTER("filesort"); DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length,special);); + CHARSET_INFO *charset=table->table_charset; + uint i; #ifdef SKIP_DBUG_IN_FILESORT DBUG_PUSH(""); /* No DBUG here */ #endif + // BAR TODO: this is not absolutely correct, but OK for now + for(i=0;ifields;i++) + if (!table->field[i]->binary()) + charset=((Field_str*)(table->field[i]))->charset(); + // /BAR TODO + outfile= table->io_cache; my_b_clear(&tempfile); my_b_clear(&buffpek_pointers); @@ -129,7 +137,7 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length, records=param.max_rows; /* purecov: inspected */ #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info) && + if (use_strcoll(charset) && !(param.tmp_buffer=my_malloc(param.sort_length,MYF(MY_WME)))) goto err; #endif diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 43485a97fe3..e18bc877540 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -85,7 +85,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) seg->start= (uint) key_part->offset; seg->length= (uint) key_part->length; seg->flag = 0; - seg->charset= default_charset_info; + seg->charset= field->binary() ? NULL : ((Field_str*)field)->charset(); if (field->null_ptr) { seg->null_bit= field->null_bit; diff --git a/sql/table.cc b/sql/table.cc index 3c217ced03c..eb5f5ecbc9a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -341,6 +341,15 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, (hash_get_key) get_field_name,0, HASH_CASE_INSENSITIVE); +// BAR: dirty hack while waiting for new FRM +// BAR: take a charset information from table name +{ + const char* csname=strstr(alias,"_cs_"); + if(!csname || + !(outparam->table_charset=get_charset_by_name(csname+4,MYF(MY_WME)))) + outparam->table_charset=default_charset_info; +} + for (i=0 ; i < outparam->fields; i++, strpos+= 11, field_ptr++) { uint pack_flag= uint2korr(strpos+6); @@ -357,6 +366,18 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, (TYPELIB*) 0), outparam->fieldnames.type_names[i], outparam); + if (!reg_field->binary()) + { + // BAR: dirty hack while waiting for new FRM + // BAR: take a charset information from field name + + Field_str* str_field=(Field_str*)reg_field; + const char* csname=strstr(str_field->field_name,"_cs_"); + CHARSET_INFO *fcs; + if (!csname || (!(fcs=get_charset_by_name(csname+4,MYF(MY_WME))))) + fcs=outparam->table_charset; + str_field->set_charset(fcs); + } if (!(reg_field->flags & NOT_NULL_FLAG)) { if ((null_bit<<=1) == 256) diff --git a/sql/table.h b/sql/table.h index 59cb28038bf..183e1b2a38f 100644 --- a/sql/table.h +++ b/sql/table.h @@ -104,6 +104,7 @@ struct st_table { *rowid_field; Field_timestamp *timestamp_field; my_string comment; /* Comment about table */ + CHARSET_INFO *table_charset; /* Default charset of string fields */ REGINFO reginfo; /* field connections */ MEM_ROOT mem_root; GRANT_INFO grant; -- cgit v1.2.1 From 8bee96ab0ad02e45bb4652f6878173d030642051 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 May 2002 16:29:52 +0500 Subject: Now string values are created and filled with charset field SELECT func(charset2) FROM t ORDER BY 1 works in correct charset --- sql/field.cc | 121 +++++++++++++++++++++++++++------------------------ sql/field.h | 84 +++++++++++++++++------------------ sql/field_conv.cc | 16 +++---- sql/filesort.cc | 5 +-- sql/handler.cc | 2 +- sql/item.cc | 31 +++++++------ sql/item.h | 16 +++---- sql/item_cmpfunc.cc | 12 ++--- sql/item_cmpfunc.h | 6 +-- sql/item_create.cc | 10 +++-- sql/item_func.cc | 16 +++---- sql/item_strfunc.cc | 20 ++++----- sql/item_strfunc.h | 2 +- sql/item_sum.cc | 6 +-- sql/item_timefunc.cc | 32 +++++++++++--- sql/item_timefunc.h | 4 +- sql/log_event.cc | 32 +++++++------- sql/net_pkg.cc | 2 +- sql/opt_range.cc | 4 +- sql/sql_acl.cc | 102 +++++++++++++++++++++---------------------- sql/sql_analyse.cc | 17 ++++---- sql/sql_analyse.h | 5 ++- sql/sql_base.cc | 3 +- sql/sql_class.cc | 10 +++-- sql/sql_load.cc | 4 +- sql/sql_select.cc | 38 ++++++++-------- sql/sql_select.h | 2 +- sql/sql_show.cc | 18 ++++---- sql/sql_string.cc | 1 + sql/sql_string.h | 23 +++++----- sql/sql_table.cc | 2 +- sql/sql_test.cc | 5 ++- sql/sql_udf.cc | 4 +- sql/sql_update.cc | 5 ++- sql/sql_yacc.yy | 22 +++++----- sql/table.cc | 2 +- sql/unireg.cc | 7 +-- 37 files changed, 366 insertions(+), 325 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index bd4b8e9f29d..75cbedbb71b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -257,7 +257,7 @@ bool Field::send(THD *thd, String *packet) if (is_null()) return net_store_null(packet); char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),default_charset_info); val_str(&tmp,&tmp); CONVERT *convert; if ((convert=thd->convert_set)) @@ -320,7 +320,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy) bool Field::get_date(TIME *ltime,bool fuzzydate) { char buff[40]; - String tmp(buff,sizeof(buff)),tmp2,*res; + String tmp(buff,sizeof(buff),default_charset_info),tmp2,*res; if (!(res=val_str(&tmp,&tmp2)) || str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE) return 1; @@ -330,7 +330,7 @@ bool Field::get_date(TIME *ltime,bool fuzzydate) bool Field::get_time(TIME *ltime) { char buff[40]; - String tmp(buff,sizeof(buff)),tmp2,*res; + String tmp(buff,sizeof(buff),default_charset_info),tmp2,*res; if (!(res=val_str(&tmp,&tmp2)) || str_to_time(res->ptr(),res->length(),ltime)) return 1; @@ -344,22 +344,22 @@ void Field::store_time(TIME *ltime,timestamp_type type) char buff[25]; switch (type) { case TIMESTAMP_NONE: - store("",0); // Probably an error + store("",0,default_charset_info); // Probably an error break; case TIMESTAMP_DATE: sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day); - store(buff,10); + store(buff,10,default_charset_info); break; case TIMESTAMP_FULL: sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d", ltime->year,ltime->month,ltime->day, ltime->hour,ltime->minute,ltime->second); - store(buff,19); + store(buff,19,default_charset_info); break; case TIMESTAMP_TIME: sprintf(buff, "%02d:%02d:%02d", ltime->hour,ltime->minute,ltime->second); - store(buff,(uint) strlen(buff)); + store(buff,(uint) strlen(buff),default_charset_info); break; } } @@ -378,7 +378,7 @@ bool Field::optimize_range(uint idx) void Field_decimal::reset(void) { - Field_decimal::store("0",1); + Field_decimal::store("0",1,default_charset_info); } void Field_decimal::overflow(bool negative) @@ -397,7 +397,7 @@ void Field_decimal::overflow(bool negative) } -void Field_decimal::store(const char *from,uint len) +void Field_decimal::store(const char *from,uint len,CHARSET_INFO *cs) { reg3 int i; uint tmp_dec; @@ -589,7 +589,7 @@ String *Field_decimal::val_str(String *val_buffer __attribute__((unused)), if (field_length < tmp_length) // Error in data val_ptr->length(0); else - val_ptr->set((const char*) str,field_length-tmp_length); + val_ptr->set((const char*) str,field_length-tmp_length,default_charset_info); return val_ptr; } @@ -672,9 +672,9 @@ void Field_decimal::sql_type(String &res) const ** tiny int ****************************************************************************/ -void Field_tiny::store(const char *from,uint len) +void Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); long tmp= strtol(tmp_str.c_ptr(),NULL,10); if (unsigned_flag) @@ -843,9 +843,9 @@ void Field_tiny::sql_type(String &res) const // Note: Sometimes this should be fixed to use one strtol() to use // len and check for garbage after number. -void Field_short::store(const char *from,uint len) +void Field_short::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); long tmp= strtol(tmp_str.c_ptr(),NULL,10); if (unsigned_flag) { @@ -1083,9 +1083,9 @@ void Field_short::sql_type(String &res) const // Note: Sometimes this should be fixed to use one strtol() to use // len and check for garbage after number. -void Field_medium::store(const char *from,uint len) +void Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); long tmp= strtol(tmp_str.c_ptr(),NULL,10); if (unsigned_flag) @@ -1268,14 +1268,14 @@ void Field_medium::sql_type(String &res) const // Note: Sometimes this should be fixed to use one strtol() to use // len and check for garbage after number. -void Field_long::store(const char *from,uint len) +void Field_long::store(const char *from,uint len,CHARSET_INFO *cs) { while (len && my_isspace(system_charset_info,*from)) { len--; from++; } long tmp; - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); errno=0; if (unsigned_flag) { @@ -1496,14 +1496,14 @@ void Field_long::sql_type(String &res) const ** longlong int ****************************************************************************/ -void Field_longlong::store(const char *from,uint len) +void Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) { while (len && my_isspace(system_charset_info,*from)) { // For easy error check len--; from++; } longlong tmp; - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); errno=0; if (unsigned_flag) { @@ -1703,9 +1703,9 @@ void Field_longlong::sql_type(String &res) const ** single precision float ****************************************************************************/ -void Field_float::store(const char *from,uint len) +void Field_float::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); errno=0; Field_float::store(atof(tmp_str.c_ptr())); if (errno || current_thd->count_cuted_fields && !test_if_real(from,len)) @@ -1953,9 +1953,9 @@ void Field_float::sql_type(String &res) const ** double precision floating point numbers ****************************************************************************/ -void Field_double::store(const char *from,uint len) +void Field_double::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); errno=0; double j= atof(tmp_str.c_ptr()); if (errno || current_thd->count_cuted_fields && !test_if_real(from,len)) @@ -2209,7 +2209,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, } -void Field_timestamp::store(const char *from,uint len) +void Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { long tmp=(long) str_to_timestamp(from,len); #ifdef WORDS_BIGENDIAN @@ -2548,7 +2548,7 @@ void Field_timestamp::set_time() ** Stored as a 3 byte unsigned int ****************************************************************************/ -void Field_time::store(const char *from,uint len) +void Field_time::store(const char *from,uint len,CHARSET_INFO *cs) { TIME ltime; long tmp; @@ -2688,7 +2688,7 @@ void Field_time::sort_string(char *to,uint length __attribute__((unused))) void Field_time::sql_type(String &res) const { - res.set("time",4); + res.set("time",4,default_charset_info); } /**************************************************************************** @@ -2697,9 +2697,9 @@ void Field_time::sql_type(String &res) const ** Can handle 2 byte or 4 byte years! ****************************************************************************/ -void Field_year::store(const char *from, uint len) +void Field_year::store(const char *from, uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); long nr= strtol(tmp_str.c_ptr(),NULL,10); if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) @@ -2786,7 +2786,7 @@ void Field_year::sql_type(String &res) const ** Stored as a 4 byte unsigned int ****************************************************************************/ -void Field_date::store(const char *from, uint len) +void Field_date::store(const char *from, uint len,CHARSET_INFO *cs) { TIME l_time; uint32 tmp; @@ -2934,7 +2934,7 @@ void Field_date::sort_string(char *to,uint length __attribute__((unused))) void Field_date::sql_type(String &res) const { - res.set("date",4); + res.set("date",4,default_charset_info); } /**************************************************************************** @@ -2943,7 +2943,7 @@ void Field_date::sql_type(String &res) const ** In number context: YYYYMMDD ****************************************************************************/ -void Field_newdate::store(const char *from,uint len) +void Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) { TIME l_time; long tmp; @@ -3085,7 +3085,7 @@ void Field_newdate::sort_string(char *to,uint length __attribute__((unused))) void Field_newdate::sql_type(String &res) const { - res.set("date",4); + res.set("date",4,default_charset_info); } @@ -3096,7 +3096,7 @@ void Field_newdate::sql_type(String &res) const ** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int. ****************************************************************************/ -void Field_datetime::store(const char *from,uint len) +void Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) { longlong tmp=str_to_datetime(from,len,1); #ifdef WORDS_BIGENDIAN @@ -3302,7 +3302,7 @@ void Field_datetime::sort_string(char *to,uint length __attribute__((unused))) void Field_datetime::sql_type(String &res) const { - res.set("datetime",8); + res.set("datetime",8,default_charset_info); } /**************************************************************************** @@ -3312,8 +3312,9 @@ void Field_datetime::sql_type(String &res) const /* Copy a string and fill with space */ -void Field_string::store(const char *from,uint length) +void Field_string::store(const char *from,uint length,CHARSET_INFO *cs) { + field_charset=cs; #ifdef USE_TIS620 if(!binary_flag) { ThNormalize((uchar *)ptr, field_length, (uchar *)from, length); @@ -3354,7 +3355,7 @@ void Field_string::store(double nr) int width=min(field_length,DBL_DIG+5); sprintf(buff,"%-*.*g",width,max(width-5,0),nr); end=strcend(buff,' '); - Field_string::store(buff,(uint) (end - buff)); + Field_string::store(buff,(uint) (end - buff), default_charset_info); } @@ -3362,7 +3363,7 @@ void Field_string::store(longlong nr) { char buff[22]; char *end=longlong10_to_str(nr,buff,-10); - Field_string::store(buff,(uint) (end-buff)); + Field_string::store(buff,(uint) (end-buff), default_charset_info); } @@ -3397,7 +3398,7 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)), #endif while (end > ptr && end[-1] == ' ') end--; - val_ptr->set((const char*) ptr,(uint) (end - ptr)); + val_ptr->set((const char*) ptr,(uint) (end - ptr),field_charset); return val_ptr; } @@ -3516,8 +3517,9 @@ uint Field_string::max_packed_col_length(uint max_length) ****************************************************************************/ -void Field_varstring::store(const char *from,uint length) +void Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) { + field_charset=cs; #ifdef USE_TIS620 if(!binary_flag) { @@ -3545,7 +3547,7 @@ void Field_varstring::store(double nr) int width=min(field_length,DBL_DIG+5); sprintf(buff,"%-*.*g",width,max(width-5,0),nr); end=strcend(buff,' '); - Field_varstring::store(buff,(uint) (end - buff)); + Field_varstring::store(buff,(uint) (end - buff), default_charset_info); } @@ -3553,7 +3555,7 @@ void Field_varstring::store(longlong nr) { char buff[22]; char *end=longlong10_to_str(nr,buff,-10); - Field_varstring::store(buff,(uint) (end-buff)); + Field_varstring::store(buff,(uint) (end-buff), default_charset_info); } @@ -3585,7 +3587,7 @@ String *Field_varstring::val_str(String *val_buffer __attribute__((unused)), String *val_ptr) { uint length=uint2korr(ptr); - val_ptr->set((const char*) ptr+2,length); + val_ptr->set((const char*) ptr+2,length,field_charset); return val_ptr; } @@ -3741,7 +3743,7 @@ Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, bool binary_arg) :Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, - table_arg), + table_arg, default_charset_info), packlength(blob_pack_length),binary_flag(binary_arg), geom_flag(true) { flags|= BLOB_FLAG; @@ -3833,8 +3835,9 @@ uint32 Field_blob::get_length(const char *pos) } -void Field_blob::store(const char *from,uint len) +void Field_blob::store(const char *from,uint len,CHARSET_INFO *cs) { + field_charset=cs; if (!len) { bzero(ptr,Field_blob::pack_length()); @@ -3872,14 +3875,14 @@ void Field_blob::store(const char *from,uint len) void Field_blob::store(double nr) { value.set(nr); - Field_blob::store(value.ptr(),(uint) value.length()); + Field_blob::store(value.ptr(),(uint) value.length(), default_charset_info); } void Field_blob::store(longlong nr) { value.set(nr); - Field_blob::store(value.ptr(), (uint) value.length()); + Field_blob::store(value.ptr(), (uint) value.length(), default_charset_info); } @@ -3922,9 +3925,9 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)), char *blob; memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) - val_ptr->set("",0); // A bit safer than ->length(0) + val_ptr->set("",0,default_charset_info); // A bit safer than ->length(0) else - val_ptr->set((const char*) blob,get_length(ptr)); + val_ptr->set((const char*) blob,get_length(ptr),default_charset_info); return val_ptr; } @@ -4026,7 +4029,7 @@ void Field_blob::get_key_image(char *buff,uint length, imagetype type) void Field_blob::set_key_image(char *buff,uint length) { length=uint2korr(buff); - Field_blob::store(buff+2,length); + Field_blob::store(buff+2,length, default_charset_info); } void Field_geom::get_key_image(char *buff,uint length, imagetype type) @@ -4121,7 +4124,7 @@ void Field_blob::sql_type(String &res) const case 3: str="medium"; break; case 4: str="long"; break; } - res.set(str,(uint) strlen(str)); + res.set(str,(uint) strlen(str),default_charset_info); res.append(binary_flag ? "blob" : "text"); } @@ -4342,7 +4345,7 @@ uint find_enum(TYPELIB *lib,const char *x, uint length) ** (if there isn't a empty value in the enum) */ -void Field_enum::store(const char *from,uint length) +void Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) { uint tmp=find_enum(typelib,from,length); if (!tmp) @@ -4448,7 +4451,8 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)), val_ptr->length(0); else val_ptr->set((const char*) typelib->type_names[tmp-1], - (uint) strlen(typelib->type_names[tmp-1])); + (uint) strlen(typelib->type_names[tmp-1]), + default_charset_info); return val_ptr; } @@ -4534,7 +4538,7 @@ ulonglong find_set(TYPELIB *lib,const char *x,uint length) } -void Field_set::store(const char *from,uint length) +void Field_set::store(const char *from,uint length,CHARSET_INFO *cs) { ulonglong tmp=find_set(typelib,from,length); if (!tmp && length && length < 22) @@ -4585,7 +4589,8 @@ String *Field_set::val_str(String *val_buffer, if (val_buffer->length()) val_buffer->append(field_separator); String str(typelib->type_names[bitnr], - (uint) strlen(typelib->type_names[bitnr])); + (uint) strlen(typelib->type_names[bitnr]), + default_charset_info); val_buffer->append(str); } tmp>>=1; @@ -4723,7 +4728,7 @@ Field *make_field(char *ptr, uint32 field_length, if (!f_is_packed(pack_flag)) return new Field_string(ptr,field_length,null_pos,null_bit, unireg_check, field_name, table, - f_is_binary(pack_flag) != 0); + f_is_binary(pack_flag) != 0, default_charset_info); uint pack_length=calc_pack_length((enum_field_types) f_packtype(pack_flag), @@ -4853,7 +4858,7 @@ create_field::create_field(Field *old_field,Field *orig_field) orig_field) { char buff[MAX_FIELD_WIDTH],*pos; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),default_charset_info); /* Get the value from record[2] (the default value row) */ my_ptrdiff_t diff= (my_ptrdiff_t) (orig_field->table->rec_buff_length*2); @@ -4865,7 +4870,7 @@ create_field::create_field(Field *old_field,Field *orig_field) { pos= (char*) sql_memdup(tmp.ptr(),tmp.length()+1); pos[tmp.length()]=0; - def=new Item_string(pos,tmp.length()); + def=new Item_string(pos,tmp.length(),default_charset_info); } } } diff --git a/sql/field.h b/sql/field.h index 91bb39dd338..cf7c2a50218 100644 --- a/sql/field.h +++ b/sql/field.h @@ -59,7 +59,7 @@ public: utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg); virtual ~Field() {} - virtual void store(const char *to,uint length)=0; + virtual void store(const char *to,uint length,CHARSET_INFO *cs)=0; virtual void store(double nr)=0; virtual void store(longlong nr)=0; virtual void store_time(TIME *ltime,timestamp_type t_type); @@ -242,10 +242,10 @@ public: Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg) + struct st_table *table_arg,CHARSET_INFO *charset) :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg) - { field_charset=default_charset_info; } + { field_charset=charset; } Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } friend class create_field; @@ -279,7 +279,7 @@ public: enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } void reset(void); - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); double val_real(void); @@ -308,7 +308,7 @@ public: enum_field_types type() const { return FIELD_TYPE_TINY;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=0; } @@ -337,7 +337,7 @@ public: enum_field_types type() const { return FIELD_TYPE_SHORT;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;} - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=0; } @@ -366,7 +366,7 @@ public: enum_field_types type() const { return FIELD_TYPE_INT24;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } @@ -400,7 +400,7 @@ public: enum_field_types type() const { return FIELD_TYPE_LONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } @@ -436,7 +436,7 @@ public: enum_field_types type() const { return FIELD_TYPE_LONGLONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } @@ -463,7 +463,7 @@ public: {} enum_field_types type() const { return FIELD_TYPE_FLOAT;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { bzero(ptr,sizeof(float)); } @@ -495,7 +495,7 @@ public: {} enum_field_types type() const { return FIELD_TYPE_DOUBLE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { bzero(ptr,sizeof(double)); } @@ -518,10 +518,10 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str(ptr_arg, len_arg, null, 1, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_NULL;} - void store(const char *to, uint length) { null[0]=1; } + void store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; } void store(double nr) { null[0]=1; } void store(longlong nr) { null[0]=1; } void reset(void) {} @@ -532,7 +532,7 @@ public: int cmp(const char *a, const char *b) { return 0;} void sort_string(char *buff, uint length) {} uint32 pack_length() const { return 0; } - void sql_type(String &str) const { str.set("null",4); } + void sql_type(String &str) const { str.set("null",4,default_charset_info); } uint size_of() const { return sizeof(*this); } }; @@ -545,7 +545,7 @@ public: enum Item_result result_type () const { return field_length == 8 || field_length == 14 ? INT_RESULT : STRING_RESULT; } enum_field_types type() const { return FIELD_TYPE_TIMESTAMP;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } @@ -585,7 +585,7 @@ public: unireg_check_arg, field_name_arg, table_arg, 1, 1) {} enum_field_types type() const { return FIELD_TYPE_YEAR;} - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); double val_real(void); @@ -601,16 +601,16 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} Field_date(bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str((char*) 0,10, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg) {} + NONE, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_DATE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } @@ -631,13 +631,13 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_DATE;} enum_field_types real_type() const { return FIELD_TYPE_NEWDATE; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; } enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void store_time(TIME *ltime,timestamp_type type); @@ -662,16 +662,16 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str(ptr_arg, 8, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} Field_time(bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str((char*) 0,8, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg) {} + NONE, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_TIME;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } @@ -694,18 +694,18 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} Field_datetime(bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str((char*) 0,19, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg) {} + NONE, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_DATETIME;} #ifdef HAVE_LONG_LONG enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; } #endif enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void store_time(TIME *ltime,timestamp_type type); @@ -730,18 +730,18 @@ public: Field_string(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg,bool binary_arg) + struct st_table *table_arg,bool binary_arg, CHARSET_INFO *cs) :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg), + unireg_check_arg, field_name_arg, table_arg,cs), binary_flag(binary_arg) { if (binary_arg) flags|=BINARY_FLAG; } Field_string(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, bool binary_arg) + struct st_table *table_arg, bool binary_arg, CHARSET_INFO *cs) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg), + NONE, field_name_arg, table_arg, cs), binary_flag(binary_arg) { if (binary_arg) @@ -759,7 +759,7 @@ public: bool zero_pack() const { return 0; } bool binary() const { return binary_flag; } void reset(void) { bfill(ptr,field_length,' '); } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); double val_real(void); @@ -785,18 +785,18 @@ public: Field_varstring(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg,bool binary_arg) + struct st_table *table_arg,bool binary_arg, CHARSET_INFO *cs) :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg), + unireg_check_arg, field_name_arg, table_arg, cs), binary_flag(binary_arg) { if (binary_arg) flags|=BINARY_FLAG; } Field_varstring(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, bool binary_arg) + struct st_table *table_arg, bool binary_arg, CHARSET_INFO *cs) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg), + NONE, field_name_arg, table_arg, cs), binary_flag(binary_arg) { if (binary_arg) @@ -811,7 +811,7 @@ public: void reset(void) { bzero(ptr,field_length+2); } uint32 pack_length() const { return (uint32) field_length+2; } uint32 key_length() const { return (uint32) field_length; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); double val_real(void); @@ -844,7 +844,7 @@ public: Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg, bool binary_arg) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg), + NONE, field_name_arg, table_arg, default_charset_info), packlength(3),binary_flag(binary_arg), geom_flag(true) { flags|= BLOB_FLAG; @@ -854,7 +854,7 @@ public: enum_field_types type() const { return FIELD_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary_flag ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); double val_real(void); @@ -951,7 +951,7 @@ public: struct st_table *table_arg,uint packlength_arg, TYPELIB *typelib_arg) :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg), + unireg_check_arg, field_name_arg, table_arg, default_charset_info), packlength(packlength_arg),typelib(typelib_arg) { flags|=ENUM_FLAG; @@ -959,7 +959,7 @@ public: enum_field_types type() const { return FIELD_TYPE_STRING; } enum Item_result cmp_type () const { return INT_RESULT; } enum ha_base_keytype key_type() const; - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset() { bzero(ptr,packlength); } @@ -994,7 +994,7 @@ public: { flags=(flags & ~ENUM_FLAG) | SET_FLAG; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr) { Field_set::store((longlong) nr); } void store(longlong nr); virtual bool zero_pack() const { return 1; } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 02be0365002..3b6de1383e2 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -228,7 +228,7 @@ static void do_conv_blob(Copy_field *copy) { copy->from_field->val_str(©->tmp,©->tmp); ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(), - copy->tmp.length()); + copy->tmp.length(),default_charset_info); } /* Save blob in copy->tmp for GROUP BY */ @@ -236,20 +236,20 @@ static void do_conv_blob(Copy_field *copy) static void do_save_blob(Copy_field *copy) { char buff[MAX_FIELD_WIDTH]; - String res(buff,sizeof(buff)); + String res(buff,sizeof(buff),default_charset_info); copy->from_field->val_str(&res,&res); copy->tmp.copy(res); ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(), - copy->tmp.length()); + copy->tmp.length(),default_charset_info); } static void do_field_string(Copy_field *copy) { char buff[MAX_FIELD_WIDTH]; - copy->tmp.set_quick(buff,sizeof(buff)); + copy->tmp.set_quick(buff,sizeof(buff),default_charset_info); copy->from_field->val_str(©->tmp,©->tmp); - copy->to_field->store(copy->tmp.c_ptr_quick(),copy->tmp.length()); + copy->to_field->store(copy->tmp.c_ptr_quick(),copy->tmp.length(),default_charset_info); } @@ -508,7 +508,7 @@ void field_conv(Field *to,Field *from) if (!blob->value.is_alloced() && from->real_type() != FIELD_TYPE_STRING) blob->value.copy(); - blob->store(blob->value.ptr(),blob->value.length()); + blob->store(blob->value.ptr(),blob->value.length(),default_charset_info); return; } if ((from->result_type() == STRING_RESULT && @@ -518,9 +518,9 @@ void field_conv(Field *to,Field *from) to->type() == FIELD_TYPE_DECIMAL) { char buff[MAX_FIELD_WIDTH]; - String result(buff,sizeof(buff)); + String result(buff,sizeof(buff),default_charset_info); from->val_str(&result,&result); - to->store(result.c_ptr_quick(),result.length()); + to->store(result.c_ptr_quick(),result.length(),default_charset_info); } else if (from->result_type() == REAL_RESULT) to->store(from->val_real()); diff --git a/sql/filesort.cc b/sql/filesort.cc index c087e65172e..ec49163f8a0 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -475,12 +475,10 @@ static void make_sortkey(register SORTPARAM *param, switch (sort_field->result_type) { case STRING_RESULT: { - CHARSET_INFO *cs=item->str_value.charset(); - if (item->maybe_null) *to++=1; /* All item->str() to use some extra byte for end null.. */ - String tmp((char*) to,sort_field->length+4); + String tmp((char*) to,sort_field->length+4,default_charset_info); String *res=item->val_str(&tmp); if (!res) { @@ -495,6 +493,7 @@ static void make_sortkey(register SORTPARAM *param, break; } length=res->length(); + CHARSET_INFO *cs=res->charset(); int diff=(int) (sort_field->length-length); if (diff < 0) { diff --git a/sql/handler.cc b/sql/handler.cc index 7947ae5a9f0..47c59be0166 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -665,7 +665,7 @@ void handler::print_error(int error, myf errflag) { /* Write the dupplicated key in the error message */ char key[MAX_KEY_LENGTH]; - String str(key,sizeof(key)); + String str(key,sizeof(key),default_charset_info); key_unpack(&str,table,(uint) key_nr); uint max_length=MYSQL_ERRMSG_SIZE-(uint) strlen(ER(ER_DUP_ENTRY)); if (str.length() >= max_length) diff --git a/sql/item.cc b/sql/item.cc index 84f4624a248..d5b9487eea6 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -89,7 +89,7 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const bool Item::get_date(TIME *ltime,bool fuzzydate) { char buff[40]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; if (!(res=val_str(&tmp)) || str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE) { @@ -107,7 +107,7 @@ bool Item::get_date(TIME *ltime,bool fuzzydate) bool Item::get_time(TIME *ltime) { char buff[40]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; if (!(res=val_str(&tmp)) || str_to_time(res->ptr(),res->length(),ltime)) { @@ -457,14 +457,15 @@ bool Item::save_in_field(Field *field) field->result_type() == STRING_RESULT) { String *result; + CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns - str_value.set_quick(buff,sizeof(buff)); + str_value.set_quick(buff,sizeof(buff),cs); result=val_str(&str_value); if (null_value) return set_field_to_null(field); field->set_notnull(); - field->store(result->ptr(),result->length()); - str_value.set_quick(0, 0); + field->store(result->ptr(),result->length(),cs); + str_value.set_quick(0, 0, cs); } else if (result_type() == REAL_RESULT) { @@ -488,11 +489,12 @@ bool Item::save_in_field(Field *field) bool Item_string::save_in_field(Field *field) { String *result; + CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); result=val_str(&str_value); if (null_value) return set_field_to_null(field); field->set_notnull(); - field->store(result->ptr(),result->length()); + field->store(result->ptr(),result->length(),cs); return 0; } @@ -529,14 +531,14 @@ inline uint char_val(char X) X-'a'+10); } -Item_varbinary::Item_varbinary(const char *str, uint str_length) +Item_varbinary::Item_varbinary(const char *str, uint str_length, CHARSET_INFO *cs) { name=(char*) str-2; // Lex makes this start with 0x max_length=(str_length+1)/2; char *ptr=(char*) sql_alloc(max_length+1); if (!ptr) return; - str_value.set(ptr,max_length); + str_value.set(ptr,max_length,cs); char *end=ptr+max_length; if (max_length*2 != str_length) *ptr++=char_val(*str++); // Not even, assume 0 prefix @@ -563,10 +565,11 @@ longlong Item_varbinary::val_int() bool Item_varbinary::save_in_field(Field *field) { + CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); field->set_notnull(); if (field->result_type() == STRING_RESULT) { - field->store(str_value.ptr(),str_value.length()); + field->store(str_value.ptr(),str_value.length(),cs); } else { @@ -590,7 +593,7 @@ bool Item::send(THD *thd, String *packet) { char buff[MAX_FIELD_WIDTH]; CONVERT *convert; - String s(buff,sizeof(buff)),*res; + String s(buff,sizeof(buff),packet->charset()),*res; if (!(res=val_str(&s))) return net_store_null(packet); if ((convert=thd->convert_set)) @@ -649,7 +652,7 @@ Item *resolve_const_item(Item *item,Item *comp_item) if (res_type == STRING_RESULT) { char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)),*result; + String tmp(buff,sizeof(buff),default_charset_info),*result; result=item->val_str(&tmp); if (item->null_value) { @@ -663,7 +666,7 @@ Item *resolve_const_item(Item *item,Item *comp_item) #ifdef DELETE_ITEMS delete item; #endif - return new Item_string(name,tmp_str,length); + return new Item_string(name,tmp_str,length,default_charset_info); } if (res_type == INT_RESULT) { @@ -704,8 +707,8 @@ bool field_is_equal_to_item(Field *field,Item *item) { char item_buff[MAX_FIELD_WIDTH]; char field_buff[MAX_FIELD_WIDTH]; - String item_tmp(item_buff,sizeof(item_buff)),*item_result; - String field_tmp(field_buff,sizeof(field_buff)); + String item_tmp(item_buff,sizeof(item_buff),default_charset_info),*item_result; + String field_tmp(field_buff,sizeof(field_buff),default_charset_info); item_result=item->val_str(&item_tmp); if (item->null_value) return 1; // This must be true diff --git a/sql/item.h b/sql/item.h index 97f2862bb8b..927e86398c2 100644 --- a/sql/item.h +++ b/sql/item.h @@ -241,16 +241,16 @@ public: class Item_string :public Item { public: - Item_string(const char *str,uint length) + Item_string(const char *str,uint length,CHARSET_INFO *cs) { - str_value.set(str,length); + str_value.set(str,length,cs); max_length=length; name=(char*) str_value.ptr(); decimals=NOT_FIXED_DEC; } - Item_string(const char *name_par,const char *str,uint length) + Item_string(const char *name_par,const char *str,uint length,CHARSET_INFO *cs) { - str_value.set(str,length); + str_value.set(str,length,cs); max_length=length; name=(char*) name_par; decimals=NOT_FIXED_DEC; @@ -265,7 +265,7 @@ public: enum Item_result result_type () const { return STRING_RESULT; } bool basic_const_item() const { return 1; } bool eq(const Item *item, bool binary_cmp) const; - Item *new_item() { return new Item_string(name,str_value.ptr(),max_length); } + Item *new_item() { return new Item_string(name,str_value.ptr(),max_length,default_charset_info); } String *const_string() { return &str_value; } inline void append(char *str,uint length) { str_value.append(str,length); } void print(String *str); @@ -276,7 +276,7 @@ public: class Item_datetime :public Item_string { public: - Item_datetime(const char *item_name): Item_string(item_name,"",0) + Item_datetime(const char *item_name): Item_string(item_name,"",0,default_charset_info) { max_length=19;} void make_field(Send_field *field); }; @@ -284,14 +284,14 @@ public: class Item_empty_string :public Item_string { public: - Item_empty_string(const char *header,uint length) :Item_string("",0) + Item_empty_string(const char *header,uint length) :Item_string("",0,default_charset_info) { name=(char*) header; max_length=length;} }; class Item_varbinary :public Item { public: - Item_varbinary(const char *str,uint str_length); + Item_varbinary(const char *str,uint str_length,CHARSET_INFO *cs); ~Item_varbinary() {} enum Type type() const { return VARBIN_ITEM; } double val() { return (double) Item_varbinary::val_int(); } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index c34440d92d4..072eaf51567 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -687,7 +687,7 @@ String *Item_func_case::val_str(String *str) longlong Item_func_case::val_int() { char buff[MAX_FIELD_WIDTH]; - String dummy_str(buff,sizeof(buff)); + String dummy_str(buff,sizeof(buff),default_charset_info); Item *item=find_item(&dummy_str); longlong res; @@ -704,7 +704,7 @@ longlong Item_func_case::val_int() double Item_func_case::val() { char buff[MAX_FIELD_WIDTH]; - String dummy_str(buff,sizeof(buff)); + String dummy_str(buff,sizeof(buff),default_charset_info); Item *item=find_item(&dummy_str); double res; @@ -876,7 +876,7 @@ int in_vector::find(Item *item) in_string::in_string(uint elements,qsort_cmp cmp_func) - :in_vector(elements,sizeof(String),cmp_func),tmp(buff,sizeof(buff)) + :in_vector(elements,sizeof(String),cmp_func),tmp(buff,sizeof(buff),default_charset_info) {} in_string::~in_string() @@ -1272,7 +1272,7 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) if (!regex_compiled && args[1]->const_item()) { char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),default_charset_info); String *res=args[1]->val_str(&tmp); if (args[1]->null_value) { // Will always return NULL @@ -1301,7 +1301,7 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) longlong Item_func_regex::val_int() { char buff[MAX_FIELD_WIDTH]; - String *res, tmp(buff,sizeof(buff)); + String *res, tmp(buff,sizeof(buff),default_charset_info); res=args[0]->val_str(&tmp); if (args[0]->null_value) @@ -1312,7 +1312,7 @@ longlong Item_func_regex::val_int() if (!regex_is_const) { char buff2[MAX_FIELD_WIDTH]; - String *res2, tmp2(buff2,sizeof(buff2)); + String *res2, tmp2(buff2,sizeof(buff2),default_charset_info); res2= args[1]->val_str(&tmp2); if (args[1]->null_value) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index b8f21f21008..350e369eaac 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -341,7 +341,7 @@ class cmp_item_sort_string :public cmp_item { char value_buff[80]; String value,*value_res; public: - cmp_item_sort_string() :value(value_buff,sizeof(value_buff)) {} + cmp_item_sort_string() :value(value_buff,sizeof(value_buff),default_charset_info) {} void store_value(Item *item) { value_res=item->val_str(&value); @@ -349,7 +349,7 @@ public: int cmp(Item *arg) { char buff[80]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; if (!(res=arg->val_str(&tmp))) return 1; /* Can't be right */ return sortcmp(value_res,res); @@ -362,7 +362,7 @@ public: int cmp(Item *arg) { char buff[80]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; if (!(res=arg->val_str(&tmp))) return 1; /* Can't be right */ return stringcmp(value_res,res); diff --git a/sql/item_create.cc b/sql/item_create.cc index 79d7fcfe230..9204d23b8c2 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -227,7 +227,7 @@ Item *create_func_lpad(Item* a, Item *b, Item *c) Item *create_func_ltrim(Item* a) { - return new Item_func_ltrim(a,new Item_string(" ",1)); + return new Item_func_ltrim(a,new Item_string(" ",1,default_charset_info)); } Item *create_func_md5(Item* a) @@ -309,7 +309,7 @@ Item *create_func_rpad(Item* a, Item *b, Item *c) Item *create_func_rtrim(Item* a) { - return new Item_func_rtrim(a,new Item_string(" ",1)); + return new Item_func_rtrim(a,new Item_string(" ",1,default_charset_info)); } Item *create_func_sec_to_time(Item* a) @@ -329,7 +329,7 @@ Item *create_func_sin(Item* a) Item *create_func_space(Item *a) { - return new Item_func_repeat(new Item_string(" ",1),a); + return new Item_func_repeat(new Item_string(" ",1,default_charset_info),a); } Item *create_func_soundex(Item* a) @@ -374,7 +374,9 @@ Item *create_func_ucase(Item* a) Item *create_func_version(void) { - return new Item_string(NullS,server_version, (uint) strlen(server_version)); + return new Item_string(NullS,server_version, + (uint) strlen(server_version), + default_charset_info); } Item *create_func_weekday(Item* a) diff --git a/sql/item_func.cc b/sql/item_func.cc index 9d4895788fc..057518fb5f2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1296,7 +1296,7 @@ String *udf_handler::val_str(String *str,String *save_str) str->length(res_length); return str; } - save_str->set(res, res_length); + save_str->set(res, res_length, default_charset_info); return save_str; } @@ -1438,7 +1438,7 @@ void item_user_lock_release(ULL *ull) THD *thd = current_thd; uint save_query_length; char buf[256]; - String tmp(buf,sizeof(buf)); + String tmp(buf,sizeof(buf), default_charset_info); tmp.length(0); tmp.append("DO RELEASE_LOCK(\""); tmp.append(ull->key,ull->key_length); @@ -1695,7 +1695,7 @@ longlong Item_func_set_last_insert_id::val_int() longlong Item_func_benchmark::val_int() { char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff), default_charset_info); THD *thd=current_thd; for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++) @@ -1832,7 +1832,7 @@ Item_func_set_user_var::update() break; case STRING_RESULT: char buffer[MAX_FIELD_WIDTH]; - String tmp(buffer,sizeof(buffer)); + String tmp(buffer,sizeof(buffer),default_charset_info); (void) val_str(&tmp); break; } @@ -2006,7 +2006,7 @@ longlong Item_func_inet_aton::val_int() char c = '.'; // we mark c to indicate invalid IP in case length is 0 char buff[36]; - String *s,tmp(buff,sizeof(buff)); + String *s,tmp(buff,sizeof(buff),default_charset_info); if (!(s = args[0]->val_str(&tmp))) // If null value goto err; null_value=0; @@ -2052,17 +2052,17 @@ void Item_func_match::init_search(bool no_order) } if (key == NO_SUCH_KEY) - concat=new Item_func_concat_ws (new Item_string(" ",1), fields); + concat=new Item_func_concat_ws (new Item_string(" ",1,default_charset_info), fields); String *ft_tmp=0; char tmp1[FT_QUERY_MAXLEN]; - String tmp2(tmp1,sizeof(tmp1)); + String tmp2(tmp1,sizeof(tmp1),default_charset_info); // MATCH ... AGAINST (NULL) is meaningless, but possible if (!(ft_tmp=key_item()->val_str(&tmp2))) { ft_tmp=&tmp2; - tmp2.set("",0); + tmp2.set("",0,default_charset_info); } ft_handler=table->file->ft_init_ext(mode, key, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9c791453fd8..e3436ac4641 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -35,7 +35,7 @@ #endif /* HAVE_OPENSSL */ #include "md5.h" -String empty_string(""); +String empty_string("",default_charset_info); uint nr_of_decimals(const char *str) { @@ -371,7 +371,7 @@ error: String *Item_func_concat_ws::val_str(String *str) { char tmp_str_buff[10]; - String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff)), + String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info), *sep_str, *res, *res2,*use_as_buff; uint i; @@ -989,7 +989,7 @@ String *Item_func_ltrim::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),res->charset()); String *remove_str=args[1]->val_str(&tmp); uint remove_length; LINT_INIT(remove_length); @@ -1027,7 +1027,7 @@ String *Item_func_rtrim::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),res->charset()); String *remove_str=args[1]->val_str(&tmp); uint remove_length; LINT_INIT(remove_length); @@ -1099,7 +1099,7 @@ String *Item_func_trim::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),res->charset()); String *remove_str=args[1]->val_str(&tmp); uint remove_length; LINT_INIT(remove_length); @@ -1154,7 +1154,7 @@ String *Item_func_password::val_str(String *str) if (res->length() == 0) return &empty_string; make_scrambled_password(tmp_value,res->c_ptr()); - str->set(tmp_value,16); + str->set(tmp_value,16,res->charset()); return str; } @@ -1188,7 +1188,7 @@ String *Item_func_encrypt::val_str(String *str) } pthread_mutex_lock(&LOCK_crypt); char *tmp=crypt(res->c_ptr(),salt_ptr); - str->set(tmp,(uint) strlen(tmp)); + str->set(tmp,(uint) strlen(tmp),res->charset()); str->copy(); pthread_mutex_unlock(&LOCK_crypt); return str; @@ -1240,7 +1240,7 @@ String *Item_func_database::val_str(String *str) if (!current_thd->db) str->length(0); else - str->set((const char*) current_thd->db,(uint) strlen(current_thd->db)); + str->set((const char*) current_thd->db,(uint) strlen(current_thd->db), default_charset_info); return str; } @@ -2035,7 +2035,7 @@ String* Item_func_export_set::val_str(String* str) } break; case 3: - sep_buf.set(",", 1); + sep_buf.set(",", 1, default_charset_info); sep = &sep_buf; } null_value=0; @@ -2154,7 +2154,7 @@ String *Item_func_geometry_type::val_str(String *str) if ((null_value=(args[0]->null_value || geom.create_from_wkb(wkt->ptr(),wkt->length())))) return 0; - str->copy(geom.get_class_info()->m_name); + str->copy(geom.get_class_info()->m_name,strlen(geom.get_class_info()->m_name)); return str; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 091289fd040..8627ecd0d73 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -38,7 +38,7 @@ public: Field *tmp_table_field(TABLE *t_arg) { if (!t_arg) return result_field; - return (max_length > 255) ? (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) : (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary); + return (max_length > 255) ? (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) : (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary, default_charset_info); } }; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 83bc2272515..2275ce4eeb6 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -513,7 +513,7 @@ void Item_sum_hybrid::reset_field() if (hybrid_type == STRING_RESULT) { char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; res=args[0]->val_str(&tmp); if (args[0]->null_value) @@ -524,7 +524,7 @@ void Item_sum_hybrid::reset_field() else { result_field->set_notnull(); - result_field->store(res->ptr(),res->length()); + result_field->store(res->ptr(),res->length(),tmp.charset()); } } else if (hybrid_type == INT_RESULT) @@ -694,7 +694,7 @@ Item_sum_hybrid::min_max_update_str_field(int offset) if (result_field->is_null() || (cmp_sign * (binary ? stringcmp(res_str,&tmp_value) : sortcmp(res_str,&tmp_value)) < 0)) - result_field->store(res_str->ptr(),res_str->length()); + result_field->store(res_str->ptr(),res_str->length(),res_str->charset()); else { // Use old value char *res=result_field->ptr; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 404d44d7122..9bbb9e4fe19 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -29,11 +29,31 @@ ** Todo: Move month and days to language files */ -static String month_names[] = { "January", "February", "March", "April", - "May", "June", "July", "August", - "September", "October", "November", "December" }; -static String day_names[] = { "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" ,"Sunday" }; +static String month_names[] = +{ + String("January", default_charset_info), + String("February", default_charset_info), + String("March", default_charset_info), + String("April", default_charset_info), + String("May", default_charset_info), + String("June", default_charset_info), + String("July", default_charset_info), + String("August", default_charset_info), + String("September", default_charset_info), + String("October", default_charset_info), + String("November", default_charset_info), + String("December", default_charset_info) +}; +static String day_names[] = +{ + String("Monday", default_charset_info), + String("Tuesday", default_charset_info), + String("Wednesday", default_charset_info), + String("Thursday", default_charset_info), + String("Friday", default_charset_info), + String("Saturday", default_charset_info), + String("Sunday", default_charset_info) +}; /* ** Get a array of positive numbers from a string object. @@ -376,7 +396,7 @@ String *Item_date::val_str(String *str) return (String*) 0; if (!value) // zero daynr { - str->copy("0000-00-00"); + str->copy("0000-00-00",10); return str; } if (str->alloc(11)) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index aa4140192ab..9ff2734f460 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -271,7 +271,7 @@ public: double val() { return (double) value; } longlong val_int() { return value; } String *val_str(String *str) - { str_value.set(buff,buff_length); return &str_value; } + { str_value.set(buff,buff_length,default_charset_info); return &str_value; } const char *func_name() const { return "curtime"; } void fix_length_and_dec(); void make_field(Send_field *tmp_field) @@ -313,7 +313,7 @@ public: longlong val_int() { return value; } bool save_in_field(Field *to); String *val_str(String *str) - { str_value.set(buff,buff_length); return &str_value; } + { str_value.set(buff,buff_length,default_charset_info); return &str_value; } const char *func_name() const { return "now"; } void fix_length_and_dec(); bool get_date(TIME *res,bool fuzzy_date); diff --git a/sql/log_event.cc b/sql/log_event.cc index fd04f8dbbaa..cd116f867c2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -213,7 +213,7 @@ void Log_event::pack_info(String* packet) void Query_log_event::pack_info(String* packet) { char buf[256]; - String tmp(buf, sizeof(buf)); + String tmp(buf, sizeof(buf), system_charset_info); tmp.length(0); if (db && db_len) { @@ -230,7 +230,7 @@ void Query_log_event::pack_info(String* packet) void Start_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; @@ -244,7 +244,7 @@ void Start_log_event::pack_info(String* packet) void Load_log_event::pack_info(String* packet) { char buf[256]; - String tmp(buf, sizeof(buf)); + String tmp(buf, sizeof(buf), system_charset_info); tmp.length(0); if(db && db_len) { @@ -320,7 +320,7 @@ void Load_log_event::pack_info(String* packet) void Rotate_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append(new_log_ident, ident_len); @@ -334,7 +334,7 @@ void Rotate_log_event::pack_info(String* packet) void Intvar_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append(get_var_type_name()); @@ -346,7 +346,7 @@ void Intvar_log_event::pack_info(String* packet) void Slave_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append("host="); @@ -1417,7 +1417,7 @@ void Create_file_log_event::print(FILE* file, bool short_form, void Create_file_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append("db="); @@ -1475,7 +1475,7 @@ void Append_block_log_event::print(FILE* file, bool short_form, void Append_block_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append(";file_id="); @@ -1524,7 +1524,7 @@ void Delete_file_log_event::print(FILE* file, bool short_form, void Delete_file_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append(";file_id="); @@ -1571,7 +1571,7 @@ void Execute_load_log_event::print(FILE* file, bool short_form, void Execute_load_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append(";file_id="); @@ -1690,12 +1690,12 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli) handle_dup = DUP_REPLACE; sql_exchange ex((char*)fname, sql_ex.opt_flags && DUMPFILE_FLAG ); - String field_term(sql_ex.field_term,sql_ex.field_term_len); - String enclosed(sql_ex.enclosed,sql_ex.enclosed_len); - String line_term(sql_ex.line_term,sql_ex.line_term_len); - String line_start(sql_ex.line_start,sql_ex.line_start_len); - String escaped(sql_ex.escaped,sql_ex.escaped_len); - + String field_term(sql_ex.field_term,sql_ex.field_term_len, system_charset_info); + String enclosed(sql_ex.enclosed,sql_ex.enclosed_len, system_charset_info); + String line_term(sql_ex.line_term,sql_ex.line_term_len, system_charset_info); + String line_start(sql_ex.line_start,sql_ex.line_start_len, system_charset_info); + String escaped(sql_ex.escaped,sql_ex.escaped_len, system_charset_info); + ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG); if (sql_ex.empty_flags & FIELD_TERM_EMPTY) ex.field_term->length(0); diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index 1ab3e18424f..a201651fc2f 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -334,7 +334,7 @@ net_store_data(String *packet,struct tm *tmp) bool net_store_data(String* packet, I_List* str_list) { char buf[256]; - String tmp(buf, sizeof(buf)); + String tmp(buf, sizeof(buf), default_charset_info); tmp.length(0); I_List_iterator it(*str_list); i_string* s; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 9f547c6e0ca..ccee7192682 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -930,7 +930,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, { bool like_error; char buff1[MAX_FIELD_WIDTH],*min_str,*max_str; - String tmp(buff1,sizeof(buff1)),*res; + String tmp(buff1,sizeof(buff1),default_charset_info),*res; uint length,offset,min_length,max_length; if (!field->optimize_range((uint) key_part->key)) @@ -2836,7 +2836,7 @@ static void print_key(KEY_PART *key_part,const char *key,uint used_length) { char buff[1024]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),default_charset_info); for (uint length=0; length < used_length ; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 1398b2ce84f..f8f13c35e35 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -377,7 +377,7 @@ static uint get_access(TABLE *form,uint fieldnr) { uint access_bits=0,bit; char buff[2]; - String res(buff,sizeof(buff)); + String res(buff,sizeof(buff),default_charset_info); Field **pos; for (pos=form->field+fieldnr,bit=1 ; *pos ; pos++ , bit<<=1) @@ -1091,8 +1091,8 @@ static bool update_user_table(THD *thd, const char *host, const char *user, tables.db=(char*) "mysql"; if (!(table=open_ltable(thd,&tables,TL_WRITE))) DBUG_RETURN(1); /* purecov: deadcode */ - table->field[0]->store(host,(uint) strlen(host)); - table->field[1]->store(user,(uint) strlen(user)); + table->field[0]->store(host,(uint) strlen(host), system_charset_info); + table->field[1]->store(user,(uint) strlen(user), system_charset_info); if (table->file->index_read_idx(table->record[0],0, (byte*) table->field[0]->ptr,0, @@ -1102,7 +1102,7 @@ static bool update_user_table(THD *thd, const char *host, const char *user, DBUG_RETURN(1); /* purecov: deadcode */ } store_record(table,1); - table->field[2]->store(new_password,(uint) strlen(new_password)); + table->field[2]->store(new_password,(uint) strlen(new_password), system_charset_info); if ((error=table->file->update_row(table->record[1],table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: deadcode */ @@ -1161,8 +1161,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, empty_string[0]=0; } - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(combo.user.str,combo.user.length); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(combo.user.str,combo.user.length, system_charset_info); table->file->index_init(0); if (table->file->index_read(table->record[0], (byte*) table->field[0]->ptr,0, @@ -1183,17 +1183,17 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, goto end; } old_row_exists = 0; - restore_record(table,2); // cp empty row from record[2] - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(combo.user.str,combo.user.length); - table->field[2]->store(password,(uint) strlen(password)); + restore_record(table,2); // cp empty row from record[2] + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[2]->store(password,(uint) strlen(password), system_charset_info); } else { old_row_exists = 1; store_record(table,1); // Save copy for update if (combo.password.str) // If password given - table->field[2]->store(password,(uint) strlen(password)); + table->field[2]->store(password,(uint) strlen(password), system_charset_info); } for (i = 3, j = SELECT_ACL; // starting from reload @@ -1201,7 +1201,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, i++, j <<= 1) { if (j & rights) // set requested privileges - table->field[i]->store(&what,1); + table->field[i]->store(&what,1, system_charset_info); } rights=get_access(table,3); #ifdef HAVE_OPENSSL @@ -1209,30 +1209,30 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, DBUG_PRINT("info",("table->fields=%d",table->fields)); if (table->fields >= 21) /* From 4.0.0 we have more fields */ { - table->field[18]->store("",0); - table->field[19]->store("",0); - table->field[20]->store("",0); + table->field[18]->store("",0, system_charset_info); + table->field[19]->store("",0, system_charset_info); + table->field[20]->store("",0, system_charset_info); switch (thd->lex.ssl_type) { case SSL_TYPE_ANY: - table->field[17]->store("ANY",3); + table->field[17]->store("ANY",3, system_charset_info); break; case SSL_TYPE_X509: - table->field[17]->store("X509",4); + table->field[17]->store("X509",4, system_charset_info); break; case SSL_TYPE_SPECIFIED: - table->field[17]->store("SPECIFIED",9); + table->field[17]->store("SPECIFIED",9, system_charset_info); if (thd->lex.ssl_cipher) table->field[18]->store(thd->lex.ssl_cipher, - strlen(thd->lex.ssl_cipher)); + strlen(thd->lex.ssl_cipher), system_charset_info); if (thd->lex.x509_issuer) table->field[19]->store(thd->lex.x509_issuer, - strlen(thd->lex.x509_issuer)); + strlen(thd->lex.x509_issuer), system_charset_info); if (thd->lex.x509_subject) table->field[20]->store(thd->lex.x509_subject, - strlen(thd->lex.x509_subject)); + strlen(thd->lex.x509_subject), system_charset_info); break; default: - table->field[17]->store("NONE",4); + table->field[17]->store("NONE",4, system_charset_info); } } #endif /* HAVE_OPENSSL */ @@ -1315,9 +1315,9 @@ static int replace_db_table(TABLE *table, const char *db, DBUG_RETURN(-1); } - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(db,(uint) strlen(db)); - table->field[2]->store(combo.user.str,combo.user.length); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); table->file->index_init(0); if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,0, HA_READ_KEY_EXACT)) @@ -1330,9 +1330,9 @@ static int replace_db_table(TABLE *table, const char *db, } old_row_exists = 0; restore_record(table,2); // cp empty row from record[2] - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(db,(uint) strlen(db)); - table->field[2]->store(combo.user.str,combo.user.length); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); } else { @@ -1344,7 +1344,7 @@ static int replace_db_table(TABLE *table, const char *db, for (i = 3, j = 1; i < table->fields; i++, j <<= 1) { if (j & store_rights) // do it if priv is chosen - table->field [i]->store(&what,1); // set requested privileges + table->field [i]->store(&what,1, system_charset_info);// set requested privileges } rights=get_access(table,3); rights=fix_rights_for_db(rights); @@ -1466,16 +1466,16 @@ public: if (cols) { int key_len; - col_privs->field[0]->store(host,(uint) strlen(host)); - col_privs->field[1]->store(db,(uint) strlen(db)); - col_privs->field[2]->store(user,(uint) strlen(user)); - col_privs->field[3]->store(tname,(uint) strlen(tname)); + col_privs->field[0]->store(host,(uint) strlen(host), system_charset_info); + col_privs->field[1]->store(db,(uint) strlen(db), system_charset_info); + col_privs->field[2]->store(user,(uint) strlen(user), system_charset_info); + col_privs->field[3]->store(tname,(uint) strlen(tname), system_charset_info); key_len=(col_privs->field[0]->pack_length()+ col_privs->field[1]->pack_length()+ col_privs->field[2]->pack_length()+ col_privs->field[3]->pack_length()); key_copy(key,col_privs,0,key_len); - col_privs->field[4]->store("",0); + col_privs->field[4]->store("",0, system_charset_info); col_privs->file->index_init(0); if (col_privs->file->index_read(col_privs->record[0], (byte*) col_privs->field[0]->ptr, @@ -1574,10 +1574,10 @@ static int replace_column_table(GRANT_TABLE *g_t, byte key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_column_table"); - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(db,(uint) strlen(db)); - table->field[2]->store(combo.user.str,combo.user.length); - table->field[3]->store(table_name,(uint) strlen(table_name)); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); key_length=(table->field[0]->pack_length()+ table->field[1]->pack_length()+ table->field[2]->pack_length()+ table->field[3]->pack_length()); key_copy(key,table,0,key_length); @@ -1594,7 +1594,7 @@ static int replace_column_table(GRANT_TABLE *g_t, uint privileges = xx->rights; bool old_row_exists=0; key_restore(table,key,0,key_length); - table->field[4]->store(xx->column.ptr(),xx->column.length()); + table->field[4]->store(xx->column.ptr(),xx->column.length(),system_charset_info); if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) @@ -1608,9 +1608,9 @@ static int replace_column_table(GRANT_TABLE *g_t, continue; /* purecov: inspected */ } old_row_exists = 0; - restore_record(table,2); // Get empty record + restore_record(table,2); // Get empty record key_restore(table,key,0,key_length); - table->field[4]->store(xx->column.ptr(),xx->column.length()); + table->field[4]->store(xx->column.ptr(),xx->column.length(), system_charset_info); } else { @@ -1682,7 +1682,7 @@ static int replace_column_table(GRANT_TABLE *g_t, { GRANT_COLUMN *grant_column = NULL; char colum_name_buf[HOSTNAME_LENGTH+1]; - String column_name(colum_name_buf,sizeof(colum_name_buf)); + String column_name(colum_name_buf,sizeof(colum_name_buf),system_charset_info); privileges&= ~rights; table->field[6]->store((longlong) @@ -1749,10 +1749,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } restore_record(table,2); // Get empty record - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(db,(uint) strlen(db)); - table->field[2]->store(combo.user.str,combo.user.length); - table->field[3]->store(table_name,(uint) strlen(table_name)); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); store_record(table,1); // store at pos 1 if (table->file->index_read_idx(table->record[0],0, @@ -1797,7 +1797,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } } - table->field[4]->store(grantor,(uint) strlen(grantor)); + table->field[4]->store(grantor,(uint) strlen(grantor), system_charset_info); table->field[6]->store((longlong) store_table_rights); table->field[7]->store((longlong) store_col_rights); rights=fix_rights_for_table(store_table_rights); @@ -2612,7 +2612,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) DBUG_RETURN(-1); } - Item_string *field=new Item_string("",0); + Item_string *field=new Item_string("",0,system_charset_info); List field_list; field->name=buff; field->max_length=1024; @@ -2628,7 +2628,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (acl_user->access || acl_user->password) { want_access=acl_user->access; - String global(buff,sizeof(buff)); + String global(buff,sizeof(buff),system_charset_info); global.length(0); global.append("GRANT ",6); @@ -2734,7 +2734,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) want_access=acl_db->access; if (want_access) { - String db(buff,sizeof(buff)); + String db(buff,sizeof(buff),system_charset_info); db.length(0); db.append("GRANT ",6); @@ -2793,7 +2793,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) want_access=grant_table->privs; if ((want_access | grant_table->cols) != 0) { - String global(buff,sizeof(buff)); + String global(buff,sizeof(buff),system_charset_info); global.length(0); global.append("GRANT ",6); diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 8f086863a4e..cc3406d0f54 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -270,7 +270,7 @@ void free_string(String *s) void field_str::add() { char buff[MAX_FIELD_WIDTH], *ptr; - String s(buff, sizeof(buff)), *res; + String s(buff, sizeof(buff),default_charset_info), *res; ulong length; if (!(res = item->val_str(&s))) @@ -573,8 +573,9 @@ bool analyse::end_of_records() { field_info **f = f_info; char buff[MAX_FIELD_WIDTH]; - String *res, s_min(buff, sizeof(buff)), s_max(buff, sizeof(buff)), - ans(buff, sizeof(buff)); + String *res, s_min(buff, sizeof(buff),default_charset_info), + s_max(buff, sizeof(buff),default_charset_info), + ans(buff, sizeof(buff),default_charset_info); for (; f != f_end; f++) { @@ -620,14 +621,14 @@ bool analyse::end_of_records() ((*f)->tree.elements_in_tree * 3 - 1 + 6)))) { char tmp[331]; //331, because one double prec. num. can be this long - String tmp_str(tmp, sizeof(tmp)); + String tmp_str(tmp, sizeof(tmp),default_charset_info); TREE_INFO tree_info; tree_info.str = &tmp_str; tree_info.found = 0; tree_info.item = (*f)->item; - tmp_str.set("ENUM(", 5); + tmp_str.set("ENUM(", 5,default_charset_info); tree_walk(&(*f)->tree, (*f)->collect_enum(), (char*) &tree_info, left_root_right); tmp_str.append(')'); @@ -891,7 +892,7 @@ int collect_real(double *element, element_count count __attribute__((unused)), TREE_INFO *info) { char buff[MAX_FIELD_WIDTH]; - String s(buff, sizeof(buff)); + String s(buff, sizeof(buff),default_charset_info); if (info->found) info->str->append(','); @@ -910,7 +911,7 @@ int collect_longlong(longlong *element, TREE_INFO *info) { char buff[MAX_FIELD_WIDTH]; - String s(buff, sizeof(buff)); + String s(buff, sizeof(buff),default_charset_info); if (info->found) info->str->append(','); @@ -929,7 +930,7 @@ int collect_ulonglong(ulonglong *element, TREE_INFO *info) { char buff[MAX_FIELD_WIDTH]; - String s(buff, sizeof(buff)); + String s(buff, sizeof(buff),default_charset_info); if (info->found) info->str->append(','); diff --git a/sql/sql_analyse.h b/sql/sql_analyse.h index 1c60d0c150f..3e8ddd67023 100644 --- a/sql/sql_analyse.h +++ b/sql/sql_analyse.h @@ -110,8 +110,9 @@ class field_str :public field_info EV_NUM_INFO ev_num_info; public: - field_str(Item* a, analyse* b) :field_info(a,b), min_arg(""), - max_arg(""), sum(0), + field_str(Item* a, analyse* b) :field_info(a,b), + min_arg("",default_charset_info), + max_arg("",default_charset_info), sum(0), must_be_blob(0), was_zero_fill(0), was_maybe_zerofill(0), can_be_still_num(1) { init_tree(&tree, 0, 0, sizeof(String), a->binary ? diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 031c83a2aeb..5e3bf90c4a5 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -197,7 +197,8 @@ send_fields(THD *thd,List &list,uint flag) char buff[80]; CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set; - String tmp((char*) buff,sizeof(buff)),*res,*packet= &thd->packet; + String tmp((char*) buff,sizeof(buff),default_charset_info); + String *res,*packet= &thd->packet; if (thd->fatal_error) // We have got an error goto err; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 29cdaa676d6..d5d5c8fa6f9 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -363,8 +363,10 @@ select_result::select_result() thd=current_thd; } -static String default_line_term("\n"),default_escaped("\\"), - default_field_term("\t"); +static String + default_line_term("\n",default_charset_info), + default_escaped("\\",default_charset_info), + default_field_term("\t",default_charset_info); sql_exchange::sql_exchange(char *name,bool flag) :file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0) @@ -507,7 +509,7 @@ bool select_export::send_data(List &items) DBUG_ENTER("send_data"); char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH]; bool space_inited=0; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; tmp.length(0); if (thd->offset_limit) @@ -714,7 +716,7 @@ bool select_dump::send_data(List &items) { List_iterator_fast li(items); char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; tmp.length(0); Item *item; DBUG_ENTER("send_data"); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 419e3fccabd..faeeaf2812e 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -358,7 +358,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List &fields, field->field_length) length=field->field_length; save_chr=pos[length]; pos[length]='\0'; // Safeguard aganst malloc - field->store((char*) pos,length); + field->store((char*) pos,length,default_charset_info); pos[length]=save_chr; if ((pos+=length) > read_info.row_end) pos= read_info.row_end; /* Fills rest with space */ @@ -427,7 +427,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, } field->set_notnull(); read_info.row_end[0]=0; // Safe to change end marker - field->store((char*) read_info.row_start,length); + field->store((char*) read_info.row_start,length,default_charset_info); } if (read_info.error) break; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2599fe216c5..c539afb00c1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3377,14 +3377,14 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item_sum::AVG_FUNC: /* Place for sum & count */ if (group) return new Field_string(sizeof(double)+sizeof(longlong), - maybe_null, item->name,table,1); + maybe_null, item->name,table,1,default_charset_info); else return new Field_double(item_sum->max_length,maybe_null, item->name, table, item_sum->decimals); case Item_sum::STD_FUNC: /* Place for sum & count */ if (group) return new Field_string(sizeof(double)*2+sizeof(longlong), - maybe_null, item->name,table,1); + maybe_null, item->name,table,1,default_charset_info); else return new Field_double(item_sum->max_length, maybe_null, item->name,table,item_sum->decimals); @@ -3403,7 +3403,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, return new Field_blob(item_sum->max_length,maybe_null, item->name,table,item->binary); return new Field_string(item_sum->max_length,maybe_null, - item->name,table,item->binary); + item->name,table,item->binary,default_charset_info); } } thd->fatal_error=1; @@ -3457,7 +3457,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, item->name,table,item->binary); else new_field= new Field_string(item->max_length,maybe_null, - item->name,table,item->binary); + item->name,table,item->binary,default_charset_info); break; } if (copy_func) @@ -3876,7 +3876,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, (uchar*) 0, (uint) 0, Field::NONE, - NullS, table, (bool) 1); + NullS, table, (bool) 1, default_charset_info); key_part_info->key_type=FIELDFLAG_BINARY; key_part_info->type= HA_KEYTYPE_BINARY; key_part_info++; @@ -6790,7 +6790,7 @@ change_to_use_tmp_fields(List &items) if (_db_on_ && !item_field->name) { char buff[256]; - String str(buff,sizeof(buff)); + String str(buff,sizeof(buff),default_charset_info); str.length(0); item->print(&str); item_field->name=sql_strmake(str.ptr(),str.length()); @@ -7021,7 +7021,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(new Item_empty_string("",0)); item_list.push_back(new Item_empty_string("",0)); item_list.push_back(new Item_empty_string("",0)); - item_list.push_back(new Item_string(message,strlen(message))); + item_list.push_back(new Item_string(message,strlen(message),default_charset_info)); if (result->send_data(item_list)) result->send_error(0,NullS); } @@ -7034,13 +7034,13 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, TABLE *table=tab->table; char buff[512],*buff_ptr=buff; char buff1[512], buff2[512], bufff[512]; - String tmp1(buff1,sizeof(buff1)); - String tmp2(buff2,sizeof(buff2)); + String tmp1(buff1,sizeof(buff1),default_charset_info); + String tmp2(buff2,sizeof(buff2),default_charset_info); item_list.empty(); if (tab->type == JT_ALL && tab->select && tab->select->quick) tab->type= JT_RANGE; - item_list.push_back(new Item_string(table->table_name,strlen(table->table_name))); - item_list.push_back(new Item_string(join_type_str[tab->type],strlen(join_type_str[tab->type]))); + item_list.push_back(new Item_string(table->table_name,strlen(table->table_name),default_charset_info)); + item_list.push_back(new Item_string(join_type_str[tab->type],strlen(join_type_str[tab->type]),default_charset_info)); tmp1.length(0); tmp2.length(0); key_map bits; uint j; @@ -7054,12 +7054,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } } if (tmp1.length()) - item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length())); + item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),default_charset_info)); else item_list.push_back(new Item_null()); if (tab->ref.key_parts) { - item_list.push_back(new Item_string(table->key_info[tab->ref.key].name,strlen(table->key_info[tab->ref.key].name))); + item_list.push_back(new Item_string(table->key_info[tab->ref.key].name,strlen(table->key_info[tab->ref.key].name),default_charset_info)); item_list.push_back(new Item_int((int) tab->ref.key_length)); for (store_key **ref=tab->ref.key_copy ; *ref ; ref++) { @@ -7067,17 +7067,17 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, tmp2.append(','); tmp2.append((*ref)->name()); } - item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length())); + item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),default_charset_info)); } else if (tab->type == JT_NEXT) { - item_list.push_back(new Item_string(table->key_info[tab->index].name,strlen(table->key_info[tab->index].name))); + item_list.push_back(new Item_string(table->key_info[tab->index].name,strlen(table->key_info[tab->index].name),default_charset_info)); item_list.push_back(new Item_int((int) table->key_info[tab->index].key_length)); item_list.push_back(new Item_null()); } else if (tab->select && tab->select->quick) { - item_list.push_back(new Item_string(table->key_info[tab->select->quick->index].name,strlen(table->key_info[tab->select->quick->index].name))); + item_list.push_back(new Item_string(table->key_info[tab->select->quick->index].name,strlen(table->key_info[tab->select->quick->index].name),default_charset_info)); item_list.push_back(new Item_int((int) tab->select->quick->max_used_key_length)); item_list.push_back(new Item_null()); } @@ -7088,14 +7088,14 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(new Item_null()); } sprintf(bufff,"%.0f",join->best_positions[i].records_read); - item_list.push_back(new Item_string(bufff,strlen(bufff))); + item_list.push_back(new Item_string(bufff,strlen(bufff),default_charset_info)); my_bool key_read=table->key_read; if (tab->type == JT_NEXT && ((table->used_keys & ((key_map) 1 << tab->index)))) key_read=1; if (tab->info) - item_list.push_back(new Item_string(tab->info,strlen(tab->info))); + item_list.push_back(new Item_string(tab->info,strlen(tab->info),default_charset_info)); else if (tab->select) { if (tab->use_quick == 2) @@ -7149,7 +7149,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } buff_ptr=strmov(buff_ptr,"Distinct"); } - item_list.push_back(new Item_string(buff,(uint) (buff_ptr - buff))); + item_list.push_back(new Item_string(buff,(uint) (buff_ptr - buff),default_charset_info)); // For next iteration used_tables|=table->map; if (result->send_data(item_list)) diff --git a/sql/sql_select.h b/sql/sql_select.h index befa1efde53..054d427a4e0 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -217,7 +217,7 @@ class store_key :public Sql_alloc if (field_arg->type() == FIELD_TYPE_BLOB) to_field=new Field_varstring(ptr, length, (uchar*) null, 1, Field::NONE, field_arg->field_name, - field_arg->table, field_arg->binary()); + field_arg->table, field_arg->binary(), default_charset_info); else { to_field=field_arg->new_field(&thd->mem_root,field_arg->table); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 95705c19d68..849a803a622 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -57,7 +57,7 @@ extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd; int mysqld_show_dbs(THD *thd,const char *wild) { - Item_string *field=new Item_string("",0); + Item_string *field=new Item_string("",0,default_charset_info); List field_list; char *end; List files; @@ -138,7 +138,7 @@ int mysqld_show_open_tables(THD *thd,const char *wild) int mysqld_show_tables(THD *thd,const char *db,const char *wild) { - Item_string *field=new Item_string("",0); + Item_string *field=new Item_string("",0,default_charset_info); List field_list; char path[FN_LEN],*end; List files; @@ -262,7 +262,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) (void) sprintf(path,"%s/%s",mysql_data_home,db); (void) unpack_dirname(path,path); - +//,default_charset_info field_list.push_back(item=new Item_empty_string("Name",NAME_LEN)); item->maybe_null=1; field_list.push_back(item=new Item_empty_string("Type",10)); @@ -483,7 +483,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, { byte *pos; uint flags=field->flags; - String type(tmp,sizeof(tmp)); + String type(tmp,sizeof(tmp),default_charset_info); uint col_access; bool null_default_value=0; @@ -506,7 +506,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, null_default_value=1; if (!null_default_value && !field->is_null()) { // Not null by default - type.set(tmp,sizeof(tmp)); + type.set(tmp,sizeof(tmp),default_charset_info); field->val_str(&type,&type); net_store_data(packet,convert,type.ptr(),type.length()); } @@ -810,7 +810,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) List field_list; char tmp[MAX_FIELD_WIDTH]; - String type(tmp, sizeof(tmp)); + String type(tmp, sizeof(tmp),default_charset_info); if (table->tmp_table) packet->append("CREATE TEMPORARY TABLE ", 23); else @@ -830,7 +830,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(' '); // check for surprises from the previous call to Field::sql_type() if (type.ptr() != tmp) - type.set(tmp, sizeof(tmp)); + type.set(tmp, sizeof(tmp),default_charset_info); field->sql_type(type); packet->append(type.ptr(),type.length()); @@ -846,7 +846,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(" default ", 9); if (!field->is_null()) { // Not null by default - type.set(tmp,sizeof(tmp)); + type.set(tmp,sizeof(tmp),default_charset_info); field->val_str(&type,&type); packet->append('\''); if (type.length()) @@ -1143,7 +1143,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables) { uint i; char buff[8192]; - String packet2(buff,sizeof(buff)); + String packet2(buff,sizeof(buff),default_charset_info); List field_list; CONVERT *convert=thd->convert_set; DBUG_ENTER("mysqld_show"); diff --git a/sql/sql_string.cc b/sql/sql_string.cc index cf9e9f62507..b222d3394eb 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -586,6 +586,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) return from; // Actually an error if ((to->str_length=min(from->str_length,from_length))) memcpy(to->Ptr,from->Ptr,to->str_length); + to->str_charset=from->str_charset; return to; } diff --git a/sql/sql_string.h b/sql/sql_string.h index 9bf13b93628..68c5e005782 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -46,22 +46,21 @@ public: String(uint32 length_arg) { alloced=0; Alloced_length=0; (void) real_alloc(length_arg); - str_charset=default_charset_info; } - String(const char *str) + String(const char *str, CHARSET_INFO *cs) { Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0; - str_charset=default_charset_info; + str_charset=cs; } - String(const char *str,uint32 len) + String(const char *str,uint32 len, CHARSET_INFO *cs) { Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0; - str_charset=default_charset_info; + str_charset=cs; } - String(char *str,uint32 len) + String(char *str,uint32 len, CHARSET_INFO *cs) { Ptr=(char*) str; Alloced_length=str_length=len; alloced=0; - str_charset=default_charset_info; + str_charset=cs; } String(const String &str) { @@ -103,23 +102,27 @@ public: Alloced_length=str.Alloced_length-offset; else Alloced_length=0; + str_charset=str.str_charset; } - inline void set(char *str,uint32 arg_length) + inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs) { free(); Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0; + str_charset=cs; } - inline void set(const char *str,uint32 arg_length) + inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs) { free(); Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0; + str_charset=cs; } - inline void set_quick(char *str,uint32 arg_length) + inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs) { if (!alloced) { Ptr=(char*) str; str_length=Alloced_length=arg_length; } + str_charset=cs; } bool set(longlong num); /* bool set(long num); */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 782caa8fa51..a60ff793cb6 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -156,7 +156,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, { if (wrong_tables.length()) wrong_tables.append(','); - wrong_tables.append(String(table->real_name)); + wrong_tables.append(String(table->real_name,default_charset_info)); } } if (some_tables_deleted) diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 43c24da85a2..0bc1feed839 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -33,7 +33,7 @@ print_where(COND *cond,const char *info) if (cond) { char buff[256]; - String str(buff,(uint32) sizeof(buff)); + String str(buff,(uint32) sizeof(buff), default_charset_info); str.length(0); cond->print(&str); str.append('\0'); @@ -99,7 +99,8 @@ void print_cached_tables(void) void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special) { char buff[256],buff2[256]; - String str(buff,sizeof(buff)),out(buff2,sizeof(buff2)); + String str(buff,sizeof(buff),default_charset_info); + String out(buff2,sizeof(buff2),default_charset_info); const char *sep; DBUG_ENTER("TEST_filesort"); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index f44fa3b7321..225c0ea26a4 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -412,9 +412,9 @@ int mysql_create_function(THD *thd,udf_func *udf) goto err; restore_record(table,2); // Get default values for fields - table->field[0]->store(u_d->name, u_d->name_length); + table->field[0]->store(u_d->name, u_d->name_length, default_charset_info); table->field[1]->store((longlong) u_d->returns); - table->field[2]->store(u_d->dl,(uint) strlen(u_d->dl)); + table->field[2]->store(u_d->dl,(uint) strlen(u_d->dl), default_charset_info); if (table->fields >= 4) // If not old func format table->field[3]->store((longlong) u_d->type); error = table->file->write_row(table->record[0]); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index db520af61c1..2a45798ddf8 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -466,7 +466,7 @@ multi_update::prepare(List &values) } if (counter) { - Field_string offset(table_ref->table->file->ref_length,false,"offset",table_ref->table,true); + Field_string offset(table_ref->table->file->ref_length,false,"offset",table_ref->table,true,default_charset_info); temp_fields->push_front(new Item_field(((Field *)&offset))); // Here I make tmp tables int cnt=counter-1; @@ -616,7 +616,8 @@ bool multi_update::send_data(List &values) { // Here we insert into each temporary table values_by_table.push_front(new Item_string((char*) table->file->ref, - table->file->ref_length)); + table->file->ref_length, + system_charset_info)); fill_record(tmp_tables[secure_counter]->field,values_by_table); error= write_record(tmp_tables[secure_counter], &(infos[secure_counter])); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 24321dbdb53..6ce661440c0 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1904,7 +1904,7 @@ simple_expr: | SUBSTRING_INDEX '(' expr ',' expr ',' expr ')' { $$= new Item_func_substr_index($3,$5,$7); } | TRIM '(' expr ')' - { $$= new Item_func_trim($3,new Item_string(" ",1)); } + { $$= new Item_func_trim($3,new Item_string(" ",1,default_charset_info)); } | TRIM '(' LEADING opt_pad FROM expr ')' { $$= new Item_func_ltrim($6,$4); } | TRIM '(' TRAILING opt_pad FROM expr ')' @@ -2089,7 +2089,7 @@ when_list2: } opt_pad: - /* empty */ { $$=new Item_string(" ",1); } + /* empty */ { $$=new Item_string(" ",1,default_charset_info); } | expr { $$=$1; } join_table_list: @@ -2204,11 +2204,11 @@ key_usage_list: key_usage_list2: key_usage_list2 ',' ident - { Select->interval_list.push_back(new String((const char*) $3.str,$3.length)); } + { Select->interval_list.push_back(new String((const char*) $3.str,$3.length,default_charset_info)); } | ident - { Select->interval_list.push_back(new String((const char*) $1.str,$1.length)); } + { Select->interval_list.push_back(new String((const char*) $1.str,$1.length,default_charset_info)); } | PRIMARY_SYM - { Select->interval_list.push_back(new String("PRIMARY",7)); } + { Select->interval_list.push_back(new String("PRIMARY",7,default_charset_info)); } using_list: ident @@ -2815,7 +2815,7 @@ describe_command: opt_describe_column: /* empty */ {} | text_string { Lex->wild= $1; } - | ident { Lex->wild= new String((const char*) $1.str,$1.length); } + | ident { Lex->wild= new String((const char*) $1.str,$1.length,default_charset_info); } /* flush things */ @@ -2983,15 +2983,15 @@ opt_ignore_lines: /* Common definitions */ text_literal: - TEXT_STRING { $$ = new Item_string($1.str,$1.length); } + TEXT_STRING { $$ = new Item_string($1.str,$1.length,default_charset_info); } | text_literal TEXT_STRING { ((Item_string*) $1)->append($2.str,$2.length); } text_string: - TEXT_STRING { $$= new String($1.str,$1.length); } + TEXT_STRING { $$= new String($1.str,$1.length,default_charset_info); } | HEX_NUM { - Item *tmp = new Item_varbinary($1.str,$1.length); + Item *tmp = new Item_varbinary($1.str,$1.length,default_charset_info); $$= tmp ? tmp->val_str((String*) 0) : (String*) 0; } @@ -3004,7 +3004,7 @@ literal: | FLOAT_NUM { $$ = new Item_float($1.str, $1.length); } | NULL_SYM { $$ = new Item_null(); Lex->next_state=STATE_OPERATOR_OR_IDENT;} - | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length);} + | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length,default_charset_info);} | DATE_SYM text_literal { $$ = $2; } | TIME_SYM text_literal { $$ = $2; } | TIMESTAMP text_literal { $$ = $2; } @@ -3731,7 +3731,7 @@ column_list: column_list_id: ident { - String *new_str = new String((const char*) $1.str,$1.length); + String *new_str = new String((const char*) $1.str,$1.length,default_charset_info); List_iterator iter(Lex->columns); class LEX_COLUMN *point; LEX *lex=Lex; diff --git a/sql/table.cc b/sql/table.cc index eb5f5ecbc9a..29c50fd8dcc 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1072,7 +1072,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) { Field *field=table->field[fieldnr]; char buff[MAX_FIELD_WIDTH]; - String str(buff,sizeof(buff)); + String str(buff,sizeof(buff),table->table_charset); field->val_str(&str,&str); uint length=str.length(); if (!length) diff --git a/sql/unireg.cc b/sql/unireg.cc index 1c35f7a6a08..16f51658313 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -484,7 +484,7 @@ static bool pack_fields(File file,List &create_fields) /* Write intervals */ if (int_count) { - String tmp((char*) buff,sizeof(buff)); + String tmp((char*) buff,sizeof(buff), default_charset_info); tmp.length(0); it.rewind(); int_count=0; @@ -561,6 +561,7 @@ static bool make_empty_rec(File file,enum db_type table_type, field->interval, field->field_name, &table); + if (!(field->flags & NOT_NULL_FLAG)) null_count++; @@ -581,9 +582,9 @@ static bool make_empty_rec(File file,enum db_type table_type, regfield->store((longlong) 1); } else if (type == Field::YES) // Old unireg type - regfield->store(ER(ER_YES),(uint) strlen(ER(ER_YES))); + regfield->store(ER(ER_YES),(uint) strlen(ER(ER_YES)),default_charset_info); else if (type == Field::NO) // Old unireg type - regfield->store(ER(ER_NO), (uint) strlen(ER(ER_NO))); + regfield->store(ER(ER_NO), (uint) strlen(ER(ER_NO)),default_charset_info); else regfield->reset(); delete regfield; -- cgit v1.2.1 From 3f50440f30f5b49f78672f804c578ff1484ee274 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 May 2002 17:10:50 +0500 Subject: Charset related synax changes, now these things work in parser: CREATE DATABASE name DEFAULT CHARACTER SET charsetname; CREATE DATABASE name (fieldname CHAR(n) CHARACTER SET charsetname); Changes affect query parsing ONLY and do not have other effect yet. sql/sql_lex.h: Charset related synax changes sql/sql_yacc.yy: Charset related synax changes --- sql/sql_lex.h | 1 + sql/sql_yacc.yy | 29 ++++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 53422b050a3..e53a2e7bda8 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -189,6 +189,7 @@ typedef struct st_lex { bool drop_primary,drop_if_exists,local_file; bool in_comment,ignore_space,verbose,simple_alter, option_type, derived_tables; uint slave_thd_opt; + CHARSET_INFO *charset; } LEX; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6ce661440c0..756afbd7a09 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -777,7 +777,7 @@ create: lex->key_list.push_back(new Key($2,$5,$4.str,lex->col_list)); lex->col_list.empty(); } - | CREATE DATABASE opt_if_not_exists ident + | CREATE DATABASE opt_if_not_exists ident default_charset { LEX *lex=Lex; lex->sql_command=SQLCOM_CREATE_DB; @@ -1095,8 +1095,31 @@ attribute: | UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; } opt_binary: - /* empty */ {} - | BINARY { Lex->type|=BINARY_FLAG; } + /* empty */ { Lex->charset=default_charset_info; } + | BINARY { Lex->type|=BINARY_FLAG; Lex->charset=default_charset_info; } + | CHAR_SYM SET ident + { + CHARSET_INFO *cs=get_charset_by_name($3.str,MYF(MY_WME)); + if (!cs) + { + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3); + YYABORT; + } + Lex->charset=cs; + } + +default_charset: + /* empty */ { Lex->charset-default_charset_info; } + | DEFAULT CHAR_SYM SET ident + { + CHARSET_INFO *cs=get_charset_by_name($4.str,MYF(MY_WME)); + if (!cs) + { + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$4); + YYABORT; + } + Lex->charset=cs; + } references: REFERENCES table_ident opt_on_delete {} -- cgit v1.2.1 From 1afa4558563c758277052520f811d665845a223c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 May 2002 20:38:39 +0500 Subject: Fix for bug mentioned by Peter and Sanja sql/sql_table.cc: Remove debug output --- sql/filesort.cc | 2 +- sql/sql_table.cc | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/filesort.cc b/sql/filesort.cc index ec49163f8a0..b7745ccb8ca 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -87,6 +87,7 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length, for(i=0;ifields;i++) if (!table->field[i]->binary()) charset=((Field_str*)(table->field[i]))->charset(); + charset=charset?charset:default_charset_info; // /BAR TODO outfile= table->io_cache; @@ -930,7 +931,6 @@ sortlength(SORT_FIELD *sortorder, uint s_length) #ifdef USE_STRCOLL if (!sortorder->field->binary()) { - // BAR TODO: need checking that it is really Field_str based class CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); if (use_strcoll(cs)) sortorder->length= sortorder->length*cs->strxfrm_multiply; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a60ff793cb6..36c4f4cba48 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -476,9 +476,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, checking for proper key parts number: */ -printf("key_info->flags=%d key_info->algorithm=%d\n", - key_info->flags,key_info->algorithm); - if(key_info->flags == HA_SPATIAL){ if(key_info->key_parts!=1){ my_printf_error(ER_WRONG_ARGUMENTS, -- cgit v1.2.1 From 1b49cd8ca1391d5141750fae62fa0c9c13da6e86 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 May 2002 21:56:27 +0500 Subject: Bug fix: charset was not initialized --- sql/sql_string.cc | 1 + sql/sql_string.h | 1 + 2 files changed, 2 insertions(+) (limited to 'sql') diff --git a/sql/sql_string.cc b/sql/sql_string.cc index b222d3394eb..c05a7b85f77 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -203,6 +203,7 @@ bool String::copy(const String &str) str_length=str.str_length; bmove(Ptr,str.Ptr,str_length); // May be overlapping Ptr[str_length]=0; + str_charset=str.str_charset; return FALSE; } diff --git a/sql/sql_string.h b/sql/sql_string.h index 68c5e005782..5e5c9001590 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -46,6 +46,7 @@ public: String(uint32 length_arg) { alloced=0; Alloced_length=0; (void) real_alloc(length_arg); + str_charset=default_charset_info; } String(const char *str, CHARSET_INFO *cs) { -- cgit v1.2.1 From c811538f89925b7111e4ee0e3b940726f32a64d9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 May 2002 21:54:08 +0500 Subject: BTREE heap key structure is now the same as MyISAM _mi_compare_text -> mi_compate_text Changes according Monty's suggestions heap/heapdef.h: BTREE heap key structure is now the same as MyISAM heap/hp_delete.c: BTREE heap key structure is now the same as MyISAM heap/hp_hash.c: BTREE heap key structure is now the same as MyISAM heap/hp_open.c: BTREE heap key structure is now the same as MyISAM heap/hp_rfirst.c: BTREE heap key structure is now the same as MyISAM heap/hp_rkey.c: BTREE heap key structure is now the same as MyISAM heap/hp_rlast.c: BTREE heap key structure is now the same as MyISAM heap/hp_rnext.c: BTREE heap key structure is now the same as MyISAM heap/hp_rprev.c: BTREE heap key structure is now the same as MyISAM heap/hp_write.c: BTREE heap key structure is now the same as MyISAM include/heap.h: BTREE heap key structure is now the same as MyISAM include/my_handler.h: Removed hp_rb_key_cmp() _mi_compare_text -> mi_compate_text include/my_tree.h: Fixed typo myisam/ft_boolean_search.c: _mi_compare_text -> mi_compate_text myisam/ft_nlq_search.c: _mi_compare_text -> mi_compate_text myisam/ft_parser.c: _mi_compare_text -> mi_compate_text myisam/ft_stopwords.c: _mi_compare_text -> mi_compate_text myisam/ft_update.c: _mi_compare_text -> mi_compate_text mysys/my_handler.c: Removed hp_rb_key_cmp() _mi_compare_text -> mi_compate_text mysys/tree.c: BTREE heap key structure is now the same as MyISAM sql/ha_heap.cc: BTREE heap key structure is now the same as MyISAM --- sql/ha_heap.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index e18bc877540..70409be4e42 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -42,9 +42,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) { parts+=table->key_info[key].key_parts; if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE) - { parts++; /* additional HA_KEYTYPE_END keyseg */ - } } if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+ @@ -55,7 +53,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) { KEY *pos=table->key_info+key; KEY_PART_INFO *key_part= pos->key_part; - KEY_PART_INFO *key_part_end= key_part+pos->key_parts; + KEY_PART_INFO *key_part_end= key_part + pos->key_parts; mem_per_row+= (pos->key_length + (sizeof(char*) * 2)); @@ -94,14 +92,13 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) } else { - seg->null_bit=0; - seg->null_pos=0; + seg->null_bit= 0; + seg->null_pos= 0; } } if (pos->algorithm == HA_KEY_ALG_BTREE) { /* additional HA_KEYTYPE_END keyseg */ - keydef[key].keysegs++; seg->type= HA_KEYTYPE_END; seg->length= sizeof(byte*); seg->flag= 0; -- cgit v1.2.1 From a8652e9957e014c19b47635e09147a7bc17a3b8c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 22 May 2002 18:51:21 +0300 Subject: Fixed problem in fulltest testcase include/my_base.h: Fix to ensure that old tables works in 4.1 myisam/mi_open.c: cleanup mysys/my_handler.c: Fixed problem in fulltest testcase sql/spatial.cc: cleanup sql/sql_table.cc: cleanup --- sql/spatial.cc | 14 +++++++++++--- sql/sql_table.cc | 20 +++++++++++--------- 2 files changed, 22 insertions(+), 12 deletions(-) (limited to 'sql') diff --git a/sql/spatial.cc b/sql/spatial.cc index 32942a70dc2..bb6e03c3c03 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -680,13 +680,16 @@ int GPolygon::centroid_xy(double *x, double *y) const uint32 i; double res_area, res_cx, res_cy; const char *data = m_data; + LINT_INIT(res_area); + LINT_INIT(res_cx); + LINT_INIT(res_cy); if (no_data(data, 4)) return 1; n_linear_rings = uint4korr(data); data += 4; - for(i = 0; i < n_linear_rings; ++i) + for (i = 0; i < n_linear_rings; ++i) { if (no_data(data, 4)) return 1; @@ -720,7 +723,8 @@ int GPolygon::centroid_xy(double *x, double *y) const cur_area = fabs(cur_area) / 2; cur_cx = cur_cx / (n_points - 1); cur_cy = cur_cy / (n_points - 1); - if(i) + + if (i) { double d_area = res_area - cur_area; if (d_area <= 0) @@ -1195,6 +1199,10 @@ int GMultiPolygon::centroid(String *result) const double res_area, res_cx, res_cy; double cur_area, cur_cx, cur_cy; + LINT_INIT(res_area); + LINT_INIT(res_cx); + LINT_INIT(res_cy); + const char *data = m_data; if (no_data(data, 4)) return 1; @@ -1211,7 +1219,7 @@ int GMultiPolygon::centroid(String *result) const if (p.centroid_xy(&cur_cx, &cur_cy)) return 1; - if(i) + if (i) { double sum_area = res_area + cur_area; res_cx = (res_area * res_cx + cur_area * cur_cx) / sum_area; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 36c4f4cba48..bdcb325774b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -476,20 +476,22 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, checking for proper key parts number: */ - if(key_info->flags == HA_SPATIAL){ - if(key_info->key_parts!=1){ + if (key_info->flags == HA_SPATIAL) + { + if (key_info->key_parts != 1) + { my_printf_error(ER_WRONG_ARGUMENTS, ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX"); DBUG_RETURN(-1); } - }else + } + else if (key_info->algorithm == HA_KEY_ALG_RTREE) { - if(key_info->algorithm == HA_KEY_ALG_RTREE){ - if((key_info->key_parts&1)==1){ - my_printf_error(ER_WRONG_ARGUMENTS, - ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); - DBUG_RETURN(-1); - } + if ((key_info->key_parts & 1) == 1) + { + my_printf_error(ER_WRONG_ARGUMENTS, + ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); + DBUG_RETURN(-1); } } -- cgit v1.2.1 From e494b724d0b3100d325a6dd9f59c004b3bb71c1c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 22 May 2002 20:09:03 +0300 Subject: Fixed key algorithm handling sql/sql_string.cc: Portability fix --- sql/sql_class.h | 3 --- sql/sql_parse.cc | 5 +++-- sql/sql_string.cc | 4 ++-- sql/table.cc | 5 +++++ 4 files changed, 10 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index 3ffac72c1db..5dc761ff811 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -221,9 +221,6 @@ public: List columns; const char *Name; - Key(enum Keytype type_par,const char *name_arg,List &cols) - :type(type_par), columns(cols),Name(name_arg) {} - Key(enum Keytype type_par, enum ha_key_alg alg_par, const char *name_arg, List &cols) :type(type_par), algorithm(alg_par), columns(cols), Name(name_arg) {} diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 06431124356..469de136fbb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2787,14 +2787,14 @@ bool add_field_to_list(char *field_name, enum_field_types type, if (type_modifier & PRI_KEY_FLAG) { lex->col_list.push_back(new key_part_spec(field_name,0)); - lex->key_list.push_back(new Key(Key::PRIMARY,NullS, + lex->key_list.push_back(new Key(Key::PRIMARY, HA_KEY_ALG_UNDEF, NullS, lex->col_list)); lex->col_list.empty(); } if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) { lex->col_list.push_back(new key_part_spec(field_name,0)); - lex->key_list.push_back(new Key(Key::UNIQUE,NullS, + lex->key_list.push_back(new Key(Key::UNIQUE, HA_KEY_ALG_UNDEF, NullS, lex->col_list)); lex->col_list.empty(); } @@ -2858,6 +2858,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_NULL: + case FIELD_TYPE_GEOMETRY: break; case FIELD_TYPE_DECIMAL: if (!length) diff --git a/sql/sql_string.cc b/sql/sql_string.cc index c05a7b85f77..b8e2ba7b536 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -123,7 +123,7 @@ bool String::set(double num,uint decimals) char *pos,*to; VOID(fconvert(num,(int) decimals,&decpt,&sign,buff+1)); - if (!isdigit(buff[1])) + if (!my_isdigit(system_charset_info, buff[1])) { // Nan or Inf pos=buff+1; if (sign) @@ -490,7 +490,7 @@ void String::qs_append(double d) void String::qs_append(double *d) { double ld; - float8get(ld, d); + float8get(ld, (char*) d); qs_append(ld); } diff --git a/sql/table.cc b/sql/table.cc index 29c50fd8dcc..05a5c5e6bd2 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -199,7 +199,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, /* Read key types */ keyinfo=outparam->key_info; for (i=0 ; i < keys ; i++, keyinfo++) + { keyinfo->algorithm= (enum ha_key_alg) *(strpos++); + /* Temporary fix to get spatial index to work */ + if (keyinfo->algorithm == HA_KEY_ALG_RTREE) + keyinfo->flags|= HA_SPATIAL; + } } else { -- cgit v1.2.1 From 02d8b9ba56082d26b14808f6618e098c72e083fb Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 26 May 2002 22:50:32 +0300 Subject: added depended subselect processing mysql-test/r/subselect.result: depended subselect test mysql-test/t/subselect.test: depended subselect test sql/item.cc: resolving field names in depended queries sql/item_subselect.cc: move optimization just before execution, because we can't optimize inner depended subselect if have not optimized outer subselect sql/item_subselect.h: move optimization just before execution sql/sql_lex.h: some inline methods to hide internal SELECT_LEX structures sql/sql_select.cc: fixed error --- sql/item.cc | 29 ++++++++++++++++++++++++++++- sql/item_subselect.cc | 28 +++++++++++++++++++++------- sql/item_subselect.h | 5 ++++- sql/sql_lex.cc | 1 + sql/sql_lex.h | 8 +++++++- sql/sql_select.cc | 42 +++++++++++++++++++++++++++++++++++------- sql/sql_select.h | 3 +++ 7 files changed, 99 insertions(+), 17 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 84f4624a248..13141ade2a8 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -320,7 +320,34 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) { Field *tmp; if (!(tmp=find_field_in_tables(thd,this,tables))) - return 1; + { + /* + We can't find table field in table list of current select, + consequently we have to find it in outer subselect(s). + We can't join lists of outer & current select, because of scope + of view rules. For example if both tables (outer & current) have + field 'field' it is not mistake to refer to this field without + mention of table name, but if we join tables in one list it will + cause error ER_NON_UNIQ_ERROR in find_field_in_tables. + */ + for (SELECT_LEX *sl= thd->lex.select->outer_select(); + sl && !tmp; + sl= sl->outer_select()) + tmp=find_field_in_tables(thd, this, + (TABLE_LIST*)sl->table_list.first); + if (!tmp) + return 1; + else + if( !thd->lex.select->depended ) + { + thd->lex.select->depended= 1; //Select is depended of outer select(s) + //Tables will be reopened many times + for (TABLE_LIST *tbl= (TABLE_LIST*)thd->lex.select->table_list.first; + tbl; + tbl= tbl->next) + tbl->shared= 1; + } + } set_field(tmp); } else if (thd && thd->set_query_id && field->query_id != thd->query_id) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 286c29fec7a..d71271b98fd 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -36,7 +36,7 @@ SUBSELECT TODO: #include "sql_select.h" Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex): - executed(0) + executed(0), optimized(0), error(0) { DBUG_ENTER("Item_subselect::Item_subselect"); DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex)); @@ -48,7 +48,7 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex): item value is NULL if select_subselect not changed this value (i.e. some rows will be found returned) */ - assign_null(); + assign_null(); DBUG_VOID_RETURN; } @@ -110,17 +110,31 @@ bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables) (ORDER*) 0, select_lex, (SELECT_LEX_UNIT*) select_lex->master)) return 1; - if (join->optimize()) - { - executed= 1; - return 1; - } thd->lex.select= save_select; return 0; } int Item_subselect::exec() { + if (!optimized) + { + optimized=1; + if (join->optimize()) + { + executed= 1; + return (join->error?join->error:1); + } + } + if (join->select_lex->depended && executed) + { + if (join->reinit()) + { + error= 1; + return 1; + } + assign_null(); + executed= 0; + } if (!executed) { SELECT_LEX *save_select= join->thd->lex.select; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 096da68600c..e27f14fb83d 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -29,9 +29,11 @@ class select_subselect; class Item_subselect :public Item { protected: - my_bool executed; /* simple subselect is executed */ longlong int_value; double real_value; + my_bool executed; /* simple subselect is executed */ + my_bool optimized; /* simple subselect is optimized */ + my_bool error; /* error in query */ enum Item_result res_type; int exec(); @@ -62,6 +64,7 @@ public: join= item->join; result= item->result; name= item->name; + error= item->error; } enum Type type() const; double val (); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 134e776a15a..496d21b333c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -931,6 +931,7 @@ void st_select_lex::init_select() use_index.empty(); ftfunc_list.empty(); linkage=UNSPECIFIED_TYPE; + depended= 0; } /* diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 876b9aa2743..32a98615390 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -208,6 +208,7 @@ private: SELECT_LEXs */ struct st_lex; +struct st_select_lex; struct st_select_lex_unit: public st_select_lex_node { /* Pointer to 'last' select or pointer to unit where stored @@ -218,6 +219,8 @@ struct st_select_lex_unit: public st_select_lex_node { ha_rows select_limit_cnt, offset_limit_cnt; void init_query(); bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result); + st_select_lex* first_select() { return (st_select_lex*) slave; } + st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; } private: bool create_total_list_n_last_return(THD *thd, st_lex *lex, TABLE_LIST ***result); @@ -240,9 +243,12 @@ struct st_select_lex: public st_select_lex_node { List ftfunc_list; uint in_sum_expr, sort_default; bool create_refs, - braces; /* SELECT ... UNION (SELECT ... ) <- this braces */ + braces, /* SELECT ... UNION (SELECT ... ) <- this braces */ + depended; /* depended from outer select subselect */ void init_query(); void init_select(); + st_select_lex* outer_select() { return (st_select_lex*) master->master; } + st_select_lex* next_select() { return (st_select_lex*) next; } }; typedef struct st_select_lex SELECT_LEX; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c5e5e971e33..115e5a058ed 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -213,7 +213,8 @@ JOIN::prepare(TABLE_LIST *tables_init, proc_param= proc_param_init; tables_list= tables_init; select_lex= select; - + union_part= (unit->first_select()->next_select() != 0); + /* Check that all tables, fields, conds and order are ok */ if (setup_tables(tables_list) || @@ -334,7 +335,6 @@ int JOIN::optimize() { DBUG_ENTER("JOIN::optimize"); - SELECT_LEX *select_lex = &(thd->lex.select_lex); #ifdef HAVE_REF_TO_FIELDS // Not done yet /* Add HAVING to WHERE if possible */ @@ -380,7 +380,7 @@ JOIN::optimize() } if (select_options & SELECT_DESCRIBE) { - if (select_lex->next) + if (union_part) select_describe(this, false, false, false, "Select tables optimized away"); else @@ -406,6 +406,17 @@ JOIN::optimize() if (make_join_statistics(this, tables_list, conds, &keyuse) || thd->fatal_error) DBUG_RETURN(-1); + + if (select_lex->depended) + { + /* + Just remove all const-table optimization in case of depended query + TODO: optimize + */ + const_table_map= 0; + const_tables= 0; + found_const_table_map= 0; + } thd->proc_info= "preparing"; result->initialize_tables(this); if (const_table_map != found_const_table_map && @@ -576,7 +587,7 @@ JOIN::optimize() } /* - global uptimisation (with subselect) must be here (TODO) + Global optimization (with subselect) must be here (TODO) */ int @@ -585,8 +596,25 @@ JOIN::global_optimize() return 0; } +int +JOIN::reinit() +{ + DBUG_ENTER("JOIN::reinit"); + //TODO move to unit reinit + unit->offset_limit_cnt =select_lex->offset_limit; + unit->select_limit_cnt =select_lex->select_limit+select_lex->offset_limit; + if (unit->select_limit_cnt < select_lex->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; // no limit + if (unit->select_limit_cnt == HA_POS_ERROR) + select_lex->options&= ~OPTION_FOUND_ROWS; + + if (setup_tables(tables_list)) + DBUG_RETURN(1); + DBUG_RETURN(0); +} + /* - exec select + Exec select */ void JOIN::exec() @@ -600,7 +628,7 @@ JOIN::exec() error=0; if (select_options & SELECT_DESCRIBE) { - if (select_lex->next) + if (union_part) select_describe(this, false, false, false, "No tables used"); else describe_info(thd, "No tables used"); @@ -627,7 +655,7 @@ JOIN::exec() if (zero_result_cause) { - if (select_options & SELECT_DESCRIBE && select_lex->next) + if (select_options & SELECT_DESCRIBE && union_part) select_describe(this, false, false, false, zero_result_cause); else error=return_zero_rows(result, tables_list, fields_list, diff --git a/sql/sql_select.h b/sql/sql_select.h index ba27c5b4b3b..84d4207bdb5 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -196,6 +196,8 @@ class JOIN :public Sql_alloc{ my_bool test_function_query; // need to return select items 1 row const char *zero_result_cause; // not 0 if exec must return zero result + + my_bool union_part; // this subselect is part of union JOIN(THD *thd, List &fields, ulong select_options, select_result *result): @@ -236,6 +238,7 @@ class JOIN :public Sql_alloc{ ORDER *proc_param, SELECT_LEX *select, SELECT_LEX_UNIT *unit); int optimize(); int global_optimize(); + int reinit(); void exec(); int cleanup(THD *thd); }; -- cgit v1.2.1 From 807b50855c4db0759aa93b84881c2559c24d01d4 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 27 May 2002 20:52:54 +0300 Subject: Hiding internal pointers of SELECT_LEX structures --- sql/item_subselect.cc | 2 +- sql/item_sum.cc | 2 +- sql/sql_derived.cc | 2 +- sql/sql_lex.cc | 13 +++++++------ sql/sql_lex.h | 44 +++++++++++++++++++++++++++++++++++--------- sql/sql_parse.cc | 10 +++++----- sql/sql_select.cc | 8 ++++---- sql/sql_union.cc | 2 +- sql/sql_yacc.yy | 18 +++++++++--------- 9 files changed, 64 insertions(+), 37 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index d71271b98fd..777e46ce6b0 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -108,7 +108,7 @@ bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables) (ORDER*) select_lex->group_list.first, select_lex->having, (ORDER*) 0, select_lex, - (SELECT_LEX_UNIT*) select_lex->master)) + select_lex->master_unit())) return 1; thd->lex.select= save_select; return 0; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 698f80928bb..a1ffae2ed82 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -965,7 +965,7 @@ bool Item_sum_count_distinct::setup(THD *thd) if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1, 0, 0, select_lex->options | thd->options, - (SELECT_LEX_UNIT*) select_lex->master))) + select_lex->master_unit()))) return 1; table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows table->no_rows=1; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 41f166c6ad0..4a64c30e7e5 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -34,7 +34,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) TODO: make derived tables with union inside (now only 1 SELECT may be procesed) */ - SELECT_LEX *sl= (SELECT_LEX*)unit->slave; + SELECT_LEX *sl= unit->first_select(); List item_list; TABLE *table; int res; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 496d21b333c..008ef44d83a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1021,18 +1021,19 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex, TABLE_LIST *slave_list_first=0, **slave_list_last= &slave_list_first; TABLE_LIST **new_table_list= *result, *aux; SELECT_LEX *sl= (SELECT_LEX*)slave; - for (; sl; sl= (SELECT_LEX*)sl->next) + for (; sl; sl= sl->next_select()) { // check usage of ORDER BY in union - if (sl->order_list.first && sl->next && !sl->braces) + if (sl->order_list.first && sl->next_select() && !sl->braces) { net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY"); return 1; } - if (sl->slave) - if (((SELECT_LEX_UNIT *) - sl->slave)->create_total_list_n_last_return(thd, lex, - &slave_list_last)) + for (SELECT_LEX_UNIT *inner= sl->first_inner_unit(); + inner; + inner= inner->next_unit()) + if (inner->create_total_list_n_last_return(thd, lex, + &slave_list_last)) return 1; if ((aux= (TABLE_LIST*) sl->table_list.first)) { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 22e682fef38..5c113e46a2b 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -186,11 +186,15 @@ enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, Base class for st_select_lex (SELECT_LEX) & st_select_lex_unit (SELECT_LEX_UNIT) */ -struct st_select_lex_node { - enum sub_select_type linkage; +class st_select_lex_node { +protected: st_select_lex_node *next, **prev, /* neighbor list */ *master, *slave, /* vertical links */ *link_next, **link_prev; /* list of whole SELECT_LEX */ +public: + ulong options; + enum sub_select_type linkage; + //uint sort_default; SQL_LIST order_list; /* ORDER clause */ ha_rows select_limit, offset_limit; /* LIMIT clause parameters */ void init_query(); @@ -207,9 +211,10 @@ private: SELECT_LEX_UNIT - unit of selects (UNION, INTERSECT, ...) group SELECT_LEXs */ -struct st_lex; -struct st_select_lex; -struct st_select_lex_unit: public st_select_lex_node { +class st_lex; +class st_select_lex; +class st_select_lex_unit: public st_select_lex_node { +public: /* Pointer to 'last' select or pointer to unit where stored global parameters for union @@ -219,8 +224,11 @@ struct st_select_lex_unit: public st_select_lex_node { ha_rows select_limit_cnt, offset_limit_cnt; void init_query(); bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result); + st_select_lex* outer_select() { return (st_select_lex*) master; } st_select_lex* first_select() { return (st_select_lex*) slave; } st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; } + + friend void mysql_init_query(THD *thd); private: bool create_total_list_n_last_return(THD *thd, st_lex *lex, TABLE_LIST ***result); @@ -230,10 +238,10 @@ typedef struct st_select_lex_unit SELECT_LEX_UNIT; /* SELECT_LEX - store information of parsed SELECT_LEX statment */ -struct st_select_lex: public st_select_lex_node { +class st_select_lex: public st_select_lex_node { +public: char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */ Item *where, *having; /* WHERE & HAVING clauses */ - ulong options; List expr_list; List when_list; /* WHEN clause */ SQL_LIST table_list, group_list; /* FROM & GROUP BY clauses */ @@ -241,14 +249,32 @@ struct st_select_lex: public st_select_lex_node { List interval_list, use_index, *use_index_ptr, ignore_index, *ignore_index_ptr; List ftfunc_list; - uint in_sum_expr, sort_default; + uint in_sum_expr; bool create_refs, braces, /* SELECT ... UNION (SELECT ... ) <- this braces */ depended; /* depended from outer select subselect */ void init_query(); void init_select(); - st_select_lex* outer_select() { return (st_select_lex*) master->master; } + st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; } + st_select_lex_unit* first_inner_unit() + { + return (st_select_lex_unit*) slave; + } + st_select_lex* outer_select() + { + return (st_select_lex*) master_unit()->outer_select(); + } st_select_lex* next_select() { return (st_select_lex*) next; } + st_select_lex* next_select_in_list() + { + return (st_select_lex*) link_next; + } + st_select_lex_node** next_select_in_list_addr() + { + return &link_next; + } + + friend void mysql_init_query(THD *thd); }; typedef struct st_select_lex SELECT_LEX; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8abd7a15bd4..6affc0199a5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -65,7 +65,7 @@ static void decrease_user_connections(UC *uc); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); static bool check_dup(const char *db, const char *name, TABLE_LIST *tables); -static void mysql_init_query(THD *thd); +void mysql_init_query(THD *thd); static void remove_escape(char *name); static void refresh_status(void); static bool append_file_to_dir(THD *thd, char **filename_ptr, @@ -1246,7 +1246,7 @@ mysql_execute_command(void) cursor)) DBUG_VOID_RETURN; } - if ((lex->select_lex.link_next && + if ((lex->select_lex.next_select_in_list() && lex->unit.create_total_list(thd, lex, &tables)) || (table_rules_on && tables && thd->slave_thread && !tables_ok(thd,tables))) @@ -2664,7 +2664,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize) Initialize global thd variables needed for query ****************************************************************************/ -static void +void mysql_init_query(THD *thd) { DBUG_ENTER("mysql_init_query"); @@ -2720,8 +2720,8 @@ mysql_new_select(LEX *lex, bool move_down) else select_lex->include_neighbour(lex->select); - ((SELECT_LEX_UNIT*)select_lex->master)->global_parameters= select_lex; - select_lex->include_global(&lex->select->link_next); + select_lex->master_unit()->global_parameters= select_lex; + select_lex->include_global(lex->select->next_select_in_list_addr()); lex->select= select_lex; return 0; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 60b092652aa..4748e857276 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -156,12 +156,12 @@ int handle_select(THD *thd, LEX *lex, select_result *result) { int res; register SELECT_LEX *select_lex = &lex->select_lex; - if (select_lex->link_next) + if (select_lex->next_select_in_list()) { /* Fix tables 'to-be-unioned-from' list to point at opened tables */ for (SELECT_LEX *sl= select_lex; sl; - sl= (SELECT_LEX*)sl->link_next) + sl= sl->next_select_in_list()) { for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; cursor; @@ -169,7 +169,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) cursor->table= cursor->table_list->table; } } - if (select_lex->next) + if (select_lex->next_select()) res=mysql_union(thd,lex,result); else res=mysql_select(thd,(TABLE_LIST*) select_lex->table_list.first, @@ -7275,7 +7275,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, result->send_error(0,NullS); } } - if (!join->thd->lex.select->next) + if (!join->thd->lex.select->next_select()) { save_lock=thd->lock; thd->lock=(MYSQL_LOCK *)0; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index b5db593a234..585b5de11ab 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -104,7 +104,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) } union_result->save_time_stamp=!describe; - for (sl= &lex->select_lex; sl; sl= (SELECT_LEX*) sl->next) + for (sl= &lex->select_lex; sl; sl= sl->next_select()) { lex->select=sl; unit->offset_limit_cnt= sl->offset_limit; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c5addfee15e..ebd26939ad5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1477,8 +1477,8 @@ select_init: SELECT_LEX * sel=Select; sel->braces=true; /* select in braces, can't contain global parameters */ - ((SELECT_LEX_UNIT*)sel->master)->global_parameters= - sel->master; + sel->master_unit()->global_parameters= + sel->master_unit(); } union_opt @@ -2186,8 +2186,8 @@ join_table: | '(' SELECT_SYM select_part3 ')' opt_table_alias { LEX *lex=Lex; - SELECT_LEX_UNIT *unit= (SELECT_LEX_UNIT*) lex->select->master; - lex->select= (SELECT_LEX*) unit->master; + SELECT_LEX_UNIT *unit= lex->select->master_unit(); + lex->select= unit->outer_select(); if (!($$= add_table_to_list(new Table_ident(unit), $5,0,TL_UNLOCK))) YYABORT; @@ -2325,7 +2325,7 @@ order_clause: LEX *lex=Lex; if (lex->sql_command == SQLCOM_MULTI_UPDATE) YYABORT; - lex->select->sort_default=1; + /*lex->select->sort_default=1;*/ } order_list order_list: @@ -3859,13 +3859,13 @@ optional_order_or_limit: LEX *lex=Lex; if (!lex->select->braces) YYABORT; - ((SELECT_LEX_UNIT*)lex->select->master)->global_parameters= - lex->select->master; + lex->select->master_unit()->global_parameters= + lex->select->master_unit(); /* Following type conversion looks like hack, but all that need SELECT_LEX fields always check linkage type. */ - lex->select= (SELECT_LEX*)lex->select->master; + lex->select= (SELECT_LEX*)lex->select->master_unit(); lex->select->select_limit=lex->thd->default_select_limit; } opt_order_clause limit_clause @@ -3898,5 +3898,5 @@ subselect_end: ')' { LEX *lex=Lex; - lex->select = (SELECT_LEX*)lex->select->master->master; + lex->select = lex->select->outer_select(); } -- cgit v1.2.1 From 0bef1099a224bacd2e95c976e19940bd1cdff21b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 May 2002 20:49:17 +0300 Subject: derived table with * bug fixed mysql-test/r/derived.result: derived table with * bug test suite mysql-test/t/derived.test: derived table with * bug test suite --- sql/sql_derived.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index f1b60dd9b84..af43c5dcd96 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -71,7 +71,7 @@ int mysql_derived(THD *thd, LEX *lex,SELECT_LEX *s, TABLE_LIST *t) } bzero((char*) &tmp_table_param,sizeof(tmp_table_param)); tmp_table_param.field_count=item_list.elements; - if (!(table=create_tmp_table(thd, &tmp_table_param, sl->item_list, + if (!(table=create_tmp_table(thd, &tmp_table_param, item_list, (ORDER*) 0, 0, 1, 0, (sl->options | thd->options | TMP_TABLE_ALL_COLUMNS)))) { -- cgit v1.2.1 From 3d9cd36f47649a5693695576d3e6fb9dfd6648d9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 May 2002 22:38:17 +0300 Subject: limit clause fixed --- sql/item_subselect.cc | 13 ++++++++++--- sql/sql_class.cc | 11 +++++++++-- sql/sql_parse.cc | 9 +++++---- 3 files changed, 24 insertions(+), 9 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 777e46ce6b0..72bbbcba5a7 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -24,7 +24,6 @@ SUBSELECT TODO: (sql_select.h/sql_select.cc) - add subselect union select (sql_union.cc) - - depended from outer select subselects */ @@ -41,6 +40,14 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex): DBUG_ENTER("Item_subselect::Item_subselect"); DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex)); result= new select_subselect(this); + SELECT_LEX_UNIT *unit= select_lex->master_unit(); + unit->offset_limit_cnt= unit->global_parameters->offset_limit; + unit->select_limit_cnt= unit->global_parameters->select_limit+ + select_lex->offset_limit; + if (unit->select_limit_cnt < unit->global_parameters->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; // no limit + if (unit->select_limit_cnt == HA_POS_ERROR) + select_lex->options&= ~OPTION_FOUND_ROWS; join= new JOIN(thd, select_lex->item_list, select_lex->options, result); this->select_lex= select_lex; maybe_null= 1; @@ -141,9 +148,9 @@ int Item_subselect::exec() join->thd->lex.select= select_lex; join->exec(); join->thd->lex.select= save_select; - if (!executed) + //if (!executed) //No rows returned => value is null (returned as inited) - executed= 1; + // executed= 1; return join->error; } return 0; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 751e4d25d41..975d36069f9 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -784,9 +784,15 @@ select_subselect::select_subselect(Item_subselect *item) bool select_subselect::send_data(List &items) { + DBUG_ENTER("select_subselect::send_data"); if (item->executed){ my_printf_error(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0)); - return 1; + DBUG_RETURN(1); + } + if (unit->offset_limit_cnt) + { // using limit offset,count + unit->offset_limit_cnt--; + DBUG_RETURN(0); } Item *val_item= (Item *)item->select_lex->item_list.head(); if ((item->null_value= val_item->is_null())) @@ -801,5 +807,6 @@ bool select_subselect::send_data(List &items) item->real_value= val_item->val(); item->res_type= val_item->result_type(); } - return 0; + item->executed= 1; + DBUG_RETURN(0); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6affc0199a5..3492854329a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1275,9 +1275,10 @@ mysql_execute_command(void) break; // Error message is given } - unit->offset_limit_cnt =select_lex->offset_limit; - unit->select_limit_cnt =select_lex->select_limit+select_lex->offset_limit; - if (unit->select_limit_cnt < select_lex->select_limit) + unit->offset_limit_cnt= unit->global_parameters->offset_limit; + unit->select_limit_cnt= unit->global_parameters->select_limit+ + unit->global_parameters->offset_limit; + if (unit->select_limit_cnt < unit->global_parameters->select_limit) unit->select_limit_cnt= HA_POS_ERROR; // no limit if (unit->select_limit_cnt == HA_POS_ERROR) select_lex->options&= ~OPTION_FOUND_ROWS; @@ -2672,7 +2673,7 @@ mysql_init_query(THD *thd) thd->lex.unit.init_select(); thd->lex.select_lex.init_query(); thd->lex.unit.slave= &thd->lex.select_lex; - thd->lex.unit.select_limit= thd->default_select_limit; //Global limit + thd->lex.unit.global_parameters= &thd->lex.select_lex; //Global limit & order thd->lex.select_lex.master= &thd->lex.unit; thd->lex.select_lex.prev= &thd->lex.unit.slave; thd->lex.value_list.empty(); -- cgit v1.2.1 From 58e4105b62cbc8080a67fc9f6e6f9c9de75142af Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 31 May 2002 21:04:47 +0500 Subject: Added filling of unicode mapping arrays during charset.conf loading All charset.conf files were extended to supply unicode mapping array CONVERT() now uses more common order of arguments: CONVERT(expr,charset_from,charset_to) Dynamic charset can be used as CONVERT() argument mysys/charset.c: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/armscii8.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/cp1251.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/cp1257.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/croat.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/danish.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/dec8.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/dos.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/estonia.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/german1.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/greek.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/hebrew.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/hp8.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/hungarian.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/koi8_ru.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/koi8_ukr.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/latin1.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/latin2.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/latin5.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/swe7.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/usa7.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/win1250.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/win1251.conf: Added filling of unicode mapping arrays during charset.conf loading sql/share/charsets/win1251ukr.conf: Added filling of unicode mapping arrays during charset.conf loading sql/sql_yacc.yy: Changed the order of arguments to Convert(expr,charset_from,charset_to) Dynamic charsets are now resolved too for Convert() arguments --- sql/share/charsets/armscii8.conf | 19 +++++++++++++++++++ sql/share/charsets/cp1251.conf | 19 +++++++++++++++++++ sql/share/charsets/cp1257.conf | 18 ++++++++++++++++++ sql/share/charsets/croat.conf | 18 ++++++++++++++++++ sql/share/charsets/danish.conf | 18 ++++++++++++++++++ sql/share/charsets/dec8.conf | 19 +++++++++++++++++++ sql/share/charsets/dos.conf | 19 +++++++++++++++++++ sql/share/charsets/estonia.conf | 18 ++++++++++++++++++ sql/share/charsets/german1.conf | 18 ++++++++++++++++++ sql/share/charsets/greek.conf | 18 ++++++++++++++++++ sql/share/charsets/hebrew.conf | 18 ++++++++++++++++++ sql/share/charsets/hp8.conf | 19 +++++++++++++++++++ sql/share/charsets/hungarian.conf | 18 ++++++++++++++++++ sql/share/charsets/koi8_ru.conf | 19 +++++++++++++++++++ sql/share/charsets/koi8_ukr.conf | 18 ++++++++++++++++++ sql/share/charsets/latin1.conf | 18 ++++++++++++++++++ sql/share/charsets/latin2.conf | 18 ++++++++++++++++++ sql/share/charsets/latin5.conf | 18 ++++++++++++++++++ sql/share/charsets/swe7.conf | 18 ++++++++++++++++++ sql/share/charsets/usa7.conf | 18 ++++++++++++++++++ sql/share/charsets/win1250.conf | 18 ++++++++++++++++++ sql/share/charsets/win1251.conf | 18 ++++++++++++++++++ sql/share/charsets/win1251ukr.conf | 18 ++++++++++++++++++ sql/sql_yacc.yy | 4 ++-- 24 files changed, 422 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/share/charsets/armscii8.conf b/sql/share/charsets/armscii8.conf index 15c232c7e94..54d2d0fec47 100644 --- a/sql/share/charsets/armscii8.conf +++ b/sql/share/charsets/armscii8.conf @@ -72,3 +72,22 @@ D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 2741 00A7 0589 0029 0028 00BB 00AB 2014 002E 055D 002C 002D 055F 2026 055C +055B 055E 0531 0561 0532 0562 0533 0563 0534 0564 0535 0565 0536 0566 0537 0567 +0538 0568 0539 0569 053A 056A 053B 056B 053C 056C 053D 056D 053E 056E 053F 056F +0540 0570 0541 0571 0542 0572 0543 0573 0544 0574 0545 0575 0546 0576 0547 0577 +0548 0578 0549 0579 054A 057A 054B 057B 054C 057C 054D 057D 054E 057E 054F 057F +0550 0580 0551 0581 0552 0582 0553 0583 0554 0584 0555 0585 0556 0586 2019 0027 diff --git a/sql/share/charsets/cp1251.conf b/sql/share/charsets/cp1251.conf index 6af97c891b8..4418bf48289 100644 --- a/sql/share/charsets/cp1251.conf +++ b/sql/share/charsets/cp1251.conf @@ -72,3 +72,22 @@ 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 5B 5C 5D 5E 5F 60 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B + + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0402 0403 201A 0453 201E 2026 2020 2021 003F 2030 0409 2039 040A 040C 040B 040F +0452 2018 2019 201C 201D 2022 2013 2014 003F 2122 0459 203A 045A 045C 045B 045F +00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 +00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 +0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F +0420 0421 0422 0423 0424 0425 0426 0427 0428 0429 042A 042B 042C 042D 042E 042F +0430 0431 0432 0433 0434 0435 0436 0437 0438 0439 043A 043B 043C 043D 043E 043F +0440 0441 0442 0443 0444 0445 0446 0447 0448 0449 044A 044B 044C 044D 044E 044F diff --git a/sql/share/charsets/cp1257.conf b/sql/share/charsets/cp1257.conf index 610ed5a646f..b0e89bb67c4 100644 --- a/sql/share/charsets/cp1257.conf +++ b/sql/share/charsets/cp1257.conf @@ -72,3 +72,21 @@ 5A FF FF FF FF FF FF FF 5E FF FF 5D FF FF FF FF FF 4F FF FF FF FF 48 FF 45 FF FF 49 FF FF FF FF 5A FF FF FF FF FF FF FF 5E FF FF 5D FF FF FF FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +20AC 003F 201A 003F 201E 2026 2020 2021 003F 2030 003F 2039 003F 00A8 02C7 00B8 +003F 2018 2019 201C 201D 2022 2013 2014 003F 2122 003F 203A 003F 00AF 02DB 003F +00A0 003F 00A2 00A3 00A4 003F 00A6 00A7 00D8 00A9 0156 00AB 00AC 00AD 00AE 00C6 +00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00F8 00B9 0157 00BB 00BC 00BD 00BE 00E6 +0104 012E 0100 0106 00C4 00C5 0118 0112 010C 00C9 0179 0116 0122 0136 012A 013B +0160 0143 0145 00D3 014C 00D5 00D6 00D7 0172 0141 015A 016A 00DC 017B 017D 00DF +0105 012F 0101 0107 00E4 00E5 0119 0113 010D 00E9 017A 0117 0123 0137 012B 013C +0161 0144 0146 00F3 014D 00F5 00F6 00F7 0173 0142 015B 016B 00FC 017C 017E 02D9 diff --git a/sql/share/charsets/croat.conf b/sql/share/charsets/croat.conf index fbbe3328547..bc8c1a376eb 100644 --- a/sql/share/charsets/croat.conf +++ b/sql/share/charsets/croat.conf @@ -72,3 +72,21 @@ 47 4E 4F 4F 4F 4F 5D D7 D8 55 55 55 59 59 DE DF 41 41 41 41 5C 5B 45 43 44 45 45 45 49 49 49 49 47 4E 4F 4F 4F 4F 5D F7 D8 55 55 55 59 59 DE FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 0104 02D8 0141 00A4 013D 015A 00A7 00A8 0160 015E 0164 0179 00AD 017D 017B +00B0 0105 02DB 0142 00B4 013E 015B 02C7 00B8 0161 015F 0165 017A 02DD 017E 017C +0154 00C1 00C2 0102 00C4 0139 0106 00C7 010C 00C9 0118 00CB 011A 00CD 00CE 010E +0110 0143 0147 00D3 00D4 0150 00D6 00D7 0158 016E 00DA 0170 00DC 00DD 0162 00DF +0155 00E1 00E2 0103 00E4 013A 0107 00E7 010D 00E9 0119 00EB 011B 00ED 00EE 010F +0111 0144 0148 00F3 00F4 0151 00F6 00F7 0159 016F 00FA 0171 00FC 00FD 0163 02D9 diff --git a/sql/share/charsets/danish.conf b/sql/share/charsets/danish.conf index f99590ed6f3..1543a64d7c3 100644 --- a/sql/share/charsets/danish.conf +++ b/sql/share/charsets/danish.conf @@ -72,3 +72,21 @@ 44 4E 4F 4F 4F 4F 5C D7 5C 55 55 55 59 59 DE DF 41 41 41 41 5B 5D 5B 43 45 45 45 45 49 49 49 49 44 4E 4F 4F 4F 4F 5C F7 5C 55 55 55 59 59 DE FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF +00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF +00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF +00D0 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 00DD 00DE 00DF +00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF +00F0 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 00FD 00FE 00FF diff --git a/sql/share/charsets/dec8.conf b/sql/share/charsets/dec8.conf index a4849aaa04c..87af7071f8c 100644 --- a/sql/share/charsets/dec8.conf +++ b/sql/share/charsets/dec8.conf @@ -72,3 +72,22 @@ 44 4E 4F 4F 4F 4F 5D D7 D8 55 55 55 59 59 DE DF 41 41 41 41 5C 5B 5C 43 45 45 45 45 49 49 49 49 44 4E 4F 4F 4F 4F 5D F7 D8 55 55 55 59 59 DE FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 00A1 00A2 00A3 003F 00A5 003F 00A7 00A4 00A9 00AA 00AB 003F 003F 003F 003F +00B0 00B1 00B2 00B3 003F 00B5 00B6 00B7 003F 00B9 00BA 00BB 00BC 00BD 003F 00BF +00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF +003F 00D1 00D2 00D3 00D4 00D5 00D6 0152 00D8 00D9 00DA 00DB 00DC 0178 003F 00DF +00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF +003F 00F1 00F2 00F3 00F4 00F5 00F6 0153 00F8 00F9 00FA 00FB 00FC 00FF 003F 003F + diff --git a/sql/share/charsets/dos.conf b/sql/share/charsets/dos.conf index dda86d0f3e8..fc4d4cee5c4 100644 --- a/sql/share/charsets/dos.conf +++ b/sql/share/charsets/dos.conf @@ -72,3 +72,22 @@ D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (256 elements) + +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000a 000b 000c 000d 000e 000f +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001a 001b 001c 001d 001e 001f +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002a 002b 002c 002d 002e 002f +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003a 003b 003c 003d 003e 003f +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004a 004b 004c 004d 004e 004f +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005a 005b 005c 005d 005e 005f +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006a 006b 006c 006d 006e 006f +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007a 007b 007c 007d 007e 007f +00c7 00fc 00e9 00e2 00e4 00e0 00e5 00e7 00ea 00eb 00e8 00ef 00ee 00ec 00c4 00c5 +00c9 00e6 00c6 00f4 00f6 00f2 00fb 00f9 00ff 00d6 00dc 00a2 00a3 00a5 20a7 0192 +00e1 00ed 00f3 00fa 00f1 00d1 00aa 00ba 00bf 2310 00ac 00bd 00bc 00a1 00ab 00bb +2591 2592 2593 2502 2524 2561 2562 2556 2555 2563 2551 2557 255d 255c 255b 2510 +2514 2534 252c 251c 2500 253c 255e 255f 255a 2554 2569 2566 2560 2550 256c 2567 +2568 2564 2565 2559 2558 2552 2553 256b 256a 2518 250c 2588 2584 258c 2590 2580 +03b1 00df 0393 03c0 03a3 03c3 00b5 03c4 03a6 0398 03a9 03b4 221e 03c6 03b5 2229 +2261 00b1 2265 2264 2320 2321 00f7 2248 00b0 2219 00b7 221a 207f 00b2 25a0 00a0 diff --git a/sql/share/charsets/estonia.conf b/sql/share/charsets/estonia.conf index 76bbc021b0c..0226fd1fe82 100644 --- a/sql/share/charsets/estonia.conf +++ b/sql/share/charsets/estonia.conf @@ -72,3 +72,21 @@ DB C2 C4 C8 CA F2 F6 64 EC BC D8 EA F8 E1 E3 DA 8D B1 89 95 F5 8B A3 A1 97 9D E0 9F A9 B7 AF BB DC C3 C5 C9 CB F3 F7 65 ED BD D9 EB F9 E2 E4 53 + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 201D 00A2 00A3 00A4 201E 00A6 00A7 00D8 00A9 0156 00AB 00AC 00AD 00AE 00C6 +00B0 00B1 00B2 00B3 201C 00B5 00B6 00B7 00F8 00B9 0157 00BB 00BC 00BD 00BE 00E6 +0104 012E 0100 0106 00C4 00C5 0118 0112 010C 00C9 0179 0116 0122 0136 012A 013B +0160 0143 0145 00D3 014C 00D5 00D6 00D7 0172 0141 015A 016A 00DC 017B 017D 00DF +0105 012F 0101 0107 00E4 00E5 0119 0113 010D 00E9 017A 0117 0123 0137 012B 013C +0161 0144 0146 00F3 014D 00F5 00F6 00F7 0173 0142 015B 016B 00FC 017C 017E 2019 diff --git a/sql/share/charsets/german1.conf b/sql/share/charsets/german1.conf index 3090c921ebe..64f27da3499 100644 --- a/sql/share/charsets/german1.conf +++ b/sql/share/charsets/german1.conf @@ -72,3 +72,21 @@ D0 4E 4F 4F 4F 4F 4F D7 4F 55 55 55 55 59 DE 53 41 41 41 41 41 41 41 43 45 45 45 45 49 49 49 49 D0 4E 4F 4F 4F 4F 4F F7 4F 55 55 55 55 59 DE FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF +00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF +00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF +00D0 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 00DD 00DE 00DF +00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF +00F0 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 00FD 00FE 00FF diff --git a/sql/share/charsets/greek.conf b/sql/share/charsets/greek.conf index 73d67d6ee71..3b5108b561b 100644 --- a/sql/share/charsets/greek.conf +++ b/sql/share/charsets/greek.conf @@ -72,3 +72,21 @@ D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 C9 D5 C1 C5 C7 C9 D5 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D3 D3 D4 D5 D6 D7 D8 D9 C9 D5 CF D5 D9 FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 02BD 02BC 00A3 003F 003F 00A6 00A7 00A8 00A9 003F 00AB 00AC 00AD 003F 2015 +00B0 00B1 00B2 00B3 0384 0385 0386 00B7 0388 0389 038A 00BB 038C 00BD 038E 038F +0390 0391 0392 0393 0394 0395 0396 0397 0398 0399 039A 039B 039C 039D 039E 039F +03A0 03A1 003F 03A3 03A4 03A5 03A6 03A7 03A8 03A9 03AA 03AB 03AC 03AD 03AE 03AF +03B0 03B1 03B2 03B3 03B4 03B5 03B6 03B7 03B8 03B9 03BA 03BB 03BC 03BD 03BE 03BF +03C0 03C1 03C2 03C3 03C4 03C5 03C6 03C7 03C8 03C9 03CA 03CB 03CC 03CD 03CE 003F diff --git a/sql/share/charsets/hebrew.conf b/sql/share/charsets/hebrew.conf index 6a5f88eb228..0475db02b24 100644 --- a/sql/share/charsets/hebrew.conf +++ b/sql/share/charsets/hebrew.conf @@ -72,3 +72,21 @@ D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 003F 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00D7 00AB 00AC 00AD 00AE 203E +00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00F7 00BB 00BC 00BD 00BE 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 2017 +05D0 05D1 05D2 05D3 05D4 05D5 05D6 05D7 05D8 05D9 05DA 05DB 05DC 05DD 05DE 05DF +05E0 05E1 05E2 05E3 05E4 05E5 05E6 05E7 05E8 05E9 05EA 003F 003F 003F 003F 003F diff --git a/sql/share/charsets/hp8.conf b/sql/share/charsets/hp8.conf index e9fadacbf76..d0fd37f5f24 100644 --- a/sql/share/charsets/hp8.conf +++ b/sql/share/charsets/hp8.conf @@ -72,3 +72,22 @@ D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 00C0 00C2 00C8 00CA 00CB 00CE 00CF 00B4 02CB 02C6 00A8 02DC 00D9 00DB 20A4 +00AF 00DD 00FD 00B0 00C7 00E7 00D1 00F1 00A1 00BF 00A4 00A3 00A5 00A7 0192 00A2 +00E2 00EA 00F4 00FB 00E1 00E9 00F3 00FA 00E0 00E8 00F2 00F9 00E4 00EB 00F6 00FC +00C5 00EE 00D8 00C6 00E5 00ED 00F8 00E6 00C4 00EC 00D6 00DC 00C9 00EF 00DF 00D4 +00C1 00C3 00E3 00D0 00F0 00CD 00CC 00D3 00D2 00D5 00F5 0160 0161 00DA 0178 00FF +00DE 00FE 00B7 00B5 00B6 00BE 2014 00BC 00BD 00AA 00BA 00AB 25A0 00BB 00B1 003F + diff --git a/sql/share/charsets/hungarian.conf b/sql/share/charsets/hungarian.conf index db58d62575f..dffaff9348d 100644 --- a/sql/share/charsets/hungarian.conf +++ b/sql/share/charsets/hungarian.conf @@ -72,3 +72,21 @@ FF 62 63 64 66 67 67 FF 6D 77 75 78 78 7E 74 FF 64 41 44 45 46 5F 49 4B 4A 4E 51 78 50 56 58 4D FF 62 63 64 66 67 67 FF 6D 77 75 78 78 7E 74 FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 0104 02D8 0141 00A4 013D 015A 00A7 00A8 0160 015E 0164 0179 00AD 017D 017B +00B0 0105 02DB 0142 00B4 013E 015B 02C7 00B8 0161 015F 0165 017A 02DD 017E 017C +0154 00C1 00C2 0102 00C4 0139 0106 00C7 010C 00C9 0118 00CB 011A 00CD 00CE 010E +0110 0143 0147 00D3 00D4 0150 00D6 00D7 0158 016E 00DA 0170 00DC 00DD 0162 00DF +0155 00E1 00E2 0103 00E4 013A 0107 00E7 010D 00E9 0119 00EB 011B 00ED 00EE 010F +0111 0144 0148 00F3 00F4 0151 00F6 00F7 0159 016F 00FA 0171 00FC 00FD 0163 02D9 diff --git a/sql/share/charsets/koi8_ru.conf b/sql/share/charsets/koi8_ru.conf index 4cfee67a236..b1d9755173f 100644 --- a/sql/share/charsets/koi8_ru.conf +++ b/sql/share/charsets/koi8_ru.conf @@ -72,3 +72,22 @@ EF FF F0 F1 F2 F3 E6 E1 FC FB E7 F8 FD F9 F7 FA FE DF E0 F6 E3 E4 F4 E2 F5 E8 E9 EA EB EC ED EE EF FF F0 F1 F2 F3 E6 E1 FC FB E7 F8 FD F9 F7 FA + +# Unicode mapping table (256 elements) + +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000a 000b 000c 000d 000e 000f +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001a 001b 001c 001d 001e 001f +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002a 002b 002c 002d 002e 002f +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003a 003b 003c 003d 003e 003f +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004a 004b 004c 004d 004e 004f +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005a 005b 005c 005d 005e 005f +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006a 006b 006c 006d 006e 006f +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007a 007b 007c 007d 007e 007f +2500 2502 250c 2510 2514 2518 251c 2524 252c 2534 253c 2580 2584 2588 258c 2590 +2591 2592 2593 2320 25a0 2219 221a 2248 2264 2265 00a0 2321 00b0 00b2 00b7 00f7 +2550 2551 2552 0451 2553 2554 2555 2556 2557 2558 2559 255a 255b 255c 255d 255e +255f 2560 2561 0401 2562 2563 2564 2565 2566 2567 2568 2569 256a 256b 256c 00a9 +044e 0430 0431 0446 0434 0435 0444 0433 0445 0438 0439 043a 043b 043c 043d 043e +043f 044f 0440 0441 0442 0443 0436 0432 044c 044b 0437 0448 044d 0449 0447 044a +042e 0410 0411 0426 0414 0415 0424 0413 0425 0418 0419 041a 041b 041c 041d 041e +041f 042f 0420 0421 0422 0423 0416 0412 042c 042b 0417 0428 042d 0429 0427 042a diff --git a/sql/share/charsets/koi8_ukr.conf b/sql/share/charsets/koi8_ukr.conf index 3e2c8e27325..5a552900544 100644 --- a/sql/share/charsets/koi8_ukr.conf +++ b/sql/share/charsets/koi8_ukr.conf @@ -72,3 +72,21 @@ 94 A4 95 96 97 98 89 82 A1 A0 8A 9D A2 9E 9C 9F A3 80 81 9B 85 86 99 83 9A 8B 8E 8F 90 91 92 93 94 A4 95 96 97 98 89 82 A1 A0 8A 9D A2 9E 9C 9F + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +2500 2502 250C 2510 2514 2518 251C 2524 252C 2534 253C 2580 2584 2588 258C 2590 +2591 2592 2593 2320 25A0 2022 221A 2248 2264 2265 00A0 2321 00B0 00B2 00B7 00F7 +2550 2551 2552 0451 0454 2554 0456 0457 2557 2558 2559 255A 255B 0491 255D 255E +255F 2560 2561 0401 0404 2563 0406 0407 2566 2567 2568 2569 256A 0490 256C 00A9 +044E 0430 0431 0446 0434 0435 0444 0433 0445 0438 0439 043A 043B 043C 043D 043E +043F 044F 0440 0441 0442 0443 0436 0432 044C 044B 0437 0448 044D 0449 0447 044A +042E 0410 0411 0426 0414 0415 0424 0413 0425 0418 0419 041A 041B 041C 041D 041E +041F 042F 0420 0421 0422 0423 0416 0412 042C 042B 0417 0428 042D 0429 0427 042A diff --git a/sql/share/charsets/latin1.conf b/sql/share/charsets/latin1.conf index cf974aefa14..7cb5cfb3cfd 100644 --- a/sql/share/charsets/latin1.conf +++ b/sql/share/charsets/latin1.conf @@ -72,3 +72,21 @@ 44 4E 4F 4F 4F 4F 5D D7 D8 55 55 55 59 59 DE DF 41 41 41 41 5C 5B 5C 43 45 45 45 45 49 49 49 49 44 4E 4F 4F 4F 4F 5D F7 D8 55 55 55 59 59 DE FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF +00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF +00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF +00D0 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 00DD 00DE 00DF +00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF +00F0 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 00FD 00FE 00FF diff --git a/sql/share/charsets/latin2.conf b/sql/share/charsets/latin2.conf index cc18c22c0a2..cc21af9faa1 100644 --- a/sql/share/charsets/latin2.conf +++ b/sql/share/charsets/latin2.conf @@ -72,3 +72,21 @@ FF 55 54 57 56 56 56 FF 5A 5F 5F 5F 5F 63 5E FF 5A 43 43 43 43 51 46 45 47 49 4A 49 49 4E 4E 48 FF 55 54 57 56 56 56 FF 5A 5F 5F 5F 5F 63 5E FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 0104 02D8 0141 00A4 013D 015A 00A7 00A8 0160 015E 0164 0179 00AD 017D 017B +00B0 0105 02DB 0142 00B4 013E 015B 02C7 00B8 0161 015F 0165 017A 02DD 017E 017C +0154 00C1 00C2 0102 00C4 0139 0106 00C7 010C 00C9 0118 00CB 011A 00CD 00CE 010E +0110 0143 0147 00D3 00D4 0150 00D6 00D7 0158 016E 00DA 0170 00DC 00DD 0162 00DF +0155 00E1 00E2 0103 00E4 013A 0107 00E7 010D 00E9 0119 00EB 011B 00ED 00EE 010F +0111 0144 0148 00F3 00F4 0151 00F6 00F7 0159 016F 00FA 0171 00FC 00FD 0163 02D9 diff --git a/sql/share/charsets/latin5.conf b/sql/share/charsets/latin5.conf index 92fbd2299bb..d603d019ce6 100644 --- a/sql/share/charsets/latin5.conf +++ b/sql/share/charsets/latin5.conf @@ -76,3 +76,21 @@ 49 DB DC DD DE DF 53 E0 E1 E2 E3 E4 5B 4C 58 E5 CC CD CE CF D0 D1 D2 44 D3 D4 D5 D6 D7 D8 D9 DA 49 DB DC DD DE DF 53 FA E1 E2 E3 E4 5B 4B 58 FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF +00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF +00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF +011E 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 0130 015E 00DF +00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF +011F 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 0131 015F 00FF diff --git a/sql/share/charsets/swe7.conf b/sql/share/charsets/swe7.conf index d2de48b4d1c..c68593a351c 100644 --- a/sql/share/charsets/swe7.conf +++ b/sql/share/charsets/swe7.conf @@ -72,3 +72,21 @@ D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +00C9 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 00C4 00D6 00C5 00DC 005F +00E9 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 00E4 00F6 00E5 00FC 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F diff --git a/sql/share/charsets/usa7.conf b/sql/share/charsets/usa7.conf index b9e7a44c894..45e260870ba 100644 --- a/sql/share/charsets/usa7.conf +++ b/sql/share/charsets/usa7.conf @@ -72,3 +72,21 @@ D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F diff --git a/sql/share/charsets/win1250.conf b/sql/share/charsets/win1250.conf index 31d253d7381..abe0a9a8702 100644 --- a/sql/share/charsets/win1250.conf +++ b/sql/share/charsets/win1250.conf @@ -72,3 +72,21 @@ 47 53 53 55 55 55 55 D7 58 5C 5C 5C 5C 60 5B 59 58 41 41 41 41 50 45 43 44 49 49 49 49 4D 4D 46 47 53 53 55 55 55 55 F7 58 5C 5C 5C 5C 60 5B FF + +# Unicode mapping table (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +20AC 003F 201A 003F 201E 2026 2020 2021 003F 2030 0160 2039 015A 0164 017D 0179 +003F 2018 2019 201C 201D 2022 2013 2014 003F 2122 0161 203A 015B 0165 017E 017A +00A0 02C7 02D8 0141 00A4 0104 00A6 00A7 00A8 00A9 015E 00AB 00AC 00AD 00AE 017B +00B0 00B1 02DB 0142 00B4 00B5 00B6 00B7 00B8 0105 015F 00BB 013D 02DD 013E 017C +0154 00C1 00C2 0102 00C4 0139 0106 00C7 010C 00C9 0118 00CB 011A 00CD 00CE 010E +0110 0143 0147 00D3 00D4 0150 00D6 00D7 0158 016E 00DA 0170 00DC 00DD 0162 00DF +0155 00E1 00E2 0103 00E4 013A 0107 00E7 010D 00E9 0119 00EB 011B 00ED 00EE 010F +0111 0144 0148 00F3 00F4 0151 00F6 00F7 0159 016F 00FA 0171 00FC 00FD 0163 02D9 diff --git a/sql/share/charsets/win1251.conf b/sql/share/charsets/win1251.conf index a5ccc3190ad..55f688f59b9 100644 --- a/sql/share/charsets/win1251.conf +++ b/sql/share/charsets/win1251.conf @@ -80,3 +80,21 @@ D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 C0 C1 C2 C3 C4 C5 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0402 0403 201A 0453 201E 2026 2020 2021 003F 2030 0409 2039 040A 040C 040B 040F +0452 2018 2019 201C 201D 2022 2013 2014 003F 2122 0459 203A 045A 045C 045B 045F +00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 +00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 +0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F +0420 0421 0422 0423 0424 0425 0426 0427 0428 0429 042A 042B 042C 042D 042E 042F +0430 0431 0432 0433 0434 0435 0436 0437 0438 0439 043A 043B 043C 043D 043E 043F +0440 0441 0442 0443 0444 0445 0446 0447 0448 0449 044A 044B 044C 044D 044E 044F diff --git a/sql/share/charsets/win1251ukr.conf b/sql/share/charsets/win1251ukr.conf index e693958910e..2fbab363e5e 100644 --- a/sql/share/charsets/win1251ukr.conf +++ b/sql/share/charsets/win1251ukr.conf @@ -75,3 +75,21 @@ 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 80 81 82 83 85 86 89 8A 8B 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0402 0403 201A 0453 201E 2026 2020 2021 003F 2030 0409 2039 040A 040C 040B 040F +0452 2018 2019 201C 201D 2022 2013 2014 003F 2122 0459 203A 045A 045C 045B 045F +00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 +00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 +0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F +0420 0421 0422 0423 0424 0425 0426 0427 0428 0429 042A 042B 042C 042D 042E 042F +0430 0431 0432 0433 0434 0435 0436 0437 0438 0439 043A 043B 043C 043D 043E 043F +0440 0441 0442 0443 0444 0445 0446 0447 0448 0449 044A 044B 044C 044D 044E 044F diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 756afbd7a09..61d97cb43f2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1718,7 +1718,7 @@ simple_expr: | CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); } | CONVERT_SYM '(' expr USING IDENT ')' { - CHARSET_INFO *cs=find_compiled_charset_by_name($5.str); + CHARSET_INFO *cs=get_charset_by_name($5.str,MYF(MY_WME)); if (!cs) { net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$5); @@ -1728,7 +1728,7 @@ simple_expr: } | CONVERT_SYM '(' expr ',' expr ',' expr ')' { - $$= new Item_func_conv_charset3($3,$5,$7); + $$= new Item_func_conv_charset3($3,$7,$5); } | FUNC_ARG0 '(' ')' { $$= ((Item*(*)(void))($1.symbol->create_func))();} -- cgit v1.2.1 From a532bfb2ea0a0d1cfc0c8d25e6a18cf5a8c0c5bc Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 1 Jun 2002 23:35:36 +0300 Subject: new subselect tests LIMIT fixed AVG & STD with subselect fixed join_free fixed to be depended queries compatible sort_default removed from SELECT_LEX mysql-test/r/subselect.result: new subselect tests mysql-test/t/subselect.test: new subselect tests sql/item.cc: marking as depended _ALL_ subselects under select from wich depend sql/item_subselect.cc: limit fixed TODO added sql/sql_class.cc: AVG & STD function with subselects fixed sql/sql_lex.h: sort_default removed sql/sql_parse.cc: limit fixed sql/sql_select.cc: fixed to be subselect compatible sql/sql_yacc.yy: sort_default removed --- sql/item.cc | 29 +++++++++++++++++++---------- sql/item_subselect.cc | 6 ++---- sql/sql_class.cc | 11 ++++++++--- sql/sql_lex.h | 1 - sql/sql_parse.cc | 10 +++++----- sql/sql_select.cc | 7 +++++-- sql/sql_yacc.yy | 1 - 7 files changed, 39 insertions(+), 26 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 8a785ee3902..45564bcd98e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -330,23 +330,32 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) mention of table name, but if we join tables in one list it will cause error ER_NON_UNIQ_ERROR in find_field_in_tables. */ + SELECT_LEX *last; for (SELECT_LEX *sl= thd->lex.select->outer_select(); sl && !tmp; sl= sl->outer_select()) tmp=find_field_in_tables(thd, this, - (TABLE_LIST*)sl->table_list.first); + (TABLE_LIST*)(last= sl)->table_list.first); if (!tmp) return 1; else - if( !thd->lex.select->depended ) - { - thd->lex.select->depended= 1; //Select is depended of outer select(s) - //Tables will be reopened many times - for (TABLE_LIST *tbl= (TABLE_LIST*)thd->lex.select->table_list.first; - tbl; - tbl= tbl->next) - tbl->shared= 1; - } + /* + Mark all selects from resolved to 1 before select where was + found table as depended (of select where was found table) + */ + for (SELECT_LEX *s= thd->lex.select; + s &&s != last; + s= s->outer_select()) + if( !s->depended ) + { + s->depended= 1; //Select is depended of outer select + //Tables will be reopened many times + for (TABLE_LIST *tbl= + (TABLE_LIST*)s->table_list.first; + tbl; + tbl= tbl->next) + tbl->shared= 1; + } } set_field(tmp); } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 72bbbcba5a7..e18c8d78830 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -23,6 +23,7 @@ SUBSELECT TODO: - remove double 'having' & 'having_list' from JOIN (sql_select.h/sql_select.cc) + - subselect in HAVING clause - add subselect union select (sql_union.cc) */ @@ -43,7 +44,7 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex): SELECT_LEX_UNIT *unit= select_lex->master_unit(); unit->offset_limit_cnt= unit->global_parameters->offset_limit; unit->select_limit_cnt= unit->global_parameters->select_limit+ - select_lex->offset_limit; + unit->global_parameters ->offset_limit; if (unit->select_limit_cnt < unit->global_parameters->select_limit) unit->select_limit_cnt= HA_POS_ERROR; // no limit if (unit->select_limit_cnt == HA_POS_ERROR) @@ -148,9 +149,6 @@ int Item_subselect::exec() join->thd->lex.select= select_lex; join->exec(); join->thd->lex.select= save_select; - //if (!executed) - //No rows returned => value is null (returned as inited) - // executed= 1; return join->error; } return 0; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 975d36069f9..d3bd957c308 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -790,11 +790,17 @@ bool select_subselect::send_data(List &items) DBUG_RETURN(1); } if (unit->offset_limit_cnt) - { // using limit offset,count + { // Using limit offset,count unit->offset_limit_cnt--; DBUG_RETURN(0); } - Item *val_item= (Item *)item->select_lex->item_list.head(); + List_iterator_fast li(items); + Item *val_item= li++; // Only one (single value subselect) + /* + Following val() call have to be first, because function AVG() & STD() + calculate value on it & determinate "is it NULL?". + */ + item->real_value= val_item->val(); if ((item->null_value= val_item->is_null())) { item->assign_null(); @@ -804,7 +810,6 @@ bool select_subselect::send_data(List &items) item->binary= val_item->binary; val_item->val_str(&item->str_value); item->int_value= val_item->val_int(); - item->real_value= val_item->val(); item->res_type= val_item->result_type(); } item->executed= 1; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5c113e46a2b..47bbfea3030 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -194,7 +194,6 @@ protected: public: ulong options; enum sub_select_type linkage; - //uint sort_default; SQL_LIST order_list; /* ORDER clause */ ha_rows select_limit, offset_limit; /* LIMIT clause parameters */ void init_query(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3492854329a..ab49645dbae 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2690,12 +2690,12 @@ mysql_init_query(THD *thd) void mysql_init_select(LEX *lex) { - SELECT_LEX *select_lex = lex->select; + SELECT_LEX *select_lex= lex->select; select_lex->init_select(); - select_lex->select_limit=lex->thd->default_select_limit; - select_lex->offset_limit=0; - lex->exchange = 0; - lex->proc_list.first=0; + select_lex->master_unit()->select_limit= select_lex->select_limit= + lex->thd->default_select_limit; + lex->exchange= 0; + lex->proc_list.first= 0; } bool diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4748e857276..62418a12497 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -607,9 +607,10 @@ JOIN::reinit() unit->select_limit_cnt= HA_POS_ERROR; // no limit if (unit->select_limit_cnt == HA_POS_ERROR) select_lex->options&= ~OPTION_FOUND_ROWS; - + if (setup_tables(tables_list)) DBUG_RETURN(1); + DBUG_RETURN(0); } @@ -2830,7 +2831,9 @@ join_free(JOIN *join) } end_read_record(&tab->read_record); } - join->table=0; + //TODO: is enough join_free at the end of mysql_select? + if (!join->select_lex->depended) + join->table=0; } // We are not using tables anymore // Unlock all tables. We may be in an INSERT .... SELECT statement. diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ebd26939ad5..9b95ab05977 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2325,7 +2325,6 @@ order_clause: LEX *lex=Lex; if (lex->sql_command == SQLCOM_MULTI_UPDATE) YYABORT; - /*lex->select->sort_default=1;*/ } order_list order_list: -- cgit v1.2.1 From 7aef75a9a9b3f1965f1989bf224d8c9ba0090f86 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 2 Jun 2002 21:32:02 +0500 Subject: Changed 003F -> 0000 for undefinite characters in charset.conf Charset convertion FROM dynamic charset is now working too Allow dynamic charsets in CONVERT() mysys/charset.c: Charset convertion FROM dynamic charset is now working too sql/item_strfunc.cc: Allow dynamic charsets in CONVERT() sql/share/charsets/cp1251.conf: Change 003F -> 0000 for undefinite characters sql/share/charsets/cp1257.conf: Change 003F -> 0000 for undefinite characters sql/share/charsets/dec8.conf: Change 003F -> 0000 for undefinite characters sql/share/charsets/greek.conf: Change 003F -> 0000 for undefinite characters sql/share/charsets/hebrew.conf: Change 003F -> 0000 for undefinite characters sql/share/charsets/hp8.conf: Change 003F -> 0000 for undefinite characters sql/share/charsets/swe7.conf: Change 003F -> 0000 for undefinite characters sql/share/charsets/usa7.conf: Change 003F -> 0000 for undefinite characters sql/share/charsets/win1250.conf: Change 003F -> 0000 for undefinite characters sql/share/charsets/win1251.conf: Change 003F -> 0000 for undefinite characters sql/share/charsets/win1251ukr.conf: Change 003F -> 0000 for undefinite characters --- sql/item_strfunc.cc | 4 ++-- sql/share/charsets/cp1251.conf | 4 ++-- sql/share/charsets/cp1257.conf | 6 +++--- sql/share/charsets/dec8.conf | 9 ++++----- sql/share/charsets/greek.conf | 7 ++++--- sql/share/charsets/hebrew.conf | 11 ++++++----- sql/share/charsets/hp8.conf | 2 +- sql/share/charsets/swe7.conf | 18 +++++++++--------- sql/share/charsets/usa7.conf | 18 +++++++++--------- sql/share/charsets/win1250.conf | 4 ++-- sql/share/charsets/win1251.conf | 4 ++-- sql/share/charsets/win1251ukr.conf | 4 ++-- 12 files changed, 46 insertions(+), 45 deletions(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e3436ac4641..8f77f736c86 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1860,8 +1860,8 @@ String *Item_func_conv_charset3::val_str(String *str) if (!arg || args[0]->null_value || !to_cs || args[1]->null_value || !from_cs || args[2]->null_value || - !(from_charset=find_compiled_charset_by_name(from_cs->ptr())) || - !(to_charset=find_compiled_charset_by_name(to_cs->ptr()))) + !(from_charset=get_charset_by_name(from_cs->ptr(), MYF(MY_WME))) || + !(to_charset=get_charset_by_name(to_cs->ptr(), MYF(MY_WME)))) { null_value=1; return 0; diff --git a/sql/share/charsets/cp1251.conf b/sql/share/charsets/cp1251.conf index 4418bf48289..653f7d26879 100644 --- a/sql/share/charsets/cp1251.conf +++ b/sql/share/charsets/cp1251.conf @@ -83,8 +83,8 @@ 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F -0402 0403 201A 0453 201E 2026 2020 2021 003F 2030 0409 2039 040A 040C 040B 040F -0452 2018 2019 201C 201D 2022 2013 2014 003F 2122 0459 203A 045A 045C 045B 045F +0402 0403 201A 0453 201E 2026 2020 2021 0000 2030 0409 2039 040A 040C 040B 040F +0452 2018 2019 201C 201D 2022 2013 2014 0000 2122 0459 203A 045A 045C 045B 045F 00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F diff --git a/sql/share/charsets/cp1257.conf b/sql/share/charsets/cp1257.conf index b0e89bb67c4..8338f99c83b 100644 --- a/sql/share/charsets/cp1257.conf +++ b/sql/share/charsets/cp1257.conf @@ -82,9 +82,9 @@ 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F -20AC 003F 201A 003F 201E 2026 2020 2021 003F 2030 003F 2039 003F 00A8 02C7 00B8 -003F 2018 2019 201C 201D 2022 2013 2014 003F 2122 003F 203A 003F 00AF 02DB 003F -00A0 003F 00A2 00A3 00A4 003F 00A6 00A7 00D8 00A9 0156 00AB 00AC 00AD 00AE 00C6 +20AC 0000 201A 0000 201E 2026 2020 2021 0000 2030 0000 2039 0000 00A8 02C7 00B8 +0000 2018 2019 201C 201D 2022 2013 2014 0000 2122 0000 203A 0000 00AF 02DB 0000 +00A0 0000 00A2 00A3 00A4 0000 00A6 00A7 00D8 00A9 0156 00AB 00AC 00AD 00AE 00C6 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00F8 00B9 0157 00BB 00BC 00BD 00BE 00E6 0104 012E 0100 0106 00C4 00C5 0118 0112 010C 00C9 0179 0116 0122 0136 012A 013B 0160 0143 0145 00D3 014C 00D5 00D6 00D7 0172 0141 015A 016A 00DC 017B 017D 00DF diff --git a/sql/share/charsets/dec8.conf b/sql/share/charsets/dec8.conf index 87af7071f8c..d1ffe45032d 100644 --- a/sql/share/charsets/dec8.conf +++ b/sql/share/charsets/dec8.conf @@ -84,10 +84,9 @@ 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F 0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F -00A0 00A1 00A2 00A3 003F 00A5 003F 00A7 00A4 00A9 00AA 00AB 003F 003F 003F 003F -00B0 00B1 00B2 00B3 003F 00B5 00B6 00B7 003F 00B9 00BA 00BB 00BC 00BD 003F 00BF +00A0 00A1 00A2 00A3 0000 00A5 0000 00A7 00A4 00A9 00AA 00AB 0000 0000 0000 0000 +00B0 00B1 00B2 00B3 0000 00B5 00B6 00B7 0000 00B9 00BA 00BB 00BC 00BD 0000 00BF 00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF -003F 00D1 00D2 00D3 00D4 00D5 00D6 0152 00D8 00D9 00DA 00DB 00DC 0178 003F 00DF +0000 00D1 00D2 00D3 00D4 00D5 00D6 0152 00D8 00D9 00DA 00DB 00DC 0178 0000 00DF 00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF -003F 00F1 00F2 00F3 00F4 00F5 00F6 0153 00F8 00F9 00FA 00FB 00FC 00FF 003F 003F - +0000 00F1 00F2 00F3 00F4 00F5 00F6 0153 00F8 00F9 00FA 00FB 00FC 00FF 0000 0000 diff --git a/sql/share/charsets/greek.conf b/sql/share/charsets/greek.conf index 3b5108b561b..5eb38e2efbe 100644 --- a/sql/share/charsets/greek.conf +++ b/sql/share/charsets/greek.conf @@ -84,9 +84,10 @@ 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F 0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F -00A0 02BD 02BC 00A3 003F 003F 00A6 00A7 00A8 00A9 003F 00AB 00AC 00AD 003F 2015 +00A0 02BD 02BC 00A3 0000 0000 00A6 00A7 00A8 00A9 0000 00AB 00AC 00AD 0000 2015 00B0 00B1 00B2 00B3 0384 0385 0386 00B7 0388 0389 038A 00BB 038C 00BD 038E 038F 0390 0391 0392 0393 0394 0395 0396 0397 0398 0399 039A 039B 039C 039D 039E 039F -03A0 03A1 003F 03A3 03A4 03A5 03A6 03A7 03A8 03A9 03AA 03AB 03AC 03AD 03AE 03AF +03A0 03A1 0000 03A3 03A4 03A5 03A6 03A7 03A8 03A9 03AA 03AB 03AC 03AD 03AE 03AF 03B0 03B1 03B2 03B3 03B4 03B5 03B6 03B7 03B8 03B9 03BA 03BB 03BC 03BD 03BE 03BF -03C0 03C1 03C2 03C3 03C4 03C5 03C6 03C7 03C8 03C9 03CA 03CB 03CC 03CD 03CE 003F +03C0 03C1 03C2 03C3 03C4 03C5 03C6 03C7 03C8 03C9 03CA 03CB 03CC 03CD 03CE 0000 + \ No newline at end of file diff --git a/sql/share/charsets/hebrew.conf b/sql/share/charsets/hebrew.conf index 0475db02b24..84581f6f1bb 100644 --- a/sql/share/charsets/hebrew.conf +++ b/sql/share/charsets/hebrew.conf @@ -84,9 +84,10 @@ 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F 0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F -00A0 003F 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00D7 00AB 00AC 00AD 00AE 203E -00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00F7 00BB 00BC 00BD 00BE 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 2017 +00A0 0000 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00D7 00AB 00AC 00AD 00AE 203E +00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00F7 00BB 00BC 00BD 00BE 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 2017 05D0 05D1 05D2 05D3 05D4 05D5 05D6 05D7 05D8 05D9 05DA 05DB 05DC 05DD 05DE 05DF -05E0 05E1 05E2 05E3 05E4 05E5 05E6 05E7 05E8 05E9 05EA 003F 003F 003F 003F 003F +05E0 05E1 05E2 05E3 05E4 05E5 05E6 05E7 05E8 05E9 05EA 0000 0000 0000 0000 0000 + \ No newline at end of file diff --git a/sql/share/charsets/hp8.conf b/sql/share/charsets/hp8.conf index d0fd37f5f24..07036d6f186 100644 --- a/sql/share/charsets/hp8.conf +++ b/sql/share/charsets/hp8.conf @@ -89,5 +89,5 @@ 00E2 00EA 00F4 00FB 00E1 00E9 00F3 00FA 00E0 00E8 00F2 00F9 00E4 00EB 00F6 00FC 00C5 00EE 00D8 00C6 00E5 00ED 00F8 00E6 00C4 00EC 00D6 00DC 00C9 00EF 00DF 00D4 00C1 00C3 00E3 00D0 00F0 00CD 00CC 00D3 00D2 00D5 00F5 0160 0161 00DA 0178 00FF -00DE 00FE 00B7 00B5 00B6 00BE 2014 00BC 00BD 00AA 00BA 00AB 25A0 00BB 00B1 003F +00DE 00FE 00B7 00B5 00B6 00BE 2014 00BC 00BD 00AA 00BA 00AB 25A0 00BB 00B1 0000 diff --git a/sql/share/charsets/swe7.conf b/sql/share/charsets/swe7.conf index c68593a351c..49938800f39 100644 --- a/sql/share/charsets/swe7.conf +++ b/sql/share/charsets/swe7.conf @@ -81,12 +81,12 @@ 00C9 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 00C4 00D6 00C5 00DC 005F 00E9 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F -0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 00E4 00F6 00E5 00FC 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 00E4 00F6 00E5 00FC 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 diff --git a/sql/share/charsets/usa7.conf b/sql/share/charsets/usa7.conf index 45e260870ba..380fc9b5d8b 100644 --- a/sql/share/charsets/usa7.conf +++ b/sql/share/charsets/usa7.conf @@ -81,12 +81,12 @@ 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F -0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F -003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F 003F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 diff --git a/sql/share/charsets/win1250.conf b/sql/share/charsets/win1250.conf index abe0a9a8702..0a5b5074bde 100644 --- a/sql/share/charsets/win1250.conf +++ b/sql/share/charsets/win1250.conf @@ -82,8 +82,8 @@ 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F -20AC 003F 201A 003F 201E 2026 2020 2021 003F 2030 0160 2039 015A 0164 017D 0179 -003F 2018 2019 201C 201D 2022 2013 2014 003F 2122 0161 203A 015B 0165 017E 017A +20AC 0000 201A 0000 201E 2026 2020 2021 0000 2030 0160 2039 015A 0164 017D 0179 +0000 2018 2019 201C 201D 2022 2013 2014 0000 2122 0161 203A 015B 0165 017E 017A 00A0 02C7 02D8 0141 00A4 0104 00A6 00A7 00A8 00A9 015E 00AB 00AC 00AD 00AE 017B 00B0 00B1 02DB 0142 00B4 00B5 00B6 00B7 00B8 0105 015F 00BB 013D 02DD 013E 017C 0154 00C1 00C2 0102 00C4 0139 0106 00C7 010C 00C9 0118 00CB 011A 00CD 00CE 010E diff --git a/sql/share/charsets/win1251.conf b/sql/share/charsets/win1251.conf index 55f688f59b9..2164cb36b9e 100644 --- a/sql/share/charsets/win1251.conf +++ b/sql/share/charsets/win1251.conf @@ -90,8 +90,8 @@ 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F -0402 0403 201A 0453 201E 2026 2020 2021 003F 2030 0409 2039 040A 040C 040B 040F -0452 2018 2019 201C 201D 2022 2013 2014 003F 2122 0459 203A 045A 045C 045B 045F +0402 0403 201A 0453 201E 2026 2020 2021 0000 2030 0409 2039 040A 040C 040B 040F +0452 2018 2019 201C 201D 2022 2013 2014 0000 2122 0459 203A 045A 045C 045B 045F 00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F diff --git a/sql/share/charsets/win1251ukr.conf b/sql/share/charsets/win1251ukr.conf index 2fbab363e5e..da08e4c7d6f 100644 --- a/sql/share/charsets/win1251ukr.conf +++ b/sql/share/charsets/win1251ukr.conf @@ -85,8 +85,8 @@ 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F -0402 0403 201A 0453 201E 2026 2020 2021 003F 2030 0409 2039 040A 040C 040B 040F -0452 2018 2019 201C 201D 2022 2013 2014 003F 2122 0459 203A 045A 045C 045B 045F +0402 0403 201A 0453 201E 2026 2020 2021 0000 2030 0409 2039 040A 040C 040B 040F +0452 2018 2019 201C 201D 2022 2013 2014 0000 2122 0459 203A 045A 045C 045B 045F 00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F -- cgit v1.2.1 From bdb74237346fefff8829d9f4d5f61ec48b35a8f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 2 Jun 2002 21:22:20 +0300 Subject: Extension of .frm file (not yet ready for push) include/m_ctype.h: cleanup include/mysqld_error.h: New error messages sql/field.cc: Extension of .frm file sql/field.h: Extension of .frm file sql/handler.h: cleanup Added CHARSET_INFO to ha_create_information sql/item_strfunc.cc: cleanup sql/lex.h: Update for FOREIGN KEYS sql/mysql_priv.h: Extension of .frm file sql/slave.cc: Fixed bug in wait_for_relay_log_space() sql/spatial.h: Cleanup sql/sql_class.h: Cleanup sql/sql_lex.h: Extension of .frm file sql/sql_parse.cc: Extension of .frm file sql/sql_show.cc: Extension of .frm file sql/sql_table.cc: Extension of .frm file sql/sql_yacc.yy: Extension of .frm file sql/table.cc: Extension of .frm file sql/unireg.cc: Extension of .frm file --- sql/field.cc | 14 +++--- sql/field.h | 6 ++- sql/handler.h | 19 ++++---- sql/item_strfunc.cc | 114 +++++++++++++++++++++---------------------- sql/lex.h | 1 + sql/mysql_priv.h | 7 +-- sql/slave.cc | 4 +- sql/spatial.h | 4 +- sql/sql_class.h | 96 +++++++++++++++++++++++-------------- sql/sql_lex.h | 8 ++-- sql/sql_parse.cc | 20 ++++++-- sql/sql_show.cc | 54 +++++++++++++-------- sql/sql_table.cc | 68 ++++++++++++++++---------- sql/sql_yacc.yy | 99 +++++++++++++++++++++----------------- sql/table.cc | 136 +++++++++++++++++++++++++++++----------------------- sql/unireg.cc | 52 +++++++++++++------- 16 files changed, 415 insertions(+), 287 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 75cbedbb71b..819583ba9fb 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4489,9 +4489,7 @@ void Field_enum::sql_type(String &res) const { if (flag) res.append(','); - res.append('\''); - append_unescaped(&res,*pos); - res.append('\''); + append_unescaped(&res, *pos, strlen(*pos)); flag=1; } res.append(')'); @@ -4610,9 +4608,7 @@ void Field_set::sql_type(String &res) const { if (flag) res.append(','); - res.append('\''); - append_unescaped(&res,*pos); - res.append('\''); + append_unescaped(&res, *pos, strlen(*pos)); flag=1; } res.append(')'); @@ -4713,6 +4709,7 @@ uint pack_length_to_packflag(uint type) Field *make_field(char *ptr, uint32 field_length, uchar *null_pos, uchar null_bit, uint pack_flag, + enum_field_types field_type, Field::utype unireg_check, TYPELIB *interval, const char *field_name, @@ -4728,7 +4725,8 @@ Field *make_field(char *ptr, uint32 field_length, if (!f_is_packed(pack_flag)) return new Field_string(ptr,field_length,null_pos,null_bit, unireg_check, field_name, table, - f_is_binary(pack_flag) != 0, default_charset_info); + f_is_binary(pack_flag) != 0, + default_charset_info); uint pack_length=calc_pack_length((enum_field_types) f_packtype(pack_flag), @@ -4756,7 +4754,7 @@ Field *make_field(char *ptr, uint32 field_length, } } - switch ((enum enum_field_types) f_packtype(pack_flag)) { + switch (field_type) { case FIELD_TYPE_DECIMAL: return new Field_decimal(ptr,field_length,null_pos,null_bit, unireg_check, field_name, table, diff --git a/sql/field.h b/sql/field.h index cf7c2a50218..7fb43ddd29f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -41,6 +41,7 @@ public: uchar *null_ptr; // Byte where null_bit is struct st_table *table; // Pointer for table const char *table_name,*field_name; + LEX_STRING comment; ulong query_id; // For quick test of used fields // Field is part of the following keys key_map key_start,part_of_key,part_of_sortkey; @@ -1013,6 +1014,7 @@ public: const char *field_name; const char *change; // If done with alter table const char *after; // Put column after this one + LEX_STRING comment; // Comment for field Item *def; // Default value enum enum_field_types sql_type; uint32 length; @@ -1020,6 +1022,7 @@ public: Field::utype unireg_check; TYPELIB *interval; // Which interval to use Field *field; // For alter table + CHARSET_INFO *charset; uint8 row,col,sc_length,interval_id; // For rea_create_table uint offset,pack_flag; @@ -1067,7 +1070,8 @@ public: Field *make_field(char *ptr, uint32 field_length, uchar *null_pos, uchar null_bit, - uint pack_flag, Field::utype unireg_check, + uint pack_flag, enum_field_types field_type, + Field::utype unireg_check, TYPELIB *interval, const char *field_name, struct st_table *table); uint pack_length_to_packflag(uint type); diff --git a/sql/handler.h b/sql/handler.h index 668453f8905..45865c39154 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -149,22 +149,23 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, typedef struct st_ha_create_information { - ulong table_options; - enum db_type db_type; - enum row_type row_type; - ulong avg_row_length; - ulonglong max_rows,min_rows; - ulonglong auto_increment_value; + CHARSET_INFO *table_charset; char *comment,*password; char *data_file_name, *index_file_name; char *create_statement; - uint options; /* OR of HA_CREATE_ options */ - uint raid_type,raid_chunks; + ulonglong max_rows,min_rows; + ulonglong auto_increment_value; + ulong table_options; + ulong avg_row_length; ulong raid_chunksize; - bool if_not_exists; ulong used_fields; SQL_LIST merge_list; + enum db_type db_type; + enum row_type row_type; + uint options; /* OR of HA_CREATE_ options */ + uint raid_type,raid_chunks; uint merge_insert_method; + bool if_not_exists; } HA_CREATE_INFO; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e3436ac4641..b0ab03363d3 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2342,7 +2342,8 @@ String *Item_func_spatial_collection::val_str(String *str) } else { - uint32 wkb_type, len=res->length(); + enum Geometry::wkbType wkb_type; + uint32 len=res->length(); const char *data=res->ptr()+1; /* @@ -2351,75 +2352,74 @@ String *Item_func_spatial_collection::val_str(String *str) do this checking now */ - if (len<5) + if (len < 5) goto ret; - wkb_type=uint4korr(data); + wkb_type= (Geometry::wkbType) uint4korr(data); data+=4; len-=5; - if ( wkb_type != item_type ) + if (wkb_type != item_type) goto ret; - switch(coll_type) - { - case Geometry::wkbMultiPoint: - case Geometry::wkbMultiLineString: - case Geometry::wkbMultiPolygon: - if (lenreserve(len,512)) - goto ret; - str->q_append(data,len); - break; - - case Geometry::wkbLineString: - if (str->reserve(POINT_DATA_SIZE,512)) - goto ret; - str->q_append(data,POINT_DATA_SIZE); - break; - - case Geometry::wkbPolygon: - { - uint32 n_points; - double x1, y1, x2, y2; - - if (len < WKB_HEADER_SIZE + 4 + 8 + 8) - goto ret; - data+=WKB_HEADER_SIZE; - len-=WKB_HEADER_SIZE; - - uint32 llen=len; - const char *ldata=data; + data+=WKB_HEADER_SIZE; + len-=WKB_HEADER_SIZE; + if (str->reserve(len,512)) + goto ret; + str->q_append(data,len); + break; + + case Geometry::wkbLineString: + if (str->reserve(POINT_DATA_SIZE,512)) + goto ret; + str->q_append(data,POINT_DATA_SIZE); + break; + + case Geometry::wkbPolygon: + { + uint32 n_points; + double x1, y1, x2, y2; + + if (len < WKB_HEADER_SIZE + 4 + 8 + 8) + goto ret; + data+=WKB_HEADER_SIZE; + len-=WKB_HEADER_SIZE; + + uint32 llen=len; + const char *ldata=data; - n_points=uint4korr(data); - data+=4; - float8get(x1,data); - data+=8; - float8get(y1,data); - data+=8; + n_points=uint4korr(data); + data+=4; + float8get(x1,data); + data+=8; + float8get(y1,data); + data+=8; - len-= 4 + 8 + 8; + len-= 4 + 8 + 8; - if (len < n_points * POINT_DATA_SIZE) - goto ret; - data+=(n_points-2) * POINT_DATA_SIZE; + if (len < n_points * POINT_DATA_SIZE) + goto ret; + data+=(n_points-2) * POINT_DATA_SIZE; - float8get(x2,data); - float8get(y2,data+8); + float8get(x2,data); + float8get(y2,data+8); - if ((x1 != x2) || (y1 != y2)) - goto ret; + if ((x1 != x2) || (y1 != y2)) + goto ret; - if (str->reserve(llen,512)) - goto ret; - str->q_append(ldata, llen); - } - break; + if (str->reserve(llen,512)) + goto ret; + str->q_append(ldata, llen); + } + break; - default: - goto ret; + default: + goto ret; } } } diff --git a/sql/lex.h b/sql/lex.h index ea712523993..482a73cf11b 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -309,6 +309,7 @@ static SYMBOL symbols[] = { { "SESSION", SYM(SESSION_SYM),0,0}, { "SET", SYM(SET),0,0}, { "SIGNED", SYM(SIGNED_SYM),0,0}, + { "SIMPLE", SYM(SIMPLE_SYM),0,0}, { "SHARE", SYM(SHARE_SYM),0,0}, { "SHOW", SYM(SHOW),0,0}, { "SHUTDOWN", SYM(SHUTDOWN),0,0}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 4c71e845207..7d43ed1b38f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -474,8 +474,9 @@ int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, void set_item_name(Item *item,char *pos,uint length); bool add_field_to_list(char *field_name, enum enum_field_types type, char *length, char *decimal, - uint type_modifier, Item *default_value,char *change, - TYPELIB *interval); + uint type_modifier, + Item *default_value, Item *comment, + char *change, TYPELIB *interval); void store_position_for_column(const char *name); bool add_to_list(SQL_LIST &list,Item *group,bool asc=0); TABLE_LIST *add_table_to_list(Table_ident *table,LEX_STRING *alias, @@ -726,7 +727,7 @@ ulong get_form_pos(File file, uchar *head, TYPELIB *save_names); ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, const char *newname); ulong next_io_size(ulong pos); -void append_unescaped(String *res,const char *pos); +void append_unescaped(String *res, const char *pos, uint length); int create_frm(char *name,uint reclength,uchar *fileinfo, HA_CREATE_INFO *create_info, uint keys); void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); diff --git a/sql/slave.cc b/sql/slave.cc index 8461b72f4c6..7de3022f551 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1104,14 +1104,16 @@ static inline int add_relay_log(RELAY_LOG_INFO* rli,LOG_INFO* linfo) static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli) { - bool slave_killed; + bool slave_killed=0; MASTER_INFO* mi = rli->mi; const char* save_proc_info; THD* thd = mi->io_thd; DBUG_ENTER("wait_for_relay_log_space"); + pthread_mutex_lock(&rli->log_space_lock); save_proc_info = thd->proc_info; thd->proc_info = "Waiting for relay log space to free"; + while (rli->log_space_limit < rli->log_space_total && !(slave_killed=io_slave_killed(thd,mi))) { diff --git a/sql/spatial.h b/sql/spatial.h index 09e8722a85e..2daa8e856c9 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -3,8 +3,8 @@ #include "gstream.h" -const int POINT_DATA_SIZE = 8+8; -const int WKB_HEADER_SIZE = 1+4; +const uint POINT_DATA_SIZE = 8+8; +const uint WKB_HEADER_SIZE = 1+4; struct stPoint2D { diff --git a/sql/sql_class.h b/sql/sql_class.h index 5dc761ff811..cc1caa91a73 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -69,11 +69,13 @@ class MYSQL_LOG { char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN]; bool write_error,inited; uint file_id; // current file sequence number for load data infile - // binary logging - bool no_rotate; // for binlog - if log name can never change - // we should not try to rotate it or write any rotation events - // the user should use FLUSH MASTER instead of FLUSH LOGS for - // purging + /* + For binlog - if log name can never change + we should not try to rotate it or write any rotation events + the user should use FLUSH MASTER instead of FLUSH LOGS for + purging + */ + bool no_rotate; enum cache_type io_cache_type; bool need_start_event; pthread_cond_t update_cond; @@ -215,19 +217,40 @@ public: class Key :public Sql_alloc { public: - enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL }; + enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY}; enum Keytype type; enum ha_key_alg algorithm; List columns; - const char *Name; + const char *name; - Key(enum Keytype type_par, enum ha_key_alg alg_par, const char *name_arg, List &cols) - :type(type_par), algorithm(alg_par), columns(cols), Name(name_arg) + Key(enum Keytype type_par, const char *name_arg, enum ha_key_alg alg_par, + List &cols) + :type(type_par), algorithm(alg_par), columns(cols), name(name_arg) {} ~Key() {} - const char *name() { return Name; } }; +class Table_ident; + +class foreign_key: public Key { +public: + enum fk_match_opt { FK_MATCH_UNDEF, FK_MATCH_FULL, + FK_MATCH_PARTIAL, FK_MATCH_SIMPLE}; + enum fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, FK_OPTION_CASCADE, + FK_OPTION_SET_NULL, FK_OPTION_NO_ACTION, FK_OPTION_DEFAULT}; + + Table_ident *ref_table; + List ref_columns; + uint delete_opt, update_opt, match_opt; + foreign_key(const char *name_arg, List &cols, + Table_ident *table, List &ref_cols, + uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg) + :Key(FOREIGN_KEY, name_arg, HA_KEY_ALG_UNDEF, cols), + ref_table(table), ref_columns(cols), + delete_opt(delete_opt_arg), update_opt(update_opt_arg), + match_opt(match_opt_arg) + {} +}; typedef struct st_mysql_lock { @@ -247,8 +270,8 @@ public: #include "sql_lex.h" /* Must be here */ -// needed to be able to have an I_List of char* strings.in mysqld.cc where we cannot use String -// because it is Sql_alloc'ed +/* Needed to be able to have an I_List of char* strings in mysqld.cc. */ + class i_string: public ilink { public: @@ -257,7 +280,7 @@ public: i_string(char* s) : ptr(s) {} }; -//needed for linked list of two strings for replicate-rewrite-db +/* needed for linked list of two strings for replicate-rewrite-db */ class i_string_pair: public ilink { public: @@ -275,39 +298,42 @@ class delayed_insert; #define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC) -/* For each client connection we create a separate thread with THD serving as - a thread/connection descriptor */ +/* + For each client connection we create a separate thread with THD serving as + a thread/connection descriptor. +*/ class THD :public ilink { public: - NET net; // client connection descriptor - LEX lex; // parse tree descriptor - MEM_ROOT mem_root; // 1 command-life memory allocation pool - HASH user_vars; // hash for user variables - String packet; // dynamic string buffer used for network I/O - struct sockaddr_in remote; // client socket address - struct rand_struct rand; // used for authentication + NET net; // client connection descriptor + LEX lex; // parse tree descriptor + MEM_ROOT mem_root; // 1 command-life memory + HASH user_vars; // hash for user variables + String packet; // buffer used for network I/O + struct sockaddr_in remote; // client socket address + struct rand_struct rand; // used for authentication - /* query points to the current query, - thread_stack is a pointer to the stack frame of handle_one_connection(), - which is called first in the thread for handling a client - */ + /* + Query points to the current query, + thread_stack is a pointer to the stack frame of handle_one_connection(), + which is called first in the thread for handling a client + */ char *query,*thread_stack; /* host - host of the client user - user of the client, set to NULL until the user has been read from the connection - priv_user - not sure why we have it, but it is set to "boot" when we run - with --bootstrap + priv_user - The user privilege we are using. May be '' for anonymous user. db - currently selected database ip - client IP */ char *host,*user,*priv_user,*db,*ip; - /* proc_info points to a string that will show in the Info column of - SHOW PROCESSLIST output - host_or_ip points to host if host is available, otherwise points to ip - */ + /* + Proc_info points to a string that will show in the Info column of + SHOW PROCESSLIST output + host_or_ip points to host if host is available, otherwise points to ip + */ const char *proc_info, *host_or_ip; /* @@ -334,7 +360,8 @@ public: */ TABLE *open_tables,*temporary_tables, *handler_tables; // TODO: document the variables below - MYSQL_LOCK *lock,*locked_tables; + MYSQL_LOCK *lock; /* Current locks */ + MYSQL_LOCK *locked_tables; /* Tables locked with LOCK */ ULL *ull; #ifndef DBUG_OFF uint dbug_sentry; // watch out for memory corruption @@ -538,7 +565,7 @@ public: #include "log_event.h" /* -** This is used to get result from a select + This is used to get result from a select */ class JOIN; @@ -787,7 +814,6 @@ public: class multi_update : public select_result { TABLE_LIST *update_tables, *table_being_updated; -// Unique **tempfiles; COPY_INFO *infos; TABLE **tmp_tables; THD *thd; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e53a2e7bda8..27ca601ed87 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -154,6 +154,7 @@ typedef struct st_lex { sql_exchange *exchange; List col_list; + List ref_list; List drop_list; List alter_list; List interval_list; @@ -167,7 +168,7 @@ typedef struct st_lex { SQL_LIST proc_list, auxilliary_table_list; TYPELIB *interval; create_field *last_field; - Item *default_value; + Item *default_value, *comment; CONVERT *convert_set; LEX_USER *grant_user; gptr yacc_yyss,yacc_yyvs; @@ -178,14 +179,15 @@ typedef struct st_lex { LEX_MASTER_INFO mi; // used by CHANGE MASTER ulong thread_id,type; enum_sql_command sql_command; + thr_lock_type lock_option; enum lex_states next_state; enum enum_duplicates duplicates; enum enum_tx_isolation tx_isolation; enum enum_ha_read_modes ha_read_mode; enum ha_rkey_function ha_rkey_mode; enum enum_enable_or_disable alter_keys_onoff; - uint grant,grant_tot_col,which_columns, union_option, mqh; - thr_lock_type lock_option; + uint grant, grant_tot_col, which_columns, union_option, mqh; + uint fk_delete_opt, fk_update_opt, fk_match_option; bool drop_primary,drop_if_exists,local_file; bool in_comment,ignore_space,verbose,simple_alter, option_type, derived_tables; uint slave_thd_opt; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 469de136fbb..f0842c0896e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2770,8 +2770,9 @@ link_in_list(SQL_LIST *list,byte *element,byte **next) bool add_field_to_list(char *field_name, enum_field_types type, char *length, char *decimals, - uint type_modifier, Item *default_value,char *change, - TYPELIB *interval) + uint type_modifier, + Item *default_value, Item *comment, + char *change, TYPELIB *interval) { register create_field *new_field; THD *thd=current_thd; @@ -2787,14 +2788,14 @@ bool add_field_to_list(char *field_name, enum_field_types type, if (type_modifier & PRI_KEY_FLAG) { lex->col_list.push_back(new key_part_spec(field_name,0)); - lex->key_list.push_back(new Key(Key::PRIMARY, HA_KEY_ALG_UNDEF, NullS, + lex->key_list.push_back(new Key(Key::PRIMARY, NullS, HA_KEY_ALG_UNDEF, lex->col_list)); lex->col_list.empty(); } if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) { lex->col_list.push_back(new key_part_spec(field_name,0)); - lex->key_list.push_back(new Key(Key::UNIQUE, HA_KEY_ALG_UNDEF, NullS, + lex->key_list.push_back(new Key(Key::UNIQUE, NullS, HA_KEY_ALG_UNDEF, lex->col_list)); lex->col_list.empty(); } @@ -2824,6 +2825,17 @@ bool add_field_to_list(char *field_name, enum_field_types type, new_field->change=change; new_field->interval=0; new_field->pack_length=0; + if (!comment) + { + new_field->comment.str=0; + new_field->comment.length=0; + } + else + { + /* In this case comment is always of type Item_string */ + new_field->comment.str= (char*) comment->str_value.ptr(); + new_field->comment.length=comment->str_value.length(); + } if (length) if (!(new_field->length= (uint) atoi(length))) length=0; /* purecov: inspected */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 849a803a622..359ed48ed48 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -454,8 +454,10 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, field_list.push_back(new Item_empty_string("Default",NAME_LEN)); field_list.push_back(new Item_empty_string("Extra",20)); if (verbose) + { field_list.push_back(new Item_empty_string("Privileges",80)); - + field_list.push_back(new Item_empty_string("Comment",255)); + } // Send first number of fields and records { char *pos; @@ -522,7 +524,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, if (verbose) { - /* Add grant options */ + /* Add grant options & comments */ col_access= get_column_grant(thd,table_list,field) & COL_ACLS; end=tmp; for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) @@ -534,6 +536,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, } } net_store_data(packet,convert, tmp+1,end == tmp ? 0 : (uint) (end-tmp-1)); + net_store_data(packet, field->comment.str,field->comment.length); } if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) DBUG_RETURN(1); @@ -571,21 +574,28 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) { packet->length(0); net_store_data(packet,convert, table->table_name); - // a hack - we need to reserve some space for the length before - // we know what it is - let's assume that the length of create table - // statement will fit into 3 bytes ( 16 MB max :-) ) + /* + A hack - we need to reserve some space for the length before + we know what it is - let's assume that the length of create table + statement will fit into 3 bytes ( 16 MB max :-) ) + */ ulong store_len_offset = packet->length(); packet->length(store_len_offset + 4); if (store_create_info(thd, table, packet)) DBUG_RETURN(-1); ulong create_len = packet->length() - store_len_offset - 4; + /* + Just in case somebody manages to create a table + with *that* much stuff in the definition + */ if (create_len > 0x00ffffff) // better readable in HEX ... - DBUG_RETURN(1); // just in case somebody manages to create a table - // with *that* much stuff in the definition + DBUG_RETURN(1); - // now we have to store the length in three bytes, even if it would fit - // into fewer, so we cannot use net_store_data() anymore, - // and do it ourselves + /* + Now we have to store the length in three bytes, even if it would fit + into fewer, so we cannot use net_store_data() anymore, + and do it ourselves + */ char* p = (char*)packet->ptr() + store_len_offset; *p++ = (char) 253; // The client the length is stored using 3-bytes int3store(p, create_len); @@ -848,10 +858,10 @@ store_create_info(THD *thd, TABLE *table, String *packet) { // Not null by default type.set(tmp,sizeof(tmp),default_charset_info); field->val_str(&type,&type); - packet->append('\''); if (type.length()) - append_unescaped(packet, type.c_ptr()); - packet->append('\''); + append_unescaped(packet, type.ptr(), type.length()); + else + packet->append("''",2); } else if (field->maybe_null()) packet->append("NULL", 4); // Null as default @@ -860,7 +870,13 @@ store_create_info(THD *thd, TABLE *table, String *packet) } if (field->unireg_check == Field::NEXT_NUMBER) - packet->append(" auto_increment", 15 ); + packet->append(" auto_increment", 15 ); + + if (field->comment.length) + { + packet->append(" COMMENT ",9); + append_unescaped(packet, field->comment.str, field->comment.length); + } } KEY *key_info=table->key_info; @@ -890,8 +906,9 @@ store_create_info(THD *thd, TABLE *table, String *packet) append_identifier(thd,packet,key_info->name); // +BAR: send USING only in non-default case: non-spatial rtree - if((key_info->algorithm == HA_KEY_ALG_RTREE) && !(key_info->flags & HA_SPATIAL)) - packet->append(" USING RTREE",12); + if((key_info->algorithm == HA_KEY_ALG_RTREE) && + !(key_info->flags & HA_SPATIAL)) + packet->append(" USING RTREE",12); packet->append(" (", 2); @@ -972,9 +989,8 @@ store_create_info(THD *thd, TABLE *table, String *packet) table->file->append_create_info(packet); if (table->comment && table->comment[0]) { - packet->append(" COMMENT='", 10); - append_unescaped(packet, table->comment); - packet->append('\''); + packet->append(" COMMENT=", 9); + append_unescaped(packet, table->comment, strlen(table->comment)); } if (file->raid_type) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bdcb325774b..5c7d9e538e4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -266,7 +266,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_ENTER("mysql_create_table"); /* - ** Check for duplicate fields and check type of table to create + Check for duplicate fields and check type of table to create */ if (!fields.elements) @@ -398,35 +398,50 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, /* Create keys */ List_iterator key_iterator(keys); - uint key_parts=0,key_count=keys.elements; + uint key_parts=0, key_count=0, fk_key_count=0; List keys_in_order; // Add new keys here bool primary_key=0,unique_key=0; Key *key; uint tmp, key_number; - tmp=min(file->max_keys(), MAX_KEY); - if (key_count > tmp) - { - my_error(ER_TOO_MANY_KEYS,MYF(0),tmp); - DBUG_RETURN(-1); - } /* Calculate number of key segements */ while ((key=key_iterator++)) { + if (key->type == Key::FOREIGN_KEY) + { + fk_key_count++; + foreign_key *fk_key= (foreign_key*) key; + if (fk_key->ref_columns.elements && + fk_key->ref_columns.elements != fk_key->columns.elements) + { + my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name : + "foreign key without name", + ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); + DBUG_RETURN(-1); + } + continue; + } + key_count++; tmp=max(file->max_key_parts(),MAX_REF_PARTS); if (key->columns.elements > tmp) { my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp); DBUG_RETURN(-1); } - if (key->name() && strlen(key->name()) > NAME_LEN) + if (key->name && strlen(key->name) > NAME_LEN) { - my_error(ER_TOO_LONG_IDENT, MYF(0), key->name()); + my_error(ER_TOO_LONG_IDENT, MYF(0), key->name); DBUG_RETURN(-1); } key_parts+=key->columns.elements; } + tmp=min(file->max_keys(), MAX_KEY); + if (key_count > tmp) + { + my_error(ER_TOO_MANY_KEYS,MYF(0),tmp); + DBUG_RETURN(-1); + } key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)*key_count); key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts); @@ -450,7 +465,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, case Key::SPATIAL: key_info->flags = HA_SPATIAL; break; - default: + case Key::FOREIGN_KEY: + key_number--; // Skip this key + continue; + default: key_info->flags = HA_NOSAME; } @@ -623,7 +641,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, key_name=primary_key_name; primary_key=1; } - else if (!(key_name = key->name())) + else if (!(key_name = key->name)) key_name=make_unique_key_name(sql_field->field_name, key_info_buffer,key_info); if (check_if_keyname_exists(key_name,key_info_buffer,key_info)) @@ -1395,7 +1413,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, List key_list; // Add new keys here /* - ** First collect all fields from table which isn't in drop_list + First collect all fields from table which isn't in drop_list */ create_field *def; @@ -1511,8 +1529,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } /* - ** Collect all keys which isn't in drop list. Add only those - ** for which some fields exists. + Collect all keys which isn't in drop list. Add only those + for which some fields exists. */ List_iterator key_it(keys); @@ -1583,18 +1601,20 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, (!my_strcasecmp(system_charset_info, key_name, "PRIMARY") ? Key::PRIMARY : Key::UNIQUE) : - (key_info->flags & HA_FULLTEXT ? - Key::FULLTEXT : Key::MULTIPLE)), + (key_info->flags & HA_FULLTEXT ? + Key::FULLTEXT : Key::MULTIPLE)), + key_name, key_info->algorithm, - key_name,key_parts)); + key_parts)); } - key_it.rewind(); { Key *key; while ((key=key_it++)) // Add new keys - key_list.push_back(key); + { + if (key->type != Key::FOREIGN_KEY) + key_list.push_back(key); + } } - if (drop_list.elements) { my_error(ER_CANT_DROP_FIELD_OR_KEY,MYF(0),drop_list.head()->name); @@ -1764,9 +1784,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err; } /* - ** Data is copied. Now we rename the old table to a temp name, - ** rename the new one to the old name, remove all entries from the old table - ** from the cash, free all locks, close the old table and remove it. + Data is copied. Now we rename the old table to a temp name, + rename the new one to the old name, remove all entries from the old table + from the cash, free all locks, close the old table and remove it. */ thd->proc_info="rename result table"; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 756afbd7a09..a9961090197 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -302,6 +302,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SET %token SERIALIZABLE_SYM %token SESSION_SYM +%token SIMPLE_SYM %token SHUTDOWN %token SPATIAL_SYM %token SQL_CACHE_SYM @@ -520,7 +521,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); opt_table_alias %type - table_ident + table_ident references %type remember_name remember_end opt_len opt_ident opt_db text_or_password @@ -532,7 +533,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type type int_type real_type order_dir opt_field_spec set_option lock_option udf_type if_exists opt_local opt_table_options table_options - table_option opt_if_not_exists + table_option opt_if_not_exists delete_option %type ULONG_NUM raid_types merge_insert_types @@ -600,7 +601,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); opt_precision opt_ignore opt_column opt_restrict grant revoke set lock unlock string_list field_options field_option field_opt_list opt_binary table_lock_list table_lock varchar - references opt_on_delete opt_on_delete_list opt_on_delete_item use + ref_list opt_on_delete opt_on_delete_list opt_on_delete_item use opt_delete_options opt_delete_option opt_outer table_list table_name opt_option opt_place opt_low_priority opt_attribute opt_attribute_list attribute column_list column_list_id @@ -612,7 +613,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild union union_list - precision union_option + precision union_option opt_on_delete_item END_OF_INPUT %type @@ -756,6 +757,7 @@ create: bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.options=$2 | $4; lex->create_info.db_type= default_table_type; + lex->create_info.table_charset=default_charset_info; } create2 @@ -774,7 +776,7 @@ create: { LEX *lex=Lex; - lex->key_list.push_back(new Key($2,$5,$4.str,lex->col_list)); + lex->key_list.push_back(new Key($2,$4.str, $5, lex->col_list)); lex->col_list.empty(); } | CREATE DATABASE opt_if_not_exists ident default_charset @@ -924,12 +926,19 @@ field_list_item: | key_type opt_ident key_alg '(' key_list ')' { LEX *lex=Lex; - lex->key_list.push_back(new Key($1,$3,$2,lex->col_list)); + lex->key_list.push_back(new Key($1,$2, $3, lex->col_list)); lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references { - Lex->col_list.empty(); /* Alloced by sql_alloc */ + LEX *lex=Lex; + lex->key_list.push_back(new foreign_key($4, lex->col_list, + $8, + lex->ref_list, + lex->fk_delete_opt, + lex->fk_update_opt, + lex->fk_match_option)); + lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint CHECK_SYM '(' expr ')' { @@ -945,7 +954,7 @@ field_spec: { LEX *lex=Lex; lex->length=lex->dec=0; lex->type=0; lex->interval=0; - lex->default_value=0; + lex->default_value=lex->comment=0; } type opt_attribute { @@ -953,8 +962,8 @@ field_spec: if (add_field_to_list($1.str, (enum enum_field_types) $3, lex->length,lex->dec,lex->type, - lex->default_value,lex->change, - lex->interval)) + lex->default_value, lex->comment, + lex->change,lex->interval)) YYABORT; } @@ -1093,6 +1102,7 @@ attribute: | PRIMARY_SYM KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; } | UNIQUE_SYM { Lex->type|= UNIQUE_FLAG; } | UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; } + | COMMENT_SYM text_literal { Lex->comment= $2; } opt_binary: /* empty */ { Lex->charset=default_charset_info; } @@ -1122,11 +1132,25 @@ default_charset: } references: - REFERENCES table_ident opt_on_delete {} - | REFERENCES table_ident '(' key_list ')' opt_on_delete - { - Lex->col_list.empty(); /* Alloced by sql_alloc */ - } + REFERENCES table_ident + { + LEX *lex=Lex; + lex->fk_delete_opt= lex->fk_update_opt= lex->fk_match_option= 0; + lex->ref_list.empty(); + } + opt_ref_list + { + $$=$2; + } + +opt_ref_list: + /* empty */ {} + | '(' ref_list ')' opt_on_delete {} + +ref_list: + ref_list ',' ident { Lex->ref_list.push_back(new key_part_spec($3.str)); } + | ident { Lex->ref_list.push_back(new key_part_spec($1.str)); } + opt_on_delete: /* empty */ {} @@ -1136,19 +1160,19 @@ opt_on_delete_list: opt_on_delete_list opt_on_delete_item {} | opt_on_delete_item {} - opt_on_delete_item: - ON DELETE_SYM delete_option {} - | ON UPDATE_SYM delete_option {} - | MATCH FULL {} - | MATCH PARTIAL {} + ON DELETE_SYM delete_option { Lex->fk_delete_opt= $3; } + | ON UPDATE_SYM delete_option { Lex->fk_update_opt= $3; } + | MATCH FULL { Lex->fk_match_option= foreign_key::FK_MATCH_FULL; } + | MATCH PARTIAL { Lex->fk_match_option= foreign_key::FK_MATCH_PARTIAL; } + | MATCH SIMPLE_SYM { Lex->fk_match_option= foreign_key::FK_MATCH_SIMPLE; } delete_option: - RESTRICT {} - | CASCADE {} - | SET NULL_SYM {} - | NO_SYM ACTION {} - | SET DEFAULT {} + RESTRICT { $$= (int) foreign_key::FK_OPTION_RESTRICT; } + | CASCADE { $$= (int) foreign_key::FK_OPTION_CASCADE; } + | SET NULL_SYM { $$= (int) foreign_key::FK_OPTION_SET_NULL; } + | NO_SYM ACTION { $$= (int) foreign_key::FK_OPTION_NO_ACTION; } + | SET DEFAULT { $$= (int) foreign_key::FK_OPTION_DEFAULT; } key_type: opt_constraint PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; } @@ -1225,6 +1249,7 @@ alter: bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.db_type= DB_TYPE_DEFAULT; lex->create_info.row_type= ROW_TYPE_NOT_USED; + lex->create_info.table_charset=default_charset_info; lex->alter_keys_onoff=LEAVE_AS_IS; lex->simple_alter=1; } @@ -1246,23 +1271,9 @@ alter_list_item: lex->change= $3.str; lex->simple_alter=0; } field_spec opt_place - | MODIFY_SYM opt_column field_ident + | MODIFY_SYM opt_column field_spec { - LEX *lex=Lex; - lex->length=lex->dec=0; lex->type=0; lex->interval=0; - lex->default_value=0; - lex->simple_alter=0; - } - type opt_attribute - { - LEX *lex=Lex; - if (add_field_to_list($3.str, - (enum enum_field_types) $5, - lex->length,lex->dec,lex->type, - lex->default_value, $3.str, - lex->interval)) - YYABORT; - lex->simple_alter=0; + Lex->simple_alter=0; } opt_place | DROP opt_column field_ident opt_restrict @@ -3209,6 +3220,7 @@ keyword: | OFF {} | OPEN_SYM {} | PACK_KEYS_SYM {} + | PARTIAL {} | PASSWORD {} | PREV_SYM {} | PROCESS {} @@ -3220,8 +3232,8 @@ keyword: | RAID_CHUNKSIZE {} | RAID_STRIPED_SYM {} | RAID_TYPE {} - | RELAY_LOG_FILE_SYM {} - | RELAY_LOG_POS_SYM {} + | RELAY_LOG_FILE_SYM {} + | RELAY_LOG_POS_SYM {} | RELOAD {} | REPAIR {} | REPEATABLE_SYM {} @@ -3235,6 +3247,7 @@ keyword: | SERIALIZABLE_SYM {} | SESSION_SYM {} | SIGNED_SYM {} + | SIMPLE_SYM {} | SHARE_SYM {} | SHUTDOWN {} | SLAVE {} diff --git a/sql/table.cc b/sql/table.cc index 05a5c5e6bd2..a7571d2183f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -47,19 +47,19 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, int j,error; uint rec_buff_length,n_length,int_length,records,key_parts,keys, interval_count,interval_parts,read_length,db_create_options; - uint key_info_length; + uint key_info_length, com_length; ulong pos; char index_file[FN_REFLEN], *names,*keynames; uchar head[288],*disk_buff,new_field_pack_flag; my_string record; const char **int_array; - bool new_frm_ver,use_hash, null_field_first; + bool use_hash, null_field_first; File file; Field **field_ptr,*reg_field; KEY *keyinfo; KEY_PART_INFO *key_part; - uchar *null_pos; - uint null_bit; + uchar *null_pos, *comment_pos; + uint null_bit, new_frm_ver, field_pack_length; SQL_CRYPT *crypted=0; DBUG_ENTER("openfrm"); DBUG_PRINT("enter",("name: '%s' form: %lx",name,outparam)); @@ -95,10 +95,11 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (my_read(file,(byte*) head,64,MYF(MY_NABP))) goto err_not_open; if (head[0] != (uchar) 254 || head[1] != 1 || - (head[2] != FRM_VER && head[2] != FRM_VER+1)) + (head[2] < FRM_VER && head[2] > FRM_VER+2)) goto err_not_open; /* purecov: inspected */ new_field_pack_flag=head[27]; - new_frm_ver= (head[2] == FRM_VER+1); + new_frm_ver= (head[2] - FRM_VER); + field_pack_length= new_frm_ver < 2 ? 11 : 15; error=3; if (!(pos=get_form_pos(file,head,(TYPELIB*) 0))) @@ -116,6 +117,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->raid_type= head[41]; outparam->raid_chunks= head[42]; outparam->raid_chunksize= uint4korr(head+43); + if (!(outparam->table_charset=get_charset((uint) head[38],MYF(0)))) + outparam->table_charset=default_charset_info; null_field_first=1; } outparam->db_record_offset=1; @@ -153,10 +156,22 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, for (i=0 ; i < keys ; i++, keyinfo++) { - keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME; - keyinfo->key_length= (uint) uint2korr(strpos+1); - keyinfo->key_parts= (uint) strpos[3]; - strpos+=4; + if (new_frm_ver == 2) + { + keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; + keyinfo->key_length= (uint) uint2korr(strpos+2); + keyinfo->key_parts= (uint) strpos[4]; + keyinfo->algorithm= (enum ha_key_alg) strpos[5]; + strpos+=8; + } + else + { + keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME; + keyinfo->key_length= (uint) uint2korr(strpos+1); + keyinfo->key_parts= (uint) strpos[3]; + keyinfo->algorithm= HA_KEY_ALG_UNDEF; + strpos+=4; + } keyinfo->key_part= key_part; keyinfo->rec_per_key= rec_per_key; @@ -167,7 +182,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, key_part->offset= (uint) uint2korr(strpos+2)-1; key_part->key_type= (uint) uint2korr(strpos+5); // key_part->field= (Field*) 0; // Will be fixed later - if (new_frm_ver) + if (new_frm_ver >= 1) { key_part->key_part_flag= *(strpos+4); key_part->length= (uint) uint2korr(strpos+7); @@ -193,26 +208,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, } keynames=(char*) key_part; strpos+= (strmov(keynames, (char *) strpos) - keynames)+1; - /* Test if new 4.0 format */ - if ((uint) (strpos - disk_buff) < key_info_length) - { - /* Read key types */ - keyinfo=outparam->key_info; - for (i=0 ; i < keys ; i++, keyinfo++) - { - keyinfo->algorithm= (enum ha_key_alg) *(strpos++); - /* Temporary fix to get spatial index to work */ - if (keyinfo->algorithm == HA_KEY_ALG_RTREE) - keyinfo->flags|= HA_SPATIAL; - } - } - else - { - /* Set key types to BTREE, BAR TODO: how to be with HASH/RBTREE? */ - keyinfo=outparam->key_info; - for (i=0 ; i < keys ; i++, keyinfo++) - keyinfo->algorithm= HA_KEY_ALG_BTREE; - } outparam->reclength = uint2korr((head+16)); if (*(head+26) == 1) outparam->system=1; /* one-record-database */ @@ -280,10 +275,11 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, interval_parts=uint2korr(head+272); int_length=uint2korr(head+274); outparam->null_fields=uint2korr(head+282); + com_length=uint2korr(head+284); outparam->comment=strdup_root(&outparam->mem_root, (char*) head+47); - DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d", interval_count,interval_parts, outparam->keys,n_length,int_length)); + DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d", interval_count,interval_parts, outparam->keys,n_length,int_length, com_length)); if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root, @@ -291,12 +287,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, interval_count*sizeof(TYPELIB)+ (outparam->fields+interval_parts+ keys+3)*sizeof(my_string)+ - (n_length+int_length))))) + (n_length+int_length+com_length))))) goto err_not_open; /* purecov: inspected */ outparam->field=field_ptr; - read_length=((uint) (outparam->fields*11)+pos+ - (uint) (n_length+int_length)); + read_length=(uint) (outparam->fields * field_pack_length + + pos+ (uint) (n_length+int_length)); if (read_string(file,(gptr*) &disk_buff,read_length)) goto err_not_open; /* purecov: inspected */ if (crypted) @@ -306,13 +302,14 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, crypted=0; } strpos= disk_buff+pos; + comment_pos=disk_buff+read_length-com_length; outparam->intervals= (TYPELIB*) (field_ptr+outparam->fields+1); int_array= (const char **) (outparam->intervals+interval_count); names= (char*) (int_array+outparam->fields+interval_parts+keys+3); if (!interval_count) outparam->intervals=0; // For better debugging - memcpy((char*) names, strpos+(outparam->fields*11), + memcpy((char*) names, strpos+(outparam->fields*field_pack_length), (uint) (n_length+int_length)); fix_type_pointers(&int_array,&outparam->fieldnames,1,&names); @@ -346,43 +343,55 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, (hash_get_key) get_field_name,0, HASH_CASE_INSENSITIVE); -// BAR: dirty hack while waiting for new FRM -// BAR: take a charset information from table name -{ - const char* csname=strstr(alias,"_cs_"); - if(!csname || - !(outparam->table_charset=get_charset_by_name(csname+4,MYF(MY_WME)))) - outparam->table_charset=default_charset_info; -} - - for (i=0 ; i < outparam->fields; i++, strpos+= 11, field_ptr++) + for (i=0 ; i < outparam->fields; i++, strpos+=field_pack_length, field_ptr++) { uint pack_flag= uint2korr(strpos+6); uint interval_nr= (uint) strpos[10]; + enum_field_types field_type; + CHARSET_INFO *charset; + LEX_STRING comment; + if (new_frm_ver == 2) + { + /* new frm file in 4.1 */ + uint comment_length=uint2korr(strpos+13); + field_type=(enum_field_types) (uint) strpos[11]; + if (!(charset=get_charset((uint) strpos[12], MYF(0)))) + charset=outparam->table_charset; + if (!comment_length) + { + comment.str= (char*) ""; + comment.length=0; + } + else + { + comment.str= (char*) comment_pos; + comment.length= comment_length; + comment_pos+= comment_length; + } + } + else + { + /* old frm file */ + field_type= (enum_field_types) f_packtype(pack_flag); + charset=outparam->table_charset; + bzero((char*) &comment, sizeof(comment)); + } *field_ptr=reg_field= make_field(record+uint2korr(strpos+4), (uint32) strpos[3], // field_length null_pos,null_bit, pack_flag, + field_type, (Field::utype) MTYP_TYPENR((uint) strpos[8]), (interval_nr ? outparam->intervals+interval_nr-1 : (TYPELIB*) 0), outparam->fieldnames.type_names[i], outparam); + reg_field->comment=comment; if (!reg_field->binary()) - { - // BAR: dirty hack while waiting for new FRM - // BAR: take a charset information from field name - - Field_str* str_field=(Field_str*)reg_field; - const char* csname=strstr(str_field->field_name,"_cs_"); - CHARSET_INFO *fcs; - if (!csname || (!(fcs=get_charset_by_name(csname+4,MYF(MY_WME))))) - fcs=outparam->table_charset; - str_field->set_charset(fcs); - } + ((Field_str*) reg_field)->set_charset(charset); if (!(reg_field->flags & NOT_NULL_FLAG)) { if ((null_bit<<=1) == 256) @@ -956,9 +965,14 @@ ulong next_io_size(register ulong pos) } /* next_io_size */ -void append_unescaped(String *res,const char *pos) + /* Store in String an SQL quoted string */ + +void append_unescaped(String *res,const char *pos, uint length) { - for ( ; *pos ; pos++) + const char *end= pos+length; + res->append('\''); + + for (; pos != end ; pos++) { switch (*pos) { case 0: /* Must be escaped for 'mysql' */ @@ -986,6 +1000,7 @@ void append_unescaped(String *res,const char *pos) break; } } + res->append('\''); } /* Create a .frm file */ @@ -1009,7 +1024,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, if ((file=my_create(name,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) { bzero((char*) fileinfo,64); - fileinfo[0]=(uchar) 254; fileinfo[1]= 1; fileinfo[2]= FRM_VER+1; // Header + fileinfo[0]=(uchar) 254; fileinfo[1]= 1; fileinfo[2]= FRM_VER+2; // Header fileinfo[3]= (uchar) ha_checktype(create_info->db_type); fileinfo[4]=1; int2store(fileinfo+6,IO_SIZE); /* Next block starts here */ @@ -1025,6 +1040,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, int2store(fileinfo+30,create_info->table_options); fileinfo[32]=0; // No filename anymore int4store(fileinfo+34,create_info->avg_row_length); + fileinfo[38]= create_info->table_charset->number; fileinfo[40]= (uchar) create_info->row_type; fileinfo[41]= (uchar) create_info->raid_type; fileinfo[42]= (uchar) create_info->raid_chunks; diff --git a/sql/unireg.cc b/sql/unireg.cc index 16f51658313..7c4f199ab7f 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -28,7 +28,7 @@ #include "mysql_priv.h" #include -#define FCOMP 11 /* Byte per packat f{lt */ +#define FCOMP 11 /* Byte for packed field */ static uchar * pack_screens(List &create_fields, uint *info_length, uint *screens, bool small_file); @@ -255,10 +255,11 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) key_parts=0; for (key=keyinfo,end=keyinfo+key_count ; key != end ; key++) { - pos[0]=(uchar) (key->flags ^ HA_NOSAME); - int2store(pos+1,key->key_length); - pos[3]=key->key_parts; - pos+=4; + int2store(pos, (key->flags ^ HA_NOSAME)); + int2store(pos+2,key->key_length); + pos[4]= (uchar) key->key_parts; + pos[5]= (uchar) key->algorithm; + pos+=8; key_parts+=key->key_parts; DBUG_PRINT("loop",("flags: %d key_parts: %d at %lx", key->flags,key->key_parts, @@ -290,13 +291,6 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) } *(pos++)=0; - /* For MySQL 4.0; Store key algoritms last */ - key_alg_pos= pos; - for (key=keyinfo ; key != end ; key++) - { - *(pos++)= (uchar) key->algorithm; - } - keybuff[0]=(uchar) key_count; keybuff[1]=(uchar) key_parts; length=(uint) (keyname_pos-keybuff); @@ -314,8 +308,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, uint info_length, uint screens,uint table_options, handler *file) { - uint length,int_count,int_length,no_empty, int_parts, - time_stamp_pos,null_fields; + uint length,int_count,int_length,no_empty, int_parts; + uint time_stamp_pos,null_fields, com_length; ulong reclength,totlength,n_length; DBUG_ENTER("pack_header"); @@ -326,7 +320,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, } totlength=reclength=0L; - no_empty=int_count=int_parts=int_length=time_stamp_pos=null_fields=0; + no_empty=int_count=int_parts=int_length=time_stamp_pos=null_fields= + com_length=0; n_length=2L; /* Check fields */ @@ -336,6 +331,7 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, while ((field=it++)) { totlength+= field->length; + com_length+= field->comment.length; if (MTYP_TYPENR(field->unireg_check) == Field::NOEMPTY || field->unireg_check & MTYP_NOEMPTY_BIT) { @@ -378,14 +374,15 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, /* Hack to avoid bugs with small static rows in MySQL */ reclength=max(file->min_record_length(table_options),reclength); if (info_length+(ulong) create_fields.elements*FCOMP+288+ - n_length+int_length > 65535L || int_count > 255) + n_length+int_length+com_length > 65535L || int_count > 255) { my_error(ER_TOO_MANY_FIELDS,MYF(0)); DBUG_RETURN(1); } bzero((char*)forminfo,288); - length=info_length+create_fields.elements*FCOMP+288+n_length+int_length; + length=(info_length+create_fields.elements*FCOMP+288+n_length+int_length+ + com_length); int2store(forminfo,length); forminfo[256] = (uint8) screens; int2store(forminfo+258,create_fields.elements); @@ -401,6 +398,7 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, int2store(forminfo+278,80); /* Columns needed */ int2store(forminfo+280,22); /* Rows needed */ int2store(forminfo+282,null_fields); + int2store(forminfo+284,com_length); DBUG_RETURN(0); } /* pack_header */ @@ -438,7 +436,7 @@ static uint get_interval_id(uint *int_count,List &create_fields, static bool pack_fields(File file,List &create_fields) { reg2 uint i; - uint int_count; + uint int_count, comment_length=0; uchar buff[MAX_FIELD_WIDTH]; create_field *field; DBUG_ENTER("pack_fields"); @@ -459,6 +457,11 @@ static bool pack_fields(File file,List &create_fields) int2store(buff+6,field->pack_flag); int2store(buff+8,field->unireg_check); buff[10]= (uchar) field->interval_id; + buff[11]= (uchar) field->sql_type; + buff[12]= (uchar) (field->charset ? field->charset->number : + default_charset_info->number); + int2store(buff, field->comment.length); + comment_length+= field->comment.length; set_if_bigger(int_count,field->interval_id); if (my_write(file,(byte*) buff,FCOMP,MYF_RW)) DBUG_RETURN(1); @@ -505,6 +508,18 @@ static bool pack_fields(File file,List &create_fields) if (my_write(file,(byte*) tmp.ptr(),tmp.length(),MYF_RW)) DBUG_RETURN(1); } + if (comment_length) + { + it.rewind(); + int_count=0; + while ((field=it++)) + { + if (field->comment.length) + if (my_write(file, (byte*) field->comment.str, field->comment.length, + MYF_RW)) + DBUG_RETURN(1); + } + } DBUG_RETURN(0); } @@ -557,6 +572,7 @@ static bool make_empty_rec(File file,enum db_type table_type, null_pos+null_count/8, 1 << (null_count & 7), field->pack_flag, + field->sql_type, field->unireg_check, field->interval, field->field_name, -- cgit v1.2.1 From ebbcb0f391d7df364e0ccc6bca706456e9aadbf7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 3 Jun 2002 10:50:19 +0300 Subject: new error messages (foreign key) --- sql/share/czech/errmsg.txt | 6 ++++-- sql/share/danish/errmsg.txt | 4 +++- sql/share/dutch/errmsg.txt | 6 ++++-- sql/share/english/errmsg.txt | 4 +++- sql/share/estonian/errmsg.txt | 4 +++- sql/share/french/errmsg.txt | 6 ++++-- sql/share/german/errmsg.txt | 4 +++- sql/share/greek/errmsg.txt | 4 +++- sql/share/hungarian/errmsg.txt | 6 ++++-- sql/share/italian/errmsg.txt | 6 ++++-- sql/share/japanese/errmsg.txt | 6 ++++-- sql/share/korean/errmsg.txt | 6 ++++-- sql/share/norwegian-ny/errmsg.txt | 6 ++++-- sql/share/norwegian/errmsg.txt | 6 ++++-- sql/share/polish/errmsg.txt | 6 ++++-- sql/share/portuguese/errmsg.txt | 4 +++- sql/share/romanian/errmsg.txt | 4 +++- sql/share/russian/errmsg.txt | 4 +++- sql/share/serbian/errmsg.txt | 4 +++- sql/share/slovak/errmsg.txt | 6 ++++-- sql/share/spanish/errmsg.txt | 6 ++++-- sql/share/swedish/errmsg.txt | 8 +++++--- sql/share/ukrainian/errmsg.txt | 4 +++- 23 files changed, 83 insertions(+), 37 deletions(-) (limited to 'sql') diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 950ca4f6623..48c42b98261 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -156,7 +156,7 @@ "%-.16s p-Bøíkaz nepøístupný pro u¾ivatele: '%-.32s@%-.64s' pro sloupec '%-.64s' v tabulce '%-.64s'", "Neplatn-Bý pøíkaz GRANT/REVOKE. Prosím, pøeètìte si v manuálu, jaká privilegia je mo¾né pou¾ít.", "Argument p-Bøíkazu GRANT u¾ivatel nebo stroj je pøíli¹ dlouhý", -"Tabulka '%-64s.%s' neexistuje", +"Tabulka '%-.64s.%s' neexistuje", "Neexistuje odpov-Bídající grant pro u¾ivatele '%-.32s' na stroji '%-.64s' pro tabulku '%-.64s'", "Pou-B¾itý pøíkaz není v této verzi MySQL povolen", "Va-B¹e syntaxe je nìjaká divná", @@ -236,4 +236,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index d87ed4ee629..5fde80fd631 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -230,4 +230,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index c8b47cb3c19..6d48be9e724 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -155,7 +155,7 @@ "%-.16s commando geweigerd voor gebruiker: '%-.32s@%-.64s' voor kolom '%-.64s' in tabel '%-.64s'", "Foutief GRANT/REVOKE commando. Raadpleeg de handleiding welke priveleges gebruikt kunnen worden.", "De host of gebruiker parameter voor GRANT is te lang", -"Tabel '%-64s.%s' bestaat niet", +"Tabel '%-.64s.%s' bestaat niet", "Deze toegang (GRANT) is niet toegekend voor gebruiker '%-.32s' op host '%-.64s' op tabel '%-.64s'", "Het used commando is niet toegestaan in deze MySQL versie", "Er is iets fout in de gebruikte syntax", @@ -235,4 +235,6 @@ "Kan de query niet uitvoeren vanwege een conflicterende read lock", "Het combineren van transactionele en niet-transactionele tabellen is uitgeschakeld.", "Optie '%s' tweemaal gebruikt in opdracht", -"Gebruiker '%-64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)", +"Gebruiker '%-.64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 5033449c266..60710a07728 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 6a83468eae5..f902b93aa1f 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -232,4 +232,6 @@ "Ei suuda täita päringut konfliktse luku tõttu", "Transaktsioone toetavate ning mittetoetavate tabelite kooskasutamine ei ole lubatud", "Määrangut '%s' on lauses kasutatud topelt", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index cf3e3e845e4..6473b2a71f3 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -147,7 +147,7 @@ "%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 19d46fabab8..271fe8cbb66 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -230,4 +230,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index f9b4f137f82..d003c5c8ce6 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 38877371243..84ba644ce45 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -149,7 +149,7 @@ "%-.16s parancs a '%-.32s@%-.64s' felhasznalo szamara nem engedelyezett a '%-.64s' mezo eseten a '%-.64s' tablaban", "Ervenytelen GRANT/REVOKE parancs. Kerem, nezze meg a kezikonyvben, milyen jogok lehetsegesek", "A host vagy felhasznalo argumentuma tul hosszu a GRANT parancsban", -"A '%-64s.%s' tabla nem letezik", +"A '%-.64s.%s' tabla nem letezik", "A '%-.32s' felhasznalo szamara a '%-.64s' host '%-.64s' tablajaban ez a parancs nem engedelyezett", "A hasznalt parancs nem engedelyezett ebben a MySQL verzioban", "Szintaktikai hiba", @@ -229,4 +229,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index e8cfd5a63a9..37f574966b6 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -147,7 +147,7 @@ "Comando %-.16s negato per l'utente: '%-.32s@%-.64s' sulla colonna '%-.64s' della tabella '%-.64s'", "Comando GRANT/REVOKE illegale. Prego consultare il manuale per sapere quali privilegi possono essere usati.", "L'argomento host o utente per la GRANT e` troppo lungo", -"La tabella '%-64s.%s' non esiste", +"La tabella '%-.64s.%s' non esiste", "GRANT non definita per l'utente '%-.32s' dalla macchina '%-.64s' sulla tabella '%-.64s'", "Il comando utilizzato non e` supportato in questa versione di MySQL", "Errore di sintassi nella query SQL", @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 98bc099954f..157f891b310 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -149,7 +149,7 @@ "¥³¥Þ¥ó¥É %-.16s ¤Ï ¥æ¡¼¥¶¡¼ '%-.32s@%-.64s'\n ¥«¥é¥à '%-.64s' ¥Æ¡¼¥Ö¥ë '%-.64s' ¤ËÂФ·¤Æµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -229,4 +229,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index f6cc890cb39..12389919463 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -147,7 +147,7 @@ "'%-.16s' ¸í·ÉÀº ´ÙÀ½ »ç¿ëÀÚ¿¡°Ô °ÅºÎµÇ¾ú½À´Ï´Ù. : '%-.32s@%-.64s' for Ä®·³ '%-.64s' in Å×À̺í '%-.64s'", "À߸øµÈ GRANT/REVOKE ¸í·É. ¾î¶² ±Ç¸®¿Í ½ÂÀÎÀÌ »ç¿ëµÇ¾î Áú ¼ö ÀÖ´ÂÁö ¸Þ´º¾óÀ» º¸½Ã¿À.", "½ÂÀÎ(GRANT)À» À§ÇÏ¿© »ç¿ëÇÑ »ç¿ëÀÚ³ª È£½ºÆ®ÀÇ °ªµéÀÌ ³Ê¹« ±é´Ï´Ù.", -"Å×À̺í '%-64s.%s' ´Â Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.", +"Å×À̺í '%-.64s.%s' ´Â Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.", "»ç¿ëÀÚ '%-.32s'(È£½ºÆ® '%-.64s')´Â Å×À̺í '%-.64s'¸¦ »ç¿ëÇϱâ À§ÇÏ¿© Á¤ÀÇµÈ ½ÂÀÎÀº ¾ø½À´Ï´Ù. ", "»ç¿ëµÈ ¸í·ÉÀº ÇöÀçÀÇ MySQL ¹öÁ¯¿¡¼­´Â ÀÌ¿ëµÇÁö ¾Ê½À´Ï´Ù.", "SQL ±¸¹®¿¡ ¿À·ù°¡ ÀÖ½À´Ï´Ù.", @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index adffc27949f..40a25ac35b4 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -149,7 +149,7 @@ "%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -229,4 +229,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 09a1ea4684c..afe15ba3e44 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -149,7 +149,7 @@ "%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -229,4 +229,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 12a9bd358b5..ff8dcc70d49 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -151,7 +151,7 @@ "%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -231,4 +231,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index b7feb0a7b0d..55f986d14a3 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 8e48cabfc39..7a56df6e74e 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -231,4 +231,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 8ed33ec21a0..f3e778d6e28 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -230,4 +230,6 @@ "îÅ×ÏÚÍÏÖÎÏ ×ÙÐÏÌÎÉÔØ ÚÁÐÒÏÓ ÉÚ-ÚÁ ËÏÎÆÌÉËÔÎÏÊ ÂÌÏËÉÒÏ×ËÉ ÞÔÅÎÉÑ", "ïÄÎÏ×ÒÅÍÅÎÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ transactional É non-transactional ÔÁÂÌÉà ÏÔËÌÀÞÅÎÏ", "ïÐÃÉÑ '%s' ÉÓÐÏÌØÚÏ×ÁÎÁ Ä×ÁÖÄÙ", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 105860f0e4b..1b9ffe755f1 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -233,4 +233,6 @@ "Ne mogu da izvršim upit zbog toga što imate zakljuèavanja èitanja podataka u konfliktu", "Mešanje tabela koje podržavaju transakcije i onih koje ne podržavaju transakcije je iskljuèeno", "Opcija '%s' je upotrebljena dva puta u istom iskazu", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 06503cdf69e..aa2701022cc 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -155,7 +155,7 @@ "%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -235,4 +235,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 4240581c5b8..26306dfa3d9 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -148,7 +148,7 @@ "%-.16s comando negado para usuario: '%-.32s@%-.64s' para columna '%-.64s' en la tabla '%-.64s'", "Ilegal comando GRANT/REVOKE. Por favor consulte el manual para cuales permisos pueden ser usados.", "El argumento para servidor o usuario para GRANT es demasiado grande", -"Tabla '%-64s.%s' no existe", +"Tabla '%-.64s.%s' no existe", "No existe tal permiso definido para usuario '%-.32s' en el servidor '%-.64s' en la tabla '%-.64s'", "El comando usado no es permitido con esta versión de MySQL", "Algo está equivocado en su sintax", @@ -228,4 +228,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index e774f4a2c5c..3040d434354 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -61,7 +61,7 @@ "Kommandot har både sum functions och enkla funktioner", "Antalet kolumner motsvarar inte antalet värden", "Kolumn namn '%-.64s' är för långt", -"Kolumn namn '%-64s finns flera gånger", +"Kolumn namn '%-.64s finns flera gånger", "Nyckel namn '%-.64s' finns flera gånger", "Dubbel nyckel '%-.64s' för nyckel: %d", "Felaktigt kolumn typ för kolumn: '%-.64s'", @@ -147,7 +147,7 @@ "%-.16s ej tillåtet för '%-.32s@%-.64s'\n för kolumn '%-.64s' i tabell '%-.64s'", "Felaktigt GRANT privilegium använt", "Felaktigt maskinnamn eller användarnamn använt med GRANT", -"Det finns ingen tabell som heter '%-64s.%s'" +"Det finns ingen tabell som heter '%-.64s.%s'" "Det finns inget privilegium definierat för användare '%-.32s' på '%-.64s' för tabell '%-.64s'", "Du kan inte använda detta kommando med denna MySQL version", "Du har något fel i din syntax", @@ -227,4 +227,6 @@ "Kan inte utföra kommandot emedan du har ett READ lås", "Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat", "Option '%s' användes två gånger", -"Användare '%-64s' har överskridit '%s' (nuvarande värde: %ld)", +"Användare '%-.64s' har överskridit '%s' (nuvarande värde: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index c4c89433331..d32ec16952e 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -232,4 +232,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", -- cgit v1.2.1 From 08526ba32d9f4c353640b928edfdde862efc8596 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 4 Jun 2002 08:23:57 +0300 Subject: Changes for new binary .frm format Fixes after last merge from 4.0. (Code not yet complete, need anoter merge from 4.0) heap/hp_write.c: cleanup myisam/ft_boolean_search.c: Fixed tree handling to new format mysql-test/r/alter_table.result: SHOW FULL COLUMN FROM TABLE now returns comment mysql-test/r/func_math.result: Updated results mysql-test/r/heap_btree.result: Portability fix mysql-test/r/isam.result: SHOW FULL COLUMN FROM TABLE now returns comment mysql-test/r/show_check.result: SHOW FULL COLUMN FROM TABLE now returns comment mysql-test/t/heap_btree.test: Portability fix mysql-test/t/show_check.test: SHOW FULL COLUMN FROM TABLE now returns comment sql/field.cc: Fix for comment handling sql/field.h: Added CHARSET_INFO to field structure sql/item_cmpfunc.cc: Fixed like to use system charset (need to be updated) sql/item_func.cc: Update to new charset handling sql/mysql_priv.h: cleanup sql/sql_base.cc: Added charset to HA_CREATE_INFO sql/sql_delete.cc: Added charset to HA_CREATE_INFO sql/sql_parse.cc: Added charset to HA_CREATE_INFO sql/sql_select.cc: cleanup sql/sql_show.cc: charset change sql/sql_string.h: cleanup sql/sql_table.cc: cleanup sql/sql_yacc.yy: Go back to old code for ALTER table ... MODIFY sql/table.cc: fixed comment handling sql/unireg.cc: new field format --- sql/field.cc | 5 +++++ sql/field.h | 7 ++++--- sql/item_cmpfunc.cc | 31 ++++++++++++++++++++----------- sql/item_func.cc | 10 ++++++---- sql/mysql_priv.h | 2 +- sql/sql_base.cc | 10 ++++++---- sql/sql_delete.cc | 8 ++++++-- sql/sql_parse.cc | 3 +++ sql/sql_select.cc | 1 + sql/sql_show.cc | 3 ++- sql/sql_string.h | 9 +++++---- sql/sql_table.cc | 6 ++++-- sql/sql_yacc.yy | 25 +++++++++++++++++++------ sql/table.cc | 21 +++++++++++---------- sql/unireg.cc | 13 +++++++------ 15 files changed, 100 insertions(+), 54 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 43a46bb67a0..39e32a9cdc4 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -233,6 +233,8 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, field_length(length_arg),null_bit(null_bit_arg) { flags=null_ptr ? 0: NOT_NULL_FLAG; + comment.str= (char*) ""; + comment.length=0; } uint Field::offset() @@ -4861,6 +4863,8 @@ create_field::create_field(Field *old_field,Field *orig_field) unireg_check=old_field->unireg_check; pack_length=old_field->pack_length(); sql_type= old_field->real_type(); + charset= old_field->charset(); // May be NULL ptr + comment= old_field->comment; /* Fix if the original table had 4 byte pointer blobs */ if (flags & BLOB_FLAG) @@ -4869,6 +4873,7 @@ create_field::create_field(Field *old_field,Field *orig_field) decimals= old_field->decimals(); if (sql_type == FIELD_TYPE_STRING) { + /* Change CHAR -> VARCHAR if dynamic record length */ sql_type=old_field->type(); decimals=0; } diff --git a/sql/field.h b/sql/field.h index 7fb43ddd29f..f84b54271ce 100644 --- a/sql/field.h +++ b/sql/field.h @@ -190,6 +190,7 @@ public: uint fill_cache_field(struct st_cache_field *copy); virtual bool get_date(TIME *ltime,bool fuzzydate); virtual bool get_time(TIME *ltime); + virtual CHARSET_INFO *charset(void) { return 0; } friend bool reopen_table(THD *,struct st_table *,bool); friend int cre_myisam(my_string name, register TABLE *form, uint options, ulonglong auto_increment_value); @@ -249,10 +250,10 @@ public: { field_charset=charset; } Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } - friend class create_field; void make_field(Send_field *); uint size_of() const { return sizeof(*this); } - inline CHARSET_INFO *charset() const { return field_charset; } + CHARSET_INFO *charset(void) { return field_charset; } + inline void set_charset(CHARSET_INFO *charset) { field_charset=charset; } inline int cmp_image(char *buff,uint length) { @@ -261,7 +262,7 @@ public: else return my_strncasecmp(field_charset,ptr,buff,length); } - + friend class create_field; }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5fe232b6b80..4e25fae56b2 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1420,9 +1420,9 @@ Item_func_regex::~Item_func_regex() #ifdef LIKE_CMP_TOUPPER -#define likeconv(A) (uchar) toupper(A) +#define likeconv(cs,A) (uchar) (cs)->toupper(A) #else -#define likeconv(A) (uchar) my_sort_order[(uchar) (A)] +#define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)] #endif @@ -1436,7 +1436,8 @@ void Item_func_like::turboBM_compute_suffixes(int* suff) const int plm1 = pattern_len - 1; int f = 0; int g = plm1; - int* const splm1 = suff + plm1; + int *const splm1 = suff + plm1; + CHARSET_INFO *cs=system_charset_info; // QQ Needs to be fixed *splm1 = pattern_len; @@ -1472,7 +1473,8 @@ void Item_func_like::turboBM_compute_suffixes(int* suff) if (i < g) g = i; // g = min(i, g) f = i; - while (g >= 0 && likeconv(pattern[g]) == likeconv(pattern[g + plm1 - f])) + while (g >= 0 && likeconv(cs, pattern[g]) == + likeconv(cs, pattern[g + plm1 - f])) g--; suff[i] = f - g; } @@ -1533,19 +1535,25 @@ void Item_func_like::turboBM_compute_good_suffix_shifts(int* suff) void Item_func_like::turboBM_compute_bad_character_shifts() { - int* i; - int* end = bmBc + alphabet_size; + int *i; + int *end = bmBc + alphabet_size; + int j; + const int plm1 = pattern_len - 1; + CHARSET_INFO *cs=system_charset_info; // QQ Needs to be fixed + for (i = bmBc; i < end; i++) *i = pattern_len; - int j; - const int plm1 = pattern_len - 1; if (binary) + { for (j = 0; j < plm1; j++) bmBc[pattern[j]] = plm1 - j; + } else + { for (j = 0; j < plm1; j++) - bmBc[likeconv(pattern[j])] = plm1 - j; + bmBc[likeconv(cs,pattern[j])] = plm1 - j; + } } @@ -1561,6 +1569,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const int shift = pattern_len; int j = 0; int u = 0; + CHARSET_INFO *cs=system_charset_info; // QQ Needs to be fixed const int plm1 = pattern_len - 1; const int tlmpl = text_len - pattern_len; @@ -1602,7 +1611,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const while (j <= tlmpl) { register int i = plm1; - while (i >= 0 && likeconv(pattern[i]) == likeconv(text[i + j])) + while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j])) { i--; if (i == plm1 - shift) @@ -1613,7 +1622,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const register const int v = plm1 - i; turboShift = u - v; - bcShift = bmBc[likeconv(text[i + j])] - plm1 + i; + bcShift = bmBc[likeconv(cs, text[i + j])] - plm1 + i; shift = max(turboShift, bcShift); shift = max(shift, bmGs[i]); if (shift == bmGs[i]) diff --git a/sql/item_func.cc b/sql/item_func.cc index a9264b78b64..0675bf81dab 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2048,7 +2048,9 @@ void Item_func_match::init_search(bool no_order) return; if (key == NO_SUCH_KEY) - concat=new Item_func_concat_ws(new Item_string(" ",1), default_charset_info, fields); + concat=new Item_func_concat_ws(new Item_string(" ",1, + default_charset_info), + fields); if (master) { @@ -2256,12 +2258,12 @@ double Item_func_match::val() Item *get_system_var(LEX_STRING name) { - if (!my_strcasecmp(name.str,"IDENTITY")) + if (!my_strcasecmp(system_charset_info, name.str, "IDENTITY")) return new Item_int((char*) "@@IDENTITY", current_thd->insert_id(),21); - if (!my_strcasecmp(name.str,"VERSION")) + if (!my_strcasecmp(system_charset_info, name.str, "VERSION")) return new Item_string("@@VERSION",server_version, - (uint) strlen(server_version)); + (uint) strlen(server_version), system_charset_info); net_printf(¤t_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, name.str); return 0; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d98d44efb1f..e6c44f949ab 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -748,7 +748,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr); int wild_compare(const char *str,const char *str_end, const char *wildstr,const char *wildend,char escape); int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end, - const char *wildstr,const char *wildend,char escape); + const char *wildstr,const char *wildend,char escape); /* from hostname.cc */ struct in_addr; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 98b8ab83e9d..c9ef64b6da9 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2051,10 +2051,10 @@ static void mysql_rm_tmp_tables(void) /* -** CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with -** the proper arguments. This isn't very fast but it should work for most -** cases. -** One should normally create all indexes with CREATE TABLE or ALTER TABLE. + CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with + the proper arguments. This isn't very fast but it should work for most + cases. + One should normally create all indexes with CREATE TABLE or ALTER TABLE. */ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys) @@ -2066,6 +2066,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys) DBUG_ENTER("mysql_create_index"); bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; + create_info.table_charset=default_charset_info; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, fields, keys, drop, alter, (ORDER*)0, FALSE, @@ -2082,6 +2083,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List &drop) DBUG_ENTER("mysql_drop_index"); bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; + create_info.table_charset=default_charset_info; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, fields, keys, drop, alter, (ORDER*)0, FALSE, diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index c8ed74c9bca..48a738f9f6b 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -516,8 +516,9 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); bzero((char*) &create_info,sizeof(create_info)); create_info.auto_increment_value= table->file->auto_increment_value; - db_type table_type=table->db_type; + create_info.table_charset=default_charset_info; + db_type table_type=table->db_type; strmov(path,table->path); *table_ptr= table->next; // Unlink table from list close_temporary(table,0); @@ -527,7 +528,8 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) if ((error= (int) !(open_temporary_table(thd, path, table_list->db, table_list->real_name, 1)))) (void) rm_temporary_table(table_type, path); - /* Sasha: if we return here we will not have binloged the truncation and + /* + If we return here we will not have binloged the truncation and we will not send_ok() to the client. Yes, we do need better coverage testing, this bug has been here for a few months :-). */ @@ -557,6 +559,8 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) } bzero((char*) &create_info,sizeof(create_info)); + create_info.table_charset=default_charset_info; + *fn_ext(path)=0; // Remove the .frm extension error= ha_create_table(path,&create_info,1) ? -1 : 0; query_cache_invalidate3(thd, table_list, 0); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4dc6aef6154..d999271e3df 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1749,6 +1749,7 @@ mysql_execute_command(void) bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; create_info.row_type=ROW_TYPE_DEFAULT; + create_info.table_charset=default_charset_info; res= mysql_alter_table(thd, NullS, NullS, &create_info, tables, lex->create_list, lex->key_list, lex->drop_list, lex->alter_list, @@ -2866,6 +2867,8 @@ bool add_field_to_list(char *field_name, enum_field_types type, new_field->change=change; new_field->interval=0; new_field->pack_length=0; + new_field->charset=0; // QQ: To be fixed + if (!comment) { new_field->comment.str=0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a4a0a73dfb6..5e18299ef87 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4019,6 +4019,7 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, } MI_CREATE_INFO create_info; bzero((char*) &create_info,sizeof(create_info)); + if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES) create_info.data_file_length= ~(ulonglong) 0; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 86247397e0a..995142d6566 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1180,7 +1180,8 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables) pthread_mutex_lock(&LOCK_status); for (i=0; variables[i].name; i++) { - if (!(wild && wild[0] && wild_case_compare(variables[i].name,wild))) + if (!(wild && wild[0] && wild_case_compare(system_charset_info, + variables[i].name,wild))) { packet2.length(0); net_store_data(&packet2,convert,variables[i].name); diff --git a/sql/sql_string.h b/sql/sql_string.h index 5e5c9001590..e94981d22c3 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -213,16 +213,17 @@ public: uint32 numchars(); int charpos(int i,uint32 offset=0); -// added by Holyfoot for "geometry" needs int reserve(uint32 space_needed) { return realloc(str_length + space_needed); } int reserve(uint32 space_needed, uint32 grow_by); -// these append operations do NOT check alloced memory -// q_*** methods writes values of parameters itself -// qs_*** methods writes string representation of value + /* + The following append operations do NOT check alloced memory + q_*** methods writes values of parameters itself + qs_*** methods writes string representation of value + */ void q_append(const char &c) { Ptr[str_length++] = c; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a032adb1520..977571e1ff5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1577,12 +1577,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (cfield->change) { - if (!my_strcasecmp(system_charset_info,key_part_name, cfield->change)) + if (!my_strcasecmp(system_charset_info, key_part_name, + cfield->change)) break; } else if (!my_strcasecmp(system_charset_info, key_part_name, cfield->field_name)) - break; + break; } if (!cfield) continue; // Field is removed @@ -1618,6 +1619,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, key_list.push_back(key); } } + if (drop_list.elements) { my_error(ER_CANT_DROP_FIELD_OR_KEY,MYF(0),drop_list.head()->name); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 32af9a0197f..578cad25bb4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1147,7 +1147,7 @@ references: }; opt_ref_list: - /* empty */ {} + /* empty */ opt_on_delete {} | '(' ref_list ')' opt_on_delete {}; ref_list: @@ -1273,11 +1273,24 @@ alter_list_item: lex->change= $3.str; lex->simple_alter=0; } field_spec opt_place - | MODIFY_SYM opt_column field_spec - { - Lex->simple_alter=0; - } - opt_place + | MODIFY_SYM opt_column field_ident + { + LEX *lex=Lex; + lex->length=lex->dec=0; lex->type=0; lex->interval=0; + lex->default_value=lex->comment=0; + lex->simple_alter=0; + } + type opt_attribute + { + LEX *lex=Lex; + if (add_field_to_list($3.str, + (enum enum_field_types) $5, + lex->length,lex->dec,lex->type, + lex->default_value, lex->comment, + $3.str, lex->interval)) + YYABORT; + } + opt_place | DROP opt_column field_ident opt_restrict { LEX *lex=Lex; diff --git a/sql/table.cc b/sql/table.cc index a7571d2183f..201b67032bf 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -49,7 +49,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, interval_count,interval_parts,read_length,db_create_options; uint key_info_length, com_length; ulong pos; - char index_file[FN_REFLEN], *names,*keynames; + char index_file[FN_REFLEN], *names, *keynames, *comment_pos; uchar head[288],*disk_buff,new_field_pack_flag; my_string record; const char **int_array; @@ -58,7 +58,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, Field **field_ptr,*reg_field; KEY *keyinfo; KEY_PART_INFO *key_part; - uchar *null_pos, *comment_pos; + uchar *null_pos; uint null_bit, new_frm_ver, field_pack_length; SQL_CRYPT *crypted=0; DBUG_ENTER("openfrm"); @@ -292,7 +292,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->field=field_ptr; read_length=(uint) (outparam->fields * field_pack_length + - pos+ (uint) (n_length+int_length)); + pos+ (uint) (n_length+int_length+com_length)); if (read_string(file,(gptr*) &disk_buff,read_length)) goto err_not_open; /* purecov: inspected */ if (crypted) @@ -302,7 +302,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, crypted=0; } strpos= disk_buff+pos; - comment_pos=disk_buff+read_length-com_length; outparam->intervals= (TYPELIB*) (field_ptr+outparam->fields+1); int_array= (const char **) (outparam->intervals+interval_count); @@ -311,6 +310,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->intervals=0; // For better debugging memcpy((char*) names, strpos+(outparam->fields*field_pack_length), (uint) (n_length+int_length)); + comment_pos=names+(n_length+int_length); + memcpy(comment_pos, disk_buff+read_length-com_length, com_length); fix_type_pointers(&int_array,&outparam->fieldnames,1,&names); fix_type_pointers(&int_array,outparam->intervals,interval_count, @@ -489,13 +490,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, keyinfo->key_length ? UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG); if (i == 0) field->key_start|= ((key_map) 1 << key); - if ((ha_option & HA_HAVE_KEY_READ_ONLY) && - field->key_length() == key_part->length && + if (field->key_length() == key_part->length && field->type() != FIELD_TYPE_BLOB) { - if (field->key_type() != HA_KEYTYPE_TEXT || - (!(ha_option & HA_KEY_READ_WRONG_STR) && - !(keyinfo->flags & HA_FULLTEXT))) + if ((ha_option & HA_HAVE_KEY_READ_ONLY) && + (field->key_type() != HA_KEYTYPE_TEXT || + (!(ha_option & HA_KEY_READ_WRONG_STR) && + !(keyinfo->flags & HA_FULLTEXT)))) field->part_of_key|= ((key_map) 1 << key); if ((field->key_type() != HA_KEYTYPE_TEXT || !(keyinfo->flags & HA_FULLTEXT)) && @@ -1200,7 +1201,7 @@ db_type get_table_type(const char *name) error=my_read(file,(byte*) head,4,MYF(MY_NABP)); my_close(file,MYF(0)); if (error || head[0] != (uchar) 254 || head[1] != 1 || - (head[2] != FRM_VER && head[2] != FRM_VER+1)) + (head[2] < FRM_VER && head[2] > FRM_VER+2)) DBUG_RETURN(DB_TYPE_UNKNOWN); DBUG_RETURN(ha_checktype((enum db_type) (uint) *(head+3))); } diff --git a/sql/unireg.cc b/sql/unireg.cc index 7c4f199ab7f..863f71d1cce 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -28,7 +28,7 @@ #include "mysql_priv.h" #include -#define FCOMP 11 /* Byte for packed field */ +#define FCOMP 15 /* Bytes for a packed field */ static uchar * pack_screens(List &create_fields, uint *info_length, uint *screens, bool small_file); @@ -246,7 +246,7 @@ static uchar * pack_screens(List &create_fields, static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) { uint key_parts,length; - uchar *pos, *keyname_pos, *key_alg_pos; + uchar *pos, *keyname_pos; KEY *key,*end; KEY_PART_INFO *key_part,*key_part_end; DBUG_ENTER("pack_keys"); @@ -259,6 +259,7 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) int2store(pos+2,key->key_length); pos[4]= (uchar) key->key_parts; pos[5]= (uchar) key->algorithm; + pos[6]=pos[7]=0; // For the future pos+=8; key_parts+=key->key_parts; DBUG_PRINT("loop",("flags: %d key_parts: %d at %lx", @@ -295,7 +296,7 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) keybuff[1]=(uchar) key_parts; length=(uint) (keyname_pos-keybuff); int2store(keybuff+2,length); - length=(uint) (key_alg_pos-keyname_pos); + length=(uint) (pos-keyname_pos); int2store(keybuff+4,length); DBUG_RETURN((uint) (pos-keybuff)); } /* pack_keys */ @@ -309,8 +310,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, handler *file) { uint length,int_count,int_length,no_empty, int_parts; - uint time_stamp_pos,null_fields, com_length; - ulong reclength,totlength,n_length; + uint time_stamp_pos,null_fields; + ulong reclength, totlength, n_length, com_length; DBUG_ENTER("pack_header"); if (create_fields.elements > MAX_FIELDS) @@ -460,7 +461,7 @@ static bool pack_fields(File file,List &create_fields) buff[11]= (uchar) field->sql_type; buff[12]= (uchar) (field->charset ? field->charset->number : default_charset_info->number); - int2store(buff, field->comment.length); + int2store(buff+13, field->comment.length); comment_length+= field->comment.length; set_if_bigger(int_count,field->interval_id); if (my_write(file,(byte*) buff,FCOMP,MYF_RW)) -- cgit v1.2.1 From 4a1dec3dfbf750dab7fcd6a5c6785c28b96a3c65 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 5 Jun 2002 22:05:08 +0300 Subject: post-merged fixing --- sql/sql_parse.cc | 4 ++-- sql/sql_select.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 621f1d60a95..61a7f5e0ae5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1809,7 +1809,7 @@ mysql_execute_command(void) tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); if ((res=open_and_lock_tables(thd,tables))) break; - thd->select_limit=HA_POS_ERROR; + unit->select_limit_cnt= HA_POS_ERROR; if (!setup_fields(thd,tables,select_lex->item_list,1,0,0) && !setup_fields(thd,tables,lex->value_list,0,0,0) && ! thd->fatal_error && (result=new multi_update(thd,tables,select_lex->item_list,lex->duplicates, @@ -2776,7 +2776,7 @@ void mysql_init_multi_delete(LEX *lex) { lex->sql_command= SQLCOM_DELETE_MULTI; mysql_init_select(lex); - lex->select->select_limit= lex->select->master_union()->select_limit_cnt= + lex->select->select_limit= lex->select->master_unit()->select_limit_cnt= HA_POS_ERROR; lex->auxilliary_table_list= lex->select_lex.table_list; lex->select->init_query(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7e5130e93ab..d4f6504ec32 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2480,7 +2480,7 @@ make_simple_join(JOIN *join,TABLE *tmp_table) join->send_records=(ha_rows) 0; join->group=0; join->do_send_rows = 1; - join->row_limit=join->thd->select_limit; + join->row_limit=join->unit->select_limit_cnt; join_tab->cache.buff=0; /* No cacheing */ join_tab->table=tmp_table; @@ -7119,7 +7119,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, /* Don't log this into the slow query log */ select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED); - thd->offset_limit=0; + join->unit->offset_limit_cnt= 0; if (thd->lex.select == select_lex) { field_list.push_back(new Item_empty_string("table",NAME_LEN)); -- cgit v1.2.1 From 90ced85443e4563ab1a7f94581691d2b7e30bdaa Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 6 Jun 2002 16:28:22 +0300 Subject: Prevent needless rexecuting empty subselects --- sql/item_subselect.cc | 5 +++-- sql/item_subselect.h | 2 ++ sql/sql_class.cc | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index e18c8d78830..fc0228455ff 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -36,7 +36,7 @@ SUBSELECT TODO: #include "sql_select.h" Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex): - executed(0), optimized(0), error(0) + assigned(0), executed(0), optimized(0), error(0) { DBUG_ENTER("Item_subselect::Item_subselect"); DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex)); @@ -141,7 +141,7 @@ int Item_subselect::exec() return 1; } assign_null(); - executed= 0; + executed= assigned= 0; } if (!executed) { @@ -149,6 +149,7 @@ int Item_subselect::exec() join->thd->lex.select= select_lex; join->exec(); join->thd->lex.select= save_select; + executed= 1; return join->error; } return 0; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index e27f14fb83d..c6963df2d53 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -31,6 +31,7 @@ class Item_subselect :public Item protected: longlong int_value; double real_value; + my_bool assigned; /* value already assigned to subselect */ my_bool executed; /* simple subselect is executed */ my_bool optimized; /* simple subselect is optimized */ my_bool error; /* error in query */ @@ -59,6 +60,7 @@ public: max_length= item->max_length; decimals= item->decimals; res_type= item->res_type; + assigned= item->assigned; executed= item->executed; select_lex= item->select_lex; join= item->join; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0fb15c4342f..cd548f36cff 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -785,7 +785,7 @@ select_subselect::select_subselect(Item_subselect *item) bool select_subselect::send_data(List &items) { DBUG_ENTER("select_subselect::send_data"); - if (item->executed){ + if (item->assigned){ my_printf_error(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0)); DBUG_RETURN(1); } @@ -812,6 +812,6 @@ bool select_subselect::send_data(List &items) item->int_value= val_item->val_int(); item->res_type= val_item->result_type(); } - item->executed= 1; + item->assigned= 1; DBUG_RETURN(0); } -- cgit v1.2.1 From 6192996d17bb37e87a62a5e92f9e89330ccc6f28 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Jun 2002 16:47:36 +0500 Subject: heap_create() <-> heap_open() --- sql/ha_heap.cc | 180 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 90 insertions(+), 90 deletions(-) (limited to 'sql') diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 70409be4e42..f56bfe74265 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -33,92 +33,12 @@ const char **ha_heap::bas_ext() const int ha_heap::open(const char *name, int mode, uint test_if_locked) { - uint key,parts,mem_per_row=0; - ulong max_rows; - HP_KEYDEF *keydef; - HA_KEYSEG *seg; - - for (key=parts=0 ; key < table->keys ; key++) + if (!(file= heap_open(name, mode)) && my_errno == ENOENT) { - parts+=table->key_info[key].key_parts; - if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE) - parts++; /* additional HA_KEYTYPE_END keyseg */ + if (!create(name, table, NULL)) + file= heap_open(name, mode); } - - if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+ - parts*sizeof(HA_KEYSEG),MYF(MY_WME)))) - return my_errno; - seg=my_reinterpret_cast(HA_KEYSEG*) (keydef+table->keys); - for (key=0 ; key < table->keys ; key++) - { - KEY *pos=table->key_info+key; - KEY_PART_INFO *key_part= pos->key_part; - KEY_PART_INFO *key_part_end= key_part + pos->key_parts; - - mem_per_row+= (pos->key_length + (sizeof(char*) * 2)); - - keydef[key].keysegs= (uint) pos->key_parts; - keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); - keydef[key].seg= seg; - keydef[key].algorithm= pos->algorithm == HA_KEY_ALG_UNDEF ? - HA_KEY_ALG_HASH : pos->algorithm; - - for (; key_part != key_part_end ; key_part++, seg++) - { - uint flag= key_part->key_type; - Field *field= key_part->field; - if (pos->algorithm == HA_KEY_ALG_BTREE) - { - seg->type= field->key_type(); - } - else - { - if (!f_is_packed(flag) && - f_packtype(flag) == (int) FIELD_TYPE_DECIMAL && - !(flag & FIELDFLAG_BINARY)) - seg->type= (int) HA_KEYTYPE_TEXT; - else - seg->type= (int) HA_KEYTYPE_BINARY; - } - seg->start= (uint) key_part->offset; - seg->length= (uint) key_part->length; - seg->flag = 0; - seg->charset= field->binary() ? NULL : ((Field_str*)field)->charset(); - if (field->null_ptr) - { - seg->null_bit= field->null_bit; - seg->null_pos= (uint) (field->null_ptr- - (uchar*) table->record[0]); - } - else - { - seg->null_bit= 0; - seg->null_pos= 0; - } - } - if (pos->algorithm == HA_KEY_ALG_BTREE) - { - /* additional HA_KEYTYPE_END keyseg */ - seg->type= HA_KEYTYPE_END; - seg->length= sizeof(byte*); - seg->flag= 0; - seg->null_bit= 0; - seg++; - } - } - mem_per_row += MY_ALIGN(table->reclength+1, sizeof(char*)); - max_rows = (ulong) (max_heap_table_size / mem_per_row); - file=heap_open(name,mode, - table->keys,keydef, - table->reclength, - ((table->max_rows < max_rows && table->max_rows) ? - table->max_rows : max_rows), - table->min_rows); - my_free((gptr) keydef,MYF(0)); - if (file) - info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); - ref_length=sizeof(HEAP_PTR); - return (!file ? errno : 0); + return (file ? 0 : 1); } int ha_heap::close(void) @@ -274,7 +194,6 @@ THR_LOCK_DATA **ha_heap::store_lock(THD *thd, return to; } - /* We have to ignore ENOENT entries as the HEAP table is created on open and not when doing a CREATE on the table. @@ -291,7 +210,6 @@ int ha_heap::rename_table(const char * from, const char * to) return heap_rename(from,to); } - ha_rows ha_heap::records_in_range(int inx, const byte *start_key,uint start_key_len, enum ha_rkey_function start_search_flag, @@ -315,10 +233,92 @@ ha_rows ha_heap::records_in_range(int inx, } } - -int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info) - +int ha_heap::create(const char *name, TABLE *table, HA_CREATE_INFO *create_info) { + uint key, parts, mem_per_row= 0; + ulong max_rows; + HP_KEYDEF *keydef; + HA_KEYSEG *seg; char buff[FN_REFLEN]; - return heap_create(fn_format(buff,name,"","",4+2)); + int error; + + for (key= parts= 0; key < table->keys; key++) + { + parts+= table->key_info[key].key_parts; + if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE) + parts++; /* additional HA_KEYTYPE_END keyseg */ + } + + if (!(keydef= (HP_KEYDEF*) my_malloc(table->keys * sizeof(HP_KEYDEF) + + parts * sizeof(HA_KEYSEG), MYF(MY_WME)))) + return my_errno; + seg= my_reinterpret_cast(HA_KEYSEG*) (keydef + table->keys); + for (key= 0; key < table->keys; key++) + { + KEY *pos= table->key_info+key; + KEY_PART_INFO *key_part= pos->key_part; + KEY_PART_INFO *key_part_end= key_part + pos->key_parts; + + mem_per_row+= (pos->key_length + (sizeof(char*) * 2)); + + keydef[key].keysegs= (uint) pos->key_parts; + keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); + keydef[key].seg= seg; + keydef[key].algorithm= pos->algorithm == HA_KEY_ALG_UNDEF ? + HA_KEY_ALG_HASH : pos->algorithm; + + for (; key_part != key_part_end; key_part++, seg++) + { + uint flag= key_part->key_type; + Field *field= key_part->field; + if (pos->algorithm == HA_KEY_ALG_BTREE) + { + seg->type= field->key_type(); + } + else + { + if (!f_is_packed(flag) && + f_packtype(flag) == (int) FIELD_TYPE_DECIMAL && + !(flag & FIELDFLAG_BINARY)) + seg->type= (int) HA_KEYTYPE_TEXT; + else + seg->type= (int) HA_KEYTYPE_BINARY; + } + seg->start= (uint) key_part->offset; + seg->length= (uint) key_part->length; + seg->flag = 0; + seg->charset= field->binary() ? NULL : ((Field_str*)field)->charset(); + if (field->null_ptr) + { + seg->null_bit= field->null_bit; + seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]); + } + else + { + seg->null_bit= 0; + seg->null_pos= 0; + } + } + if (pos->algorithm == HA_KEY_ALG_BTREE) + { + /* additional HA_KEYTYPE_END keyseg */ + seg->type= HA_KEYTYPE_END; + seg->length= sizeof(byte*); + seg->flag= 0; + seg->null_bit= 0; + seg++; + } + } + mem_per_row+= MY_ALIGN(table->reclength + 1, sizeof(char*)); + max_rows= (ulong) (max_heap_table_size / mem_per_row); + error= heap_create(fn_format(buff,name,"","",4+2), + table->keys,keydef, table->reclength, + ((table->max_rows < max_rows && table->max_rows) ? + table->max_rows : max_rows), + table->min_rows); + my_free((gptr) keydef, MYF(0)); + if (file) + info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); + ref_length= sizeof(HEAP_PTR); + return (error); } -- cgit v1.2.1 From 6c2dcd86a3145177028b114def5c9fd3327cfb61 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Jun 2002 17:23:33 +0500 Subject: Charset of any string field now can be specified during CREATE TABLE mysql-test/r/alter_table.result: Fix test result according to new SHOW CREATE TABLE and SHOW FIELDS mysql-test/r/create.result: Fix test result according to new SHOW CREATE TABLE and SHOW FIELDS mysql-test/r/fulltext.result: Fix test result according to new SHOW CREATE TABLE and SHOW FIELDS mysql-test/r/innodb.result: Fix test result according to new SHOW CREATE TABLE and SHOW FIELDS mysql-test/r/merge.result: Fix test result according to new SHOW CREATE TABLE and SHOW FIELDS mysql-test/r/select.result: Fix test result according to new SHOW CREATE TABLE and SHOW FIELDS mysql-test/r/show_check.result: Fix test result according to new SHOW CREATE TABLE and SHOW FIELDS mysql-test/r/symlink.result: Fix test result according to new SHOW CREATE TABLE and SHOW FIELDS mysql-test/r/type_blob.result: Fix test result according to new SHOW CREATE TABLE and SHOW FIELDS mysql-test/r/type_ranges.result: Fix test result according to new SHOW CREATE TABLE and SHOW FIELDS sql/field.cc: New format for string fields in SHOW CREATE TABLE and SHOW FIELDS sql/mysql_priv.h: pass charset sql/sql_parse.cc: QQ is now fixed :) sql/sql_yacc.yy: New format for string fields in SHOW CREATE TABLE and SHOW FIELDS --- sql/field.cc | 15 +++++++++++++++ sql/mysql_priv.h | 2 +- sql/sql_parse.cc | 4 ++-- sql/sql_yacc.yy | 15 ++++++++------- 4 files changed, 26 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 39e32a9cdc4..1561f1831de 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3471,6 +3471,11 @@ void Field_string::sql_type(String &res) const res.length((uint) strlen(res.ptr())); if (binary_flag) res.append(" binary"); + else + { + res.append(" character set "); + res.append(field_charset->name); + } } @@ -3667,6 +3672,11 @@ void Field_varstring::sql_type(String &res) const res.length((uint) strlen(res.ptr())); if (binary_flag) res.append(" binary"); + else + { + res.append(" character set "); + res.append(field_charset->name); + } } char *Field_varstring::pack(char *to, const char *from, uint max_length) @@ -4154,6 +4164,11 @@ void Field_blob::sql_type(String &res) const } res.set(str,(uint) strlen(str),default_charset_info); res.append(binary_flag ? "blob" : "text"); + if (!binary_flag) + { + res.append(" character set "); + res.append(field_charset->name); + } } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index e6c44f949ab..6d26f5a1b9a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -484,7 +484,7 @@ bool add_field_to_list(char *field_name, enum enum_field_types type, char *length, char *decimal, uint type_modifier, Item *default_value, Item *comment, - char *change, TYPELIB *interval); + char *change, TYPELIB *interval,CHARSET_INFO *cs); void store_position_for_column(const char *name); bool add_to_list(SQL_LIST &list,Item *group,bool asc=0); TABLE_LIST *add_table_to_list(Table_ident *table,LEX_STRING *alias, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 790994b897e..b8ec541225a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2824,7 +2824,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, char *length, char *decimals, uint type_modifier, Item *default_value, Item *comment, - char *change, TYPELIB *interval) + char *change, TYPELIB *interval, CHARSET_INFO *cs) { register create_field *new_field; THD *thd=current_thd; @@ -2877,7 +2877,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, new_field->change=change; new_field->interval=0; new_field->pack_length=0; - new_field->charset=0; // QQ: To be fixed + new_field->charset=cs; if (!comment) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d9595e841b3..316996ac7c2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -958,6 +958,7 @@ field_spec: LEX *lex=Lex; lex->length=lex->dec=0; lex->type=0; lex->interval=0; lex->default_value=lex->comment=0; + lex->charset=default_charset_info; } type opt_attribute { @@ -966,7 +967,7 @@ field_spec: (enum enum_field_types) $3, lex->length,lex->dec,lex->type, lex->default_value, lex->comment, - lex->change,lex->interval)) + lex->change,lex->interval,lex->charset)) YYABORT; }; @@ -1009,11 +1010,11 @@ type: $$=FIELD_TYPE_LONG_BLOB; } | LONG_SYM VARBINARY { Lex->type|=BINARY_FLAG; $$=FIELD_TYPE_MEDIUM_BLOB; } - | LONG_SYM varchar { $$=FIELD_TYPE_MEDIUM_BLOB; } - | TINYTEXT { $$=FIELD_TYPE_TINY_BLOB; } - | TEXT_SYM { $$=FIELD_TYPE_BLOB; } - | MEDIUMTEXT { $$=FIELD_TYPE_MEDIUM_BLOB; } - | LONGTEXT { $$=FIELD_TYPE_LONG_BLOB; } + | LONG_SYM varchar opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } + | TINYTEXT opt_binary { $$=FIELD_TYPE_TINY_BLOB; } + | TEXT_SYM opt_binary { $$=FIELD_TYPE_BLOB; } + | MEDIUMTEXT opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } + | LONGTEXT opt_binary { $$=FIELD_TYPE_LONG_BLOB; } | DECIMAL_SYM float_options field_options { $$=FIELD_TYPE_DECIMAL;} | NUMERIC_SYM float_options field_options @@ -1287,7 +1288,7 @@ alter_list_item: (enum enum_field_types) $5, lex->length,lex->dec,lex->type, lex->default_value, lex->comment, - $3.str, lex->interval)) + $3.str, lex->interval, lex->charset)) YYABORT; } opt_place -- cgit v1.2.1 From b0c1e004670c7119b75e517cea77bf9894a00cb4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Jun 2002 21:26:43 +0300 Subject: temporary preventing subselect in HAVING clause --- sql/item_subselect.cc | 7 +++++++ sql/sql_class.cc | 4 ++-- sql/sql_class.h | 2 ++ sql/sql_select.cc | 6 +++++- 4 files changed, 16 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index fc0228455ff..c2349ed414c 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -102,6 +102,13 @@ void Item_subselect::make_field (Send_field *tmp_field) bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables) { + + if (thd->having_fix_field) + { + //TODO: subselects in having do not suported now + my_printf_error(ER_SYNTAX_ERROR, ER(ER_SYNTAX_ERROR), MYF(0)); + return 1; + } // Is it one field subselect? if (select_lex->item_list.elements != 1) { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cd548f36cff..86e4e6896e6 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -80,8 +80,8 @@ static void free_var(user_var_entry *entry) ****************************************************************************/ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), - insert_id_used(0),in_lock_tables(0), - global_read_lock(0),bootstrap(0) + insert_id_used(0), in_lock_tables(0), + global_read_lock(0), bootstrap(0), having_fix_field(0) { host=user=priv_user=db=query=ip=0; host_or_ip="unknown ip"; diff --git a/sql/sql_class.h b/sql/sql_class.h index 019217cb656..8a1a299ceee 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -428,6 +428,8 @@ public: bool query_error, bootstrap, cleanup_done; bool safe_to_cache_query; bool volatile killed; + // TRUE when having fix field called + bool having_fix_field; /* If we do a purge of binary logs, log index info of the threads that are currently reading it needs to be adjusted. To do that diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d4f6504ec32..c10174a7b71 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -229,7 +229,11 @@ JOIN::prepare(TABLE_LIST *tables_init, { thd->where="having clause"; thd->allow_sum_func=1; - if (having->fix_fields(thd,tables_list) || thd->fatal_error) + bool having_fix_field_store= thd->having_fix_field; + thd->having_fix_field= 1; + bool having_fix_rc= having->fix_fields(thd,tables_list); + thd->having_fix_field= having_fix_field_store; + if (having_fix_rc || thd->fatal_error) DBUG_RETURN(-1); /* purecov: inspected */ if (having->with_sum_func) having->split_sum_func(all_fields); -- cgit v1.2.1 From 9c7d06273b3f96625b7c6a3bbd57a6bf5fd19898 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 10 Jun 2002 21:10:57 +0500 Subject: Fixed that charset was not properly strored in index segment on myisam table --- sql/ha_myisam.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index a8bbc03aa91..e32656b44d3 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1046,7 +1046,8 @@ int ha_myisam::create(const char *name, register TABLE *table, keydef[i].seg[j].start= pos->key_part[j].offset; keydef[i].seg[j].length= pos->key_part[j].length; keydef[i].seg[j].bit_start=keydef[i].seg[j].bit_end=0; - keydef[i].seg[j].language=MY_CHARSET_CURRENT; + keydef[i].seg[j].language = field->binary() ? MY_CHARSET_CURRENT : + ((Field_str*)field)->charset()->number; if (field->null_ptr) { -- cgit v1.2.1 From e557317598691727af876a7155ec95a1e3071139 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 10 Jun 2002 20:22:31 +0300 Subject: deleted accidentally pushed file BitKeeper/deleted/.del-sql_select.cc.rej~b567fd439ef37cc8: Delete: sql/sql_select.cc.rej --- sql/sql_select.cc.rej | 1576 ------------------------------------------------- 1 file changed, 1576 deletions(-) delete mode 100644 sql/sql_select.cc.rej (limited to 'sql') diff --git a/sql/sql_select.cc.rej b/sql/sql_select.cc.rej deleted file mode 100644 index e5be98e9859..00000000000 --- a/sql/sql_select.cc.rej +++ /dev/null @@ -1,1576 +0,0 @@ -*************** -*** 65,71 **** - static int return_zero_rows(select_result *res,TABLE_LIST *tables, - List &fields, bool send_row, - uint select_options, const char *info, -- Item *having, Procedure *proc); - static COND *optimize_cond(COND *conds,Item::cond_result *cond_value); - static COND *remove_eq_conds(COND *cond,Item::cond_result *cond_value); - static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item); ---- 65,72 ---- - static int return_zero_rows(select_result *res,TABLE_LIST *tables, - List &fields, bool send_row, - uint select_options, const char *info, -+ Item *having, Procedure *proc, -+ SELECT_LEX *select_lex); - static COND *optimize_cond(COND *conds,Item::cond_result *cond_value); - static COND *remove_eq_conds(COND *cond,Item::cond_result *cond_value); - static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item); -*************** -*** 180,228 **** - ** mysql_select assumes that all tables are already opened - *****************************************************************************/ - - int -- mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, -- ORDER *order, ORDER *group,Item *having,ORDER *proc_param, -- ulong select_options,select_result *result) -- { -- TABLE *tmp_table; -- int error, tmp_error; -- bool need_tmp,hidden_group_fields; -- bool simple_order,simple_group,no_order, skip_sort_order, buffer_result; -- Item::cond_result cond_value; -- SQL_SELECT *select; -- DYNAMIC_ARRAY keyuse; -- JOIN join; -- Procedure *procedure; -- List all_fields(fields); -- bool select_distinct; -- SELECT_LEX *select_lex = &(thd->lex.select_lex); -- SELECT_LEX *cur_sel = thd->lex.select; -- DBUG_ENTER("mysql_select"); - -- /* Check that all tables, fields, conds and order are ok */ - -- select_distinct=test(select_options & SELECT_DISTINCT); -- buffer_result=test(select_options & OPTION_BUFFER_RESULT) && !test(select_options & OPTION_FOUND_ROWS); -- tmp_table=0; -- select=0; -- no_order=skip_sort_order=0; -- bzero((char*) &keyuse,sizeof(keyuse)); -- thd->proc_info="init"; -- thd->used_tables=0; // Updated by setup_fields - -- if (setup_tables(tables) || -- setup_fields(thd,tables,fields,1,&all_fields,1) || -- setup_conds(thd,tables,&conds) || -- setup_order(thd,tables,fields,all_fields,order) || -- setup_group(thd,tables,fields,all_fields,group,&hidden_group_fields)) - DBUG_RETURN(-1); /* purecov: inspected */ - - if (having) - { - thd->where="having clause"; - thd->allow_sum_func=1; -- if (having->fix_fields(thd,tables) || thd->fatal_error) - DBUG_RETURN(-1); /* purecov: inspected */ - if (having->with_sum_func) - having->split_sum_func(all_fields); ---- 195,237 ---- - ** mysql_select assumes that all tables are already opened - *****************************************************************************/ - -+ /* -+ Prepare of whole select (including subselect in future). -+ return -1 on error -+ 0 on success -+ */ - int - -+ JOIN::prepare(TABLE_LIST *tables_init, -+ COND *conds_init, ORDER *order_init, ORDER *group_init, -+ Item *having_init, -+ ORDER *proc_param_init, SELECT_LEX *select) -+ { -+ DBUG_ENTER("JOIN::prepare"); -+ -+ conds= conds_init; -+ order= order_init; -+ group_list= group_init; -+ having= having_init; -+ proc_param= proc_param_init; -+ tables_list= tables_init; -+ select_lex= select; - -+ /* Check that all tables, fields, conds and order are ok */ - -+ if (setup_tables(tables_list) || -+ setup_fields(thd,tables_list,fields_list,1,&all_fields,1) || -+ setup_conds(thd,tables_list,&conds) || -+ setup_order(thd,tables_list,fields_list,all_fields,order) || -+ setup_group(thd,tables_list,fields_list,all_fields,group_list, -+ &hidden_group_fields)) - DBUG_RETURN(-1); /* purecov: inspected */ - - if (having) - { - thd->where="having clause"; - thd->allow_sum_func=1; -+ if (having->fix_fields(thd,tables_list) || thd->fatal_error) - DBUG_RETURN(-1); /* purecov: inspected */ - if (having->with_sum_func) - having->split_sum_func(all_fields); -*************** -*** 297,347 **** - } - - /* Init join struct */ -- join.thd=thd; -- join.lock=thd->lock; -- join.join_tab=0; -- join.tmp_table_param.copy_field=0; -- join.sum_funcs=0; -- join.send_records=join.found_records=join.examined_rows=0; -- join.tmp_table_param.end_write_records= HA_POS_ERROR; -- join.first_record=join.sort_and_group=0; -- join.select_options=select_options; -- join.result=result; -- count_field_types(&join.tmp_table_param,all_fields,0); -- join.const_tables=0; -- join.having=0; -- join.do_send_rows = 1; -- join.group= group != 0; -- join.row_limit= ((select_distinct || order || group) ? HA_POS_ERROR : -- thd->select_limit); - - #ifdef RESTRICTED_GROUP -- if (join.sum_func_count && !group && (join.func_count || join.field_count)) - { - my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0)); - delete procedure; - DBUG_RETURN(-1); - } - #endif -- if (!procedure && result->prepare(fields)) - { /* purecov: inspected */ - DBUG_RETURN(-1); /* purecov: inspected */ - } - - #ifdef HAVE_REF_TO_FIELDS // Not done yet - /* Add HAVING to WHERE if possible */ -- if (having && !group && ! join.sum_func_count) - { - if (!conds) - { -- conds=having; -- having=0; - } - else if ((conds=new Item_cond_and(conds,having))) - { -- conds->fix_fields(thd,tables); -- conds->change_ref_to_fields(thd,tables); -- having=0; - } - } - #endif ---- 305,358 ---- - } - - /* Init join struct */ -+ count_field_types(&tmp_table_param, all_fields, 0); -+ this->group= group_list != 0; -+ row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR : -+ select_lex->first_in_union->select_limit_cnt); - - #ifdef RESTRICTED_GROUP -+ if (sum_func_count && !group_list && (func_count || field_count)) - { - my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0)); - delete procedure; - DBUG_RETURN(-1); - } - #endif -+ if (!procedure && result->prepare(fields_list, select_lex->first_in_union)) - { /* purecov: inspected */ - DBUG_RETURN(-1); /* purecov: inspected */ - } -+ DBUG_RETURN(0); // All OK -+ } -+ -+ /* -+ global select optimisation. -+ return 0 - success -+ 1 - go out -+ -1 - go out with cleaning -+ -+ error code saved in field 'error' -+ */ -+ int -+ JOIN::optimize() -+ { -+ DBUG_ENTER("JOIN::optimize"); -+ SELECT_LEX *select_lex = &(thd->lex.select_lex); - - #ifdef HAVE_REF_TO_FIELDS // Not done yet - /* Add HAVING to WHERE if possible */ -+ if (having && !group_list && ! sum_func_count) - { - if (!conds) - { -+ conds= having; -+ having= 0; - } - else if ((conds=new Item_cond_and(conds,having))) - { -+ conds->fix_fields(thd, tables_list); -+ conds->change_ref_to_fields(thd, tables_list); -+ having= 0; - } - } - #endif -*************** -*** 350,459 **** - if (thd->fatal_error) // Out of memory - { - delete procedure; -- DBUG_RETURN(0); - } -- if (cond_value == Item::COND_FALSE || !thd->select_limit) - { /* Impossible cond */ -- if (select_options & SELECT_DESCRIBE && select_lex->next) -- select_describe(&join,false,false,false,"Impossible WHERE"); -- else -- error=return_zero_rows(result, tables, fields, -- join.tmp_table_param.sum_func_count != 0 && !group, -- select_options,"Impossible WHERE",having, -- procedure); -- delete procedure; -- DBUG_RETURN(error); - } - - /* Optimize count(*), min() and max() */ -- if (tables && join.tmp_table_param.sum_func_count && ! group) - { - int res; -- if ((res=opt_sum_query(tables, all_fields, conds))) - { - if (res < 0) - { -- if (select_options & SELECT_DESCRIBE && select_lex->next) -- select_describe(&join,false,false,false,"No matching min/max row"); -- else -- error=return_zero_rows(result, tables, fields, !group, -- select_options,"No matching min/max row", -- having,procedure); -- delete procedure; -- DBUG_RETURN(error); - } - if (select_options & SELECT_DESCRIBE) - { - if (select_lex->next) -- select_describe(&join,false,false,false,"Select tables optimized away"); - else -- describe_info(thd,"Select tables optimized away"); - delete procedure; -- DBUG_RETURN(error); - } -- tables=0; // All tables resolved - } - } -- if (!tables) -- { // Only test of functions -- error=0; -- if (select_options & SELECT_DESCRIBE) -- { -- if (select_lex->next) -- select_describe(&join,false,false,false,"No tables used"); -- else -- describe_info(thd,"No tables used"); -- } -- else -- { -- result->send_fields(fields,1); -- if (!having || having->val_int()) -- { -- if (join.do_send_rows && result->send_data(fields)) -- { -- result->send_error(0,NullS); /* purecov: inspected */ -- error=1; -- } -- else -- error=(int) result->send_eof(); -- } -- else -- error=(int) result->send_eof(); -- } -- delete procedure; -- DBUG_RETURN(error); - } - -- error = -1; -- join.sort_by_table=get_sort_by_table(order,group,tables); - - /* Calculate how to do the join */ -- thd->proc_info="statistics"; -- if (make_join_statistics(&join,tables,conds,&keyuse) || thd->fatal_error) -- goto err; -- thd->proc_info="preparing"; -- result->initialize_tables(&join); -- if (join.const_table_map != join.found_const_table_map && - !(select_options & SELECT_DESCRIBE)) - { -- error=return_zero_rows(result,tables,fields, -- join.tmp_table_param.sum_func_count != 0 && -- !group,0,"",having,procedure); -- goto err; - } - if (!(thd->options & OPTION_BIG_SELECTS) && -- join.best_read > (double) thd->max_join_size && - !(select_options & SELECT_DESCRIBE)) - { /* purecov: inspected */ - result->send_error(ER_TOO_BIG_SELECT,ER(ER_TOO_BIG_SELECT)); /* purecov: inspected */ - error= 1; /* purecov: inspected */ -- goto err; /* purecov: inspected */ - } -- if (join.const_tables && !thd->locked_tables && - !(select_options & SELECT_NO_UNLOCK)) - { - TABLE **table, **end; -- for (table=join.table, end=table + join.const_tables ; - table != end; - table++) - { ---- 361,436 ---- - if (thd->fatal_error) // Out of memory - { - delete procedure; -+ error = 0; -+ DBUG_RETURN(1); - } -+ if (cond_value == Item::COND_FALSE || -+ !select_lex->first_in_union->select_limit_cnt) - { /* Impossible cond */ -+ zero_result_cause= "Impossible WHERE"; -+ DBUG_RETURN(0); - } - - /* Optimize count(*), min() and max() */ -+ if (tables_list && tmp_table_param.sum_func_count && ! group_list) - { - int res; -+ if ((res=opt_sum_query(tables_list, all_fields, conds))) - { - if (res < 0) - { -+ zero_result_cause= "No matching min/max row"; -+ DBUG_RETURN(0); - } - if (select_options & SELECT_DESCRIBE) - { - if (select_lex->next) -+ select_describe(this, false, false, false, -+ "Select tables optimized away"); - else -+ describe_info(thd, "Select tables optimized away"); - delete procedure; -+ DBUG_RETURN(1); - } -+ tables_list=0; // All tables resolved - } - } -+ if (!tables_list) -+ { -+ test_function_query= 1; -+ DBUG_RETURN(0); - } - -+ error= -1; -+ sort_by_table= get_sort_by_table(order, group_list, tables_list); - - /* Calculate how to do the join */ -+ thd->proc_info= "statistics"; -+ if (make_join_statistics(this, tables_list, conds, &keyuse) || -+ thd->fatal_error) -+ DBUG_RETURN(-1); -+ thd->proc_info= "preparing"; -+ result->initialize_tables(this); -+ if (const_table_map != found_const_table_map && - !(select_options & SELECT_DESCRIBE)) - { -+ zero_result_cause= ""; -+ select_options= 0; //TODO why option in return_zero_rows was droped -+ DBUG_RETURN(0); - } - if (!(thd->options & OPTION_BIG_SELECTS) && -+ best_read > (double) thd->max_join_size && - !(select_options & SELECT_DESCRIBE)) - { /* purecov: inspected */ - result->send_error(ER_TOO_BIG_SELECT,ER(ER_TOO_BIG_SELECT)); /* purecov: inspected */ - error= 1; /* purecov: inspected */ -+ DBUG_RETURN(-1); - } -+ if (const_tables && !thd->locked_tables && - !(select_options & SELECT_NO_UNLOCK)) - { - TABLE **table, **end; -+ for (table=this->table, end=table + const_tables ; - table != end; - table++) - { -*************** -*** 465,561 **** - } - (*table)->file->index_end(); - } -- mysql_unlock_some_tables(thd, join.table,join.const_tables); - } -- if (!conds && join.outer_join) - { - /* Handle the case where we have an OUTER JOIN without a WHERE */ - conds=new Item_int((longlong) 1,1); // Always true - } -- select=make_select(*join.table, join.const_table_map, -- join.const_table_map,conds,&error); - if (error) - { /* purecov: inspected */ - error= -1; /* purecov: inspected */ -- goto err; /* purecov: inspected */ - } -- if (make_join_select(&join,select,conds)) - { -- if (select_options & SELECT_DESCRIBE && select_lex->next) -- select_describe(&join,false,false,false,"Impossible WHERE noticed after reading const tables"); -- else -- error=return_zero_rows(result,tables,fields, -- join.tmp_table_param.sum_func_count != 0 && !group, -- select_options, -- "Impossible WHERE noticed after reading const tables", -- having,procedure); -- goto err; - } - - error= -1; /* if goto err */ - - /* Optimize distinct away if possible */ -- order=remove_const(&join,order,conds,&simple_order); -- if (group || join.tmp_table_param.sum_func_count) - { - if (! hidden_group_fields) - select_distinct=0; - } -- else if (select_distinct && join.tables - join.const_tables == 1 && -- (thd->select_limit == HA_POS_ERROR || -- (join.select_options & OPTION_FOUND_ROWS) || - order && - !(skip_sort_order= -- test_if_skip_sort_order(&join.join_tab[join.const_tables], -- order, thd->select_limit,1)))) - { -- if ((group=create_distinct_group(order,fields))) - { - select_distinct=0; - no_order= !order; -- join.group=1; // For end_write_group - } - else if (thd->fatal_error) // End of memory -- goto err; - } -- group=remove_const(&join,group,conds,&simple_group); -- if (!group && join.group) - { - order=0; // The output has only one row - simple_order=1; - } - -- calc_group_buffer(&join,group); -- join.send_group_parts=join.tmp_table_param.group_parts; /* Save org parts */ - if (procedure && procedure->group) - { -- group=procedure->group=remove_const(&join,procedure->group,conds, -- &simple_group); -- calc_group_buffer(&join,group); - } - -- if (test_if_subpart(group,order) || -- (!group && join.tmp_table_param.sum_func_count)) - order=0; - - // Can't use sort on head table if using row cache -- if (join.full_join) - { -- if (group) - simple_group=0; - if (order) - simple_order=0; - } - -- need_tmp= (join.const_tables != join.tables && - ((select_distinct || !simple_order || !simple_group) || -- (group && order) || buffer_result)); - - // No cache for MATCH -- make_join_readinfo(&join, - (select_options & (SELECT_DESCRIBE | - SELECT_NO_JOIN_CACHE)) | -- (cur_sel->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE : 0)); - - /* Need to tell Innobase that to play it safe, it should fetch all - columns of the tables: this is because MySQL ---- 442,535 ---- - } - (*table)->file->index_end(); - } -+ mysql_unlock_some_tables(thd, this->table, const_tables); - } -+ if (!conds && outer_join) - { - /* Handle the case where we have an OUTER JOIN without a WHERE */ - conds=new Item_int((longlong) 1,1); // Always true - } -+ select=make_select(*table, const_table_map, -+ const_table_map, conds, &error); - if (error) - { /* purecov: inspected */ - error= -1; /* purecov: inspected */ -+ DBUG_RETURN(-1); - } -+ if (make_join_select(this, select, conds)) - { -+ zero_result_cause= -+ "Impossible WHERE noticed after reading const tables"; -+ DBUG_RETURN(0); - } - - error= -1; /* if goto err */ - - /* Optimize distinct away if possible */ -+ order=remove_const(this,order,conds,&simple_order); -+ if (group_list || tmp_table_param.sum_func_count) - { - if (! hidden_group_fields) - select_distinct=0; - } -+ else if (select_distinct && tables - const_tables == 1 && -+ (select_lex->first_in_union->select_limit_cnt == HA_POS_ERROR || -+ (select_options & OPTION_FOUND_ROWS) || - order && - !(skip_sort_order= -+ test_if_skip_sort_order(&join_tab[const_tables], -+ order, -+ select_lex->first_in_union->select_limit_cnt, -+ 1)))) - { -+ if ((group_list=create_distinct_group(order, fields_list))) - { - select_distinct=0; - no_order= !order; -+ group=1; // For end_write_group - } - else if (thd->fatal_error) // End of memory -+ DBUG_RETURN(-1); - } -+ group_list= remove_const(this, group_list, conds, &simple_group); -+ if (!group_list && group) - { - order=0; // The output has only one row - simple_order=1; - } - -+ calc_group_buffer(this, group_list); -+ send_group_parts=tmp_table_param.group_parts; /* Save org parts */ - if (procedure && procedure->group) - { -+ group_list= procedure->group= remove_const(this, procedure->group, conds, -+ &simple_group); -+ calc_group_buffer(this, group_list); - } - -+ if (test_if_subpart(group_list, order) || -+ (!group_list && tmp_table_param.sum_func_count)) - order=0; - - // Can't use sort on head table if using row cache -+ if (full_join) - { -+ if (group_list) - simple_group=0; - if (order) - simple_order=0; - } - -+ need_tmp= (const_tables != tables && - ((select_distinct || !simple_order || !simple_group) || -+ (group_list && order) || buffer_result)); - - // No cache for MATCH -+ make_join_readinfo(this, - (select_options & (SELECT_DESCRIBE | - SELECT_NO_JOIN_CACHE)) | -+ (thd->lex.select->ftfunc_list.elements ? -+ SELECT_NO_JOIN_CACHE : 0)); - - /* Need to tell Innobase that to play it safe, it should fetch all - columns of the tables: this is because MySQL -*************** -*** 564,624 **** - by MySQL. */ - - #ifdef HAVE_INNOBASE_DB -- if (need_tmp || select_distinct || group || order) - { -- for (uint i_h = join.const_tables; i_h < join.tables; i_h++) - { -- TABLE* table_h = join.join_tab[i_h].table; - if (table_h->db_type == DB_TYPE_INNODB) - table_h->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE); - } - } - #endif - -- DBUG_EXECUTE("info",TEST_join(&join);); - /* - Because filesort always does a full table scan or a quick range scan - we must add the removed reference to the select for the table. - We only need to do this when we have a simple_order or simple_group - as in other cases the join is done before the sort. - */ -- if ((order || group) && join.join_tab[join.const_tables].type != JT_ALL && -- join.join_tab[join.const_tables].type != JT_FT && -- (order && simple_order || group && simple_group)) - { -- if (add_ref_to_table_cond(thd,&join.join_tab[join.const_tables])) -- goto err; - } - - if (!(select_options & SELECT_BIG_RESULT) && -- ((group && join.const_tables != join.tables && - (!simple_group || -- !test_if_skip_sort_order(&join.join_tab[join.const_tables], group, -- thd->select_limit,0))) || - select_distinct) && -- join.tmp_table_param.quick_group && !procedure) - { - need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort - } - - if (select_options & SELECT_DESCRIBE) - { - if (!order && !no_order) -- order=group; - if (order && -- (join.const_tables == join.tables || - (simple_order && -- test_if_skip_sort_order(&join.join_tab[join.const_tables], order, -- (join.const_tables != join.tables - 1 || -- (join.select_options & OPTION_FOUND_ROWS)) ? -- HA_POS_ERROR : thd->select_limit,0)))) - order=0; -- select_describe(&join,need_tmp, - (order != 0 && -- (!need_tmp || order != group || simple_group)), - select_distinct); - error=0; -- goto err; - } - - /* Perform FULLTEXT search before all regular searches */ ---- 538,672 ---- - by MySQL. */ - - #ifdef HAVE_INNOBASE_DB -+ if (need_tmp || select_distinct || group_list || order) - { -+ for (uint i_h = const_tables; i_h < tables; i_h++) - { -+ TABLE* table_h = join_tab[i_h].table; - if (table_h->db_type == DB_TYPE_INNODB) - table_h->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE); - } - } - #endif - -+ DBUG_EXECUTE("info",TEST_join(this);); - /* - Because filesort always does a full table scan or a quick range scan - we must add the removed reference to the select for the table. - We only need to do this when we have a simple_order or simple_group - as in other cases the join is done before the sort. - */ -+ if ((order || group_list) && join_tab[const_tables].type != JT_ALL && -+ join_tab[const_tables].type != JT_FT && -+ (order && simple_order || group_list && simple_group)) - { -+ if (add_ref_to_table_cond(thd,&join_tab[const_tables])) -+ DBUG_RETURN(-1); - } - - if (!(select_options & SELECT_BIG_RESULT) && -+ ((group_list && const_tables != tables && - (!simple_group || -+ !test_if_skip_sort_order(&join_tab[const_tables], group_list, -+ select_lex->first_in_union->select_limit_cnt, -+ 0))) || - select_distinct) && -+ tmp_table_param.quick_group && !procedure) - { - need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort - } -+ DBUG_RETURN(0); -+ } -+ -+ /* -+ global uptimisation (with subselect) must be here (TODO) -+ */ -+ -+ int -+ JOIN::global_optimize() -+ { -+ return 0; -+ } -+ -+ /* -+ exec select -+ */ -+ -+ void -+ JOIN::exec() -+ { -+ int tmp_error; -+ -+ DBUG_ENTER("JOIN::exec"); -+ -+ if (test_function_query) -+ { // Only test of functions -+ error=0; -+ if (select_options & SELECT_DESCRIBE) -+ { -+ if (select_lex->next) -+ select_describe(this, false, false, false, "No tables used"); -+ else -+ describe_info(thd, "No tables used"); -+ } -+ else -+ { -+ result->send_fields(fields_list,1); -+ if (!having || having->val_int()) -+ { -+ if (do_send_rows && result->send_data(fields_list)) -+ { -+ result->send_error(0,NullS); /* purecov: inspected */ -+ error=1; -+ } -+ else -+ error=(int) result->send_eof(); -+ } -+ else -+ error=(int) result->send_eof(); -+ } -+ delete procedure; -+ DBUG_VOID_RETURN; -+ } -+ -+ if (zero_result_cause) -+ { -+ if (select_options & SELECT_DESCRIBE && select_lex->next) -+ select_describe(this, false, false, false, zero_result_cause); -+ else -+ error=return_zero_rows(result, tables_list, fields_list, -+ tmp_table_param.sum_func_count != 0 && -+ !group_list, -+ select_options, -+ zero_result_cause, -+ having,procedure, -+ select_lex->first_in_union); -+ DBUG_VOID_RETURN; -+ } -+ -+ Item *having_list = having; -+ having = 0; - - if (select_options & SELECT_DESCRIBE) - { - if (!order && !no_order) -+ order=group_list; - if (order && -+ (const_tables == tables || - (simple_order && -+ test_if_skip_sort_order(&join_tab[const_tables], order, -+ (const_tables != tables - 1 || -+ (select_options & OPTION_FOUND_ROWS)) ? -+ HA_POS_ERROR : -+ select_lex->first_in_union->select_limit_cnt, -+ 0)))) - order=0; -+ select_describe(this, need_tmp, - (order != 0 && -+ (!need_tmp || order != group_list || simple_group)), - select_distinct); - error=0; -+ DBUG_VOID_RETURN; - } - - /* Perform FULLTEXT search before all regular searches */ -*************** -*** 630,673 **** - DBUG_PRINT("info",("Creating tmp table")); - thd->proc_info="Creating tmp table"; - -- if (!(tmp_table = -- create_tmp_table(thd,&join.tmp_table_param,all_fields, - ((!simple_group && !procedure && - !(test_flags & TEST_NO_KEY_GROUP)) ? -- group : (ORDER*) 0), -- group ? 0 : select_distinct, -- group && simple_group, - (order == 0 || skip_sort_order) && -- !(join.select_options & OPTION_FOUND_ROWS), -- join.select_options))) -- goto err; /* purecov: inspected */ -- -- if (having && (join.sort_and_group || (tmp_table->distinct && !group))) -- join.having=having; - - /* if group or order on first table, sort first */ -- if (group && simple_group) - { - DBUG_PRINT("info",("Sorting for group")); - thd->proc_info="Sorting for group"; -- if (create_sort_index(&join.join_tab[join.const_tables],group, - HA_POS_ERROR) || -- make_sum_func_list(&join,all_fields) || -- alloc_group_fields(&join,group)) -- goto err; -- group=0; - } - else - { -- if (make_sum_func_list(&join,all_fields)) -- goto err; -- if (!group && ! tmp_table->distinct && order && simple_order) - { - DBUG_PRINT("info",("Sorting for order")); - thd->proc_info="Sorting for order"; -- if (create_sort_index(&join.join_tab[join.const_tables],order, - HA_POS_ERROR)) -- goto err; /* purecov: inspected */ - order=0; - } - } ---- 678,722 ---- - DBUG_PRINT("info",("Creating tmp table")); - thd->proc_info="Creating tmp table"; - -+ if (!(exec_tmp_table = -+ create_tmp_table(thd,&tmp_table_param,all_fields, - ((!simple_group && !procedure && - !(test_flags & TEST_NO_KEY_GROUP)) ? -+ group_list : (ORDER*) 0), -+ group_list ? 0 : select_distinct, -+ group_list && simple_group, - (order == 0 || skip_sort_order) && -+ !(select_options & OPTION_FOUND_ROWS), -+ select_options, select_lex->first_in_union))) -+ DBUG_VOID_RETURN; -+ -+ if (having_list && -+ (sort_and_group || (exec_tmp_table->distinct && !group_list))) -+ having=having_list; - - /* if group or order on first table, sort first */ -+ if (group_list && simple_group) - { - DBUG_PRINT("info",("Sorting for group")); - thd->proc_info="Sorting for group"; -+ if (create_sort_index(&join_tab[const_tables],group_list, - HA_POS_ERROR) || -+ make_sum_func_list(this, all_fields) || -+ alloc_group_fields(this, group_list)) -+ DBUG_VOID_RETURN; -+ group_list=0; - } - else - { -+ if (make_sum_func_list(this, all_fields)) -+ DBUG_VOID_RETURN; -+ if (!group_list && ! exec_tmp_table->distinct && order && simple_order) - { - DBUG_PRINT("info",("Sorting for order")); - thd->proc_info="Sorting for order"; -+ if (create_sort_index(&join_tab[const_tables], order, - HA_POS_ERROR)) -+ DBUG_VOID_RETURN; - order=0; - } - } -*************** -*** 678,735 **** - In this case we can stop scanning t2 when we have found one t1.a - */ - -- if (tmp_table->distinct) - { - table_map used_tables= thd->used_tables; -- JOIN_TAB *join_tab=join.join_tab+join.tables-1; - do - { - if (used_tables & join_tab->table->map) - break; - join_tab->not_used_in_distinct=1; -- } while (join_tab-- != join.join_tab); - /* Optimize "select distinct b from t1 order by key_part_1 limit #" */ - if (order && skip_sort_order) - { -- (void) test_if_skip_sort_order(&join.join_tab[join.const_tables], -- order, thd->select_limit,0); - order=0; - } - } - - /* Copy data to the temporary table */ - thd->proc_info="Copying to tmp table"; -- if ((tmp_error=do_select(&join,(List *) 0,tmp_table,0))) - { -- error=tmp_error; -- goto err; /* purecov: inspected */ - } -- if (join.having) -- join.having=having=0; // Allready done - - /* Change sum_fields reference to calculated fields in tmp_table */ -- if (join.sort_and_group || tmp_table->group) - { - if (change_to_use_tmp_fields(all_fields)) -- goto err; -- join.tmp_table_param.field_count+=join.tmp_table_param.sum_func_count+ -- join.tmp_table_param.func_count; -- join.tmp_table_param.sum_func_count=join.tmp_table_param.func_count=0; - } - else - { - if (change_refs_to_tmp_fields(thd,all_fields)) -- goto err; -- join.tmp_table_param.field_count+=join.tmp_table_param.func_count; -- join.tmp_table_param.func_count=0; - } - if (procedure) - procedure->update_refs(); -- if (tmp_table->group) - { // Already grouped - if (!order && !no_order) -- order=group; /* order by group */ -- group=0; - } - - /* ---- 727,786 ---- - In this case we can stop scanning t2 when we have found one t1.a - */ - -+ if (exec_tmp_table->distinct) - { - table_map used_tables= thd->used_tables; -+ JOIN_TAB *join_tab= this->join_tab+tables-1; - do - { - if (used_tables & join_tab->table->map) - break; - join_tab->not_used_in_distinct=1; -+ } while (join_tab-- != this->join_tab); - /* Optimize "select distinct b from t1 order by key_part_1 limit #" */ - if (order && skip_sort_order) - { -+ (void) test_if_skip_sort_order(&this->join_tab[const_tables], -+ order, -+ select_lex->first_in_union->select_limit_cnt, -+ 0); - order=0; - } - } - - /* Copy data to the temporary table */ - thd->proc_info="Copying to tmp table"; -+ if ((tmp_error=do_select(this, (List *) 0, exec_tmp_table, 0))) - { -+ error= tmp_error; -+ DBUG_VOID_RETURN; - } -+ if (having) -+ having= having_list= 0; // Allready done - - /* Change sum_fields reference to calculated fields in tmp_table */ -+ if (sort_and_group || exec_tmp_table->group) - { - if (change_to_use_tmp_fields(all_fields)) -+ DBUG_VOID_RETURN; -+ tmp_table_param.field_count+= tmp_table_param.sum_func_count+ -+ tmp_table_param.func_count; -+ tmp_table_param.sum_func_count= tmp_table_param.func_count= 0; - } - else - { - if (change_refs_to_tmp_fields(thd,all_fields)) -+ DBUG_VOID_RETURN; -+ tmp_table_param.field_count+= tmp_table_param.func_count; -+ tmp_table_param.func_count= 0; - } - if (procedure) - procedure->update_refs(); -+ if (exec_tmp_table->group) - { // Already grouped - if (!order && !no_order) -+ order= group_list; /* order by group */ -+ group_list= 0; - } - - /* -*************** -*** 740,892 **** - ** like SEC_TO_TIME(SUM(...)). - */ - -- if (group && (!test_if_subpart(group,order) || select_distinct) || - (select_distinct && -- join.tmp_table_param.using_indirect_summary_function)) - { /* Must copy to another table */ - TABLE *tmp_table2; - DBUG_PRINT("info",("Creating group table")); - - /* Free first data from old join */ -- join_free(&join); -- if (make_simple_join(&join,tmp_table)) -- goto err; -- calc_group_buffer(&join,group); -- count_field_types(&join.tmp_table_param,all_fields, -- select_distinct && !group); -- join.tmp_table_param.hidden_field_count=(all_fields.elements- -- fields.elements); - - /* group data to new table */ -- if (!(tmp_table2 = create_tmp_table(thd,&join.tmp_table_param,all_fields, - (ORDER*) 0, -- select_distinct && !group, - 1, 0, -- join.select_options))) -- goto err; /* purecov: inspected */ -- if (group) - { - thd->proc_info="Creating sort index"; -- if (create_sort_index(join.join_tab,group,HA_POS_ERROR) || -- alloc_group_fields(&join,group)) - { - free_tmp_table(thd,tmp_table2); /* purecov: inspected */ -- goto err; /* purecov: inspected */ - } -- group=0; - } - thd->proc_info="Copying to group table"; - tmp_error= -1; -- if (make_sum_func_list(&join,all_fields) || -- (tmp_error=do_select(&join,(List *) 0,tmp_table2,0))) - { - error=tmp_error; - free_tmp_table(thd,tmp_table2); -- goto err; /* purecov: inspected */ - } -- end_read_record(&join.join_tab->read_record); -- free_tmp_table(thd,tmp_table); -- join.const_tables=join.tables; // Mark free for join_free() -- tmp_table=tmp_table2; -- join.join_tab[0].table=0; // Table is freed - - if (change_to_use_tmp_fields(all_fields)) // No sum funcs anymore -- goto err; -- join.tmp_table_param.field_count+=join.tmp_table_param.sum_func_count; -- join.tmp_table_param.sum_func_count=0; - } - -- if (tmp_table->distinct) - select_distinct=0; /* Each row is unique */ - -- join_free(&join); /* Free quick selects */ -- if (select_distinct && ! group) - { - thd->proc_info="Removing duplicates"; -- if (having) -- having->update_used_tables(); -- if (remove_duplicates(&join,tmp_table,fields, having)) -- goto err; /* purecov: inspected */ -- having=0; - select_distinct=0; - } -- tmp_table->reginfo.lock_type=TL_UNLOCK; -- if (make_simple_join(&join,tmp_table)) -- goto err; -- calc_group_buffer(&join,group); -- count_field_types(&join.tmp_table_param,all_fields,0); - } - if (procedure) - { -- if (procedure->change_columns(fields) || -- result->prepare(fields)) -- goto err; -- count_field_types(&join.tmp_table_param,all_fields,0); - } -- if (join.group || join.tmp_table_param.sum_func_count || - (procedure && (procedure->flags & PROC_GROUP))) - { -- alloc_group_fields(&join,group); -- setup_copy_fields(thd, &join.tmp_table_param,all_fields); -- if (make_sum_func_list(&join,all_fields) || thd->fatal_error) -- goto err; /* purecov: inspected */ - } -- if (group || order) - { - DBUG_PRINT("info",("Sorting for send_fields")); - thd->proc_info="Sorting result"; - /* If we have already done the group, add HAVING to sorted table */ -- if (having && ! group && ! join.sort_and_group) - { -- having->update_used_tables(); // Some tables may have been const -- JOIN_TAB *table=&join.join_tab[join.const_tables]; -- table_map used_tables= join.const_table_map | table->table->map; - -- Item* sort_table_cond=make_cond_for_table(having,used_tables,used_tables); - if (sort_table_cond) - { - if (!table->select) - if (!(table->select=new SQL_SELECT)) -- goto err; - if (!table->select->cond) - table->select->cond=sort_table_cond; - else // This should never happen - if (!(table->select->cond=new Item_cond_and(table->select->cond, - sort_table_cond))) -- goto err; - table->select_cond=table->select->cond; - DBUG_EXECUTE("where",print_where(table->select->cond, - "select and having");); -- having=make_cond_for_table(having,~ (table_map) 0,~used_tables); - DBUG_EXECUTE("where",print_where(conds,"having after sort");); - } - } -- if (create_sort_index(&join.join_tab[join.const_tables], -- group ? group : order, -- (having || group || -- join.const_tables != join.tables - 1 || -- (join.select_options & OPTION_FOUND_ROWS)) ? -- HA_POS_ERROR : thd->select_limit)) -- goto err; /* purecov: inspected */ - } -- join.having=having; // Actually a parameter - thd->proc_info="Sending data"; -- error=do_select(&join,&fields,NULL,procedure); - -- err: -- thd->limit_found_rows = join.send_records; -- thd->examined_row_count = join.examined_rows; -- thd->proc_info="end"; -- join.lock=0; // It's faster to unlock later -- join_free(&join); -- thd->proc_info="end2"; // QQ -- if (tmp_table) -- free_tmp_table(thd,tmp_table); -- thd->proc_info="end3"; // QQ - delete select; - delete_dynamic(&keyuse); - delete procedure; -- thd->proc_info="end4"; // QQ - DBUG_RETURN(error); - } - ---- 791,987 ---- - ** like SEC_TO_TIME(SUM(...)). - */ - -+ if (group_list && (!test_if_subpart(group_list,order) || select_distinct) || - (select_distinct && -+ tmp_table_param.using_indirect_summary_function)) - { /* Must copy to another table */ - TABLE *tmp_table2; - DBUG_PRINT("info",("Creating group table")); - - /* Free first data from old join */ -+ join_free(this); -+ if (make_simple_join(this, exec_tmp_table)) -+ DBUG_VOID_RETURN; -+ calc_group_buffer(this, group_list); -+ count_field_types(&tmp_table_param, all_fields, -+ select_distinct && !group_list); -+ tmp_table_param.hidden_field_count= (all_fields.elements- -+ fields_list.elements); - - /* group data to new table */ -+ if (!(tmp_table2 = create_tmp_table(thd,&tmp_table_param, all_fields, - (ORDER*) 0, -+ select_distinct && !group_list, - 1, 0, -+ select_options, -+ select_lex->first_in_union))) -+ DBUG_VOID_RETURN; -+ if (group_list) - { - thd->proc_info="Creating sort index"; -+ if (create_sort_index(join_tab,group_list,HA_POS_ERROR) || -+ alloc_group_fields(this, group_list)) - { - free_tmp_table(thd,tmp_table2); /* purecov: inspected */ -+ DBUG_VOID_RETURN; - } -+ group_list=0; - } - thd->proc_info="Copying to group table"; - tmp_error= -1; -+ if (make_sum_func_list(this, all_fields) || -+ (tmp_error=do_select(this, (List *) 0,tmp_table2,0))) - { - error=tmp_error; - free_tmp_table(thd,tmp_table2); -+ DBUG_VOID_RETURN; - } -+ end_read_record(&join_tab->read_record); -+ free_tmp_table(thd,exec_tmp_table); -+ const_tables= tables; // Mark free for join_free() -+ exec_tmp_table= tmp_table2; -+ join_tab[0].table= 0; // Table is freed - - if (change_to_use_tmp_fields(all_fields)) // No sum funcs anymore -+ DBUG_VOID_RETURN; -+ tmp_table_param.field_count+= tmp_table_param.sum_func_count; -+ tmp_table_param.sum_func_count=0; - } - -+ if (exec_tmp_table->distinct) - select_distinct=0; /* Each row is unique */ - -+ join_free(this); /* Free quick selects */ -+ if (select_distinct && ! group_list) - { - thd->proc_info="Removing duplicates"; -+ if (having_list) -+ having_list->update_used_tables(); -+ if (remove_duplicates(this, exec_tmp_table, fields_list, having_list)) -+ DBUG_VOID_RETURN; -+ having_list=0; - select_distinct=0; - } -+ exec_tmp_table->reginfo.lock_type=TL_UNLOCK; -+ if (make_simple_join(this, exec_tmp_table)) -+ DBUG_VOID_RETURN; -+ calc_group_buffer(this, group_list); -+ count_field_types(&tmp_table_param, all_fields, 0); - } - if (procedure) - { -+ if (procedure->change_columns(fields_list) || -+ result->prepare(fields_list, select_lex->first_in_union)) -+ DBUG_VOID_RETURN; -+ count_field_types(&tmp_table_param,all_fields,0); - } -+ if (group || tmp_table_param.sum_func_count || - (procedure && (procedure->flags & PROC_GROUP))) - { -+ alloc_group_fields(this, group_list); -+ setup_copy_fields(thd, &tmp_table_param,all_fields); -+ if (make_sum_func_list(this, all_fields) || thd->fatal_error) -+ DBUG_VOID_RETURN; - } -+ if (group_list || order) - { - DBUG_PRINT("info",("Sorting for send_fields")); - thd->proc_info="Sorting result"; - /* If we have already done the group, add HAVING to sorted table */ -+ if (having_list && ! group_list && ! sort_and_group) - { -+ having_list->update_used_tables(); // Some tables may have been const -+ JOIN_TAB *table=&join_tab[const_tables]; -+ table_map used_tables= const_table_map | table->table->map; - -+ Item* sort_table_cond=make_cond_for_table(having_list, used_tables, -+ used_tables); - if (sort_table_cond) - { - if (!table->select) - if (!(table->select=new SQL_SELECT)) -+ DBUG_VOID_RETURN; - if (!table->select->cond) - table->select->cond=sort_table_cond; - else // This should never happen - if (!(table->select->cond=new Item_cond_and(table->select->cond, - sort_table_cond))) -+ DBUG_VOID_RETURN; - table->select_cond=table->select->cond; - DBUG_EXECUTE("where",print_where(table->select->cond, - "select and having");); -+ having_list= make_cond_for_table(having_list, ~ (table_map) 0, -+ ~used_tables); - DBUG_EXECUTE("where",print_where(conds,"having after sort");); - } - } -+ if (create_sort_index(&join_tab[const_tables], -+ group_list ? group_list : order, -+ (having_list || group_list || -+ const_tables != tables - 1 || -+ (select_options & OPTION_FOUND_ROWS)) ? -+ HA_POS_ERROR : -+ select_lex->first_in_union->select_limit_cnt)) -+ DBUG_VOID_RETURN; - } -+ having=having_list; // Actually a parameter - thd->proc_info="Sending data"; -+ error=do_select(this, &fields_list, NULL, procedure); -+ DBUG_VOID_RETURN; -+ } - -+ /* -+ Clean up join. Return error that hold JOIN. -+ */ -+ -+ int -+ JOIN::cleanup(THD *thd) -+ { -+ lock=0; // It's faster to unlock later -+ join_free(this); -+ if (exec_tmp_table) -+ free_tmp_table(thd, exec_tmp_table); - delete select; - delete_dynamic(&keyuse); - delete procedure; -+ return error; -+ } -+ -+ int -+ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, -+ ORDER *order, ORDER *group,Item *having,ORDER *proc_param, -+ ulong select_options,select_result *result) -+ { -+ JOIN *join = new JOIN(thd, fields, select_options, result); -+ -+ DBUG_ENTER("mysql_select"); -+ thd->proc_info="init"; -+ thd->used_tables=0; // Updated by setup_fields -+ -+ if (join->prepare(tables, conds, order, group, having, proc_param, -+ &(thd->lex.select_lex))) -+ { -+ DBUG_RETURN(-1); -+ } -+ switch(join->optimize()) -+ { -+ case 1: -+ DBUG_RETURN(join->error); -+ case -1: -+ goto err; -+ } -+ -+ if(join->global_optimize()) -+ goto err; -+ -+ join->exec(); -+ -+ err: -+ thd->limit_found_rows = join->send_records; -+ thd->examined_row_count = join->examined_rows; -+ thd->proc_info="end"; -+ int error= join->cleanup(thd); -+ delete join; - DBUG_RETURN(error); - } - -*************** -*** 2480,2486 **** - - if ((tab->keys & ~ tab->const_keys && i > 0) || - (tab->const_keys && i == join->const_tables && -- join->thd->select_limit < join->best_positions[i].records_read && - !(join->select_options & OPTION_FOUND_ROWS))) - { - /* Join with outer join condition */ ---- 2575,2582 ---- - - if ((tab->keys & ~ tab->const_keys && i > 0) || - (tab->const_keys && i == join->const_tables && -+ join->select_lex->first_in_union->select_limit_cnt < -+ join->best_positions[i].records_read && - !(join->select_options & OPTION_FOUND_ROWS))) - { - /* Join with outer join condition */ -*************** -*** 2491,2497 **** - (join->select_options & - OPTION_FOUND_ROWS ? - HA_POS_ERROR : -- join->thd->select_limit)) < 0) - DBUG_RETURN(1); // Impossible range - sel->cond=orig_cond; - } ---- 2587,2593 ---- - (join->select_options & - OPTION_FOUND_ROWS ? - HA_POS_ERROR : -+ join->select_lex->first_in_union->select_limit_cnt)) < 0) - DBUG_RETURN(1); // Impossible range - sel->cond=orig_cond; - } -*************** -*** 2933,2939 **** - static int - return_zero_rows(select_result *result,TABLE_LIST *tables,List &fields, - bool send_row, uint select_options,const char *info, -- Item *having, Procedure *procedure) - { - DBUG_ENTER("return_zero_rows"); - ---- 3029,3035 ---- - static int - return_zero_rows(select_result *result,TABLE_LIST *tables,List &fields, - bool send_row, uint select_options,const char *info, -+ Item *having, Procedure *procedure, SELECT_LEX *select_lex) - { - DBUG_ENTER("return_zero_rows"); - -*************** -*** 2944,2950 **** - } - if (procedure) - { -- if (result->prepare(fields)) // This hasn't been done yet - DBUG_RETURN(-1); - } - if (send_row) ---- 3040,3047 ---- - } - if (procedure) - { -+ if (result->prepare(fields, -+ select_lex->first_in_union))//This hasn't been done yet - DBUG_RETURN(-1); - } - if (send_row) -*************** -*** 3479,3485 **** - TABLE * - create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, - ORDER *group, bool distinct, bool save_sum_fields, -- bool allow_distinct_limit, ulong select_options) - { - TABLE *table; - uint i,field_count,reclength,null_count,null_pack_length, ---- 3576,3583 ---- - TABLE * - create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, - ORDER *group, bool distinct, bool save_sum_fields, -+ bool allow_distinct_limit, ulong select_options, -+ SELECT_LEX *first_select) - { - TABLE *table; - uint i,field_count,reclength,null_count,null_pack_length, -*************** -*** 3850,3857 **** - test(null_pack_length)); - if (allow_distinct_limit) - { -- set_if_smaller(table->max_rows,thd->select_limit); -- param->end_write_records=thd->select_limit; - } - else - param->end_write_records= HA_POS_ERROR; ---- 3948,3955 ---- - test(null_pack_length)); - if (allow_distinct_limit) - { -+ set_if_smaller(table->max_rows,first_select->select_limit_cnt); -+ param->end_write_records=first_select->select_limit_cnt; - } - else - param->end_write_records= HA_POS_ERROR; -*************** -*** 4896,4902 **** - error=join->result->send_data(*join->fields); - if (error) - DBUG_RETURN(-1); /* purecov: inspected */ -- if (++join->send_records >= join->thd->select_limit && join->do_send_rows) - { - if (join->select_options & OPTION_FOUND_ROWS) - { ---- 4994,5002 ---- - error=join->result->send_data(*join->fields); - if (error) - DBUG_RETURN(-1); /* purecov: inspected */ -+ if (++join->send_records >= -+ join->select_lex->first_in_union->select_limit_cnt && -+ join->do_send_rows) - { - if (join->select_options & OPTION_FOUND_ROWS) - { -*************** -*** 4912,4918 **** - else - { - join->do_send_rows=0; -- join->thd->select_limit = HA_POS_ERROR; - DBUG_RETURN(0); - } - } ---- 5012,5018 ---- - else - { - join->do_send_rows=0; -+ join->select_lex->first_in_union->select_limit_cnt = HA_POS_ERROR; - DBUG_RETURN(0); - } - } -*************** -*** 4973,4985 **** - DBUG_RETURN(-1); /* purecov: inspected */ - if (end_of_records) - DBUG_RETURN(0); -- if (!error && ++join->send_records >= join->thd->select_limit && - join->do_send_rows) - { - if (!(join->select_options & OPTION_FOUND_ROWS)) - DBUG_RETURN(-3); // Abort nicely - join->do_send_rows=0; -- join->thd->select_limit = HA_POS_ERROR; - } - } - } ---- 5073,5086 ---- - DBUG_RETURN(-1); /* purecov: inspected */ - if (end_of_records) - DBUG_RETURN(0); -+ if (!error && ++join->send_records >= -+ join->select_lex->first_in_union->select_limit_cnt && - join->do_send_rows) - { - if (!(join->select_options & OPTION_FOUND_ROWS)) - DBUG_RETURN(-3); // Abort nicely - join->do_send_rows=0; -+ join->select_lex->first_in_union->select_limit_cnt = HA_POS_ERROR; - } - } - } -*************** -*** 5060,5066 **** - if (!(join->select_options & OPTION_FOUND_ROWS)) - DBUG_RETURN(-3); - join->do_send_rows=0; -- join->thd->select_limit = HA_POS_ERROR; - DBUG_RETURN(0); - } - } ---- 5161,5167 ---- - if (!(join->select_options & OPTION_FOUND_ROWS)) - DBUG_RETURN(-3); - join->do_send_rows=0; -+ join->select_lex->first_in_union->select_limit_cnt = HA_POS_ERROR; - DBUG_RETURN(0); - } - } -*************** -*** 5743,5749 **** - - if (!field_count) - { // only const items -- join->thd->select_limit=1; // Only send first row - DBUG_RETURN(0); - } - Field **first_field=entry->field+entry->fields - field_count; ---- 5844,5850 ---- - - if (!field_count) - { // only const items -+ join->select_lex->first_in_union->select_limit_cnt=1;// Only send first row - DBUG_RETURN(0); - } - Field **first_field=entry->field+entry->fields - field_count; -- cgit v1.2.1 From e4437030b20a6b7df2b8368215af85d260c43b52 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Jun 2002 17:40:06 +0500 Subject: New command: SHOW CHARACTER SET [LIKE 'wild'] --- sql/mysql_priv.h | 1 + sql/sql_lex.h | 2 +- sql/sql_parse.cc | 3 +++ sql/sql_show.cc | 38 ++++++++++++++++++++++++++++++++++++++ sql/sql_yacc.yy | 2 ++ 5 files changed, 45 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 4753435bbfa..268a452095e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -472,6 +472,7 @@ void mysqld_list_processes(THD *thd,const char *user,bool verbose); int mysqld_show_status(THD *thd); int mysqld_show_variables(THD *thd,const char *wild); int mysqld_show(THD *thd, const char *wild, show_var_st *variables); +int mysqld_show_charsets(THD *thd,const char *wild); /* sql_handler.cc */ int mysql_ha_open(THD *thd, TABLE_LIST *tables); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 25798bbf079..ee0209f9329 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -41,7 +41,7 @@ enum enum_sql_command { SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS, SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS, SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, - SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, + SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, SQLCOM_GRANT, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 174942054e1..a5d8aa3185e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2101,6 +2101,9 @@ mysql_execute_command(void) case SQLCOM_SHOW_OPEN_TABLES: res= mysqld_show_open_tables(thd,(lex->wild ? lex->wild->ptr() : NullS)); break; + case SQLCOM_SHOW_CHARSETS: + res= mysqld_show_charsets(thd,(lex->wild ? lex->wild->ptr() : NullS)); + break; case SQLCOM_SHOW_FIELDS: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 995142d6566..1421eac168f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1162,6 +1162,44 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) ** Status functions *****************************************************************************/ +int mysqld_show_charsets(THD *thd, const char *wild) +{ + uint i; + char buff[8192]; + String packet2(buff,sizeof(buff),default_charset_info); + List field_list; + CONVERT *convert=thd->convert_set; + CHARSET_INFO *cs; + DBUG_ENTER("mysqld_show_charsets"); + + field_list.push_back(new Item_empty_string("Name",30)); + field_list.push_back(new Item_int("Id",0,7)); + field_list.push_back(new Item_int("strx_maxlen",0,7)); + field_list.push_back(new Item_int("mb_maxlen",0,7)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + for (cs=compiled_charsets ; cs->name ; cs++ ) + { + if (!(wild && wild[0] && wild_case_compare(system_charset_info,cs->name,wild))) + { + packet2.length(0); + net_store_data(&packet2,convert,cs->name); + net_store_data(&packet2,(uint32) cs->number); + net_store_data(&packet2,(uint32) cs->strxfrm_multiply); + net_store_data(&packet2,(uint32) cs->mbmaxlen); + + if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length())) + goto err; /* purecov: inspected */ + } + } + send_eof(&thd->net); + DBUG_RETURN(0); +err: + DBUG_RETURN(1); +} + int mysqld_show(THD *thd, const char *wild, show_var_st *variables) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index efc8b8b5389..25d8dbbab16 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2801,6 +2801,8 @@ show_param: { Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;} | VARIABLES wild { Lex->sql_command= SQLCOM_SHOW_VARIABLES; } + | CHAR_SYM SET wild + { Lex->sql_command= SQLCOM_SHOW_CHARSETS; } | LOGS_SYM { Lex->sql_command= SQLCOM_SHOW_LOGS; } | GRANTS FOR_SYM user -- cgit v1.2.1 From 6cdebb33d7849adb90015ecd4a7312de81200de0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jun 2002 14:13:12 -0700 Subject: sql_error.cc, sql_prepare.cc: new file Client-server protocol 4.1 changes - Server side: * Enhanced metadata information: - SHOW [COUNT(*)] ERRORS [LIMIT [offset,] rows] - SHOW [COUNT(*)] WARNING [LIMIT [offset,] rows] - SHOW TABLE TYPES - SHOW PRIVILEGES - SHOW COLUMN TYPES (Not fully implemented) * Prepared execution * Long data handling in pieces * And other misc changes --- sql/Makefile.am | 1 + sql/field.cc | 8 +- sql/field.h | 4 +- sql/item.cc | 139 ++++++++++- sql/item.h | 34 +++ sql/item_sum.cc | 5 +- sql/lex.h | 4 + sql/mysql_priv.h | 28 ++- sql/net_pkg.cc | 11 +- sql/sql_base.cc | 188 +++++++++++--- sql/sql_class.cc | 3 + sql/sql_class.h | 36 ++- sql/sql_error.cc | 219 +++++++++++++++++ sql/sql_insert.cc | 2 +- sql/sql_lex.h | 7 +- sql/sql_list.h | 121 +++++++++ sql/sql_parse.cc | 54 +++- sql/sql_prepare.cc | 709 +++++++++++++++++++++++++++++++++++++++++++++++++++++ sql/sql_select.cc | 4 +- sql/sql_show.cc | 195 +++++++++++++++ sql/sql_yacc.yy | 57 ++++- sql/structs.h | 23 ++ 22 files changed, 1794 insertions(+), 58 deletions(-) create mode 100644 sql/sql_error.cc create mode 100644 sql/sql_prepare.cc (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index bd626ea10b7..81fe927ce5a 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -67,6 +67,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ mysqld.cc password.c hash_filo.cc hostname.cc \ convert.cc sql_parse.cc sql_yacc.yy \ sql_base.cc table.cc sql_select.cc sql_insert.cc \ + sql_prepare.cc sql_error.cc \ sql_update.cc sql_delete.cc uniques.cc sql_do.cc \ procedure.cc item_uniq.cc sql_test.cc \ log.cc log_event.cc init.cc derror.cc sql_acl.cc \ diff --git a/sql/field.cc b/sql/field.cc index 1561f1831de..8b1073d32f3 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -279,8 +279,10 @@ void Field_num::add_zerofill_and_unsigned(String &res) const void Field_num::make_field(Send_field *field) { + field->db_name=table->table_cache_key ? table->table_cache_key : ""; + field->org_table_name=table->real_name; field->table_name=table_name; - field->col_name=field_name; + field->col_name=field->org_col_name=field_name; field->length=field_length; field->type=type(); field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags; @@ -290,8 +292,10 @@ void Field_num::make_field(Send_field *field) void Field_str::make_field(Send_field *field) { + field->db_name=table->table_cache_key ? table->table_cache_key : ""; + field->org_table_name=table->real_name; field->table_name=table_name; - field->col_name=field_name; + field->col_name=field->org_col_name=field_name; field->length=field_length; field->type=type(); field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags; diff --git a/sql/field.h b/sql/field.h index f84b54271ce..5b9723654d9 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1038,7 +1038,9 @@ public: class Send_field { public: - const char *table_name,*col_name; + const char *db_name; + const char *table_name,*org_table_name; + const char *col_name,*org_col_name; uint length,flags,decimals; enum_field_types type; Send_field() {} diff --git a/sql/item.cc b/sql/item.cc index 45564bcd98e..d01a06e5eba 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -287,6 +287,140 @@ String *Item_null::val_str(String *str) { null_value=1; return 0;} +/* Item_param related */ +void Item_param::set_null() +{ + maybe_null=null_value=1; +} + +void Item_param::set_int(longlong i) +{ + int_value=(longlong)i; + item_result_type = INT_RESULT; + item_type = INT_ITEM; +} + +void Item_param::set_double(double i) +{ + double value = (double)i; + real_value=value; + item_result_type = REAL_RESULT; + item_type = REAL_ITEM; +} + +void Item_param::set_double(float i) +{ + float value = (float)i; + real_value=(double)value; + item_result_type = REAL_RESULT; + item_type = REAL_ITEM; +} + +void Item_param::set_value(const char *str, uint length) +{ + str_value.set(str,length,default_charset_info); + item_result_type = STRING_RESULT; + item_type = STRING_ITEM; +} + +void Item_param::set_longdata(const char *str, ulong length) +{ + /* TODO: Fix this for binary handling by making use of + buffer_type.. + */ + str_value.append(str,length); +} + +void Item_param::set_long_end() +{ + long_data_supplied = true; + item_result_type = STRING_RESULT; +}; + +bool Item_param::save_in_field(Field *field) +{ + if (null_value) + return set_field_to_null(field); + + field->set_notnull(); + if (item_result_type == INT_RESULT) + { + longlong nr=val_int(); + field->store(nr); + return 0; + } + if (item_result_type == REAL_RESULT) + { + double nr=val(); + field->store(nr); + return 0; + } + String *result; + CHARSET_INFO *cs=default_charset_info;//fix this + result=val_str(&str_value); + field->store(result->ptr(),result->length(),cs); + return 0; +} + +void Item_param::make_field(Send_field *tmp_field) +{ + init_make_field(tmp_field,FIELD_TYPE_STRING); +} + +double Item_param::val() +{ + /* Cross check whether we need need this conversions ? or direct + return(real_value) is enough ? + */ + + switch(item_result_type) { + + case STRING_RESULT: + return (double)atof(str_value.ptr()); + case INT_RESULT: + return (double)int_value; + default: + return real_value; + } +} + +longlong Item_param::val_int() +{ + /* Cross check whether we need need this conversions ? or direct + return(int_value) is enough ? + */ + + switch(item_result_type) { + + case STRING_RESULT: + return (longlong)strtoll(str_value.ptr(),(char**) 0,10); + case REAL_RESULT: + return (longlong) (real_value+(real_value > 0 ? 0.5 : -0.5)); + default: + return int_value; + } +} + +String *Item_param::val_str(String* str) +{ + /* Cross check whether we need need this conversions ? or direct + return(&str_value) is enough ? + */ + + switch(item_result_type) { + + case INT_RESULT: + str->set(int_value); + return str; + case REAL_RESULT: + str->set(real_value); + return str; + default: + return (String*) &str_value; + } +} +/* End of Item_param related */ + void Item_copy_string::copy() { String *res=item->val_str(&str_value); @@ -373,7 +507,10 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) void Item::init_make_field(Send_field *tmp_field, enum enum_field_types field_type) -{ +{ + tmp_field->db_name=(char*) ""; + tmp_field->org_table_name=(char*) ""; + tmp_field->org_col_name=(char*) ""; tmp_field->table_name=(char*) ""; tmp_field->col_name=name; tmp_field->flags=maybe_null ? 0 : NOT_NULL_FLAG; diff --git a/sql/item.h b/sql/item.h index 8e8b44a5006..e6debdf2afc 100644 --- a/sql/item.h +++ b/sql/item.h @@ -155,6 +155,40 @@ public: bool is_null() { return 1; } }; +class Item_param :public Item +{ +public: + longlong int_value; + double real_value; + enum Item_result item_result_type; + enum Type item_type; + enum enum_field_types buffer_type; + my_bool long_data_supplied; + + Item_param(char *name_par=0){ + name= name_par ? name_par : (char*) "?"; + long_data_supplied = false; + item_type = STRING_ITEM; item_result_type = STRING_RESULT; + } + enum Type type() const { return item_type; } + double val(); + longlong val_int(); + String *val_str(String*); + void make_field(Send_field *field); + bool save_in_field(Field *field); + void set_null(); + void set_int(longlong i); + void set_double(float i); + void set_double(double i); + void set_value(const char *str, uint length); + void set_long_str(const char *str, ulong length); + void set_long_binary(const char *str, ulong length); + void set_longdata(const char *str, ulong length); + void set_long_end(); + enum Item_result result_type () const + { return item_result_type; } + Item *new_item() { return new Item_param(name); } +}; class Item_int :public Item { diff --git a/sql/item_sum.cc b/sql/item_sum.cc index a1ffae2ed82..6ef968c33f7 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -60,8 +60,9 @@ void Item_sum::make_field(Send_field *tmp_field) result_type() == REAL_RESULT ? FIELD_TYPE_DOUBLE : FIELD_TYPE_VAR_STRING); } - tmp_field->table_name=(char*)""; - tmp_field->col_name=name; + tmp_field->db_name=(char*)""; + tmp_field->org_table_name=tmp_field->table_name=(char*)""; + tmp_field->org_col_name=tmp_field->col_name=name; } void Item_sum::print(String *str) diff --git a/sql/lex.h b/sql/lex.h index dd1a69f9c83..da0a71a135e 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -129,6 +129,7 @@ static SYMBOL symbols[] = { { "DROP", SYM(DROP),0,0}, { "DUMPFILE", SYM(DUMPFILE),0,0}, { "DYNAMIC", SYM(DYNAMIC_SYM),0,0}, + { "ERRORS", SYM(ERRORS),0,0}, { "END", SYM(END),0,0}, { "ELSE", SYM(ELSE),0,0}, { "ESCAPE", SYM(ESCAPE_SYM),0,0}, @@ -327,6 +328,7 @@ static SYMBOL symbols[] = { { "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0}, { "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0}, { "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS),0,0}, + { "SQL_ERROR_COUNT", SYM(SQL_ERROR_COUNT),0,0}, { "SQL_LOG_BIN", SYM(SQL_LOG_BIN),0,0}, { "SQL_LOG_OFF", SYM(SQL_LOG_OFF),0,0}, { "SQL_LOG_UPDATE", SYM(SQL_LOG_UPDATE),0,0}, @@ -366,6 +368,7 @@ static SYMBOL symbols[] = { { "TRUNCATE", SYM(TRUNCATE_SYM),0,0}, { "TO", SYM(TO_SYM),0,0}, { "TYPE", SYM(TYPE_SYM),0,0}, + { "TYPES", SYM(TYPES_SYM),0,0}, { "UNCOMMITTED", SYM(UNCOMMITTED_SYM),0,0}, { "UNION", SYM(UNION_SYM),0,0}, { "UNIQUE", SYM(UNIQUE_SYM),0,0}, @@ -381,6 +384,7 @@ static SYMBOL symbols[] = { { "VARIABLES", SYM(VARIABLES),0,0}, { "VARYING", SYM(VARYING),0,0}, { "VARBINARY", SYM(VARBINARY),0,0}, + { "WARNINGS", SYM(WARNINGS),0,0}, { "WITH", SYM(WITH),0,0}, { "WORK", SYM(WORK_SYM),0,0}, { "WRITE", SYM(WRITE_SYM),0,0}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 268a452095e..011b7823dd0 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -287,6 +287,8 @@ inline THD *_current_thd(void) #define query_cache_invalidate_by_MyISAM_filename_ref NULL #endif /*HAVE_QUERY_CACHE*/ +#define prepare_execute(A) ((A)->command == COM_EXECUTE) + int mysql_create_db(THD *thd, char *db, uint create_info, bool silent); int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent); void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags); @@ -363,6 +365,8 @@ bool net_store_data(String *packet, CONVERT *convert, const char *from); SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length); int setup_order(THD *thd,TABLE_LIST *tables, List &fields, List &all_fields, ORDER *order); +int setup_group(THD *thd,TABLE_LIST *tables,List &fields, + List &all_fields, ORDER *order, bool *hidden_group_fields); int handle_select(THD *thd, LEX *lex, select_result *result); int mysql_select(THD *thd,TABLE_LIST *tables,List &list,COND *conds, @@ -455,7 +459,7 @@ bool load_des_key_file(const char *file_name); /* sql_do.cc */ int mysql_do(THD *thd, List &values); -/* sql_list.c */ +/* sql_show.c */ int mysqld_show_dbs(THD *thd,const char *wild); int mysqld_show_open_tables(THD *thd,const char *wild); int mysqld_show_tables(THD *thd,const char *db,const char *wild); @@ -473,6 +477,24 @@ int mysqld_show_status(THD *thd); int mysqld_show_variables(THD *thd,const char *wild); int mysqld_show(THD *thd, const char *wild, show_var_st *variables); int mysqld_show_charsets(THD *thd,const char *wild); +int mysqld_show_privileges(THD *thd); +int mysqld_show_column_types(THD *thd); + +/* sql_prepare.cc */ +void mysql_com_prepare(THD *thd,char*packet,uint packet_length); +void mysql_init_query(THD *thd);/* sql_parse. cc */ +void mysql_com_execute(THD *thd); +void mysql_com_longdata(THD *thd); +int check_insert_fields(THD *thd,TABLE *table,List &fields, + List &values, ulong counter); + +/* sql_error.cc */ +void push_error(uint code, const char *msg); +void push_warning(uint code, const char *msg); +int mysqld_show_warnings(THD *thd); +int mysqld_show_errors(THD *thd); +int mysqld_show_warnings_count(THD *thd); +int mysqld_show_errors_count(THD *); /* sql_handler.cc */ int mysql_ha_open(THD *thd, TABLE_LIST *tables); @@ -654,6 +676,10 @@ extern const char *default_tx_isolation_name; extern String empty_string; extern struct show_var_st init_vars[]; extern struct show_var_st status_vars[]; +extern struct show_table_type_st table_type_vars[]; +extern SHOW_COMP_OPTION have_isam; +extern SHOW_COMP_OPTION have_innodb; +extern SHOW_COMP_OPTION have_berkeley_db; extern enum db_type default_table_type; extern enum enum_tx_isolation default_tx_isolation; extern char glob_hostname[FN_REFLEN]; diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index a201651fc2f..fa3abc68bfa 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -48,6 +48,7 @@ void send_error(NET *net, uint sql_errno, const char *err) } } } + push_error(sql_errno, err); if (net->vio == 0) { if (thd && thd->bootstrap) @@ -82,7 +83,14 @@ void send_error(NET *net, uint sql_errno, const char *err) void send_warning(NET *net, uint sql_errno, const char *err) { - DBUG_ENTER("send_warning"); + DBUG_ENTER("send_warning"); + push_warning(sql_errno, err ? err : ER(sql_errno)); + + /* + TODO : + Try to return ok with warning status to client, instead + of returning error .. + */ send_error(net,sql_errno,err); DBUG_VOID_RETURN; } @@ -123,6 +131,7 @@ net_printf(NET *net, uint errcode, ...) length=sizeof(net->last_error)-1; /* purecov: inspected */ va_end(args); + push_error(errcode, text_pos); if (net->vio == 0) { if (thd && thd->bootstrap) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c9ef64b6da9..92606716c63 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -179,56 +179,58 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild) DBUG_RETURN(open_list); } - -/****************************************************************************** -** Send name and type of result to client. -** Sum fields has table name empty and field_name. -** flag is a bit mask with the following functions: -** 1 send number of rows -** 2 send default values -** 4 Don't convert field names -******************************************************************************/ +/* + Send name and type of result to client. + Sum fields has table name empty and field_name. + flag is a bit mask with the following functions: + 1 send number of rows + 2 send default values + 4 Don't convert field names +*/ bool -send_fields(THD *thd,List &list,uint flag) +send_convert_fields(THD *thd,List &list,CONVERT *convert,uint flag) { List_iterator_fast it(list); Item *item; char buff[80]; - CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set; - DBUG_ENTER("send_fields"); - + String tmp((char*) buff,sizeof(buff),default_charset_info); String *res,*packet= &thd->packet; - - if (thd->fatal_error) // We have got an error - goto err; - - if (flag & 1) - { // Packet with number of elements - char *pos=net_store_length(buff,(uint) list.elements); - (void) my_net_write(&thd->net, buff,(uint) (pos-buff)); - } + while ((item=it++)) { char *pos; Send_field field; item->make_field(&field); + packet->length(0); - if (convert) + if (thd->client_capabilities & CLIENT_PROTOCOL_41) { - if (convert->store(packet,field.table_name, + if (convert->store(packet,field.db_name, + (uint) strlen(field.db_name)) || + convert->store(packet,field.table_name, (uint) strlen(field.table_name)) || + convert->store(packet,field.org_table_name, + (uint) strlen(field.org_table_name)) || convert->store(packet,field.col_name, (uint) strlen(field.col_name)) || + convert->store(packet,field.org_col_name, + (uint) strlen(field.org_col_name)) || packet->realloc(packet->length()+10)) - goto err; + return 1; + } + else + { + if (convert->store(packet,field.table_name, + (uint) strlen(field.table_name)) || + convert->store(packet,field.col_name, + (uint) strlen(field.col_name)) || + packet->realloc(packet->length()+10)) + return 1; } - else if (net_store_data(packet,field.table_name) || - net_store_data(packet,field.col_name) || - packet->realloc(packet->length()+10)) - goto err; /* purecov: inspected */ + pos= (char*) packet->ptr()+packet->length(); if (!(thd->client_capabilities & CLIENT_LONG_FLAG)) @@ -250,19 +252,135 @@ send_fields(THD *thd,List &list,uint flag) if (!(res=item->val_str(&tmp))) { if (net_store_null(packet)) - goto err; + return 1; } else if (net_store_data(packet,res->ptr(),res->length())) - goto err; + return 1; } if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length())) break; /* purecov: inspected */ } - send_eof(&thd->net,1); - DBUG_RETURN(0); - err: + return 0; +} + +/* + Send name and type of result to client. + Sum fields has table name empty and field_name + flag is a bit mask with the following functios: + 1 send number of rows + 2 send default values + 4 Don't convert field names +*/ + +bool +send_non_convert_fields(THD *thd,List &list,uint flag) +{ + List_iterator_fast it(list); + Item *item; + char buff[80]; + + String tmp((char*) buff,sizeof(buff),default_charset_info); + String *res,*packet= &thd->packet; + + while ((item=it++)) + { + char *pos; + Send_field field; + item->make_field(&field); + + packet->length(0); + + if (thd->client_capabilities & CLIENT_PROTOCOL_41) + { + if (net_store_data(packet,field.db_name) || + net_store_data(packet,field.table_name) || + net_store_data(packet,field.org_table_name) || + net_store_data(packet,field.col_name) || + net_store_data(packet,field.org_col_name) || + packet->realloc(packet->length()+10)) + return 1; + } + else + { + if (net_store_data(packet,field.table_name) || + net_store_data(packet,field.col_name) || + packet->realloc(packet->length()+10)) + return 1; + } + + pos= (char*) packet->ptr()+packet->length(); + + if (!(thd->client_capabilities & CLIENT_LONG_FLAG)) + { + packet->length(packet->length()+9); + pos[0]=3; int3store(pos+1,field.length); + pos[4]=1; pos[5]=field.type; + pos[6]=2; pos[7]=(char) field.flags; pos[8]= (char) field.decimals; + } + else + { + packet->length(packet->length()+10); + pos[0]=3; int3store(pos+1,field.length); + pos[4]=1; pos[5]=field.type; + pos[6]=3; int2store(pos+7,field.flags); pos[9]= (char) field.decimals; + } + if (flag & 2) + { // Send default value + if (!(res=item->val_str(&tmp))) + { + if (net_store_null(packet)) + return 1; + } + else if (net_store_data(packet,res->ptr(),res->length())) + return 1; + } + if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length())) + break; + } + return 0; +} + +/****************************************************************************** +** Send name and type of result to client. +** Sum fields has table name empty and field_name. +** flag is a bit mask with the following functions: +** 1 send number of rows +** 2 send default values +** 4 Don't convert field names +******************************************************************************/ + +bool +send_fields(THD *thd,List &list,uint flag) +{ + List_iterator_fast it(list); + char buff[80]; + CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set; + + String tmp((char*) buff,sizeof(buff),default_charset_info); + + if (thd->fatal_error) // We have got an error + goto err; + + if (flag & 1) + { // Packet with number of elements + char *pos=net_store_length(buff,(uint) list.elements); + (void) my_net_write(&thd->net, buff,(uint) (pos-buff)); + } + + /* Avoid check conditions on convert() for each field + by having two diffrent functions + */ + if (convert && send_convert_fields(thd,list,convert,flag)) + goto err; + + else if(send_non_convert_fields(thd,list,flag)) + goto err; + + send_eof(&thd->net); + return 0; +err: send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */ - DBUG_RETURN(1); /* purecov: inspected */ + return 1; /* purecov: inspected */ } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 86e4e6896e6..f91c508e8af 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -140,6 +140,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), command=COM_CONNECT; set_query_id=1; default_select_limit= HA_POS_ERROR; + max_error_count=max_warning_count=MYSQL_DEFAULT_ERROR_COUNT; max_join_size= ((::max_join_size != ~ (ulong) 0L) ? ::max_join_size : HA_POS_ERROR); db_access=NO_ACCESS; @@ -147,6 +148,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), /* Initialize sub structures */ bzero((char*) &mem_root,sizeof(mem_root)); bzero((char*) &transaction.mem_root,sizeof(transaction.mem_root)); + bzero((char*) &con_root,sizeof(con_root)); user_connect=(USER_CONN *)0; hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, @@ -223,6 +225,7 @@ THD::~THD() safeFree(db); safeFree(ip); free_root(&mem_root,MYF(0)); + free_root(&con_root,MYF(0)); free_root(&transaction.mem_root,MYF(0)); mysys_var=0; // Safety (shouldn't be needed) #ifdef SIGNAL_WITH_VIO_CLOSE diff --git a/sql/sql_class.h b/sql/sql_class.h index 8a1a299ceee..016df485245 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -289,7 +289,30 @@ public: i_string_pair():key(0),val(0) { } i_string_pair(char* key_arg, char* val_arg) : key(key_arg),val(val_arg) {} }; +#define MYSQL_DEFAULT_ERROR_COUNT 500 +class mysql_st_error +{ +public: + uint code; + char msg[MYSQL_ERRMSG_SIZE+1]; + char query[NAME_LEN+1]; + + static void *operator new(size_t size) + { + return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE)); + } + static void operator delete(void* ptr_arg, size_t size) + { + my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); + } + mysql_st_error(uint ecode, const char *emsg, const char *equery) + { + code = ecode; + strmov(msg, emsg); + strnmov(query, equery ? equery : "", NAME_LEN); + } +}; class delayed_insert; @@ -308,6 +331,7 @@ public: NET net; // client connection descriptor LEX lex; // parse tree descriptor MEM_ROOT mem_root; // 1 command-life memory + MEM_ROOT con_root; // connection-life memory HASH user_vars; // hash for user variables String packet; // buffer used for network I/O struct sockaddr_in remote; // client socket address @@ -410,7 +434,8 @@ public: max_join_size, sent_row_count, examined_row_count; table_map used_tables; USER_CONN *user_connect; - ulong query_id,version, inactive_timeout,options,thread_id; + ulong query_id,version, inactive_timeout,options,thread_id, + max_error_count, max_warning_count; long dbug_thread_id; pthread_t real_id; uint current_tablenr,tmp_table,cond_count,col_access; @@ -428,8 +453,13 @@ public: bool query_error, bootstrap, cleanup_done; bool safe_to_cache_query; bool volatile killed; - // TRUE when having fix field called - bool having_fix_field; + bool having_fix_field; //TRUE when having fix field called + bool prepare_command; + ulong param_count,current_param_number; + Error err_list; + Error warn_list; + Item_param *current_param; + /* If we do a purge of binary logs, log index info of the threads that are currently reading it needs to be adjusted. To do that diff --git a/sql/sql_error.cc b/sql/sql_error.cc new file mode 100644 index 00000000000..13466f454c5 --- /dev/null +++ b/sql/sql_error.cc @@ -0,0 +1,219 @@ +/* Copyright (C) 1995-2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/********************************************************************** +This file contains the implementation of error and warnings related + + - Whenever an error or warning occured, it pushes the same to + the respective list along with sending it to client. + + - When client requests the information using SHOW command, then + server processes from this list and returns back in the form of + resultset. + + syntax : SHOW [COUNT(*)] ERRORS [LIMIT [offset,] rows] + SHOW [COUNT(*)] WARNINGS [LIMIT [offset,] rows] + +***********************************************************************/ +/* Handles errors and warnings .. */ + +#include "mysql_priv.h" + +/* + Push the error to error list +*/ + +void push_error(uint code, const char *msg) +{ + THD *thd=current_thd; + + mysql_st_error *err = new mysql_st_error(code,msg,(const char*)thd->query); + + if (thd->err_list.elements >= thd->max_error_count) + { + /* Remove the old elements and always maintain the max size + equal to sql_error_count. + + If one max_error_count using sets sql_error_count less than + the current list size, then make sure it always grows upto + sql_error_count size only + + ** BUG ** : Doesn't work in removing the old one + from the list, and thus SET SQL_ERROR_COUNT=x doesn't work + */ + for (uint count=thd->err_list.elements-1; + count <= thd->max_error_count-1; count++) + { + thd->err_list.remove_last(); + } + } + thd->err_list.push_front(err); +} + +/* + Push the warning to warning list +*/ + +void push_warning(uint code, const char *msg) +{ + THD *thd=current_thd; + + mysql_st_error *warn = new mysql_st_error(code,msg,(const char *)thd->query); + + if (thd->warn_list.elements >= thd->max_warning_count) + { + /* Remove the old elements and always maintian the max size + equal to sql_error_count + */ + for (uint count=thd->warn_list.elements; + count <= thd->max_warning_count-1; count++) + { + thd->warn_list.remove_last(); + } + } + thd->warn_list.push_front(warn); +} + +/* + List all errors +*/ + +int mysqld_show_errors(THD *thd) +{ + List field_list; + DBUG_ENTER("mysqld_show_errors"); + + field_list.push_back(new Item_int("CODE",0,4)); + field_list.push_back(new Item_empty_string("MESSAGE",MYSQL_ERRMSG_SIZE)); + field_list.push_back(new Item_empty_string("QUERY",NAME_LEN)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + mysql_st_error *err; + SELECT_LEX *sel=&thd->lex.select_lex; + ha_rows offset = sel->offset_limit,limit = sel->select_limit; + uint num_rows = 0; + + Error_iterator it(thd->err_list); + + while(offset-- && (err = it++));/* Should be fixed with overloaded + operator '+' or with new funtion + goto() in list ? + */ + + while((num_rows++ < limit) && (err = it++)) + { + thd->packet.length(0); + net_store_data(&thd->packet,(uint32)err->code); + net_store_data(&thd->packet,err->msg); + net_store_data(&thd->packet,err->query); + + if (my_net_write(&thd->net,(char*)thd->packet.ptr(),thd->packet.length())) + DBUG_RETURN(-1); + } + send_eof(&thd->net); + DBUG_RETURN(0); +} + +/* + Return errors count +*/ + +int mysqld_show_errors_count(THD *thd) +{ + List field_list; + DBUG_ENTER("mysqld_show_errors_count"); + + field_list.push_back(new Item_int("COUNT(*)",0,4)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + thd->packet.length(0); + net_store_data(&thd->packet,(uint32)thd->err_list.elements); + + if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + DBUG_RETURN(-1); + + send_eof(&thd->net); + DBUG_RETURN(0); +} + +/* + List all warnings +*/ + +int mysqld_show_warnings(THD *thd) +{ + List field_list; + DBUG_ENTER("mysqld_show_warnings"); + + field_list.push_back(new Item_int("CODE",0,21)); + field_list.push_back(new Item_empty_string("MESSAGE",MYSQL_ERRMSG_SIZE)); + field_list.push_back(new Item_empty_string("QUERY",NAME_LEN)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + mysql_st_error *warn; + + + SELECT_LEX *sel=&thd->lex.select_lex; + ha_rows offset = sel->offset_limit,limit = sel->select_limit; + uint num_rows = 0; + + Error_iterator it(thd->warn_list); + while(offset-- && (warn = it++)); + while((num_rows++ < limit) && (warn = it++)) + { + thd->packet.length(0); + net_store_data(&thd->packet,(uint32)warn->code); + net_store_data(&thd->packet,warn->msg); + net_store_data(&thd->packet,warn->query); + + if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + DBUG_RETURN(-1); + } + send_eof(&thd->net); + DBUG_RETURN(0); +} + +/* + Return warnings count +*/ + +int mysqld_show_warnings_count(THD *thd) +{ + List field_list; + DBUG_ENTER("mysqld_show_warnings_count"); + + field_list.push_back(new Item_int("COUNT(*)",0,21)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + thd->packet.length(0); + net_store_data(&thd->packet,(uint32)thd->warn_list.elements); + + if (my_net_write(&thd->net,(char*)thd->packet.ptr(),thd->packet.length())) + DBUG_RETURN(-1); + + send_eof(&thd->net); + DBUG_RETURN(0); +} + diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index c181e299d05..c3aeca1fff8 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -44,7 +44,7 @@ static void unlink_blobs(register TABLE *table); Resets form->time_stamp if a timestamp value is set */ -static int +int check_insert_fields(THD *thd,TABLE *table,List &fields, List &values, ulong counter) { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ee0209f9329..ca824b3eab8 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -57,8 +57,10 @@ enum enum_sql_command { SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ, SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_DELETE_MULTI, SQLCOM_MULTI_UPDATE, SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, SQLCOM_DO, - SQLCOM_EMPTY_QUERY, - SQLCOM_END + SQLCOM_END, SQLCOM_SHOW_WARNS, SQLCOM_SHOW_WARNS_COUNT, + SQLCOM_EMPTY_QUERY, SQLCOM_SHOW_ERRORS, + SQLCOM_SHOW_ERRORS_COUNT, SQLCOM_SHOW_COLUMN_TYPES, + SQLCOM_SHOW_TABLE_TYPES, SQLCOM_SHOW_PRIVILEGES }; enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT, @@ -318,6 +320,7 @@ typedef struct st_lex { List *insert_list,field_list,value_list; List many_values; List option_list; + List param_list; SQL_LIST proc_list, auxilliary_table_list; TYPELIB *interval; create_field *last_field; diff --git a/sql/sql_list.h b/sql/sql_list.h index 542eef623f0..541db4ec166 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -122,11 +122,14 @@ public: last= &first; return tmp->info; } + inline list_node* last_node() { return *last; } + inline list_node* first_node() { return first;} inline void *head() { return first->info; } inline void **head_ref() { return first != &end_of_list ? &first->info : 0; } inline bool is_empty() { return first == &end_of_list ; } inline list_node *last_ref() { return &end_of_list; } friend class base_list_iterator; + friend class error_list; protected: void after(void *info,list_node *node) @@ -204,6 +207,7 @@ public: { return el == &list->last_ref()->next; } + friend class error_list_iterator; }; @@ -356,3 +360,120 @@ public: I_List_iterator(I_List &a) : base_ilist_iterator(a) {} inline T* operator++(int) { return (T*) base_ilist_iterator::next(); } }; + +/* + New error list without mem_root from THD, to have the life of the + allocation becomes connection level . by ovveriding new from Sql_alloc. +*/ +class Error_alloc +{ +public: + static void *operator new(size_t size) + { + return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE)); + } +#if 0 + static void operator delete(void* ptr_arg, size_t size) + { + my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); + } +#endif + friend class error_node; + friend class error_list; +}; + +class error_node :public Error_alloc, public list_node +{ +public: + static void *operator new(size_t size) + { + return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE)); + } +#if 0 + static void operator delete(void* ptr_arg, size_t size) + { + my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); + } +#endif + error_node(void *info_par,list_node *next_par):list_node(info_par,next_par){}; + error_node() : list_node() {}; + friend class error_list; + friend class error_list_iterator; +}; + +class error_list: public Error_alloc, public base_list +{ +public: + inline error_list() : base_list() { }; + inline error_list(const error_list &tmp) : Error_alloc() + { + elements=tmp.elements; + first=tmp.first; + last=tmp.last; + } + inline bool push_front(void *info) + { + error_node *node=new error_node(info,first); + if (node) + { + if (last == &first) + last= &node->next; + first=node; + elements++; + return 0; + } + return 1; + } + inline void remove_last(void) + { + remove(last); + } +protected: + void after(void *info,list_node *node) + { + error_node *new_node=new error_node(info,node->next); + node->next=new_node; + elements++; + if (last == &(node->next)) + last= &new_node->next; + } +}; + +class error_list_iterator : public base_list_iterator +{ + inline error_list_iterator(base_list &base_ptr): base_list_iterator(base_ptr) {}; +}; + +template class Error :public error_list +{ +public: + inline Error() :error_list() {} + inline Error(const Error &tmp) :error_list(tmp) {} + inline bool push_back(T *a) { return error_list::push_back(a); } + inline bool push_front(T *a) { return error_list::push_front(a); } + inline T* head() {return (T*) error_list::head(); } + inline T** head_ref() {return (T**) error_list::head_ref(); } + inline T* pop() {return (T*) error_list::pop(); } + void delete_elements(void) + { + error_node *element,*next; + for (element=first; element != &error_end_of_list; element=next) + { + next=element->next; + delete (T*) element->info; + } + empty(); + } +}; + +template class Error_iterator :public base_list_iterator +{ +public: + Error_iterator(Error &a) : base_list_iterator(a) {} + inline T* operator++(int) { return (T*) base_list_iterator::next(); } + inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); } + inline T *replace(Error &a) { return (T*) base_list_iterator::replace(a); } + inline void after(T *a) { base_list_iterator::after(a); } + inline T** ref(void) { return (T**) base_list_iterator::ref(); } +}; + diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a5d8aa3185e..70f50483114 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -65,7 +65,6 @@ static void decrease_user_connections(USER_CONN *uc); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); static bool check_dup(const char *db, const char *name, TABLE_LIST *tables); -void mysql_init_query(THD *thd); static void remove_escape(char *name); static void refresh_status(void); static bool append_file_to_dir(THD *thd, char **filename_ptr, @@ -77,7 +76,8 @@ const char *command_name[]={ "Sleep", "Quit", "Init DB", "Query", "Field List", "Create DB", "Drop DB", "Refresh", "Shutdown", "Statistics", "Processlist", "Connect","Kill","Debug","Ping","Time","Delayed_insert","Change user", - "Binlog Dump","Table Dump", "Connect Out", "Register Slave" + "Binlog Dump","Table Dump", "Connect Out", "Register Slave", + "Prepare", "Prepare Execute", "Long Data" }; bool volatile abort_slave = 0; @@ -486,7 +486,7 @@ check_connections(THD *thd) { /* buff[] needs to big enough to hold the server_version variable */ char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+32],*end; - int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB; + int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB | CLIENT_PROTOCOL_41; if (opt_using_transactions) client_flags|=CLIENT_TRANSACTIONS; @@ -957,7 +957,21 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->password=test(passwd[0]); break; } - + case COM_EXECUTE: + { + mysql_com_execute(thd); + break; + } + case COM_LONG_DATA: + { + mysql_com_longdata(thd); + break; + } + case COM_PREPARE: + { + mysql_com_prepare(thd,packet,packet_length); + break; + } case COM_QUERY: { packet_length--; // Remove end null @@ -1380,6 +1394,26 @@ mysql_execute_command(void) res = purge_master_logs(thd, lex->to_log); break; } + case SQLCOM_SHOW_WARNS_COUNT: + { + res = mysqld_show_warnings_count(thd); + break; + } + case SQLCOM_SHOW_WARNS: + { + res = mysqld_show_warnings(thd); + break; + } + case SQLCOM_SHOW_ERRORS_COUNT: + { + res = mysqld_show_errors_count(thd); + break; + } + case SQLCOM_SHOW_ERRORS: + { + res = mysqld_show_errors(thd); + break; + } case SQLCOM_SHOW_NEW_MASTER: { if (check_access(thd, FILE_ACL, any_db)) @@ -2048,6 +2082,15 @@ mysql_execute_command(void) mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS : thd->priv_user,lex->verbose); break; + case SQLCOM_SHOW_TABLE_TYPES: + res= mysqld_show_table_types(thd); + break; + case SQLCOM_SHOW_PRIVILEGES: + res= mysqld_show_privileges(thd); + break; + case SQLCOM_SHOW_COLUMN_TYPES: + res= mysqld_show_column_types(thd); + break; case SQLCOM_SHOW_STATUS: res= mysqld_show(thd,(lex->wild ? lex->wild->ptr() : NullS),status_vars); break; @@ -2732,6 +2775,9 @@ mysql_init_query(THD *thd) thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; thd->sent_row_count= thd->examined_row_count= 0; thd->safe_to_cache_query= 1; + thd->param_count=0; + thd->prepare_command=false; + thd->lex.param_list.empty(); DBUG_VOID_RETURN; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc new file mode 100644 index 00000000000..d5896901935 --- /dev/null +++ b/sql/sql_prepare.cc @@ -0,0 +1,709 @@ +/* Copyright (C) 1995-2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/********************************************************************** +This file contains the implementation of prepare and executes. + +Prepare: + + - Server gets the query from client with command 'COM_PREPARE' + - Parse the query and recognize any parameter markers '?' and + store its information list lex->param_list + - Without executing the query, return back to client the total + number of parameters along with result-set metadata information + (if any ) + +Prepare-execute: + + - Server gets the command 'COM_EXECUTE' to execute the + previously prepared query. + - If there is are any parameters, then replace the markers with the + data supplied by client with the following format: + [types_specified(0/1)][type][length][data] .. [type][length].. + - Execute the query without re-parsing and send back the results + to client + +Long data handling: + + - Server gets the long data in pieces with command type 'COM_LONG_DATA'. + - The packet recieved will have the format as: + [type_spec_exists][type][length][data] + - Checks if the type is specified by client, and if yes reads the type, + and stores the data in that format. + - If length == MYSQL_END_OF_DATA, then server sets up the data read ended. +***********************************************************************/ + +#include "mysql_priv.h" +#include "sql_acl.h" +#include // for DEBUG_ASSERT() +#include // for isspace() + +/**************************************************************************/ +extern int yyparse(void); +static ulong get_param_length(uchar **packet); +static uint get_buffer_type(uchar **packet); +static bool param_is_null(uchar **packet); +static bool setup_param_fields(THD *thd,List ¶ms); +static uchar* setup_param_field(Item_param *item_param, uchar *pos, uint buffer_type); +static void setup_longdata_field(Item_param *item_param, uchar *pos); +static bool setup_longdata(THD *thd,List ¶ms); +static void send_prepare_results(THD *thd); +static void mysql_parse_prepare_query(THD *thd,char *packet,uint length); +static bool mysql_send_insert_fields(THD *thd,TABLE_LIST *table_list, + List &fields, + List &values_list,thr_lock_type lock_type); +static bool mysql_test_insert_fields(THD *thd,TABLE_LIST *table_list, + List &fields, + List &values_list,thr_lock_type lock_type); +static bool mysql_test_upd_fields(THD *thd,TABLE_LIST *table_list, + List &fields, List &values, + COND *conds,thr_lock_type lock_type); +static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables, + List &fields, List &values, + COND *conds, ORDER *order, ORDER *group, + Item *having,thr_lock_type lock_type); +extern const char *any_db; +/**************************************************************************/ + +/* + Read the buffer type, this happens only first time +*/ + +static uint get_buffer_type(uchar **packet) +{ + reg1 uchar *pos= *packet; + (*packet)+= 2; + return (uint) uint2korr(pos); +} + +/* + Check for NULL param data +*/ + +static bool param_is_null(uchar **packet) +{ + reg1 uchar *pos= *packet; + if (*pos == 251) + { + (*packet)++; + return 1; + } + return 0; +} + +/* + Read the length of the parameter data and retun back to + caller by positing the pointer to param data +*/ + +static ulong get_param_length(uchar **packet) +{ + reg1 uchar *pos= *packet; + if (*pos < 251) + { + (*packet)++; + return (ulong) *pos; + } + if (*pos == 252) + { + (*packet)+=3; + return (ulong) uint2korr(pos+1); + } + if (*pos == 253) + { + (*packet)+=4; + return (ulong) uint3korr(pos+1); + } + (*packet)+=9; // Must be 254 when here + return (ulong) uint4korr(pos+1); +} + +/* + Read and return the data for parameters supplied by client +*/ + +static uchar* setup_param_field(Item_param *item_param, + uchar *pos, uint buffer_type) +{ + if (param_is_null(&pos)) + { + item_param->set_null(); + return(pos); + } + switch (buffer_type) + { + case FIELD_TYPE_TINY: + item_param->set_int((longlong)(*pos)); + pos += 1; + break; + case FIELD_TYPE_SHORT: + item_param->set_int((longlong)sint2korr(pos)); + pos += 2; + break; + case FIELD_TYPE_INT24: + item_param->set_int((longlong)sint4korr(pos)); + pos += 3; + break; + case FIELD_TYPE_LONG: + item_param->set_int((longlong)sint4korr(pos)); + pos += 4; + break; + case FIELD_TYPE_LONGLONG: + item_param->set_int((longlong)sint8korr(pos)); + pos += 8; + break; + case FIELD_TYPE_FLOAT: + float data; + float4get(data,pos); + item_param->set_double(data); + pos += 4; + break; + case FIELD_TYPE_DOUBLE: + double j; + float8get(j,pos) + item_param->set_double(j); + pos += 8; + break; + default: + { + ulong len=get_param_length(&pos); + item_param->set_value((const char*)pos,len); + pos+=len; + } + } + return(pos); +} + +/* + Update the parameter markers by reading the data + from client .. +*/ + +static bool setup_param_fields(THD *thd, List ¶ms) +{ + reg2 Item_param *item_param; + List_iterator it(params); + NET *net = &thd->net; + DBUG_ENTER("setup_param_fields"); + + ulong param_count=0; + uchar *pos=(uchar*)net->read_pos+1;// skip command type + + if(*pos++) // No types supplied, read only param data + { + while ((item_param=(Item_param *)it++) && + (param_count++ < thd->param_count)) + { + if (item_param->long_data_supplied) + continue; + + if (!(pos=setup_param_field(item_param,pos,item_param->buffer_type))) + DBUG_RETURN(1); + } + } + else // Types supplied, read and store it along with param data + { + while ((item_param=(Item_param *)it++) && + (param_count++ < thd->param_count)) + { + if (item_param->long_data_supplied) + continue; + + if (!(pos=setup_param_field(item_param,pos, + item_param->buffer_type=(enum_field_types)get_buffer_type(&pos)))) + DBUG_RETURN(1); + } + } + DBUG_RETURN(0); +} + +/* + Buffer the long data and update the flags +*/ + +static void setup_longdata_field(Item_param *item_param, uchar *pos) +{ + ulong len; + + if (!*pos++) + item_param->buffer_type=(enum_field_types)get_buffer_type(&pos); + + if (*pos == MYSQL_LONG_DATA_END) + item_param->set_long_end(); + + else + { + len = get_param_length(&pos); + item_param->set_longdata((const char *)pos, len); + } +} + +/* + Store the long data from client in pieces +*/ + +static bool setup_longdata(THD *thd, List ¶ms) +{ + NET *net=&thd->net; + List_iterator it(params); + DBUG_ENTER("setup_longdata"); + + uchar *pos=(uchar*)net->read_pos+1;// skip command type at first position + ulong param_number = get_param_length(&pos); + Item_param *item_param = thd->current_param; + + if (thd->current_param_number != param_number) + { + thd->current_param_number = param_number; + while (param_number--) /* TODO: + Change this loop by either having operator '+' + overloaded to point to desired 'item' or + add another memeber in list as 'goto' with + location count as parameter number, but what + is the best way to traverse ? + */ + { + it++; + } + thd->current_param = item_param = (Item_param *)it++; + } + setup_longdata_field(item_param,pos); + DBUG_RETURN(0); +} + + + +/* + Validates insert fields +*/ + +static int check_prepare_fields(THD *thd,TABLE *table, List &fields, + List &values, ulong counter) +{ + if (fields.elements == 0 && values.elements != 0) + { + if (values.elements != table->fields) + { + my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, + ER(ER_WRONG_VALUE_COUNT_ON_ROW), + MYF(0),counter); + return -1; + } + } + else + { + if (fields.elements != values.elements) + { + my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, + ER(ER_WRONG_VALUE_COUNT_ON_ROW), + MYF(0),counter); + return -1; + } + TABLE_LIST table_list; + bzero((char*) &table_list,sizeof(table_list)); + table_list.name=table->table_name; + table_list.table=table; + table_list.grant=table->grant; + + thd->dupp_field=0; + if (setup_tables(&table_list) || + setup_fields(thd,&table_list,fields,1,0,0)) + return -1; + if (thd->dupp_field) + { + my_error(ER_FIELD_SPECIFIED_TWICE,MYF(0), thd->dupp_field->field_name); + return -1; + } + } + return 0; +} + + +/* + Validate the following information for INSERT statement: + - field existance + - fields count + + If there is no column list spec exists, then update the field_list + with all columns from the table, and send fields info back to client +*/ + +static bool mysql_test_insert_fields(THD *thd, TABLE_LIST *table_list, + List &fields, + List &values_list, + thr_lock_type lock_type) +{ + TABLE *table; + List_iterator_fast its(values_list); + List_item *values; + DBUG_ENTER("mysql_test_insert_fields"); + + if (!(table = open_ltable(thd,table_list,lock_type))) + DBUG_RETURN(1); + + if ((values= its++)) + { + uint value_count; + ulong counter=0; + + if (check_insert_fields(thd,table,fields,*values,1)) + DBUG_RETURN(1); + + value_count= values->elements; + its.rewind(); + + while ((values = its++)) + { + counter++; + if (values->elements != value_count) + { + my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, + ER(ER_WRONG_VALUE_COUNT_ON_ROW), + MYF(0),counter); + DBUG_RETURN(1); + } + } + if (fields.elements == 0) + { + /* No field listing, so setup all fields */ + List all_fields; + Field **ptr,*field; + for (ptr=table->field; (field= *ptr) ; ptr++) + { + all_fields.push_back(new Item_field(table->table_cache_key, + table->real_name, + field->field_name)); + } + if ((setup_fields(thd,table_list,all_fields,1,0,0) || + send_fields(thd,all_fields,1))) + DBUG_RETURN(1); + } + else if (send_fields(thd,fields,1)) + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} + + +/* + Validate the following information + UPDATE - set and where clause DELETE - where clause + + And send update-set cluase column list fields info + back to client. For DELETE, just validate where cluase + and return no fields information back to client. +*/ + +static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list, + List &fields, List &values, + COND *conds, thr_lock_type lock_type) +{ + TABLE *table; + DBUG_ENTER("mysql_test_upd_fields"); + + if (!(table = open_ltable(thd,table_list,lock_type))) + DBUG_RETURN(1); + + if (setup_tables(table_list) || setup_fields(thd,table_list,fields,1,0,0) || + setup_conds(thd,table_list,&conds)) + DBUG_RETURN(1); + + /* + Currently return only column list info only, and we are not + sending any info on where clause. + */ + if (fields.elements && send_fields(thd,fields,1)) + DBUG_RETURN(1); + + DBUG_RETURN(0); +} + +/* + Validate the following information: + + SELECT - column list + - where clause + - orderr clause + - having clause + - group by clause + - if no column spec i.e. '*', then setup all fields + + And send column list fields info back to client. +*/ + +static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables, + List &fields, List &values, + COND *conds, ORDER *order, ORDER *group, + Item *having,thr_lock_type lock_type) +{ + TABLE *table; + bool hidden_group_fields; + List all_fields(fields); + DBUG_ENTER("mysql_test_select_fields"); + + if (!(table = open_ltable(thd,tables,lock_type))) + DBUG_RETURN(1); + + thd->used_tables=0; // Updated by setup_fields + if (setup_tables(tables) || + setup_fields(thd,tables,fields,1,&all_fields,1) || + setup_conds(thd,tables,&conds) || + setup_order(thd,tables,fields,all_fields,order) || + setup_group(thd,tables,fields,all_fields,group,&hidden_group_fields)) + DBUG_RETURN(1); + + if (having) + { + thd->where="having clause"; + thd->allow_sum_func=1; + if (having->fix_fields(thd,tables) || thd->fatal_error) + DBUG_RETURN(1); + if (having->with_sum_func) + having->split_sum_func(all_fields); + } + if (setup_ftfuncs(thd)) + DBUG_RETURN(1); + + /* + Currently return only column list info only, and we are not + sending any info on where clause. + */ + if (fields.elements && send_fields(thd,fields,1)) + DBUG_RETURN(1); + DBUG_RETURN(0); +} + +/* + Check the access privileges +*/ + +static bool check_prepare_access(THD *thd, TABLE_LIST *tables, + uint type) +{ + if (check_access(thd,type,tables->db,&tables->grant.privilege)) + return 1; + if (grant_option && check_grant(thd,type,tables)) + return 1; + return 0; +} + +/* + Send the prepare query results back to client +*/ + +static void send_prepare_results(THD *thd) +{ + DBUG_ENTER("send_prepare_results"); + enum enum_sql_command sql_command = thd->lex.sql_command; + + DBUG_PRINT("enter",("command :%d, param_count :%ld", + sql_command,thd->param_count)); + + LEX *lex=&thd->lex; + SELECT_LEX *select_lex = lex->select; + TABLE_LIST *tables=(TABLE_LIST*) select_lex->table_list.first; + + switch(sql_command) { + + case SQLCOM_INSERT: + if (mysql_test_insert_fields(thd,tables, lex->field_list, + lex->many_values, lex->lock_option)) + goto abort; + break; + + case SQLCOM_UPDATE: + if (mysql_test_upd_fields(thd,tables, select_lex->item_list, + lex->value_list, select_lex->where, + lex->lock_option)) + goto abort; + break; + + case SQLCOM_DELETE: + if (mysql_test_upd_fields(thd,tables, select_lex->item_list, + lex->value_list, select_lex->where, + lex->lock_option)) + goto abort; + break; + + case SQLCOM_SELECT: + if (mysql_test_select_fields(thd,tables, select_lex->item_list, + lex->value_list, select_lex->where, + (ORDER*) select_lex->order_list.first, + (ORDER*) select_lex->group_list.first, + select_lex->having, lex->lock_option)) + goto abort; + break; + + default: + { + /* + Rest fall through to default category, no parsing + for non-DML statements + */ + } + } + send_ok(&thd->net,thd->param_count,0); + DBUG_VOID_RETURN; + +abort: + send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0); + DBUG_VOID_RETURN; +} + +/* + Parse the prepare query +*/ + +static void mysql_parse_prepare_query(THD *thd, char *packet, uint length) +{ + DBUG_ENTER("mysql_parse_prepare_query"); + + mysql_log.write(thd,COM_PREPARE,"%s",packet); + mysql_init_query(thd); + thd->prepare_command=true; + + if (query_cache.send_result_to_client(thd, packet, length) <= 0) + { + LEX *lex=lex_start(thd, (uchar*)packet, length); + + if (!yyparse() && !thd->fatal_error) + { + send_prepare_results(thd); + query_cache_end_of_result(&thd->net); + } + else + query_cache_abort(&thd->net); + lex_end(lex); + } + DBUG_VOID_RETURN; +} + +/* + Parse the query and send the total number of parameters + and resultset metadata information back to client (if any), + without executing the query i.e. with out any log/disk + writes. This will allow the queries to be re-executed + without re-parsing during execute. + + If parameter markers are found in the query, then store + the information using Item_param along with maintaining a + list in lex->param_list, so that a fast and direct + retrieveal can be made without going through all field + items. +*/ + +void mysql_com_prepare(THD *thd, char *packet, uint packet_length) +{ + MEM_ROOT thd_root = thd->mem_root; + DBUG_ENTER("mysql_com_prepare"); + + packet_length--; + + while (isspace(packet[0]) && packet_length > 0) + { + packet++; + packet_length--; + } + char *pos=packet+packet_length; + while (packet_length > 0 && (pos[-1] == ';' || isspace(pos[-1]))) + { + pos--; + packet_length--; + } + /* + Have the prepare items to have a connection level scope or + till next prepare statement by doing all allocations using + connection level memory allocator 'con_root' from THD. + */ + free_root(&thd->con_root,MYF(0)); + init_sql_alloc(&thd->con_root,8192,8192); + thd->mem_root = thd->con_root; + + if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), + packet_length, + thd->db_length+2))) + DBUG_VOID_RETURN; + thd->query[packet_length]=0; + thd->packet.shrink(net_buffer_length); + thd->query_length = packet_length; + + if (!(specialflag & SPECIAL_NO_PRIOR)) + my_pthread_setprio(pthread_self(),QUERY_PRIOR); + + mysql_parse_prepare_query(thd,thd->query,packet_length); + + if (!(specialflag & SPECIAL_NO_PRIOR)) + my_pthread_setprio(pthread_self(),WAIT_PRIOR); + + thd->mem_root = thd_root; // restore main mem_root + DBUG_PRINT("exit",("prepare query ready")); + DBUG_VOID_RETURN; +} + + +/* + Executes previously prepared query + + If there is any parameters(thd->param_count), then replace + markers with the data supplied from client, and then + execute the query +*/ + +void mysql_com_execute(THD *thd) +{ + MEM_ROOT thd_root=thd->mem_root; + DBUG_ENTER("mysql_com_execute"); + DBUG_PRINT("enter", ("parameters : %ld", thd->param_count)); + + thd->mem_root = thd->con_root; + if (thd->param_count && setup_param_fields(thd, thd->lex.param_list)) + DBUG_VOID_RETURN; + + if (!(specialflag & SPECIAL_NO_PRIOR)) + my_pthread_setprio(pthread_self(),QUERY_PRIOR); + + /* TODO: + Also, have checks on basic executions such as mysql_insert(), + mysql_delete(), mysql_update() and mysql_select() to not to + have re-check on setup_* and other things .. + */ + mysql_execute_command(); + + if (!(specialflag & SPECIAL_NO_PRIOR)) + my_pthread_setprio(pthread_self(),WAIT_PRIOR); + + thd->mem_root = (MEM_ROOT )thd_root; + DBUG_PRINT("exit",("prepare-execute done!")); + DBUG_VOID_RETURN; +} + +/* + Long data in pieces from client +*/ + +void mysql_com_longdata(THD *thd) +{ + DBUG_ENTER("mysql_com_execute"); + + if(thd->param_count && setup_longdata(thd,thd->lex.param_list)) + DBUG_VOID_RETURN; + + send_ok(&thd->net,0,0);// ok status to client + DBUG_PRINT("exit",("longdata-buffering done!")); + DBUG_VOID_RETURN; +} + diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c10174a7b71..4737e068d3e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -126,8 +126,6 @@ static bool store_record_in_cache(JOIN_CACHE *cache); static void reset_cache(JOIN_CACHE *cache); static void read_cached_record(JOIN_TAB *tab); static bool cmp_buffer_with_ref(JOIN_TAB *tab); -static int setup_group(THD *thd,TABLE_LIST *tables,List &fields, - List &all_fields, ORDER *order, bool *hidden); static bool setup_new_fields(THD *thd,TABLE_LIST *tables,List &fields, List &all_fields,ORDER *new_order); static ORDER *create_distinct_group(ORDER *order, List &fields); @@ -6456,7 +6454,7 @@ int setup_order(THD *thd,TABLE_LIST *tables,List &fields, } -static int +int setup_group(THD *thd,TABLE_LIST *tables,List &fields, List &all_fields, ORDER *order, bool *hidden_group_fields) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1421eac168f..48d6bc7471f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -169,6 +169,201 @@ int mysqld_show_tables(THD *thd,const char *db,const char *wild) DBUG_RETURN(0); } +/*************************************************************************** +** List all table types supported +***************************************************************************/ + +static struct show_table_type_st sys_table_types[]= { + {"MyISAM", (char *)"YES", "Default type from 3.23 with great performance"}, + {"HEAP" , (char *)"YES", "Hash based, stored in memory, useful for temporary tables"}, + {"MERGE", (char *)"YES", "Collection of identical MyISAM tables"}, + {"ISAM", (char*) &have_isam,"Obsolete table type"}, + {"InnoDB", (char*) &have_innodb,"Supports transactions, row-level locking and foreign keys"}, + {"BDB", (char*) &have_berkeley_db, "Supports transactions and page-level locking"}, +}; + +int mysqld_show_table_types(THD *thd) +{ + List field_list; + DBUG_ENTER("mysqld_show_table_types"); + + field_list.push_back(new Item_empty_string("Type",10)); + field_list.push_back(new Item_empty_string("Support",10)); + field_list.push_back(new Item_empty_string("Comment",NAME_LEN)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + const char *default_type_name=ha_table_typelib.type_names[default_table_type-1]; + show_table_type_st *types = sys_table_types; + + uint i; + for (i = 0; i < 3; i++) + { + thd->packet.length(0); + net_store_data(&thd->packet,types[i].type); + if (!strcasecmp(default_type_name,types[i].type)) + net_store_data(&thd->packet,"DEFAULT"); + else + net_store_data(&thd->packet,types[i].value); + net_store_data(&thd->packet,types[i].comment); + if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + DBUG_RETURN(-1); + } + + for (; i < sizeof(sys_table_types)/sizeof(sys_table_types[0]); i++) + { + thd->packet.length(0); + net_store_data(&thd->packet,types[i].type); + SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) types[i].value; + + if (tmp == SHOW_OPTION_NO) + net_store_data(&thd->packet,"NO"); + else + { + if (tmp == SHOW_OPTION_YES) + { + if (!strcasecmp(default_type_name,types[i].type)) + net_store_data(&thd->packet,"DEFAULT"); + else + net_store_data(&thd->packet,"YES"); + } + else net_store_data(&thd->packet,"DISABLED"); + } + net_store_data(&thd->packet,types[i].comment); + if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + DBUG_RETURN(-1); + } + send_eof(&thd->net); + DBUG_RETURN(0); +} + +/*************************************************************************** +** List all privileges supported +***************************************************************************/ + +static struct show_table_type_st sys_privileges[]= { + {"Select", (char *)"Tables", "To retrieve rows from table"}, + {"Insert", (char *)"Tables", "To insert data into tables"}, + {"Update", (char *)"Tables", "To update existing rows "}, + {"Delete", (char *)"Tables", "To delete existing rows"}, + {"Index", (char *)"Tables", "To create or drop indexes"}, + {"Alter", (char *)"Tables", "To alter the table"}, + {"Create", (char *)"Databases,Tables,Indexes", "To create new databases and tables"}, + {"Drop", (char *)"Databases,Tables", "To drop databases and tables"}, + {"Grant", (char *)"Databases,Tables", "To give to other users those privileges you possesed"}, + {"References", (char *)"Databases,Tables", "To have references on tables"}, + {"Reload", (char *)"Server Admin", "To reload or refresh tables, logs and privileges"}, + {"Shutdown",(char *)"Server Admin", "To shutdown the server"}, + {"Process", (char *)"Server Admin", "To view the plain text of currently executing queries"}, + {"File", (char *)"File access on server", "To read and write files on the server"}, +}; + +int mysqld_show_privileges(THD *thd) +{ + List field_list; + DBUG_ENTER("mysqld_show_privileges"); + + field_list.push_back(new Item_empty_string("Privilege",10)); + field_list.push_back(new Item_empty_string("Context",15)); + field_list.push_back(new Item_empty_string("Comment",NAME_LEN)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + for (uint i=0; i < sizeof(sys_privileges)/sizeof(sys_privileges[0]); i++) + { + thd->packet.length(0); + net_store_data(&thd->packet,sys_privileges[i].type); + net_store_data(&thd->packet,sys_privileges[i].value); + net_store_data(&thd->packet,sys_privileges[i].comment); + if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + DBUG_RETURN(-1); + } + send_eof(&thd->net); + DBUG_RETURN(0); +} + + +/*************************************************************************** +** List all column types +***************************************************************************/ + +#if 0 +struct show_column_type_st { + const char *type; + uint size; + char *min_value; + char *max_value; + uint precision, + uint scale, + char *nullable; + char *auto_increment; + char *unsigned_attr; + char *zerofill; + char *searchable; + char *case_sensitivity; + char *default_value; + char *comment; +}; +#endif +static struct show_column_type_st sys_column_types[]= { + {"tinyint", + 1, "-128", "127", 0, 0, "YES", "YES", + "NO", "YES", "YES", "NO", "NULL,0", + "A very small integer"}, + {"tinyint unsigned", + 1, "0" , "255", 0, 0, "YES", "YES", + "YES", "YES", "YES", "NO", "NULL,0", + "A very small integer"}, +}; + +int mysqld_show_column_types(THD *thd) +{ + List field_list; + DBUG_ENTER("mysqld_show_column_types"); + + field_list.push_back(new Item_empty_string("Type",30)); + field_list.push_back(new Item_int("Size",(longlong) 1,21)); + field_list.push_back(new Item_empty_string("Min_Value",20)); + field_list.push_back(new Item_empty_string("Max_Value",20)); + field_list.push_back(new Item_int("Prec", 0,4)); + field_list.push_back(new Item_int("Scale", 0,4)); + field_list.push_back(new Item_empty_string("Nullable",4)); + field_list.push_back(new Item_empty_string("Auto_Increment",4)); + field_list.push_back(new Item_empty_string("Unsigned",4)); + field_list.push_back(new Item_empty_string("Zerofill",4)); + field_list.push_back(new Item_empty_string("Searchable",4)); + field_list.push_back(new Item_empty_string("Case_Sensitive",4)); + field_list.push_back(new Item_empty_string("Default",NAME_LEN)); + field_list.push_back(new Item_empty_string("Comment",NAME_LEN)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++) + { + thd->packet.length(0); + net_store_data(&thd->packet,sys_column_types[i].type); + net_store_data(&thd->packet,(longlong)sys_column_types[i].size); + net_store_data(&thd->packet,sys_column_types[i].min_value); + net_store_data(&thd->packet,sys_column_types[i].max_value); + net_store_data(&thd->packet,(uint32)sys_column_types[i].precision); + net_store_data(&thd->packet,(uint32)sys_column_types[i].scale); + net_store_data(&thd->packet,sys_column_types[i].nullable); + net_store_data(&thd->packet,sys_column_types[i].auto_increment); + net_store_data(&thd->packet,sys_column_types[i].unsigned_attr); + net_store_data(&thd->packet,sys_column_types[i].zerofill); + net_store_data(&thd->packet,sys_column_types[i].searchable); + net_store_data(&thd->packet,sys_column_types[i].case_sensitivity); + net_store_data(&thd->packet,sys_column_types[i].default_value); + net_store_data(&thd->packet,sys_column_types[i].comment); + if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + DBUG_RETURN(-1); + } + send_eof(&thd->net); + DBUG_RETURN(0); +} static int mysql_find_files(THD *thd,List *files, const char *db,const char *path, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 25d8dbbab16..d140cd4dcdd 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -324,6 +324,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token TRAILING %token TRANSACTION_SYM %token TYPE_SYM +%token TYPES_SYM %token FUNC_ARG0 %token FUNC_ARG1 %token FUNC_ARG2 @@ -346,6 +347,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token X509_SYM %token COMPRESSED_SYM +%token ERRORS +%token SQL_ERROR_COUNT +%token WARNINGS +%token SQL_WARNING_COUNT + %token BIGINT %token BLOB_SYM %token CHAR_SYM @@ -548,7 +554,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); literal text_literal insert_ident order_ident simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr - using_list subselect subselect_init + using_list param_marker subselect subselect_init %type expr_list udf_expr_list when_list ident_list ident_list_arg @@ -1720,6 +1726,7 @@ no_and_expr: simple_expr: simple_ident | literal + | param_marker | '@' ident_or_text SET_VAR expr { $$= new Item_func_set_user_var($2,$4); current_thd->safe_to_cache_query=0; @@ -2795,6 +2802,29 @@ show_param: if (!add_table_to_list($3,NULL,0)) YYABORT; } + | COLUMN_SYM TYPES_SYM + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_COLUMN_TYPES; + } + | TABLE_SYM TYPES_SYM + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_TABLE_TYPES; + } + | PRIVILEGES + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_PRIVILEGES; + } + | COUNT_SYM '(' '*' ')' WARNINGS + { Lex->sql_command = SQLCOM_SHOW_WARNS_COUNT;} + | COUNT_SYM '(' '*' ')' ERRORS + { Lex->sql_command = SQLCOM_SHOW_ERRORS_COUNT;} + | WARNINGS {Select->offset_limit=0L;} limit_clause + { Lex->sql_command = SQLCOM_SHOW_WARNS;} + | ERRORS {Select->offset_limit=0L;} limit_clause + { Lex->sql_command = SQLCOM_SHOW_ERRORS;} | STATUS_SYM wild { Lex->sql_command= SQLCOM_SHOW_STATUS; } | opt_full PROCESSLIST_SYM @@ -3055,7 +3085,20 @@ text_string: Item *tmp = new Item_varbinary($1.str,$1.length,default_charset_info); $$= tmp ? tmp->val_str((String*) 0) : (String*) 0; }; - +param_marker: + '?' + { + if(current_thd->prepare_command) + { + Lex->param_list.push_back($$=new Item_param()); + current_thd->param_count++; + } + else + { + yyerror("You have an error in your SQL syntax"); + YYABORT; + } + } literal: text_literal { $$ = $1; } | NUM { $$ = new Item_int($1.str, (longlong) atol($1.str),$1.length); } @@ -3411,6 +3454,16 @@ option_value: YYABORT; } | SQL_QUERY_CACHE_TYPE_SYM equal query_cache_type + | SQL_ERROR_COUNT equal ULONG_NUM + { + LEX *lex = Lex; + lex->thd->max_error_count = $3; + } + | SQL_WARNING_COUNT equal ULONG_NUM + { + LEX *lex = Lex; + lex->thd->max_warning_count = $3; + } | '@' ident_or_text equal expr { Item_func_set_user_var *item = new Item_func_set_user_var($2,$4); diff --git a/sql/structs.h b/sql/structs.h index 75280b34715..c4cb6c82209 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -152,6 +152,29 @@ struct show_var_st { SHOW_TYPE type; }; +struct show_table_type_st { + const char *type; + char *value; + const char *comment; +}; + +struct show_column_type_st { + const char *type; + uint size; + const char *min_value; + const char *max_value; + uint precision; + uint scale; + const char *nullable; + const char *auto_increment; + const char *unsigned_attr; + const char *zerofill; + const char *searchable; + const char *case_sensitivity; + const char *default_value; + const char *comment; +}; + typedef struct lex_string { char *str; uint length; -- cgit v1.2.1 From 25a38bb96fc286a0682d08dcc44c9daf20cd29d7 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jun 2002 15:47:05 -0700 Subject: mysql_priv.h: Missed change from previous resolve sql/mysql_priv.h: Missed change from previous resolve --- sql/mysql_priv.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 011b7823dd0..4f0bc2fe14a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -459,7 +459,7 @@ bool load_des_key_file(const char *file_name); /* sql_do.cc */ int mysql_do(THD *thd, List &values); -/* sql_show.c */ +/* sql_show.cc */ int mysqld_show_dbs(THD *thd,const char *wild); int mysqld_show_open_tables(THD *thd,const char *wild); int mysqld_show_tables(THD *thd,const char *db,const char *wild); @@ -477,6 +477,7 @@ int mysqld_show_status(THD *thd); int mysqld_show_variables(THD *thd,const char *wild); int mysqld_show(THD *thd, const char *wild, show_var_st *variables); int mysqld_show_charsets(THD *thd,const char *wild); +int mysqld_show_table_types(THD *thd); int mysqld_show_privileges(THD *thd); int mysqld_show_column_types(THD *thd); -- cgit v1.2.1 From 1fac9fecf7d93e42cefbecef6c1636b03af54955 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jun 2002 17:20:16 -0700 Subject: sql_list.h: One more missed fix from Windows sql/sql_list.h: One more missed fix from Windows --- sql/sql_list.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_list.h b/sql/sql_list.h index 541db4ec166..ef8a0c41a1b 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -82,6 +82,7 @@ public: first=tmp.first; last=tmp.last; } + inline base_list(bool error) { } inline bool push_back(void *info) { if (((*last)=new list_node(info, &end_of_list))) @@ -130,6 +131,7 @@ public: inline list_node *last_ref() { return &end_of_list; } friend class base_list_iterator; friend class error_list; + friend class error_list_iterator; protected: void after(void *info,list_node *node) @@ -405,7 +407,7 @@ class error_list: public Error_alloc, public base_list { public: inline error_list() : base_list() { }; - inline error_list(const error_list &tmp) : Error_alloc() + inline error_list(const error_list &tmp) : base_list(tmp) { elements=tmp.elements; first=tmp.first; -- cgit v1.2.1 From 2ec3617476e7731c5f6b704b0321d6be60822b2d Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jun 2002 22:43:40 +0500 Subject: UCS2 charset has been added --- sql/share/charsets/Index | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/share/charsets/Index b/sql/share/charsets/Index index 075cdc9872b..52cb6b99705 100644 --- a/sql/share/charsets/Index +++ b/sql/share/charsets/Index @@ -39,3 +39,4 @@ latin1_de 31 armscii8 32 utf8 33 win1250ch 34 +ucs2 35 -- cgit v1.2.1 From c6a2ae17a01d1f93257ea1ce5af0513d870585b0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jun 2002 17:52:44 +0300 Subject: EXISTS type of subselect more correct parameters in result creation script mysql-test/create-test-result: more correct parameters in result creation script mysql-test/r/subselect.result: test of EXISTS mysql-test/t/subselect.test: test of EXISTS sql/item_subselect.cc: EXISTS type of subselect sql/item_subselect.h: EXISTS type of subselect sql/sql_class.cc: EXISTS type of subselect sql/sql_class.h: EXISTS type of subselect sql/sql_yacc.yy: EXISTS type of subselect --- sql/item_subselect.cc | 121 +++++++++++++++++++++++++++++++++++--------------- sql/item_subselect.h | 89 +++++++++++++++++++++++++++++-------- sql/sql_class.cc | 43 ++++++++++++------ sql/sql_class.h | 23 ++++++++-- sql/sql_yacc.yy | 27 ++++++++--- 5 files changed, 225 insertions(+), 78 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index c2349ed414c..d8f9cf40d50 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -35,12 +35,13 @@ SUBSELECT TODO: #include "mysql_priv.h" #include "sql_select.h" -Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex): +Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex, + select_subselect *result): assigned(0), executed(0), optimized(0), error(0) { DBUG_ENTER("Item_subselect::Item_subselect"); DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex)); - result= new select_subselect(this); + this->result= result; SELECT_LEX_UNIT *unit= select_lex->master_unit(); unit->offset_limit_cnt= unit->global_parameters->offset_limit; unit->select_limit_cnt= unit->global_parameters->select_limit+ @@ -51,41 +52,15 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex): select_lex->options&= ~OPTION_FOUND_ROWS; join= new JOIN(thd, select_lex->item_list, select_lex->options, result); this->select_lex= select_lex; - maybe_null= 1; + assign_null(); /* item value is NULL if select_subselect not changed this value (i.e. some rows will be found returned) */ - assign_null(); + null_value= 1; DBUG_VOID_RETURN; } -Item::Type Item_subselect::type() const -{ - return SUBSELECT_ITEM; -} - -double Item_subselect::val () -{ - if (exec()) - return 0; - return real_value; -} - -longlong Item_subselect::val_int () -{ - if (exec()) - return 0; - return int_value; -} - -String *Item_subselect::val_str (String *str) -{ - if (exec() || null_value) - return 0; - return &str_value; -} - void Item_subselect::make_field (Send_field *tmp_field) { if (null_value) @@ -108,9 +83,9 @@ bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables) //TODO: subselects in having do not suported now my_printf_error(ER_SYNTAX_ERROR, ER(ER_SYNTAX_ERROR), MYF(0)); return 1; - } + } // Is it one field subselect? - if (select_lex->item_list.elements != 1) + if (select_lex->item_list.elements > max_columns) { my_printf_error(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0)); return 1; @@ -131,13 +106,14 @@ bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables) int Item_subselect::exec() { + DBUG_ENTER("Item_subselect::exec"); if (!optimized) { optimized=1; if (join->optimize()) { executed= 1; - return (join->error?join->error:1); + DBUG_RETURN(join->error?join->error:1); } } if (join->select_lex->depended && executed) @@ -145,7 +121,7 @@ int Item_subselect::exec() if (join->reinit()) { error= 1; - return 1; + DBUG_RETURN(1); } assign_null(); executed= assigned= 0; @@ -157,7 +133,80 @@ int Item_subselect::exec() join->exec(); join->thd->lex.select= save_select; executed= 1; - return join->error; + DBUG_RETURN(join->error); } - return 0; + DBUG_RETURN(0); } + +inline table_map Item_subselect::used_tables() const +{ + return (table_map) select_lex->depended ? 1L : 0L; +} + +Item_singleval_subselect::Item_singleval_subselect(THD *thd, + st_select_lex *select_lex): + Item_subselect(thd, select_lex, new select_singleval_subselect(this)) +{ + max_columns= 1; + maybe_null= 1; +} + +Item::Type Item_subselect::type() const +{ + return SUBSELECT_ITEM; +} + +double Item_singleval_subselect::val () +{ + if (exec()) + return 0; + return real_value; +} + +longlong Item_singleval_subselect::val_int () +{ + if (exec()) + return 0; + return int_value; +} + +String *Item_singleval_subselect::val_str (String *str) +{ + if (exec() || null_value) + return 0; + return &str_value; +} + +Item_exists_subselect::Item_exists_subselect(THD *thd, + st_select_lex *select_lex): + Item_subselect(thd, select_lex, new select_singleval_subselect(this)) +{ + max_columns= UINT_MAX; + null_value= 0; //can't be NULL + maybe_null= 0; //can't be NULL + value= 0; + select_lex->select_limit= 1; // we need only 1 row to determinate existence +} + +double Item_exists_subselect::val () +{ + if (exec()) + return 0; + return (double) value; +} + +longlong Item_exists_subselect::val_int () +{ + if (exec()) + return 0; + return value; +} + +String *Item_exists_subselect::val_str(String *str) +{ + if (exec()) + return 0; + str->set(value); + return str; +} + diff --git a/sql/item_subselect.h b/sql/item_subselect.h index c6963df2d53..79832116c67 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -24,42 +24,34 @@ struct st_select_lex; class JOIN; class select_subselect; -/* simple (not depended of covered select ) subselect */ +/* base class for subselects */ class Item_subselect :public Item { protected: - longlong int_value; - double real_value; + uint max_columns; my_bool assigned; /* value already assigned to subselect */ my_bool executed; /* simple subselect is executed */ my_bool optimized; /* simple subselect is optimized */ my_bool error; /* error in query */ - enum Item_result res_type; int exec(); - void assign_null() + virtual void assign_null() { null_value= 1; - int_value= 0; - real_value= 0; - max_length= 4; - res_type= STRING_RESULT; } public: st_select_lex *select_lex; JOIN *join; select_subselect *result; - Item_subselect(THD *thd, st_select_lex *select_lex); + Item_subselect(THD *thd, st_select_lex *select_lex, + select_subselect* result); Item_subselect(Item_subselect *item) { null_value= item->null_value; - int_value= item->int_value; - real_value= item->real_value; - max_length= item->max_length; decimals= item->decimals; - res_type= item->res_type; + max_columns= item->max_columns; assigned= item->assigned; executed= item->executed; select_lex= item->select_lex; @@ -69,16 +61,75 @@ public: error= item->error; } enum Type type() const; - double val (); - longlong val_int (); - String *val_str (String *); bool is_null() { return null_value; } void make_field (Send_field *); bool fix_fields(THD *thd, TABLE_LIST *tables); - Item *new_item() { return new Item_subselect(this); } - enum Item_result result_type() const { return res_type; } + table_map used_tables() const; friend class select_subselect; }; +/* single value subselect */ + +class Item_singleval_subselect :public Item_subselect +{ +protected: + longlong int_value; + double real_value; + enum Item_result res_type; + + virtual void assign_null() + { + null_value= 1; + int_value= 0; + real_value= 0; + max_length= 4; + res_type= STRING_RESULT; + } +public: + Item_singleval_subselect(THD *thd, st_select_lex *select_lex); + Item_singleval_subselect(Item_singleval_subselect *item): + Item_subselect(item) + { + int_value= item->int_value; + real_value= item->real_value; + max_length= item->max_length; + decimals= item->decimals; + res_type= item->res_type; + } + double val (); + longlong val_int (); + String *val_str (String *); + Item *new_item() { return new Item_singleval_subselect(this); } + enum Item_result result_type() const { return res_type; } + + friend class select_singleval_subselect; +}; + +/* exists subselect */ + +class Item_exists_subselect :public Item_subselect +{ +protected: + longlong value; + + virtual void assign_null() + { + value= 0; + } +public: + Item_exists_subselect(THD *thd, st_select_lex *select_lex); + Item_exists_subselect(Item_exists_subselect *item): + Item_subselect(item) + { + value= item->value; + } + Item *new_item() { return new Item_exists_subselect(this); } + enum Item_result result_type() const { return INT_RESULT;} + longlong val_int(); + double val(); + String *val_str(String*); + + friend class select_exists_subselect; +}; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 86e4e6896e6..85f5b3cb5f2 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -763,7 +763,6 @@ void select_dump::send_error(uint errcode,const char *err) file= -1; } - bool select_dump::send_eof() { int error=test(end_io_cache(&cache)); @@ -782,10 +781,11 @@ select_subselect::select_subselect(Item_subselect *item) this->item=item; } -bool select_subselect::send_data(List &items) +bool select_singleval_subselect::send_data(List &items) { - DBUG_ENTER("select_subselect::send_data"); - if (item->assigned){ + DBUG_ENTER("select_singleval_subselect::send_data"); + Item_singleval_subselect *it= (Item_singleval_subselect *)item; + if (it->assigned){ my_printf_error(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0)); DBUG_RETURN(1); } @@ -800,18 +800,33 @@ bool select_subselect::send_data(List &items) Following val() call have to be first, because function AVG() & STD() calculate value on it & determinate "is it NULL?". */ - item->real_value= val_item->val(); - if ((item->null_value= val_item->is_null())) + it->real_value= val_item->val(); + if ((it->null_value= val_item->is_null())) { - item->assign_null(); + it->assign_null(); } else { - item->max_length= val_item->max_length; - item->decimals= val_item->decimals; - item->binary= val_item->binary; - val_item->val_str(&item->str_value); - item->int_value= val_item->val_int(); - item->res_type= val_item->result_type(); + it->max_length= val_item->max_length; + it->decimals= val_item->decimals; + it->binary= val_item->binary; + val_item->val_str(&it->str_value); + it->int_value= val_item->val_int(); + it->res_type= val_item->result_type(); } - item->assigned= 1; + it->assigned= 1; DBUG_RETURN(0); } + +bool select_exists_subselect::send_data(List &items) +{ + DBUG_ENTER("select_exists_subselect::send_data"); + Item_exists_subselect *it= (Item_exists_subselect *)item; + if (unit->offset_limit_cnt) + { // Using limit offset,count + unit->offset_limit_cnt--; + DBUG_RETURN(0); + } + it->value= 1; + it->assigned= 1; + DBUG_RETURN(0); +} + diff --git a/sql/sql_class.h b/sql/sql_class.h index 8a1a299ceee..eb57b5828f6 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -712,19 +712,36 @@ class select_union :public select_result { bool flush(); }; -/* Single value subselect interface class */ +/* Base subselect interface class */ class select_subselect :public select_result { +protected: Item_subselect *item; public: select_subselect(Item_subselect *item); bool send_fields(List &list, uint flag) { return 0; }; - bool send_data(List &items); + bool send_data(List &items)=0; bool send_eof() { return 0; }; - + friend class Ttem_subselect; }; +/* Single value subselect interface class */ +class select_singleval_subselect :public select_subselect +{ +public: + select_singleval_subselect(Item_subselect *item):select_subselect(item){} + bool send_data(List &items); +}; + +/* EXISTS subselect interface class */ +class select_exists_subselect :public select_subselect +{ +public: + select_exists_subselect(Item_subselect *item):select_subselect(item){} + bool send_data(List &items); +}; + /* Structs used when sorting */ typedef struct st_sort_field { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index efc8b8b5389..9047bc472ac 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -548,7 +548,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); literal text_literal insert_ident order_ident simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr - using_list subselect subselect_init + using_list singleval_subselect singleval_subselect_init + exists_subselect exists_subselect_init %type expr_list udf_expr_list when_list ident_list ident_list_arg @@ -1738,7 +1739,8 @@ simple_expr: | NOT expr %prec NEG { $$= new Item_func_not($2); } | '!' expr %prec NEG { $$= new Item_func_not($2); } | '(' expr ')' { $$= $2; } - | subselect { $$= $1; } + | EXISTS exists_subselect { $$= $2; } + | singleval_subselect { $$= $1; } | '{' ident expr '}' { $$= $3; } | MATCH ident_list_arg AGAINST '(' expr ')' { Select->ftfunc_list.push_back((Item_func_match *) @@ -3918,17 +3920,30 @@ union_option: /* empty */ {} | ALL {Lex->union_option=1;}; -subselect: - subselect_start subselect_init +singleval_subselect: + subselect_start singleval_subselect_init subselect_end { $$= $2; }; -subselect_init: +singleval_subselect_init: select_init { - $$= new Item_subselect(current_thd, Lex->select); + $$= new Item_singleval_subselect(current_thd, Lex->select); + }; + +exists_subselect: + subselect_start exists_subselect_init + subselect_end + { + $$= $2; + }; + +exists_subselect_init: + select_init + { + $$= new Item_exists_subselect(current_thd, Lex->select); }; subselect_start: -- cgit v1.2.1 From e38f8e8ce21bc60f508ba15b3c01f3f1be4f7eef Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jun 2002 21:21:30 +0500 Subject: Default table character set has been added: CREATE TABLE a (field,...) TYPE=type CHARSET=cset; sql/handler.h: New flag to remember whether new table default charset has been passed in ALTER TABLE sql/lex.h: New language symbol sql/sql_show.cc: Display default table charset if exists sql/sql_table.cc: Check table charset before default server charset sql/sql_yacc.yy: New create table option: default table character set sql/table.cc: Table charset sql/unireg.cc: field->charset must be initialized before. So assumes it is not NULL --- sql/handler.h | 1 + sql/lex.h | 1 + sql/sql_show.cc | 8 +++++++- sql/sql_table.cc | 5 +++++ sql/sql_yacc.yy | 24 ++++++++++++++++++------ sql/table.cc | 11 ++++++----- sql/unireg.cc | 3 +-- 7 files changed, 39 insertions(+), 14 deletions(-) (limited to 'sql') diff --git a/sql/handler.h b/sql/handler.h index 45865c39154..7260e8f2f8c 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -137,6 +137,7 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, #define HA_CREATE_USED_MAX_ROWS 32 #define HA_CREATE_USED_AVG_ROW_LENGTH 64 #define HA_CREATE_USED_PACK_KEYS 128 +#define HA_CREATE_USED_CHARSET 256 typedef struct st_thd_trans { void *bdb_tid; diff --git a/sql/lex.h b/sql/lex.h index da0a71a135e..4af36df58af 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -82,6 +82,7 @@ static SYMBOL symbols[] = { { "CASE", SYM(CASE_SYM),0,0}, { "CHAR", SYM(CHAR_SYM),0,0}, { "CHARACTER", SYM(CHAR_SYM),0,0}, + { "CHARSET", SYM(CHARSET),0,0}, { "CHANGE", SYM(CHANGE),0,0}, { "CHANGED", SYM(CHANGED),0,0}, { "CHECK", SYM(CHECK_SYM),0,0}, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 48d6bc7471f..494607c7fff 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1156,6 +1156,12 @@ store_create_info(THD *thd, TABLE *table, String *packet) char buff[128]; char* p; + if (table->table_charset) + { + packet->append(" CHARSET="); + packet->append(table->table_charset->name); + } + if (table->min_rows) { packet->append(" MIN_ROWS="); @@ -1386,7 +1392,7 @@ int mysqld_show_charsets(THD *thd, const char *wild) net_store_data(&packet2,(uint32) cs->mbmaxlen); if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length())) - goto err; /* purecov: inspected */ + goto err; } } send_eof(&thd->net); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f4f4dd212bd..3a6ff3d6b16 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -375,6 +375,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, sql_field->offset= pos; if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) auto_increment++; + if(!sql_field->charset) + sql_field->charset = create_info->table_charset ? + create_info->table_charset : default_charset_info; pos+=sql_field->pack_length; } if (auto_increment > 1) @@ -1645,6 +1648,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, create_info->max_rows=table->max_rows; if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH)) create_info->avg_row_length=table->avg_row_length; + if (!(used_fields & HA_CREATE_USED_CHARSET)) + create_info->table_charset=table->table_charset; table->file->update_create_info(create_info); if ((create_info->table_options & diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d140cd4dcdd..228e43f3954 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -162,6 +162,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token CACHE_SYM %token CASCADE %token CAST_SYM +%token CHARSET %token CHECKSUM_SYM %token CHECK_SYM %token CIPHER @@ -767,7 +768,7 @@ create: bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.options=$2 | $4; lex->create_info.db_type= default_table_type; - lex->create_info.table_charset=default_charset_info; + lex->create_info.table_charset=NULL; } create2 @@ -881,6 +882,17 @@ create_table_option: table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } + | CHARSET EQ ident + { + CHARSET_INFO *cs=get_charset_by_name($3.str,MYF(MY_WME)); + if (!cs) + { + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3); + YYABORT; + } + Lex->create_info.table_charset=cs; + Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET; + } | INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} | DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; } | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; }; @@ -965,7 +977,7 @@ field_spec: LEX *lex=Lex; lex->length=lex->dec=0; lex->type=0; lex->interval=0; lex->default_value=lex->comment=0; - lex->charset=default_charset_info; + lex->charset=NULL; } type opt_attribute { @@ -1116,8 +1128,8 @@ attribute: | COMMENT_SYM text_literal { Lex->comment= $2; }; opt_binary: - /* empty */ { Lex->charset=default_charset_info; } - | BINARY { Lex->type|=BINARY_FLAG; Lex->charset=default_charset_info; } + /* empty */ { Lex->charset=NULL; } + | BINARY { Lex->type|=BINARY_FLAG; Lex->charset=NULL; } | CHAR_SYM SET ident { CHARSET_INFO *cs=get_charset_by_name($3.str,MYF(MY_WME)); @@ -1130,7 +1142,7 @@ opt_binary: }; default_charset: - /* empty */ { Lex->charset-default_charset_info; } + /* empty */ { Lex->charset=NULL; } | DEFAULT CHAR_SYM SET ident { CHARSET_INFO *cs=get_charset_by_name($4.str,MYF(MY_WME)); @@ -1259,7 +1271,7 @@ alter: bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.db_type= DB_TYPE_DEFAULT; lex->create_info.row_type= ROW_TYPE_NOT_USED; - lex->create_info.table_charset=default_charset_info; + lex->create_info.table_charset=NULL; lex->alter_keys_onoff=LEAVE_AS_IS; lex->simple_alter=1; } diff --git a/sql/table.cc b/sql/table.cc index 201b67032bf..8a7604687e7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -118,7 +118,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->raid_chunks= head[42]; outparam->raid_chunksize= uint4korr(head+43); if (!(outparam->table_charset=get_charset((uint) head[38],MYF(0)))) - outparam->table_charset=default_charset_info; + outparam->table_charset=NULL; // QQ display error message? null_field_first=1; } outparam->db_record_offset=1; @@ -358,7 +358,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, uint comment_length=uint2korr(strpos+13); field_type=(enum_field_types) (uint) strpos[11]; if (!(charset=get_charset((uint) strpos[12], MYF(0)))) - charset=outparam->table_charset; + charset=outparam->table_charset?outparam->table_charset:default_charset_info; if (!comment_length) { comment.str= (char*) ""; @@ -375,7 +375,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, { /* old frm file */ field_type= (enum_field_types) f_packtype(pack_flag); - charset=outparam->table_charset; + charset=outparam->table_charset?outparam->table_charset:default_charset_info; bzero((char*) &comment, sizeof(comment)); } *field_ptr=reg_field= @@ -1041,7 +1041,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, int2store(fileinfo+30,create_info->table_options); fileinfo[32]=0; // No filename anymore int4store(fileinfo+34,create_info->avg_row_length); - fileinfo[38]= create_info->table_charset->number; + fileinfo[38]= create_info->table_charset?create_info->table_charset->number:0; fileinfo[40]= (uchar) create_info->row_type; fileinfo[41]= (uchar) create_info->raid_type; fileinfo[42]= (uchar) create_info->raid_chunks; @@ -1072,6 +1072,7 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) create_info->raid_type=table->raid_type; create_info->raid_chunks=table->raid_chunks; create_info->raid_chunksize=table->raid_chunksize; + create_info->table_charset=table->table_charset; DBUG_VOID_RETURN; } @@ -1094,7 +1095,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) { Field *field=table->field[fieldnr]; char buff[MAX_FIELD_WIDTH]; - String str(buff,sizeof(buff),table->table_charset); + String str(buff,sizeof(buff),default_charset_info); field->val_str(&str,&str); uint length=str.length(); if (!length) diff --git a/sql/unireg.cc b/sql/unireg.cc index 863f71d1cce..f2d8d6532a9 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -459,8 +459,7 @@ static bool pack_fields(File file,List &create_fields) int2store(buff+8,field->unireg_check); buff[10]= (uchar) field->interval_id; buff[11]= (uchar) field->sql_type; - buff[12]= (uchar) (field->charset ? field->charset->number : - default_charset_info->number); + buff[12]= (uchar) field->charset->number; int2store(buff+13, field->comment.length); comment_length+= field->comment.length; set_if_bigger(int_count,field->interval_id); -- cgit v1.2.1 From 83dfb9f88582d3501e5dbee0340051119c4193f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jun 2002 21:48:34 +0500 Subject: Now it is possible to drop default charset from table: ALTER TABLE a CHARSET=DEFAULT --- sql/sql_yacc.yy | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 228e43f3954..83343e429e8 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -882,6 +882,11 @@ create_table_option: table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } + | CHARSET EQ DEFAULT + { + Lex->create_info.table_charset=NULL; + Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET; + } | CHARSET EQ ident { CHARSET_INFO *cs=get_charset_by_name($3.str,MYF(MY_WME)); -- cgit v1.2.1 From 2753972c39c5d07f9cd8899e086cc308dd09ca81 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 20 Jun 2002 18:47:55 +0500 Subject: New syntax for string with charset: _latin1'string' Remove dupicated code sql/sql_lex.cc: new UNDERSCORE_CHARSET language item --- sql/sql_lex.cc | 14 +++++++++++++- sql/sql_yacc.yy | 58 +++++++++++++++++++-------------------------------------- 2 files changed, 32 insertions(+), 40 deletions(-) (limited to 'sql') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 008ef44d83a..bcf212f6bd2 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -525,7 +525,19 @@ int yylex(void *arg) yylval->lex_str=get_token(lex,length); if (lex->convert_set) lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen); - return(IDENT); + + /* + Note: "SELECT _bla AS 'alias'" + _bla should be considered as a IDENT if charset haven't been found. + So we don't use MYF(MY_WME) with get_charset_by_name to avoid + producing an error. + */ + + if ((yylval->lex_str.str[0]=='_') && + (lex->charset=get_charset_by_name(yylval->lex_str.str+1,MYF(0)))) + return(UNDERSCORE_CHARSET); + else + return(IDENT); case STATE_IDENT_SEP: // Found ident and now '.' lex->next_state=STATE_IDENT_START;// Next is an ident (not a keyword) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 78d03bbbd1a..f3c5ae6efaf 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -334,6 +334,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token UDF_SONAME_SYM %token UDF_SYM %token UNCOMMITTED_SYM +%token UNDERSCORE_CHARSET %token UNION_SYM %token UNIQUE_SYM %token USAGE @@ -525,7 +526,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME - ULONGLONG_NUM field_ident select_alias ident ident_or_text + ULONGLONG_NUM field_ident select_alias ident ident_or_text UNDERSCORE_CHARSET %type opt_table_alias @@ -888,15 +889,9 @@ create_table_option: Lex->create_info.table_charset=NULL; Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET; } - | CHARSET EQ ident + | CHARSET EQ charset { - CHARSET_INFO *cs=get_charset_by_name($3.str,MYF(MY_WME)); - if (!cs) - { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3); - YYABORT; - } - Lex->create_info.table_charset=cs; + Lex->create_info.table_charset=Lex->charset; Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET; } | INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} @@ -1133,32 +1128,24 @@ attribute: | UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; } | COMMENT_SYM text_literal { Lex->comment= $2; }; +charset: + ident + { + if (!(Lex->charset=get_charset_by_name($1.str,MYF(0)))) + { + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$1); + YYABORT; + } + }; + opt_binary: /* empty */ { Lex->charset=NULL; } | BINARY { Lex->type|=BINARY_FLAG; Lex->charset=NULL; } - | CHAR_SYM SET ident - { - CHARSET_INFO *cs=get_charset_by_name($3.str,MYF(MY_WME)); - if (!cs) - { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3); - YYABORT; - } - Lex->charset=cs; - }; + | CHAR_SYM SET charset {/* charset is already in Lex->charset */} ; default_charset: /* empty */ { Lex->charset=NULL; } - | DEFAULT CHAR_SYM SET ident - { - CHARSET_INFO *cs=get_charset_by_name($4.str,MYF(MY_WME)); - if (!cs) - { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$4); - YYABORT; - } - Lex->charset=cs; - }; + | DEFAULT CHAR_SYM SET charset ; references: REFERENCES table_ident @@ -1777,16 +1764,8 @@ simple_expr: | CASE_SYM opt_expr WHEN_SYM when_list opt_else END { $$= new Item_func_case(* $4, $2, $5 ); } | CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); } - | CONVERT_SYM '(' expr USING IDENT ')' - { - CHARSET_INFO *cs=get_charset_by_name($5.str,MYF(MY_WME)); - if (!cs) - { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$5); - YYABORT; - } - $$= new Item_func_conv_charset($3,cs); - } + | CONVERT_SYM '(' expr USING charset ')' + { $$= new Item_func_conv_charset($3,Lex->charset); } | CONVERT_SYM '(' expr ',' expr ',' expr ')' { $$= new Item_func_conv_charset3($3,$7,$5); @@ -3094,6 +3073,7 @@ opt_ignore_lines: text_literal: TEXT_STRING { $$ = new Item_string($1.str,$1.length,default_charset_info); } + | UNDERSCORE_CHARSET TEXT_STRING { $$ = new Item_string($2.str,$2.length,Lex->charset); } | text_literal TEXT_STRING { ((Item_string*) $1)->append($2.str,$2.length); }; -- cgit v1.2.1 From 2583ecd6423922a89f75eec76f6cafbaba23c1f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 20 Jun 2002 22:52:56 +0500 Subject: SELECT left(non_default_charset_field,n) GROUP BY 1 now works more correctly. Still needs fixes. --- sql/item.cc | 3 +++ sql/item_func.cc | 11 +++++++++++ sql/item_strfunc.cc | 1 + sql/sql_select.cc | 3 ++- 4 files changed, 17 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index d01a06e5eba..415fe4d72af 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -133,6 +133,9 @@ void Item_field::set_field(Field *field_par) field_name=field_par->field_name; binary=field_par->binary(); unsigned_flag=test(field_par->flags & UNSIGNED_FLAG); + /* For string fields copy character set from original field */ + if (!field_par->binary()) + str_value.set_charset(((Field_str*)field_par)->charset()); } const char *Item_ident::full_name() const diff --git a/sql/item_func.cc b/sql/item_func.cc index 0675bf81dab..b14c1b38383 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -78,6 +78,17 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables) maybe_null=1; if ((*arg)->binary) binary=1; + /* + Change charset to arg charset if it is not equal to + default_charset_info. This will work for many cases, + but generally this should be done more carefull. Each string + function should have it's own fix_fields() method to correctly + setup it's result's character set taking in account arguments. + For example: left(a,b) should take in account only first argument, + but ignore the second one. + */ + if ((*arg)->str_value.charset() != default_charset_info) + str_value.set_charset((*arg)->str_value.charset()); with_sum_func= with_sum_func || (*arg)->with_sum_func; used_tables_cache|=(*arg)->used_tables(); const_item_cache&= (*arg)->const_item(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 5275da95b6e..81d866bfe6d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -759,6 +759,7 @@ String *Item_func_left::val_str(String *str) if (!res->alloced_length()) { // Don't change const str str_value= *res; // Not malloced string + str_value.set_charset(res->charset()); res= &str_value; } res->length((uint) length); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4737e068d3e..025a5c600a5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3579,7 +3579,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, item->name,table,item->binary); else new_field= new Field_string(item->max_length,maybe_null, - item->name,table,item->binary,default_charset_info); + item->name,table,item->binary, + item->str_value.charset()); break; } if (copy_func) -- cgit v1.2.1 From f7322a3cbd0d606f0ce2cdedf15d3212e1873bd0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 20 Jun 2002 23:26:04 +0500 Subject: New CHARSET() function --- sql/item_strfunc.cc | 13 +++++++++++++ sql/item_strfunc.h | 12 ++++++++++++ sql/sql_yacc.yy | 2 ++ 3 files changed, 27 insertions(+) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 81d866bfe6d..a4f09f9103e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1911,12 +1911,25 @@ outp: return str; } +String *Item_func_charset::val_str(String *str) +{ + String *res = args[0]->val_str(str); + + if ((null_value=(args[0]->null_value || !res->charset()))) + return 0; + str->copy(res->charset()->name,strlen(res->charset()->name)); + return str; +} + + void Item_func_conv_charset3::fix_length_and_dec() { /* BAR TODO: What to do here??? */ } + + String *Item_func_hex::val_str(String *str) { if (args[0]->result_type() != STRING_RESULT) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 03ef65c352a..a273abaf614 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -503,6 +503,18 @@ public: const char *func_name() const { return "conv_charset3"; } }; +class Item_func_charset :public Item_str_func +{ +public: + Item_func_charset(Item *a) :Item_str_func(a) {} + String *val_str(String *); + const char *func_name() const { return "charset"; } + void fix_length_and_dec() + { + max_length=20; // should be enough + }; +}; + /******************************************************* Spatial functions diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f3c5ae6efaf..91c87e9b849 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1784,6 +1784,8 @@ simple_expr: { $$= new Item_func_atan($3,$5); } | CHAR_SYM '(' expr_list ')' { $$= new Item_func_char(*$3); } + | CHARSET '(' expr ')' + { $$= new Item_func_charset($3); } | COALESCE '(' expr_list ')' { $$= new Item_func_coalesce(* $3); } | CONCAT '(' expr_list ')' -- cgit v1.2.1 From 17b4e3ed9661cb7b8d55128254ad76509e0b2abc Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 21 Jun 2002 14:46:50 +0500 Subject: Fixed charset problem on UPDATE in non-default-charset field --- sql/field_conv.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 3b6de1383e2..3b8a2ee791c 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -520,7 +520,9 @@ void field_conv(Field *to,Field *from) char buff[MAX_FIELD_WIDTH]; String result(buff,sizeof(buff),default_charset_info); from->val_str(&result,&result); - to->store(result.c_ptr_quick(),result.length(),default_charset_info); + to->store(result.c_ptr_quick(),result.length(), + to->binary()?default_charset_info:((Field_str*)to)->charset()); + // QQ: what to do if "from" and "to" are of dirrent charsets? } else if (from->result_type() == REAL_RESULT) to->store(from->val_real()); -- cgit v1.2.1 From 000828e0113e5fc79248ea38999ff67b3f19bac3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 21 Jun 2002 16:55:55 +0500 Subject: database default character set is now stored in database directory --- sql/mysql_priv.h | 2 +- sql/sql_db.cc | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- sql/sql_parse.cc | 2 +- sql/sql_yacc.yy | 1 + 4 files changed, 59 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 4f0bc2fe14a..1d0e3c1a72f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -289,7 +289,7 @@ inline THD *_current_thd(void) #define prepare_execute(A) ((A)->command == COM_EXECUTE) -int mysql_create_db(THD *thd, char *db, uint create_info, bool silent); +int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent); int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent); void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags); int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 3f619b70244..5275403db40 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -31,13 +31,15 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, /* db-name is already validated when we come here */ -int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) +int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent) { char path[FN_REFLEN+16]; MY_DIR *dirp; long result=1; int error = 0; DBUG_ENTER("mysql_create_db"); + register File file; + uint create_options = create_info ? create_info->options : 0; VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); @@ -73,6 +75,37 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) } } + /* + Create database options file: + Currently databse default charset is only stored there. + */ + + strcat(path,"/"); + unpack_dirname(path,path); + strcat(path,"db.opt"); + if ((file=my_create(path,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) + { + sprintf(path,"CREATE DATABASE %s DEFAULT CHARACTER SET=%s\n",db, + (create_info && create_info->table_charset) + ? create_info->table_charset->name : "DEFAULT"); + + if (my_write(file,(byte*) path,strlen(path),MYF(MY_NABP+MY_WME))) + { + // QQ : should we send more suitable error message? + my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno); + error = -1; + goto exit; + } + my_close(file,MYF(0)); + } + else + { + // QQ : should we send more suitable error message? + my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno); + error = -1; + goto exit; + } + if (!silent) { if (!thd->query) @@ -104,7 +137,7 @@ exit2: DBUG_RETURN(error); } -const char *del_exts[]= {".frm", ".BAK", ".TMD", NullS}; +const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS}; static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts}; @@ -333,6 +366,7 @@ bool mysql_change_db(THD *thd,const char *name) char path[FN_REFLEN]; uint db_access; DBUG_ENTER("mysql_change_db"); + register File file; if (!dbname || !(db_length=strip_sp(dbname))) { @@ -382,5 +416,25 @@ bool mysql_change_db(THD *thd,const char *name) thd->db=dbname; thd->db_length=db_length; thd->db_access=db_access; + + /* + Load database options file: + */ + + strcat(path,"/"); + unpack_dirname(path,path); + strcat(path,"db.opt"); + if ((file=my_open(path,O_RDWR|O_BINARY,MYF(MY_WME))) >= 0) + { + int nbytes=my_read(file,(byte*) path,sizeof(path),MYF(0)); + if ( nbytes >= 0 ) + { + path[nbytes]='\0'; + // BAR TODO: parse create options + // and extract database default charset + } + my_close(file,MYF(0)); + } + DBUG_RETURN(0); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 70f50483114..1f7e05fbae0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2308,7 +2308,7 @@ mysql_execute_command(void) } if (check_access(thd,CREATE_ACL,lex->name,0,1)) break; - res=mysql_create_db(thd,lex->name,lex->create_info.options,0); + res=mysql_create_db(thd,lex->name,&lex->create_info,0); break; } case SQLCOM_DROP_DB: diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 91c87e9b849..faa63afa6c7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -798,6 +798,7 @@ create: lex->sql_command=SQLCOM_CREATE_DB; lex->name=$4.str; lex->create_info.options=$3; + lex->create_info.table_charset=lex->charset; } | CREATE udf_func_type UDF_SYM ident { -- cgit v1.2.1 From 969919146e96f7709f32ac882359372a45da7944 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 24 Jun 2002 21:50:08 +0500 Subject: Database default charset now works: CREATE DATABASE dbname DEFAULT CHARACTERSET=latin1 sql/sql_class.cc: Database default charset sql/sql_class.h: Database default charset sql/sql_db.cc: Database default charset sql/sql_table.cc: Database default charset BitKeeper/etc/ignore: Added tests/client_test to the ignore list --- sql/sql_class.cc | 1 + sql/sql_class.h | 3 ++- sql/sql_db.cc | 45 ++++++++++++++++++++++++++++++++++++++------- sql/sql_table.cc | 4 +++- 4 files changed, 44 insertions(+), 9 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7a1ac4728da..c8914702ae7 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -103,6 +103,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), file_id = 0; cond_count=0; convert_set=0; + db_charset=default_charset_info; mysys_var=0; #ifndef DBUG_OFF dbug_sentry=THD_SENTRY_MAGIC; diff --git a/sql/sql_class.h b/sql/sql_class.h index 37eb366e21f..9b708e35a1e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -473,7 +473,8 @@ public: ulong slave_proxy_id; NET* slave_net; // network connection from slave -> m. my_off_t log_pos; - + CHARSET_INFO *db_charset; + THD(); ~THD(); void cleanup(void); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 5275403db40..91f7474bb33 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -25,6 +25,8 @@ #include #endif +#define MY_DB_OPT_FILE ".db.opt" + static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, const char *path, uint level); @@ -82,12 +84,12 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent strcat(path,"/"); unpack_dirname(path,path); - strcat(path,"db.opt"); + strcat(path,MY_DB_OPT_FILE); if ((file=my_create(path,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) { - sprintf(path,"CREATE DATABASE %s DEFAULT CHARACTER SET=%s\n",db, - (create_info && create_info->table_charset) - ? create_info->table_charset->name : "DEFAULT"); + sprintf(path,"default-character-set=%s\n", + (create_info && create_info->table_charset) ? + create_info->table_charset->name : "DEFAULT"); if (my_write(file,(byte*) path,strlen(path),MYF(MY_NABP+MY_WME))) { @@ -423,15 +425,44 @@ bool mysql_change_db(THD *thd,const char *name) strcat(path,"/"); unpack_dirname(path,path); - strcat(path,"db.opt"); + strcat(path,MY_DB_OPT_FILE); if ((file=my_open(path,O_RDWR|O_BINARY,MYF(MY_WME))) >= 0) { int nbytes=my_read(file,(byte*) path,sizeof(path),MYF(0)); if ( nbytes >= 0 ) { + char *ln=path; + char *pe=path+nbytes; + path[nbytes]='\0'; - // BAR TODO: parse create options - // and extract database default charset + for ( ln=path; lndb_charset=get_charset_by_name(val, MYF(0)); + } + goto cnt; + break; + } + } +cnt: + ln=le; + } } my_close(file,MYF(0)); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3a6ff3d6b16..d8012c0c102 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -377,7 +377,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, auto_increment++; if(!sql_field->charset) sql_field->charset = create_info->table_charset ? - create_info->table_charset : default_charset_info; + create_info->table_charset : + thd->db_charset? thd->db_charset : + default_charset_info; pos+=sql_field->pack_length; } if (auto_increment > 1) -- cgit v1.2.1 From 1ff701ee0ccc7410a9dc42ce5ee11e4004002d3a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Jun 2002 16:00:43 +0500 Subject: Several problems were fixed (mostly BLOB+charset related) Fixed that MyISAM were not working properly with non-8bit charsets in some cases CONVERT() function now works properly myisam/mi_unique.c: Fix for non-8bit charsets sql/field.cc: Initialize blobs with charset sql/field.h: Initialize blobs with charset sql/field_conv.cc: Initialize blobs with charset sql/item_strfunc.cc: CONVERT() function now has working fix_lenght_and_dec(), and it's own fix_fields() sql/item_strfunc.h: CONVERT() function now has working fix_lenght_and_dec(), and it's own fix_fields() sql/sql_select.cc: Fixes for BLOBs Fixed that wrong charset was used in some cases --- sql/field.cc | 11 ++++++----- sql/field.h | 11 ++++++----- sql/field_conv.cc | 3 ++- sql/item_strfunc.cc | 38 ++++++++++++++++++++++++++++---------- sql/item_strfunc.h | 4 +++- sql/sql_select.cc | 9 ++++++--- 6 files changed, 51 insertions(+), 25 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 8b1073d32f3..a475612fbb0 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3782,10 +3782,10 @@ uint Field_varstring::max_packed_col_length(uint max_length) Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg,uint blob_pack_length, - bool binary_arg) + bool binary_arg, CHARSET_INFO *cs) :Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, - table_arg, default_charset_info), + table_arg, cs), packlength(blob_pack_length),binary_flag(binary_arg), geom_flag(true) { flags|= BLOB_FLAG; @@ -3967,9 +3967,9 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)), char *blob; memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) - val_ptr->set("",0,default_charset_info); // A bit safer than ->length(0) + val_ptr->set("",0,field_charset); // A bit safer than ->length(0) else - val_ptr->set((const char*) blob,get_length(ptr),default_charset_info); + val_ptr->set((const char*) blob,get_length(ptr),field_charset); return val_ptr; } @@ -4782,7 +4782,8 @@ Field *make_field(char *ptr, uint32 field_length, if (f_is_blob(pack_flag)) return new Field_blob(ptr,null_pos,null_bit, unireg_check, field_name, table, - pack_length,f_is_binary(pack_flag) != 0); + pack_length,f_is_binary(pack_flag) != 0, + default_charset_info); if (f_is_geom(pack_flag)) return new Field_geom(ptr,null_pos,null_bit, unireg_check, field_name, table, diff --git a/sql/field.h b/sql/field.h index 5b9723654d9..5bc463af48d 100644 --- a/sql/field.h +++ b/sql/field.h @@ -842,11 +842,11 @@ public: Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg,uint blob_pack_length, - bool binary_arg); + bool binary_arg, CHARSET_INFO *cs); Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, bool binary_arg) + struct st_table *table_arg, bool binary_arg, CHARSET_INFO *cs) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg, default_charset_info), + NONE, field_name_arg, table_arg, cs), packlength(3),binary_flag(binary_arg), geom_flag(true) { flags|= BLOB_FLAG; @@ -930,11 +930,12 @@ public: struct st_table *table_arg,uint blob_pack_length, bool binary_arg) :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, - field_name_arg, table_arg, blob_pack_length,binary_arg) {} + field_name_arg, table_arg, blob_pack_length,binary_arg, + default_charset_info) {} Field_geom(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg, bool binary_arg) :Field_blob(len_arg, maybe_null_arg, field_name_arg, - table_arg, binary_arg) {} + table_arg, binary_arg, default_charset_info) {} enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; } void get_key_image(char *buff,uint length, imagetype type); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 3b8a2ee791c..da7a1187a47 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -508,7 +508,8 @@ void field_conv(Field *to,Field *from) if (!blob->value.is_alloced() && from->real_type() != FIELD_TYPE_STRING) blob->value.copy(); - blob->store(blob->value.ptr(),blob->value.length(),default_charset_info); + blob->store(blob->value.ptr(),blob->value.length(), + to->binary()?default_charset_info:((Field_str*)to)->charset()); return; } if ((from->result_type() == STRING_RESULT && diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index a4f09f9103e..c2549ddc769 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1799,7 +1799,7 @@ String *Item_func_conv_charset::val_str(String *str) s=(const uchar*)arg->ptr(); se=s+arg->length(); - dmaxlen=arg->length()*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1)+1; + dmaxlen=arg->length()*(to->mbmaxlen?to->mbmaxlen:1)+1; str->alloc(dmaxlen); d0=d=(unsigned char*)str->ptr(); de=d+dmaxlen; @@ -1841,7 +1841,7 @@ outp: void Item_func_conv_charset::fix_length_and_dec() { - /* BAR TODO: What to do here??? */ + max_length = args[0]->max_length*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1); } @@ -1911,23 +1911,41 @@ outp: return str; } -String *Item_func_charset::val_str(String *str) -{ - String *res = args[0]->val_str(str); - if ((null_value=(args[0]->null_value || !res->charset()))) - return 0; - str->copy(res->charset()->name,strlen(res->charset()->name)); - return str; +bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables) +{ + char buff[STACK_BUFF_ALLOC]; // Max argument in function + binary=0; + used_tables_cache=0; + const_item_cache=1; + + if (thd && check_stack_overrun(thd,buff)) + return 0; // Fatal error if flag is set! + if (args[0]->fix_fields(thd,tables)) + return 1; + maybe_null=args[0]->maybe_null; + binary=args[0]->binary; + str_value.set_charset(conv_charset); + fix_length_and_dec(); + return 0; } void Item_func_conv_charset3::fix_length_and_dec() { - /* BAR TODO: What to do here??? */ + max_length = args[0]->max_length; } +String *Item_func_charset::val_str(String *str) +{ + String *res = args[0]->val_str(str); + + if ((null_value=(args[0]->null_value || !res->charset()))) + return 0; + str->copy(res->charset()->name,strlen(res->charset()->name)); + return str; +} String *Item_func_hex::val_str(String *str) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index a273abaf614..74ec51274fc 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -40,7 +40,8 @@ public: if (!t_arg) return result_field; return (max_length > 255) ? - (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) : + (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary, + default_charset_info) : (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary, default_charset_info); } @@ -488,6 +489,7 @@ public: { conv_charset=cs; } + bool fix_fields(THD *thd,struct st_table_list *tables); String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "conv_charset"; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 025a5c600a5..f528750341e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3523,7 +3523,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case STRING_RESULT: if (item_sum->max_length > 255) return new Field_blob(item_sum->max_length,maybe_null, - item->name,table,item->binary); + item->name,table,item->binary,default_charset_info); return new Field_string(item_sum->max_length,maybe_null, item->name,table,item->binary,default_charset_info); } @@ -3576,7 +3576,8 @@ 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->binary); + item->name,table,item->binary, + item->str_value.charset()); else new_field= new Field_string(item->max_length,maybe_null, item->name,table,item->binary, @@ -4104,7 +4105,9 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, { Field *field=keyinfo->key_part[i].field; seg->flag= 0; - seg->language= MY_CHARSET_CURRENT; + seg->language= field->binary() ? MY_CHARSET_CURRENT : + ((Field_str*)field)->charset()->number; + seg->length= keyinfo->key_part[i].length; seg->start= keyinfo->key_part[i].offset; if (field->flags & BLOB_FLAG) -- cgit v1.2.1 From 328d6f42fcf06fb8bb62ab09bedf5a96dc955f22 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Jun 2002 16:41:51 +0500 Subject: This now correctly substitutes charset to new table: CREATE TABLE a SELECT strfunc(non_default_charset_expr) --- sql/item_strfunc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 74ec51274fc..967fb1ee7f2 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -41,9 +41,9 @@ public: return result_field; return (max_length > 255) ? (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary, - default_charset_info) : + str_value.charset()) : (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary, - default_charset_info); + str_value.charset()); } }; -- cgit v1.2.1 From 0d354e47ff13b0b3511a462f330e041e427061a0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Jun 2002 18:08:33 +0500 Subject: SELECT DISTINCT CONVERT(field USING charset) now works properly --- sql/item_strfunc.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index c2549ddc769..8fb3b7f6897 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1925,6 +1925,7 @@ bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables) return 1; maybe_null=args[0]->maybe_null; binary=args[0]->binary; + const_item_cache=args[0]->const_item(); str_value.set_charset(conv_charset); fix_length_and_dec(); return 0; -- cgit v1.2.1 From fce882261151614d2790aa9597eb668f3114c9d5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Jun 2002 14:41:02 +0500 Subject: ALTER DATABASE DEFAULT CHARACTER SET latin1; --- sql/mysql_priv.h | 3 +- sql/sql_db.cc | 227 ++++++++++++++++++++++++++++++++++++++----------------- sql/sql_lex.h | 3 +- sql/sql_parse.cc | 17 +++++ sql/sql_yacc.yy | 24 ++++-- 5 files changed, 195 insertions(+), 79 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 1d0e3c1a72f..2992f11ef65 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -289,7 +289,8 @@ inline THD *_current_thd(void) #define prepare_execute(A) ((A)->command == COM_EXECUTE) -int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent); +int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); +int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent); void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags); int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 91f7474bb33..aa8030e5a3e 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -31,6 +31,96 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, const char *path, uint level); +/* + Create database options file: + Currently databse default charset is only stored there. +*/ + +static int write_db_opt(THD *thd, char *db, HA_CREATE_INFO *create, char *fn) +{ + register File file; + char buf[256]; // Should be enough + int error=0; + + if ((file=my_create(fn,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) + { + sprintf(buf,"default-character-set=%s\n", + (create && create->table_charset) ? + create->table_charset->name : "DEFAULT"); + + if (my_write(file,(byte*)buf,strlen(buf),MYF(MY_NABP+MY_WME))) + { + // QQ : should we send more suitable error message? + my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno); + error = -1; + goto exit; + } + my_close(file,MYF(0)); + } + else + { + // QQ : should we send more suitable error message? + my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno); + error = -1; + goto exit; + } +exit: + return error; +} + + + /* + Load database options file: + */ +static int load_db_opt(THD *thd,char *fn) +{ + register File file; + char buf[256]=""; + + if ((file=my_open(fn,O_RDWR|O_BINARY,MYF(MY_WME))) >= 0) + { + int nbytes=my_read(file,(byte*)buf,sizeof(buf)-1,MYF(0)); + if ( nbytes >= 0 ) + { + char *ln=buf; + char *pe=buf+nbytes; + + buf[nbytes]='\0'; + + for ( ln=buf; lndb_charset=get_charset_by_name(val, MYF(0)); + } + goto cnt; + break; + } + } +cnt: + ln=le; + } + } + my_close(file,MYF(0)); + } + return 0; +} + /* db-name is already validated when we come here */ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent) @@ -39,10 +129,10 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent MY_DIR *dirp; long result=1; int error = 0; - DBUG_ENTER("mysql_create_db"); - register File file; uint create_options = create_info ? create_info->options : 0; - + + DBUG_ENTER("mysql_create_db"); + VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); // do not create database if another thread is holding read lock @@ -77,43 +167,81 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent } } - /* - Create database options file: - Currently databse default charset is only stored there. - */ - strcat(path,"/"); unpack_dirname(path,path); strcat(path,MY_DB_OPT_FILE); - if ((file=my_create(path,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) + if ((error=write_db_opt(thd,db,create_info,path))) + goto exit; + + if (!silent) { - sprintf(path,"default-character-set=%s\n", - (create_info && create_info->table_charset) ? - create_info->table_charset->name : "DEFAULT"); - - if (my_write(file,(byte*) path,strlen(path),MYF(MY_NABP+MY_WME))) + if (!thd->query) { - // QQ : should we send more suitable error message? - my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno); - error = -1; - goto exit; + thd->query = path; + thd->query_length = (uint) (strxmov(path,"create database ", db, NullS)- + path); } - my_close(file,MYF(0)); + { + mysql_update_log.write(thd,thd->query, thd->query_length); + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query); + mysql_bin_log.write(&qinfo); + } + } + if (thd->query == path) + { + thd->query = 0; // just in case + thd->query_length = 0; + } + send_ok(&thd->net, result); } - else + +exit: + start_waiting_global_read_lock(thd); +exit2: + VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); + DBUG_RETURN(error); +} + + +/* db-name is already validated when we come here */ + +int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent) +{ + char path[FN_REFLEN+16]; + MY_DIR *dirp; + long result=1; + int error = 0; + DBUG_ENTER("mysql_create_db"); + register File file; + uint create_options = create_info ? create_info->options : 0; + + printf("alter database\n"); + + VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); + + // do not alter database if another thread is holding read lock + if (wait_if_global_read_lock(thd,0)) { - // QQ : should we send more suitable error message? - my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno); - error = -1; - goto exit; + error= -1; + goto exit2; } + /* Check directory */ + (void)sprintf(path,"%s/%s", mysql_data_home, db); + strcat(path,"/"); + unpack_dirname(path,path); // Convert if not unix + strcat(path,MY_DB_OPT_FILE); + if ((error=write_db_opt(thd,db,create_info,path))) + goto exit; + if (!silent) { if (!thd->query) { thd->query = path; - thd->query_length = (uint) (strxmov(path,"create database ", db, NullS)- + thd->query_length = (uint) (strxmov(path,"alter database ", db, NullS)- path); } { @@ -139,6 +267,10 @@ exit2: DBUG_RETURN(error); } + + + + const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS}; static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts}; @@ -368,7 +500,6 @@ bool mysql_change_db(THD *thd,const char *name) char path[FN_REFLEN]; uint db_access; DBUG_ENTER("mysql_change_db"); - register File file; if (!dbname || !(db_length=strip_sp(dbname))) { @@ -419,53 +550,11 @@ bool mysql_change_db(THD *thd,const char *name) thd->db_length=db_length; thd->db_access=db_access; - /* - Load database options file: - */ - strcat(path,"/"); unpack_dirname(path,path); strcat(path,MY_DB_OPT_FILE); - if ((file=my_open(path,O_RDWR|O_BINARY,MYF(MY_WME))) >= 0) - { - int nbytes=my_read(file,(byte*) path,sizeof(path),MYF(0)); - if ( nbytes >= 0 ) - { - char *ln=path; - char *pe=path+nbytes; + load_db_opt(thd,path); - path[nbytes]='\0'; - for ( ln=path; lndb_charset=get_charset_by_name(val, MYF(0)); - } - goto cnt; - break; - } - } -cnt: - ln=le; - } - } - my_close(file,MYF(0)); - } DBUG_RETURN(0); } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ca824b3eab8..545300b2629 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -44,7 +44,8 @@ enum enum_sql_command { SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, - SQLCOM_GRANT, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, + SQLCOM_GRANT, + SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB, SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1f7e05fbae0..43cb056ffc8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2328,6 +2328,23 @@ mysql_execute_command(void) res=mysql_rm_db(thd,lex->name,lex->drop_if_exists,0); break; } + case SQLCOM_ALTER_DB: + { + if (!strip_sp(lex->name) || check_db_name(lex->name)) + { + net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); + break; + } + if (check_access(thd,DROP_ACL,lex->name,0,1)) + break; + if (thd->locked_tables || thd->active_transaction()) + { + send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); + goto error; + } + res=mysql_alter_db(thd,lex->name,&lex->create_info,0); + break; + } case SQLCOM_CREATE_FUNCTION: if (check_access(thd,INSERT_ACL,"mysql",0,1)) break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index faa63afa6c7..303a539eb49 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -885,12 +885,7 @@ create_table_option: table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } - | CHARSET EQ DEFAULT - { - Lex->create_info.table_charset=NULL; - Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET; - } - | CHARSET EQ charset + | CHARSET EQ charset_or_nocharset { Lex->create_info.table_charset=Lex->charset; Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET; @@ -1139,6 +1134,10 @@ charset: } }; +charset_or_nocharset: + charset + | DEFAULT {Lex->charset=NULL; } + opt_binary: /* empty */ { Lex->charset=NULL; } | BINARY { Lex->type|=BINARY_FLAG; Lex->charset=NULL; } @@ -1146,7 +1145,7 @@ opt_binary: default_charset: /* empty */ { Lex->charset=NULL; } - | DEFAULT CHAR_SYM SET charset ; + | DEFAULT CHAR_SYM SET charset_or_nocharset ; references: REFERENCES table_ident @@ -1270,7 +1269,16 @@ alter: lex->simple_alter=1; } alter_list; - + + | ALTER DATABASE ident default_charset + { + LEX *lex=Lex; + lex->sql_command=SQLCOM_ALTER_DB; + lex->name=$3.str; + lex->create_info.table_charset=lex->charset; + } + + alter_list: | alter_list_item | alter_list ',' alter_list_item; -- cgit v1.2.1 From e6a32a67ba7a1ec636df9d05a67a241cef2e5b4a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Jun 2002 15:21:52 +0500 Subject: Now database default character is changed during ALTER DATABASE if the current db is being altered --- sql/sql_db.cc | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/sql_db.cc b/sql/sql_db.cc index aa8030e5a3e..63edebd4ac7 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -36,7 +36,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, Currently databse default charset is only stored there. */ -static int write_db_opt(THD *thd, char *db, HA_CREATE_INFO *create, char *fn) +static int write_db_opt(THD *thd,const char *db,HA_CREATE_INFO *create,char *fn) { register File file; char buf[256]; // Should be enough @@ -72,7 +72,7 @@ exit: /* Load database options file: */ -static int load_db_opt(THD *thd,char *fn) +static int load_db_opt(THD *thd,const char *db,HA_CREATE_INFO *create,char *fn) { register File file; char buf[256]=""; @@ -217,8 +217,6 @@ int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent) register File file; uint create_options = create_info ? create_info->options : 0; - printf("alter database\n"); - VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); // do not alter database if another thread is holding read lock @@ -236,6 +234,15 @@ int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent) if ((error=write_db_opt(thd,db,create_info,path))) goto exit; + /* + Change options if current + database is being altered + */ + if (thd->db && !strcmp(thd->db,db)) + { + thd->db_charset= create_info ? create_info->table_charset : NULL; + } + if (!silent) { if (!thd->query) @@ -499,6 +506,8 @@ bool mysql_change_db(THD *thd,const char *name) char *dbname=my_strdup((char*) name,MYF(MY_WME)); char path[FN_REFLEN]; uint db_access; + HA_CREATE_INFO create; + DBUG_ENTER("mysql_change_db"); if (!dbname || !(db_length=strip_sp(dbname))) @@ -553,8 +562,9 @@ bool mysql_change_db(THD *thd,const char *name) strcat(path,"/"); unpack_dirname(path,path); strcat(path,MY_DB_OPT_FILE); - load_db_opt(thd,path); - + bzero(&create,sizeof(create)); + load_db_opt(thd,name,&create,path); + thd->db_charset=create.table_charset; DBUG_RETURN(0); } -- cgit v1.2.1 From 96d34f547b59fa5bd1f36956cfe9b92778f1b39e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Jun 2002 19:00:49 +0500 Subject: Fix --- sql/item_strfunc.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 8fb3b7f6897..5bb2c4015ad 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1792,6 +1792,7 @@ String *Item_func_conv_charset::val_str(String *str) null_value=1; return 0; } + null_value=0; from=arg->charset(); to=conv_charset; -- cgit v1.2.1 From e5b5f45319a9fe1c90710e49faecc6a33eeac486 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Jul 2002 14:14:51 +0300 Subject: subselect in having clause fixed bug in sum function in subselect mysql-test/r/subselect.result: subselect in having clause mysql-test/t/subselect.test: subselect in having clause sql/item.cc: subselect in having clause sql/item.h: subselect in having clause sql/item_cmpfunc.cc: subselect in having clause sql/item_cmpfunc.h: subselect in having clause sql/item_func.cc: subselect in having clause sql/item_func.h: subselect in having clause sql/item_strfunc.h: subselect in having clause sql/item_subselect.cc: subselect in having clause sql/item_subselect.h: subselect in having clause sql/item_uniq.h: subselect in having clause sql/sql_base.cc: subselect in having clause sql/sql_class.cc: subselect in having clause sql/sql_class.h: subselect in having clause sql/sql_handler.cc: subselect in having clause sql/sql_lex.cc: subselect in having clause sql/sql_lex.h: subselect in having clause sql/sql_prepare.cc: subselect in having clause sql/sql_yacc.yy: subselect in having clause --- sql/item.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++++----- sql/item.h | 11 +++++---- sql/item_cmpfunc.cc | 21 ++++++++--------- sql/item_cmpfunc.h | 18 ++++++++------- sql/item_func.cc | 19 ++++++++-------- sql/item_func.h | 19 ++++++++-------- sql/item_strfunc.h | 16 +++++++------ sql/item_subselect.cc | 9 +------- sql/item_subselect.h | 2 +- sql/item_sum.cc | 13 ++++++----- sql/item_sum.h | 8 +++---- sql/item_uniq.h | 2 +- sql/sql_base.cc | 6 ++--- sql/sql_class.cc | 2 +- sql/sql_class.h | 1 - sql/sql_handler.cc | 2 +- sql/sql_lex.cc | 4 ++-- sql/sql_lex.h | 5 ++++- sql/sql_prepare.cc | 4 ++-- sql/sql_select.cc | 28 ++++++++++++++--------- sql/sql_yacc.yy | 7 +++--- 21 files changed, 162 insertions(+), 97 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 415fe4d72af..81c5168b72d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -446,12 +446,13 @@ String *Item_copy_string::val_str(String *str) /* ARGSUSED */ bool Item::fix_fields(THD *thd, - struct st_table_list *list) + struct st_table_list *list, + Item ** ref) { return 0; } -bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) +bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { if (!field) // If field is not checked { @@ -467,7 +468,7 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) mention of table name, but if we join tables in one list it will cause error ER_NON_UNIQ_ERROR in find_field_in_tables. */ - SELECT_LEX *last; + SELECT_LEX *last= 0; for (SELECT_LEX *sl= thd->lex.select->outer_select(); sl && !tmp; sl= sl->outer_select()) @@ -476,6 +477,8 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) if (!tmp) return 1; else + { + depended_from= last; /* Mark all selects from resolved to 1 before select where was found table as depended (of select where was found table) @@ -493,6 +496,7 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) tbl= tbl->next) tbl->shared= 1; } + } } set_field(tmp); } @@ -504,6 +508,14 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) table->used_fields++; table->used_keys&=field->part_of_key; } + if (depended_from != 0 && depended_from->having_fix_field) + { + *ref= new Item_ref((char *)db_name, (char *)table_name, + (char *)field_name); + if (!*ref) + return 1; + return (*ref)->fix_fields(thd, tables, ref); + } return 0; } @@ -787,12 +799,50 @@ bool Item_null::send(THD *thd, String *packet) Find field in select list having the same name */ -bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables) +bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { if (!ref) { - if (!(ref=find_item_in_list(this,thd->lex.select->item_list))) - return 1; + if (!(ref= find_item_in_list(this,thd->lex.select->item_list))) + { + /* + We can't find table field in table list of current select, + consequently we have to find it in outer subselect(s). + We can't join lists of outer & current select, because of scope + of view rules. For example if both tables (outer & current) have + field 'field' it is not mistake to refer to this field without + mention of table name, but if we join tables in one list it will + cause error ER_NON_UNIQ_ERROR in find_field_in_tables. + */ + SELECT_LEX *last=0; + for (SELECT_LEX *sl= thd->lex.select->outer_select(); + sl && !ref; + sl= sl->outer_select()) + ref= find_item_in_list(this, (last= sl)->item_list); + if (!ref) + return 1; + else + { + depended_from= last; + /* + Mark all selects from resolved to 1 before select where was + found table as depended (of select where was found table) + */ + for (SELECT_LEX *s= thd->lex.select; + s &&s != last; + s= s->outer_select()) + if( !s->depended ) + { + s->depended= 1; //Select is depended of outer select + //Tables will be reopened many times + for (TABLE_LIST *tbl= + (TABLE_LIST*)s->table_list.first; + tbl; + tbl= tbl->next) + tbl->shared= 1; + } + } + } max_length= (*ref)->max_length; maybe_null= (*ref)->maybe_null; decimals= (*ref)->decimals; diff --git a/sql/item.h b/sql/item.h index e6debdf2afc..187e3903b84 100644 --- a/sql/item.h +++ b/sql/item.h @@ -52,7 +52,7 @@ public: virtual ~Item() { name=0; } /*lint -e1509 */ void set_name(char* str,uint length=0); void init_make_field(Send_field *tmp_field,enum enum_field_types type); - virtual bool fix_fields(THD *,struct st_table_list *); + virtual bool fix_fields(THD *, struct st_table_list *, Item **); virtual bool save_in_field(Field *field); virtual void save_org_in_field(Field *field) { (void) save_in_field(field); } @@ -85,15 +85,18 @@ public: }; +class st_select_lex; class Item_ident :public Item { public: const char *db_name; const char *table_name; const char *field_name; + st_select_lex *depended_from; Item_ident(const char *db_name_par,const char *table_name_par, const char *field_name_par) - :db_name(db_name_par),table_name(table_name_par),field_name(field_name_par) + :db_name(db_name_par),table_name(table_name_par), + field_name(field_name_par), depended_from(0) { name = (char*) field_name_par; } const char *full_name() const; }; @@ -120,7 +123,7 @@ public: String *str_result(String* tmp); bool send(THD *thd, String *str_arg) { return result_field->send(thd,str_arg); } void make_field(Send_field *field); - bool fix_fields(THD *,struct st_table_list *); + bool fix_fields(THD *, struct st_table_list *, Item **); bool save_in_field(Field *field); void save_org_in_field(Field *field); table_map used_tables() const; @@ -390,7 +393,7 @@ public: } bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); } void make_field(Send_field *field) { (*ref)->make_field(field); } - bool fix_fields(THD *,struct st_table_list *); + bool fix_fields(THD *, struct st_table_list *, Item **); bool save_in_field(Field *field) { return (*ref)->save_in_field(field); } void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); } enum Item_result result_type () const { return (*ref)->result_type(); } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8433ae5bfba..0fc9a1f0e4c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -727,12 +727,12 @@ double Item_func_case::val() bool -Item_func_case::fix_fields(THD *thd,TABLE_LIST *tables) +Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { - if (first_expr && first_expr->fix_fields(thd,tables) || - else_expr && else_expr->fix_fields(thd,tables)) + if (first_expr && first_expr->fix_fields(thd, tables, &first_expr) || + else_expr && else_expr->fix_fields(thd, tables, &else_expr)) return 1; - if (Item_func::fix_fields(thd,tables)) + if (Item_func::fix_fields(thd, tables, ref)) return 1; if (first_expr) { @@ -1074,7 +1074,7 @@ longlong Item_func_bit_and::val_int() bool -Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) +Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { List_iterator li(list); Item *item; @@ -1096,7 +1096,7 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) #endif item= *li.ref(); // new current item } - if (item->fix_fields(thd,tables)) + if (item->fix_fields(thd, tables, li.ref())) return 1; /* purecov: inspected */ used_tables_cache|=item->used_tables(); with_sum_func= with_sum_func || item->with_sum_func; @@ -1272,9 +1272,9 @@ Item_func::optimize_type Item_func_like::select_optimize() const return OPTIMIZE_NONE; } -bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist) +bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) { - if (Item_bool_func2::fix_fields(thd, tlist)) + if (Item_bool_func2::fix_fields(thd, tlist, ref)) return 1; /* @@ -1324,9 +1324,10 @@ bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist) #ifdef USE_REGEX bool -Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) +Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { - if (args[0]->fix_fields(thd,tables) || args[1]->fix_fields(thd,tables)) + if (args[0]->fix_fields(thd, tables, args) || + args[1]->fix_fields(thd,tables, args + 1)) return 1; /* purecov: inspected */ with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func; max_length=1; decimals=0; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 302ad88905e..08c5a30c57c 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -177,9 +177,10 @@ public: Item_func_interval(Item *a,List &list) :Item_int_func(list),item(a),intervals(0) {} longlong val_int(); - bool fix_fields(THD *thd,struct st_table_list *tlist) + bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref) { - return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); + return (item->fix_fields(thd, tlist, &item) || + Item_func::fix_fields(thd, tlist, ref)); } void fix_length_and_dec(); ~Item_func_interval() { delete item; } @@ -259,7 +260,7 @@ public: enum Item_result result_type () const { return cached_result_type; } const char *func_name() const { return "case"; } void print(String *str); - bool fix_fields(THD *thd,struct st_table_list *tlist); + bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); Item *find_item(String *str); }; @@ -409,9 +410,10 @@ class Item_func_in :public Item_int_func Item_func_in(Item *a,List &list) :Item_int_func(list),item(a),array(0),in_item(0) {} longlong val_int(); - bool fix_fields(THD *thd,struct st_table_list *tlist) + bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref) { - return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); + return (item->fix_fields(thd, tlist, &item) || + Item_func::fix_fields(thd, tlist, ref)); } void fix_length_and_dec(); ~Item_func_in() { delete item; delete array; delete in_item; } @@ -505,7 +507,7 @@ public: cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "like"; } void fix_length_and_dec(); - bool fix_fields(THD *thd,struct st_table_list *tlist); + bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); }; #ifdef USE_REGEX @@ -523,7 +525,7 @@ public: regex_compiled(0),regex_is_const(0) {} ~Item_func_regex(); longlong val_int(); - bool fix_fields(THD *thd,struct st_table_list *tlist); + bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); const char *func_name() const { return "regex"; } }; @@ -552,7 +554,7 @@ public: { list.push_back(i1); list.push_back(i2); } ~Item_cond() { list.delete_elements(); } bool add(Item *item) { return list.push_back(item); } - bool fix_fields(THD *,struct st_table_list *); + bool fix_fields(THD *, struct st_table_list *, Item **ref); enum Type type() const { return COND_ITEM; } List* argument_list() { return &list; } diff --git a/sql/item_func.cc b/sql/item_func.cc index b14c1b38383..ae3fc7cb8f0 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -58,7 +58,7 @@ Item_func::Item_func(List &list) } bool -Item_func::fix_fields(THD *thd,TABLE_LIST *tables) +Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { Item **arg,**arg_end; char buff[STACK_BUFF_ALLOC]; // Max argument in function @@ -72,7 +72,7 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables) { // Print purify happy for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) { - if ((*arg)->fix_fields(thd,tables)) + if ((*arg)->fix_fields(thd, tables, arg)) return 1; /* purecov: inspected */ if ((*arg)->maybe_null) maybe_null=1; @@ -1102,7 +1102,7 @@ udf_handler::~udf_handler() bool -udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func, +udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, uint arg_count, Item **arguments) { char buff[STACK_BUFF_ALLOC]; // Max argument in function @@ -1146,7 +1146,7 @@ udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func, arg != arg_end ; arg++,i++) { - if ((*arg)->fix_fields(thd,tables)) + if ((*arg)->fix_fields(thd, tables, arg)) return 1; if ((*arg)->binary) func->binary=1; @@ -1765,11 +1765,12 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, } -bool Item_func_set_user_var::fix_fields(THD *thd,TABLE_LIST *tables) +bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, + Item **ref) { if (!thd) thd=current_thd; - if (Item_func::fix_fields(thd,tables) || + if (Item_func::fix_fields(thd, tables, ref) || !(entry= get_variable(&thd->user_vars, name, 1))) return 1; entry->update_query_id=thd->query_id; @@ -2095,7 +2096,7 @@ void Item_func_match::init_search(bool no_order) } } -bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) +bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { List_iterator li(fields); Item *item; @@ -2108,7 +2109,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) modifications to find_best and auto_close as complement to auto_init code above. */ - if (Item_func::fix_fields(thd,tlist) || !const_item()) + if (Item_func::fix_fields(thd, tlist, ref) || !const_item()) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST"); return 1; @@ -2116,7 +2117,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) while ((item=li++)) { - if (item->fix_fields(thd,tlist)) + if (item->fix_fields(thd, tlist, li.ref())) return 1; if (item->type() == Item::REF_ITEM) li.replace(item= *((Item_ref *)item)->ref); diff --git a/sql/item_func.h b/sql/item_func.h index 0056126d50e..86b2a17931d 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -99,7 +99,7 @@ public: } Item_func(List &list); ~Item_func() {} /* Nothing to do; Items are freed automaticly */ - bool fix_fields(THD *,struct st_table_list *); + bool fix_fields(THD *,struct st_table_list *, Item **ref); void make_field(Send_field *field); table_map used_tables() const; void update_used_tables(); @@ -567,9 +567,10 @@ public: Item_func_field(Item *a,List &list) :Item_int_func(list),item(a) {} ~Item_func_field() { delete item; } longlong val_int(); - bool fix_fields(THD *thd,struct st_table_list *tlist) + bool fix_fields(THD *thd,struct st_table_list *tlist, Item **ref) { - return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); + return (item->fix_fields(thd, tlist, &item) || + Item_func::fix_fields(thd, tlist, ref)); } void update_used_tables() { @@ -708,11 +709,11 @@ public: :Item_func(list), udf(udf_arg) {} ~Item_udf_func() {} const char *func_name() const { return udf.name(); } - bool fix_fields(THD *thd,struct st_table_list *tables) + bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref) { - bool res=udf.fix_fields(thd,tables,this,arg_count,args); - used_tables_cache=udf.used_tables_cache; - const_item_cache=udf.const_item_cache; + bool res= udf.fix_fields(thd, tables, this, arg_count, args); + used_tables_cache= udf.used_tables_cache; + const_item_cache= udf.const_item_cache; return res; } Item_result result_type () const { return udf.result_type(); } @@ -867,7 +868,7 @@ public: void update_hash(void *ptr, uint length, enum Item_result type); bool update(); enum Item_result result_type () const { return cached_result_type; } - bool fix_fields(THD *thd,struct st_table_list *tables); + bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref); void fix_length_and_dec(); void print(String *str); const char *func_name() const { return "set_user_var"; } @@ -941,7 +942,7 @@ public: } enum Functype functype() const { return FT_FUNC; } void update_used_tables() {} - bool fix_fields(THD *thd,struct st_table_list *tlist); + bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); bool eq(const Item *, bool binary_cmp) const; longlong val_int() { return val()!=0.0; } double val(); diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index a273abaf614..6e15b8317d1 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -79,10 +79,10 @@ public: String *val_str(String *); void fix_length_and_dec(); void update_used_tables(); - bool fix_fields(THD *thd,struct st_table_list *tlist) + bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { - return (separator->fix_fields(thd,tlist) - || Item_func::fix_fields(thd,tlist)); + return (separator->fix_fields(thd, tlist, &separator) + || Item_func::fix_fields(thd, tlist, ref)); } const char *func_name() const { return "concat_ws"; } }; @@ -325,9 +325,10 @@ public: double val(); longlong val_int(); String *val_str(String *str); - bool fix_fields(THD *thd,struct st_table_list *tlist) + bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { - return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); + return (item->fix_fields(thd, tlist, &item) || + Item_func::fix_fields(thd, tlist, ref)); } void fix_length_and_dec(); void update_used_tables(); @@ -344,9 +345,10 @@ public: Item_func_make_set(Item *a,List &list) :Item_str_func(list),item(a) {} ~Item_func_make_set() { delete item; } String *val_str(String *str); - bool fix_fields(THD *thd,struct st_table_list *tlist) + bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { - return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); + return (item->fix_fields(thd, tlist, &item) || + Item_func::fix_fields(thd, tlist, ref)); } void fix_length_and_dec(); void update_used_tables(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index d8f9cf40d50..2bff2af45e4 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -75,15 +75,8 @@ void Item_subselect::make_field (Send_field *tmp_field) } } -bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables) +bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { - - if (thd->having_fix_field) - { - //TODO: subselects in having do not suported now - my_printf_error(ER_SYNTAX_ERROR, ER(ER_SYNTAX_ERROR), MYF(0)); - return 1; - } // Is it one field subselect? if (select_lex->item_list.elements > max_columns) { diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 79832116c67..3f363df33df 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -63,7 +63,7 @@ public: enum Type type() const; bool is_null() { return null_value; } void make_field (Send_field *); - bool fix_fields(THD *thd, TABLE_LIST *tables); + bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); table_map used_tables() const; friend class select_subselect; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 6ef968c33f7..809dd65d52b 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -112,7 +112,7 @@ Item_sum_int::val_str(String *str) bool -Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables) +Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { if (!thd->allow_sum_func) { @@ -124,7 +124,7 @@ Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables) maybe_null=0; for (uint i=0 ; i < arg_count ; i++) { - if (args[i]->fix_fields(thd,tables)) + if (args[i]->fix_fields(thd, tables, args + i)) return 1; if (decimals < args[i]->decimals) decimals=args[i]->decimals; @@ -140,7 +140,7 @@ Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables) bool -Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables) +Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { Item *item=args[0]; if (!thd->allow_sum_func) @@ -149,7 +149,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables) return 1; } thd->allow_sum_func=0; // No included group funcs - if (item->fix_fields(thd,tables)) + if (item->fix_fields(thd, tables, args)) return 1; hybrid_type=item->result_type(); if (hybrid_type == INT_RESULT) @@ -930,9 +930,10 @@ Item_sum_count_distinct::~Item_sum_count_distinct() } -bool Item_sum_count_distinct::fix_fields(THD *thd,TABLE_LIST *tables) +bool Item_sum_count_distinct::fix_fields(THD *thd, TABLE_LIST *tables, + Item **ref) { - if (Item_sum_num::fix_fields(thd,tables) || + if (Item_sum_num::fix_fields(thd, tables, ref) || !(tmp_table_param= new TMP_TABLE_PARAM)) return 1; return 0; diff --git a/sql/item_sum.h b/sql/item_sum.h index a963799b6a7..3e67f1e3624 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -80,7 +80,7 @@ public: Item_sum_num(Item *item_par) :Item_sum(item_par) {} Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {} Item_sum_num(List &list) :Item_sum(list) {} - bool fix_fields(THD *,struct st_table_list *); + bool fix_fields(THD *, TABLE_LIST *, Item **); longlong val_int() { return (longlong) val(); } /* Real as default */ String *val_str(String*str); void reset_field(); @@ -146,7 +146,7 @@ class Item_sum_count_distinct :public Item_sum_int { TABLE *table; table_map used_table_cache; - bool fix_fields(THD *thd,TABLE_LIST *tables); + bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); uint32 *field_lengths; TMP_TABLE_PARAM *tmp_table_param; TREE tree; @@ -283,7 +283,7 @@ class Item_sum_hybrid :public Item_sum Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par),cmp_sign(sign), used_table_cache(~(table_map) 0) {} - bool fix_fields(THD *,struct st_table_list *); + bool fix_fields(THD *, TABLE_LIST *, Item **); table_map used_tables() const { return used_table_cache; } bool const_item() const { return !used_table_cache; } @@ -382,7 +382,7 @@ public: { quick_group=0;} ~Item_udf_sum() {} const char *func_name() const { return udf.name(); } - bool fix_fields(THD *thd,struct st_table_list *tables) + bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { return udf.fix_fields(thd,tables,this,this->arg_count,this->args); } diff --git a/sql/item_uniq.h b/sql/item_uniq.h index 4be64ecc74a..e56632e7289 100644 --- a/sql/item_uniq.h +++ b/sql/item_uniq.h @@ -42,5 +42,5 @@ public: bool add() { return 0; } void reset_field() {} void update_field(int offset) {} - bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;} + bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { return 0;} }; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 92606716c63..b3ef043f582 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1874,7 +1874,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List &fields, } else { - if (item->fix_fields(thd,tables)) + if (item->fix_fields(thd, tables, it.ref())) DBUG_RETURN(-1); /* purecov: inspected */ if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM && sum_func_list) @@ -2025,7 +2025,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) if (*conds) { thd->where="where clause"; - if ((*conds)->fix_fields(thd,tables)) + if ((*conds)->fix_fields(thd, tables, conds)) DBUG_RETURN(1); } @@ -2036,7 +2036,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) { /* Make a join an a expression */ thd->where="on clause"; - if (table->on_expr->fix_fields(thd,tables)) + if (table->on_expr->fix_fields(thd, tables, &table->on_expr)) DBUG_RETURN(1); thd->cond_count++; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c8914702ae7..9922eacdec1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -81,7 +81,7 @@ static void free_var(user_var_entry *entry) THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), insert_id_used(0), in_lock_tables(0), - global_read_lock(0), bootstrap(0), having_fix_field(0) + global_read_lock(0), bootstrap(0) { host=user=priv_user=db=query=ip=0; host_or_ip="unknown ip"; diff --git a/sql/sql_class.h b/sql/sql_class.h index 9b708e35a1e..a6b7e45ab03 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -453,7 +453,6 @@ public: bool query_error, bootstrap, cleanup_done; bool safe_to_cache_query; bool volatile killed; - bool having_fix_field; //TRUE when having fix field called bool prepare_command; ulong param_count,current_param_number; Error err_list; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 4ecd5dbca36..a98012653b3 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -106,7 +106,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, } tables->table=table; - if (cond && cond->fix_fields(thd,tables)) + if (cond && cond->fix_fields(thd, tables, &cond)) return -1; if (keyname) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index bcf212f6bd2..9ae5cdeeb15 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -942,8 +942,8 @@ void st_select_lex::init_select() interval_list.empty(); use_index.empty(); ftfunc_list.empty(); - linkage=UNSPECIFIED_TYPE; - depended= 0; + linkage= UNSPECIFIED_TYPE; + depended= having_fix_field= 0; } /* diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ca824b3eab8..f4e788b67e2 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -253,7 +253,10 @@ public: uint in_sum_expr; bool create_refs, braces, /* SELECT ... UNION (SELECT ... ) <- this braces */ - depended; /* depended from outer select subselect */ + depended, /* depended from outer select subselect */ + /* TRUE when having fix field called in processing of this SELECT */ + having_fix_field; + void init_query(); void init_select(); st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d5896901935..d41aca21fb8 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -448,7 +448,7 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list, static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables, List &fields, List &values, COND *conds, ORDER *order, ORDER *group, - Item *having,thr_lock_type lock_type) + Item *having, thr_lock_type lock_type) { TABLE *table; bool hidden_group_fields; @@ -470,7 +470,7 @@ static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables, { thd->where="having clause"; thd->allow_sum_func=1; - if (having->fix_fields(thd,tables) || thd->fatal_error) + if (having->fix_fields(thd, tables, &having) || thd->fatal_error) DBUG_RETURN(1); if (having->with_sum_func) having->split_sum_func(all_fields); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 025a5c600a5..d70b7dfdbed 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -227,10 +227,9 @@ JOIN::prepare(TABLE_LIST *tables_init, { thd->where="having clause"; thd->allow_sum_func=1; - bool having_fix_field_store= thd->having_fix_field; - thd->having_fix_field= 1; - bool having_fix_rc= having->fix_fields(thd,tables_list); - thd->having_fix_field= having_fix_field_store; + select_lex->having_fix_field= 1; + bool having_fix_rc= having->fix_fields(thd, tables_list, &having); + select_lex->having_fix_field= 0; if (having_fix_rc || thd->fatal_error) DBUG_RETURN(-1); /* purecov: inspected */ if (having->with_sum_func) @@ -349,7 +348,7 @@ JOIN::optimize() } else if ((conds=new Item_cond_and(conds,having))) { - conds->fix_fields(thd, tables_list); + conds->fix_fields(thd, tables_list, &conds); conds->change_ref_to_fields(thd, tables_list); having= 0; } @@ -612,6 +611,15 @@ JOIN::reinit() if (setup_tables(tables_list)) DBUG_RETURN(1); + + // Reset of sum functions + first_record= 0; + if (sum_funcs) + { + Item_sum *func, **func_ptr= sum_funcs; + while ((func= *(func_ptr++))) + func->null_value= 1; + } DBUG_RETURN(0); } @@ -3381,7 +3389,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value) 21)))) { cond=new_cond; - cond->fix_fields(thd,0); + cond->fix_fields(thd, 0, &cond); } thd->insert_id(0); // Clear for next request } @@ -3395,7 +3403,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value) if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2)))) { cond=new_cond; - cond->fix_fields(thd,0); + cond->fix_fields(thd, 0, &cond); } } } @@ -6429,7 +6437,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List &fields, return 0; } order->in_field_list=0; - if ((*order->item)->fix_fields(thd,tables) || thd->fatal_error) + if ((*order->item)->fix_fields(thd, tables, order->item) || thd->fatal_error) return 1; // Wrong field all_fields.push_front(*order->item); // Add new field to field list order->item=(Item**) all_fields.head_ref(); @@ -6527,7 +6535,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List &fields, else { thd->where="procedure list"; - if ((*new_field->item)->fix_fields(thd,tables)) + if ((*new_field->item)->fix_fields(thd, tables, new_field->item)) DBUG_RETURN(1); /* purecov: inspected */ thd->where=0; all_fields.push_front(*new_field->item); @@ -7092,7 +7100,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) Here we pass 0 as the first argument to fix_fields that don't need to do any stack checking (This is already done in the initial fix_fields). */ - cond->fix_fields((THD *) 0,(TABLE_LIST *) 0); + cond->fix_fields((THD *) 0,(TABLE_LIST *) 0, (Item**)&cond); if (join_tab->select) { error=(int) cond->add(join_tab->select->cond); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index faa63afa6c7..f237aac81d3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2973,7 +2973,7 @@ kill: KILL_SYM expr { LEX *lex=Lex; - if ($2->fix_fields(lex->thd,0)) + if ($2->fix_fields(lex->thd, 0, &$2)) { send_error(&lex->thd->net, ER_SET_CONSTANTS_ONLY); YYABORT; @@ -3469,7 +3469,8 @@ option_value: | '@' ident_or_text equal expr { Item_func_set_user_var *item = new Item_func_set_user_var($2,$4); - if (item->fix_fields(current_thd,0) || item->update()) + if (item->fix_fields(current_thd, 0, (Item**) &item) || + item->update()) { send_error(¤t_thd->net, ER_SET_CONSTANTS_ONLY); YYABORT; @@ -3501,7 +3502,7 @@ option_value: { THD *thd=current_thd; Item *item= $3; - if (item->fix_fields(current_thd,0)) + if (item->fix_fields(current_thd, 0, &item)) { send_error(&thd->net, ER_SET_CONSTANTS_ONLY); YYABORT; -- cgit v1.2.1 From 5d2927e4a67dfc181cb4cae9fe74888676d83491 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Jul 2002 19:06:24 +0300 Subject: subselect clean up fix after automerge sql/item_strfunc.cc: fix after automerge sql/sql_lex.h: subselect clean up sql/sql_select.cc: subselect clean up --- sql/item_strfunc.cc | 2 +- sql/sql_lex.h | 4 +++- sql/sql_select.cc | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 5bb2c4015ad..1aee4e7d553 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1922,7 +1922,7 @@ bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables) if (thd && check_stack_overrun(thd,buff)) return 0; // Fatal error if flag is set! - if (args[0]->fix_fields(thd,tables)) + if (args[0]->fix_fields(thd, tables, args)) return 1; maybe_null=args[0]->maybe_null; binary=args[0]->binary; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index c3a4526e052..658c1dc2cdb 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -240,6 +240,7 @@ typedef struct st_select_lex_unit SELECT_LEX_UNIT; /* SELECT_LEX - store information of parsed SELECT_LEX statment */ +class JOIN; class st_select_lex: public st_select_lex_node { public: char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */ @@ -251,12 +252,13 @@ public: List interval_list, use_index, *use_index_ptr, ignore_index, *ignore_index_ptr; List ftfunc_list; + JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */ uint in_sum_expr; bool create_refs, braces, /* SELECT ... UNION (SELECT ... ) <- this braces */ depended, /* depended from outer select subselect */ /* TRUE when having fix field called in processing of this SELECT */ - having_fix_field; + having_fix_field;e void init_query(); void init_select(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8dd611add86..76f78009e84 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -211,6 +211,7 @@ JOIN::prepare(TABLE_LIST *tables_init, proc_param= proc_param_init; tables_list= tables_init; select_lex= select; + select->join= this; union_part= (unit->first_select()->next_select() != 0); /* Check that all tables, fields, conds and order are ok */ @@ -974,6 +975,21 @@ JOIN::cleanup(THD *thd) delete select; delete_dynamic(&keyuse); delete procedure; + for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit(); + unit != 0; + unit= unit->next_unit()) + for (SELECT_LEX *sl= unit->first_select(); + sl != 0; + sl= sl->next_select()) + { + if (sl->join) + { + int err= sl->join->cleanup(thd); + if (err) + error= err; + sl->join= 0; + } + } return error; } -- cgit v1.2.1 From ff5fadb71aced6b29d4c2466bc3813e8350103d0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Jul 2002 19:13:14 +0300 Subject: typo fixed --- sql/sql_lex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 658c1dc2cdb..7234a7a92ff 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -258,7 +258,7 @@ public: braces, /* SELECT ... UNION (SELECT ... ) <- this braces */ depended, /* depended from outer select subselect */ /* TRUE when having fix field called in processing of this SELECT */ - having_fix_field;e + having_fix_field; void init_query(); void init_select(); -- cgit v1.2.1 From 1648e47889f6c981847ab300bf6e71d08c9f0667 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Jul 2002 14:31:54 +0500 Subject: SHOW CREATE DATABASE name; Small fixes in database default charset code sql/mysql_priv.h: SHOW CREATE DATABASE name; sql/sql_db.cc: SHOW CREATE DATABASE name; sql/sql_lex.h: SHOW CREATE DATABASE name; sql/sql_parse.cc: SHOW CREATE DATABASE name; sql/sql_yacc.yy: SHOW CREATE DATABASE name; --- sql/mysql_priv.h | 1 + sql/sql_db.cc | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- sql/sql_lex.h | 1 + sql/sql_parse.cc | 19 +++++++++++- sql/sql_yacc.yy | 5 ++++ 5 files changed, 115 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2992f11ef65..c0371d1e90c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -472,6 +472,7 @@ int mysqld_show_logs(THD *thd); void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild); int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1); int mysqld_show_create(THD *thd, TABLE_LIST *table_list); +int mysqld_show_create_db(THD *thd, const char *dbname); void mysqld_list_processes(THD *thd,const char *user,bool verbose); int mysqld_show_status(THD *thd); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 63edebd4ac7..7e82e1433b9 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -106,7 +106,7 @@ static int load_db_opt(THD *thd,const char *db,HA_CREATE_INFO *create,char *fn) for( ; (le[0]=='\r' || le[0]=='\n') ; le++); if (!strcmp(ln,"default-character-set") && val && val[0]) { - thd->db_charset=get_charset_by_name(val, MYF(0)); + create->table_charset=get_charset_by_name(val, MYF(0)); } goto cnt; break; @@ -568,3 +568,92 @@ bool mysql_change_db(THD *thd,const char *name) DBUG_RETURN(0); } + + +int mysqld_show_create_db(THD *thd,const char *name) +{ + int length, db_length; + char *dbname=my_strdup((char*) name,MYF(MY_WME)); + char path[FN_REFLEN]; + uint db_access; + HA_CREATE_INFO create; + CONVERT *convert=thd->convert_set; + + DBUG_ENTER("mysql_show_create_db"); + + if (!dbname || !(db_length=strip_sp(dbname))) + { + x_free(dbname); /* purecov: inspected */ + send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ + DBUG_RETURN(1); /* purecov: inspected */ + } + + if ((db_length > NAME_LEN) || check_db_name(dbname)) + { + net_printf(&thd->net,ER_WRONG_DB_NAME, dbname); + x_free(dbname); + DBUG_RETURN(1); + } + + if (test_all_bits(thd->master_access,DB_ACLS)) + db_access=DB_ACLS; + else + db_access= (acl_get(thd->host,thd->ip,(char*) &thd->remote.sin_addr, + thd->priv_user,dbname) | + thd->master_access); + if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) + { + net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, + thd->priv_user, + thd->host_or_ip, + dbname); + mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), + thd->priv_user, + thd->host_or_ip, + dbname); + my_free(dbname,MYF(0)); + DBUG_RETURN(1); + } + + (void) sprintf(path,"%s/%s",mysql_data_home,dbname); + length=unpack_dirname(path,path); // Convert if not unix + if (length && path[length-1] == FN_LIBCHAR) + path[length-1]=0; // remove ending '\' + if (access(path,F_OK)) + { + net_printf(&thd->net,ER_BAD_DB_ERROR,dbname); + my_free(dbname,MYF(0)); + DBUG_RETURN(1); + } + + strcat(path,"/"); + unpack_dirname(path,path); + strcat(path,MY_DB_OPT_FILE); + bzero(&create,sizeof(create)); + load_db_opt(thd,name,&create,path); + + List field_list; + field_list.push_back(new Item_empty_string("Database",NAME_LEN)); + field_list.push_back(new Item_empty_string("Create Database",1024)); + + if (send_fields(thd,field_list,1)) + DBUG_RETURN(1); + + String *packet = &thd->packet; + packet->length(0); + net_store_data(packet, convert, name); + sprintf(path, "CREATE DATABASE %s", name); + if (create.table_charset) + { + strcat(path," DEFAULT CHARACTER SET "); + strcat(path,create.table_charset->name); + } + net_store_data(packet, convert, path); + + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) + DBUG_RETURN(1); + + send_eof(&thd->net); + + DBUG_RETURN(0); +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 7234a7a92ff..470230c0999 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -42,6 +42,7 @@ enum enum_sql_command { SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS, SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, + SQLCOM_SHOW_CREATE_DB, SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, SQLCOM_GRANT, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 43cb056ffc8..e006855105c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2335,7 +2335,7 @@ mysql_execute_command(void) net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); break; } - if (check_access(thd,DROP_ACL,lex->name,0,1)) + if (check_access(thd,ALTER_ACL,lex->name,0,1)) break; if (thd->locked_tables || thd->active_transaction()) { @@ -2345,6 +2345,23 @@ mysql_execute_command(void) res=mysql_alter_db(thd,lex->name,&lex->create_info,0); break; } + case SQLCOM_SHOW_CREATE_DB: + { + if (!strip_sp(lex->name) || check_db_name(lex->name)) + { + net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); + break; + } + if (check_access(thd,DROP_ACL,lex->name,0,1)) + break; + if (thd->locked_tables || thd->active_transaction()) + { + send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); + goto error; + } + res=mysqld_show_create_db(thd,lex->name); + break; + } case SQLCOM_CREATE_FUNCTION: if (check_access(thd,INSERT_ACL,"mysql",0,1)) break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e96c72ab04b..160bc253dc9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2851,6 +2851,11 @@ show_param: lex->grant_user=$3; lex->grant_user->password.str=NullS; } + | CREATE DATABASE ident + { + Lex->sql_command=SQLCOM_SHOW_CREATE_DB; + Lex->name=$3.str; + } | CREATE TABLE_SYM table_ident { Lex->sql_command = SQLCOM_SHOW_CREATE; -- cgit v1.2.1 From 7cbdd6de7eebbe76568d5de36b4457b9ffda5a84 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Jul 2002 08:15:57 +0300 Subject: cleanup --- sql/item_subselect.h | 2 +- sql/sql_lex.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 3f363df33df..88ea01f9c68 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -20,7 +20,7 @@ #pragma interface /* gcc class implementation */ #endif -struct st_select_lex; +class st_select_lex; class JOIN; class select_subselect; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 470230c0999..af80b175cd3 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -236,7 +236,7 @@ private: bool create_total_list_n_last_return(THD *thd, st_lex *lex, TABLE_LIST ***result); }; -typedef struct st_select_lex_unit SELECT_LEX_UNIT; +typedef class st_select_lex_unit SELECT_LEX_UNIT; /* SELECT_LEX - store information of parsed SELECT_LEX statment @@ -284,7 +284,7 @@ public: friend void mysql_init_query(THD *thd); }; -typedef struct st_select_lex SELECT_LEX; +typedef class st_select_lex SELECT_LEX; class Set_option :public Sql_alloc { public: -- cgit v1.2.1 From 2ed3a33855c1cc652c9d0ed3bf8de1636d5c61ce Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 20 Jul 2002 16:36:56 +0200 Subject: CREATE ... SELECT extension (WL 317) BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/mysql_priv.h | 10 +++++++--- sql/sql_parse.cc | 2 +- sql/sql_table.cc | 45 ++++++++++++++++++++++++++++++++------------- 3 files changed, 40 insertions(+), 17 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c0371d1e90c..9fff4880573 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -382,9 +382,13 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, int mysql_create_table(THD *thd,const char *db, const char *table_name, HA_CREATE_INFO *create_info, List &fields, List &keys, - bool tmp_table, bool no_log); -// no_log is needed for the case of CREATE TABLE ... SELECT , as the logging -// will be done later in sql_insert.cc + bool tmp_table, bool no_log, uint select_field_count); +/* + no_log is needed for the case of CREATE ... SELECT, + as the logging will be done later in sql_insert.cc + select_field_count is also used for CREATE ... SELECT, + and must be zero for standart create of table +*/ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, const char *db, const char *name, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e006855105c..fef022ff513 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1598,7 +1598,7 @@ mysql_execute_command(void) res = mysql_create_table(thd,tables->db ? tables->db : thd->db, tables->real_name, &lex->create_info, lex->create_list, - lex->key_list,0, 0); // do logging + lex->key_list,0,0,0); // do logging if (!res) send_ok(&thd->net); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d8012c0c102..3652b2512f4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -70,7 +70,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) } error=mysql_rm_table_part2(thd,tables,if_exists,0); - err: + err: VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh pthread_mutex_unlock(&LOCK_open); @@ -209,7 +209,6 @@ int quick_rm_table(enum db_type base,const char *db, PRIMARY keys are prioritized. */ - static int sort_keys(KEY *a, KEY *b) { if (a->flags & HA_NOSAME) @@ -251,7 +250,8 @@ static int sort_keys(KEY *a, KEY *b) int mysql_create_table(THD *thd,const char *db, const char *table_name, HA_CREATE_INFO *create_info, List &fields, - List &keys,bool tmp_table,bool no_log) + List &keys,bool tmp_table,bool no_log, + uint select_field_count) { char path[FN_REFLEN]; const char *key_name; @@ -259,10 +259,11 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, int error= -1; uint db_options,field,null_fields,blob_columns; ulong pos; - KEY *key_info,*key_info_buffer; + KEY *key_info,*key_info_buffer; KEY_PART_INFO *key_part_info; int auto_increment=0; handler *file; + int field_no,dup_no; DBUG_ENTER("mysql_create_table"); /* @@ -275,6 +276,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } List_iterator it(fields),it2(fields); + int select_field_pos=fields.elements - select_field_count; null_fields=blob_columns=0; db_options=create_info->table_options; if (create_info->row_type == ROW_TYPE_DYNAMIC) @@ -288,10 +290,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } - /* Don't pack keys in old tables if the user has requested this */ - while ((sql_field=it++)) + for(field_no=0; (sql_field=it++) ; field_no++) { + /* Don't pack keys in old tables if the user has requested this */ if ((sql_field->flags & BLOB_FLAG) || sql_field->sql_type == FIELD_TYPE_VAR_STRING && create_info->row_type != ROW_TYPE_FIXED) @@ -300,14 +302,29 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } if (!(sql_field->flags & NOT_NULL_FLAG)) null_fields++; - while ((dup_field=it2++) != sql_field) + for(dup_no=0; (dup_field=it2++) != sql_field; dup_no++) { - if (my_strcasecmp(system_charset_info, - sql_field->field_name, + if (my_strcasecmp(system_charset_info, + sql_field->field_name, dup_field->field_name) == 0) { - my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name); - DBUG_RETURN(-1); + if (field_no=select_field_pos) + { + my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name); + DBUG_RETURN(-1); + } + else + { + sql_field->length=dup_field->length; + sql_field->decimals=dup_field->decimals; + sql_field->flags=dup_field->flags; + sql_field->pack_length=dup_field->pack_length; + sql_field->unireg_check=dup_field->unireg_check; + sql_field->sql_type=dup_field->sql_type; + it2.remove(); + select_field_pos--; + break; + } } } it2.rewind(); @@ -793,6 +810,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, TABLE tmp_table; // Used during 'create_field()' TABLE *table; tmp_table.table_name=0; + uint select_field_count=0; DBUG_ENTER("create_table_from_items"); /* Add selected items to field list */ @@ -826,11 +844,12 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, (Field*) 0)))) DBUG_RETURN(0); extra_fields->push_back(cr_field); + select_field_count++; } /* create and lock table */ /* QQ: This should be done atomic ! */ if (mysql_create_table(thd,db,name,create_info,*extra_fields, - *keys,0,1)) // no logging + *keys,0,1,select_field_count)) // no logging DBUG_RETURN(0); if (!(table=open_table(thd,db,name,name,(bool*) 0))) { @@ -1719,7 +1738,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if ((error=mysql_create_table(thd, new_db, tmp_name, create_info, - create_list,key_list,1,1))) // no logging + create_list,key_list,1,1,0))) // no logging DBUG_RETURN(error); if (table->tmp_table) -- cgit v1.2.1 From fcaf867bb93d188397cb4788b6204283a8af39d3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 30 Jul 2002 14:02:29 +0500 Subject: Renamed some charset related constant New fields in CHARSET_INFO for more nice SHOW CHARACTER SET Dynamic charsets are now handled in faster way SHOW CHARACTER SET now displays not only compiled charsets but dynamic charsets too include/m_ctype.h: Renamed constant New fields in CHARSET_INFO include/my_sys.h: Constant have been moved to m_ctype.h libmysqld/lib_sql.cc: Renamed constant mysys/charset.c: Dynamic charsets are now handled in new way to speedup things mysys/test_charset.c: Renamed constant sql/mysqld.cc: Renamed constant sql/sql_show.cc: SHOW CHARACTER SET now displays not only compiled charsets but dynamic charsets too strings/ctype.c: New fields in CHARSET_INFO --- sql/mysqld.cc | 2 +- sql/sql_show.cc | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 98bfa162242..59630644e5a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1840,7 +1840,7 @@ int main(int argc, char **argv) if (set_default_charset_by_name(default_charset, MYF(MY_WME))) exit( 1 ); - charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS)); + charsets_list = list_charsets(MYF(MY_CS_COMPILED|MY_CS_CONFIG)); #ifdef HAVE_OPENSSL if (opt_use_ssl) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 494607c7fff..e227a5bf5ca 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1381,8 +1381,10 @@ int mysqld_show_charsets(THD *thd, const char *wild) if (send_fields(thd,field_list,1)) DBUG_RETURN(1); - for (cs=compiled_charsets ; cs->name ; cs++ ) + for (cs=all_charsets ; cs < all_charsets+255 ; cs++ ) { + if (!cs->name) + continue; if (!(wild && wild[0] && wild_case_compare(system_charset_info,cs->name,wild))) { packet2.length(0); -- cgit v1.2.1 From f0f5a892039cb1155608c8c84854b20e93112dc4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 31 Jul 2002 01:26:51 +0300 Subject: fixed bug reported by Walrus & Miguel in exists subselect mysql-test/r/subselect.result: added test suite of EXISTS clause mysql-test/t/subselect.test: added test suite of EXISTS clause sql/item_subselect.cc: added checking out of memory fixed bug in exists subselect --- sql/item_subselect.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 2bff2af45e4..b0a94f0b8e6 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -51,6 +51,12 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex, if (unit->select_limit_cnt == HA_POS_ERROR) select_lex->options&= ~OPTION_FOUND_ROWS; join= new JOIN(thd, select_lex->item_list, select_lex->options, result); + if (!join || !result) + { + //out of memory + thd->fatal_error= 1; + my_printf_error(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); + } this->select_lex= select_lex; assign_null(); /* @@ -172,7 +178,7 @@ String *Item_singleval_subselect::val_str (String *str) Item_exists_subselect::Item_exists_subselect(THD *thd, st_select_lex *select_lex): - Item_subselect(thd, select_lex, new select_singleval_subselect(this)) + Item_subselect(thd, select_lex, new select_exists_subselect(this)) { max_columns= UINT_MAX; null_value= 0; //can't be NULL -- cgit v1.2.1 From 5d61c21aa9716544df6fce044ec27d8ce771c9d9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 31 Jul 2002 13:25:37 +0500 Subject: Some more speedup in charsets handling sql/init.cc: This code is moved to more proper place in mysys/charset.c --- sql/init.cc | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'sql') diff --git a/sql/init.cc b/sql/init.cc index ac0ff701649..052ee16925e 100644 --- a/sql/init.cc +++ b/sql/init.cc @@ -53,23 +53,6 @@ void unireg_init(ulong options) } specialflag|=options; /* Set options from argv */ - // The following is needed because of like optimization in select.cc - - for (cs=compiled_charsets; cs->number; cs++) - { - uchar max_char; - if (!cs->sort_order) - continue; - max_char=cs->sort_order[(uchar) cs->max_sort_char]; - for (i = 0; i < 256; i++) - { - if ((uchar) cs->sort_order[i] > max_char) - { - max_char=(uchar) cs->sort_order[i]; - cs->max_sort_char= (char) i; - } - } - } thread_stack_min=thread_stack - STACK_MIN_SIZE; DBUG_VOID_RETURN; } -- cgit v1.2.1 From 700cefd28bb970afb004745af71098034fa37038 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 6 Aug 2002 13:59:07 +0200 Subject: - Added missing files to distribution - removoved getopt.h (has been replaced by my_getopt.h) BitKeeper/deleted/.del-getopt.h~a9ae679fa84f395: Delete: include/getopt.h include/Makefile.am: - Added missing file my_getopt.h to distribution sql/Makefile.am: - Added missing files spatial.h adn gstream.h to distribution --- sql/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index 81fe927ce5a..9cfdf4c4d9b 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -56,7 +56,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ sql_select.h structs.h table.h sql_udf.h hash_filo.h\ lex.h lex_symbol.h sql_acl.h sql_crypt.h \ log_event.h mini_client.h sql_repl.h slave.h \ - stacktrace.h sql_sort.h sql_cache.h + stacktrace.h sql_sort.h sql_cache.h spatial.h gstream.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ -- cgit v1.2.1 From 01a8a45f1eb70cbada195ab3c838137294b636fb Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 6 Aug 2002 19:29:33 +0500 Subject: New CRC32() SQL function --- sql/item_create.cc | 5 +++++ sql/item_create.h | 1 + sql/item_func.cc | 13 +++++++++++++ sql/item_func.h | 10 ++++++++++ sql/lex.h | 1 + 5 files changed, 30 insertions(+) (limited to 'sql') diff --git a/sql/item_create.cc b/sql/item_create.cc index 9204d23b8c2..a41ba1cc526 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -86,6 +86,11 @@ Item *create_func_cot(Item* a) new Item_func_tan(a)); } +Item *create_func_crc32(Item* a) +{ + return new Item_func_crc32(a); +} + Item *create_func_date_format(Item* a,Item *b) { return new Item_func_date_format(a,b,0); diff --git a/sql/item_create.h b/sql/item_create.h index 6f7e8ebf89a..fd9a856f283 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -29,6 +29,7 @@ Item *create_func_connection_id(void); Item *create_func_conv(Item* a, Item *b, Item *c); Item *create_func_cos(Item* a); Item *create_func_cot(Item* a); +Item *create_func_crc32(Item* a); Item *create_func_date_format(Item* a,Item *b); Item *create_func_dayname(Item* a); Item *create_func_dayofmonth(Item* a); diff --git a/sql/item_func.cc b/sql/item_func.cc index ae3fc7cb8f0..8728187718c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include "slave.h" // for wait_for_master_pos #include "gstream.h" @@ -801,6 +802,18 @@ longlong Item_func_min_max::val_int() return value; } +longlong Item_func_crc32::val_int() +{ + String *res=args[0]->val_str(&value); + if (!res) + { + null_value=1; + return 0; /* purecov: inspected */ + } + null_value=0; + return (longlong) crc32(0L, (Bytef*)res->ptr(), res->length()); +} + longlong Item_func_length::val_int() { diff --git a/sql/item_func.h b/sql/item_func.h index 86b2a17931d..2e61ed87c3c 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -518,6 +518,16 @@ public: const char *func_name() const { return "greatest"; } }; +class Item_func_crc32 :public Item_int_func +{ + String value; +public: + Item_func_crc32(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "crc32"; } + void fix_length_and_dec() { max_length=10; } +}; + class Item_func_length :public Item_int_func { diff --git a/sql/lex.h b/sql/lex.h index 4af36df58af..c41ad8c1d44 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -430,6 +430,7 @@ static SYMBOL sql_functions[] = { { "COUNT", SYM(COUNT_SYM),0,0}, { "COS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)}, { "COT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)}, + { "CRC32", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_crc32)}, { "CROSSES", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_crosses)}, { "CURDATE", SYM(CURDATE),0,0}, { "CURTIME", SYM(CURTIME),0,0}, -- cgit v1.2.1 From 6cc0d7d7e8d8321ecd2d918cb0e3160eb0322ecd Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 15 Aug 2002 14:43:05 +0500 Subject: New character sets sql/share/charsets/Index: New charsets --- sql/share/charsets/Index | 7 +++ sql/share/charsets/cp866.conf | 91 ++++++++++++++++++++++++++++++++++++++ sql/share/charsets/keybcs2.conf | 91 ++++++++++++++++++++++++++++++++++++++ sql/share/charsets/latvian.conf | 95 ++++++++++++++++++++++++++++++++++++++++ sql/share/charsets/latvian1.conf | 94 +++++++++++++++++++++++++++++++++++++++ sql/share/charsets/macce.conf | 91 ++++++++++++++++++++++++++++++++++++++ sql/share/charsets/macroman.conf | 91 ++++++++++++++++++++++++++++++++++++++ sql/share/charsets/pclatin2.conf | 91 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 651 insertions(+) create mode 100644 sql/share/charsets/cp866.conf create mode 100644 sql/share/charsets/keybcs2.conf create mode 100644 sql/share/charsets/latvian.conf create mode 100644 sql/share/charsets/latvian1.conf create mode 100644 sql/share/charsets/macce.conf create mode 100644 sql/share/charsets/macroman.conf create mode 100644 sql/share/charsets/pclatin2.conf (limited to 'sql') diff --git a/sql/share/charsets/Index b/sql/share/charsets/Index index 52cb6b99705..c8ae877887e 100644 --- a/sql/share/charsets/Index +++ b/sql/share/charsets/Index @@ -40,3 +40,10 @@ armscii8 32 utf8 33 win1250ch 34 ucs2 35 +cp866 36 +keybcs2 37 +macce 38 +macroman 39 +pclatin2 40 +latvian 41 +latvian1 42 diff --git a/sql/share/charsets/cp866.conf b/sql/share/charsets/cp866.conf new file mode 100644 index 00000000000..e6b5c064fd7 --- /dev/null +++ b/sql/share/charsets/cp866.conf @@ -0,0 +1,91 @@ +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 01 02 01 02 01 02 01 02 00 00 00 00 00 00 00 48 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + A0 A1 A2 A3 A4 A5 86 87 88 89 AA AB AC AD AE AF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + A0 A1 A2 A3 A4 A5 86 87 88 89 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F1 F1 F3 F3 F5 F5 F7 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + F0 F0 F2 F2 F4 F4 F6 F6 F8 F9 FA FB FC FD FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 56 57 58 59 5A 5B 5C 5E 5F 62 + 67 68 69 6C 71 74 75 76 77 78 7B B0 B1 B2 B3 B4 + B5 41 42 43 44 45 56 57 58 59 5A 5B 5C 5E 5F 62 + 67 68 69 6C 71 74 75 76 77 78 7B B6 B7 B8 B9 BA + 80 81 82 83 84 85 88 89 8A 8C 8D 8E 8F 90 91 92 + 93 94 95 96 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 + 80 81 82 83 84 85 88 89 8A 8C 8D 8E 8F 90 91 92 + BB BD BE C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC + CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD + DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 F3 F4 F5 F6 F7 + 93 94 95 96 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 + 86 86 87 87 8B 8B 97 97 F8 F9 FA FB FC FD FE FF + +# Unicode mappping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F + 0420 0421 0422 0423 0424 0425 0426 0427 0428 0429 042A 042B 042C 042D 042E 042F + 0430 0431 0432 0433 0434 0435 0436 0437 0438 0439 043A 043B 043C 043D 043E 043F + 2591 2592 2593 2502 2524 2561 2562 2556 2555 2563 2551 2557 255D 255C 255B 2510 + 2514 2534 252C 251C 2500 253C 255E 255F 255A 2554 2569 2566 2560 2550 256C 2567 + 2568 2564 2565 2559 2558 2552 2553 256B 256A 2518 250C 2588 2584 258C 2590 2580 + 0440 0441 0442 0443 0444 0445 0446 0447 0448 0449 044A 044B 044C 044D 044E 044F + 0401 0451 0404 0454 0407 0457 040E 045E 00B0 2219 00B7 221A 207F 00B2 25A0 00A0 + diff --git a/sql/share/charsets/keybcs2.conf b/sql/share/charsets/keybcs2.conf new file mode 100644 index 00000000000..f272960b683 --- /dev/null +++ b/sql/share/charsets/keybcs2.conf @@ -0,0 +1,91 @@ +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 02 82 02 02 01 01 02 82 81 01 01 02 02 01 01 + 81 02 01 02 02 01 02 01 02 01 01 01 01 01 01 02 + 02 02 02 02 02 01 01 01 02 02 02 01 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 02 02 01 02 01 02 00 02 01 01 01 02 00 02 02 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 87 81 82 83 84 83 86 87 88 88 8D A1 8C 8D 84 A0 + 82 91 91 93 94 A2 96 A3 98 94 81 9B 8C 98 A9 9F + A0 A1 A2 A3 A4 A4 96 93 9B A9 AA AA AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 ED E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 68 59 5A 7B 7C 7D 7E 7F + 87 9A 90 85 8E 85 86 80 89 89 8A 8B 9C 8A 8E 8F + 90 92 92 A7 99 95 A6 97 9D 99 9A A8 9C 9D 9E 9F + 8F 8B 95 97 A5 A5 A6 A7 A8 9E AB AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC E8 EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 44 45 47 49 50 51 52 53 54 55 56 57 58 5A + 5E 5F 60 63 66 68 6C 6D 6E 6F 72 90 91 92 93 94 + 95 41 44 45 47 49 50 51 52 53 54 55 56 57 58 5A + 5E 5F 60 63 66 68 6C 6D 6E 6F 72 96 97 98 99 9A + 45 68 49 47 41 47 66 45 49 49 56 53 56 56 41 41 + 49 72 72 5A 5A 5A 68 68 6F 5A 68 63 56 6F 60 66 + 41 53 5A 68 58 58 68 5A 63 60 60 60 A0 A1 A2 A3 + A4 A5 A6 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC + BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC + CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC + 80 65 83 87 88 89 DD 8A 85 8B 84 81 DE 85 82 DF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mappping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 010C 00FC 00E9 010F 00E4 010E 0164 010D 011B 011A 0139 00CD 013E 013A 00C4 00C1 + 00C9 017E 017D 00F4 00F6 00D3 016F 00DA 00FD 00D6 00DC 0160 013D 00DD 0158 0165 + 00E1 00ED 00F3 00FA 0148 0147 016E 00D4 0161 0159 0155 0154 00BC 00A1 00AB 00BB + 2591 2592 2593 2502 2524 2561 2562 2556 2555 2563 2551 2557 255D 255C 255B 2510 + 2514 2534 252C 251C 2500 253C 255E 255F 255A 2554 2569 2566 2560 2550 256C 2567 + 2568 2564 2565 2559 2558 2552 2553 256B 256A 2518 250C 2588 2584 258C 2590 2580 + 03B1 00DF 0393 03C0 03A3 03C3 00B5 03C4 03A6 0398 03A9 03B4 221E 03C6 03B5 2229 + 2261 00B1 2265 2264 2320 2321 00F7 2248 00B0 2219 00B7 221A 207F 00B2 25A0 00A0 + diff --git a/sql/share/charsets/latvian.conf b/sql/share/charsets/latvian.conf new file mode 100644 index 00000000000..c3dee95d55c --- /dev/null +++ b/sql/share/charsets/latvian.conf @@ -0,0 +1,95 @@ +# Configuration file for the latvian character set. +# Created for case-sensitive record search +# Created accord with windows-1257 (iso-8859-4) codepage +# Created by Andis Grasis & Rihards Grasis e-mail:andis@cata.lv + +# The ctype array must have 257 elements. + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20 + 01 20 10 20 10 10 00 00 20 10 20 10 20 10 10 10 + 20 10 10 10 10 10 10 10 20 00 20 10 20 10 10 20 + 48 20 10 10 10 20 10 10 10 10 01 10 10 10 10 01 + 10 10 10 10 10 10 10 10 10 10 02 10 10 10 10 02 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 10 + +# The to_lower array must have 256 elements. + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 B8 A9 BA AB AC AD AE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# The to_upper array must have 256 elements. + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 A8 B9 AA BB BC BD BE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF + +# The sort_order array must have 256 elements. + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 30 32 33 34 35 36 37 2B 38 39 3A 5C 3B 2C 3C 3D + 76 7A 7C 7E 80 81 82 83 84 85 3E 3F 5D 5E 5F 40 + 41 86 92 94 9A 9C A6 A8 AC AE B4 B6 BA C0 C2 C8 + D4 D6 D8 DC E3 E6 EE F0 F2 F4 F6 42 43 44 45 46 + 47 87 93 95 9B 9D A7 A9 AD AF B5 B7 BB C1 C3 C9 + D5 D7 D9 DD E4 E7 EF F1 F3 F5 F7 48 49 4A 4B 20 + 75 21 56 22 59 73 70 71 23 74 24 5A 25 4D 51 50 + 26 54 55 57 58 72 2E 2F 27 E5 28 5B 29 4E 53 2A + 31 FE 65 66 67 FF 4C 68 D3 69 DA 61 6A 2D 6B 90 + 6C 60 7D 7F 4F 6D 6E 6F D2 7B DB 62 77 78 79 91 + 8E B2 8A 96 88 8C A4 A2 98 9E F8 A0 AA B8 B0 BE + E1 C4 C6 CA CE D0 CC 63 EC BC DE EA E8 FA FC E0 + 8F B3 8B 97 89 8D A5 A3 99 9F F9 A1 AB B9 B1 BF + E2 C5 C7 CB CF D1 CD 64 ED BD DF EB E9 FB FD 52 + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 201D 00A2 00A3 00A4 201E 00A6 00A7 00D8 00A9 0156 00AB 00AC 00AD 00AE 00C6 +00B0 00B1 00B2 00B3 201C 00B5 00B6 00B7 00F8 00B9 0157 00BB 00BC 00BD 00BE 00E6 +0104 012E 0100 0106 00C4 00C5 0118 0112 010C 00C9 0179 0116 0122 0136 012A 013B +0160 0143 0145 00D3 014C 00D5 00D6 00D7 0172 0141 015A 016A 00DC 017B 017D 00DF +0105 012F 0101 0107 00E4 00E5 0119 0113 010D 00E9 017A 0117 0123 0137 012B 013C +0161 0144 0146 00F3 014D 00F5 00F6 00F7 0173 0142 015B 016B 00FC 017C 017E 2019 diff --git a/sql/share/charsets/latvian1.conf b/sql/share/charsets/latvian1.conf new file mode 100644 index 00000000000..3094525052d --- /dev/null +++ b/sql/share/charsets/latvian1.conf @@ -0,0 +1,94 @@ +# Configuration file for the latvian character set. +# Created for case-insensitive record search +# Created by Andis & Rihards + +# The ctype array must have 257 elements. + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20 + 00 00 10 00 10 10 00 00 00 00 00 10 00 10 10 10 + 00 10 10 10 10 10 10 10 00 00 00 10 00 10 10 00 + 48 00 10 10 10 00 10 10 10 10 01 10 10 10 10 10 + 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 10 + +# The to_lower array must have 256 elements. + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 B8 A9 BA AB AC AD AE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# The to_upper array must have 256 elements. + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 A8 B9 AA BB BC BD BE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF + +# The sort_order array must have 256 elements. + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 30 32 33 34 35 36 37 2B 38 39 3A 5C 3B 2C 3C 3D + 76 7A 7C 7E 80 81 82 83 84 85 3E 3F 5D 5E 5F 40 + 41 86 92 94 9A 9C A6 A8 AC AE B4 B6 BA C0 C2 C8 + D4 D6 D8 DC E3 E6 EE F0 F2 F4 F6 42 43 44 45 46 + 47 86 92 94 9A 9C A6 A8 AC AE B4 B6 BA C0 C2 C8 + D4 D6 D8 DC E2 E6 EE F0 F2 F4 F6 48 49 4A 4B 20 + 75 21 56 22 59 73 70 71 23 74 24 5A 25 4D 51 50 + 26 54 55 57 58 72 2E 2F 27 E5 28 5B 29 4E 53 2A + 31 FE 65 66 67 FF 4C 68 2D 69 DA 61 6A 2D 6B 90 + 6C 60 7D 7F 4F 6D 6E 6F D3 7B DB 62 77 78 79 90 + 8E B2 8A 96 88 8C A4 A2 98 9E F8 A0 AA B8 B0 BE + E1 C4 C6 CA CE D0 CC 63 EC BC DE EA E8 FA FC E0 + 8E B2 8A 96 88 8C A4 A2 98 9E F8 A0 AA B8 B0 BE + E1 C4 C6 CA CE D0 CC 64 EC BC DE EA E8 FA FC 52 + +# Unicode mapping (256 elements) +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F +0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F +00A0 201D 00A2 00A3 00A4 201E 00A6 00A7 00D8 00A9 0156 00AB 00AC 00AD 00AE 00C6 +00B0 00B1 00B2 00B3 201C 00B5 00B6 00B7 00F8 00B9 0157 00BB 00BC 00BD 00BE 00E6 +0104 012E 0100 0106 00C4 00C5 0118 0112 010C 00C9 0179 0116 0122 0136 012A 013B +0160 0143 0145 00D3 014C 00D5 00D6 00D7 0172 0141 015A 016A 00DC 017B 017D 00DF +0105 012F 0101 0107 00E4 00E5 0119 0113 010D 00E9 017A 0117 0123 0137 012B 013C +0161 0144 0146 00F3 014D 00F5 00F6 00F7 0173 0142 015B 016B 00FC 017C 017E 2019 diff --git a/sql/share/charsets/macce.conf b/sql/share/charsets/macce.conf new file mode 100644 index 00000000000..f3ac08df087 --- /dev/null +++ b/sql/share/charsets/macce.conf @@ -0,0 +1,91 @@ +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 01 02 01 01 01 01 02 02 01 02 02 01 02 02 01 + 02 01 02 02 01 02 01 02 02 02 02 02 02 01 02 02 + 00 00 01 00 00 00 00 02 00 00 00 02 00 00 02 01 + 02 01 00 00 02 01 00 00 02 01 02 01 02 01 02 01 + 02 01 00 00 02 01 00 00 00 00 00 02 01 01 02 01 + 00 00 00 00 00 00 00 00 02 01 02 01 00 00 02 01 + 02 01 00 00 02 01 02 01 01 02 01 01 02 01 01 01 + 02 01 01 02 01 02 01 02 01 02 02 01 01 02 01 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 8A 82 82 8E 88 9A 9F 87 88 8B 8A 8B 8D 8D 8E 90 + 90 93 92 93 95 95 98 97 98 99 9A 9B 9C 9E 9E 9F + A0 A1 AB A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE B0 + B0 B4 B2 B3 B4 FA B6 B7 B8 BA BA BC BC BE BE C0 + C0 C4 C2 C3 C4 CB C6 C7 C8 C9 CA CB CE 9B CE D8 + D0 D1 D2 D3 D4 D5 D6 D7 D8 DA DA DE DC DD DE E0 + E0 E4 E2 E3 E4 E6 E6 87 E9 E9 92 EC EC F0 97 99 + F0 F3 9C F3 F5 F5 F7 F7 F9 F9 FA FD B8 FD AE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 81 83 84 85 86 E7 84 89 80 89 8C 8C 83 8F + 8F 91 EA 91 94 94 96 EE 96 EF 85 CD F2 9D 9D 86 + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA A2 AC AD FE AF + AF B1 B2 B3 B1 B5 B6 B7 FC B9 B9 BB BB BD BD BF + BF C1 C2 C3 C1 C5 C6 C7 C8 C9 CA C5 CC CD CC CF + D0 D1 D2 D3 D4 D5 D6 D7 CF D9 D9 DB DC DD DB DF + DF E1 E2 E3 E1 E5 E5 E7 E8 E8 EA EB EB ED EE EF + ED F1 F2 F1 F4 F4 F6 F6 F8 F8 B5 FB FC FB FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 46 47 4A 4C 52 53 55 56 5A 5B 5D 62 62 67 + 6F 70 71 75 79 81 88 89 8A 8B 8D 90 91 92 93 94 + 95 41 46 47 4A 4C 52 53 55 56 5A 5B 5D 62 62 67 + 6F 70 71 75 79 81 88 89 8A 8B 8D 96 97 98 99 9A + 41 41 41 4C 41 67 81 41 41 47 41 47 47 47 4C 8D + 8D 4A 56 4A 4C 4C 4C 67 4C 67 67 67 81 4C 4C 81 + A0 A1 4C A3 A4 A5 A6 75 A8 A9 AA 4C AC AD 53 56 + 56 56 B2 B3 56 5B B6 B7 5D 5D 5D 5D 5D 5D 5D 62 + 62 62 C2 C3 62 62 C6 C7 C8 C9 CA 62 67 67 67 67 + D0 D1 D2 D3 D4 D5 D6 D7 67 71 71 71 DC DD 71 71 + 71 75 E2 E3 75 75 75 41 79 79 56 8D 8D 81 67 67 + 81 81 81 81 81 81 81 81 8B 8B 5B 8D 5D 8D 53 FF + +# Unicode mappping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C4 0100 0101 00C9 0104 00D6 00DC 00E1 0105 010C 00E4 010D 0106 0107 00E9 0179 + 017A 010E 00ED 010F 0112 0113 0116 00F3 0117 00F4 00F6 00F5 00FA 011A 011B 00FC + 2020 00B0 0118 00A3 00A7 2022 00B6 00DF 00AE 00A9 2122 0119 00A8 2260 0123 012E + 012F 012A 2264 2265 012B 0136 2202 2211 0142 013B 013C 013D 013E 0139 013A 0145 + 0146 0143 00AC 221A 0144 0147 2206 00AB 00BB 2026 00A0 0148 0150 00D5 0151 014C + 2013 2014 201C 201D 2018 2019 00F7 25CA 014D 0154 0155 0158 2039 203A 0159 0156 + 0157 0160 201A 201E 0161 015A 015B 00C1 0164 0165 00CD 017D 017E 016A 00D3 00D4 + 016B 016E 00DA 016F 0170 0171 0172 0173 00DD 00FD 0137 017B 0141 017C 0122 02C7 + diff --git a/sql/share/charsets/macroman.conf b/sql/share/charsets/macroman.conf new file mode 100644 index 00000000000..11cbee40e94 --- /dev/null +++ b/sql/share/charsets/macroman.conf @@ -0,0 +1,91 @@ +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 10 + 20 01 01 01 01 01 01 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 00 00 00 00 00 00 00 02 00 00 00 00 00 00 01 01 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 02 + 00 00 00 00 02 00 00 00 00 00 00 20 01 01 00 00 + 00 00 00 00 00 00 00 00 02 01 00 00 00 00 00 00 + 00 00 00 00 00 20 01 01 01 01 01 01 01 01 01 01 + 00 01 01 01 01 02 00 00 00 00 00 00 00 00 00 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 8A 8C 8D 8E 96 9A 9F 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD BE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA 88 8B 9B CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D8 DA DB DC DD DE DF + E0 E1 E2 E3 E4 89 90 87 91 8F 92 94 95 93 97 99 + F0 98 9C 9E 9D F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 E7 CB E5 80 CC 81 82 83 E9 + E6 E8 EA ED EB EC 84 EE F1 EF 85 CD F2 F4 F3 86 + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD AE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D9 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 49 50 52 53 57 59 60 61 67 68 69 70 71 72 + 79 80 81 82 84 85 90 91 92 93 95 A0 A1 A2 A3 A4 + A5 41 49 50 52 53 57 59 60 61 67 68 69 70 71 72 + 79 80 81 82 84 85 90 91 92 93 95 A6 A7 A8 A9 AA + 41 41 50 53 71 72 85 41 41 41 41 41 41 50 53 53 + 53 53 61 61 61 61 71 72 72 72 72 72 85 85 85 85 + AB AC AD AE AF B0 B1 82 B2 B3 B4 B5 B6 B7 48 72 + B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 48 72 + C6 C7 C8 C9 57 CA CB CC CD CE CF 41 41 72 D0 D1 + D2 D3 D4 D5 D6 D7 D8 D9 93 93 DA DB DC DD DE DF + E0 E1 E2 E3 E4 41 53 41 53 53 61 61 61 61 72 72 + F0 72 85 85 85 61 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mappping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C4 00C5 00C7 00C9 00D1 00D6 00DC 00E1 00E0 00E2 00E4 00E3 00E5 00E7 00E9 00E8 + 00EA 00EB 00ED 00EC 00EE 00EF 00F1 00F3 00F2 00F4 00F6 00F5 00FA 00F9 00FB 00FC + 2020 00B0 00A2 00A3 00A7 2022 00B6 00DF 00AE 00A9 2122 00B4 00A8 2260 00C6 00D8 + 221E 00B1 2264 2265 00A5 00B5 2202 2211 220F 03C0 222B 00AA 00BA 03A9 00E6 00F8 + 00BF 00A1 00AC 221A 0192 2248 2206 00AB 00BB 2026 00A0 00C0 00C3 00D5 0152 0153 + 2013 2014 201C 201D 2018 2019 00F7 25CA 00FF 0178 2044 20AC 2039 203A FB01 FB02 + 2021 00B7 201A 201E 2030 00C2 00CA 00C1 00CB 00C8 00CD 00CE 00CF 00CC 00D3 00D4 + F8FF 00D2 00DA 00DB 00D9 0131 02C6 02DC 00AF 02D8 02D9 02DA 00B8 02DD 02DB 02C7 + diff --git a/sql/share/charsets/pclatin2.conf b/sql/share/charsets/pclatin2.conf new file mode 100644 index 00000000000..dea8d085595 --- /dev/null +++ b/sql/share/charsets/pclatin2.conf @@ -0,0 +1,91 @@ +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 02 02 02 02 02 02 02 02 02 01 02 02 01 01 01 + 01 01 02 02 02 01 02 01 02 01 01 01 02 01 00 02 + 02 02 02 02 01 02 01 02 01 02 00 02 01 01 00 00 + 00 00 00 00 00 01 01 01 02 00 00 00 00 01 02 00 + 00 00 00 00 00 00 01 02 00 00 00 00 00 00 00 00 + 02 01 01 01 02 01 01 01 02 00 00 00 00 01 01 00 + 01 02 01 01 02 02 01 02 01 01 02 01 02 01 02 00 + 00 00 00 00 00 00 00 00 00 00 00 02 01 02 00 48 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 87 81 82 83 84 85 86 87 88 89 8B 8B 8C AB 84 86 + 82 92 92 93 94 96 96 98 98 94 81 9C 9C 88 9E 9F + A0 A1 A2 A3 A5 A5 A7 A7 A9 A9 AA AB 9F B8 AE AF + B0 B1 B2 B3 B4 A0 83 D8 B8 B9 BA BB BC BE BE BF + C0 C1 C2 C3 C4 C5 C7 C7 C8 C9 CA CB CC CD CE CF + D0 D0 D4 89 D4 E5 A1 8C D8 D9 DA DB DC EE 85 DF + A2 E1 93 E4 E4 E5 E7 E7 EA A3 E8 FB EC EC EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 9A 90 B6 8E DE 8F 80 9D D3 8A 8A D7 8D 8E 8F + 90 91 91 E2 99 95 95 97 97 99 9A 9B 9B 9D 9E AC + B5 D6 E0 E9 A4 A4 A6 A6 A8 A8 AA 8D AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 AD B9 BA BB BC BE BD BF + C0 C1 C2 C3 C4 C5 C6 C6 C8 C9 CA CB CC CD CE CF + D1 D1 D2 D3 D2 D5 D6 D7 B7 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E3 D5 E6 E6 E8 E9 E8 EB ED ED DD EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA EB FC FC FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 47 48 4C 4F 54 55 56 57 5A 5B 5C 5E 5F 62 + 67 68 69 6C 71 74 75 76 77 78 7B 90 91 92 93 94 + 95 41 47 48 4C 4F 54 55 56 57 5A 5B 5C 5E 5F 62 + 67 68 69 6C 71 74 75 76 77 78 7B 96 97 98 99 9A + 48 74 4F 41 41 74 48 48 5C 4F 62 62 57 7B 41 48 + 4F 5C 5C 62 62 5C 5C 6C 6C 62 74 71 71 5C 9E 48 + 41 57 62 74 41 41 7B 7B 4F 4F AA 7B 48 6C AE AF + B0 B1 B2 B3 B4 41 41 4F 6C B5 BA BB BC 7B 7B BF + C0 C1 C2 C3 C4 C5 41 41 C8 C9 CA CB CC CD CE CF + 4C 4C 4C 4F 4C 60 57 57 4F D9 DA DB DC 71 74 DF + 62 70 62 60 60 60 6C 6C 69 74 69 74 78 78 71 EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA 74 69 69 FE FF + +# Unicode mappping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C7 00FC 00E9 00E2 00E4 016F 0107 00E7 0142 00EB 0150 0151 00EE 0179 00C4 0106 + 00C9 0139 013A 00F4 00F6 013D 013E 015A 015B 00D6 00DC 0164 0165 0141 00D7 010D + 00E1 00ED 00F3 00FA 0104 0105 017D 017E 0118 0119 00AC 017A 010C 015F 00AB 00BB + 2591 2592 2593 2502 2524 00C1 00C2 011A 015E 2563 2551 2557 255D 017B 017C 2510 + 2514 2534 252C 251C 2500 253C 0102 0103 255A 2554 2569 2566 2560 2550 256C 00A4 + 0111 0110 010E 00CB 010F 0147 00CD 00CE 011B 2518 250C 2588 2584 0162 016E 2580 + 00D3 00DF 00D4 0143 0144 0148 0160 0161 0154 00DA 0155 0170 00FD 00DD 0163 00B4 + 00AD 02DD 02DB 02C7 02D8 00A7 00F7 00B8 00B0 00A8 02D9 0171 0158 0159 25A0 00A0 + -- cgit v1.2.1 From 08a32ab1b12ec34bdf8f0e5da3bdffb6423884a2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Aug 2002 17:24:56 +0500 Subject: A comment about actual charset has been added --- sql/share/charsets/dos.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/share/charsets/dos.conf b/sql/share/charsets/dos.conf index fc4d4cee5c4..205202711b8 100644 --- a/sql/share/charsets/dos.conf +++ b/sql/share/charsets/dos.conf @@ -1,4 +1,4 @@ -# Configuration file for the dos character set +# Configuration file for the dos (aka cp437 DOSLatinUS) character set # ctype array (must have 257 elements) 00 -- cgit v1.2.1 From d1a7eea83e474cc83f1754ca19602dc8b483ae5b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Aug 2002 12:21:58 +0500 Subject: Spatial code cleanup --- sql/spatial.cc | 11 +++++------ sql/spatial.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/spatial.cc b/sql/spatial.cc index bb6e03c3c03..b21d30e4b53 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -285,7 +285,7 @@ int GLineString::get_mbr(MBR *mbr) const return 1; for (; n_points>0; --n_points) { - mbr->add_xy((double *)data, (double *)(data + 8)); + mbr->add_xy(data, data + 8); data += 8+8; } @@ -551,7 +551,7 @@ int GPolygon::get_mbr(MBR *mbr) const return 1; for (; n_points>0; --n_points) { - mbr->add_xy((double *)data, (double *)(data + 8)); + mbr->add_xy(data, data + 8); data += 8+8; } } @@ -838,8 +838,7 @@ int GMultiPoint::get_mbr(MBR *mbr) const return 1; for (; n_points>0; --n_points) { - mbr->add_xy((double *)(data + WKB_HEADER_SIZE), - (double *)(data + 8 + WKB_HEADER_SIZE)); + mbr->add_xy(data + WKB_HEADER_SIZE, data + 8 + WKB_HEADER_SIZE); data += (8+8+WKB_HEADER_SIZE); } return 0; @@ -963,7 +962,7 @@ int GMultiLineString::get_mbr(MBR *mbr) const for (; n_points>0; --n_points) { - mbr->add_xy((double *)data, (double *)(data + 8)); + mbr->add_xy(data, data + 8); data += 8+8; } } @@ -1156,7 +1155,7 @@ int GMultiPolygon::get_mbr(MBR *mbr) const for (; n_points>0; --n_points) { - mbr->add_xy((double *)data, (double *)(data + 8)); + mbr->add_xy(data, data + 8); data += 8+8; } } diff --git a/sql/spatial.h b/sql/spatial.h index 2daa8e856c9..c6e30a44fbf 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -71,7 +71,7 @@ struct MBR } } - void add_xy(double *px, double *py) + void add_xy(const char *px, const char *py) { /* Not using "else" for proper one point MBR calculation */ double x, y; float8get(x, px); -- cgit v1.2.1 From 56e866ae05fda040fb04edf172c5651f577a3d46 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Aug 2002 18:12:45 +0500 Subject: Stupid bug fixes in sql_yacc.cc New class Item_func_set_collation() Fixed that "SELECT CONVERT(expr USING charset) GROUP BY 1" was not working New COLLATION syntax: COLLATE latin1 mysql-test/r/ctype_many.result: New test slot has been added mysql-test/t/ctype_many.test: New test slot has been added sql/item_strfunc.cc: "SELECT CONVERT(expr USING another_charset) GROUP BY 1" was not working as expected New Item_func_set_collation class sql/item_strfunc.h: "SELECT CONVERT(expr USING another_charset) GROUP BY 1" was not working as expected New Item_func_set_collation class sql/lex.h: New keyword sql/sql_yacc.yy: Stupid bug fixes COLLATION syntax --- sql/item_strfunc.cc | 29 +++++++++++++++++++++++++++++ sql/item_strfunc.h | 22 ++++++++++++++++++---- sql/lex.h | 1 + sql/sql_yacc.yy | 18 ++++++++++++++---- 4 files changed, 62 insertions(+), 8 deletions(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 1aee4e7d553..b5b9ed2931e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1843,9 +1843,11 @@ outp: void Item_func_conv_charset::fix_length_and_dec() { max_length = args[0]->max_length*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1); + str_value.set_charset(conv_charset); } + String *Item_func_conv_charset3::val_str(String *str) { my_wc_t wc; @@ -1938,6 +1940,33 @@ void Item_func_conv_charset3::fix_length_and_dec() max_length = args[0]->max_length; } +String *Item_func_set_collation::val_str(String *str) +{ + str=args[0]->val_str(str); + null_value=args[0]->null_value; + str->set_charset(set_collation); + return str; +} + +bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables) +{ + char buff[STACK_BUFF_ALLOC]; // Max argument in function + binary=0; + used_tables_cache=0; + const_item_cache=1; + + if (thd && check_stack_overrun(thd,buff)) + return 0; // Fatal error if flag is set! + if (args[0]->fix_fields(thd, tables, args)) + return 1; + maybe_null=args[0]->maybe_null; + binary=args[0]->binary; + const_item_cache=args[0]->const_item(); + str_value.set_charset(set_collation); + fix_length_and_dec(); + return 0; +} + String *Item_func_charset::val_str(String *str) { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 7b5bd7ae90b..7f82cd3b5de 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -472,7 +472,7 @@ class Item_func_export_set: public Item_str_func const char *func_name() const { return "export_set"; } }; - class Item_func_inet_ntoa : public Item_str_func +class Item_func_inet_ntoa : public Item_str_func { public: Item_func_inet_ntoa(Item *a) :Item_str_func(a) @@ -488,15 +488,29 @@ class Item_func_conv_charset :public Item_str_func CHARSET_INFO *conv_charset; public: Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) - { - conv_charset=cs; - } + { conv_charset=cs; } bool fix_fields(THD *thd,struct st_table_list *tables); String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "conv_charset"; } }; +class Item_func_set_collation :public Item_str_func +{ + CHARSET_INFO *set_collation; +public: + Item_func_set_collation(Item *a, CHARSET_INFO *cs) :Item_str_func(a) + { set_collation=cs; } + bool fix_fields(THD *thd,struct st_table_list *tables); + String *val_str(String *); + void fix_length_and_dec() + { + max_length = args[0]->max_length; + str_value.set_charset(set_collation); + } + const char *func_name() const { return "set_collation"; } +}; + class Item_func_conv_charset3 :public Item_str_func { public: diff --git a/sql/lex.h b/sql/lex.h index c41ad8c1d44..cd25c3883fe 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -89,6 +89,7 @@ static SYMBOL symbols[] = { { "CHECKSUM", SYM(CHECKSUM_SYM),0,0}, { "CIPHER", SYM(CIPHER_SYM),0,0}, { "CLOSE", SYM(CLOSE_SYM),0,0}, + { "COLLATE", SYM(COLLATE_SYM),0,0}, { "COLUMN", SYM(COLUMN_SYM),0,0}, { "COLUMNS", SYM(COLUMNS),0,0}, { "COMMENT", SYM(COMMENT_SYM),0,0}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 160bc253dc9..01894bfb7ad 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -167,6 +167,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token CHECK_SYM %token CIPHER %token COMMITTED_SYM +%token COLLATE_SYM %token COLUMNS %token COLUMN_SYM %token CONCURRENT @@ -522,7 +523,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %left '*' '/' '%' %left NEG '~' %right NOT -%right BINARY +%right BINARY COLLATE_SYM %type IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME @@ -1129,7 +1130,7 @@ charset: { if (!(Lex->charset=get_charset_by_name($1.str,MYF(0)))) { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$1); + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$1.str); YYABORT; } }; @@ -1658,7 +1659,16 @@ expr_expr: | expr '+' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,0); } | expr '-' INTERVAL_SYM expr interval - { $$= new Item_date_add_interval($1,$4,$5,1); }; + { $$= new Item_date_add_interval($1,$4,$5,1); } + | expr COLLATE_SYM ident + { + if (!(Lex->charset=get_charset_by_name($3.str,MYF(0)))) + { + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3.str); + YYABORT; + } + $$= new Item_func_set_collation($1,Lex->charset); + }; /* expressions that begin with 'expr' that do NOT follow IN_SYM */ no_in_expr: @@ -3446,7 +3456,7 @@ option_value: CONVERT *tmp; if (!(tmp=get_convert_set($3.str))) { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3); + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3.str); YYABORT; } current_thd->convert_set=tmp; -- cgit v1.2.1 From 2077c98682badf881e4bd227bb09aa2e714c1268 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Aug 2002 18:40:21 +0300 Subject: removed accidentally pushed file BitKeeper/deleted/.del-sql_select.h.rej~9724e7a9d86d9f54: Delete: sql/sql_select.h.rej --- sql/sql_select.h.rej | 96 ---------------------------------------------------- 1 file changed, 96 deletions(-) delete mode 100644 sql/sql_select.h.rej (limited to 'sql') diff --git a/sql/sql_select.h.rej b/sql/sql_select.h.rej deleted file mode 100644 index 07b1c4403f9..00000000000 --- a/sql/sql_select.h.rej +++ /dev/null @@ -1,96 +0,0 @@ -*************** -*** 173,178 **** - select_result *result; - TMP_TABLE_PARAM tmp_table_param; - MYSQL_LOCK *lock; - }; - - ---- 172,240 ---- - select_result *result; - TMP_TABLE_PARAM tmp_table_param; - MYSQL_LOCK *lock; -+ -+ bool select_distinct, //Is select distinct? -+ no_order, simple_order, simple_group, -+ skip_sort_order, need_tmp, -+ hidden_group_fields, -+ buffer_result; -+ DYNAMIC_ARRAY keyuse; -+ Item::cond_result cond_value; -+ List all_fields; -+ List & fields_list; // hold field list passed to mysql_select -+ int error; -+ -+ ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select -+ COND *conds; // ---"--- -+ TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_select -+ SQL_SELECT *select; //created in optimisation phase -+ TABLE *exec_tmp_table; //used in 'exec' to hold temporary table -+ SELECT_LEX *select_lex; //corresponding select_lex -+ -+ my_bool test_function_query; // need to return select items 1 row -+ const char *zero_result_cause; // not 0 if exec must return zero result -+ -+ JOIN(THD *thd, List &fields, -+ ulong select_options, select_result *result): -+ join_tab(0), -+ table(0), -+ tables(0), const_tables(0), -+ sort_and_group(0), first_record(0), -+ do_send_rows(1), -+ send_records(0), found_records(0), examined_rows(0), -+ thd(thd), -+ sum_funcs(0), -+ having(0), -+ select_options(select_options), -+ result(result), -+ lock(thd->lock), -+ select_distinct(test(select_options & SELECT_DISTINCT)), -+ no_order(0), simple_order(0), simple_group(0), skip_sort_order(0), -+ need_tmp(0), -+ hidden_group_fields (0), /*safety*/ -+ buffer_result(test(select_options & OPTION_BUFFER_RESULT) && -+ !test(select_options & OPTION_FOUND_ROWS)), -+ all_fields(fields), -+ fields_list(fields), -+ select(0), -+ exec_tmp_table(0), -+ select_lex(0), //for safety -+ test_function_query(0), -+ zero_result_cause(0) -+ { -+ fields_list = fields; -+ bzero((char*) &keyuse,sizeof(keyuse)); -+ tmp_table_param.copy_field=0; -+ tmp_table_param.end_write_records= HA_POS_ERROR; -+ } -+ -+ int prepare(TABLE_LIST *tables, -+ COND *conds, ORDER *order, ORDER *group, Item *having, -+ ORDER *proc_param, SELECT_LEX *select); -+ int optimize(); -+ int global_optimize(); -+ void exec(); -+ int cleanup(THD *thd); - }; - - -*************** -*** 187,193 **** - bool store_val_in_field(Field *field,Item *val); - TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, - ORDER *group, bool distinct, bool save_sum_fields, -- bool allow_distinct_limit, ulong select_options); - void free_tmp_table(THD *thd, TABLE *entry); - void count_field_types(TMP_TABLE_PARAM *param, List &fields, - bool reset_with_sum_func); ---- 249,256 ---- - bool store_val_in_field(Field *field,Item *val); - TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, - ORDER *group, bool distinct, bool save_sum_fields, -+ bool allow_distinct_limit, ulong select_options, -+ SELECT_LEX *first_select); - void free_tmp_table(THD *thd, TABLE *entry); - void count_field_types(TMP_TABLE_PARAM *param, List &fields, - bool reset_with_sum_func); -- cgit v1.2.1 From 7f13b1bdd59e798af7477f4eda46ce249c4b5c4e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 24 Aug 2002 14:49:04 +0300 Subject: Adding a necessary functionality to ::store and ::save_in_field that will take place properly after pull from 4.0, in order to handle conversions from quoted constants to bigint's. --- sql/field.cc | 365 ++++++++++++++++++++++++++++++++++++++++----------- sql/field.h | 126 +++++++++--------- sql/item.cc | 50 ++++--- sql/item.h | 20 +-- sql/item_cmpfunc.cc | 3 +- sql/item_strfunc.cc | 4 +- sql/item_strfunc.h | 4 +- sql/item_timefunc.cc | 4 +- sql/item_timefunc.h | 4 +- sql/opt_range.cc | 2 +- sql/sql_base.cc | 4 +- sql/sql_handler.cc | 2 +- sql/sql_select.cc | 2 +- sql/sql_select.h | 4 +- sql/unireg.cc | 2 +- 15 files changed, 401 insertions(+), 195 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index a475612fbb0..462088d26a6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -424,7 +424,7 @@ void Field_decimal::overflow(bool negative) } -void Field_decimal::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_decimal::store(const char *from,uint len,CHARSET_INFO *cs) { reg3 int i; uint tmp_dec; @@ -459,7 +459,7 @@ void Field_decimal::store(const char *from,uint len,CHARSET_INFO *cs) if (!error) current_thd->cuted_fields++; Field_decimal::overflow(1); - return; + return 1; } } } @@ -485,7 +485,7 @@ void Field_decimal::store(const char *from,uint len,CHARSET_INFO *cs) current_thd->cuted_fields++; // too big number, change to max or min number Field_decimal::overflow(decstr.sign && decstr.sign_char == '-'); - return; + return 1; } char *to=ptr; for (i=(int) (field_length-tmp_dec-decstr.nr_length-decstr.extra - decstr.sign) ; @@ -520,16 +520,17 @@ void Field_decimal::store(const char *from,uint len,CHARSET_INFO *cs) } } } + return (error) ? 1 : 0; } -void Field_decimal::store(double nr) +int Field_decimal::store(double nr) { if (unsigned_flag && nr < 0) { overflow(1); current_thd->cuted_fields++; - return; + return 1; } reg4 uint i,length; char fyllchar,*to; @@ -548,6 +549,7 @@ void Field_decimal::store(double nr) { overflow(nr < 0.0); current_thd->cuted_fields++; + return 1; } else { @@ -555,17 +557,18 @@ void Field_decimal::store(double nr) for (i=field_length-length ; i-- > 0 ;) *to++ = fyllchar; memcpy(to,buff,length); + return 0; } } -void Field_decimal::store(longlong nr) +int Field_decimal::store(longlong nr) { if (unsigned_flag && nr < 0) { overflow(1); current_thd->cuted_fields++; - return; + return 1; } char buff[22]; uint length=(uint) (longlong10_to_str(nr,buff,-10)-buff); @@ -575,6 +578,7 @@ void Field_decimal::store(longlong nr) { overflow(test(nr < 0L)); /* purecov: inspected */ current_thd->cuted_fields++; /* purecov: inspected */ + return 1; } else { @@ -588,6 +592,7 @@ void Field_decimal::store(longlong nr) to[length]='.'; bfill(to+length+1,dec,'0'); } + return 0; } } @@ -704,10 +709,11 @@ void Field_decimal::sql_type(String &res) const ** tiny int ****************************************************************************/ -void Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) { String tmp_str(from,len,default_charset_info); long tmp= strtol(tmp_str.c_ptr(),NULL,10); + int error=0; if (unsigned_flag) { @@ -715,14 +721,19 @@ void Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) { tmp=0; /* purecov: inspected */ current_thd->cuted_fields++; /* purecov: inspected */ + error = 1; } else if (tmp > 255) { tmp= 255; current_thd->cuted_fields++; + error = 1; } else if (current_thd->count_cuted_fields && !test_if_int(from,len)) + { current_thd->cuted_fields++; + error = 1; + } } else { @@ -730,21 +741,28 @@ void Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) { tmp= -128; current_thd->cuted_fields++; + error = 1; } else if (tmp >= 128) { tmp= 127; current_thd->cuted_fields++; + error = 1; } else if (current_thd->count_cuted_fields && !test_if_int(from,len)) + { current_thd->cuted_fields++; + error = 1; + } } ptr[0]= (char) tmp; + return error; } -void Field_tiny::store(double nr) +int Field_tiny::store(double nr) { + int error=0; nr=rint(nr); if (unsigned_flag) { @@ -752,11 +770,13 @@ void Field_tiny::store(double nr) { *ptr=0; current_thd->cuted_fields++; + error = 1; } else if (nr > 255.0) { *ptr=(char) 255; current_thd->cuted_fields++; + error = 1; } else *ptr=(char) nr; @@ -767,30 +787,36 @@ void Field_tiny::store(double nr) { *ptr= (char) -128; current_thd->cuted_fields++; + error = 1; } else if (nr > 127.0) { *ptr=127; current_thd->cuted_fields++; + error = 1; } else *ptr=(char) nr; } + return error; } -void Field_tiny::store(longlong nr) +int Field_tiny::store(longlong nr) { + int error=0; if (unsigned_flag) { if (nr < 0L) { *ptr=0; current_thd->cuted_fields++; + error = 1; } else if (nr > 255L) { *ptr= (char) 255; current_thd->cuted_fields++; + error = 1; } else *ptr=(char) nr; @@ -801,15 +827,18 @@ void Field_tiny::store(longlong nr) { *ptr= (char) -128; current_thd->cuted_fields++; + error = 1; } else if (nr > 127L) { *ptr=127; current_thd->cuted_fields++; + error = 1; } else *ptr=(char) nr; } + return error; } @@ -875,24 +904,30 @@ void Field_tiny::sql_type(String &res) const // Note: Sometimes this should be fixed to use one strtol() to use // len and check for garbage after number. -void Field_short::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_short::store(const char *from,uint len,CHARSET_INFO *cs) { String tmp_str(from,len,default_charset_info); long tmp= strtol(tmp_str.c_ptr(),NULL,10); + int error=0; if (unsigned_flag) { if (tmp < 0) { tmp=0; current_thd->cuted_fields++; + error = 1; } else if (tmp > (uint16) ~0) { tmp=(uint16) ~0; current_thd->cuted_fields++; + error = 1; } else if (current_thd->count_cuted_fields && !test_if_int(from,len)) + { current_thd->cuted_fields++; + error = 1; + } } else { @@ -900,14 +935,19 @@ void Field_short::store(const char *from,uint len,CHARSET_INFO *cs) { tmp= INT_MIN16; current_thd->cuted_fields++; + error = 1; } else if (tmp > INT_MAX16) { tmp=INT_MAX16; current_thd->cuted_fields++; + error = 1; } else if (current_thd->count_cuted_fields && !test_if_int(from,len)) + { current_thd->cuted_fields++; + error = 1; + } } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -917,11 +957,13 @@ void Field_short::store(const char *from,uint len,CHARSET_INFO *cs) else #endif shortstore(ptr,(short) tmp); + return error; } -void Field_short::store(double nr) +int Field_short::store(double nr) { + int error=0; int16 res; nr=rint(nr); if (unsigned_flag) @@ -930,11 +972,13 @@ void Field_short::store(double nr) { res=0; current_thd->cuted_fields++; + error = 1; } else if (nr > (double) (uint16) ~0) { res=(int16) (uint16) ~0; current_thd->cuted_fields++; + error = 1; } else res=(int16) (uint16) nr; @@ -945,11 +989,13 @@ void Field_short::store(double nr) { res=INT_MIN16; current_thd->cuted_fields++; + error = 1; } else if (nr > (double) INT_MAX16) { res=INT_MAX16; current_thd->cuted_fields++; + error = 1; } else res=(int16) nr; @@ -962,10 +1008,12 @@ void Field_short::store(double nr) else #endif shortstore(ptr,res); + return error; } -void Field_short::store(longlong nr) +int Field_short::store(longlong nr) { + int error=0; int16 res; if (unsigned_flag) { @@ -973,11 +1021,13 @@ void Field_short::store(longlong nr) { res=0; current_thd->cuted_fields++; + error = 1; } else if (nr > (longlong) (uint16) ~0) { res=(int16) (uint16) ~0; current_thd->cuted_fields++; + error = 1; } else res=(int16) (uint16) nr; @@ -988,11 +1038,13 @@ void Field_short::store(longlong nr) { res=INT_MIN16; current_thd->cuted_fields++; + error = 1; } else if (nr > INT_MAX16) { res=INT_MAX16; current_thd->cuted_fields++; + error = 1; } else res=(int16) nr; @@ -1005,6 +1057,7 @@ void Field_short::store(longlong nr) else #endif shortstore(ptr,res); + return error; } @@ -1115,10 +1168,11 @@ void Field_short::sql_type(String &res) const // Note: Sometimes this should be fixed to use one strtol() to use // len and check for garbage after number. -void Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) { String tmp_str(from,len,default_charset_info); long tmp= strtol(tmp_str.c_ptr(),NULL,10); + int error=0; if (unsigned_flag) { @@ -1126,14 +1180,19 @@ void Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) { tmp=0; current_thd->cuted_fields++; + error = 1; } else if (tmp >= (long) (1L << 24)) { tmp=(long) (1L << 24)-1L; current_thd->cuted_fields++; + error = 1; } else if (current_thd->count_cuted_fields && !test_if_int(from,len)) + { current_thd->cuted_fields++; + error = 1; + } } else { @@ -1141,22 +1200,29 @@ void Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) { tmp= INT_MIN24; current_thd->cuted_fields++; + error = 1; } else if (tmp > INT_MAX24) { tmp=INT_MAX24; current_thd->cuted_fields++; + error = 1; } else if (current_thd->count_cuted_fields && !test_if_int(from,len)) + { current_thd->cuted_fields++; + error = 1; + } } int3store(ptr,tmp); + return error; } -void Field_medium::store(double nr) +int Field_medium::store(double nr) { + int error=0; nr=rint(nr); if (unsigned_flag) { @@ -1164,12 +1230,14 @@ void Field_medium::store(double nr) { int3store(ptr,0); current_thd->cuted_fields++; + error = 1; } else if (nr >= (double) (long) (1L << 24)) { uint32 tmp=(uint32) (1L << 24)-1L; int3store(ptr,tmp); current_thd->cuted_fields++; + error = 1; } else int3store(ptr,(uint32) nr); @@ -1181,32 +1249,38 @@ void Field_medium::store(double nr) long tmp=(long) INT_MIN24; int3store(ptr,tmp); current_thd->cuted_fields++; + error = 1; } else if (nr > (double) INT_MAX24) { long tmp=(long) INT_MAX24; int3store(ptr,tmp); current_thd->cuted_fields++; + error = 1; } else int3store(ptr,(long) nr); } + return error; } -void Field_medium::store(longlong nr) +int Field_medium::store(longlong nr) { + int error=0; if (unsigned_flag) { if (nr < 0L) { int3store(ptr,0); current_thd->cuted_fields++; + error = 1; } else if (nr >= (longlong) (long) (1L << 24)) { long tmp=(long) (1L << 24)-1L;; int3store(ptr,tmp); current_thd->cuted_fields++; + error = 1; } else int3store(ptr,(uint32) nr); @@ -1218,16 +1292,19 @@ void Field_medium::store(longlong nr) long tmp=(long) INT_MIN24; int3store(ptr,tmp); current_thd->cuted_fields++; + error = 1; } else if (nr > (longlong) INT_MAX24) { long tmp=(long) INT_MAX24; int3store(ptr,tmp); current_thd->cuted_fields++; + error = 1; } else int3store(ptr,(long) nr); } + return error; } @@ -1300,13 +1377,14 @@ void Field_medium::sql_type(String &res) const // Note: Sometimes this should be fixed to use one strtol() to use // len and check for garbage after number. -void Field_long::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) { while (len && my_isspace(system_charset_info,*from)) { len--; from++; } long tmp; + int error=0; String tmp_str(from,len,default_charset_info); errno=0; if (unsigned_flag) @@ -1315,6 +1393,7 @@ void Field_long::store(const char *from,uint len,CHARSET_INFO *cs) { tmp=0; // Set negative to 0 errno=ERANGE; + error = 1; } else tmp=(long) strtoul(tmp_str.c_ptr(),NULL,10); @@ -1322,7 +1401,10 @@ void Field_long::store(const char *from,uint len,CHARSET_INFO *cs) else tmp=strtol(tmp_str.c_ptr(),NULL,10); if (errno || current_thd->count_cuted_fields && !test_if_int(from,len)) + { current_thd->cuted_fields++; + error = 1; + } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -1331,11 +1413,13 @@ void Field_long::store(const char *from,uint len,CHARSET_INFO *cs) else #endif longstore(ptr,tmp); + return error; } -void Field_long::store(double nr) +int Field_long::store(double nr) { + int error=0; int32 res; nr=rint(nr); if (unsigned_flag) @@ -1344,11 +1428,13 @@ void Field_long::store(double nr) { res=0; current_thd->cuted_fields++; + error = 1; } else if (nr > (double) (ulong) ~0L) { res=(int32) (uint32) ~0L; current_thd->cuted_fields++; + error = 1; } else res=(int32) (ulong) nr; @@ -1359,11 +1445,13 @@ void Field_long::store(double nr) { res=(int32) INT_MIN32; current_thd->cuted_fields++; + error = 1; } else if (nr > (double) INT_MAX32) { res=(int32) INT_MAX32; current_thd->cuted_fields++; + error = 1; } else res=(int32) nr; @@ -1376,11 +1464,13 @@ void Field_long::store(double nr) else #endif longstore(ptr,res); + return error; } -void Field_long::store(longlong nr) +int Field_long::store(longlong nr) { + int error=0; int32 res; if (unsigned_flag) { @@ -1388,11 +1478,13 @@ void Field_long::store(longlong nr) { res=0; current_thd->cuted_fields++; + error = 1; } else if (nr >= (LL(1) << 32)) { res=(int32) (uint32) ~0L; current_thd->cuted_fields++; + error = 1; } else res=(int32) (uint32) nr; @@ -1403,11 +1495,13 @@ void Field_long::store(longlong nr) { res=(int32) INT_MIN32; current_thd->cuted_fields++; + error = 1; } else if (nr > (longlong) INT_MAX32) { res=(int32) INT_MAX32; current_thd->cuted_fields++; + error = 1; } else res=(int32) nr; @@ -1420,6 +1514,7 @@ void Field_long::store(longlong nr) else #endif longstore(ptr,res); + return error; } @@ -1528,7 +1623,7 @@ void Field_long::sql_type(String &res) const ** longlong int ****************************************************************************/ -void Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) { while (len && my_isspace(system_charset_info,*from)) { // For easy error check @@ -1536,6 +1631,7 @@ void Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) } longlong tmp; String tmp_str(from,len,default_charset_info); + int error=0; errno=0; if (unsigned_flag) { @@ -1543,6 +1639,7 @@ void Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) { tmp=0; // Set negative to 0 errno=ERANGE; + error = 1; } else tmp=(longlong) strtoull(tmp_str.c_ptr(),NULL,10); @@ -1550,7 +1647,10 @@ void Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) else tmp=strtoll(tmp_str.c_ptr(),NULL,10); if (errno || current_thd->count_cuted_fields && !test_if_int(from,len)) + { current_thd->cuted_fields++; + error = 1; + } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -1559,11 +1659,13 @@ void Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) else #endif longlongstore(ptr,tmp); + return error; } -void Field_longlong::store(double nr) +int Field_longlong::store(double nr) { + int error=0; longlong res; nr=rint(nr); if (unsigned_flag) @@ -1572,11 +1674,13 @@ void Field_longlong::store(double nr) { res=0; current_thd->cuted_fields++; + error = 1; } else if (nr >= (double) ~ (ulonglong) 0) { res= ~(longlong) 0; current_thd->cuted_fields++; + error = 1; } else res=(longlong) (ulonglong) nr; @@ -1587,11 +1691,13 @@ void Field_longlong::store(double nr) { res=(longlong) LONGLONG_MIN; current_thd->cuted_fields++; + error = 1; } else if (nr >= (double) LONGLONG_MAX) { res=(longlong) LONGLONG_MAX; current_thd->cuted_fields++; + error = 1; } else res=(longlong) nr; @@ -1604,10 +1710,11 @@ void Field_longlong::store(double nr) else #endif longlongstore(ptr,res); + return error; } -void Field_longlong::store(longlong nr) +int Field_longlong::store(longlong nr) { #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -1617,6 +1724,7 @@ void Field_longlong::store(longlong nr) else #endif longlongstore(ptr,nr); + return 0; } @@ -1735,35 +1843,43 @@ void Field_longlong::sql_type(String &res) const ** single precision float ****************************************************************************/ -void Field_float::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) { String tmp_str(from,len,default_charset_info); errno=0; Field_float::store(atof(tmp_str.c_ptr())); if (errno || current_thd->count_cuted_fields && !test_if_real(from,len)) + { current_thd->cuted_fields++; + return 1; + } + return (errno) ? 1 : 0; } -void Field_float::store(double nr) +int Field_float::store(double nr) { float j; + int error=0; if (dec < NOT_FIXED_DEC) nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point if (unsigned_flag && nr < 0) { current_thd->cuted_fields++; nr=0; + error = 1; } if (nr < -FLT_MAX) { j= -FLT_MAX; current_thd->cuted_fields++; + error = 1; } else if (nr > FLT_MAX) { j=FLT_MAX; current_thd->cuted_fields++; + error = 1; } else j= (float) nr; @@ -1775,16 +1891,19 @@ void Field_float::store(double nr) else #endif memcpy_fixed(ptr,(byte*) &j,sizeof(j)); + return error; } -void Field_float::store(longlong nr) +int Field_float::store(longlong nr) { + int error=0; float j= (float) nr; if (unsigned_flag && j < 0) { current_thd->cuted_fields++; j=0; + error = 1; } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -1794,6 +1913,7 @@ void Field_float::store(longlong nr) else #endif memcpy_fixed(ptr,(byte*) &j,sizeof(j)); + return error; } @@ -1985,17 +2105,22 @@ void Field_float::sql_type(String &res) const ** double precision floating point numbers ****************************************************************************/ -void Field_double::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) { String tmp_str(from,len,default_charset_info); errno=0; + int error=0; double j= atof(tmp_str.c_ptr()); if (errno || current_thd->count_cuted_fields && !test_if_real(from,len)) + { current_thd->cuted_fields++; + error = 1; + } if (unsigned_flag && j < 0) { current_thd->cuted_fields++; j=0; + error = 1; } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -2005,17 +2130,20 @@ void Field_double::store(const char *from,uint len,CHARSET_INFO *cs) else #endif doublestore(ptr,j); + return error; } -void Field_double::store(double nr) +int Field_double::store(double nr) { + int error=0; if (dec < NOT_FIXED_DEC) nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point if (unsigned_flag && nr < 0) { current_thd->cuted_fields++; nr=0; + error = 1; } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -2025,15 +2153,18 @@ void Field_double::store(double nr) else #endif doublestore(ptr,nr); + return error; } -void Field_double::store(longlong nr) +int Field_double::store(longlong nr) { double j= (double) nr; + int error=0; if (unsigned_flag && j < 0) { current_thd->cuted_fields++; + error = 1; j=0; } #ifdef WORDS_BIGENDIAN @@ -2044,6 +2175,7 @@ void Field_double::store(longlong nr) else #endif doublestore(ptr,j); + return error; } @@ -2241,7 +2373,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, } -void Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { long tmp=(long) str_to_timestamp(from,len); #ifdef WORDS_BIGENDIAN @@ -2252,9 +2384,10 @@ void Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) else #endif longstore(ptr,tmp); + return 0; } -void Field_timestamp::fill_and_store(char *from,uint len) +void Field_timestamp::fill_and_store(char *from,uint len) { uint res_length; if (len <= field_length) @@ -2283,14 +2416,17 @@ void Field_timestamp::fill_and_store(char *from,uint len) } -void Field_timestamp::store(double nr) +int Field_timestamp::store(double nr) { + int error=0; if (nr < 0 || nr > 99991231235959.0) { nr=0; // Avoid overflow on buff current_thd->cuted_fields++; + error = 1; } - Field_timestamp::store((longlong) rint(nr)); + error |= Field_timestamp::store((longlong) rint(nr)); + return error; } @@ -2331,7 +2467,7 @@ static longlong fix_datetime(longlong nr) } -void Field_timestamp::store(longlong nr) +int Field_timestamp::store(longlong nr) { TIME l_time; time_t timestamp; @@ -2359,6 +2495,7 @@ void Field_timestamp::store(longlong nr) else #endif longstore(ptr,(uint32) timestamp); + return 0; } @@ -2580,12 +2717,16 @@ void Field_timestamp::set_time() ** Stored as a 3 byte unsigned int ****************************************************************************/ -void Field_time::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) { TIME ltime; long tmp; + int error=0; if (str_to_time(from,len,<ime)) + { tmp=0L; + error = 1; + } else { if (ltime.month) @@ -2595,26 +2736,31 @@ void Field_time::store(const char *from,uint len,CHARSET_INFO *cs) { tmp=8385959; current_thd->cuted_fields++; + error = 1; } } if (ltime.neg) tmp= -tmp; - Field_time::store((longlong) tmp); + error |= Field_time::store((longlong) tmp); + return error; } -void Field_time::store(double nr) +int Field_time::store(double nr) { long tmp; + int error=0; if (nr > 8385959.0) { tmp=8385959L; current_thd->cuted_fields++; + error = 1; } else if (nr < -8385959.0) { tmp= -8385959L; current_thd->cuted_fields++; + error = 1; } else { @@ -2625,24 +2771,29 @@ void Field_time::store(double nr) { tmp=0; current_thd->cuted_fields++; + error = 1; } } int3store(ptr,tmp); + return error; } -void Field_time::store(longlong nr) +int Field_time::store(longlong nr) { long tmp; + int error=0; if (nr > (longlong) 8385959L) { tmp=8385959L; current_thd->cuted_fields++; + error = 1; } else if (nr < (longlong) -8385959L) { tmp= -8385959L; current_thd->cuted_fields++; + error = 1; } else { @@ -2651,9 +2802,11 @@ void Field_time::store(longlong nr) { tmp=0; current_thd->cuted_fields++; + error = 1; } } int3store(ptr,tmp); + return error; } @@ -2729,7 +2882,7 @@ void Field_time::sql_type(String &res) const ** Can handle 2 byte or 4 byte years! ****************************************************************************/ -void Field_year::store(const char *from, uint len,CHARSET_INFO *cs) +int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) { String tmp_str(from,len,default_charset_info); long nr= strtol(tmp_str.c_ptr(),NULL,10); @@ -2738,7 +2891,7 @@ void Field_year::store(const char *from, uint len,CHARSET_INFO *cs) { *ptr=0; current_thd->cuted_fields++; - return; + return 1; } else if (current_thd->count_cuted_fields && !test_if_int(from,len)) current_thd->cuted_fields++; @@ -2750,23 +2903,27 @@ void Field_year::store(const char *from, uint len,CHARSET_INFO *cs) nr-= 1900; } *ptr= (char) (unsigned char) nr; + return 0; } -void Field_year::store(double nr) +int Field_year::store(double nr) { if (nr < 0.0 || nr >= 2155.0) - Field_year::store((longlong) -1); + { + (void) Field_year::store((longlong) -1); + return 1; + } else - Field_year::store((longlong) nr); + return Field_year::store((longlong) nr); } -void Field_year::store(longlong nr) +int Field_year::store(longlong nr) { if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) { *ptr=0; current_thd->cuted_fields++; - return; + return 1; } if (nr != 0 || field_length != 4) // 0000 -> 0; 00 -> 2000 { @@ -2776,6 +2933,7 @@ void Field_year::store(longlong nr) nr-= 1900; } *ptr= (char) (unsigned char) nr; + return 0; } @@ -2818,12 +2976,16 @@ void Field_year::sql_type(String &res) const ** Stored as a 4 byte unsigned int ****************************************************************************/ -void Field_date::store(const char *from, uint len,CHARSET_INFO *cs) +int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) { TIME l_time; uint32 tmp; + int error=0; if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE) + { tmp=0; + error = 1; + } else tmp=(uint32) l_time.year*10000L + (uint32) (l_time.month*100+l_time.day); #ifdef WORDS_BIGENDIAN @@ -2834,18 +2996,21 @@ void Field_date::store(const char *from, uint len,CHARSET_INFO *cs) else #endif longstore(ptr,tmp); + return error; } -void Field_date::store(double nr) +int Field_date::store(double nr) { long tmp; + int error=0; if (nr >= 19000000000000.0 && nr <= 99991231235959.0) nr=floor(nr/1000000.0); // Timestamp to date if (nr < 0.0 || nr > 99991231.0) { tmp=0L; current_thd->cuted_fields++; + error = 1; } else tmp=(long) rint(nr); @@ -2857,18 +3022,21 @@ void Field_date::store(double nr) else #endif longstore(ptr,tmp); + return error; } -void Field_date::store(longlong nr) +int Field_date::store(longlong nr) { long tmp; + int error=0; if (nr >= LL(19000000000000) && nr < LL(99991231235959)) nr=nr/LL(1000000); // Timestamp to date if (nr < 0 || nr > LL(99991231)) { tmp=0L; current_thd->cuted_fields++; + error = 1; } else tmp=(long) nr; @@ -2880,6 +3048,7 @@ void Field_date::store(longlong nr) else #endif longstore(ptr,tmp); + return error; } @@ -2975,35 +3144,45 @@ void Field_date::sql_type(String &res) const ** In number context: YYYYMMDD ****************************************************************************/ -void Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) { TIME l_time; long tmp; + int error=0; if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE) + { tmp=0L; + error = 1; + } else tmp= l_time.day + l_time.month*32 + l_time.year*16*32; int3store(ptr,tmp); + return error; } -void Field_newdate::store(double nr) +int Field_newdate::store(double nr) { if (nr < 0.0 || nr > 99991231235959.0) - Field_newdate::store((longlong) -1); + { + (void) Field_newdate::store((longlong) -1); + return 1; + } else - Field_newdate::store((longlong) rint(nr)); + return Field_newdate::store((longlong) rint(nr)); } -void Field_newdate::store(longlong nr) +int Field_newdate::store(longlong nr) { int32 tmp; + int error=0; if (nr >= LL(100000000) && nr <= LL(99991231235959)) nr=nr/LL(1000000); // Timestamp to date if (nr < 0L || nr > 99991231L) { tmp=0; current_thd->cuted_fields++; + error = 1; } else { @@ -3021,11 +3200,13 @@ void Field_newdate::store(longlong nr) { tmp=0L; // Don't allow date to change current_thd->cuted_fields++; + error = 1; } else tmp= day + month*32 + (tmp/10000)*16*32; } int3store(ptr,(int32) tmp); + return error; } void Field_newdate::store_time(TIME *ltime,timestamp_type type) @@ -3128,7 +3309,7 @@ void Field_newdate::sql_type(String &res) const ** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int. ****************************************************************************/ -void Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) { longlong tmp=str_to_datetime(from,len,1); #ifdef WORDS_BIGENDIAN @@ -3139,26 +3320,32 @@ void Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) else #endif longlongstore(ptr,tmp); + return 0; } -void Field_datetime::store(double nr) +int Field_datetime::store(double nr) { + int error=0; if (nr < 0.0 || nr > 99991231235959.0) { nr=0.0; current_thd->cuted_fields++; + error = 1; } - Field_datetime::store((longlong) rint(nr)); + error |= Field_datetime::store((longlong) rint(nr)); + return error; } -void Field_datetime::store(longlong nr) +int Field_datetime::store(longlong nr) { + int error=0; if (nr < 0 || nr > LL(99991231235959)) { nr=0; current_thd->cuted_fields++; + error = 1; } else nr=fix_datetime(nr); @@ -3170,6 +3357,7 @@ void Field_datetime::store(longlong nr) else #endif longlongstore(ptr,nr); + return error; } void Field_datetime::store_time(TIME *ltime,timestamp_type type) @@ -3344,9 +3532,10 @@ void Field_datetime::sql_type(String &res) const /* Copy a string and fill with space */ -void Field_string::store(const char *from,uint length,CHARSET_INFO *cs) +int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) { field_charset=cs; + int error=0; #ifdef USE_TIS620 if(!binary_flag) { ThNormalize((uchar *)ptr, field_length, (uchar *)from, length); @@ -3372,30 +3561,32 @@ void Field_string::store(const char *from,uint length,CHARSET_INFO *cs) if (!my_isspace(field_charset,*from)) { current_thd->cuted_fields++; + error=1; break; } } } } #endif /* USE_TIS620 */ + return error; } -void Field_string::store(double nr) +int Field_string::store(double nr) { char buff[MAX_FIELD_WIDTH],*end; int width=min(field_length,DBL_DIG+5); sprintf(buff,"%-*.*g",width,max(width-5,0),nr); end=strcend(buff,' '); - Field_string::store(buff,(uint) (end - buff), default_charset_info); + return Field_string::store(buff,(uint) (end - buff), default_charset_info); } -void Field_string::store(longlong nr) +int Field_string::store(longlong nr) { char buff[22]; char *end=longlong10_to_str(nr,buff,-10); - Field_string::store(buff,(uint) (end-buff), default_charset_info); + return Field_string::store(buff,(uint) (end-buff), default_charset_info); } @@ -3554,8 +3745,9 @@ uint Field_string::max_packed_col_length(uint max_length) ****************************************************************************/ -void Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) +int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) { + int error=0; field_charset=cs; #ifdef USE_TIS620 if(!binary_flag) @@ -3572,27 +3764,29 @@ void Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) length=field_length; memcpy(ptr+2,from,field_length); current_thd->cuted_fields++; + error = 1; } #endif /* USE_TIS620 */ int2store(ptr,length); + return error; } -void Field_varstring::store(double nr) +int Field_varstring::store(double nr) { char buff[MAX_FIELD_WIDTH],*end; int width=min(field_length,DBL_DIG+5); sprintf(buff,"%-*.*g",width,max(width-5,0),nr); end=strcend(buff,' '); - Field_varstring::store(buff,(uint) (end - buff), default_charset_info); + return Field_varstring::store(buff,(uint) (end - buff), default_charset_info); } -void Field_varstring::store(longlong nr) +int Field_varstring::store(longlong nr) { char buff[22]; char *end=longlong10_to_str(nr,buff,-10); - Field_varstring::store(buff,(uint) (end-buff), default_charset_info); + return Field_varstring::store(buff,(uint) (end-buff), default_charset_info); } @@ -3877,7 +4071,7 @@ uint32 Field_blob::get_length(const char *pos) } -void Field_blob::store(const char *from,uint len,CHARSET_INFO *cs) +int Field_blob::store(const char *from,uint len,CHARSET_INFO *cs) { field_charset=cs; if (!len) @@ -3911,20 +4105,21 @@ void Field_blob::store(const char *from,uint len,CHARSET_INFO *cs) } bmove(ptr+packlength,(char*) &from,sizeof(char*)); } + return 0; } -void Field_blob::store(double nr) +int Field_blob::store(double nr) { value.set(nr); - Field_blob::store(value.ptr(),(uint) value.length(), default_charset_info); + return Field_blob::store(value.ptr(),(uint) value.length(), default_charset_info); } -void Field_blob::store(longlong nr) +int Field_blob::store(longlong nr) { value.set(nr); - Field_blob::store(value.ptr(), (uint) value.length(), default_charset_info); + return Field_blob::store(value.ptr(), (uint) value.length(), default_charset_info); } @@ -4071,7 +4266,7 @@ void Field_blob::get_key_image(char *buff,uint length, imagetype type) void Field_blob::set_key_image(char *buff,uint length) { length=uint2korr(buff); - Field_blob::store(buff+2,length, default_charset_info); + (void) Field_blob::store(buff+2,length, default_charset_info); } void Field_geom::get_key_image(char *buff,uint length, imagetype type) @@ -4392,8 +4587,9 @@ uint find_enum(TYPELIB *lib,const char *x, uint length) ** (if there isn't a empty value in the enum) */ -void Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) +int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) { + int error=0; uint tmp=find_enum(typelib,from,length); if (!tmp) { @@ -4413,29 +4609,34 @@ void Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) { tmp=0; current_thd->cuted_fields++; + error=1; } } else current_thd->cuted_fields++; } store_type((ulonglong) tmp); + return error; } -void Field_enum::store(double nr) +int Field_enum::store(double nr) { - Field_enum::store((longlong) nr); + return Field_enum::store((longlong) nr); } -void Field_enum::store(longlong nr) +int Field_enum::store(longlong nr) { + int error=0; if ((uint) nr > typelib->count || nr == 0) { current_thd->cuted_fields++; nr=0; + error=1; } store_type((ulonglong) (uint) nr); + return error; } @@ -4583,8 +4784,9 @@ ulonglong find_set(TYPELIB *lib,const char *x,uint length) } -void Field_set::store(const char *from,uint length,CHARSET_INFO *cs) +int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) { + int error=0; ulonglong tmp=find_set(typelib,from,length); if (!tmp && length && length < 22) { @@ -4600,23 +4802,30 @@ void Field_set::store(const char *from,uint length,CHARSET_INFO *cs) tmp=strtoull(conv,&end,10); if (my_errno || end != conv+length || tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1)) + { tmp=0; + error=1; + } else current_thd->cuted_fields--; // Remove warning from find_set } store_type(tmp); + return error; } -void Field_set::store(longlong nr) +int Field_set::store(longlong nr) { + int error=0; if ((ulonglong) nr > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1)) { nr&= (longlong) (((longlong) 1 << typelib->count) - (longlong) 1); current_thd->cuted_fields++; + error=1; } store_type((ulonglong) nr); + return error; } diff --git a/sql/field.h b/sql/field.h index 5bc463af48d..88187b2b7aa 100644 --- a/sql/field.h +++ b/sql/field.h @@ -60,9 +60,9 @@ public: utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg); virtual ~Field() {} - virtual void store(const char *to,uint length,CHARSET_INFO *cs)=0; - virtual void store(double nr)=0; - virtual void store(longlong nr)=0; + virtual int store(const char *to,uint length,CHARSET_INFO *cs)=0; + virtual int store(double nr)=0; + virtual int store(longlong nr)=0; virtual void store_time(TIME *ltime,timestamp_type t_type); virtual double val_real(void)=0; virtual longlong val_int(void)=0; @@ -281,9 +281,9 @@ public: enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } void reset(void); - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -310,9 +310,9 @@ public: enum_field_types type() const { return FIELD_TYPE_TINY;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset(void) { ptr[0]=0; } double val_real(void); longlong val_int(void); @@ -339,9 +339,9 @@ public: enum_field_types type() const { return FIELD_TYPE_SHORT;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;} - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset(void) { ptr[0]=ptr[1]=0; } double val_real(void); longlong val_int(void); @@ -368,9 +368,9 @@ public: enum_field_types type() const { return FIELD_TYPE_INT24;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } double val_real(void); longlong val_int(void); @@ -402,9 +402,9 @@ public: enum_field_types type() const { return FIELD_TYPE_LONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } double val_real(void); longlong val_int(void); @@ -438,9 +438,9 @@ public: enum_field_types type() const { return FIELD_TYPE_LONGLONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } double val_real(void); longlong val_int(void); @@ -465,9 +465,9 @@ public: {} enum_field_types type() const { return FIELD_TYPE_FLOAT;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset(void) { bzero(ptr,sizeof(float)); } double val_real(void); longlong val_int(void); @@ -497,9 +497,9 @@ public: {} enum_field_types type() const { return FIELD_TYPE_DOUBLE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset(void) { bzero(ptr,sizeof(double)); } double val_real(void); longlong val_int(void); @@ -523,9 +523,9 @@ public: unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_NULL;} - void store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; } - void store(double nr) { null[0]=1; } - void store(longlong nr) { null[0]=1; } + int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; } + int store(double nr) { null[0]=1; return 0; } + int store(longlong nr) { null[0]=1; return 0; } void reset(void) {} double val_real(void) { return 0.0;} longlong val_int(void) { return 0;} @@ -547,9 +547,9 @@ public: enum Item_result result_type () const { return field_length == 8 || field_length == 14 ? INT_RESULT : STRING_RESULT; } enum_field_types type() const { return FIELD_TYPE_TIMESTAMP;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } double val_real(void); longlong val_int(void); @@ -587,9 +587,9 @@ public: unireg_check_arg, field_name_arg, table_arg, 1, 1) {} enum_field_types type() const { return FIELD_TYPE_YEAR;} - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -612,9 +612,9 @@ public: enum_field_types type() const { return FIELD_TYPE_DATE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } double val_real(void); longlong val_int(void); @@ -639,9 +639,9 @@ public: enum_field_types real_type() const { return FIELD_TYPE_NEWDATE; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; } enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void store_time(TIME *ltime,timestamp_type type); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } double val_real(void); @@ -673,9 +673,9 @@ public: enum_field_types type() const { return FIELD_TYPE_TIME;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } double val_real(void); longlong val_int(void); @@ -707,9 +707,9 @@ public: enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; } #endif enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void store_time(TIME *ltime,timestamp_type type); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } double val_real(void); @@ -761,9 +761,9 @@ public: bool zero_pack() const { return 0; } bool binary() const { return binary_flag; } void reset(void) { bfill(ptr,field_length,' '); } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -813,9 +813,9 @@ public: void reset(void) { bzero(ptr,field_length+2); } uint32 pack_length() const { return (uint32) field_length+2; } uint32 key_length() const { return (uint32) field_length; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -856,9 +856,9 @@ public: enum_field_types type() const { return FIELD_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary_flag ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -962,9 +962,9 @@ public: enum_field_types type() const { return FIELD_TYPE_STRING; } enum Item_result cmp_type () const { return INT_RESULT; } enum ha_base_keytype key_type() const; - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr); - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr); void reset() { bzero(ptr,packlength); } double val_real(void); longlong val_int(void); @@ -997,9 +997,9 @@ public: { flags=(flags & ~ENUM_FLAG) | SET_FLAG; } - void store(const char *to,uint length,CHARSET_INFO *charset); - void store(double nr) { Field_set::store((longlong) nr); } - void store(longlong nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr) { return Field_set::store((longlong) nr); } + int store(longlong nr); virtual bool zero_pack() const { return 1; } String *val_str(String*,String *); void sql_type(String &str) const; diff --git a/sql/item.cc b/sql/item.cc index 81c5168b72d..f717b78f4bf 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -340,7 +340,7 @@ void Item_param::set_long_end() item_result_type = STRING_RESULT; }; -bool Item_param::save_in_field(Field *field) +int Item_param::save_in_field(Field *field) { if (null_value) return set_field_to_null(field); @@ -349,20 +349,17 @@ bool Item_param::save_in_field(Field *field) if (item_result_type == INT_RESULT) { longlong nr=val_int(); - field->store(nr); - return 0; + return (field->store(nr)) ? -1 : 0; } if (item_result_type == REAL_RESULT) { double nr=val(); - field->store(nr); - return 0; + return (field->store(nr)) ? -1 : 0; } String *result; CHARSET_INFO *cs=default_charset_info;//fix this result=val_str(&str_value); - field->store(result->ptr(),result->length(),cs); - return 0; + return (field->store(result->ptr(),result->length(),cs)) ? -1 : 0; } void Item_param::make_field(Send_field *tmp_field) @@ -615,7 +612,7 @@ void Item_field::save_org_in_field(Field *to) } } -bool Item_field::save_in_field(Field *to) +int Item_field::save_in_field(Field *to) { if (result_field->is_null()) { @@ -632,14 +629,15 @@ bool Item_field::save_in_field(Field *to) } -bool Item_null::save_in_field(Field *field) +int Item_null::save_in_field(Field *field) { return set_field_to_null(field); } -bool Item::save_in_field(Field *field) +int Item::save_in_field(Field *field) { + int error; if (result_type() == STRING_RESULT || result_type() == REAL_RESULT && field->result_type() == STRING_RESULT) @@ -652,7 +650,7 @@ bool Item::save_in_field(Field *field) if (null_value) return set_field_to_null(field); field->set_notnull(); - field->store(result->ptr(),result->length(),cs); + error=field->store(result->ptr(),result->length(),cs); str_value.set_quick(0, 0, cs); } else if (result_type() == REAL_RESULT) @@ -661,7 +659,7 @@ bool Item::save_in_field(Field *field) if (null_value) return set_field_to_null(field); field->set_notnull(); - field->store(nr); + error=field->store(nr); } else { @@ -669,12 +667,12 @@ bool Item::save_in_field(Field *field) if (null_value) return set_field_to_null(field); field->set_notnull(); - field->store(nr); + error=field->store(nr); } - return 0; + return (error) ? -1 : 0; } -bool Item_string::save_in_field(Field *field) +int Item_string::save_in_field(Field *field) { String *result; CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); @@ -682,28 +680,25 @@ bool Item_string::save_in_field(Field *field) if (null_value) return set_field_to_null(field); field->set_notnull(); - field->store(result->ptr(),result->length(),cs); - return 0; + return (field->store(result->ptr(),result->length(),cs)) ? -1 : 0; } -bool Item_int::save_in_field(Field *field) +int Item_int::save_in_field(Field *field) { longlong nr=val_int(); if (null_value) return set_field_to_null(field); field->set_notnull(); - field->store(nr); - return 0; + return (field->store(nr)) ? -1 : 0; } -bool Item_real::save_in_field(Field *field) +int Item_real::save_in_field(Field *field) { double nr=val(); if (null_value) return set_field_to_null(field); field->set_notnull(); - field->store(nr); - return 0; + return (field->store(nr)) ? -1 : 0; } /**************************************************************************** @@ -751,20 +746,21 @@ longlong Item_varbinary::val_int() } -bool Item_varbinary::save_in_field(Field *field) +int Item_varbinary::save_in_field(Field *field) { + int error; CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); field->set_notnull(); if (field->result_type() == STRING_RESULT) { - field->store(str_value.ptr(),str_value.length(),cs); + error=field->store(str_value.ptr(),str_value.length(),cs); } else { longlong nr=val_int(); - field->store(nr); + error=field->store(nr); } - return 0; + return (error) ? -1 : 0; } diff --git a/sql/item.h b/sql/item.h index 187e3903b84..a0b637b6030 100644 --- a/sql/item.h +++ b/sql/item.h @@ -53,7 +53,7 @@ public: void set_name(char* str,uint length=0); void init_make_field(Send_field *tmp_field,enum enum_field_types type); virtual bool fix_fields(THD *, struct st_table_list *, Item **); - virtual bool save_in_field(Field *field); + virtual int save_in_field(Field *field); virtual void save_org_in_field(Field *field) { (void) save_in_field(field); } virtual bool send(THD *thd, String *str); @@ -124,7 +124,7 @@ public: bool send(THD *thd, String *str_arg) { return result_field->send(thd,str_arg); } void make_field(Send_field *field); bool fix_fields(THD *, struct st_table_list *, Item **); - bool save_in_field(Field *field); + int save_in_field(Field *field); void save_org_in_field(Field *field); table_map used_tables() const; enum Item_result result_type () const @@ -149,7 +149,7 @@ public: longlong val_int(); String *val_str(String *str); void make_field(Send_field *field); - bool save_in_field(Field *field); + int save_in_field(Field *field); enum Item_result result_type () const { return STRING_RESULT; } bool send(THD *thd, String *str); @@ -178,7 +178,7 @@ public: longlong val_int(); String *val_str(String*); void make_field(Send_field *field); - bool save_in_field(Field *field); + int save_in_field(Field *field); void set_null(); void set_int(longlong i); void set_double(float i); @@ -215,7 +215,7 @@ public: double val() { return (double) value; } String *val_str(String*); void make_field(Send_field *field); - bool save_in_field(Field *field); + int save_in_field(Field *field); bool basic_const_item() const { return 1; } Item *new_item() { return new Item_int(name,value,max_length); } void print(String *str); @@ -254,7 +254,7 @@ public: max_length=length; } Item_real(double value_par) :value(value_par) {} - bool save_in_field(Field *field); + int save_in_field(Field *field); enum Type type() const { return REAL_ITEM; } double val() { return value; } longlong val_int() { return (longlong) (value+(value > 0 ? 0.5 : -0.5));} @@ -297,7 +297,7 @@ public: double val() { return atof(str_value.ptr()); } longlong val_int() { return strtoll(str_value.ptr(),(char**) 0,10); } String *val_str(String*) { return (String*) &str_value; } - bool save_in_field(Field *field); + int save_in_field(Field *field); void make_field(Send_field *field); enum Item_result result_type () const { return STRING_RESULT; } bool basic_const_item() const { return 1; } @@ -334,7 +334,7 @@ public: double val() { return (double) Item_varbinary::val_int(); } longlong val_int(); String *val_str(String*) { return &str_value; } - bool save_in_field(Field *field); + int save_in_field(Field *field); void make_field(Send_field *field); enum Item_result result_type () const { return INT_RESULT; } }; @@ -394,7 +394,7 @@ public: bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); } void make_field(Send_field *field) { (*ref)->make_field(field); } bool fix_fields(THD *, struct st_table_list *, Item **); - bool save_in_field(Field *field) { return (*ref)->save_in_field(field); } + int save_in_field(Field *field) { return (*ref)->save_in_field(field); } void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); } enum Item_result result_type () const { return (*ref)->result_type(); } table_map used_tables() const { return (*ref)->used_tables(); } @@ -413,7 +413,7 @@ class Item_int_with_ref :public Item_int public: Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg) {} - bool save_in_field(Field *field) + int save_in_field(Field *field) { return ref->save_in_field(field); } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0fc9a1f0e4c..084688f7d3d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -43,7 +43,8 @@ static bool convert_constant_item(Field *field, Item **item) { if ((*item)->const_item()) { - (*item)->save_in_field(field); + if ((*item)->save_in_field(field)) + return 0; if (!((*item)->null_value)) { Item *tmp=new Item_int_with_ref(field->val_int(), *item); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index b5b9ed2931e..594049b3870 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1915,7 +1915,7 @@ outp: } -bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables) +bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables, Item **ref) { char buff[STACK_BUFF_ALLOC]; // Max argument in function binary=0; @@ -1948,7 +1948,7 @@ String *Item_func_set_collation::val_str(String *str) return str; } -bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables) +bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, Item **ref) { char buff[STACK_BUFF_ALLOC]; // Max argument in function binary=0; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 7f82cd3b5de..becb7981acd 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -489,7 +489,7 @@ class Item_func_conv_charset :public Item_str_func public: Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) { conv_charset=cs; } - bool fix_fields(THD *thd,struct st_table_list *tables); + bool fix_fields(THD *thd,struct st_table_list *tables,Item **ref); String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "conv_charset"; } @@ -501,7 +501,7 @@ class Item_func_set_collation :public Item_str_func public: Item_func_set_collation(Item *a, CHARSET_INFO *cs) :Item_str_func(a) { set_collation=cs; } - bool fix_fields(THD *thd,struct st_table_list *tables); + bool fix_fields(THD *thd,struct st_table_list *tables, Item **ref); String *val_str(String *); void fix_length_and_dec() { diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 9bbb9e4fe19..297ff30bd9c 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -410,7 +410,7 @@ String *Item_date::val_str(String *str) } -bool Item_date::save_in_field(Field *field) +int Item_date::save_in_field(Field *field) { TIME ltime; timestamp_type t_type=TIMESTAMP_FULL; @@ -525,7 +525,7 @@ bool Item_func_now::get_date(TIME *res, } -bool Item_func_now::save_in_field(Field *to) +int Item_func_now::save_in_field(Field *to) { to->set_notnull(); to->store_time(<ime,TIMESTAMP_FULL); diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 53beb78e1d4..6d016df6eb7 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -228,7 +228,7 @@ public: double val() { return (double) val_int(); } const char *func_name() const { return "date"; } void fix_length_and_dec() { decimals=0; max_length=10; } - bool save_in_field(Field *to); + int save_in_field(Field *to); void make_field(Send_field *tmp_field) { init_make_field(tmp_field,FIELD_TYPE_DATE); @@ -311,7 +311,7 @@ public: enum Item_result result_type () const { return STRING_RESULT; } double val() { return (double) value; } longlong val_int() { return value; } - bool save_in_field(Field *to); + int save_in_field(Field *to); String *val_str(String *str) { str_value.set(buff,buff_length,default_charset_info); return &str_value; } const char *func_name() const { return "now"; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ccee7192682..3764ff2d55c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1028,7 +1028,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, field->cmp_type() != value->result_type()) DBUG_RETURN(0); - if (value->save_in_field(field)) + if (value->save_in_field(field) == 1) { if (type == Item_func::EQUAL_FUNC) { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b3ef043f582..6185b031c2e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2113,7 +2113,7 @@ fill_record(List &fields,List &values) while ((field=(Item_field*) f++)) { value=v++; - if (value->save_in_field(field->field)) + if (value->save_in_field(field->field) == 1) DBUG_RETURN(1); } DBUG_RETURN(0); @@ -2131,7 +2131,7 @@ fill_record(Field **ptr,List &values) while ((field = *ptr++)) { value=v++; - if (value->save_in_field(field)) + if (value->save_in_field(field) == 1) DBUG_RETURN(1); } DBUG_RETURN(0); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index a98012653b3..3668a817165 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -179,7 +179,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, Item *item; for (key_len=0 ; (item=it_ke++) ; key_part++) { - item->save_in_field(key_part->field); + (void) item->save_in_field(key_part->field); key_len+=key_part->store_length; } if (!(key= (byte*) sql_calloc(ALIGN_SIZE(key_len)))) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 76f78009e84..4e7dbd96127 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2478,7 +2478,7 @@ store_val_in_field(Field *field,Item *item) THD *thd=current_thd; ulong cuted_fields=thd->cuted_fields; thd->count_cuted_fields=1; - item->save_in_field(field); + (void) item->save_in_field(field); thd->count_cuted_fields=0; return cuted_fields != thd->cuted_fields; } diff --git a/sql/sql_select.h b/sql/sql_select.h index 3062747a08f..f651f069c13 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -338,7 +338,7 @@ public: {} bool copy() { - item->save_in_field(to_field); + (void) item->save_in_field(to_field); return err != 0; } const char *name() const { return "func"; } @@ -362,7 +362,7 @@ public: if (!inited) { inited=1; - item->save_in_field(to_field); + (void)item->save_in_field(to_field); } return err != 0; } diff --git a/sql/unireg.cc b/sql/unireg.cc index f2d8d6532a9..57a1407ea06 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -590,7 +590,7 @@ static bool make_empty_rec(File file,enum db_type table_type, if (field->def && (regfield->real_type() != FIELD_TYPE_YEAR || field->def->val_int() != 0)) - field->def->save_in_field(regfield); + (void) field->def->save_in_field(regfield); else if (regfield->real_type() == FIELD_TYPE_ENUM && (field->flags & NOT_NULL_FLAG)) { -- cgit v1.2.1 From 1895448e66b39542d58a77e705449b92414ff3f7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Aug 2002 17:33:44 +0500 Subject: Fix that this didn't work as far as sorting for ORDER BY was removed by optimizer: SELECT k FROM t1 GROUP BY k COLLATE latin1 ORDER BY k COLLATE latin1_de --- sql/item_strfunc.cc | 20 ++++++++++++++++++++ sql/item_strfunc.h | 1 + 2 files changed, 21 insertions(+) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 594049b3870..dc9d57b1d9d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1967,6 +1967,26 @@ bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, return 0; } +bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const +{ + /* Assume we don't have rtti */ + if (this == item) + return 1; + if (item->type() != FUNC_ITEM) + return 0; + Item_func *item_func=(Item_func*) item; + if (arg_count != item_func->arg_count || + func_name() != item_func->func_name()) + return 0; + Item_func_set_collation *item_func_sc=(Item_func_set_collation*) item; + if (set_collation != item_func_sc->set_collation) + return 0; + for (uint i=0; i < arg_count ; i++) + if (!args[i]->eq(item_func_sc->args[i], binary_cmp)) + return 0; + return 1; +} + String *Item_func_charset::val_str(String *str) { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index becb7981acd..997d9c8d834 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -508,6 +508,7 @@ public: max_length = args[0]->max_length; str_value.set_charset(set_collation); } + bool eq(const Item *item, bool binary_cmp) const; const char *func_name() const { return "set_collation"; } }; -- cgit v1.2.1 From c36c00632acf264e35e0b72fdf1756ae1f492d97 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Aug 2002 21:11:23 +0300 Subject: some small speed improvements after my last changes. I know I should have waited for Monty's merge ... --- sql/opt_range.cc | 2 +- sql/sql_base.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 3764ff2d55c..a99a701e4b4 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1028,7 +1028,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, field->cmp_type() != value->result_type()) DBUG_RETURN(0); - if (value->save_in_field(field) == 1) + if (value->save_in_field(field) > 0) { if (type == Item_func::EQUAL_FUNC) { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 6185b031c2e..080a521cc91 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2113,7 +2113,7 @@ fill_record(List &fields,List &values) while ((field=(Item_field*) f++)) { value=v++; - if (value->save_in_field(field->field) == 1) + if (value->save_in_field(field->field) > 0) DBUG_RETURN(1); } DBUG_RETURN(0); -- cgit v1.2.1 From 3fbcafea9c5e85dc6315f0b89872ac5e273195c8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Sep 2002 09:50:36 +0300 Subject: subselect with union new error handling Item_ref bug fixed include/mysql_com.h: new error handling query cache pointer description mysql-test/r/distinct.result: new result's after Monty's bug fixing mysql-test/r/subselect.result: subselect with union test mysql-test/t/subselect.test: subselect with union test sql/item.cc: subselect with union Item_ref bug fixed sql/item_cmpfunc.cc: Monty's bug fixing sql/item_subselect.cc: TODO changing subselect with union sql/item_subselect.h: subselect with union sql/mysql_priv.h: Item_ref bug fixed sql/mysqld.cc: new error handling sql/net_pkg.cc: new error handling sql/net_serv.cc: new error handling sql/sql_base.cc: Item_ref bug fixed sql/sql_class.cc: new error handling sql/sql_class.h: new error handling sql/sql_derived.cc: subselect with union sql/sql_insert.cc: new error handling (only with mysql_select now) sql/sql_lex.cc: subselect with union sql/sql_lex.h: subselect with union sql/sql_parse.cc: new error handling sql/sql_select.cc: new error handling subselect with union removed thd->where=0 hack sql/sql_select.h: subselect with union sql/sql_union.cc: subselect with union sql/sql_update.cc: new error handling (only with mysql_select now) sql/sql_yacc.yy: subselect with union --- sql/item.cc | 25 ++-- sql/item_cmpfunc.cc | 2 + sql/item_subselect.cc | 214 +++++++++++++++++++++++----------- sql/item_subselect.h | 125 ++++++++++++++------ sql/mysql_priv.h | 7 +- sql/mysqld.cc | 3 +- sql/net_pkg.cc | 5 +- sql/net_serv.cc | 37 +++--- sql/sql_base.cc | 36 +++--- sql/sql_class.cc | 48 ++++---- sql/sql_class.h | 4 +- sql/sql_derived.cc | 2 +- sql/sql_insert.cc | 2 + sql/sql_lex.cc | 9 +- sql/sql_lex.h | 32 +++++- sql/sql_parse.cc | 20 ++-- sql/sql_select.cc | 69 ++++++----- sql/sql_select.h | 4 +- sql/sql_union.cc | 312 ++++++++++++++++++++++++++++++-------------------- sql/sql_update.cc | 3 + sql/sql_yacc.yy | 10 +- 21 files changed, 621 insertions(+), 348 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 81c5168b72d..47171206e3d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -457,7 +457,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (!field) // If field is not checked { Field *tmp; - if (!(tmp=find_field_in_tables(thd,this,tables))) + if (!(tmp=find_field_in_tables(thd, this, tables, 0))) { /* We can't find table field in table list of current select, @@ -473,9 +473,14 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) sl && !tmp; sl= sl->outer_select()) tmp=find_field_in_tables(thd, this, - (TABLE_LIST*)(last= sl)->table_list.first); + (TABLE_LIST*)(last= sl)->table_list.first, + 0); if (!tmp) - return 1; + { + // Call to produce appropriate error message + find_field_in_tables(thd, this, tables, 1); + return -1; + } else { depended_from= last; @@ -488,7 +493,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) s= s->outer_select()) if( !s->depended ) { - s->depended= 1; //Select is depended of outer select + // Select is depended of outer select + s->depended= s->master_unit()->depended= 1; //Tables will be reopened many times for (TABLE_LIST *tbl= (TABLE_LIST*)s->table_list.first; @@ -803,7 +809,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { if (!ref) { - if (!(ref= find_item_in_list(this,thd->lex.select->item_list))) + if (!(ref= find_item_in_list(this, thd->lex.select->item_list, 0))) { /* We can't find table field in table list of current select, @@ -818,9 +824,13 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) for (SELECT_LEX *sl= thd->lex.select->outer_select(); sl && !ref; sl= sl->outer_select()) - ref= find_item_in_list(this, (last= sl)->item_list); + ref= find_item_in_list(this, (last= sl)->item_list, 0); if (!ref) + { + // Call to report error + find_item_in_list(this, thd->lex.select->item_list, 1); return 1; + } else { depended_from= last; @@ -833,7 +843,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) s= s->outer_select()) if( !s->depended ) { - s->depended= 1; //Select is depended of outer select + // Select is depended of outer select + s->depended= s->master_unit()->depended= 1; //Tables will be reopened many times for (TABLE_LIST *tbl= (TABLE_LIST*)s->table_list.first; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0fc9a1f0e4c..d1a130aa12b 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1101,6 +1101,8 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) used_tables_cache|=item->used_tables(); with_sum_func= with_sum_func || item->with_sum_func; const_item_cache&=item->const_item(); + if (item->maybe_null) + maybe_null=1; } if (thd) thd->cond_count+=list.elements; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 2bff2af45e4..18e9f51925a 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -23,9 +23,6 @@ SUBSELECT TODO: - remove double 'having' & 'having_list' from JOIN (sql_select.h/sql_select.cc) - - subselect in HAVING clause - - add subselect union select (sql_union.cc) - */ #ifdef __GNUC__ @@ -37,21 +34,17 @@ SUBSELECT TODO: Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex, select_subselect *result): - assigned(0), executed(0), optimized(0), error(0) + engine_owner(1), value_assigned(0) { DBUG_ENTER("Item_subselect::Item_subselect"); DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex)); - this->result= result; - SELECT_LEX_UNIT *unit= select_lex->master_unit(); - unit->offset_limit_cnt= unit->global_parameters->offset_limit; - unit->select_limit_cnt= unit->global_parameters->select_limit+ - unit->global_parameters ->offset_limit; - if (unit->select_limit_cnt < unit->global_parameters->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // no limit - if (unit->select_limit_cnt == HA_POS_ERROR) - select_lex->options&= ~OPTION_FOUND_ROWS; - join= new JOIN(thd, select_lex->item_list, select_lex->options, result); - this->select_lex= select_lex; + + if (select_lex->next_select()) + engine= new subselect_union_engine(thd, select_lex->master_unit(), result, + this); + else + engine= new subselect_single_select_engine(thd, select_lex, result, + this); assign_null(); /* item value is NULL if select_subselect not changed this value @@ -61,6 +54,12 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex, DBUG_VOID_RETURN; } +Item_subselect::~Item_subselect() +{ + if (engine_owner) + delete engine; +} + void Item_subselect::make_field (Send_field *tmp_field) { if (null_value) @@ -78,62 +77,17 @@ void Item_subselect::make_field (Send_field *tmp_field) bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { // Is it one field subselect? - if (select_lex->item_list.elements > max_columns) + if (engine->cols() > max_columns) { - my_printf_error(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0)); + my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0)); return 1; } - SELECT_LEX *save_select= thd->lex.select; - thd->lex.select= select_lex; - if(join->prepare((TABLE_LIST*) select_lex->table_list.first, - select_lex->where, - (ORDER*) select_lex->order_list.first, - (ORDER*) select_lex->group_list.first, - select_lex->having, - (ORDER*) 0, select_lex, - select_lex->master_unit())) - return 1; - thd->lex.select= save_select; - return 0; -} - -int Item_subselect::exec() -{ - DBUG_ENTER("Item_subselect::exec"); - if (!optimized) - { - optimized=1; - if (join->optimize()) - { - executed= 1; - DBUG_RETURN(join->error?join->error:1); - } - } - if (join->select_lex->depended && executed) - { - if (join->reinit()) - { - error= 1; - DBUG_RETURN(1); - } - assign_null(); - executed= assigned= 0; - } - if (!executed) - { - SELECT_LEX *save_select= join->thd->lex.select; - join->thd->lex.select= select_lex; - join->exec(); - join->thd->lex.select= save_select; - executed= 1; - DBUG_RETURN(join->error); - } - DBUG_RETURN(0); + return engine->prepare(); } inline table_map Item_subselect::used_tables() const { - return (table_map) select_lex->depended ? 1L : 0L; + return (table_map) engine->depended() ? 1L : 0L; } Item_singleval_subselect::Item_singleval_subselect(THD *thd, @@ -151,21 +105,21 @@ Item::Type Item_subselect::type() const double Item_singleval_subselect::val () { - if (exec()) + if (engine->exec()) return 0; return real_value; } longlong Item_singleval_subselect::val_int () { - if (exec()) + if (engine->exec()) return 0; return int_value; } String *Item_singleval_subselect::val_str (String *str) { - if (exec() || null_value) + if (engine->exec() || null_value) return 0; return &str_value; } @@ -183,23 +137,143 @@ Item_exists_subselect::Item_exists_subselect(THD *thd, double Item_exists_subselect::val () { - if (exec()) + if (engine->exec()) return 0; return (double) value; } longlong Item_exists_subselect::val_int () { - if (exec()) + if (engine->exec()) return 0; return value; } String *Item_exists_subselect::val_str(String *str) { - if (exec()) + if (engine->exec()) return 0; str->set(value); return str; } + +subselect_single_select_engine::subselect_single_select_engine(THD *thd, + st_select_lex *select, + select_subselect *result, + Item_subselect *item): + subselect_engine(thd, item, result), + executed(0), optimized(0) +{ + select_lex= select; + SELECT_LEX_UNIT *unit= select_lex->master_unit(); + unit->offset_limit_cnt= unit->global_parameters->offset_limit; + unit->select_limit_cnt= unit->global_parameters->select_limit+ + unit->global_parameters ->offset_limit; + if (unit->select_limit_cnt < unit->global_parameters->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; // no limit + if (unit->select_limit_cnt == HA_POS_ERROR) + select_lex->options&= ~OPTION_FOUND_ROWS; + join= new JOIN(thd, select_lex->item_list, select_lex->options, result); + if (!join || !result) + { + //out of memory + thd->fatal_error= 1; + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); + } + this->select_lex= select_lex; +} + +subselect_union_engine::subselect_union_engine(THD *thd, + st_select_lex_unit *u, + select_subselect *result, + Item_subselect *item): + subselect_engine(thd, item, result) +{ + unit= u; + if( !result) + { + //out of memory + thd->fatal_error= 1; + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); + } + unit->item= item; +} + +int subselect_single_select_engine::prepare() +{ + SELECT_LEX *save_select= thd->lex.select; + thd->lex.select= select_lex; + if(join->prepare((TABLE_LIST*) select_lex->table_list.first, + select_lex->where, + (ORDER*) select_lex->order_list.first, + (ORDER*) select_lex->group_list.first, + select_lex->having, + (ORDER*) 0, select_lex, + select_lex->master_unit(), 0)) + return 1; + thd->lex.select= save_select; + return 0; +} + +int subselect_union_engine::prepare() +{ + return unit->prepare(thd, result); +} + + +int subselect_single_select_engine::exec() +{ + DBUG_ENTER("subselect_single_select_engine::exec"); + if (!optimized) + { + optimized=1; + if (join->optimize()) + { + executed= 1; + DBUG_RETURN(join->error?join->error:1); + } + } + if (select_lex->depended && executed) + { + if (join->reinit()) + DBUG_RETURN(1); + item->assign_null(); + item->assigned((executed= 0)); + } + if (!executed) + { + SELECT_LEX *save_select= join->thd->lex.select; + join->thd->lex.select= select_lex; + join->exec(); + join->thd->lex.select= save_select; + executed= 1; + DBUG_RETURN(join->error||thd->fatal_error); + } + DBUG_RETURN(0); +} + +int subselect_union_engine::exec() +{ + return unit->exec(); +} + +uint subselect_single_select_engine::cols() +{ + return select_lex->item_list.elements; +} + +uint subselect_union_engine::cols() +{ + return unit->first_select()->item_list.elements; +} + +bool subselect_single_select_engine::depended() +{ + return select_lex->depended; +} + +bool subselect_union_engine::depended() +{ + return unit->depended; +} diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 3f363df33df..0d8495d3ae8 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -20,31 +20,25 @@ #pragma interface /* gcc class implementation */ #endif -struct st_select_lex; +class st_select_lex; +class st_select_lex_unit; class JOIN; class select_subselect; +class subselect_engine; /* base class for subselects */ class Item_subselect :public Item { + my_bool engine_owner; /* Is this item owner of engine */ + my_bool value_assigned; /* value already assigned to subselect */ protected: + /* engine that perform execution of subselect (single select or union) */ + subselect_engine *engine; + /* allowed number of columns (1 for single value subqueries) */ uint max_columns; - my_bool assigned; /* value already assigned to subselect */ - my_bool executed; /* simple subselect is executed */ - my_bool optimized; /* simple subselect is optimized */ - my_bool error; /* error in query */ - int exec(); - virtual void assign_null() - { - null_value= 1; - } public: - st_select_lex *select_lex; - JOIN *join; - select_subselect *result; - Item_subselect(THD *thd, st_select_lex *select_lex, select_subselect* result); Item_subselect(Item_subselect *item) @@ -52,14 +46,17 @@ public: null_value= item->null_value; decimals= item->decimals; max_columns= item->max_columns; - assigned= item->assigned; - executed= item->executed; - select_lex= item->select_lex; - join= item->join; - result= item->result; + engine= item->engine; + engine_owner= 0; name= item->name; - error= item->error; } + ~Item_subselect(); + virtual void assign_null() + { + null_value= 1; + } + bool assigned() { return value_assigned; } + void assigned(bool a) { value_assigned= a; } enum Type type() const; bool is_null() { return null_value; } void make_field (Send_field *); @@ -75,18 +72,10 @@ public: class Item_singleval_subselect :public Item_subselect { protected: - longlong int_value; - double real_value; - enum Item_result res_type; + longlong int_value; /* here stored integer value of this item */ + double real_value; /* here stored real value of this item */ + enum Item_result res_type; /* type of results */ - virtual void assign_null() - { - null_value= 1; - int_value= 0; - real_value= 0; - max_length= 4; - res_type= STRING_RESULT; - } public: Item_singleval_subselect(THD *thd, st_select_lex *select_lex); Item_singleval_subselect(Item_singleval_subselect *item): @@ -98,6 +87,14 @@ public: decimals= item->decimals; res_type= item->res_type; } + virtual void assign_null() + { + null_value= 1; + int_value= 0; + real_value= 0; + max_length= 4; + res_type= STRING_RESULT; + } double val (); longlong val_int (); String *val_str (String *); @@ -112,12 +109,8 @@ public: class Item_exists_subselect :public Item_subselect { protected: - longlong value; + longlong value; /* value of this item (boolean: exists/not-exists) */ - virtual void assign_null() - { - value= 0; - } public: Item_exists_subselect(THD *thd, st_select_lex *select_lex); Item_exists_subselect(Item_exists_subselect *item): @@ -125,6 +118,11 @@ public: { value= item->value; } + virtual void assign_null() + { + value= 0; + } + Item *new_item() { return new Item_exists_subselect(this); } enum Item_result result_type() const { return INT_RESULT;} longlong val_int(); @@ -133,3 +131,58 @@ public: friend class select_exists_subselect; }; + +class subselect_engine +{ +protected: + select_subselect *result; /* results storage class */ + THD *thd; /* pointer to current THD */ + Item_subselect *item; /* item, that use this engine */ +public: + static void *operator new(size_t size) + { + return (void*) sql_alloc((uint) size); + } + static void operator delete(void *ptr, size_t size) {} + + subselect_engine(THD *thd, Item_subselect *si, select_subselect *res) + { + result= res; + item= si; + this->thd= thd; + } + virtual int prepare()= 0; + virtual int exec()= 0; + virtual uint cols()= 0; /* return number of columnss in select */ + virtual bool depended()= 0; /* depended from outer select */ +}; + +class subselect_single_select_engine: public subselect_engine +{ + my_bool executed; /* simple subselect is executed */ + my_bool optimized; /* simple subselect is optimized */ + st_select_lex *select_lex; /* corresponding select_lex */ + JOIN * join; /* corresponding JOIN structure */ +public: + subselect_single_select_engine(THD *thd, st_select_lex *select, + select_subselect *result, + Item_subselect *item); + virtual int prepare(); + virtual int exec(); + virtual uint cols(); + virtual bool depended(); +}; + +class subselect_union_engine: public subselect_engine +{ + st_select_lex_unit *unit; /* corresponding unit structure */ +public: + subselect_union_engine(THD *thd, + st_select_lex_unit *u, + select_subselect *result, + Item_subselect *item); + virtual int prepare(); + virtual int exec(); + virtual uint cols(); + virtual bool depended(); +}; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c0371d1e90c..155d056db42 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -373,7 +373,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result); int mysql_select(THD *thd,TABLE_LIST *tables,List &list,COND *conds, ORDER *order, ORDER *group,Item *having,ORDER *proc_param, ulong select_type,select_result *result, - SELECT_LEX_UNIT *unit); + SELECT_LEX_UNIT *unit, bool fake_select_lex); int mysql_union(THD *thd, LEX *lex,select_result *result); int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, @@ -438,7 +438,8 @@ bool wait_for_tables(THD *thd); bool table_is_used(TABLE *table, bool wait_for_name_lock); bool drop_locked_tables(THD *thd,const char *db, const char *table_name); void abort_locked_tables(THD *thd,const char *db, const char *table_name); -Field *find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables); +Field *find_field_in_tables(THD *thd, Item_field *item, TABLE_LIST *tables, + bool report_error); Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, bool check_grant,bool allow_rowid); #ifdef HAVE_OPENSSL @@ -526,7 +527,7 @@ TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find); SQL_SELECT *make_select(TABLE *head, table_map const_tables, table_map read_tables, COND *conds, int *error); -Item ** find_item_in_list(Item *item,List &items); +Item ** find_item_in_list(Item *item, List &items, bool report_error); bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator *it); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 98bfa162242..830c7324771 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1608,8 +1608,9 @@ static int my_message_sql(uint error, const char *str, NET *net; DBUG_ENTER("my_message_sql"); DBUG_PRINT("error",("Message: '%s'",str)); - if ((net=my_pthread_getspecific_ptr(NET*,THR_NET))) + if ((net= my_pthread_getspecific_ptr(NET*,THR_NET))) { + net->report_error= 1; if (!net->last_error[0]) // Return only first message { strmake(net->last_error,str,sizeof(net->last_error)-1); diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index fa3abc68bfa..5551e2b19bc 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -72,7 +72,10 @@ void send_error(NET *net, uint sql_errno, const char *err) } VOID(net_write_command(net,(uchar) 255,(char*) err,length)); if (thd) - thd->fatal_error=0; // Error message is given + { + thd->fatal_error= 0; // Error message is given + thd->net.report_error= 0; + } DBUG_VOID_RETURN; } diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 0d6e548a873..abda5a3c275 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -113,6 +113,7 @@ int my_net_init(NET *net, Vio* vio) net->where_b = net->remain_in_buf=0; net->last_errno=0; net->query_cache_query=0; + net->report_error= 0; if (vio != 0) /* If real connection */ { @@ -141,8 +142,9 @@ static my_bool net_realloc(NET *net, ulong length) if (length >= max_allowed_packet) { DBUG_PRINT("error",("Packet too large (%lu)", length)); - net->error=1; - net->last_errno=ER_NET_PACKET_TOO_LARGE; + net->error= 1; + net->report_error= 1; + net->last_errno= ER_NET_PACKET_TOO_LARGE; return 1; } pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); @@ -152,9 +154,10 @@ static my_bool net_realloc(NET *net, ulong length) NET_HEADER_SIZE + COMP_HEADER_SIZE, MYF(MY_WME)))) { - net->error=1; + net->error= 1; + net->report_error= 1; #ifdef MYSQL_SERVER - net->last_errno=ER_OUT_OF_RESOURCES; + net->last_errno= ER_OUT_OF_RESOURCES; #endif return 1; } @@ -348,10 +351,12 @@ net_real_write(NET *net,const char *packet,ulong len) COMP_HEADER_SIZE, MYF(MY_WME)))) { #ifdef MYSQL_SERVER - net->last_errno=ER_OUT_OF_RESOURCES; - net->error=2; + net->last_errno= ER_OUT_OF_RESOURCES; + net->error= 2; + //TODO is it needed to set this variable if we have no socket + net->report_error= 1; #endif - net->reading_or_writing=0; + net->reading_or_writing= 0; DBUG_RETURN(1); } memcpy(b+header_length,packet,len); @@ -401,7 +406,8 @@ net_real_write(NET *net,const char *packet,ulong len) "%s: my_net_write: fcntl returned error %d, aborting thread\n", my_progname,vio_errno(net->vio)); #endif /* EXTRA_DEBUG */ - net->error=2; /* Close socket */ + net->error= 2; /* Close socket */ + net->report_error= 1; goto end; } } @@ -428,7 +434,8 @@ net_real_write(NET *net,const char *packet,ulong len) continue; } #endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */ - net->error=2; /* Close socket */ + net->error= 2; /* Close socket */ + net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE); @@ -562,9 +569,10 @@ my_real_read(NET *net, ulong *complen) my_progname,vio_errno(net->vio)); #endif /* EXTRA_DEBUG */ len= packet_error; - net->error=2; /* Close socket */ + net->error= 2; /* Close socket */ + net->report_error= 1; #ifdef MYSQL_SERVER - net->last_errno=ER_NET_FCNTL_ERROR; + net->last_errno= ER_NET_FCNTL_ERROR; #endif goto end; } @@ -593,7 +601,8 @@ my_real_read(NET *net, ulong *complen) #endif DBUG_PRINT("error",("Couldn't read packet: remain: %lu errno: %d length: %ld alarmed: %d", remain,vio_errno(net->vio),length,alarmed)); len= packet_error; - net->error=2; /* Close socket */ + net->error= 2; /* Close socket */ + net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno= (interrupted ? ER_NET_READ_INTERRUPTED : ER_NET_READ_ERROR); @@ -622,6 +631,7 @@ my_real_read(NET *net, ulong *complen) #endif } len= packet_error; + net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER; #endif @@ -794,7 +804,8 @@ my_net_read(NET *net) if (my_uncompress((byte*) net->buff + net->where_b, &packet_len, &complen)) { - net->error=2; /* caller will close socket */ + net->error= 2; /* caller will close socket */ + net->report_error= 1; #ifdef MYSQL_SERVER net->last_errno=ER_NET_UNCOMPRESS_ERROR; #endif diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b3ef043f582..95f9e15331f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1711,7 +1711,8 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, Field * -find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) +find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables, + bool report_error) { Field *found=0; const char *db=item->db_name; @@ -1748,7 +1749,7 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) } if (found) return found; - if (!found_table) + if (!found_table && report_error) { char buff[NAME_LEN*2+1]; if (db) @@ -1760,8 +1761,9 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) thd->where); } else - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), - item->full_name(),thd->where); + if (report_error) + my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), + item->full_name(),thd->where); return (Field*) 0; } bool allow_rowid= tables && !tables->next; // Only one table @@ -1778,8 +1780,9 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) { if (!thd->where) // Returns first found break; - my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), - name,thd->where); + if (report_error) + my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), + name,thd->where); return (Field*) 0; } found=field; @@ -1787,13 +1790,14 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) } if (found) return found; - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR), - MYF(0),item->full_name(),thd->where); + if (report_error) + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), + MYF(0), item->full_name(), thd->where); return (Field*) 0; } Item ** -find_item_in_list(Item *find,List &items) +find_item_in_list(Item *find,List &items, bool report_error) { List_iterator li(items); Item **found=0,*item; @@ -1841,9 +1845,9 @@ find_item_in_list(Item *find,List &items) break; } } - if (!found && current_thd->where) - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), - find->full_name(),current_thd->where); + if (!found && report_error) + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), + find->full_name(), current_thd->where); return found; } @@ -2303,8 +2307,8 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, int setup_ftfuncs(THD *thd) { - List_iterator li(thd->lex.select->ftfunc_list), - lj(thd->lex.select->ftfunc_list); + List_iterator li(*(thd->lex.select->ftfunc_list)), + lj(*(thd->lex.select->ftfunc_list)); Item_func_match *ftf, *ftf2; while ((ftf=li++)) @@ -2324,9 +2328,9 @@ int setup_ftfuncs(THD *thd) int init_ftfuncs(THD *thd, bool no_order) { - if (thd->lex.select->ftfunc_list.elements) + if (thd->lex.select->ftfunc_list->elements) { - List_iterator li(thd->lex.select->ftfunc_list); + List_iterator li(*(thd->lex.select->ftfunc_list)); Item_func_match *ifm; DBUG_PRINT("info",("Performing FULLTEXT search")); thd->proc_info="FULLTEXT initialization"; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9922eacdec1..b84bcf1df72 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -407,13 +407,19 @@ bool select_send::send_data(List &items) if (item->send(thd, packet)) { packet->free(); // Free used - my_error(ER_OUT_OF_RESOURCES,MYF(0)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); DBUG_RETURN(1); } } thd->sent_row_count++; - bool error=my_net_write(&thd->net,(char*) packet->ptr(),packet->length()); - DBUG_RETURN(error); + if (!thd->net.report_error) + { + DBUG_RETURN(my_net_write(&thd->net, + (char*) packet->ptr(), + packet->length())); + } + else + DBUG_RETURN(1); } bool select_send::send_eof() @@ -423,8 +429,13 @@ bool select_send::send_eof() { mysql_unlock_tables(thd, thd->lock); thd->lock=0; } - ::send_eof(&thd->net); - return 0; + if (!thd->net.report_error) + { + ::send_eof(&thd->net); + return 0; + } + else + return 1; } @@ -460,7 +471,7 @@ select_export::prepare(List &list, SELECT_LEX_UNIT *u) option); if (!access(path,F_OK)) { - my_error(ER_FILE_EXISTS_ERROR,MYF(0),exchange->file_name); + my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name); return 1; } /* Create the file world readable */ @@ -646,9 +657,9 @@ err: } -void select_export::send_error(uint errcode,const char *err) +void select_export::send_error(uint errcode, const char *err) { - ::send_error(&thd->net,errcode,err); + my_message(errcode, err, MYF(0));; (void) end_io_cache(&cache); (void) my_close(file,MYF(0)); file= -1; @@ -660,9 +671,7 @@ bool select_export::send_eof() int error=test(end_io_cache(&cache)); if (my_close(file,MYF(MY_WME))) error=1; - if (error) - ::send_error(&thd->net); - else + if (!error) ::send_ok(&thd->net,row_count); file= -1; return error; @@ -735,7 +744,7 @@ bool select_dump::send_data(List &items) } if (row_count++ > 1) { - my_error(ER_TOO_MANY_ROWS,MYF(0)); + my_error(ER_TOO_MANY_ROWS, MYF(0)); goto err; } while ((item=li++)) @@ -760,7 +769,7 @@ err: void select_dump::send_error(uint errcode,const char *err) { - ::send_error(&thd->net,errcode,err); + my_message(errcode, err, MYF(0)); (void) end_io_cache(&cache); (void) my_close(file,MYF(0)); (void) my_delete(path,MYF(0)); // Delete file on error @@ -772,9 +781,7 @@ bool select_dump::send_eof() int error=test(end_io_cache(&cache)); if (my_close(file,MYF(MY_WME))) error=1; - if (error) - ::send_error(&thd->net); - else + if (!error) ::send_ok(&thd->net,row_count); file= -1; return error; @@ -789,8 +796,9 @@ bool select_singleval_subselect::send_data(List &items) { DBUG_ENTER("select_singleval_subselect::send_data"); Item_singleval_subselect *it= (Item_singleval_subselect *)item; - if (it->assigned){ - my_printf_error(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0)); + if (it->assigned()){ + thd->fatal_error= 1; + my_message(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0)); DBUG_RETURN(1); } if (unit->offset_limit_cnt) @@ -816,7 +824,7 @@ bool select_singleval_subselect::send_data(List &items) it->int_value= val_item->val_int(); it->res_type= val_item->result_type(); } - it->assigned= 1; + it->assigned(1); DBUG_RETURN(0); } @@ -830,7 +838,7 @@ bool select_exists_subselect::send_data(List &items) DBUG_RETURN(0); } it->value= 1; - it->assigned= 1; + it->assigned(1); DBUG_RETURN(0); } diff --git a/sql/sql_class.h b/sql/sql_class.h index a6b7e45ab03..82241f0ff1f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -453,7 +453,7 @@ public: bool query_error, bootstrap, cleanup_done; bool safe_to_cache_query; bool volatile killed; - bool prepare_command; + bool prepare_command; ulong param_count,current_param_number; Error err_list; Error warn_list; @@ -621,7 +621,7 @@ public: virtual void initialize_tables (JOIN *join=0) {} virtual void send_error(uint errcode,const char *err) { - ::send_error(&thd->net,errcode,err); + my_message(errcode, err, MYF(0)); } virtual bool send_eof()=0; virtual void abort() {} diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index fb40a85fd91..cde120f3774 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -99,7 +99,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) (ORDER*) sl->group_list.first, sl->having, (ORDER*) NULL, sl->options | thd->options | SELECT_NO_UNLOCK, - derived_result, unit); + derived_result, unit, 0); if (!res) { // Here we entirely fix both TABLE_LIST and list of SELECT's as there were no derived tables diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index c3aeca1fff8..ea949e9eb99 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1331,6 +1331,7 @@ bool select_insert::send_data(List &values) void select_insert::send_error(uint errcode,const char *err) { + //TODO error should be sent at the query processing end ::send_error(&thd->net,errcode,err); table->file->extra(HA_EXTRA_NO_CACHE); table->file->activate_all_index(thd); @@ -1357,6 +1358,7 @@ bool select_insert::send_eof() if (error) { table->file->print_error(error,MYF(0)); + //TODO error should be sent at the query processing end ::send_error(&thd->net); return 1; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 9ae5cdeeb15..7e6e2524400 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -146,7 +146,8 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->length=0; lex->select->in_sum_expr=0; lex->select->expr_list.empty(); - lex->select->ftfunc_list.empty(); + lex->select->ftfunc_list_alloc.empty(); + lex->select->ftfunc_list= &lex->select->ftfunc_list_alloc; lex->convert_set=(lex->thd=thd)->convert_set; lex->yacc_yyss=lex->yacc_yyvs=0; lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE); @@ -918,6 +919,8 @@ void st_select_lex_unit::init_query() global_parameters= this; select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; + optimized= 0; + item= 0; } void st_select_lex::init_query() @@ -941,9 +944,11 @@ void st_select_lex::init_select() expr_list.empty(); interval_list.empty(); use_index.empty(); - ftfunc_list.empty(); + ftfunc_list_alloc.empty(); + ftfunc_list= &ftfunc_list_alloc; linkage= UNSPECIFIED_TYPE; depended= having_fix_field= 0; + } /* diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 470230c0999..26b59207f5d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -216,7 +216,22 @@ private: */ class st_lex; class st_select_lex; +class THD; +class select_result; +class JOIN; +class select_union; class st_select_lex_unit: public st_select_lex_node { +protected: + List item_list; + List joins; /* list of *JOINs, to delete it in cleanup() */ + TABLE_LIST result_table_list; + select_union *union_result; + TABLE *table; /* temporary table using for appending UNION results */ + THD *thd; + select_result *result; + int res; + bool describe, found_rows_for_union, + optimized; // optimize phase already performed for UNION (unit) public: /* Pointer to 'last' select or pointer to unit where stored @@ -225,12 +240,21 @@ public: st_select_lex_node *global_parameters; /* LIMIT clause runtime counters */ ha_rows select_limit_cnt, offset_limit_cnt; + bool depended; /* depended from outer select subselect */ + /* not NULL if union used in subselect, point to subselect item */ + Item_subselect *item; + void init_query(); bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result); st_select_lex* outer_select() { return (st_select_lex*) master; } st_select_lex* first_select() { return (st_select_lex*) slave; } st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; } + /* UNION methods */ + int prepare(THD *thd, select_result *result); + int exec(); + int cleanup(); + friend void mysql_init_query(THD *thd); private: bool create_total_list_n_last_return(THD *thd, st_lex *lex, @@ -241,7 +265,6 @@ typedef struct st_select_lex_unit SELECT_LEX_UNIT; /* SELECT_LEX - store information of parsed SELECT_LEX statment */ -class JOIN; class st_select_lex: public st_select_lex_node { public: char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */ @@ -252,7 +275,12 @@ public: List item_list; /* list of fields & expressions */ List interval_list, use_index, *use_index_ptr, ignore_index, *ignore_index_ptr; - List ftfunc_list; + /* + Usualy it is pointer to ftfunc_list_alloc, but in union used to create fake + select_lex for calling mysql_select under results of union + */ + List *ftfunc_list; + List ftfunc_list_alloc; JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */ uint in_sum_expr; bool create_refs, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e006855105c..49a961c1a78 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -665,7 +665,7 @@ pthread_handler_decl(handle_one_connection,arg) if (thd->user_connect) decrease_user_connections(thd->user_connect); free_root(&thd->mem_root,MYF(0)); - if (net->error && net->vio != 0) + if (net->error && net->vio != 0 && net->report_error) { if (!thd->killed && opt_warnings) sql_print_error(ER(ER_NEW_ABORTING_CONNECTION), @@ -1169,6 +1169,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } case COM_PING: + DBUG_PRINT("info", ("query: PING")); thread_safe_increment(com_other,&LOCK_thread_count); send_ok(net); // Tell client we are alive break; @@ -1257,6 +1258,7 @@ mysql_execute_command(void) SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); + thd->net.report_error= 0; if (thd->slave_thread) { /* @@ -1864,7 +1866,7 @@ mysql_execute_command(void) (ORDER *)NULL, select_lex->options | thd->options | SELECT_NO_JOIN_CACHE, - result, unit); + result, unit, 0); delete result; } else @@ -2029,13 +2031,13 @@ mysql_execute_command(void) lex->lock_option, table_count))) { - res=mysql_select(thd,tables,select_lex->item_list, - select_lex->where, - (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL, - (ORDER *)NULL, - select_lex->options | thd->options | - SELECT_NO_JOIN_CACHE, - result, unit); + res= mysql_select(thd,tables,select_lex->item_list, + select_lex->where, + (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL, + (ORDER *)NULL, + select_lex->options | thd->options | + SELECT_NO_JOIN_CACHE, + result, unit, 0); delete result; } else diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 76f78009e84..690270d6407 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -178,9 +178,14 @@ int handle_select(THD *thd, LEX *lex, select_result *result) select_lex->having, (ORDER*) lex->proc_list.first, select_lex->options | thd->options, - result, &(lex->unit)); + result, &(lex->unit), 0); if (res && result) result->abort(); + if (res || thd->net.report_error) + { + send_error(&thd->net, 0, MYF(0)); + res= 1; + } delete result; return res; } @@ -198,9 +203,10 @@ int handle_select(THD *thd, LEX *lex, select_result *result) */ int JOIN::prepare(TABLE_LIST *tables_init, - COND *conds_init, ORDER *order_init, ORDER *group_init, - Item *having_init, - ORDER *proc_param_init, SELECT_LEX *select, SELECT_LEX_UNIT *unit) + COND *conds_init, ORDER *order_init, ORDER *group_init, + Item *having_init, + ORDER *proc_param_init, SELECT_LEX *select, + SELECT_LEX_UNIT *unit, bool fake_select_lex) { DBUG_ENTER("JOIN::prepare"); @@ -211,7 +217,8 @@ JOIN::prepare(TABLE_LIST *tables_init, proc_param= proc_param_init; tables_list= tables_init; select_lex= select; - select->join= this; + if (!fake_select_lex) + select->join= this; union_part= (unit->first_select()->next_select() != 0); /* Check that all tables, fields, conds and order are ok */ @@ -231,7 +238,7 @@ JOIN::prepare(TABLE_LIST *tables_init, select_lex->having_fix_field= 1; bool having_fix_rc= having->fix_fields(thd, tables_list, &having); select_lex->having_fix_field= 0; - if (having_fix_rc || thd->fatal_error) + if (having_fix_rc || thd->net.report_error) DBUG_RETURN(-1); /* purecov: inspected */ if (having->with_sum_func) having->split_sum_func(all_fields); @@ -538,7 +545,7 @@ JOIN::optimize() make_join_readinfo(this, (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | - (thd->lex.select->ftfunc_list.elements ? + (thd->lex.select->ftfunc_list->elements ? SELECT_NO_JOIN_CACHE : 0)); /* Need to tell Innobase that to play it safe, it should fetch all @@ -650,16 +657,16 @@ JOIN::exec() result->send_fields(fields_list,1); if (!having || having->val_int()) { - if (do_send_rows && result->send_data(fields_list)) - { - result->send_error(0,NullS); /* purecov: inspected */ - error=1; - } + if (do_send_rows && result->send_data(fields_list)) + { + result->send_error(0,NullS); /* purecov: inspected */ + error= 1; + } else error=(int) result->send_eof(); } else - error=(int) result->send_eof(); + error=(int) result->send_eof(); } delete procedure; DBUG_VOID_RETURN; @@ -995,8 +1002,9 @@ JOIN::cleanup(THD *thd) int mysql_select(THD *thd, TABLE_LIST *tables, List &fields, COND *conds, - ORDER *order, ORDER *group,Item *having, ORDER *proc_param, - ulong select_options, select_result *result, SELECT_LEX_UNIT *unit) + ORDER *order, ORDER *group,Item *having, ORDER *proc_param, + ulong select_options, select_result *result, + SELECT_LEX_UNIT *unit, bool fake_select_lex) { JOIN *join = new JOIN(thd, fields, select_options, result); @@ -1005,7 +1013,7 @@ mysql_select(THD *thd, TABLE_LIST *tables, List &fields, COND *conds, thd->used_tables=0; // Updated by setup_fields if (join->prepare(tables, conds, order, group, having, proc_param, - &(thd->lex.select_lex), unit)) + &(thd->lex.select_lex), unit, fake_select_lex)) { DBUG_RETURN(-1); } @@ -1026,7 +1034,7 @@ err: thd->limit_found_rows = join->send_records; thd->examined_row_count = join->examined_rows; thd->proc_info="end"; - int error= join->cleanup(thd); + int error= (fake_select_lex?0:join->cleanup(thd)) || thd->net.report_error; delete join; DBUG_RETURN(error); } @@ -1760,7 +1768,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, add_key_part(keyuse,field); } - if (thd->lex.select->ftfunc_list.elements) + if (thd->lex.select->ftfunc_list->elements) { add_ft_keys(keyuse,join_tab,cond,normal_tables); } @@ -4329,7 +4337,7 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) VOID(table->file->extra(HA_EXTRA_WRITE_CACHE)); empty_record(table); } - join->tmp_table=table; /* Save for easy recursion */ + join->tmp_table= table; /* Save for easy recursion */ join->fields= fields; /* Set up select_end */ @@ -4379,20 +4387,14 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) } else { - error=sub_select(join,join_tab,0); + error= sub_select(join,join_tab,0); if (error >= 0) - error=sub_select(join,join_tab,1); + error= sub_select(join,join_tab,1); if (error == -3) - error=0; /* select_limit used */ + error= 0; /* select_limit used */ } - /* Return 1 if error is sent; -1 if error should be sent */ - if (error < 0) - { - join->result->send_error(0,NullS); /* purecov: inspected */ - error=1; // Error sent - } - else + if (error >= 0) { error=0; if (!table) // If sending data to client @@ -6445,10 +6447,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List &fields, order->in_field_list=1; return 0; } - const char *save_where=thd->where; - thd->where=0; // No error if not found - Item **item=find_item_in_list(*order->item,fields); - thd->where=save_where; + Item **item=find_item_in_list(*order->item, fields, 0); if (item) { order->item=item; // use it @@ -6546,17 +6545,15 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List &fields, DBUG_ENTER("setup_new_fields"); thd->set_query_id=1; // Not really needed, but... - thd->where=0; // Don't give error for ( ; new_field ; new_field=new_field->next) { - if ((item=find_item_in_list(*new_field->item,fields))) + if ((item=find_item_in_list(*new_field->item, fields, 0))) new_field->item=item; /* Change to shared Item */ else { thd->where="procedure list"; if ((*new_field->item)->fix_fields(thd, tables, new_field->item)) DBUG_RETURN(1); /* purecov: inspected */ - thd->where=0; all_fields.push_front(*new_field->item); new_field->item=all_fields.head_ref(); } diff --git a/sql/sql_select.h b/sql/sql_select.h index 3062747a08f..0f7e08d268e 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -209,6 +209,7 @@ class JOIN :public Sql_alloc{ send_records(0), found_records(0), examined_rows(0), thd(thd), sum_funcs(0), + procedure(0), having(0), select_options(select_options), result(result), @@ -235,7 +236,8 @@ class JOIN :public Sql_alloc{ int prepare(TABLE_LIST *tables, COND *conds, ORDER *order, ORDER *group, Item *having, - ORDER *proc_param, SELECT_LEX *select, SELECT_LEX_UNIT *unit); + ORDER *proc_param, SELECT_LEX *select, SELECT_LEX_UNIT *unit, + bool fake_select_lex); int optimize(); int global_optimize(); int reinit(); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 0eea10e068a..e8ee3582135 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -24,31 +24,103 @@ #include "mysql_priv.h" #include "sql_select.h" +int mysql_union(THD *thd, LEX *lex, select_result *result) +{ + DBUG_ENTER("mysql_union"); + SELECT_LEX_UNIT *unit= &lex->unit; + int res= 0; + if (!(res= unit->prepare(thd, result))) + res= unit->exec(); + res|= unit->cleanup(); + DBUG_RETURN(res); +} + + +/*************************************************************************** +** store records in temporary table for UNION +***************************************************************************/ + +select_union::select_union(TABLE *table_par) + :table(table_par) +{ + bzero((char*) &info,sizeof(info)); + /* + We can always use DUP_IGNORE because the temporary table will only + contain a unique key if we are using not using UNION ALL + */ + info.handle_duplicates= DUP_IGNORE; +} + +select_union::~select_union() +{ +} + + +int select_union::prepare(List &list, SELECT_LEX_UNIT *u) +{ + unit= u; + if (save_time_stamp && list.elements != table->fields) + { + my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, + ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0)); + return -1; + } + return 0; +} + +bool select_union::send_data(List &values) +{ + if (unit->offset_limit_cnt) + { // using limit offset,count + unit->offset_limit_cnt--; + return 0; + } + fill_record(table->field,values); + if ((write_record(table,&info))) + { + if (create_myisam_from_heap(table, tmp_table_param, info.errorno, 0)) + return 1; + } + return 0; +} + +bool select_union::send_eof() +{ + return 0; +} -int mysql_union(THD *thd, LEX *lex,select_result *result) +bool select_union::flush() { - SELECT_LEX *sl; - SELECT_LEX_UNIT *unit= &(lex->unit); - List item_list; - TABLE *table; - int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0; - int res; - bool found_rows_for_union=false; - TABLE_LIST result_table_list; + int error; + if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) + { + table->file->print_error(error,MYF(0)); + ::send_error(&thd->net); + return 1; + } + return 0; +} + +typedef JOIN * JOIN_P; +int st_select_lex_unit::prepare(THD *thd, select_result *result) +{ + describe=(first_select()->options & SELECT_DESCRIBE) ? 1 : 0; + res= 0; + found_rows_for_union= false; TMP_TABLE_PARAM tmp_table_param; - select_union *union_result; - DBUG_ENTER("mysql_union"); - st_select_lex_node * global; + DBUG_ENTER("st_select_lex_unit::prepare"); + this->thd= thd; + this->result= result; /* Global option */ - if (((void*)(global= unit->global_parameters)) == ((void*)unit)) + if (((void*)(global_parameters)) == ((void*)this)) { - found_rows_for_union = lex->select_lex.options & OPTION_FOUND_ROWS && - !describe && global->select_limit; + found_rows_for_union = first_select()->options & OPTION_FOUND_ROWS && + !describe && global_parameters->select_limit; if (found_rows_for_union) - lex->select_lex.options ^= OPTION_FOUND_ROWS; + first_select()->options ^= OPTION_FOUND_ROWS; } - + item_list.empty(); if (describe) { Item *item; @@ -70,8 +142,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) else { Item *item; - List_iterator it(lex->select_lex.item_list); - TABLE_LIST *first_table= (TABLE_LIST*) lex->select_lex.table_list.first; + List_iterator it(first_select()->item_list); + TABLE_LIST *first_table= (TABLE_LIST*) first_select()->table_list.first; /* Create a list of items that will be in the result set */ while ((item= it++)) @@ -84,11 +156,12 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) bzero((char*) &tmp_table_param,sizeof(tmp_table_param)); tmp_table_param.field_count=item_list.elements; if (!(table= create_tmp_table(thd, &tmp_table_param, item_list, - (ORDER*) 0, !describe & !lex->union_option, + (ORDER*) 0, !describe & + !thd->lex.union_option, 1, 0, - (lex->select_lex.options | thd->options | + (first_select()->options | thd->options | TMP_TABLE_ALL_COLUMNS), - unit))) + this))) DBUG_RETURN(-1); table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); @@ -98,46 +171,82 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) result_table_list.table=table; if (!(union_result=new select_union(table))) - { - res= -1; - goto exit; - } + DBUG_RETURN(-1); + union_result->save_time_stamp=!describe; union_result->tmp_table_param=&tmp_table_param; - for (sl= &lex->select_lex; sl; sl= sl->next_select()) + + // prepare selects + joins.empty(); + for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) { - lex->select=sl; - unit->offset_limit_cnt= sl->offset_limit; - unit->select_limit_cnt= sl->select_limit+sl->offset_limit; - if (unit->select_limit_cnt < sl->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // no limit - if (unit->select_limit_cnt == HA_POS_ERROR) + JOIN *join= new JOIN(thd, sl->item_list, + sl->options | thd->options | SELECT_NO_UNLOCK | + ((describe) ? SELECT_DESCRIBE : 0), + union_result); + joins.push_back(new JOIN_P(join)); + thd->lex.select=sl; + offset_limit_cnt= sl->offset_limit; + select_limit_cnt= sl->select_limit+sl->offset_limit; + if (select_limit_cnt < sl->select_limit) + select_limit_cnt= HA_POS_ERROR; // no limit + if (select_limit_cnt == HA_POS_ERROR) sl->options&= ~OPTION_FOUND_ROWS; - res= mysql_select(thd, - (TABLE_LIST*) sl->table_list.first, - sl->item_list, - sl->where, - (sl->braces) ? - (ORDER *)sl->order_list.first : (ORDER *) 0, - (ORDER*) sl->group_list.first, - sl->having, - (ORDER*) NULL, - sl->options | thd->options | - SELECT_NO_UNLOCK | ((describe) ? SELECT_DESCRIBE : 0), - union_result, unit); - if (res) - goto exit; + res= join->prepare((TABLE_LIST*) sl->table_list.first, + sl->where, + (sl->braces) ? + (ORDER *)sl->order_list.first : (ORDER *) 0, + (ORDER*) sl->group_list.first, + sl->having, + (ORDER*) NULL, + sl, this, 0); + if (res | thd->fatal_error) + DBUG_RETURN(res | thd->fatal_error); } + DBUG_RETURN(res | thd->fatal_error); +} + +int st_select_lex_unit::exec() +{ + DBUG_ENTER("st_select_lex_unit::exec"); + if(depended || !item || !item->assigned()) + { + if (optimized && item && item->assigned()) + item->assigned(0); // We will reinit & rexecute unit + + for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + { + thd->lex.select=sl; + offset_limit_cnt= sl->offset_limit; + select_limit_cnt= sl->select_limit+sl->offset_limit; + if (select_limit_cnt < sl->select_limit) + select_limit_cnt= HA_POS_ERROR; // no limit + if (select_limit_cnt == HA_POS_ERROR) + sl->options&= ~OPTION_FOUND_ROWS; + + if (!optimized) + sl->join->optimize(); + else + sl->join->reinit(); + + sl->join->exec(); + res= sl->join->error; + + if (res) + DBUG_RETURN(res); + } + optimized= 1; + } + if (union_result->flush()) { res= 1; // Error is already sent - goto exit; + DBUG_RETURN(res); } - delete union_result; /* Send result to 'result' */ - lex->select = &lex->select_lex; + thd->lex.select = first_select(); res =-1; { /* Create a list of fields in the temporary table */ @@ -147,7 +256,9 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) List ftfunc_list; ftfunc_list.empty(); #else - thd->lex.select_lex.ftfunc_list.empty(); + List empty_list; + empty_list.empty(); + thd->lex.select_lex.ftfunc_list= &empty_list; #endif for (field=table->field ; *field ; field++) @@ -157,92 +268,45 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) } if (!thd->fatal_error) // Check if EOM { - st_select_lex_node * global= unit->global_parameters; - unit->offset_limit_cnt= global->offset_limit; - unit->select_limit_cnt= global->select_limit+global->offset_limit; - if (unit->select_limit_cnt < global->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // no limit - if (unit->select_limit_cnt == HA_POS_ERROR) + offset_limit_cnt= global_parameters->offset_limit; + select_limit_cnt= global_parameters->select_limit+ + global_parameters->offset_limit; + if (select_limit_cnt < global_parameters->select_limit) + select_limit_cnt= HA_POS_ERROR; // no limit + if (select_limit_cnt == HA_POS_ERROR) thd->options&= ~OPTION_FOUND_ROWS; if (describe) - unit->select_limit_cnt= HA_POS_ERROR; // no limit + select_limit_cnt= HA_POS_ERROR; // no limit res= mysql_select(thd,&result_table_list, item_list, NULL, - (describe) ? 0 : (ORDER*)global->order_list.first, + (describe) ? + 0: + (ORDER*)global_parameters->order_list.first, (ORDER*) NULL, NULL, (ORDER*) NULL, - thd->options, result, unit); + thd->options, result, this, 1); if (found_rows_for_union && !res) thd->limit_found_rows = (ulonglong)table->file->records; } } - -exit: - free_tmp_table(thd,table); + thd->lex.select_lex.ftfunc_list= &thd->lex.select_lex.ftfunc_list_alloc; DBUG_RETURN(res); } - -/*************************************************************************** -** store records in temporary table for UNION -***************************************************************************/ - -select_union::select_union(TABLE *table_par) - :table(table_par) +int st_select_lex_unit::cleanup() { - bzero((char*) &info,sizeof(info)); - /* - We can always use DUP_IGNORE because the temporary table will only - contain a unique key if we are using not using UNION ALL - */ - info.handle_duplicates= DUP_IGNORE; -} - -select_union::~select_union() -{ -} - - -int select_union::prepare(List &list, SELECT_LEX_UNIT *u) -{ - unit= u; - if (save_time_stamp && list.elements != table->fields) - { - my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, - ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0)); - return -1; - } - return 0; -} - -bool select_union::send_data(List &values) -{ - if (unit->offset_limit_cnt) - { // using limit offset,count - unit->offset_limit_cnt--; - return 0; - } - fill_record(table->field,values); - if ((write_record(table,&info))) - { - if (create_myisam_from_heap(table, tmp_table_param, info.errorno, 0)) - return 1; - } - return 0; -} - -bool select_union::send_eof() -{ - return 0; -} - -bool select_union::flush() -{ - int error; - if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) + DBUG_ENTER("st_select_lex_unit::cleanup"); + delete union_result; + free_tmp_table(thd,table); + table= 0; // Safety + + List_iterator j(joins); + JOIN** join; + while ((join= j++)) { - table->file->print_error(error,MYF(0)); - ::send_error(&thd->net); - return 1; + (*join)->cleanup(thd); + delete *join; + delete join; } - return 0; + joins.empty(); + DBUG_RETURN(0); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 51453f955e8..9ea8f725947 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -642,6 +642,8 @@ bool multi_update::send_data(List &values) void multi_update::send_error(uint errcode,const char *err) { + + //TODO error should be sent at the query processing end /* First send error what ever it is ... */ ::send_error(&thd->net,errcode,err); @@ -766,6 +768,7 @@ bool multi_update::send_eof() if (error == -1) error = 0; thd->proc_info="end"; + //TODO error should be sent at the query processing end if (error) send_error(error,"An error occured in multi-table update"); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 160bc253dc9..b762388d9be 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1763,10 +1763,10 @@ simple_expr: | singleval_subselect { $$= $1; } | '{' ident expr '}' { $$= $3; } | MATCH ident_list_arg AGAINST '(' expr ')' - { Select->ftfunc_list.push_back((Item_func_match *) + { Select->ftfunc_list->push_back((Item_func_match *) ($$=new Item_func_match_nl(*$2,$5))); } | MATCH ident_list_arg AGAINST '(' expr IN_SYM BOOLEAN_SYM MODE_SYM ')' - { Select->ftfunc_list.push_back((Item_func_match *) + { Select->ftfunc_list->push_back((Item_func_match *) ($$=new Item_func_match_bool(*$2,$5))); } | BINARY expr %prec NEG { $$= new Item_func_binary($2); } | CAST_SYM '(' expr AS cast_type ')' { $$= create_func_cast($3, $5); } @@ -3999,7 +3999,8 @@ singleval_subselect: singleval_subselect_init: select_init { - $$= new Item_singleval_subselect(current_thd, Lex->select); + $$= new Item_singleval_subselect(current_thd, + Lex->select->master_unit()->first_select()); }; exists_subselect: @@ -4012,7 +4013,8 @@ exists_subselect: exists_subselect_init: select_init { - $$= new Item_exists_subselect(current_thd, Lex->select); + $$= new Item_exists_subselect(current_thd, + Lex->select->master_unit()->first_select()); }; subselect_start: -- cgit v1.2.1 From 479da246b1c188614bb4d5e4b182c2e7aa6312a5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Sep 2002 09:40:01 +0300 Subject: query cache TODO --- sql/sql_cache.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'sql') diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index c739b43debb..38b30b683e2 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -278,6 +278,21 @@ TODO list: - Move MRG_MYISAM table type processing to handlers, something like: tables_used->table->file->register_used_filenames(callback, first_argument); + - Make derived tables cachable. + - QC improvement suggested by Monty: + - Add a counter in open_table() for how many MERGE (ISAM or MyISAM) + tables are cached in the table cache. + (This will be trivial when we have the new table cache in place I + have been working on) + - After this we can add the following test around the for loop in + is_cacheable:: + + if (thd->temp_tables || global_merge_table_count) + + - Another option would be to set thd->safe_to_cache_query to 0 + in 'get_lock_data' if any of the tables was a tmp table or a + MRG_ISAM table. + (This could be done with almost no speed penalty) */ #include "mysql_priv.h" -- cgit v1.2.1 From 51a41f1fba3bd5b9addcd63424a494263d541c34 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Sep 2002 19:30:26 +0500 Subject: Fixed sort order for cp866 sql/share/charsets/cp866.conf: Fixed sort order --- sql/share/charsets/cp866.conf | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'sql') diff --git a/sql/share/charsets/cp866.conf b/sql/share/charsets/cp866.conf index e6b5c064fd7..0e4dcb3b9bc 100644 --- a/sql/share/charsets/cp866.conf +++ b/sql/share/charsets/cp866.conf @@ -1,3 +1,8 @@ +# +# cp866_DOSCyrillicRussian +# Case insensitive, accent sensitive. +# +# # ctype array (must be 257 elements) 00 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 @@ -58,20 +63,20 @@ 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F - 40 41 42 43 44 45 56 57 58 59 5A 5B 5C 5E 5F 62 - 67 68 69 6C 71 74 75 76 77 78 7B B0 B1 B2 B3 B4 - B5 41 42 43 44 45 56 57 58 59 5A 5B 5C 5E 5F 62 - 67 68 69 6C 71 74 75 76 77 78 7B B6 B7 B8 B9 BA - 80 81 82 83 84 85 88 89 8A 8C 8D 8E 8F 90 91 92 - 93 94 95 96 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 - 80 81 82 83 84 85 88 89 8A 8C 8D 8E 8F 90 91 92 - BB BD BE C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC - CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD - DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 F3 F4 F5 F6 F7 - 93 94 95 96 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 - 86 86 87 87 8B 8B 97 97 F8 F9 FA FB FC FD FE FF + 40 41 43 45 47 49 4B 4D 4F 51 53 55 57 59 5B 5D + 5F 61 63 65 67 69 6B 6D 6F 71 73 BD BE BF C0 C1 + C2 41 43 45 47 49 4B 4D 4F 51 54 55 57 59 5B 5D + 5F 61 63 65 67 69 6B 6D 6F 71 73 C3 C4 C5 C6 C7 + 75 77 79 7B 7D 7F 85 87 89 8D 8F 91 93 95 97 99 + 9B 9D 9F A1 A5 A7 A9 AB AD AF B1 B3 B5 B7 B9 BB + 75 77 79 7B 7D 7F 85 87 89 8D 8F 91 93 95 97 99 + C8 C9 CA D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + 9B 9D 9F A1 A5 A7 A9 AB AD AF B1 B3 B5 B7 B9 BB + 81 81 83 83 8B 8B A3 A3 CB CC CD CE CF D0 D1 D2 -# Unicode mappping (must be 256 elements) +# Unicode mapping (must be 256 elements) 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F -- cgit v1.2.1 From 31f842663c99ee92d340088031ef295ce5a0d767 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Sep 2002 19:55:53 +0500 Subject: Some new charsets. --- sql/share/charsets/Index | 23 +++++++- sql/share/charsets/cp1251.conf | 19 ------- sql/share/charsets/cp1251bin.conf | 95 ++++++++++++++++++++++++++++++++ sql/share/charsets/cp1251cias.conf | 99 ++++++++++++++++++++++++++++++++++ sql/share/charsets/cp1251csas.conf | 99 ++++++++++++++++++++++++++++++++++ sql/share/charsets/cp1257bin.conf | 96 +++++++++++++++++++++++++++++++++ sql/share/charsets/cp1257ltlvciai.conf | 97 +++++++++++++++++++++++++++++++++ sql/share/charsets/cp1257ltlvcias.conf | 97 +++++++++++++++++++++++++++++++++ sql/share/charsets/cp1257ltlvcsas.conf | 97 +++++++++++++++++++++++++++++++++ sql/share/charsets/latin1bin.conf | 96 +++++++++++++++++++++++++++++++++ sql/share/charsets/latin1cias.conf | 97 +++++++++++++++++++++++++++++++++ sql/share/charsets/latin1csas.conf | 97 +++++++++++++++++++++++++++++++++ sql/share/charsets/maccebin.conf | 96 +++++++++++++++++++++++++++++++++ sql/share/charsets/macceciai.conf | 96 +++++++++++++++++++++++++++++++++ sql/share/charsets/maccecias.conf | 96 +++++++++++++++++++++++++++++++++ sql/share/charsets/maccecsas.conf | 96 +++++++++++++++++++++++++++++++++ sql/share/charsets/macromanbin.conf | 96 +++++++++++++++++++++++++++++++++ sql/share/charsets/macromanciai.conf | 97 +++++++++++++++++++++++++++++++++ sql/share/charsets/macromancias.conf | 97 +++++++++++++++++++++++++++++++++ sql/share/charsets/macromancsas.conf | 97 +++++++++++++++++++++++++++++++++ 20 files changed, 1762 insertions(+), 21 deletions(-) create mode 100644 sql/share/charsets/cp1251bin.conf create mode 100644 sql/share/charsets/cp1251cias.conf create mode 100644 sql/share/charsets/cp1251csas.conf create mode 100644 sql/share/charsets/cp1257bin.conf create mode 100644 sql/share/charsets/cp1257ltlvciai.conf create mode 100644 sql/share/charsets/cp1257ltlvcias.conf create mode 100644 sql/share/charsets/cp1257ltlvcsas.conf create mode 100644 sql/share/charsets/latin1bin.conf create mode 100644 sql/share/charsets/latin1cias.conf create mode 100644 sql/share/charsets/latin1csas.conf create mode 100644 sql/share/charsets/maccebin.conf create mode 100644 sql/share/charsets/macceciai.conf create mode 100644 sql/share/charsets/maccecias.conf create mode 100644 sql/share/charsets/maccecsas.conf create mode 100644 sql/share/charsets/macromanbin.conf create mode 100644 sql/share/charsets/macromanciai.conf create mode 100644 sql/share/charsets/macromancias.conf create mode 100644 sql/share/charsets/macromancsas.conf (limited to 'sql') diff --git a/sql/share/charsets/Index b/sql/share/charsets/Index index c8ae877887e..009eeaeac38 100644 --- a/sql/share/charsets/Index +++ b/sql/share/charsets/Index @@ -17,33 +17,52 @@ swe7 10 usa7 11 ujis 12 sjis 13 +# cp1251 is depreciated. Use cp1251cias, cp1251csas or cp1251bin instead. cp1251 14 danish 15 hebrew 16 -# The win1251 character set is deprecated. Please use cp1251 instead. -win1251 17 tis620 18 euc_kr 19 estonia 20 hungarian 21 koi8_ukr 22 +# win1251ukr is depreciated. Use cp1251cias, cp1251csas or cp1251bin instead. win1251ukr 23 gb2312 24 greek 25 win1250 26 croat 27 gbk 28 +# cp1257 is depreciated. +# Use cp1257ltlvciai, cp1257ltlvcsas, cp1257bin, cp1257ltlvcias instead cp1257 29 latin5 30 latin1_de 31 armscii8 32 utf8 33 win1250ch 34 + ucs2 35 cp866 36 keybcs2 37 + macce 38 macroman 39 + pclatin2 40 latvian 41 latvian1 42 +maccebin 43 +macceciai 44 +maccecias 45 +maccecsas 46 +latin1bin 47 +latin1cias 48 +latin1csas 49 +cp1251bin 50 +cp1251cias 51 +cp1251csas 52 +macromanbin 53 +macromancias 54 +macromanciai 55 +macromancsas 56 diff --git a/sql/share/charsets/cp1251.conf b/sql/share/charsets/cp1251.conf index 653f7d26879..6af97c891b8 100644 --- a/sql/share/charsets/cp1251.conf +++ b/sql/share/charsets/cp1251.conf @@ -72,22 +72,3 @@ 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 5B 5C 5D 5E 5F 60 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B - - -# Unicode mapping (256 elements) -0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F -0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F -0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F -0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F -0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F -0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F -0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F -0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F -0402 0403 201A 0453 201E 2026 2020 2021 0000 2030 0409 2039 040A 040C 040B 040F -0452 2018 2019 201C 201D 2022 2013 2014 0000 2122 0459 203A 045A 045C 045B 045F -00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 -00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 -0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F -0420 0421 0422 0423 0424 0425 0426 0427 0428 0429 042A 042B 042C 042D 042E 042F -0430 0431 0432 0433 0434 0435 0436 0437 0438 0439 043A 043B 043C 043D 043E 043F -0440 0441 0442 0443 0444 0445 0446 0447 0448 0449 044A 044B 044C 044D 044E 044F diff --git a/sql/share/charsets/cp1251bin.conf b/sql/share/charsets/cp1251bin.conf new file mode 100644 index 00000000000..4c17fee5934 --- /dev/null +++ b/sql/share/charsets/cp1251bin.conf @@ -0,0 +1,95 @@ +# +# cp1251 +# Binary sort order +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 01 00 02 00 00 00 00 00 00 01 00 01 01 01 01 + 02 00 00 00 00 00 00 00 00 00 02 00 02 02 02 02 + 00 01 02 01 00 01 00 00 01 00 01 00 00 00 00 01 + 00 00 01 02 02 00 00 00 02 00 02 00 02 01 02 02 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 90 83 82 83 84 85 86 87 88 89 9A 8B 9C 9D 9E 9F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A2 A2 BC A4 B4 A6 A7 B8 A9 BA AB AC AD AE BF + B0 B1 B3 B3 B4 B5 B6 B7 B8 B9 BA BB BC BE BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 81 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 80 91 92 93 94 95 96 97 98 99 8A 9B 8C 9D 8E 8F + A0 A1 A1 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B2 A5 B5 B6 B7 A8 B9 AA BB A3 BD BD AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 0402 0403 201A 0453 201E 2026 2020 2021 0000 2030 0409 2039 040A 040C 040B 040F + 0452 2018 2019 201C 201D 2022 2013 2014 0000 2122 0459 203A 045A 045C 045B 045F + 00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 + 00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 + 0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F + 0420 0421 0422 0423 0424 0425 0426 0427 0428 0429 042A 042B 042C 042D 042E 042F + 0430 0431 0432 0433 0434 0435 0436 0437 0438 0439 043A 043B 043C 043D 043E 043F + 0440 0441 0442 0443 0444 0445 0446 0447 0448 0449 044A 044B 044C 044D 044E 044F + diff --git a/sql/share/charsets/cp1251cias.conf b/sql/share/charsets/cp1251cias.conf new file mode 100644 index 00000000000..612be640b11 --- /dev/null +++ b/sql/share/charsets/cp1251cias.conf @@ -0,0 +1,99 @@ +# +# cp1251 +# Case insensitive, accent sensitive +# Sort order is correct for Belarusian, Bulgarian, Macedonian, +# Russian, Serbian, Mongolian languages. Almost good for Ukrainian, +# except that "CYRILLIC LETTER SOFT SIGN" is not in the end of alphabet, +# but between YERU and E. +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 01 00 02 00 00 00 00 00 00 01 00 01 01 01 01 + 02 00 00 00 00 00 00 00 00 00 02 00 02 02 02 02 + 00 01 02 01 00 01 00 00 01 00 01 00 00 00 00 01 + 00 00 01 02 02 00 00 00 02 00 02 00 02 01 02 02 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 90 83 82 83 84 85 86 87 88 89 9A 8B 9C 9D 9E 9F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A2 A2 BC A4 B4 A6 A7 B8 A9 BA AB AC AD AE BF + B0 B1 B3 B3 B4 B5 B6 B7 B8 B9 BA BB BC BE BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 81 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 80 91 92 93 94 95 96 97 98 99 8A 9B 8C 9D 8E 8F + A0 A1 A1 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B2 A5 B5 B6 B7 A8 B9 AA BB A3 BD BD AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 43 45 47 49 4B 4D 4F 51 53 55 57 59 5B 5D + 5F 61 63 65 67 69 6B 6D 6F 71 73 D3 D4 D5 D6 D7 + D8 41 43 45 47 49 4B 4D 4F 51 53 55 57 59 5B 5D + 5F 61 63 65 67 69 6B 6D 6F 71 73 D9 DA DB DC DD + 81 83 DE 83 DF E0 E1 E2 E3 E4 A1 E5 A7 9D B3 C1 + 81 E6 E7 E8 E9 EA EB EC ED EE A1 EF A7 9D B3 C1 + F0 B7 B7 99 F1 7D F2 F3 87 F4 89 F5 F6 F7 F8 95 + F9 FA 93 93 7D FB FC FD 87 FE 89 FF 99 8F 8F 95 + 75 77 79 7B 7F 85 8B 8D 91 97 9B 9F A3 A5 A9 AB + AD AF B1 B5 B9 BB BD BF C3 C5 C7 C9 CB CD CF D1 + 75 77 79 7B 7F 85 8B 8D 91 97 9B 9F A3 A5 A9 AB + AD AF B1 B5 B9 BB BD BF C3 C5 C7 C9 CB CD CF D1 + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 0402 0403 201A 0453 201E 2026 2020 2021 0000 2030 0409 2039 040A 040C 040B 040F + 0452 2018 2019 201C 201D 2022 2013 2014 0000 2122 0459 203A 045A 045C 045B 045F + 00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 + 00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 + 0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F + 0420 0421 0422 0423 0424 0425 0426 0427 0428 0429 042A 042B 042C 042D 042E 042F + 0430 0431 0432 0433 0434 0435 0436 0437 0438 0439 043A 043B 043C 043D 043E 043F + 0440 0441 0442 0443 0444 0445 0446 0447 0448 0449 044A 044B 044C 044D 044E 044F + diff --git a/sql/share/charsets/cp1251csas.conf b/sql/share/charsets/cp1251csas.conf new file mode 100644 index 00000000000..b6b2f853ea9 --- /dev/null +++ b/sql/share/charsets/cp1251csas.conf @@ -0,0 +1,99 @@ +# +# cp1251 +# Case sensitive, accent sensitive +# Sort order is correct for Belarusian, Bulgarian, Macedonian, +# Russian, Serbian, Mongolian languages. Almost good for Ukrainian, +# except that "CYRILLIC LETTER SOFT SIGN" is not in the end of alphabet, +# but between YERU and E. +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 01 00 02 00 00 00 00 00 00 01 00 01 01 01 01 + 02 00 00 00 00 00 00 00 00 00 02 00 02 02 02 02 + 00 01 02 01 00 01 00 00 01 00 01 00 00 00 00 01 + 00 00 01 02 02 00 00 00 02 00 02 00 02 01 02 02 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 90 83 82 83 84 85 86 87 88 89 9A 8B 9C 9D 9E 9F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A2 A2 BC A4 B4 A6 A7 B8 A9 BA AB AC AD AE BF + B0 B1 B3 B3 B4 B5 B6 B7 B8 B9 BA BB BC BE BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 81 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 80 91 92 93 94 95 96 97 98 99 8A 9B 8C 9D 8E 8F + A0 A1 A1 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B2 A5 B5 B6 B7 A8 B9 AA BB A3 BD BD AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 43 45 47 49 4B 4D 4F 51 53 55 57 59 5B 5D + 5F 61 63 65 67 69 6B 6D 6F 71 73 D3 D4 D5 D6 D7 + D8 42 44 46 48 4A 4C 4E 50 52 54 56 58 5A 5C 5E + 60 62 64 66 68 6A 6C 6E 70 72 74 D9 DA DB DC DD + 81 83 DE 84 DF E0 E1 E2 E3 E4 A1 E5 A7 9D B3 C1 + 82 E6 E7 E8 E9 EA EB EC ED EE A2 EF A8 9E B4 C2 + F0 B7 B8 99 F1 7D F2 F3 87 F4 89 F5 F6 F7 F8 95 + F9 FA 93 94 7E FB FC FD 88 FE 8A FF 9A 8F 90 96 + 75 77 79 7B 7F 85 8B 8D 91 97 9B 9F A3 A5 A9 AB + AD AF B1 B5 B9 BB BD BF C3 C5 C7 C9 CB CD CF D1 + 76 78 7A 7C 80 86 8C 8E 92 98 9C A0 A4 A6 AA AC + AE B0 B2 B6 BA BC BE C0 C4 C6 C8 CA CC CE D0 D2 + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 0402 0403 201A 0453 201E 2026 2020 2021 0000 2030 0409 2039 040A 040C 040B 040F + 0452 2018 2019 201C 201D 2022 2013 2014 0000 2122 0459 203A 045A 045C 045B 045F + 00A0 040E 045E 0408 00A4 0490 00A6 00A7 0401 00A9 0404 00AB 00AC 00AD 00AE 0407 + 00B0 00B1 0406 0456 0491 00B5 00B6 00B7 0451 2116 0454 00BB 0458 0405 0455 0457 + 0410 0411 0412 0413 0414 0415 0416 0417 0418 0419 041A 041B 041C 041D 041E 041F + 0420 0421 0422 0423 0424 0425 0426 0427 0428 0429 042A 042B 042C 042D 042E 042F + 0430 0431 0432 0433 0434 0435 0436 0437 0438 0439 043A 043B 043C 043D 043E 043F + 0440 0441 0442 0443 0444 0445 0446 0447 0448 0449 044A 044B 044C 044D 044E 044F + diff --git a/sql/share/charsets/cp1257bin.conf b/sql/share/charsets/cp1257bin.conf new file mode 100644 index 00000000000..032f8a7e05d --- /dev/null +++ b/sql/share/charsets/cp1257bin.conf @@ -0,0 +1,96 @@ +# +# cp1257 character set +# +# Binary sorting order +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 01 + 00 00 00 00 00 00 00 00 02 00 02 00 00 00 00 02 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 00 01 01 01 01 01 01 01 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 00 02 02 02 02 02 02 02 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 B8 A9 BA AB AC AD AE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 BA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 A8 B9 BA BB BC BD BE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 20AC 0000 201A 0000 201E 2026 2020 2021 0000 2030 0000 2039 0000 00A8 02C7 00B8 + 0000 2018 2019 201C 201D 2022 2013 2014 0000 2122 0000 203A 0000 00AF 02DB 0000 + 00A0 0000 00A2 00A3 00A4 0000 00A6 00A7 00D8 00A9 0156 00AB 00AC 00AD 00AE 00C6 + 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00F8 00B9 0157 00BB 00BC 00BD 00BE 00E6 + 0104 012E 0100 0106 00C4 00C5 0118 0112 010C 00C9 0179 0116 0122 0136 012A 013B + 0160 0143 0145 00D3 014C 00D5 00D6 00D7 0172 0141 015A 016A 00DC 017B 017D 00DF + 0105 012F 0101 0107 00E4 00E5 0119 0113 010D 00E9 017A 0117 0123 0137 012B 013C + 0161 0144 0146 00F3 014D 00F5 00F6 00F7 0173 0142 015B 016B 00FC 017C 017E 02D9 + diff --git a/sql/share/charsets/cp1257ltlvciai.conf b/sql/share/charsets/cp1257ltlvciai.conf new file mode 100644 index 00000000000..246ae4d1fe8 --- /dev/null +++ b/sql/share/charsets/cp1257ltlvciai.conf @@ -0,0 +1,97 @@ +# +# cp1257 character set +# +# Case-insensitive, accent insensitive sorting order +# For Latvian and Lithuanian languages +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 01 + 00 00 00 00 00 00 00 00 02 00 02 00 00 00 00 02 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 00 01 01 01 01 01 01 01 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 00 02 02 02 02 02 02 02 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 B8 A9 BA AB AC AD AE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 BA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 A8 B9 BA BB BC BD BE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 4D 4F 55 57 61 63 67 69 6F 71 75 7B 7D 83 + 8F 91 93 97 9E A0 A8 AA AC AE B0 B8 B9 BA BB BC + BD 41 4D 4F 55 57 61 63 67 69 6F 71 75 7B 7D 83 + 8F 91 93 97 9E A0 A8 AA AC AE B0 BE BF C0 C1 C4 + C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 + D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 + E5 E6 E7 E8 E9 EA EB EC 83 ED 93 EE EF F0 F1 41 + F2 F3 F4 F5 F6 F7 F8 F9 83 FA 93 FB FC FD FE 41 + 41 69 41 4F 41 41 57 57 4F 57 B0 57 63 71 69 75 + 97 7D 7D 83 83 83 83 C2 A0 75 97 A0 A0 B0 B0 97 + 41 69 41 4F 41 41 57 57 4F 57 B0 57 63 71 69 75 + 97 7D 7D 83 83 83 83 C3 A0 75 97 A0 A0 B0 B0 FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 20AC 0000 201A 0000 201E 2026 2020 2021 0000 2030 0000 2039 0000 00A8 02C7 00B8 + 0000 2018 2019 201C 201D 2022 2013 2014 0000 2122 0000 203A 0000 00AF 02DB 0000 + 00A0 0000 00A2 00A3 00A4 0000 00A6 00A7 00D8 00A9 0156 00AB 00AC 00AD 00AE 00C6 + 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00F8 00B9 0157 00BB 00BC 00BD 00BE 00E6 + 0104 012E 0100 0106 00C4 00C5 0118 0112 010C 00C9 0179 0116 0122 0136 012A 013B + 0160 0143 0145 00D3 014C 00D5 00D6 00D7 0172 0141 015A 016A 00DC 017B 017D 00DF + 0105 012F 0101 0107 00E4 00E5 0119 0113 010D 00E9 017A 0117 0123 0137 012B 013C + 0161 0144 0146 00F3 014D 00F5 00F6 00F7 0173 0142 015B 016B 00FC 017C 017E 02D9 + diff --git a/sql/share/charsets/cp1257ltlvcias.conf b/sql/share/charsets/cp1257ltlvcias.conf new file mode 100644 index 00000000000..6e49f5a245d --- /dev/null +++ b/sql/share/charsets/cp1257ltlvcias.conf @@ -0,0 +1,97 @@ +# +# cp1257 character set +# +# Case-insensitive, accent sensitive sorting order +# For Latvian and Lithuanian languages +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 01 + 00 00 00 00 00 00 00 00 02 00 02 00 00 00 00 02 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 00 01 01 01 01 01 01 01 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 00 02 02 02 02 02 02 02 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 B8 A9 BA AB AC AD AE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 BA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 A8 B9 BA BB BC BD BE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 4D 4F 55 57 61 63 67 69 6F 71 75 7B 7D 83 + 8F 91 93 97 9E A0 A8 AA AC AE B0 B8 B9 BA BB BC + BD 41 4D 4F 55 57 61 63 67 69 6F 71 75 7B 7D 83 + 8F 91 93 97 9E A0 A8 AA AC AE B0 BE BF C0 C1 C4 + C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 + D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 + E5 E6 E7 E8 E9 EA EB EC 85 ED 95 EE EF F0 F1 4B + F2 F3 F4 F5 F6 F7 F8 F9 85 FA 95 FB FC FD FE 4B + 43 6B 45 51 47 49 59 5B 53 5D B2 5F 65 73 6D 77 + 99 7F 81 87 89 8B 8D C2 A2 79 9B A4 A6 B4 B6 9D + 43 6B 45 51 47 49 59 5B 53 5D B2 5F 65 73 6D 77 + 99 7F 81 87 89 8B 8D C3 A2 79 9B A4 A6 B4 B6 FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 20AC 0000 201A 0000 201E 2026 2020 2021 0000 2030 0000 2039 0000 00A8 02C7 00B8 + 0000 2018 2019 201C 201D 2022 2013 2014 0000 2122 0000 203A 0000 00AF 02DB 0000 + 00A0 0000 00A2 00A3 00A4 0000 00A6 00A7 00D8 00A9 0156 00AB 00AC 00AD 00AE 00C6 + 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00F8 00B9 0157 00BB 00BC 00BD 00BE 00E6 + 0104 012E 0100 0106 00C4 00C5 0118 0112 010C 00C9 0179 0116 0122 0136 012A 013B + 0160 0143 0145 00D3 014C 00D5 00D6 00D7 0172 0141 015A 016A 00DC 017B 017D 00DF + 0105 012F 0101 0107 00E4 00E5 0119 0113 010D 00E9 017A 0117 0123 0137 012B 013C + 0161 0144 0146 00F3 014D 00F5 00F6 00F7 0173 0142 015B 016B 00FC 017C 017E 02D9 + diff --git a/sql/share/charsets/cp1257ltlvcsas.conf b/sql/share/charsets/cp1257ltlvcsas.conf new file mode 100644 index 00000000000..32cd1390bd5 --- /dev/null +++ b/sql/share/charsets/cp1257ltlvcsas.conf @@ -0,0 +1,97 @@ +# +# cp1257 character set +# +# Case-sensitive, accent sensitive sorting order +# For Latvian and Lithuanian languages +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 01 + 00 00 00 00 00 00 00 00 02 00 02 00 00 00 00 02 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 00 01 01 01 01 01 01 01 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 00 02 02 02 02 02 02 02 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 B8 A9 BA AB AC AD AE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 BA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 A8 B9 BA BB BC BD BE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 4D 4F 55 57 61 63 67 69 6F 71 75 7B 7D 83 + 8F 91 93 97 9E A0 A8 AA AC AE B0 B8 B9 BA BB BC + BD 42 4E 50 56 58 62 64 68 6A 70 72 76 7C 7E 84 + 90 92 94 98 9F A1 A9 AB AD AF B1 BE BF C0 C1 C4 + C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 + D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 + E5 E6 E7 E8 E9 EA EB EC 85 ED 95 EE EF F0 F1 4B + F2 F3 F4 F5 F6 F7 F8 F9 86 FA 96 FB FC FD FE 4C + 43 6B 45 51 47 49 59 5B 53 5D B2 5F 65 73 6D 77 + 99 7F 81 87 89 8B 8D C2 A2 79 9B A4 A6 B4 B6 9D + 44 6C 46 52 48 4A 5A 5C 54 5E B3 60 66 74 6E 78 + 9A 80 82 88 8A 8C 8E C3 A3 7A 9C A5 A7 B5 B7 FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 20AC 0000 201A 0000 201E 2026 2020 2021 0000 2030 0000 2039 0000 00A8 02C7 00B8 + 0000 2018 2019 201C 201D 2022 2013 2014 0000 2122 0000 203A 0000 00AF 02DB 0000 + 00A0 0000 00A2 00A3 00A4 0000 00A6 00A7 00D8 00A9 0156 00AB 00AC 00AD 00AE 00C6 + 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00F8 00B9 0157 00BB 00BC 00BD 00BE 00E6 + 0104 012E 0100 0106 00C4 00C5 0118 0112 010C 00C9 0179 0116 0122 0136 012A 013B + 0160 0143 0145 00D3 014C 00D5 00D6 00D7 0172 0141 015A 016A 00DC 017B 017D 00DF + 0105 012F 0101 0107 00E4 00E5 0119 0113 010D 00E9 017A 0117 0123 0137 012B 013C + 0161 0144 0146 00F3 014D 00F5 00F6 00F7 0173 0142 015B 016B 00FC 017C 017E 02D9 + diff --git a/sql/share/charsets/latin1bin.conf b/sql/share/charsets/latin1bin.conf new file mode 100644 index 00000000000..37e6350bcb2 --- /dev/null +++ b/sql/share/charsets/latin1bin.conf @@ -0,0 +1,96 @@ +# +# Latin1, accent sensitive, case sensitive +# +# Binary sorting order +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 00 01 01 01 01 01 01 01 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 00 02 02 02 02 02 02 02 02 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F + 0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F + 00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF + 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF + 00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF + 00D0 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 00DD 00DE 00DF + 00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF + 00F0 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 00FD 00FE 00FF + diff --git a/sql/share/charsets/latin1cias.conf b/sql/share/charsets/latin1cias.conf new file mode 100644 index 00000000000..3b0e104aafd --- /dev/null +++ b/sql/share/charsets/latin1cias.conf @@ -0,0 +1,97 @@ +# +# Latin1, accent sensitive, case insensitive +# +# Sorting for Dutch, English, French, German (Duden), +# Italian, Latin, Pogtuguese, Spanish +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 00 01 01 01 01 01 01 01 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 00 02 02 02 02 02 02 02 02 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 51 53 57 5B 65 67 69 6B 75 77 79 7B 7D 81 + 8F 91 93 95 98 9A A4 A6 A8 AA AF B3 B4 B5 B6 B7 + B8 41 51 53 57 5B 65 67 69 6B 75 77 79 7B 7D 81 + 8F 91 93 95 98 9A A4 A6 A8 AA AF B9 BA BB BC BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + 43 45 47 49 4B 4D 4F 55 5D 5F 61 63 6D 6F 71 73 + 59 7F 83 85 87 89 8B BD 8D 9C 9E A0 A2 AC B1 97 + 43 45 47 49 4B 4D 4F 55 5D 5F 61 63 6D 6F 71 73 + 59 7F 83 85 87 89 8B BE 8D 9C 9E A0 A2 AC B1 AE + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F + 0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F + 00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF + 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF + 00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF + 00D0 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 00DD 00DE 00DF + 00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF + 00F0 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 00FD 00FE 00FF + diff --git a/sql/share/charsets/latin1csas.conf b/sql/share/charsets/latin1csas.conf new file mode 100644 index 00000000000..cb3a1285de8 --- /dev/null +++ b/sql/share/charsets/latin1csas.conf @@ -0,0 +1,97 @@ +# +# Latin1, accent sensitive, case sensitive +# +# Sorting for Dutch, English, French, German (Duden), +# Italian, Latin, Pogtuguese, Spanish +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 00 01 01 01 01 01 01 01 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 00 02 02 02 02 02 02 02 02 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 51 53 57 5B 65 67 69 6B 75 77 79 7B 7D 81 + 8F 91 93 95 98 9A A4 A6 A8 AA AF B3 B4 B5 B6 B7 + B8 42 52 54 58 5C 66 68 6A 6C 76 78 7A 7C 7E 82 + 90 92 94 96 99 9B A5 A7 A9 AB B0 B9 BA BB BC BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + 43 45 47 49 4B 4D 4F 55 5D 5F 61 63 6D 6F 71 73 + 59 7F 83 85 87 89 8B BD 8D 9C 9E A0 A2 AC B1 97 + 44 46 48 4A 4C 4E 50 56 5E 60 62 64 6E 70 72 74 + 5A 80 84 86 88 8A 8C BE 8E 9D 9F A1 A3 AD B2 AE + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F + 0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F + 00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF + 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF + 00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF + 00D0 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 00DD 00DE 00DF + 00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF + 00F0 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 00FD 00FE 00FF + diff --git a/sql/share/charsets/maccebin.conf b/sql/share/charsets/maccebin.conf new file mode 100644 index 00000000000..f859e64354c --- /dev/null +++ b/sql/share/charsets/maccebin.conf @@ -0,0 +1,96 @@ +# Mac OS Central European, binary sort order +# +# Czech (cs), Hungarian (hu), Polish (pl), Romanian (ro), Croatian (hr), +# Slovak (sk), Slovenian (sl), Sorbian. +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 01 02 01 01 01 01 02 02 01 02 02 01 02 02 01 + 02 01 02 02 01 02 01 02 02 02 02 02 02 01 02 02 + 00 00 01 00 00 00 00 02 00 00 00 02 00 00 02 01 + 02 01 00 00 02 01 00 00 02 01 02 01 02 01 02 01 + 02 01 00 00 02 01 00 00 00 00 00 02 01 01 02 01 + 00 00 00 00 00 00 00 00 02 01 02 01 00 00 02 01 + 02 01 00 00 02 01 02 01 01 02 01 01 02 01 01 01 + 02 01 01 02 01 02 01 02 01 02 02 01 01 02 01 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 8A 82 82 8E 88 9A 9F 87 88 8B 8A 8B 8D 8D 8E 90 + 90 93 92 93 95 95 98 97 98 99 9A 9B 9C 9E 9E 9F + A0 A1 AB A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE B0 + B0 B4 B2 B3 B4 FA B6 B7 B8 BA BA BC BC BE BE C0 + C0 C4 C2 C3 C4 CB C6 C7 C8 C9 CA CB CE 9B CE D8 + D0 D1 D2 D3 D4 D5 D6 D7 D8 DA DA DE DC DD DE E0 + E0 E4 E2 E3 E4 E6 E6 87 E9 E9 92 EC EC F0 97 99 + F0 F3 9C F3 F5 F5 F7 F7 F9 F9 FA FD B8 FD AE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 81 83 84 85 86 E7 84 89 80 89 8C 8C 83 8F + 8F 91 EA 91 94 94 96 EE 96 EF 85 CD F2 9D 9D 86 + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA A2 AC AD FE AF + AF B1 B2 B3 B1 B5 B6 B7 FC B9 B9 BB BB BD BD BF + BF C1 C2 C3 C1 C5 C6 C7 C8 C9 CA C5 CC CD CC CF + D0 D1 D2 D3 D4 D5 D6 D7 CF D9 D9 DB DC DD DB DF + DF E1 E2 E3 E1 E5 E5 E7 E8 E8 EA EB EB ED EE EF + ED F1 F2 F1 F4 F4 F6 F6 F8 F8 B5 FB FC FB FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C4 0100 0101 00C9 0104 00D6 00DC 00E1 0105 010C 00E4 010D 0106 0107 00E9 0179 + 017A 010E 00ED 010F 0112 0113 0116 00F3 0117 00F4 00F6 00F5 00FA 011A 011B 00FC + 2020 00B0 0118 00A3 00A7 2022 00B6 00DF 00AE 00A9 2122 0119 00A8 2260 0123 012E + 012F 012A 2264 2265 012B 0136 2202 2211 0142 013B 013C 013D 013E 0139 013A 0145 + 0146 0143 00AC 221A 0144 0147 2206 00AB 00BB 2026 00A0 0148 0150 00D5 0151 014C + 2013 2014 201C 201D 2018 2019 00F7 25CA 014D 0154 0155 0158 2039 203A 0159 0156 + 0157 0160 201A 201E 0161 015A 015B 00C1 0164 0165 00CD 017D 017E 016A 00D3 00D4 + 016B 016E 00DA 016F 0170 0171 0172 0173 00DD 00FD 0137 017B 0141 017C 0122 02C7 + diff --git a/sql/share/charsets/macceciai.conf b/sql/share/charsets/macceciai.conf new file mode 100644 index 00000000000..d7cdaddc425 --- /dev/null +++ b/sql/share/charsets/macceciai.conf @@ -0,0 +1,96 @@ +# Mac OS Central European, case insensitive, accent sensitive +# +# Czech (cs), Hungarian (hu), Polish (pl), Romanian (ro), Croatian (hr), +# Slovak (sk), Slovenian (sl), Sorbian. +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 01 02 01 01 01 01 02 02 01 02 02 01 02 02 01 + 02 01 02 02 01 02 01 02 02 02 02 02 02 01 02 02 + 00 00 01 00 00 00 00 02 00 00 00 02 00 00 02 01 + 02 01 00 00 02 01 00 00 02 01 02 01 02 01 02 01 + 02 01 00 00 02 01 00 00 00 00 00 02 01 01 02 01 + 00 00 00 00 00 00 00 00 02 01 02 01 00 00 02 01 + 02 01 00 00 02 01 02 01 01 02 01 01 02 01 01 01 + 02 01 01 02 01 02 01 02 01 02 02 01 01 02 01 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 8A 82 82 8E 88 9A 9F 87 88 8B 8A 8B 8D 8D 8E 90 + 90 93 92 93 95 95 98 97 98 99 9A 9B 9C 9E 9E 9F + A0 A1 AB A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE B0 + B0 B4 B2 B3 B4 FA B6 B7 B8 BA BA BC BC BE BE C0 + C0 C4 C2 C3 C4 CB C6 C7 C8 C9 CA CB CE 9B CE D8 + D0 D1 D2 D3 D4 D5 D6 D7 D8 DA DA DE DC DD DE E0 + E0 E4 E2 E3 E4 E6 E6 87 E9 E9 92 EC EC F0 97 99 + F0 F3 9C F3 F5 F5 F7 F7 F9 F9 FA FD B8 FD AE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 81 83 84 85 86 E7 84 89 80 89 8C 8C 83 8F + 8F 91 EA 91 94 94 96 EE 96 EF 85 CD F2 9D 9D 86 + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA A2 AC AD FE AF + AF B1 B2 B3 B1 B5 B6 B7 FC B9 B9 BB BB BD BD BF + BF C1 C2 C3 C1 C5 C6 C7 C8 C9 CA C5 CC CD CC CF + D0 D1 D2 D3 D4 D5 D6 D7 CF D9 D9 DB DC DD DB DF + DF E1 E2 E3 E1 E5 E5 E7 E8 E8 EA EB EB ED EE EF + ED F1 F2 F1 F4 F4 F6 F6 F8 F8 B5 FB FC FB FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 4B 4D 53 57 63 65 69 6B 73 75 79 83 85 8D + 9B 9D 9F A7 AE B2 C0 C2 C4 C6 CA D2 D3 D4 D5 D6 + D7 41 4B 4D 53 57 63 65 69 6B 73 75 79 83 85 8D + 9B 9D 9F A7 AE B2 C0 C2 C4 C6 CA D8 D9 DA DB DC + 41 41 41 57 41 8D B2 41 41 4D 41 4D 4D 4D 57 CA + CA 53 6B 53 57 57 57 8D 57 8D 8D 8D B2 57 57 B2 + DD DE 57 DF E0 E1 E2 A7 E3 E4 E5 57 E6 E7 65 6B + 6B 6B E8 E9 6B 75 EA EB 79 79 79 79 79 79 79 85 + 85 85 EC ED 85 85 EE EF F0 F1 F2 85 8D 8D 8D 8D + F3 F4 F5 F6 F7 F8 F9 FA 8D 9F 9F 9F FB FC 9F 9F + 9F A7 FD FE A7 A7 A7 41 BE BE 6B CA CA B2 8D 8D + B2 B2 B2 B2 B2 B2 B2 B2 C6 C6 75 CA 79 CA 65 FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C4 0100 0101 00C9 0104 00D6 00DC 00E1 0105 010C 00E4 010D 0106 0107 00E9 0179 + 017A 010E 00ED 010F 0112 0113 0116 00F3 0117 00F4 00F6 00F5 00FA 011A 011B 00FC + 2020 00B0 0118 00A3 00A7 2022 00B6 00DF 00AE 00A9 2122 0119 00A8 2260 0123 012E + 012F 012A 2264 2265 012B 0136 2202 2211 0142 013B 013C 013D 013E 0139 013A 0145 + 0146 0143 00AC 221A 0144 0147 2206 00AB 00BB 2026 00A0 0148 0150 00D5 0151 014C + 2013 2014 201C 201D 2018 2019 00F7 25CA 014D 0154 0155 0158 2039 203A 0159 0156 + 0157 0160 201A 201E 0161 015A 015B 00C1 0164 0165 00CD 017D 017E 016A 00D3 00D4 + 016B 016E 00DA 016F 0170 0171 0172 0173 00DD 00FD 0137 017B 0141 017C 0122 02C7 + diff --git a/sql/share/charsets/maccecias.conf b/sql/share/charsets/maccecias.conf new file mode 100644 index 00000000000..8cefd4cf9ec --- /dev/null +++ b/sql/share/charsets/maccecias.conf @@ -0,0 +1,96 @@ +# Mac OS Central European, case insensitive, accent sensitive +# +# Czech (cs), Hungarian (hu), Polish (pl), Romanian (ro), Croatian (hr), +# Slovak (sk), Slovenian (sl), Sorbian. +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 01 02 01 01 01 01 02 02 01 02 02 01 02 02 01 + 02 01 02 02 01 02 01 02 02 02 02 02 02 01 02 02 + 00 00 01 00 00 00 00 02 00 00 00 02 00 00 02 01 + 02 01 00 00 02 01 00 00 02 01 02 01 02 01 02 01 + 02 01 00 00 02 01 00 00 00 00 00 02 01 01 02 01 + 00 00 00 00 00 00 00 00 02 01 02 01 00 00 02 01 + 02 01 00 00 02 01 02 01 01 02 01 01 02 01 01 01 + 02 01 01 02 01 02 01 02 01 02 02 01 01 02 01 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 8A 82 82 8E 88 9A 9F 87 88 8B 8A 8B 8D 8D 8E 90 + 90 93 92 93 95 95 98 97 98 99 9A 9B 9C 9E 9E 9F + A0 A1 AB A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE B0 + B0 B4 B2 B3 B4 FA B6 B7 B8 BA BA BC BC BE BE C0 + C0 C4 C2 C3 C4 CB C6 C7 C8 C9 CA CB CE 9B CE D8 + D0 D1 D2 D3 D4 D5 D6 D7 D8 DA DA DE DC DD DE E0 + E0 E4 E2 E3 E4 E6 E6 87 E9 E9 92 EC EC F0 97 99 + F0 F3 9C F3 F5 F5 F7 F7 F9 F9 FA FD B8 FD AE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 81 83 84 85 86 E7 84 89 80 89 8C 8C 83 8F + 8F 91 EA 91 94 94 96 EE 96 EF 85 CD F2 9D 9D 86 + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA A2 AC AD FE AF + AF B1 B2 B3 B1 B5 B6 B7 FC B9 B9 BB BB BD BD BF + BF C1 C2 C3 C1 C5 C6 C7 C8 C9 CA C5 CC CD CC CF + D0 D1 D2 D3 D4 D5 D6 D7 CF D9 D9 DB DC DD DB DF + DF E1 E2 E3 E1 E5 E5 E7 E8 E8 EA EB EB ED EE EF + ED F1 F2 F1 F4 F4 F6 F6 F8 F8 B5 FB FC FB FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 4B 4D 53 57 63 65 69 6B 73 75 79 83 85 8D + 9B 9D 9F A7 AE B2 C0 C2 C4 C6 CA D2 D3 D4 D5 D6 + D7 41 4B 4D 53 57 63 65 69 6B 73 75 79 83 85 8D + 9B 9D 9F A7 AE B2 C0 C2 C4 C6 CA D8 D9 DA DB DC + 45 47 47 59 49 91 B6 43 49 4F 45 4F 51 51 59 CE + CE 55 71 55 5B 5B 5D 8F 5D 99 91 97 B8 5F 5F B6 + DD DE 61 DF E0 E1 E2 AD E3 E4 E5 61 E6 E7 67 6F + 6F 6D E8 E9 6D 77 EA EB 7B 81 82 7F 7F 7D 7D 8B + 8B 87 EC ED 87 89 EE EF F0 F1 F2 89 93 97 93 95 + F3 F4 F5 F6 F7 F8 F9 FA 95 A1 A1 A3 FB FC A3 A5 + A5 A9 FD FE A9 AB AB 43 B0 B0 71 CC CC BC 8F 99 + BC B4 B8 B4 BA BA BE BE C8 C8 77 D0 7B D0 67 FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C4 0100 0101 00C9 0104 00D6 00DC 00E1 0105 010C 00E4 010D 0106 0107 00E9 0179 + 017A 010E 00ED 010F 0112 0113 0116 00F3 0117 00F4 00F6 00F5 00FA 011A 011B 00FC + 2020 00B0 0118 00A3 00A7 2022 00B6 00DF 00AE 00A9 2122 0119 00A8 2260 0123 012E + 012F 012A 2264 2265 012B 0136 2202 2211 0142 013B 013C 013D 013E 0139 013A 0145 + 0146 0143 00AC 221A 0144 0147 2206 00AB 00BB 2026 00A0 0148 0150 00D5 0151 014C + 2013 2014 201C 201D 2018 2019 00F7 25CA 014D 0154 0155 0158 2039 203A 0159 0156 + 0157 0160 201A 201E 0161 015A 015B 00C1 0164 0165 00CD 017D 017E 016A 00D3 00D4 + 016B 016E 00DA 016F 0170 0171 0172 0173 00DD 00FD 0137 017B 0141 017C 0122 02C7 + diff --git a/sql/share/charsets/maccecsas.conf b/sql/share/charsets/maccecsas.conf new file mode 100644 index 00000000000..8cc1de422f2 --- /dev/null +++ b/sql/share/charsets/maccecsas.conf @@ -0,0 +1,96 @@ +# Mac OS Central European, case sensitive, accent sensitive +# +# Czech (cs), Hungarian (hu), Polish (pl), Romanian (ro), Croatian (hr), +# Slovak (sk), Slovenian (sl), Sorbian. +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 00 + 01 01 02 01 01 01 01 02 02 01 02 02 01 02 02 01 + 02 01 02 02 01 02 01 02 02 02 02 02 02 01 02 02 + 00 00 01 00 00 00 00 02 00 00 00 02 00 00 02 01 + 02 01 00 00 02 01 00 00 02 01 02 01 02 01 02 01 + 02 01 00 00 02 01 00 00 00 00 00 02 01 01 02 01 + 00 00 00 00 00 00 00 00 02 01 02 01 00 00 02 01 + 02 01 00 00 02 01 02 01 01 02 01 01 02 01 01 01 + 02 01 01 02 01 02 01 02 01 02 02 01 01 02 01 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 54 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 8A 82 82 8E 88 9A 9F 87 88 8B 8A 8B 8D 8D 8E 90 + 90 93 92 93 95 95 98 97 98 99 9A 9B 9C 9E 9E 9F + A0 A1 AB A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE B0 + B0 B4 B2 B3 B4 FA B6 B7 B8 BA BA BC BC BE BE C0 + C0 C4 C2 C3 C4 CB C6 C7 C8 C9 CA CB CE 9B CE D8 + D0 D1 D2 D3 D4 D5 D6 D7 D8 DA DA DE DC DD DE E0 + E0 E4 E2 E3 E4 E6 E6 87 E9 E9 92 EC EC F0 97 99 + F0 F3 9C F3 F5 F5 F7 F7 F9 F9 FA FD B8 FD AE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 74 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 81 83 84 85 86 E7 84 89 80 89 8C 8C 83 8F + 8F 91 EA 91 94 94 96 EE 96 EF 85 CD F2 9D 9D 86 + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA A2 AC AD FE AF + AF B1 B2 B3 B1 B5 B6 B7 FC B9 B9 BB BB BD BD BF + BF C1 C2 C3 C1 C5 C6 C7 C8 C9 CA C5 CC CD CC CF + D0 D1 D2 D3 D4 D5 D6 D7 CF D9 D9 DB DC DD DB DF + DF E1 E2 E3 E1 E5 E5 E7 E8 E8 EA EB EB ED EE EF + ED F1 F2 F1 F4 F4 F6 F6 F8 F8 B5 FB FC FB FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 4B 4D 53 57 63 65 69 6B 73 75 79 83 85 8D + 9B 9D 9F A7 AE B2 C0 C2 C4 C6 CA D2 D3 D4 D5 D6 + D7 42 4C 4E 54 58 64 66 6A 6C 74 76 7A 84 86 8E + 9C 9E A0 A8 AF B3 C1 C3 C5 C7 CB D8 D9 DA DB DC + 45 47 48 59 49 91 B6 44 4A 4F 46 50 51 52 5A CE + CF 55 72 56 5B 5C 5D 90 5E 9A 92 98 B8 5F 60 B7 + DD DE 61 DF E0 E1 E2 AD E3 E4 E5 62 E6 E7 68 6F + 70 6D E8 E9 6E 77 EA EB 7C 81 82 7F 80 7D 7E 8B + 8C 87 EC ED 88 89 EE EF F0 F1 F2 8A 93 97 94 95 + F3 F4 F5 F6 F7 F8 F9 FA 96 A1 A2 A3 FB FC A4 A5 + A6 A9 FD FE AA AB AC 43 B0 B1 71 CC CD BC 8F 99 + BD B4 B9 B5 BA BB BE BF C8 C9 78 D0 7B D1 67 FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C4 0100 0101 00C9 0104 00D6 00DC 00E1 0105 010C 00E4 010D 0106 0107 00E9 0179 + 017A 010E 00ED 010F 0112 0113 0116 00F3 0117 00F4 00F6 00F5 00FA 011A 011B 00FC + 2020 00B0 0118 00A3 00A7 2022 00B6 00DF 00AE 00A9 2122 0119 00A8 2260 0123 012E + 012F 012A 2264 2265 012B 0136 2202 2211 0142 013B 013C 013D 013E 0139 013A 0145 + 0146 0143 00AC 221A 0144 0147 2206 00AB 00BB 2026 00A0 0148 0150 00D5 0151 014C + 2013 2014 201C 201D 2018 2019 00F7 25CA 014D 0154 0155 0158 2039 203A 0159 0156 + 0157 0160 201A 201E 0161 015A 015B 00C1 0164 0165 00CD 017D 017E 016A 00D3 00D4 + 016B 016E 00DA 016F 0170 0171 0172 0173 00DD 00FD 0137 017B 0141 017C 0122 02C7 + diff --git a/sql/share/charsets/macromanbin.conf b/sql/share/charsets/macromanbin.conf new file mode 100644 index 00000000000..d0845c07f2b --- /dev/null +++ b/sql/share/charsets/macromanbin.conf @@ -0,0 +1,96 @@ +# +# Mac OS Roman, accent insensitive, case insensitive +# +# Binary sort order +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 10 + 20 01 01 01 01 01 01 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 00 00 00 00 00 00 00 02 00 00 00 00 00 00 01 01 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 02 + 00 00 00 00 02 00 00 00 00 00 00 20 01 01 01 02 + 00 00 00 00 00 00 00 00 02 01 00 00 00 00 00 00 + 00 00 00 00 00 20 01 01 01 01 01 01 01 01 01 01 + 00 01 01 01 01 02 00 00 00 00 00 00 00 00 00 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 8A 8C 8D 8E 96 9A 9F 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD BE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA 88 8B 9B CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D8 DA DB DC DD DE DF + E0 E1 E2 E3 E4 89 90 87 91 8F 92 94 95 93 97 99 + F0 98 9C 9E 9D F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 E7 CB E5 80 CC 81 82 83 E9 + E6 E8 EA ED EB EC 84 EE F1 EF 85 CD F2 F4 F3 86 + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD AE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D9 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C4 00C5 00C7 00C9 00D1 00D6 00DC 00E1 00E0 00E2 00E4 00E3 00E5 00E7 00E9 00E8 + 00EA 00EB 00ED 00EC 00EE 00EF 00F1 00F3 00F2 00F4 00F6 00F5 00FA 00F9 00FB 00FC + 2020 00B0 00A2 00A3 00A7 2022 00B6 00DF 00AE 00A9 2122 00B4 00A8 2260 00C6 00D8 + 221E 00B1 2264 2265 00A5 00B5 2202 2211 220F 03C0 222B 00AA 00BA 03A9 00E6 00F8 + 00BF 00A1 00AC 221A 0192 2248 2206 00AB 00BB 2026 00A0 00C0 00C3 00D5 0152 0153 + 2013 2014 201C 201D 2018 2019 00F7 25CA 00FF 0178 2044 20AC 2039 203A FB01 FB02 + 2021 00B7 201A 201E 2030 00C2 00CA 00C1 00CB 00C8 00CD 00CE 00CF 00CC 00D3 00D4 + F8FF 00D2 00DA 00DB 00D9 0131 02C6 02DC 00AF 02D8 02D9 02DA 00B8 02DD 02DB 02C7 + diff --git a/sql/share/charsets/macromanciai.conf b/sql/share/charsets/macromanciai.conf new file mode 100644 index 00000000000..457e6b4f8d9 --- /dev/null +++ b/sql/share/charsets/macromanciai.conf @@ -0,0 +1,97 @@ +# +# Mac OS Roman, accent insensitive, case insensitive +# +# Sort order: Dutch, English, French, German (Duden), +# Italian, Latin, Pogtuguese, Spanish +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 10 + 20 01 01 01 01 01 01 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 00 00 00 00 00 00 00 02 00 00 00 00 00 00 01 01 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 02 + 00 00 00 00 02 00 00 00 00 00 00 20 01 01 01 02 + 00 00 00 00 00 00 00 00 02 01 00 00 00 00 00 00 + 00 00 00 00 00 20 01 01 01 01 01 01 01 01 01 01 + 00 01 01 01 01 02 00 00 00 00 00 00 00 00 00 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 8A 8C 8D 8E 96 9A 9F 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD BE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA 88 8B 9B CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D8 DA DB DC DD DE DF + E0 E1 E2 E3 E4 89 90 87 91 8F 92 94 95 93 97 99 + F0 98 9C 9E 9D F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 E7 CB E5 80 CC 81 82 83 E9 + E6 E8 EA ED EB EC 84 EE F1 EF 85 CD F2 F4 F3 86 + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD AE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D9 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 51 53 57 59 63 66 68 6A 75 77 79 7B 7D 81 + 91 93 95 97 9A 9C A6 A8 AA AC B0 B2 B3 B4 B5 B6 + B7 41 51 53 57 59 63 66 68 6A 75 77 79 7B 7D 81 + 91 93 95 97 9A 9C A6 A8 AA AC B0 B8 B9 BA BB BC + 41 41 53 59 7D 81 9C 41 41 41 41 41 41 53 59 59 + 59 59 6A 6A 6A 6A 7D 81 81 81 81 81 9C 9C 9C 9C + BD BE BF C0 C1 C2 C3 97 C4 C5 C6 C7 C8 C9 41 81 + CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 41 81 + D8 D9 DA DB 63 DC DD DE DF E0 E1 41 41 81 81 81 + E2 E3 E4 E5 E6 E7 E8 E9 AC AC EA EB EC ED EE EF + F0 F1 F2 F3 F4 41 59 41 59 59 6A 6A 6A 6A 81 81 + F0 81 9C 9C 9C 6A F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C4 00C5 00C7 00C9 00D1 00D6 00DC 00E1 00E0 00E2 00E4 00E3 00E5 00E7 00E9 00E8 + 00EA 00EB 00ED 00EC 00EE 00EF 00F1 00F3 00F2 00F4 00F6 00F5 00FA 00F9 00FB 00FC + 2020 00B0 00A2 00A3 00A7 2022 00B6 00DF 00AE 00A9 2122 00B4 00A8 2260 00C6 00D8 + 221E 00B1 2264 2265 00A5 00B5 2202 2211 220F 03C0 222B 00AA 00BA 03A9 00E6 00F8 + 00BF 00A1 00AC 221A 0192 2248 2206 00AB 00BB 2026 00A0 00C0 00C3 00D5 0152 0153 + 2013 2014 201C 201D 2018 2019 00F7 25CA 00FF 0178 2044 20AC 2039 203A FB01 FB02 + 2021 00B7 201A 201E 2030 00C2 00CA 00C1 00CB 00C8 00CD 00CE 00CF 00CC 00D3 00D4 + F8FF 00D2 00DA 00DB 00D9 0131 02C6 02DC 00AF 02D8 02D9 02DA 00B8 02DD 02DB 02C7 + diff --git a/sql/share/charsets/macromancias.conf b/sql/share/charsets/macromancias.conf new file mode 100644 index 00000000000..a00d7d412e6 --- /dev/null +++ b/sql/share/charsets/macromancias.conf @@ -0,0 +1,97 @@ +# +# Mac OS Roman, accent sensitive, case insensitive +# +# Sort order: Dutch, English, French, German (Duden), +# Italian, Latin, Pogtuguese, Spanish +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 10 + 20 01 01 01 01 01 01 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 00 00 00 00 00 00 00 02 00 00 00 00 00 00 01 01 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 02 + 00 00 00 00 02 00 00 00 00 00 00 20 01 01 01 02 + 00 00 00 00 00 00 00 00 02 01 00 00 00 00 00 00 + 00 00 00 00 00 20 01 01 01 01 01 01 01 01 01 01 + 00 01 01 01 01 02 00 00 00 00 00 00 00 00 00 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 8A 8C 8D 8E 96 9A 9F 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD BE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA 88 8B 9B CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D8 DA DB DC DD DE DF + E0 E1 E2 E3 E4 89 90 87 91 8F 92 94 95 93 97 99 + F0 98 9C 9E 9D F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 E7 CB E5 80 CC 81 82 83 E9 + E6 E8 EA ED EB EC 84 EE F1 EF 85 CD F2 F4 F3 86 + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD AE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D9 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 51 53 57 59 63 66 68 6A 75 77 79 7B 7D 81 + 91 93 95 97 9A 9C A6 A8 AA AC B0 B2 B3 B4 B5 B6 + B7 41 51 53 57 59 63 66 68 6A 75 77 79 7B 7D 81 + 91 93 95 97 9A 9C A6 A8 AA AC B0 B8 B9 BA BB BC + 4B 4D 55 5D 7F 8B A4 45 43 47 4B 49 4D 55 5D 5B + 5F 61 6E 6C 70 72 7F 85 83 87 8B 89 A0 9E A2 A4 + BD BE BF C0 C1 C2 C3 99 C4 C5 C6 C7 C8 C9 4F 8D + CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 4F 8D + D8 D9 DA DB 65 DC DD DE DF E0 E1 43 49 89 8F 8F + E2 E3 E4 E5 E6 E7 E8 E9 AE AE EA EB EC ED EE EF + F0 F1 F2 F3 F4 47 5F 45 61 5B 6E 70 70 6C 85 87 + F0 83 A0 A2 9E 72 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C4 00C5 00C7 00C9 00D1 00D6 00DC 00E1 00E0 00E2 00E4 00E3 00E5 00E7 00E9 00E8 + 00EA 00EB 00ED 00EC 00EE 00EF 00F1 00F3 00F2 00F4 00F6 00F5 00FA 00F9 00FB 00FC + 2020 00B0 00A2 00A3 00A7 2022 00B6 00DF 00AE 00A9 2122 00B4 00A8 2260 00C6 00D8 + 221E 00B1 2264 2265 00A5 00B5 2202 2211 220F 03C0 222B 00AA 00BA 03A9 00E6 00F8 + 00BF 00A1 00AC 221A 0192 2248 2206 00AB 00BB 2026 00A0 00C0 00C3 00D5 0152 0153 + 2013 2014 201C 201D 2018 2019 00F7 25CA 00FF 0178 2044 20AC 2039 203A FB01 FB02 + 2021 00B7 201A 201E 2030 00C2 00CA 00C1 00CB 00C8 00CD 00CE 00CF 00CC 00D3 00D4 + F8FF 00D2 00DA 00DB 00D9 0131 02C6 02DC 00AF 02D8 02D9 02DA 00B8 02DD 02DB 02C7 + diff --git a/sql/share/charsets/macromancsas.conf b/sql/share/charsets/macromancsas.conf new file mode 100644 index 00000000000..1f67148680d --- /dev/null +++ b/sql/share/charsets/macromancsas.conf @@ -0,0 +1,97 @@ +# +# Mac OS Roman, accent sensitive, case sensitive +# +# Sort order: Dutch, English, French, German (Duden), +# Italian, Latin, Pogtuguese, Spanish +# +# ctype array (must be 257 elements) + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 10 + 20 01 01 01 01 01 01 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 00 00 00 00 00 00 00 02 00 00 00 00 00 00 01 01 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 02 + 00 00 00 00 02 00 00 00 00 00 00 20 01 01 01 02 + 00 00 00 00 00 00 00 00 02 01 00 00 00 00 00 00 + 00 00 00 00 00 20 01 01 01 01 01 01 01 01 01 01 + 00 01 01 01 01 02 00 00 00 00 00 00 00 00 00 00 + +# to_lower array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 8A 8C 8D 8E 96 9A 9F 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD BE BF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA 88 8B 9B CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D8 DA DB DC DD DE DF + E0 E1 E2 E3 E4 89 90 87 91 8F 92 94 95 93 97 99 + F0 98 9C 9E 9D F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# to_upper array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 E7 CB E5 80 CC 81 82 83 E9 + E6 E8 EA ED EB EC 84 EE F1 EF 85 CD F2 F4 F3 86 + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD AE AF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D9 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + +# sort_order array (must be 256 elements) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 51 53 57 59 63 66 68 6A 75 77 79 7B 7D 81 + 91 93 95 97 9A 9C A6 A8 AA AC B0 B2 B3 B4 B5 B6 + B7 42 52 54 58 5A 64 67 69 6B 76 78 7A 7C 7E 82 + 92 94 96 98 9B 9D A7 A9 AB AD B1 B8 B9 BA BB BC + 4B 4D 55 5D 7F 8B A4 46 44 48 4C 4A 4E 56 5E 5C + 60 62 6F 6D 71 73 80 86 84 88 8C 8A A1 9F A3 A5 + BD BE BF C0 C1 C2 C3 99 C4 C5 C6 C7 C8 C9 4F 8D + CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 50 8E + D8 D9 DA DB 65 DC DD DE DF E0 E1 43 49 89 8F 90 + E2 E3 E4 E5 E6 E7 E8 E9 AF AE EA EB EC ED EE EF + F0 F1 F2 F3 F4 47 5F 45 61 5B 6E 70 72 6C 85 87 + F0 83 A0 A2 9E 74 F6 F7 F8 F9 FA FB FC FD FE FF + +# Unicode mapping (must be 256 elements) + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 00C4 00C5 00C7 00C9 00D1 00D6 00DC 00E1 00E0 00E2 00E4 00E3 00E5 00E7 00E9 00E8 + 00EA 00EB 00ED 00EC 00EE 00EF 00F1 00F3 00F2 00F4 00F6 00F5 00FA 00F9 00FB 00FC + 2020 00B0 00A2 00A3 00A7 2022 00B6 00DF 00AE 00A9 2122 00B4 00A8 2260 00C6 00D8 + 221E 00B1 2264 2265 00A5 00B5 2202 2211 220F 03C0 222B 00AA 00BA 03A9 00E6 00F8 + 00BF 00A1 00AC 221A 0192 2248 2206 00AB 00BB 2026 00A0 00C0 00C3 00D5 0152 0153 + 2013 2014 201C 201D 2018 2019 00F7 25CA 00FF 0178 2044 20AC 2039 203A FB01 FB02 + 2021 00B7 201A 201E 2030 00C2 00CA 00C1 00CB 00C8 00CD 00CE 00CF 00CC 00D3 00D4 + F8FF 00D2 00DA 00DB 00D9 0131 02C6 02DC 00AF 02D8 02D9 02DA 00B8 02DD 02DB 02C7 + -- cgit v1.2.1 From aa4a6df4a0fe9a128f5dd03df9e14ce8649e61c9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Sep 2002 21:55:26 +0500 Subject: "SHOW CHARACTER SET" now displays 1 for 8bit charsets in "mb_maxlen" column. 0 was dispayed before, this looked confusing. --- sql/sql_show.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e227a5bf5ca..7ac0affbec5 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1391,7 +1391,7 @@ int mysqld_show_charsets(THD *thd, const char *wild) net_store_data(&packet2,convert,cs->name); net_store_data(&packet2,(uint32) cs->number); net_store_data(&packet2,(uint32) cs->strxfrm_multiply); - net_store_data(&packet2,(uint32) cs->mbmaxlen); + net_store_data(&packet2,(uint32) cs->mbmaxlen ? cs->mbmaxlen : 1); if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length())) goto err; -- cgit v1.2.1 From d9c701eb3df84ba06eb4a57758d5df39a07cbc59 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Sep 2002 19:36:22 +0500 Subject: Now table and database inhirited a character set from a level above at CREATE time Some optimization to reduce rules number in sql_yacc.yy mysql-test/r/create.result: Now table and database inhirited a character set from a level above at CREATE time mysql-test/r/fulltext.result: Now table and database inhirited a character set from a level above at CREATE time mysql-test/r/innodb.result: Now table and database inhirited a character set from a level above at CREATE time mysql-test/r/merge.result: Now table and database inhirited a character set from a level above at CREATE time mysql-test/r/show_check.result: Now table and database inhirited a character set from a level above at CREATE time mysql-test/r/symlink.result: Now table and database inhirited a character set from a level above at CREATE time mysql-test/r/type_enum.result: Now table and database inhirited a character set from a level above at CREATE time mysql-test/r/type_set.result: Now table and database inhirited a character set from a level above at CREATE time sql/sql_yacc.yy: Now table and database inhirited a character set from a level above at CREATE time Some optimization to reduce rules number --- sql/sql_yacc.yy | 69 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 35 deletions(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 01894bfb7ad..7d6163fafc3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -67,6 +67,7 @@ inline Item *or_or_concat(Item* A, Item* B) interval_type interval; LEX_USER *lex_user; enum Item_udftype udf_type; + CHARSET_INFO *charset; } %{ @@ -600,6 +601,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type user grant_user +%type + charset_name + charset_name_or_default + opt_db_default_character_set + %type query verb_clause create change select do drop insert replace insert2 insert_values update delete truncate rename @@ -758,6 +764,7 @@ master_def: create: CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident { + THD *thd=current_thd; LEX *lex=Lex; lex->sql_command= SQLCOM_CREATE_TABLE; if (!add_table_to_list($5, @@ -771,7 +778,7 @@ create: bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.options=$2 | $4; lex->create_info.db_type= default_table_type; - lex->create_info.table_charset=NULL; + lex->create_info.table_charset=thd->db_charset?thd->db_charset:default_charset_info; } create2 @@ -793,13 +800,13 @@ create: lex->key_list.push_back(new Key($2,$4.str, $5, lex->col_list)); lex->col_list.empty(); } - | CREATE DATABASE opt_if_not_exists ident default_charset + | CREATE DATABASE opt_if_not_exists ident opt_db_default_character_set { LEX *lex=Lex; lex->sql_command=SQLCOM_CREATE_DB; lex->name=$4.str; lex->create_info.options=$3; - lex->create_info.table_charset=lex->charset; + lex->create_info.table_charset=$5; } | CREATE udf_func_type UDF_SYM ident { @@ -886,9 +893,9 @@ create_table_option: table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } - | CHARSET EQ charset_or_nocharset + | CHARSET EQ charset_name_or_default { - Lex->create_info.table_charset=Lex->charset; + Lex->create_info.table_charset= $3; Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET; } | INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} @@ -996,7 +1003,7 @@ type: $$=FIELD_TYPE_TINY; } | BOOL_SYM { Lex->length=(char*) "1"; $$=FIELD_TYPE_TINY; } - | char '(' NUM ')' opt_binary { Lex->length=$3.str; + | char '(' NUM ')' opt_binary { Lex->length=$3.str; $$=FIELD_TYPE_STRING; } | char opt_binary { Lex->length=(char*) "1"; $$=FIELD_TYPE_STRING; } @@ -1125,28 +1132,28 @@ attribute: | UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; } | COMMENT_SYM text_literal { Lex->comment= $2; }; -charset: +charset_name: ident { - if (!(Lex->charset=get_charset_by_name($1.str,MYF(0)))) + if (!($$=get_charset_by_name($1.str,MYF(0)))) { net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$1.str); YYABORT; } }; -charset_or_nocharset: - charset - | DEFAULT {Lex->charset=NULL; } +charset_name_or_default: + charset_name { $$=$1; } + | DEFAULT { $$=NULL; } ; -opt_binary: - /* empty */ { Lex->charset=NULL; } - | BINARY { Lex->type|=BINARY_FLAG; Lex->charset=NULL; } - | CHAR_SYM SET charset {/* charset is already in Lex->charset */} ; +opt_db_default_character_set: + /* empty */ { $$=default_charset_info; } + | DEFAULT CHAR_SYM SET charset_name_or_default { $$=$4; }; -default_charset: +opt_binary: /* empty */ { Lex->charset=NULL; } - | DEFAULT CHAR_SYM SET charset_or_nocharset ; + | BINARY { Lex->type|=BINARY_FLAG; Lex->charset=NULL; } + | CHAR_SYM SET charset_name { Lex->charset=$3; } ; references: REFERENCES table_ident @@ -1247,6 +1254,7 @@ string_list: alter: ALTER opt_ignore TABLE_SYM table_ident { + THD *thd=current_thd; LEX *lex=Lex; lex->sql_command = SQLCOM_ALTER_TABLE; lex->name=0; @@ -1264,20 +1272,20 @@ alter: lex->select->db=lex->name=0; bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.db_type= DB_TYPE_DEFAULT; + lex->create_info.table_charset=thd->db_charset?thd->db_charset:default_charset_info; lex->create_info.row_type= ROW_TYPE_NOT_USED; - lex->create_info.table_charset=NULL; lex->alter_keys_onoff=LEAVE_AS_IS; lex->simple_alter=1; } alter_list; - | ALTER DATABASE ident default_charset + | ALTER DATABASE ident opt_db_default_character_set { LEX *lex=Lex; lex->sql_command=SQLCOM_ALTER_DB; lex->name=$3.str; - lex->create_info.table_charset=lex->charset; - } + lex->create_info.table_charset=$4; + }; alter_list: @@ -1660,15 +1668,8 @@ expr_expr: { $$= new Item_date_add_interval($1,$4,$5,0); } | expr '-' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,1); } - | expr COLLATE_SYM ident - { - if (!(Lex->charset=get_charset_by_name($3.str,MYF(0)))) - { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3.str); - YYABORT; - } - $$= new Item_func_set_collation($1,Lex->charset); - }; + | expr COLLATE_SYM charset_name + { $$= new Item_func_set_collation($1,$3); }; /* expressions that begin with 'expr' that do NOT follow IN_SYM */ no_in_expr: @@ -1783,12 +1784,10 @@ simple_expr: | CASE_SYM opt_expr WHEN_SYM when_list opt_else END { $$= new Item_func_case(* $4, $2, $5 ); } | CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); } - | CONVERT_SYM '(' expr USING charset ')' - { $$= new Item_func_conv_charset($3,Lex->charset); } + | CONVERT_SYM '(' expr USING charset_name ')' + { $$= new Item_func_conv_charset($3,$5); } | CONVERT_SYM '(' expr ',' expr ',' expr ')' - { - $$= new Item_func_conv_charset3($3,$7,$5); - } + { $$= new Item_func_conv_charset3($3,$7,$5); } | FUNC_ARG0 '(' ')' { $$= ((Item*(*)(void))($1.symbol->create_func))();} | FUNC_ARG1 '(' expr ')' -- cgit v1.2.1 From d6d2440f433fc03dd0732f3bdb5307cb58114a0d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Sep 2002 14:11:06 +0500 Subject: Fixed that: SELECT * FROM t WHERE (c COLLATE latin1) >'a' might fail in some cases --- sql/item_strfunc.cc | 8 +++++--- sql/item_strfunc.h | 5 +---- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index dc9d57b1d9d..243f11db106 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1943,7 +1943,8 @@ void Item_func_conv_charset3::fix_length_and_dec() String *Item_func_set_collation::val_str(String *str) { str=args[0]->val_str(str); - null_value=args[0]->null_value; + if ((null_value=args[0]->null_value)) + return 0; str->set_charset(set_collation); return str; } @@ -1961,8 +1962,10 @@ bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, return 1; maybe_null=args[0]->maybe_null; binary=args[0]->binary; - const_item_cache=args[0]->const_item(); str_value.set_charset(set_collation); + with_sum_func= with_sum_func || args[0]->with_sum_func; + used_tables_cache=args[0]->used_tables(); + const_item_cache=args[0]->const_item(); fix_length_and_dec(); return 0; } @@ -1987,7 +1990,6 @@ bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const return 1; } - String *Item_func_charset::val_str(String *str) { String *res = args[0]->val_str(str); diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 997d9c8d834..af94e387717 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -504,10 +504,7 @@ public: bool fix_fields(THD *thd,struct st_table_list *tables, Item **ref); String *val_str(String *); void fix_length_and_dec() - { - max_length = args[0]->max_length; - str_value.set_charset(set_collation); - } + { max_length = args[0]->max_length; } bool eq(const Item *item, bool binary_cmp) const; const char *func_name() const { return "set_collation"; } }; -- cgit v1.2.1 From 3444f0426b89f7ff86479e9a0e659bba04108924 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Sep 2002 18:35:29 +0500 Subject: Fixed that CHARSET keyword could not be used as identifier --- sql/sql_yacc.yy | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7d6163fafc3..befd1c6b637 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3238,6 +3238,7 @@ keyword: | BOOLEAN_SYM {} | CACHE_SYM {} | CHANGED {} + | CHARSET {} | CHECKSUM_SYM {} | CHECK_SYM {} | CIPHER_SYM {} -- cgit v1.2.1 From 9396cc5a4a063f2cccd83721932abb98ce238459 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Sep 2002 23:08:22 +0300 Subject: new EXPLAIN fixed bug in mysql-test/create-test-result fixed bug in union-subselect engine mysql-test/create-test-result: fixed bug in reject file name assembling mysql-test/r/compare.result: new EXPLAIN mysql-test/r/create.result: new EXPLAIN mysql-test/r/distinct.result: new EXPLAIN mysql-test/r/explain.result: new EXPLAIN mysql-test/r/group_by.result: new EXPLAIN mysql-test/r/heap.result: new EXPLAIN mysql-test/r/heap_btree.result: new EXPLAIN mysql-test/r/heap_hash.result: new EXPLAIN mysql-test/r/innodb.result: new EXPLAIN mysql-test/r/join_outer.result: new EXPLAIN mysql-test/r/key_diff.result: new EXPLAIN mysql-test/r/key_primary.result: new EXPLAIN mysql-test/r/merge.result: new EXPLAIN mysql-test/r/myisam.result: new EXPLAIN mysql-test/r/null_key.result: new EXPLAIN mysql-test/r/odbc.result: new EXPLAIN mysql-test/r/order_by.result: new EXPLAIN mysql-test/r/range.result: new EXPLAIN mysql-test/r/select.result: new EXPLAIN mysql-test/r/subselect.result: new EXPLAIN mysql-test/r/type_datetime.result: new EXPLAIN mysql-test/r/union.result: new EXPLAIN mysql-test/r/user_var.result: new EXPLAIN mysql-test/r/varbinary.result: new EXPLAIN mysql-test/t/subselect.test: new EXPLAIN mysql-test/t/union.test: new EXPLAIN sql/mysql_priv.h: new EXPLAIN sql/sql_class.cc: new EXPLAIN sql/sql_class.h: new EXPLAIN sql/sql_derived.cc: new EXPLAIN sql/sql_lex.h: new EXPLAIN sql/sql_parse.cc: new EXPLAIN sql/sql_select.cc: new EXPLAIN sql/sql_union.cc: fixed bug in subselect-UNION engine sql/table.h: new EXPLAIN --- sql/mysql_priv.h | 9 +++- sql/sql_class.cc | 22 ++++++++ sql/sql_class.h | 3 ++ sql/sql_derived.cc | 23 ++++---- sql/sql_lex.h | 4 +- sql/sql_parse.cc | 108 +++++++++++++++++++++++++++++++++---- sql/sql_select.cc | 153 +++++++++++++++++++++++++---------------------------- sql/sql_union.cc | 23 +++++--- sql/table.h | 3 ++ 9 files changed, 237 insertions(+), 111 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d3901770230..dbf853431d6 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -373,9 +373,14 @@ int handle_select(THD *thd, LEX *lex, select_result *result); int mysql_select(THD *thd,TABLE_LIST *tables,List &list,COND *conds, ORDER *order, ORDER *group,Item *having,ORDER *proc_param, ulong select_type,select_result *result, - SELECT_LEX_UNIT *unit, bool fake_select_lex); + SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex, + bool fake_select_lex); +void fix_tables_pointers(SELECT_LEX *select_lex); +int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type, + select_result *result); int mysql_union(THD *thd, LEX *lex,select_result *result); -int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t); +int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t, + bool tables_is_opened); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item_result_field ***copy_func, Field **from_field, bool group,bool modify_item); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b84bcf1df72..c090f2336c1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -357,6 +357,28 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(TABLE *table) return new_table; } +int THD::send_explain_fields(select_result *result) +{ + List field_list; + Item *item; + field_list.push_back(new Item_int("id",0,3)); + field_list.push_back(new Item_empty_string("select_type",19)); + field_list.push_back(new Item_empty_string("table",NAME_LEN)); + field_list.push_back(new Item_empty_string("type",10)); + field_list.push_back(item=new Item_empty_string("possible_keys", + NAME_LEN*MAX_KEY)); + item->maybe_null=1; + field_list.push_back(item=new Item_empty_string("key",NAME_LEN)); + item->maybe_null=1; + field_list.push_back(item=new Item_int("key_len",0,3)); + item->maybe_null=1; + field_list.push_back(item=new Item_empty_string("ref", + NAME_LEN*MAX_REF_PARTS)); + item->maybe_null=1; + field_list.push_back(new Item_real("rows",0.0,0,10)); + field_list.push_back(new Item_empty_string("Extra",255)); + return (result->send_fields(field_list,1)); +} /***************************************************************************** ** Functions to provide a interface to select results diff --git a/sql/sql_class.h b/sql/sql_class.h index 82241f0ff1f..7be9a5ad9fe 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -315,6 +315,7 @@ public: }; class delayed_insert; +class select_result; #define THD_SENTRY_MAGIC 0xfeedd1ff #define THD_SENTRY_GONE 0xdeadbeef @@ -442,6 +443,7 @@ public: uint server_status,open_options; uint32 query_length; uint32 db_length; + uint select_number; //number of select (used for EXPLAIN) enum_tx_isolation tx_isolation, session_tx_isolation; char scramble[9]; uint8 query_cache_type; // type of query cache processing @@ -576,6 +578,7 @@ public: } void add_changed_table(TABLE *table); CHANGED_TABLE_LIST * changed_table_dup(TABLE *table); + int send_explain_fields(select_result *result); }; /* diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index cde120f3774..539a9edb479 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -28,7 +28,8 @@ static const char *any_db="*any*"; // Special symbol for check_access -int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) +int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t, + bool tables_is_opened) { /* TODO: make derived tables with union inside (now only 1 SELECT may be @@ -37,7 +38,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) SELECT_LEX *sl= unit->first_select(); List item_list; TABLE *table; - int res; + int res= 0; select_union *derived_result; TABLE_LIST *tables= (TABLE_LIST *)sl->table_list.first; TMP_TABLE_PARAM tmp_table_param; @@ -56,7 +57,8 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) { if (cursor->derived) { - res=mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, cursor); + res=mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, + cursor, 0); if (res) DBUG_RETURN(res); } } @@ -66,7 +68,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) while ((item= it++)) item_list.push_back(item); - if (!(res=open_and_lock_tables(thd,tables))) + if (tables_is_opened || !(res=open_and_lock_tables(thd,tables))) { if (tables && setup_fields(thd,tables,item_list,0,0,1)) { @@ -94,12 +96,12 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) if (unit->select_limit_cnt == HA_POS_ERROR) sl->options&= ~OPTION_FOUND_ROWS; - res=mysql_select(thd, tables, sl->item_list, - sl->where, (ORDER *) sl->order_list.first, - (ORDER*) sl->group_list.first, - sl->having, (ORDER*) NULL, - sl->options | thd->options | SELECT_NO_UNLOCK, - derived_result, unit, 0); + res= mysql_select(thd, tables, sl->item_list, + sl->where, (ORDER *) sl->order_list.first, + (ORDER*) sl->group_list.first, + sl->having, (ORDER*) NULL, + sl->options | thd->options | SELECT_NO_UNLOCK, + derived_result, unit, sl, 0); if (!res) { // Here we entirely fix both TABLE_LIST and list of SELECT's as there were no derived tables @@ -109,6 +111,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) { t->real_name=table->real_name; t->table=table; + table->derived_select_number= sl->select_number; sl->exclude(); t->derived=(SELECT_LEX *)0; // just in case ... } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index b75826663ca..e6054f5604b 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -282,8 +282,10 @@ public: List *ftfunc_list; List ftfunc_list_alloc; JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */ + const char *type; /* type of select for EXPLAIN */ uint in_sum_expr; - bool create_refs, + uint select_number; /* number of select (used for EXPLAIN) */ + bool create_refs, braces, /* SELECT ... UNION (SELECT ... ) <- this braces */ depended, /* depended from outer select subselect */ /* TRUE when having fix field called in processing of this SELECT */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9977eaad0ff..8166a156b8c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1254,7 +1254,7 @@ mysql_execute_command(void) THD *thd= current_thd; LEX *lex= &thd->lex; TABLE_LIST *tables= (TABLE_LIST*) lex->select_lex.table_list.first; - SELECT_LEX *select_lex= lex->select; + SELECT_LEX *select_lex= &lex->select_lex; SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); @@ -1281,18 +1281,69 @@ mysql_execute_command(void) #endif } + select_result *explain_result= 0; /* - Skip if we are in the slave thread, some table rules have been given - and the table list says the query should not be replicated + TODO: make derived tables processing 'inside' SELECT processing. + TODO: solve problem with depended derived tables in subselects */ - if (lex->derived_tables) + if (lex->sql_command == SQLCOM_SELECT && + (select_lex->options & SELECT_DESCRIBE) && + lex->derived_tables) + { + if (!(explain_result= new select_send())) + { + send_error(&thd->net, ER_OUT_OF_RESOURCES); + DBUG_VOID_RETURN; + } + //check rights + for (TABLE_LIST *cursor= tables; + cursor; + cursor= cursor->next) + if (cursor->derived) + { + TABLE_LIST *tables= + (TABLE_LIST *)((SELECT_LEX_UNIT *) + cursor->derived)->first_select()->table_list.first; + int res; + if (tables) + res= check_table_access(thd,SELECT_ACL, tables); + else + res= check_access(thd, SELECT_ACL, any_db); + if (res) + DBUG_VOID_RETURN; + } + thd->send_explain_fields(explain_result); + // EXPLAIN derived tables + for (TABLE_LIST *cursor= tables; + cursor; + cursor= cursor->next) + if (cursor->derived) + { + SELECT_LEX *select_lex= ((SELECT_LEX_UNIT *) + cursor->derived)->first_select(); + if (!open_and_lock_tables(thd, + (TABLE_LIST*) select_lex->table_list.first)) + { + mysql_explain_select(thd, select_lex, + "DERIVED", explain_result); + // execute derived table SELECT to provide table for other SELECTs + if (mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, + cursor, 1)) + DBUG_VOID_RETURN; + } + else + DBUG_VOID_RETURN; + } + + } + else if (lex->derived_tables) { for (TABLE_LIST *cursor= tables; cursor; cursor= cursor->next) if (cursor->derived && mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, - cursor)) + cursor, 0)) DBUG_VOID_RETURN; } if ((lex->select_lex.next_select_in_list() && @@ -1374,8 +1425,44 @@ mysql_execute_command(void) if (!(res=open_and_lock_tables(thd,tables))) { - query_cache_store_query(thd, tables); - res=handle_select(thd, lex, result); + if (select_lex->options & SELECT_DESCRIBE) + { + delete result; // we do not need it for explain + if (!explain_result) + if (!(explain_result= new select_send())) + { + send_error(&thd->net, ER_OUT_OF_RESOURCES); + DBUG_VOID_RETURN; + } + else + thd->send_explain_fields(explain_result); + fix_tables_pointers(select_lex); + for ( SELECT_LEX *sl= select_lex; + sl && res == 0; + sl= sl->next_select_in_list()) + { + SELECT_LEX *first= sl->master_unit()->first_select(); + res= mysql_explain_select(thd, sl, + ((select_lex==sl)?"FIRST": + ((sl == first)? + ((sl->depended)?"DEPENDENT SUBSELECT": + "SUBSELECT"): + ((sl->depended)?"DEPENDENT UNION": + "UNION"))), + explain_result); + } + if (res > 0) + res= -res; // mysql_explain_select do not report error + MYSQL_LOCK *save_lock= thd->lock; + thd->lock= (MYSQL_LOCK *)0; + explain_result->send_eof(); + thd->lock= save_lock; + } + else + { + query_cache_store_query(thd, tables); + res=handle_select(thd, lex, result); + } } else delete result; @@ -1866,7 +1953,7 @@ mysql_execute_command(void) (ORDER *)NULL, select_lex->options | thd->options | SELECT_NO_JOIN_CACHE, - result, unit, 0); + result, unit, select_lex, 0); delete result; } else @@ -2037,7 +2124,7 @@ mysql_execute_command(void) (ORDER *)NULL, select_lex->options | thd->options | SELECT_NO_JOIN_CACHE, - result, unit, 0); + result, unit, select_lex, 0); delete result; } else @@ -2803,6 +2890,7 @@ mysql_init_query(THD *thd) thd->lex.unit.global_parameters= &thd->lex.select_lex; //Global limit & order thd->lex.select_lex.master= &thd->lex.unit; thd->lex.select_lex.prev= &thd->lex.unit.slave; + thd->select_number= thd->lex.select_lex.select_number= 1; thd->lex.value_list.empty(); thd->free_list= 0; thd->lex.union_option= 0; @@ -2832,6 +2920,7 @@ bool mysql_new_select(LEX *lex, bool move_down) { SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX)); + select_lex->select_number= ++lex->thd->select_number; if (!select_lex) return 1; select_lex->init_query(); @@ -2874,6 +2963,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) mysql_init_query(thd); thd->query_length = length; + thd->lex.derived_tables= false; if (query_cache_send_result_to_client(thd, inBuf, length) <= 0) { LEX *lex=lex_start(thd, (uchar*) inBuf, length); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d071743aec4..b87a79cc2c6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -144,7 +144,6 @@ static void init_sum_functions(Item_sum **func); static bool update_sum_func(Item_sum **func); static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, bool distinct, const char *message=NullS); -static void describe_info(THD *thd, const char *info); /* This handles SELECT with and without UNION @@ -154,19 +153,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) { int res; register SELECT_LEX *select_lex = &lex->select_lex; - if (select_lex->next_select_in_list()) - { - /* Fix tables 'to-be-unioned-from' list to point at opened tables */ - for (SELECT_LEX *sl= select_lex; - sl; - sl= sl->next_select_in_list()) - { - for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; - cursor; - cursor=cursor->next) - cursor->table= cursor->table_list->table; - } - } + fix_tables_pointers(select_lex); if (select_lex->next_select()) res=mysql_union(thd,lex,result); else @@ -178,7 +165,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) select_lex->having, (ORDER*) lex->proc_list.first, select_lex->options | thd->options, - result, &(lex->unit), 0); + result, &(lex->unit), &(lex->select_lex), 0); if (res && result) result->abort(); if (res || thd->net.report_error) @@ -190,6 +177,22 @@ int handle_select(THD *thd, LEX *lex, select_result *result) return res; } +void fix_tables_pointers(SELECT_LEX *select_lex) +{ + if (select_lex->next_select_in_list()) + { + /* Fix tables 'to-be-unioned-from' list to point at opened tables */ + for (SELECT_LEX *sl= select_lex; + sl; + sl= sl->next_select_in_list()) + { + for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; + cursor; + cursor=cursor->next) + cursor->table= cursor->table_list->table; + } + } +} /***************************************************************************** ** check fields, find best join, do the select and output fields. @@ -209,7 +212,7 @@ JOIN::prepare(TABLE_LIST *tables_init, SELECT_LEX_UNIT *unit, bool fake_select_lex) { DBUG_ENTER("JOIN::prepare"); - + conds= conds_init; order= order_init; group_list= group_init; @@ -344,7 +347,7 @@ int JOIN::optimize() { DBUG_ENTER("JOIN::optimize"); - + #ifdef HAVE_REF_TO_FIELDS // Not done yet /* Add HAVING to WHERE if possible */ if (having && !group_list && ! sum_func_count) @@ -389,11 +392,8 @@ JOIN::optimize() } if (select_options & SELECT_DESCRIBE) { - if (union_part) - select_describe(this, false, false, false, - "Select tables optimized away"); - else - describe_info(thd, "Select tables optimized away"); + select_describe(this, false, false, false, + "Select tables optimized away"); delete procedure; DBUG_RETURN(1); } @@ -647,10 +647,7 @@ JOIN::exec() error=0; if (select_options & SELECT_DESCRIBE) { - if (union_part) - select_describe(this, false, false, false, "No tables used"); - else - describe_info(thd, "No tables used"); + select_describe(this, false, false, false, "No tables used"); } else { @@ -674,16 +671,16 @@ JOIN::exec() if (zero_result_cause) { - if (select_options & SELECT_DESCRIBE && union_part) + if (select_options & SELECT_DESCRIBE) select_describe(this, false, false, false, zero_result_cause); else - error=return_zero_rows(result, tables_list, fields_list, - tmp_table_param.sum_func_count != 0 && - !group_list, - select_options, - zero_result_cause, - having,procedure, - unit); + error= return_zero_rows(result, tables_list, fields_list, + tmp_table_param.sum_func_count != 0 && + !group_list, + select_options, + zero_result_cause, + having,procedure, + unit); DBUG_VOID_RETURN; } @@ -1004,7 +1001,8 @@ int mysql_select(THD *thd, TABLE_LIST *tables, List &fields, COND *conds, ORDER *order, ORDER *group,Item *having, ORDER *proc_param, ulong select_options, select_result *result, - SELECT_LEX_UNIT *unit, bool fake_select_lex) + SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex, + bool fake_select_lex) { JOIN *join = new JOIN(thd, fields, select_options, result); @@ -1013,7 +1011,7 @@ mysql_select(THD *thd, TABLE_LIST *tables, List &fields, COND *conds, thd->used_tables=0; // Updated by setup_fields if (join->prepare(tables, conds, order, group, having, proc_param, - &(thd->lex.select_lex), unit, fake_select_lex)) + select_lex, unit, fake_select_lex)) { DBUG_RETURN(-1); } @@ -3087,11 +3085,6 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List &fields, { DBUG_ENTER("return_zero_rows"); - if (select_options & SELECT_DESCRIBE) - { - describe_info(current_thd, info); - DBUG_RETURN(0); - } if (procedure) { if (result->prepare(fields, unit)) // This hasn't been done yet @@ -3725,6 +3718,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, table->blob_ptr_size=mi_portable_sizeof_char_ptr; table->map=1; table->tmp_table= TMP_TABLE; + table->derived_select_number= 0; table->db_low_byte_first=1; // True for HEAP and MyISAM table->temp_pool_slot = temp_pool_slot; @@ -7139,7 +7133,6 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, Item *item; List item_list; THD *thd=join->thd; - MYSQL_LOCK *save_lock; SELECT_LEX *select_lex = &(join->thd->lex.select_lex); select_result *result=join->result; DBUG_ENTER("select_describe"); @@ -7147,28 +7140,13 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, /* Don't log this into the slow query log */ select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED); join->unit->offset_limit_cnt= 0; - if (thd->lex.select == select_lex) - { - field_list.push_back(new Item_empty_string("table",NAME_LEN)); - field_list.push_back(new Item_empty_string("type",10)); - field_list.push_back(item=new Item_empty_string("possible_keys", - NAME_LEN*MAX_KEY)); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("key",NAME_LEN)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("key_len",0,3)); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("ref", - NAME_LEN*MAX_REF_PARTS)); - item->maybe_null=1; - field_list.push_back(new Item_real("rows",0.0,0,10)); - field_list.push_back(new Item_empty_string("Extra",255)); - if (result->send_fields(field_list,1)) - return; - } if (message) { + item_list.push_back(new Item_int((int)thd->lex.select->select_number)); + item_list.push_back(new Item_string(thd->lex.select->type, + strlen(thd->lex.select->type), + default_charset_info)); item_list.push_back(new Item_empty_string("",0)); item_list.push_back(new Item_empty_string("",0)); item_list.push_back(new Item_empty_string("",0)); @@ -7192,9 +7170,24 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, String tmp1(buff1,sizeof(buff1),default_charset_info); String tmp2(buff2,sizeof(buff2),default_charset_info); item_list.empty(); + item_list.push_back(new Item_int((int)thd->lex.select->select_number)); + item_list.push_back(new Item_string(thd->lex.select->type, + strlen(thd->lex.select->type), + default_charset_info)); if (tab->type == JT_ALL && tab->select && tab->select->quick) tab->type= JT_RANGE; - item_list.push_back(new Item_string(table->table_name,strlen(table->table_name),default_charset_info)); + if (table->tmp_table == TMP_TABLE && table->derived_select_number != 0) + { + // Derived table name generation + buff[512]; + int len= my_snprintf(buff, 512, "", + table->derived_select_number); + item_list.push_back(new Item_string(buff, len, default_charset_info)); + } + else + item_list.push_back(new Item_string(table->table_name, + strlen(table->table_name), + default_charset_info)); item_list.push_back(new Item_string(join_type_str[tab->type],strlen(join_type_str[tab->type]),default_charset_info)); tmp1.length(0); tmp2.length(0); key_map bits; @@ -7311,29 +7304,25 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, result->send_error(0,NullS); } } - if (!join->thd->lex.select->next_select()) - { - save_lock=thd->lock; - thd->lock=(MYSQL_LOCK *)0; - result->send_eof(); - thd->lock=save_lock; - } DBUG_VOID_RETURN; } - -static void describe_info(THD *thd, const char *info) +int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type, + select_result *result) { - List field_list; - String *packet= &thd->packet; + select_lex->type= type; + thd->lex.select= select_lex; + SELECT_LEX_UNIT *unit= select_lex->master_unit(); + int res= mysql_select(thd,(TABLE_LIST*) select_lex->table_list.first, + select_lex->item_list, + select_lex->where, + (ORDER*) select_lex->order_list.first, + (ORDER*) select_lex->group_list.first, + select_lex->having, + (ORDER*) thd->lex.proc_list.first, + select_lex->options | thd->options | SELECT_DESCRIBE, + result, unit, select_lex, 0); - /* Don't log this into the slow query log */ - thd->lex.select_lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED); - field_list.push_back(new Item_empty_string("Comment",80)); - if (send_fields(thd,field_list,1)) - return; /* purecov: inspected */ - packet->length(0); - net_store_data(packet,info); - if (!my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) - send_eof(&thd->net); + return res; } + diff --git a/sql/sql_union.cc b/sql/sql_union.cc index e8ee3582135..f6ac17e5fe3 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -111,6 +111,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) DBUG_ENTER("st_select_lex_unit::prepare"); this->thd= thd; this->result= result; + SELECT_LEX *lex_select_save= thd->lex.select; /* Global option */ if (((void*)(global_parameters)) == ((void*)this)) @@ -148,9 +149,9 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) /* Create a list of items that will be in the result set */ while ((item= it++)) if (item_list.push_back(item)) - DBUG_RETURN(-1); + goto err; if (setup_fields(thd,first_table,item_list,0,0,1)) - DBUG_RETURN(-1); + goto err; } bzero((char*) &tmp_table_param,sizeof(tmp_table_param)); @@ -162,7 +163,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) (first_select()->options | thd->options | TMP_TABLE_ALL_COLUMNS), this))) - DBUG_RETURN(-1); + goto err; table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); bzero((char*) &result_table_list,sizeof(result_table_list)); @@ -171,7 +172,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) result_table_list.table=table; if (!(union_result=new select_union(table))) - DBUG_RETURN(-1); + goto err; union_result->save_time_stamp=!describe; union_result->tmp_table_param=&tmp_table_param; @@ -202,9 +203,13 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) (ORDER*) NULL, sl, this, 0); if (res | thd->fatal_error) - DBUG_RETURN(res | thd->fatal_error); + goto err; } + thd->lex.select= lex_select_save; DBUG_RETURN(res | thd->fatal_error); +err: + thd->lex.select= lex_select_save; + DBUG_RETURN(-1); } int st_select_lex_unit::exec() @@ -214,7 +219,7 @@ int st_select_lex_unit::exec() { if (optimized && item && item->assigned()) item->assigned(0); // We will reinit & rexecute unit - + SELECT_LEX *lex_select_save= thd->lex.select; for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) { thd->lex.select=sl; @@ -234,8 +239,12 @@ int st_select_lex_unit::exec() res= sl->join->error; if (res) + { + thd->lex.select= lex_select_save; DBUG_RETURN(res); + } } + thd->lex.select= lex_select_save; optimized= 1; } @@ -283,7 +292,7 @@ int st_select_lex_unit::exec() 0: (ORDER*)global_parameters->order_list.first, (ORDER*) NULL, NULL, (ORDER*) NULL, - thd->options, result, this, 1); + thd->options, result, this, first_select(), 1); if (found_rows_for_union && !res) thd->limit_found_rows = (ulonglong)table->file->records; } diff --git a/sql/table.h b/sql/table.h index b89701bfc8e..3b8a62a09b5 100644 --- a/sql/table.h +++ b/sql/table.h @@ -128,6 +128,9 @@ struct st_table { uint temp_pool_slot; + /* number of select if it is derived table */ + uint derived_select_number; + THD *in_use; /* Which thread uses this */ struct st_table *next,*prev; }; -- cgit v1.2.1 From b14dc0ee2f1f83651fb397685f7b5f908d53ac7f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Sep 2002 09:11:40 +0300 Subject: fixed grammar error --- sql/share/czech/errmsg.txt | 4 ++-- sql/share/danish/errmsg.txt | 4 ++-- sql/share/dutch/errmsg.txt | 4 ++-- sql/share/english/errmsg.txt | 4 ++-- sql/share/estonian/errmsg.txt | 4 ++-- sql/share/french/errmsg.txt | 4 ++-- sql/share/greek/errmsg.txt | 4 ++-- sql/share/hungarian/errmsg.txt | 4 ++-- sql/share/italian/errmsg.txt | 4 ++-- sql/share/japanese/errmsg.txt | 4 ++-- sql/share/korean/errmsg.txt | 4 ++-- sql/share/norwegian-ny/errmsg.txt | 4 ++-- sql/share/norwegian/errmsg.txt | 4 ++-- sql/share/polish/errmsg.txt | 4 ++-- sql/share/portuguese/errmsg.txt | 4 ++-- sql/share/romanian/errmsg.txt | 4 ++-- sql/share/serbian/errmsg.txt | 4 ++-- sql/share/slovak/errmsg.txt | 4 ++-- sql/share/spanish/errmsg.txt | 4 ++-- sql/share/swedish/errmsg.txt | 4 ++-- 20 files changed, 40 insertions(+), 40 deletions(-) (limited to 'sql') diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 9ce8875ceeb..09975da622c 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -239,5 +239,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 0babb8981a8..f9b8057acfb 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -233,5 +233,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index b2fab274db1..f35ee9cc836 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -238,5 +238,5 @@ "Gebruiker '%-.64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 1a68a9dcb85..c5c5488fdc8 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -230,5 +230,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index e52dfd72c5a..86de766d177 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -235,5 +235,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 8d0e2505eb0..6f024a83eb9 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -230,5 +230,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 171493458c9..cbe53444c78 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -230,5 +230,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index f891f8a7e91..4338f259310 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -232,5 +232,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 9b8eb214215..209e949d67b 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -230,5 +230,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 4016dd50189..b5573b5e780 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -232,5 +232,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 93e9948d4fd..df4f8cdbe0f 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -230,5 +230,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 612757726c7..4bcc2178b11 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -232,5 +232,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index f0d884c330f..0dee930d4aa 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -232,5 +232,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 22f7c331a98..8b93c30ec5a 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -234,5 +234,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index a00dabc391b..e38ca9da548 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -230,5 +230,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 61ca19a598e..cbcefca6d04 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -234,5 +234,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 78febb65c3c..3922e0a145a 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -236,5 +236,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 9c0ecc8ca14..39189c7c46e 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -238,5 +238,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 2eca37146e4..56669e1f6d3 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -231,5 +231,5 @@ "User '%-.64s' has exceeded the '%s' resource (current value: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 557c6e55394..95e07d73da5 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -230,5 +230,5 @@ "Användare '%-.64s' har överskridit '%s' (nuvarande värde: %ld)", "Wrong foreign key definition for '%-.64s': %s", "Key reference and table reference doesn't match", -"Subselect return more than 1 field", -"Subselect return more than 1 record", +"Subselect returns more than 1 field", +"Subselect returns more than 1 record", -- cgit v1.2.1 From da891a571e49804e3743bf2776bcf2648a4832da Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Sep 2002 23:11:51 +0300 Subject: fixed Item_subselect constructor --- sql/item_subselect.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 29034549367..a8909430155 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -34,7 +34,7 @@ SUBSELECT TODO: Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex, select_subselect *result): - engine_owner(1), value_assigned(0) + Item(), engine_owner(1), value_assigned(0) { DBUG_ENTER("Item_subselect::Item_subselect"); DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex)); -- cgit v1.2.1 From c9a2b58986635015b3f3867999ef3fafa2bd2728 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Sep 2002 18:34:56 +0300 Subject: fixed bug in string & date types with group function in subselect mysql-test/r/subselect.result: test suite of string & date types with group function in subselects mysql-test/t/subselect.test: test suite of string & date types with group function in subselects sql/item_subselect.cc: fixed bug in string type with group function sql/item_subselect.h: fixed bug in string type with group function sql/sql_class.cc: fixed bug in date type with group function --- sql/item_subselect.cc | 47 ++++++++++++++++++++++++++++++++++++++++++++++- sql/item_subselect.h | 12 ++++++++++-- sql/sql_class.cc | 8 ++++++-- 3 files changed, 62 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index a8909430155..99fc0bcdb67 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -82,7 +82,14 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0)); return 1; } - return engine->prepare(); + int res= engine->prepare(); + fix_length_and_dec(); + return res; +} + +void Item_subselect::fix_length_and_dec() +{ + engine->fix_length_and_dec(); } inline table_map Item_subselect::used_tables() const @@ -98,6 +105,12 @@ Item_singleval_subselect::Item_singleval_subselect(THD *thd, maybe_null= 1; } +void Item_singleval_subselect::fix_length_and_dec() +{ + engine->fix_length_and_dec(); + res_type= engine->type(); +} + Item::Type Item_subselect::type() const { return SUBSELECT_ITEM; @@ -135,6 +148,12 @@ Item_exists_subselect::Item_exists_subselect(THD *thd, select_lex->select_limit= 1; // we need only 1 row to determinate existence } +void Item_exists_subselect::fix_length_and_dec() +{ + max_length= 1; + +} + double Item_exists_subselect::val () { if (engine->exec()) @@ -221,6 +240,32 @@ int subselect_union_engine::prepare() return unit->prepare(thd, result); } +void subselect_single_select_engine::fix_length_and_dec() +{ + List_iterator_fast li(select_lex->item_list); + Item *sel_item= li++; + item->max_length= sel_item->max_length; + res_type= sel_item->result_type(); + item->decimals= sel_item->decimals; +} + +void subselect_union_engine::fix_length_and_dec() +{ + uint32 mlen= 0, len; + Item *sel_item= 0; + for(SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) + { + List_iterator_fast li(sl->item_list); + Item *s_item= li++; + if ((len= s_item->max_length)) + mlen= len; + if (!sel_item) + sel_item= s_item; + } + item->max_length= mlen; + res_type= sel_item->result_type(); + item->decimals= sel_item->decimals; +} int subselect_single_select_engine::exec() { diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 0d8495d3ae8..92839eb0e5f 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -61,6 +61,7 @@ public: bool is_null() { return null_value; } void make_field (Send_field *); bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); + virtual void fix_length_and_dec(); table_map used_tables() const; friend class select_subselect; @@ -100,7 +101,7 @@ public: String *val_str (String *); Item *new_item() { return new Item_singleval_subselect(this); } enum Item_result result_type() const { return res_type; } - + void fix_length_and_dec(); friend class select_singleval_subselect; }; @@ -128,7 +129,7 @@ public: longlong val_int(); double val(); String *val_str(String*); - + void fix_length_and_dec(); friend class select_exists_subselect; }; @@ -138,6 +139,7 @@ protected: select_subselect *result; /* results storage class */ THD *thd; /* pointer to current THD */ Item_subselect *item; /* item, that use this engine */ + enum Item_result res_type; /* type of results */ public: static void *operator new(size_t size) { @@ -150,11 +152,15 @@ public: result= res; item= si; this->thd= thd; + res_type= STRING_RESULT; } + virtual int prepare()= 0; + virtual void fix_length_and_dec()= 0; virtual int exec()= 0; virtual uint cols()= 0; /* return number of columnss in select */ virtual bool depended()= 0; /* depended from outer select */ + enum Item_result type() { return res_type; } }; class subselect_single_select_engine: public subselect_engine @@ -168,6 +174,7 @@ public: select_subselect *result, Item_subselect *item); virtual int prepare(); + virtual void fix_length_and_dec(); virtual int exec(); virtual uint cols(); virtual bool depended(); @@ -182,6 +189,7 @@ public: select_subselect *result, Item_subselect *item); virtual int prepare(); + virtual void fix_length_and_dec(); virtual int exec(); virtual uint cols(); virtual bool depended(); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c090f2336c1..98551fa35ba 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -838,12 +838,16 @@ bool select_singleval_subselect::send_data(List &items) if ((it->null_value= val_item->is_null())) { it->assign_null(); - } else { + } + else + { it->max_length= val_item->max_length; it->decimals= val_item->decimals; it->binary= val_item->binary; - val_item->val_str(&it->str_value); it->int_value= val_item->val_int(); + String *s= val_item->val_str(&it->str_value); + if (s != &it->str_value) + it->str_value.set(*s, 0, s->length()); it->res_type= val_item->result_type(); } it->assigned(1); -- cgit v1.2.1 From 9564cd43d2d20de54fcdd0ff88f2a23724ffde26 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Oct 2002 13:54:59 +0500 Subject: SHOW TABLE STATUS now displays table charset as well --- sql/sql_show.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sql') diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 7ac0affbec5..7ac032719be 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -484,6 +484,8 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) item->maybe_null=1; field_list.push_back(item=new Item_datetime("Check_time")); item->maybe_null=1; + field_list.push_back(item=new Item_empty_string("Charset",32)); + item->maybe_null=1; field_list.push_back(item=new Item_empty_string("Create_options",255)); item->maybe_null=1; field_list.push_back(item=new Item_empty_string("Comment",80)); @@ -559,6 +561,8 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) localtime_r(&file->check_time,&tm_tmp); net_store_data(packet, &tm_tmp); } + net_store_data(packet, convert, table->table_charset ? + table->table_charset->name : "default"); { char option_buff[350],*ptr; ptr=option_buff; -- cgit v1.2.1 From 0d2b6552b14292648afafe7dcd73df4b7975ba65 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Oct 2002 17:23:28 +0500 Subject: User variables didn't store charset, so this didn't work as expected and returned default charset instead: SET @x = _koi8_ru'test'; SELECT CHARSET(@x); --- sql/item_func.cc | 14 +++++++++----- sql/item_func.h | 2 +- sql/sql_class.h | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/item_func.cc b/sql/item_func.cc index 8728187718c..ded5e045af4 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1801,7 +1801,8 @@ Item_func_set_user_var::fix_length_and_dec() } void Item_func_set_user_var::update_hash(void *ptr, uint length, - Item_result type) + Item_result type, + CHARSET_INFO *cs) { if ((null_value=args[0]->null_value)) { @@ -1810,6 +1811,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; } else { @@ -1840,6 +1842,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; } return; @@ -1874,7 +1877,7 @@ double Item_func_set_user_var::val() { double value=args[0]->val(); - update_hash((void*) &value,sizeof(value), REAL_RESULT); + update_hash((void*) &value,sizeof(value), REAL_RESULT, default_charset_info); return value; } @@ -1882,7 +1885,7 @@ longlong Item_func_set_user_var::val_int() { longlong value=args[0]->val_int(); - update_hash((void*) &value,sizeof(longlong),INT_RESULT); + update_hash((void*) &value,sizeof(longlong),INT_RESULT, default_charset_info); return value; } @@ -1891,9 +1894,9 @@ 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); + update_hash((void*) 0,0,STRING_RESULT, default_charset_info); else - update_hash(res->c_ptr(),res->length()+1,STRING_RESULT); + update_hash(res->c_ptr(),res->length()+1,STRING_RESULT,res->charset()); return res; } @@ -1939,6 +1942,7 @@ Item_func_get_user_var::val_str(String *str) null_value=1; return NULL; } + str->set_charset(entry->var_charset); break; } return str; diff --git a/sql/item_func.h b/sql/item_func.h index 2e61ed87c3c..d8f6963479d 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -875,7 +875,7 @@ public: double val(); longlong val_int(); String *val_str(String *str); - void update_hash(void *ptr, uint length, enum Item_result type); + void update_hash(void *ptr, uint length, enum Item_result type, CHARSET_INFO *cs); 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/sql_class.h b/sql/sql_class.h index a6b7e45ab03..84dde229b2f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -830,6 +830,7 @@ class user_var_entry char *value; ulong length, update_query_id; Item_result type; + CHARSET_INFO *var_charset; }; /* Class for unique (removing of duplicates) */ -- cgit v1.2.1 From 5a28c2caca888be932140d12f87c496398ad4220 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Oct 2002 13:33:08 +0300 Subject: Fixes and code cleanups after merge with 4.0.3 Warning handling and initial prepared statement handling (last not complete yet) Changed a lot of functions that returned 0/1 to my_bool type. GRANT handling now uses read/write locks instead of mutex Change basic net functions to use THD instead of NET (needed for 4.1 protocol) Use my_sprintf instead of sprintf() + strlen() Added alloc_query() to be able to chare query initialization code with prepared statements. Cleanup handling of SHOW COUNT(*) WARNINGS and SELECT LAST_INSERT_ID() Note that the following test fails (will be fixed ASAP): sub_select, union, rpl_rotate_logs and rpl_mystery22 BitKeeper/deleted/.del-README~3449730baf983117: Delete: mysql-test/t/README BitKeeper/deleted/.del-sql_error.cc~2f1caca8d2485dbe: Delete: libmysqld/sql_error.cc BitKeeper/deleted/.del-sql_prepare.cc~f703729793935ed6: Delete: libmysqld/sql_prepare.cc Docs/manual.texi: Updated variable list client/mysql.cc: Show warning count to user. client/mysqltest.c: Add warnings to test results configure.in: New shared library version number include/errmsg.h: Indentation cleanup include/mysql.h: Removed MYSQL_ERROR Indentaion cleanups include/mysql_com.h: Changed functions to returns true/false to my_bool. include/mysqld_error.h: New error messages isam/pack_isam.c: Indentation change libmysql/Makefile.am: Fix of wrong merge libmysql/Makefile.shared: Indentation cleanup libmysql/errmsg.c: Removed not used errors libmysql/libmysql.c: Change functions to return 1 on error (not -1) Change type of functions that returns 0/1 to my_bool Lot of code optimizations. Lot of changes for prepared statements. This now handles sending of binary data to server. Receving of binary data is not yet done (will have to wait until server code for this is ready) mysql_warning_count and mysql_warnings() implemented. libmysql/libmysql.def: Added mysql_warnings and mysql_warning_count libmysql/manager.c: Fixed wrong testing of result from my_connect() libmysqld/lib_sql.cc: Removed global variable THR_NET Change basic net functions to use THD instead of NET GRANT handling now uses read/write locks instead of mutex libmysqld/libmysqld.c: Changed functions to be my_bool myisam/ft_boolean_search.c: Trivial code cleanup myisam/ft_stopwords.c: Trivial code cleanup myisam/mi_check.c: Update to 4.1 structures myisam/myisampack.c: Trivial code cleanup myisam/rt_key.c: Code cleanup myisam/rt_test.c: Code cleanup Removed compiler warnings myisam/sp_key.c: Indentation changes myisam/sp_test.c: Removed compiler warnings mysql-test/README: Updated to reflect the new --external flag. mysql-test/mysql-test-run.sh: --local (start new server) is now default. Use --external to test against external server. mysql-test/r/rollback.result: Updated for 4.1 warnings mysql-test/r/rpl_log.result: Update for 4.1 mysql-test/t/rollback.test: Updated for 4.1 warnings mysql-test/t/rpl_log_pos.test: Portability fix mysys/hash.c: Indentation change mysys/my_error.c: Indentation change mysys/tree.c: Updated file description sql/field.cc: Fixed bugs introduced by merge Use my_sprintf instead of sprintf() + strlen() sql/field.h: Add CHARSET_INFO to field structure sql/gstream.h: Indentation changes. Added GPL copyright header sql/ha_innodb.cc: Updated parameters for net functions. sql/item.cc: Updates of Item_param Indentation changes sql/item.h: Removed size_of() function from item. sql/item_func.cc: Update function usage for 4.1 Added get_system_var() sql/item_func.h: Indentation change sql/item_strfunc.cc: Removed not needed inclusion of gstream.h Update to use system variables (from 4.0) sql/item_sum.h: Removed size_of() functions from item. sql/item_timefunc.cc: Change sprintf() + strlen() -> my_sprintf() Added length parameter to ->append() sql/item_timefunc.h: Removed size_of() functions from item. sql/item_uniq.h: Removed size_of() functions from item. sql/lex.h: Removed SQL_ERROR_COUNT variable sql/log.cc: Change sprintf() + strlen() -> my_sprintf() sql/log_event.cc: Change sprintf() + strlen() -> my_sprintf() sql/mini_client.cc: Added check that one always specifies a length to mc_mysql_query() sql/mysql_priv.h: New prototypes Change of NET -> THD parameter for net functions. sql/mysqld.cc: New startup options: 'max_prepared_statements', 'max_error_count' Updated usage of net functions. sql/net_pkg.cc: Change basic net functions to use THD instead of NET (needed to be able to handle 4.0 and 4.1 protocols) Lots of function comments sql/net_serv.cc: Change int return values -> my_bool Updated net_write_command() to take an extra header block to be added to the packet. (This made the prepared statement code much nicer and more efficient) sql/repl_failsafe.cc: Update net functions to use THD instead of NET sql/set_var.cc: Added @@error_count and @@warning_count variables. Updated to 4.1 function usage sql/set_var.h: Added @@error_count and @@warning_count variables. sql/share/czech/errmsg.txt: Removed Warning: from warning error messages. sql/share/english/errmsg.txt: Removed Warning: from warning error messages. sql/share/greek/errmsg.txt: Removed Warning: from warning error messages. sql/share/hungarian/errmsg.txt: Removed Warning: from warning error messages. sql/share/japanese/errmsg.txt: Removed Warning: from warning error messages. sql/share/korean/errmsg.txt: Removed Warning: from warning error messages. sql/share/norwegian-ny/errmsg.txt: Removed Warning: from warning error messages. sql/share/norwegian/errmsg.txt: Removed Warning: from warning error messages. sql/share/polish/errmsg.txt: Removed Warning: from warning error messages. sql/share/romanian/errmsg.txt: Removed Warning: from warning error messages. sql/share/slovak/errmsg.txt: Removed Warning: from warning error messages. sql/share/swedish/errmsg.txt: Removed Warning: from warning error messages. sql/slave.cc: Change basic net functions to use THD instead of NET skip_load_data_file recoded to fit new client/server protocol sql/spatial.h: Added copyright header Indentation cleanups sql/sql_acl.cc: Change basic net functions to use THD instead of NET GRANT handling now uses read/write locks instead of mutex sql/sql_analyse.cc: Change basic net functions to use THD instead of NET sprintf() + strlen() -> my_sprintf() sql/sql_base.cc: More DBUG statements sql/sql_class.cc: Change basic net functions to use THD instead of NET warning and prepared statement handling sql/sql_class.h: Change basic net functions to use THD instead of NET warning and prepared statement handling sql/sql_db.cc: Code cleanup & optimization. sql/sql_delete.cc: Change basic net functions to use THD instead of NET sql/sql_derived.cc: Change basic net functions to use THD instead of NET sql/sql_do.cc: Change basic net functions to use THD instead of NET sql/sql_error.cc: Big rewrite of error handling. sql/sql_handler.cc: Change basic net functions to use THD instead of NET sql/sql_insert.cc: Change basic net functions to use THD instead of NET sql/sql_lex.cc: Change basic net functions to use THD instead of NET sql/sql_lex.h: Added param_count to st_select_lex_node sql/sql_list.h: Removed not needed error list. sql/sql_load.cc: Change basic net functions to use THD instead of NET sql/sql_parse.cc: Change basic net functions to use THD instead of NET Added alloc_query() to be able to chare query initialization code with prepared statements. Update of warning handling. Added create_select_for_variable() (for SHOW COUNT(*) WARNINGS) sql/sql_prepare.cc: Initial prepared statement handling sql/sql_rename.cc: Change basic net functions to use THD instead of NET sql/sql_repl.cc: Change basic net functions to use THD instead of NET sql/sql_select.cc: Small code cleanups Added missing initialization of error that caused some queries that returned an empty result set to fail sql/sql_select.h: Ensure that JOIN.error is properly initialized sql/sql_show.cc: Change basic net functions to use THD instead of NET A lot of optimization sql/sql_table.cc: Change basic net functions to use THD instead of NET Indentaion cleanup sql/sql_udf.cc: Change basic net functions to use THD instead of NET sql/sql_union.cc: Change basic net functions to use THD instead of NET sql/sql_update.cc: Change basic net functions to use THD instead of NET sql/sql_yacc.yy: Change basic net functions to use THD instead of NET Cleanup handling of SHOW COUNT(*) WARNINGS and SELECT LAST_INSERT_ID() sql/structs.h: Moved structures to files where they was used sql/table.cc: Don't accept empty database names sql/uniques.cc: Indentation cleanup sql/unireg.cc: Change basic net functions to use THD instead of NET sql/unireg.h: Added defaults for warnings and prepared statements strings/ctype-simple.c: optimization tests/client_test.c: Fixed wrong paramaters to printf() --- sql/field.cc | 58 ++-- sql/field.h | 1 + sql/gstream.h | 40 +-- sql/ha_innodb.cc | 2 +- sql/item.cc | 73 ++--- sql/item.h | 35 +-- sql/item_func.cc | 39 ++- sql/item_func.h | 2 +- sql/item_strfunc.cc | 4 +- sql/item_sum.h | 17 -- sql/item_timefunc.cc | 78 +++--- sql/item_timefunc.h | 10 - sql/item_uniq.h | 2 +- sql/lex.h | 1 - sql/log.cc | 37 +-- sql/log_event.cc | 21 +- sql/mini_client.cc | 21 +- sql/mysql_priv.h | 47 ++-- sql/mysqld.cc | 45 ++-- sql/net_pkg.cc | 174 +++++++++--- sql/net_serv.cc | 76 +++--- sql/repl_failsafe.cc | 42 +-- sql/set_var.cc | 70 +++-- sql/set_var.h | 29 +- sql/share/czech/errmsg.txt | 2 +- sql/share/english/errmsg.txt | 3 +- sql/share/greek/errmsg.txt | 2 +- sql/share/hungarian/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/romanian/errmsg.txt | 2 +- sql/share/slovak/errmsg.txt | 2 +- sql/share/swedish/errmsg.txt | 2 +- sql/slave.cc | 47 ++-- sql/spatial.h | 145 +++++----- sql/sql_acl.cc | 68 ++--- sql/sql_analyse.cc | 15 +- sql/sql_base.cc | 17 +- sql/sql_class.cc | 37 ++- sql/sql_class.h | 80 +++--- sql/sql_db.cc | 373 +++++++++++++------------- sql/sql_delete.cc | 18 +- sql/sql_derived.cc | 2 +- sql/sql_do.cc | 2 +- sql/sql_error.cc | 250 +++++++---------- sql/sql_handler.cc | 10 +- sql/sql_insert.cc | 12 +- sql/sql_lex.cc | 4 +- sql/sql_lex.h | 4 +- sql/sql_list.h | 117 -------- sql/sql_load.cc | 2 +- sql/sql_parse.cc | 362 ++++++++++++++----------- sql/sql_prepare.cc | 548 +++++++++++++++++++++++--------------- sql/sql_rename.cc | 2 +- sql/sql_repl.cc | 55 ++-- sql/sql_select.cc | 45 ++-- sql/sql_select.h | 4 +- sql/sql_show.cc | 316 ++++++++++++---------- sql/sql_table.cc | 45 ++-- sql/sql_udf.cc | 20 +- sql/sql_union.cc | 2 +- sql/sql_update.cc | 16 +- sql/sql_yacc.yy | 67 +++-- sql/structs.h | 26 +- sql/table.cc | 4 +- sql/uniques.cc | 3 +- sql/unireg.cc | 7 +- sql/unireg.h | 2 + 71 files changed, 1968 insertions(+), 1708 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index c9669c93c04..336bc9d7cc2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -314,6 +314,7 @@ void Field::store_time(TIME *ltime,timestamp_type type) store(buff,(uint) length, default_charset_info); break; } + } } @@ -476,7 +477,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs) from++; frac_digits_from= from; /* Read digits at the right of '.' */ - for (;from!=end && my_isdigit(system_charset_info, (*from); from++) ; + for (;from!=end && my_isdigit(system_charset_info, *from); from++) ; frac_digits_end=from; // Some exponentiation symbol ? if (from != end && (*from == 'e' || *from == 'E')) @@ -505,7 +506,8 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs) if (current_thd->count_cuted_fields) { - for (;from != end && isspace(*from); from++) ; // Read end spaces + // Skip end spaces + for (;from != end && my_isspace(system_charset_info, *from); from++) ; if (from != end) // If still something left, warn { current_thd->cuted_fields++; @@ -736,10 +738,10 @@ int Field_decimal::store(double nr) #ifdef HAVE_SNPRINTF_ buff[sizeof(buff)-1]=0; // Safety snprintf(buff,sizeof(buff)-1, "%.*f",(int) dec,nr); + length=(uint) strlen(buff); #else - sprintf(buff,"%.*f",dec,nr); + length=(uint) my_sprintf(buff,(buff,"%.*f",dec,nr)); #endif - length=(uint) strlen(buff); if (length > field_length) { @@ -2207,10 +2209,10 @@ String *Field_float::val_str(String *val_buffer, #ifdef HAVE_SNPRINTF to[to_length-1]=0; // Safety snprintf(to,to_length-1,"%.*f",dec,nr); + to=strend(to); #else - sprintf(to,"%.*f",dec,nr); + to+= my_sprintf(to,(to,"%.*f",dec,nr)); #endif - to=strend(to); #endif } #ifdef HAVE_FCONVERT @@ -2468,10 +2470,10 @@ String *Field_double::val_str(String *val_buffer, #ifdef HAVE_SNPRINTF to[to_length-1]=0; // Safety snprintf(to,to_length-1,"%.*f",dec,nr); + to=strend(to); #else - sprintf(to,"%.*f",dec,nr); + to+= my_sprintf(to,(to,"%.*f",dec,nr)); #endif - to=strend(to); #endif } #ifdef HAVE_FCONVERT @@ -2886,8 +2888,10 @@ void Field_timestamp::sort_string(char *to,uint length __attribute__((unused))) void Field_timestamp::sql_type(String &res) const { - sprintf((char*) res.ptr(),"timestamp(%d)",(int) field_length); - res.length((uint) strlen(res.ptr())); + ulong length= my_sprintf((char*) res.ptr(), + ((char*) res.ptr(),"timestamp(%d)", + (int) field_length)); + res.length(length); } @@ -3026,10 +3030,11 @@ String *Field_time::val_str(String *val_buffer, tmp= -tmp; sign= "-"; } - sprintf((char*) val_buffer->ptr(),"%s%02d:%02d:%02d", - sign,(int) (tmp/10000), (int) (tmp/100 % 100), - (int) (tmp % 100)); - val_buffer->length((uint) strlen(val_buffer->ptr())); + long length= my_sprintf((char*) val_buffer->ptr(), + ((char*) val_buffer->ptr(),"%s%02d:%02d:%02d", + sign,(int) (tmp/10000), (int) (tmp/100 % 100), + (int) (tmp % 100))); + val_buffer->length(length); return val_buffer; } @@ -3158,8 +3163,9 @@ String *Field_year::val_str(String *val_buffer, void Field_year::sql_type(String &res) const { - sprintf((char*) res.ptr(),"year(%d)",(int) field_length); - res.length((uint) strlen(res.ptr())); + ulong length=my_sprintf((char*) res.ptr(), + ((char*) res.ptr(),"year(%d)",(int) field_length)); + res.length(length); } @@ -3852,12 +3858,14 @@ void Field_string::sort_string(char *to,uint length) void Field_string::sql_type(String &res) const { - sprintf((char*) res.ptr(),"%s(%d)", - field_length > 3 && - (table->db_options_in_use & HA_OPTION_PACK_RECORD) ? - "varchar" : "char", - (int) field_length); - res.length((uint) strlen(res.ptr())); + ulong length= my_sprintf((char*) res.ptr(), + ((char*) res.ptr(), "%s(%d)", + (field_length > 3 && + (table->db_options_in_use & + HA_OPTION_PACK_RECORD) ? + "varchar" : "char"), + (int) field_length)); + res.length((uint) length); if (binary_flag) res.append(" binary"); else @@ -4060,8 +4068,10 @@ void Field_varstring::sort_string(char *to,uint length) void Field_varstring::sql_type(String &res) const { - sprintf((char*) res.ptr(),"varchar(%d)",(int) field_length); - res.length((uint) strlen(res.ptr())); + ulong length= my_sprintf((char*) res.ptr(), + ((char*) res.ptr(),"varchar(%u)", + field_length)); + res.length((uint) length); if (binary_flag) res.append(" binary"); else diff --git a/sql/field.h b/sql/field.h index 551619abc6f..d8cfba14e02 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1036,6 +1036,7 @@ public: uint decimals,flags,pack_length; Field::utype unireg_check; TYPELIB *interval; // Which interval to use + CHARSET_INFO *charset; Field *field; // For alter table uint8 row,col,sc_length,interval_id; // For rea_create_table diff --git a/sql/gstream.h b/sql/gstream.h index f8df6e337b0..f26ef8899f8 100644 --- a/sql/gstream.h +++ b/sql/gstream.h @@ -1,11 +1,19 @@ -#ifndef GSTREAM_H -#define GSTREAM_H +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef WITHOUT_MYSQL - #include ".\rtree\myisamdef.h" -#else - #include "mysql_priv.h" -#endif class GTextReadStream { @@ -20,9 +28,13 @@ public: r_bra, comma, }; - GTextReadStream(const char *buffer, int size) : - m_cur(buffer), m_limit(buffer + size), m_last_text_position(buffer), m_err_msg(NULL) {} - GTextReadStream() : m_cur(NULL), m_limit(NULL), m_err_msg(NULL) {} + + GTextReadStream(const char *buffer, int size) + :m_cur(buffer), m_limit(buffer + size), m_last_text_position(buffer), + m_err_msg(NULL) + {} + GTextReadStream(): m_cur(NULL), m_limit(NULL), m_err_msg(NULL) + {} ~GTextReadStream() { @@ -41,21 +53,17 @@ public: void set_error_msg(const char *msg); -// caller should free this pointer + // caller should free this pointer char *get_error_msg() { char *err_msg = m_err_msg; m_err_msg = NULL; return err_msg; } + protected: const char *m_cur; const char *m_limit; const char *m_last_text_position; char *m_err_msg; }; - -#endif - - - diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index d42311b43b6..65aaa63f7db 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3557,7 +3557,7 @@ innodb_show_status( ut_free(buf); - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } diff --git a/sql/item.cc b/sql/item.cc index 7693ef428c6..946c0f24fe1 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -44,10 +44,10 @@ Item::Item() current_thd->free_list=this; } -void Item::set_name(char *str,uint length) +void Item::set_name(const char *str,uint length) { if (!length) - name=str; // Used by AS + name= (char*) str; // Used by AS else { while (length && !my_isgraph(system_charset_info,*str)) @@ -303,21 +303,13 @@ void Item_param::set_int(longlong i) item_type = INT_ITEM; } -void Item_param::set_double(double i) +void Item_param::set_double(double value) { - double value = (double)i; real_value=value; item_result_type = REAL_RESULT; item_type = REAL_ITEM; } -void Item_param::set_double(float i) -{ - float value = (float)i; - real_value=(double)value; - item_result_type = REAL_RESULT; - item_type = REAL_ITEM; -} void Item_param::set_value(const char *str, uint length) { @@ -326,6 +318,7 @@ void Item_param::set_value(const char *str, uint length) item_type = STRING_ITEM; } + void Item_param::set_longdata(const char *str, ulong length) { /* TODO: Fix this for binary handling by making use of @@ -334,16 +327,11 @@ void Item_param::set_longdata(const char *str, ulong length) str_value.append(str,length); } -void Item_param::set_long_end() -{ - long_data_supplied = true; - item_result_type = STRING_RESULT; -}; -int Item_param::save_in_field(Field *field) +int Item_param::save_in_field(Field *field) { if (null_value) - return set_field_to_null(field); + return (int) set_field_to_null(field); field->set_notnull(); if (item_result_type == INT_RESULT) @@ -357,24 +345,21 @@ int Item_param::save_in_field(Field *field) return (field->store(nr)) ? -1 : 0; } String *result; - CHARSET_INFO *cs=default_charset_info;//fix this + CHARSET_INFO *cs=default_charset_info; //fix this result=val_str(&str_value); return (field->store(result->ptr(),result->length(),cs)) ? -1 : 0; } + void Item_param::make_field(Send_field *tmp_field) { init_make_field(tmp_field,FIELD_TYPE_STRING); } + double Item_param::val() { - /* Cross check whether we need need this conversions ? or direct - return(real_value) is enough ? - */ - - switch(item_result_type) { - + switch (item_result_type) { case STRING_RESULT: return (double)atof(str_value.ptr()); case INT_RESULT: @@ -384,16 +369,12 @@ double Item_param::val() } } + longlong Item_param::val_int() { - /* Cross check whether we need need this conversions ? or direct - return(int_value) is enough ? - */ - - switch(item_result_type) { - + switch (item_result_type) { case STRING_RESULT: - return (longlong)strtoll(str_value.ptr(),(char**) 0,10); + return strtoll(str_value.ptr(),(char**) 0,10); case REAL_RESULT: return (longlong) (real_value+(real_value > 0 ? 0.5 : -0.5)); default: @@ -401,14 +382,10 @@ longlong Item_param::val_int() } } + String *Item_param::val_str(String* str) { - /* Cross check whether we need need this conversions ? or direct - return(&str_value) is enough ? - */ - - switch(item_result_type) { - + switch (item_result_type) { case INT_RESULT: str->set(int_value); return str; @@ -421,6 +398,7 @@ String *Item_param::val_str(String* str) } /* End of Item_param related */ + void Item_copy_string::copy() { String *res=item->val_str(&str_value); @@ -438,7 +416,7 @@ String *Item_copy_string::val_str(String *str) } /* -** Functions to convert item to field (for send_fields) + Functions to convert item to field (for send_fields) */ /* ARGSUSED */ @@ -614,7 +592,7 @@ void Item_field::save_org_in_field(Field *to) } } -int Item_field::save_in_field(Field *to) +int Item_field::save_in_field(Field *to) { if (result_field->is_null()) { @@ -631,13 +609,13 @@ int Item_field::save_in_field(Field *to) } -int Item_null::save_in_field(Field *field) +int Item_null::save_in_field(Field *field) { return set_field_to_null(field); } -int Item::save_in_field(Field *field) +int Item::save_in_field(Field *field) { int error; if (result_type() == STRING_RESULT || @@ -674,7 +652,7 @@ int Item::save_in_field(Field *field) return (error) ? -1 : 0; } -int Item_string::save_in_field(Field *field) +int Item_string::save_in_field(Field *field) { String *result; CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); @@ -685,7 +663,7 @@ int Item_string::save_in_field(Field *field) return (field->store(result->ptr(),result->length(),cs)) ? -1 : 0; } -int Item_int::save_in_field(Field *field) +int Item_int::save_in_field(Field *field) { longlong nr=val_int(); if (null_value) @@ -694,7 +672,7 @@ int Item_int::save_in_field(Field *field) return (field->store(nr)) ? -1 : 0; } -int Item_real::save_in_field(Field *field) +int Item_real::save_in_field(Field *field) { double nr=val(); if (null_value) @@ -716,7 +694,8 @@ inline uint char_val(char X) X-'a'+10); } -Item_varbinary::Item_varbinary(const char *str, uint str_length, CHARSET_INFO *cs) +Item_varbinary::Item_varbinary(const char *str, uint str_length, + CHARSET_INFO *cs) { name=(char*) str-2; // Lex makes this start with 0x max_length=(str_length+1)/2; @@ -748,7 +727,7 @@ longlong Item_varbinary::val_int() } -int Item_varbinary::save_in_field(Field *field) +int Item_varbinary::save_in_field(Field *field) { int error; CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); diff --git a/sql/item.h b/sql/item.h index 206d7b5bd78..84182203d4c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -50,7 +50,7 @@ public: // alloc & destruct is done as start of select using sql_alloc Item(); virtual ~Item() { name=0; } /*lint -e1509 */ - void set_name(char* str,uint length=0); + void set_name(const char *str,uint length=0); void init_make_field(Send_field *tmp_field,enum enum_field_types type); virtual bool fix_fields(THD *, struct st_table_list *, Item **); virtual int save_in_field(Field *field); @@ -82,7 +82,6 @@ public: virtual bool get_date(TIME *ltime,bool fuzzydate); virtual bool get_time(TIME *ltime); virtual bool is_null() { return 0; } - virtual unsigned int size_of()= 0; }; @@ -100,7 +99,6 @@ public: field_name(field_name_par), depended_from(0) { name = (char*) field_name_par; } const char *full_name() const; - unsigned int size_of() { return sizeof(*this);} }; @@ -141,7 +139,6 @@ public: bool get_date(TIME *ltime,bool fuzzydate); bool get_time(TIME *ltime); bool is_null() { return field->is_null(); } - unsigned int size_of() { return sizeof(*this);} }; @@ -163,7 +160,6 @@ public: bool basic_const_item() const { return 1; } Item *new_item() { return new Item_null(name); } bool is_null() { return 1; } - unsigned int size_of() { return sizeof(*this);} }; class Item_param :public Item @@ -176,10 +172,12 @@ public: enum enum_field_types buffer_type; my_bool long_data_supplied; - Item_param(char *name_par=0){ + Item_param(char *name_par=0) + { name= name_par ? name_par : (char*) "?"; long_data_supplied = false; - item_type = STRING_ITEM; item_result_type = STRING_RESULT; + item_type = STRING_ITEM; + item_result_type = STRING_RESULT; } enum Type type() const { return item_type; } double val(); @@ -189,13 +187,13 @@ public: int save_in_field(Field *field); void set_null(); void set_int(longlong i); - void set_double(float i); void set_double(double i); void set_value(const char *str, uint length); void set_long_str(const char *str, ulong length); void set_long_binary(const char *str, ulong length); void set_longdata(const char *str, ulong length); void set_long_end(); + void reset() {} enum Item_result result_type () const { return item_result_type; } Item *new_item() { return new Item_param(name); } @@ -227,7 +225,6 @@ public: bool basic_const_item() const { return 1; } Item *new_item() { return new Item_int(name,value,max_length); } void print(String *str); - unsigned int size_of() { return sizeof(*this);} }; @@ -242,7 +239,6 @@ public: void make_field(Send_field *field); Item *new_item() { return new Item_uint(name,max_length); } void print(String *str); - unsigned int size_of() { return sizeof(*this);} }; @@ -273,7 +269,6 @@ public: void make_field(Send_field *field); bool basic_const_item() const { return 1; } Item *new_item() { return new Item_real(name,value,decimals,max_length); } - unsigned int size_of() { return sizeof(*this);} }; @@ -285,7 +280,6 @@ public: decimals=NOT_FIXED_DEC; max_length=DBL_DIG+8; } - unsigned int size_of() { return sizeof(*this);} }; class Item_string :public Item @@ -319,7 +313,6 @@ public: String *const_string() { return &str_value; } inline void append(char *str,uint length) { str_value.append(str,length); } void print(String *str); - unsigned int size_of() { return sizeof(*this);} }; @@ -331,7 +324,7 @@ public: Item_default() { name= (char*) "DEFAULT"; } enum Type type() const { return DEFAULT_ITEM; } void make_field(Send_field *field) {} - bool save_in_field(Field *field) + int save_in_field(Field *field) { field->set_default(); return 0; @@ -340,7 +333,6 @@ public: virtual longlong val_int() { return 0; } virtual String *val_str(String *str) { return 0; } bool basic_const_item() const { return 1; } - unsigned int size_of() { return sizeof(*this);} }; @@ -352,7 +344,6 @@ public: Item_datetime(const char *item_name): Item_string(item_name,"",0,default_charset_info) { max_length=19;} void make_field(Send_field *field); - unsigned int size_of() { return sizeof(*this);} }; class Item_empty_string :public Item_string @@ -360,7 +351,6 @@ class Item_empty_string :public Item_string public: Item_empty_string(const char *header,uint length) :Item_string("",0,default_charset_info) { name=(char*) header; max_length=length;} - unsigned int size_of() { return sizeof(*this);} }; class Item_varbinary :public Item @@ -375,7 +365,6 @@ public: int save_in_field(Field *field); void make_field(Send_field *field); enum Item_result result_type () const { return INT_RESULT; } - unsigned int size_of() { return sizeof(*this);} }; @@ -388,7 +377,6 @@ public: Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return result_field; } table_map used_tables() const { return 1; } virtual void fix_length_and_dec()=0; - unsigned int size_of() { return sizeof(*this);} }; @@ -438,7 +426,6 @@ public: void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); } enum Item_result result_type () const { return (*ref)->result_type(); } table_map used_tables() const { return (*ref)->used_tables(); } - unsigned int size_of() { return sizeof(*this);} }; @@ -458,10 +445,10 @@ public: { return ref->save_in_field(field); } - unsigned int size_of() { return sizeof(*this);} }; +#include "gstream.h" #include "spatial.h" #include "item_sum.h" #include "item_func.h" @@ -495,7 +482,6 @@ public: table_map used_tables() const { return (table_map) 1L; } bool const_item() const { return 0; } bool is_null() { return null_value; } - unsigned int size_of() { return sizeof(*this);} }; @@ -506,7 +492,6 @@ public: Item_buff() :null_value(0) {} virtual bool cmp(void)=0; virtual ~Item_buff(); /*line -e1509 */ - unsigned int size_of() { return sizeof(*this);} }; class Item_str_buff :public Item_buff @@ -517,7 +502,6 @@ public: Item_str_buff(Item *arg) :item(arg),value(arg->max_length) {} bool cmp(void); ~Item_str_buff(); // Deallocate String:s - unsigned int size_of() { return sizeof(*this);} }; @@ -528,7 +512,6 @@ class Item_real_buff :public Item_buff public: Item_real_buff(Item *item_par) :item(item_par),value(0.0) {} bool cmp(void); - unsigned int size_of() { return sizeof(*this);} }; class Item_int_buff :public Item_buff @@ -538,7 +521,6 @@ class Item_int_buff :public Item_buff public: Item_int_buff(Item *item_par) :item(item_par),value(0) {} bool cmp(void); - unsigned int size_of() { return sizeof(*this);} }; @@ -555,7 +537,6 @@ public: buff= (char*) sql_calloc(length=field->pack_length()); } bool cmp(void); - unsigned int size_of() { return sizeof(*this);} }; extern Item_buff *new_Item_buff(Item *item); diff --git a/sql/item_func.cc b/sql/item_func.cc index bd811726b47..ed7398b4f94 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -22,14 +22,13 @@ #endif #include "mysql_priv.h" +#include "slave.h" // for wait_for_master_pos #include #include #include #include #include -#include "slave.h" // for wait_for_master_pos -#include "gstream.h" - +#include /* return TRUE if item is a constant */ @@ -231,9 +230,11 @@ Field *Item_func::tmp_table_field(TABLE *t_arg) break; case STRING_RESULT: if (max_length > 255) - res= new Field_blob(max_length, maybe_null, name, t_arg, binary); + res= new Field_blob(max_length, maybe_null, name, t_arg, binary, + str_value.charset()); else - res= new Field_string(max_length, maybe_null, name, t_arg, binary); + res= new Field_string(max_length, maybe_null, name, t_arg, binary, + str_value.charset()); break; } return res; @@ -2390,18 +2391,19 @@ longlong Item_func_bit_xor::val_int() Item *get_system_var(enum_var_type var_type, LEX_STRING name) { - if (!my_strcasecmp(name.str,"VERSION")) - return new Item_string("@@VERSION",server_version, - (uint) strlen(server_version)); + if (!my_strcasecmp(system_charset_info, name.str, "VERSION")) + return new Item_string("@@VERSION", server_version, + (uint) strlen(server_version), + system_charset_info); THD *thd=current_thd; Item *item; sys_var *var; char buff[MAX_SYS_VAR_LENGTH+3]; - if (!(var= find_sys_var(name.str))) + if (!(var= find_sys_var(name.str, name.length))) { - net_printf(&thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, name.str); + net_printf(thd, ER_UNKNOWN_SYSTEM_VARIABLE, name.str); return 0; } if (!(item=var->item(thd, var_type))) @@ -2415,6 +2417,23 @@ Item *get_system_var(enum_var_type var_type, LEX_STRING name) } +Item *get_system_var(enum_var_type var_type, const char *var_name, uint length, + const char *item_name) +{ + THD *thd=current_thd; + Item *item; + sys_var *var; + + var= find_sys_var(var_name, length); + DBUG_ASSERT(var != 0); + if (!(item=var->item(thd, var_type))) + return 0; // Impossible + thd->safe_to_cache_query=0; + item->set_name(item_name); // Will use original name + return item; +} + + /* Check a user level lock. diff --git a/sql/item_func.h b/sql/item_func.h index 45427bec017..3ef25a1fae2 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -39,7 +39,7 @@ public: enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC, GE_FUNC,GT_FUNC,FT_FUNC, LIKE_FUNC,NOTLIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC, - COND_AND_FUNC, COND_OR_FUNC, CONX_XOR_FUNC, BETWEEN, IN_FUNC, + COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC, BETWEEN, IN_FUNC, INTERVAL_FUNC, SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC, SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 2bc9b170fc1..1b091f29a6b 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2394,8 +2394,6 @@ null: General functions for spatial objects ********************************************************/ -#include "gstream.h" - String *Item_func_geometry_from_text::val_str(String *str) { Geometry geom; @@ -2715,7 +2713,7 @@ String *Item_func_spatial_collection::val_str(String *str) } } - if (str->length() > max_allowed_packet) + if (str->length() > current_thd->variables.max_allowed_packet) goto ret; null_value = 0; diff --git a/sql/item_sum.h b/sql/item_sum.h index 3c86370c189..3e67f1e3624 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -70,7 +70,6 @@ public: void print(String *str); void fix_num_length_and_dec(); virtual bool setup(THD *thd) {return 0;} - unsigned int size_of() { return sizeof(*this);} }; @@ -85,7 +84,6 @@ public: longlong val_int() { return (longlong) val(); } /* Real as default */ String *val_str(String*str); void reset_field(); - unsigned int size_of() { return sizeof(*this);} }; @@ -100,7 +98,6 @@ public: double val() { return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } - unsigned int size_of() { return sizeof(*this);} }; @@ -118,7 +115,6 @@ class Item_sum_sum :public Item_sum_num void reset_field(); void update_field(int offset); const char *func_name() const { return "sum"; } - unsigned int size_of() { return sizeof(*this);} }; @@ -141,7 +137,6 @@ class Item_sum_count :public Item_sum_int void reset_field(); void update_field(int offset); const char *func_name() const { return "count"; } - unsigned int size_of() { return sizeof(*this);} }; @@ -193,7 +188,6 @@ class Item_sum_count_distinct :public Item_sum_int void update_field(int offset) { return ; } // Never called const char *func_name() const { return "count_distinct"; } bool setup(THD *thd); - unsigned int size_of() { return sizeof(*this);} }; @@ -213,7 +207,6 @@ public: String *val_str(String*); void make_field(Send_field *field); void fix_length_and_dec() {} - unsigned int size_of() { return sizeof(*this);} }; @@ -235,7 +228,6 @@ class Item_sum_avg :public Item_sum_num Item *result_item(Field *field) { return new Item_avg_field(this); } const char *func_name() const { return "avg"; } - unsigned int size_of() { return sizeof(*this);} }; class Item_sum_std; @@ -252,7 +244,6 @@ public: bool is_null() { (void) val_int(); return null_value; } void make_field(Send_field *field); void fix_length_and_dec() {} - unsigned int size_of() { return sizeof(*this);} }; class Item_sum_std :public Item_sum_num @@ -273,7 +264,6 @@ class Item_sum_std :public Item_sum_num Item *result_item(Field *field) { return new Item_std_field(this); } const char *func_name() const { return "std"; } - unsigned int size_of() { return sizeof(*this);} }; @@ -316,7 +306,6 @@ class Item_sum_hybrid :public Item_sum void min_max_update_str_field(int offset); void min_max_update_real_field(int offset); void min_max_update_int_field(int offset); - unsigned int size_of() { return sizeof(*this);} }; @@ -328,7 +317,6 @@ public: bool add(); const char *func_name() const { return "min"; } - unsigned int size_of() { return sizeof(*this);} }; @@ -340,7 +328,6 @@ public: bool add(); const char *func_name() const { return "max"; } - unsigned int size_of() { return sizeof(*this);} }; @@ -356,7 +343,6 @@ class Item_sum_bit :public Item_sum_int void reset(); longlong val_int(); void reset_field(); - unsigned int size_of() { return sizeof(*this);} }; @@ -367,7 +353,6 @@ class Item_sum_or :public Item_sum_bit bool add(); void update_field(int offset); const char *func_name() const { return "bit_or"; } - unsigned int size_of() { return sizeof(*this);} }; @@ -378,7 +363,6 @@ class Item_sum_and :public Item_sum_bit bool add(); void update_field(int offset); const char *func_name() const { return "bit_and"; } - unsigned int size_of() { return sizeof(*this);} }; /* @@ -409,7 +393,6 @@ public: bool add(); void reset_field() {}; void update_field(int offset_arg) {}; - unsigned int size_of() { return sizeof(*this);} }; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 566097893a8..b42b78c9c91 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -477,11 +477,10 @@ void Item_func_curtime::fix_length_and_dec() value=(longlong) ((ulong) ((uint) start->tm_hour)*10000L+ (ulong) (((uint) start->tm_min)*100L+ (uint) start->tm_sec)); - sprintf(buff,"%02d:%02d:%02d", - (int) start->tm_hour, - (int) start->tm_min, - (int) start->tm_sec); - buff_length=(uint) strlen(buff); + buff_length= my_sprintf(buff, (buff,"%02d:%02d:%02d", + (int) start->tm_hour, + (int) start->tm_min, + (int) start->tm_sec)); } void Item_func_now::fix_length_and_dec() @@ -497,14 +496,13 @@ void Item_func_now::fix_length_and_dec() (longlong) ((ulong) ((uint) start->tm_hour)*10000L+ (ulong) (((uint) start->tm_min)*100L+ (uint) start->tm_sec))); - sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d", - ((int) (start->tm_year+1900)) % 10000, - (int) start->tm_mon+1, - (int) start->tm_mday, - (int) start->tm_hour, - (int) start->tm_min, - (int) start->tm_sec); - buff_length=(uint) strlen(buff); + buff_length= (uint) my_sprintf(buff, (buff,"%04d-%02d-%02d %02d:%02d:%02d", + ((int) (start->tm_year+1900)) % 10000, + (int) start->tm_mon+1, + (int) start->tm_mday, + (int) start->tm_hour, + (int) start->tm_min, + (int) start->tm_sec)); /* For getdate */ ltime.year= start->tm_year+1900; ltime.month= start->tm_mon+1; @@ -538,6 +536,7 @@ String *Item_func_sec_to_time::val_str(String *str) char buff[23]; const char *sign=""; longlong seconds=(longlong) args[0]->val_int(); + ulong length; if ((null_value=args[0]->null_value)) return (String*) 0; if (seconds < 0) @@ -546,9 +545,9 @@ String *Item_func_sec_to_time::val_str(String *str) sign= "-"; } uint sec= (uint) ((ulonglong) seconds % 3600); - sprintf(buff,"%s%02lu:%02u:%02u",sign,(long) (seconds/3600), - sec/60, sec % 60); - str->copy(buff,(uint) strlen(buff)); + length= my_sprintf(buff,(buff,"%s%02lu:%02u:%02u",sign,(long) (seconds/3600), + sec/60, sec % 60)); + str->copy(buff, length); return str; } @@ -658,6 +657,7 @@ String *Item_func_date_format::val_str(String *str) TIME l_time; char intbuff[15]; uint size,weekday; + ulong length; if (!date_or_time) { @@ -750,40 +750,39 @@ String *Item_func_date_format::val_str(String *str) null_value=1; return 0; } - sprintf(intbuff,"%d",l_time.day); - str->append(intbuff); + length= my_sprintf(intbuff, (intbuff,"%d",l_time.day)); + str->append(intbuff, length); if (l_time.day >= 10 && l_time.day <= 19) str->append("th"); else { - switch (l_time.day %10) - { + switch (l_time.day %10) { case 1: - str->append("st"); + str->append("st",2); break; case 2: - str->append("nd"); + str->append("nd",2); break; case 3: - str->append("rd"); + str->append("rd",2); break; default: - str->append("th"); + str->append("th",2); break; } } break; case 'Y': sprintf(intbuff,"%04d",l_time.year); - str->append(intbuff); + str->append(intbuff,4); break; case 'y': sprintf(intbuff,"%02d",l_time.year%100); - str->append(intbuff); + str->append(intbuff,2); break; case 'm': sprintf(intbuff,"%02d",l_time.month); - str->append(intbuff); + str->append(intbuff,2); break; case 'c': sprintf(intbuff,"%d",l_time.month); @@ -791,7 +790,7 @@ String *Item_func_date_format::val_str(String *str) break; case 'd': sprintf(intbuff,"%02d",l_time.day); - str->append(intbuff); + str->append(intbuff,2); break; case 'e': sprintf(intbuff,"%d",l_time.day); @@ -799,16 +798,16 @@ String *Item_func_date_format::val_str(String *str) break; case 'H': sprintf(intbuff,"%02d",l_time.hour); - str->append(intbuff); + str->append(intbuff,2); break; case 'h': case 'I': sprintf(intbuff,"%02d", (l_time.hour+11)%12+1); - str->append(intbuff); + str->append(intbuff,2); break; case 'i': /* minutes */ sprintf(intbuff,"%02d",l_time.minute); - str->append(intbuff); + str->append(intbuff,2); break; case 'j': if (date_or_time) @@ -819,7 +818,7 @@ String *Item_func_date_format::val_str(String *str) sprintf(intbuff,"%03d", (int) (calc_daynr(l_time.year,l_time.month,l_time.day) - calc_daynr(l_time.year,1,1)) + 1); - str->append(intbuff); + str->append(intbuff,3); break; case 'k': sprintf(intbuff,"%d",l_time.hour); @@ -830,7 +829,7 @@ String *Item_func_date_format::val_str(String *str) str->append(intbuff); break; case 'p': - str->append(l_time.hour < 12 ? "AM" : "PM"); + str->append(l_time.hour < 12 ? "AM" : "PM",2); break; case 'r': sprintf(intbuff,(l_time.hour < 12) ? "%02d:%02d:%02d AM" : @@ -844,7 +843,8 @@ String *Item_func_date_format::val_str(String *str) str->append(intbuff); break; case 'T': - sprintf(intbuff,"%02d:%02d:%02d",l_time.hour,l_time.minute,l_time.second); + sprintf(intbuff,"%02d:%02d:%02d", l_time.hour, l_time.minute, + l_time.second); str->append(intbuff); break; case 'U': @@ -852,7 +852,7 @@ String *Item_func_date_format::val_str(String *str) { uint year; sprintf(intbuff,"%02d",calc_week(&l_time, 0, (*ptr) == 'U', &year)); - str->append(intbuff); + str->append(intbuff,2); } break; case 'v': @@ -860,7 +860,7 @@ String *Item_func_date_format::val_str(String *str) { uint year; sprintf(intbuff,"%02d",calc_week(&l_time, 1, (*ptr) == 'V', &year)); - str->append(intbuff); + str->append(intbuff,2); } break; case 'x': @@ -869,13 +869,13 @@ String *Item_func_date_format::val_str(String *str) uint year; (void) calc_week(&l_time, 1, (*ptr) == 'X', &year); sprintf(intbuff,"%04d",year); - str->append(intbuff); + str->append(intbuff,4); } break; case 'w': weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),1); - sprintf(intbuff,"%01d",weekday); - str->append(intbuff); + sprintf(intbuff,"%d",weekday); + str->append(intbuff,1); break; default: str->append(*ptr); diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index a45ea159014..94e8e6eba43 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -176,7 +176,6 @@ public: const char *func_name() const { return "weekday"; } enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1; } - unsigned int size_of() { return sizeof(*this);} }; class Item_func_dayname :public Item_func_weekday @@ -202,7 +201,6 @@ public: { decimals=0; max_length=10; } - unsigned int size_of() { return sizeof(*this);} }; @@ -240,7 +238,6 @@ public: { return (!t_arg) ? result_field : new Field_date(maybe_null, name, t_arg); } - unsigned int size_of() { return sizeof(*this);} }; @@ -259,7 +256,6 @@ public: return (!t_arg) ? result_field : new Field_datetime(maybe_null, name, t_arg); } - unsigned int size_of() { return sizeof(*this);} }; @@ -286,7 +282,6 @@ public: { return (!t_arg) ? result_field : new Field_time(maybe_null, name, t_arg); } - unsigned int size_of() { return sizeof(*this);} }; @@ -300,7 +295,6 @@ public: const char *func_name() const { return "curdate"; } void fix_length_and_dec(); /* Retrieves curtime */ bool get_date(TIME *res,bool fuzzy_date); - unsigned int size_of() { return sizeof(*this);} }; @@ -322,7 +316,6 @@ public: const char *func_name() const { return "now"; } void fix_length_and_dec(); bool get_date(TIME *res,bool fuzzy_date); - unsigned int size_of() { return sizeof(*this);} }; @@ -347,7 +340,6 @@ public: const char *func_name() const { return "date_format"; } void fix_length_and_dec(); uint format_length(const String *format); - unsigned int size_of() { return sizeof(*this);} }; @@ -407,7 +399,6 @@ public: double val() { return (double) val_int(); } longlong val_int(); bool get_date(TIME *res,bool fuzzy_date); - unsigned int size_of() { return sizeof(*this);} }; class Item_extract :public Item_int_func @@ -421,7 +412,6 @@ class Item_extract :public Item_int_func longlong val_int(); const char *func_name() const { return "extract"; } void fix_length_and_dec(); - unsigned int size_of() { return sizeof(*this);} }; class Item_typecast :public Item_str_func diff --git a/sql/item_uniq.h b/sql/item_uniq.h index 6ab01d55e2f..f0d1d353cfb 100644 --- a/sql/item_uniq.h +++ b/sql/item_uniq.h @@ -29,9 +29,9 @@ public: :Item_real_func(list) {} double val() { return 0.0; } void fix_length_and_dec() { decimals=0; max_length=6; } - unsigned int size_of() { return sizeof(*this);} }; + class Item_sum_unique_users :public Item_sum_num { public: diff --git a/sql/lex.h b/sql/lex.h index 83890e75c20..b9e993c54c7 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -327,7 +327,6 @@ static SYMBOL symbols[] = { { "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0}, { "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0}, { "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS),0,0}, - { "SQL_ERROR_COUNT", SYM(SQL_ERROR_COUNT),0,0}, { "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0}, { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0}, { "SQL_THREAD", SYM(SQL_THREAD),0,0}, diff --git a/sql/log.cc b/sql/log.cc index b3ce1226210..213f5102507 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -215,15 +215,18 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, time_t skr=time(NULL); struct tm tm_tmp; localtime_r(&skr,&tm_tmp); - sprintf(buff,"# %s, Version: %s at %02d%02d%02d %2d:%02d:%02d\n", - my_progname,server_version, - tm_tmp.tm_year % 100, - tm_tmp.tm_mon+1, - tm_tmp.tm_mday, - tm_tmp.tm_hour, - tm_tmp.tm_min, - tm_tmp.tm_sec); - if (my_b_write(&log_file, (byte*) buff,(uint) strlen(buff)) || + ulong length; + length= my_sprintf(buff, + (buff, + "# %s, Version: %s at %02d%02d%02d %2d:%02d:%02d\n", + my_progname,server_version, + tm_tmp.tm_year % 100, + tm_tmp.tm_mon+1, + tm_tmp.tm_mday, + tm_tmp.tm_hour, + tm_tmp.tm_min, + tm_tmp.tm_sec)); + if (my_b_write(&log_file, (byte*) buff, length) || flush_io_cache(&log_file)) goto err; break; @@ -931,7 +934,8 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, { if (is_open() && (what_to_log & (1L << (uint) command))) { - int error=0; + uint length; + int error= 0; VOID(pthread_mutex_lock(&LOCK_log)); /* Test if someone closed after the is_open test */ @@ -965,6 +969,7 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, last_time=skr; struct tm tm_tmp; struct tm *start; + ulong length; localtime_r(&skr,&tm_tmp); start=&tm_tmp; /* Note that my_b_write() assumes it knows the length for this */ @@ -980,8 +985,10 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, } else if (my_b_write(&log_file, (byte*) "\t\t",2) < 0) error=errno; - sprintf(buff,"%7ld %-11.11s", id,command_name[(uint) command]); - if (my_b_write(&log_file, (byte*) buff,strlen(buff))) + length=my_sprintf(buff, + (buff, "%7ld %-11.11s", id, + command_name[(uint) command])); + if (my_b_write(&log_file, (byte*) buff,length)) error=errno; if (format) { @@ -1218,11 +1225,7 @@ err: /* Write update log in a format suitable for incremental backup - - NOTE - - This code should be deleted in MySQL 5,0 as the binary log - is a full replacement for the update log. - + This is also used by the slow query log. */ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, diff --git a/sql/log_event.cc b/sql/log_event.cc index 23622bc0141..df5ef4eb7fe 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1516,9 +1516,12 @@ void Append_block_log_event::print(FILE* file, bool short_form, #ifndef MYSQL_CLIENT void Append_block_log_event::pack_info(String* packet) { - char buf1[256]; - sprintf(buf1, ";file_id=%u;block_len=%u", file_id, block_len); - net_store_data(packet, buf1); + char buf[256]; + uint length; + length= (uint) my_sprintf(buf, + (buf, ";file_id=%u;block_len=%u", file_id, + block_len)); + net_store_data(packet, buf, length); } @@ -1560,9 +1563,10 @@ void Delete_file_log_event::print(FILE* file, bool short_form, #ifndef MYSQL_CLIENT void Delete_file_log_event::pack_info(String* packet) { - char buf1[64]; - sprintf(buf1, ";file_id=%u", (uint) file_id); - net_store_data(packet, buf1); + char buf[64]; + uint length; + length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id)); + net_store_data(packet, buf, length); } #endif @@ -1607,8 +1611,9 @@ void Execute_load_log_event::print(FILE* file, bool short_form, void Execute_load_log_event::pack_info(String* packet) { char buf[64]; - sprintf(buf, ";file_id=%u", (uint) file_id); - net_store_data(packet, buf); + uint length; + length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id)); + net_store_data(packet, buf, length); } #endif diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 5bd88e9b09a..d678e76c5ed 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -40,6 +40,7 @@ #include "mysql_version.h" #include "mysqld_error.h" #include "errmsg.h" +#include #if defined( OS2) && defined(MYSQL_SERVER) #undef ER @@ -124,7 +125,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host, if (!host || !strcmp(host,LOCAL_HOST)) host=LOCAL_HOST_NAMEDPIPE; - sprintf( szPipeName, "\\\\%s\\pipe\\%s", host, unix_socket); + sprintf(szPipeName, "\\\\%s\\pipe\\%s", host, unix_socket); DBUG_PRINT("info",("Server name: '%s'. Named Pipe: %s", host, unix_socket)); @@ -456,15 +457,14 @@ mc_simple_command(MYSQL *mysql,enum enum_server_command command, if (!arg) arg=""; - if (net_write_command(net,(uchar) command,arg, - length ? length :(uint) strlen(arg))) + if (net_write_command(net, (uchar) command, NullS, 0, arg, length)) { - DBUG_PRINT("error",("Can't send command to server. Error: %d",socket_errno)); + DBUG_PRINT("error",("Can't send command to server. Error: %d", + socket_errno)); mc_end_server(mysql); if (mc_mysql_reconnect(mysql)) goto end; - if (net_write_command(net,(uchar) command,arg, - length ? length :(uint) strlen(arg))) + if (net_write_command(net,(uchar) command, NullS, 0, arg, length)) { net->last_errno=CR_SERVER_GONE_ERROR; strmov(net->last_error,ER(net->last_errno)); @@ -1027,18 +1027,19 @@ get_info: DBUG_RETURN(0); } -int mc_mysql_query(MYSQL *mysql, const char *query, uint length) + +int mc_mysql_query(MYSQL *mysql, const char *query, uint length) { - DBUG_ENTER("mysql_real_query"); + DBUG_ENTER("mc_mysql_query"); DBUG_PRINT("enter",("handle: %lx",mysql)); DBUG_PRINT("query",("Query = \"%s\"",query)); - if (!length) - length = strlen(query); + DBUG_ASSERT(length == strlen(query)); if (mc_simple_command(mysql,COM_QUERY,query,length,1)) DBUG_RETURN(-1); DBUG_RETURN(mc_mysql_read_query_result(mysql)); } + static int mc_send_file_to_server(MYSQL *mysql, const char *filename) { int fd, readcount, result= -1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 61973c5af91..4532646b1c2 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -294,7 +294,7 @@ inline THD *_current_thd(void) #define prepare_execute(A) ((A)->command == COM_EXECUTE) int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); -int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); +int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create); int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent); void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags); int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists); @@ -308,8 +308,13 @@ int quick_rm_table(enum db_type base,const char *db, bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list); bool mysql_change_db(THD *thd,const char *name); void mysql_parse(THD *thd,char *inBuf,uint length); +void free_items(Item *item); +bool alloc_query(THD *thd, char *packet, ulong packet_length); void mysql_init_select(LEX *lex); +void mysql_init_query(THD *thd); +void mysql_reset_errors(THD *thd); bool mysql_new_select(LEX *lex, bool move_down); +void create_select_for_variable(const char *var_name); void mysql_init_multi_delete(LEX *lex); void init_max_user_conn(void); void free_max_user_conn(void); @@ -318,7 +323,7 @@ pthread_handler_decl(handle_bootstrap,arg); sig_handler end_thread_signal(int sig); void end_thread(THD *thd,bool put_in_cache); void flush_thread_cache(); -void mysql_execute_command(void); +void mysql_execute_command(THD *thd); bool do_command(THD *thd); bool dispatch_command(enum enum_server_command command, THD *thd, char* packet, uint packet_length); @@ -349,11 +354,12 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* table_list, bool check_simple_select(); /* net_pkg.c */ -void send_warning(NET *net, uint sql_errno, const char *err=0); -void net_printf(NET *net,uint sql_errno, ...); -void send_ok(NET *net,ha_rows affected_rows=0L,ulonglong id=0L, +void send_warning(THD *thd, uint sql_errno, const char *err=0); +void net_printf(THD *thd,uint sql_errno, ...); +void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L, const char *info=0); -void send_eof(NET *net,bool no_flush=0); +void send_eof(THD *thd, bool no_flush=0); +void net_send_error(NET *net, uint sql_errno, const char *err); char *net_store_length(char *packet,ulonglong length); char *net_store_length(char *packet,uint length); char *net_store_data(char *to,const char *from); @@ -391,7 +397,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, int mysql_create_table(THD *thd,const char *db, const char *table_name, HA_CREATE_INFO *create_info, List &fields, List &keys, - bool tmp_table, bool no_log); + bool tmp_table, bool no_log, uint select_field_count); TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, const char *db, const char *name, List *extra_fields, @@ -491,20 +497,19 @@ int mysqld_show_privileges(THD *thd); int mysqld_show_column_types(THD *thd); /* sql_prepare.cc */ -void mysql_com_prepare(THD *thd,char*packet,uint packet_length); -void mysql_init_query(THD *thd);/* sql_parse. cc */ -void mysql_com_execute(THD *thd); -void mysql_com_longdata(THD *thd); +int compare_prep_stmt(PREP_STMT *a, PREP_STMT *b, void *not_used); +void free_prep_stmt(PREP_STMT *stmt, TREE_FREE mode, void *not_used); +bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length); +void mysql_stmt_execute(THD *thd, char *packet); +void mysql_stm_close(THD *thd, char *packet); +void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length); int check_insert_fields(THD *thd,TABLE *table,List &fields, List &values, ulong counter); /* sql_error.cc */ -void push_error(uint code, const char *msg); -void push_warning(uint code, const char *msg); -int mysqld_show_warnings(THD *thd); -int mysqld_show_errors(THD *thd); -int mysqld_show_warnings_count(THD *thd); -int mysqld_show_errors_count(THD *); +void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, + const char *msg); +my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show); /* sql_handler.cc */ int mysql_ha_open(THD *thd, TABLE_LIST *tables); @@ -682,13 +687,13 @@ extern char f_fyllchar; extern MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log; extern FILE *bootstrap_file; extern pthread_key(MEM_ROOT*,THR_MALLOC); -extern pthread_key(NET*, THR_NET); extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status, - LOCK_grant, LOCK_error_log, LOCK_delayed_insert, + LOCK_error_log, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_system_variables; +extern rw_lock_t LOCK_grant; extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager; extern pthread_attr_t connection_attrib; extern I_List threads; @@ -737,7 +742,7 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list); void unireg_init(ulong options); void unireg_end(int signal); -int rea_create_table(my_string file_name,HA_CREATE_INFO *create_info, +int rea_create_table(THD *thd, my_string file_name,HA_CREATE_INFO *create_info, List &create_field, uint key_count,KEY *key_info); int format_number(uint inputflag,uint max_length,my_string pos,uint length, @@ -818,6 +823,8 @@ extern int sql_cache_hit(THD *thd, char *inBuf, uint length); /* item.cc */ Item *get_system_var(enum_var_type var_type, LEX_STRING name); +Item *get_system_var(enum_var_type var_type, const char *var_name, uint length, + const char *item_name); /* Some inline functions for more speed */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 89f1c07b2fe..8c3db86e44f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -240,6 +240,8 @@ SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_YES; SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_NO; #endif +const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"}; + bool opt_large_files= sizeof(my_off_t) > 4; /* @@ -413,15 +415,14 @@ my_bool use_temp_pool=0; pthread_key(MEM_ROOT*,THR_MALLOC); pthread_key(THD*, THR_THD); -pthread_key(NET*, THR_NET); pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, - LOCK_mapped_file, LOCK_status, LOCK_grant, + LOCK_mapped_file, LOCK_status, LOCK_error_log, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_global_system_variables, LOCK_user_conn, LOCK_slave_list, LOCK_active_mi; - +rw_lock_t LOCK_grant; pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped, COND_slave_start; pthread_cond_t COND_thread_cache,COND_flush_thread_cache; @@ -1042,7 +1043,7 @@ static void server_init(void) if (Service.IsNT() && mysql_unix_port[0] && !opt_bootstrap && opt_enable_named_pipe) { - sprintf( szPipeName, "\\\\.\\pipe\\%s", mysql_unix_port ); + sprintf(szPipeName, "\\\\.\\pipe\\%s", mysql_unix_port ); ZeroMemory( &saPipeSecurity, sizeof(saPipeSecurity) ); ZeroMemory( &sdPipeDescriptor, sizeof(sdPipeDescriptor) ); if ( !InitializeSecurityDescriptor(&sdPipeDescriptor, @@ -1127,12 +1128,12 @@ static void server_init(void) void yyerror(const char *s) { - NET *net=my_pthread_getspecific_ptr(NET*,THR_NET); - char *yytext=(char*) current_lex->tok_start; + THD *thd=current_thd; + char *yytext=(char*) thd->lex.tok_start; if (!strcmp(s,"parse error")) s=ER(ER_SYNTAX_ERROR); - net_printf(net,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "", - current_lex->yylineno); + net_printf(thd,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "", + thd->lex.yylineno); } @@ -1148,7 +1149,7 @@ void close_connection(NET *net,uint errcode,bool lock) if ((vio=net->vio) != 0) { if (errcode) - send_error(net,errcode,ER(errcode)); /* purecov: inspected */ + net_send_error(net,errcode,ER(errcode)); /* purecov: inspected */ vio_close(vio); /* vio is freed in delete thd */ } if (lock) @@ -1541,8 +1542,8 @@ static void *signal_hand(void *arg __attribute__((unused))) if ((pidFile = my_create(pidfile_name,0664, O_WRONLY, MYF(MY_WME))) >= 0) { char buff[21]; - sprintf(buff,"%lu",(ulong) getpid()); - (void) my_write(pidFile, buff,strlen(buff),MYF(MY_WME)); + ulong length= my_sprintf(buff, (buff,"%lu",(ulong) getpid())); + (void) my_write(pidFile, buff, length, MYF(MY_WME)); (void) my_close(pidFile,MYF(0)); } } @@ -1640,11 +1641,12 @@ static void *signal_hand(void *arg __attribute__((unused))) static int my_message_sql(uint error, const char *str, myf MyFlags __attribute__((unused))) { - NET *net; + THD *thd; DBUG_ENTER("my_message_sql"); DBUG_PRINT("error",("Message: '%s'",str)); - if ((net=my_pthread_getspecific_ptr(NET*,THR_NET))) + if ((thd=current_thd)) { + NET *net= &thd->net; if (!net->last_error[0]) // Return only first message { strmake(net->last_error,str,sizeof(net->last_error)-1); @@ -1853,7 +1855,6 @@ int main(int argc, char **argv) (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_grant,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_open,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW); @@ -1871,6 +1872,7 @@ int main(int argc, char **argv) (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST); + (void) my_rwlock_init(&LOCK_grant, NULL); (void) pthread_cond_init(&COND_thread_count,NULL); (void) pthread_cond_init(&COND_refresh,NULL); (void) pthread_cond_init(&COND_thread_cache,NULL); @@ -2027,7 +2029,7 @@ int main(int argc, char **argv) After this we can't quit by a simple unireg_abort */ error_handler_hook = my_message_sql; - if (pthread_key_create(&THR_THD,NULL) || pthread_key_create(&THR_NET,NULL) || + if (pthread_key_create(&THR_THD,NULL) || pthread_key_create(&THR_MALLOC,NULL)) { sql_print_error("Can't create thread-keys"); @@ -2481,7 +2483,7 @@ static void create_new_thread(THD *thd) thread_count--; thd->killed=1; // Safety (void) pthread_mutex_unlock(&LOCK_thread_count); - net_printf(net,ER_CANT_CREATE_THREAD,error); + net_printf(thd,ER_CANT_CREATE_THREAD,error); (void) pthread_mutex_lock(&LOCK_thread_count); close_connection(net,0,0); delete thd; @@ -2886,6 +2888,7 @@ enum options { OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS, OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE, + OPT_MAX_ERROR_COUNT, OPT_MAX_PREP_STMT, OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE, OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT, @@ -3506,6 +3509,11 @@ struct my_option my_long_options[] = "Don't start more than this number of threads to handle INSERT DELAYED statements.", (gptr*) &max_insert_delayed_threads, (gptr*) &max_insert_delayed_threads, 0, GET_ULONG, REQUIRED_ARG, 20, 1, 16384, 0, 1, 0}, + {"max_error_count", OPT_MAX_ERROR_COUNT, + "Max number of errors/warnings to store for a statement", + (gptr*) &global_system_variables.max_error_count, + (gptr*) &max_system_variables.max_error_count, + 0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 1, 65535, 0, 1, 0}, {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE, "Don't allow creation of heap tables bigger than this.", (gptr*) &global_system_variables.max_heap_table_size, @@ -3516,6 +3524,11 @@ struct my_option my_long_options[] = (gptr*) &global_system_variables.max_join_size, (gptr*) &max_system_variables.max_join_size, 0, GET_ULONG, REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0}, + {"max_prepared_statements", OPT_MAX_PREP_STMT, + "Max number of prepared_statements for a thread", + (gptr*) &global_system_variables.max_prep_stmt_count, + (gptr*) &max_system_variables.max_prep_stmt_count, 0, GET_ULONG, + REQUIRED_ARG, DEFAULT_PREP_STMT_COUNT, 0, ~0L, 0, 1, 0}, {"max_sort_length", OPT_MAX_SORT_LENGTH, "The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).", (gptr*) &global_system_variables.max_sort_length, diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index 1e7536e3007..19234181839 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -20,19 +20,17 @@ /* Send a error string to client */ -void send_error(NET *net, uint sql_errno, const char *err) +void send_error(THD *thd, uint sql_errno, const char *err) { uint length; char buff[MYSQL_ERRMSG_SIZE+2]; - THD *thd=current_thd; + NET *net= &thd->net; DBUG_ENTER("send_error"); DBUG_PRINT("enter",("sql_errno: %d err: %s", sql_errno, err ? err : net->last_error[0] ? - net->last_error : "NULL")); + net->last_error : "NULL")); query_cache_abort(net); - if (thd) - thd->query_error = 1; // needed to catch query errors during replication if (!err) { if (sql_errno) @@ -48,10 +46,9 @@ void send_error(NET *net, uint sql_errno, const char *err) } } } - push_error(sql_errno, err); if (net->vio == 0) { - if (thd && thd->bootstrap) + if (thd->bootstrap) { /* In bootstrap it's ok to print on stderr */ fprintf(stderr,"ERROR: %d %s\n",sql_errno,err); @@ -68,53 +65,73 @@ void send_error(NET *net, uint sql_errno, const char *err) else { length=(uint) strlen(err); - set_if_smaller(length,MYSQL_ERRMSG_SIZE); + set_if_smaller(length,MYSQL_ERRMSG_SIZE-1); } - VOID(net_write_command(net,(uchar) 255,(char*) err,length)); - if (thd) - thd->fatal_error=0; // Error message is given + VOID(net_write_command(net,(uchar) 255, "", 0, (char*) err,length)); + thd->fatal_error=0; // Error message is given DBUG_VOID_RETURN; } /* - At some point we need to be able to distinguish between warnings and - errors; The following function will help make this easier. + Send an error to the client when a connection is forced close + This is used by mysqld.cc, which doesn't have a THD */ -void send_warning(NET *net, uint sql_errno, const char *err) +void net_send_error(NET *net, uint sql_errno, const char *err) { - DBUG_ENTER("send_warning"); - push_warning(sql_errno, err ? err : ER(sql_errno)); + char buff[2]; + uint length; + DBUG_ENTER("send_net_error"); - /* - TODO : - Try to return ok with warning status to client, instead - of returning error .. - */ - send_error(net,sql_errno,err); + int2store(buff,sql_errno); + length=(uint) strlen(err); + set_if_smaller(length,MYSQL_ERRMSG_SIZE-1); + net_write_command(net,(uchar) 255, buff, 2, err, length); + DBUG_VOID_RETURN; +} + + +/* + Send a warning to the end user + + SYNOPSIS + send_warning() + thd Thread handler + sql_errno Warning number (error message) + err Error string. If not set, use ER(sql_errno) + + DESCRIPTION + Register the warning so that the user can get it with mysql_warnings() + Send an ok (+ warning count) to the end user. +*/ + +void send_warning(THD *thd, uint sql_errno, const char *err) +{ + DBUG_ENTER("send_warning"); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, sql_errno, + err ? err : ER(sql_errno)); + send_ok(thd); DBUG_VOID_RETURN; } /* Write error package and flush to client - It's a little too low level, but I don't want to allow another buffer + It's a little too low level, but I don't want to use another buffer for + this */ -/* VARARGS3 */ void -net_printf(NET *net, uint errcode, ...) +net_printf(THD *thd, uint errcode, ...) { va_list args; uint length,offset; const char *format,*text_pos; int head_length= NET_HEADER_SIZE; - THD *thd=current_thd; + NET *net= &thd->net; DBUG_ENTER("net_printf"); DBUG_PRINT("enter",("message: %u",errcode)); - if (thd) - thd->query_error = 1; // if we are here, something is wrong :-) query_cache_abort(net); // Safety va_start(args,errcode); /* @@ -132,10 +149,9 @@ net_printf(NET *net, uint errcode, ...) length=sizeof(net->last_error)-1; /* purecov: inspected */ va_end(args); - push_error(errcode, text_pos); if (net->vio == 0) { - if (thd && thd->bootstrap) + if (thd->bootstrap) { /* In bootstrap it's ok to print on stderr */ fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos); @@ -150,16 +166,42 @@ net_printf(NET *net, uint errcode, ...) if (offset) int2store(text_pos-2, errcode); VOID(net_real_write(net,(char*) net->buff,length+head_length+1+offset)); - if (thd) - thd->fatal_error=0; // Error message is given + thd->fatal_error=0; // Error message is given DBUG_VOID_RETURN; } +/* + Return ok to the client. + + SYNOPSIS + send_ok() + thd Thread handler + affected_rows Number of rows changed by statement + id Auto_increment id for first row (if used) + message Message to send to the client (Used by mysql_status) + + DESCRIPTION + The ok packet has the following structure + + 0 Marker (1 byte) + affected_rows Stored in 1-9 bytes + id Stored in 1-9 bytes + server_status Copy of thd->server_status; Can be used by client + to check if we are inside an transaction + New in 4.0 protocol + warning_count Stored in 2 bytes; New in 4.1 protocol + message Stored as packed length (1-9 bytes) + message + Is not stored if no message + + If net->no_send_ok return without sending packet +*/ + void -send_ok(NET *net,ha_rows affected_rows,ulonglong id,const char *message) +send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message) { - if (net->no_send_ok) // hack for re-parsing queries + NET *net= &thd->net; + if (net->no_send_ok || !net->vio) // hack for re-parsing queries return; char buff[MYSQL_ERRMSG_SIZE+10],*pos; @@ -167,31 +209,75 @@ send_ok(NET *net,ha_rows affected_rows,ulonglong id,const char *message) buff[0]=0; // No fields pos=net_store_length(buff+1,(ulonglong) affected_rows); pos=net_store_length(pos, (ulonglong) id); - if (net->return_status) + if (thd->client_capabilities & CLIENT_PROTOCOL_41) + { + int2store(pos,thd->server_status); + pos+=2; + + /* We can only return up to 65535 warnings in two bytes */ + uint tmp= min(thd->total_warn_count, 65535); + int2store(pos, tmp); + pos+= 2; + } + else if (net->return_status) // For 4.0 protocol { - int2store(pos,*net->return_status); + int2store(pos,thd->server_status); pos+=2; } if (message) pos=net_store_data((char*) pos,message); - if (net->vio != 0) - { - VOID(my_net_write(net,buff,(uint) (pos-buff))); - VOID(net_flush(net)); - } + VOID(my_net_write(net,buff,(uint) (pos-buff))); + VOID(net_flush(net)); DBUG_VOID_RETURN; } + +/* + Send eof (= end of result set) to the client + + SYNOPSIS + send_eof() + thd Thread handler + no_flush Set to 1 if there will be more data to the client, + like in send_fields(). + + DESCRIPTION + The eof packet has the following structure + + 254 Marker (1 byte) + warning_count Stored in 2 bytes; New in 4.1 protocol + status_flag Stored in 2 bytes; + For flags like SERVER_STATUS_MORE_RESULTS + + Note that the warning count will not be sent if 'no_flush' is set as + we don't want to report the warning count until all data is sent to the + client. +*/ + void -send_eof(NET *net,bool no_flush) +send_eof(THD *thd, bool no_flush) { static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */ + NET *net= &thd->net; DBUG_ENTER("send_eof"); if (net->vio != 0) { - VOID(my_net_write(net,eof_buff,1)); - if (!no_flush) + if (!no_flush && (thd->client_capabilities & CLIENT_PROTOCOL_41)) + { + char buff[5]; + uint tmp= min(thd->total_warn_count, 65535); + buff[0]=254; + int2store(buff+1, tmp); + int2store(buff+3, 0); // No flags yet + VOID(my_net_write(net,buff,5)); VOID(net_flush(net)); + } + else + { + VOID(my_net_write(net,eof_buff,1)); + if (!no_flush) + VOID(net_flush(net)); + } } DBUG_VOID_RETURN; } diff --git a/sql/net_serv.cc b/sql/net_serv.cc index bb7100f31be..538ff5babe6 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -75,12 +75,12 @@ extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; #define TEST_BLOCKING 8 #define MAX_THREE_BYTES 255L*255L*255L -static int net_write_buff(NET *net,const char *packet,ulong len); +static my_bool net_write_buff(NET *net,const char *packet,ulong len); /* Init with packet info */ -int my_net_init(NET *net, Vio* vio) +my_bool my_net_init(NET *net, Vio* vio) { DBUG_ENTER("my_net_init"); my_net_local_init(net); /* Set some limits */ @@ -127,7 +127,7 @@ void net_end(NET *net) /* Realloc the packet buffer */ -static my_bool net_realloc(NET *net, ulong length) +my_bool net_realloc(NET *net, ulong length) { uchar *buff; ulong pkt_length; @@ -184,14 +184,14 @@ void net_clear(NET *net) /* Flush write_buffer if not empty. */ -int net_flush(NET *net) +my_bool net_flush(NET *net) { - int error=0; + my_bool error= 0; DBUG_ENTER("net_flush"); if (net->buff != net->write_pos) { - error=net_real_write(net,(char*) net->buff, - (ulong) (net->write_pos - net->buff)); + error=test(net_real_write(net,(char*) net->buff, + (ulong) (net->write_pos - net->buff))); net->write_pos=net->buff; } /* Sync packet number if using compression */ @@ -212,7 +212,7 @@ int net_flush(NET *net) ** NOTE: If compression is used the original package is modified! */ -int +my_bool my_net_write(NET *net,const char *packet,ulong len) { uchar buff[NET_HEADER_SIZE]; @@ -242,17 +242,38 @@ my_net_write(NET *net,const char *packet,ulong len) /* Send a command to the server. - As the command is part of the first data packet, we have to do some data - juggling to put the command in there, without having to create a new - packet. - This function will split big packets into sub-packets if needed. - (Each sub packet can only be 2^24 bytes) + + SYNOPSIS + net_write_command() + net NET handler + command Command in MySQL server (enum enum_server_command) + header Header to write after command + head_len Length of header + packet Query or parameter to query + len Length of packet + + DESCRIPTION + The reason for having both header and packet is so that libmysql + can easy add a header to a special command (like prepared statements) + without having to re-alloc the string. + + As the command is part of the first data packet, we have to do some data + juggling to put the command in there, without having to create a new + packet. + This function will split big packets into sub-packets if needed. + (Each sub packet can only be 2^24 bytes) + + RETURN VALUES + 0 ok + 1 error */ -int -net_write_command(NET *net,uchar command,const char *packet,ulong len) +my_bool +net_write_command(NET *net,uchar command, + const char *header, ulong head_len, + const char *packet, ulong len) { - ulong length=len+1; /* 1 extra byte for command */ + ulong length=len+1+head_len; /* 1 extra byte for command */ uchar buff[NET_HEADER_SIZE+1]; uint header_size=NET_HEADER_SIZE+1; buff[4]=command; /* For first packet */ @@ -260,25 +281,28 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len) if (length >= MAX_THREE_BYTES) { /* Take into account that we have the command in the first header */ - len= MAX_THREE_BYTES -1; + len= MAX_THREE_BYTES - 1 - head_len; do { int3store(buff, MAX_THREE_BYTES); buff[3]= (uchar) net->pkt_nr++; if (net_write_buff(net,(char*) buff, header_size) || - net_write_buff(net,packet,len)) + net_write_buff(net, header, head_len) || + net_write_buff(net, packet, len)) return 1; packet+= len; length-= MAX_THREE_BYTES; len=MAX_THREE_BYTES; + head_len=0; header_size=NET_HEADER_SIZE; } while (length >= MAX_THREE_BYTES); len=length; /* Data left to be written */ } int3store(buff,length); buff[3]= (uchar) net->pkt_nr++; - return test(net_write_buff(net,(char*) buff,header_size) || - net_write_buff(net,packet,len) || net_flush(net)); + return test(net_write_buff(net, (char*) buff, header_size) || + (head_len && net_write_buff(net, (char*) header, head_len)) || + net_write_buff(net, packet, len) || net_flush(net)); } /* @@ -286,7 +310,7 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len) One can force the buffer to be flushed with 'net_flush'. */ -static int +static my_bool net_write_buff(NET *net,const char *packet,ulong len) { ulong left_length=(ulong) (net->buff_end - net->write_pos); @@ -815,13 +839,3 @@ my_net_read(NET *net) #endif /* HAVE_COMPRESS */ return len; } - -bool net_request_file(NET* net, const char* fname) -{ - char tmp [FN_REFLEN+1],*end; - DBUG_ENTER("net_request_file"); - tmp[0] = (char) 251; /* NULL_LENGTH */ - end=strnmov(tmp+1,fname,sizeof(tmp)-2); - DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) || - net_flush(net)); -} diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 04f1ffce00e..3d4a7893790 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -186,7 +186,7 @@ err: my_message(ER_UNKNOWN_ERROR, "Wrong parameters to function register_slave", MYF(0)); err2: - send_error(&thd->net); + send_error(thd); return 1; } @@ -425,10 +425,10 @@ int show_new_master(THD* thd) if (translate_master(thd, lex_mi, errmsg)) { if (errmsg[0]) - net_printf(&thd->net, ER_ERROR_WHEN_EXECUTING_COMMAND, + net_printf(thd, ER_ERROR_WHEN_EXECUTING_COMMAND, "SHOW NEW MASTER", errmsg); else - send_error(&thd->net, 0); + send_error(thd, 0); DBUG_RETURN(1); } @@ -444,7 +444,7 @@ int show_new_master(THD* thd) net_store_data(packet, (longlong)lex_mi->pos); if (my_net_write(&thd->net, packet->ptr(), packet->length())) DBUG_RETURN(-1); - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } } @@ -459,7 +459,7 @@ int update_slave_list(MYSQL* mysql) int port_ind; DBUG_ENTER("update_slave_list"); - if (mc_mysql_query(mysql,"SHOW SLAVE HOSTS",0) || + if (mc_mysql_query(mysql,"SHOW SLAVE HOSTS",16) || !(res = mc_mysql_store_result(mysql))) { error = "Query error"; @@ -623,7 +623,7 @@ int show_slave_hosts(THD* thd) } } pthread_mutex_unlock(&LOCK_slave_list); - send_eof(net); + send_eof(thd); DBUG_RETURN(0); } @@ -709,7 +709,7 @@ int load_master_data(THD* thd) (error=terminate_slave_threads(active_mi,restart_thread_mask, 1 /*skip lock*/))) { - send_error(&thd->net,error); + send_error(thd,error); unlock_slave_threads(active_mi); UNLOCK_ACTIVE_MI; return 1; @@ -717,7 +717,7 @@ int load_master_data(THD* thd) if (connect_to_master(thd, &mysql, active_mi)) { - net_printf(&thd->net, error= ER_CONNECT_TO_MASTER, + net_printf(thd, error= ER_CONNECT_TO_MASTER, mc_mysql_error(&mysql)); goto err; } @@ -727,10 +727,10 @@ int load_master_data(THD* thd) MYSQL_RES *db_res, **table_res, **table_res_end, **cur_table_res; uint num_dbs; - if (mc_mysql_query(&mysql, "show databases", 0) || + if (mc_mysql_query(&mysql, "SHOW DATABASES", 14) || !(db_res = mc_mysql_store_result(&mysql))) { - net_printf(&thd->net, error = ER_QUERY_ON_MASTER, + net_printf(thd, error = ER_QUERY_ON_MASTER, mc_mysql_error(&mysql)); goto err; } @@ -744,7 +744,7 @@ int load_master_data(THD* thd) if (!(table_res = (MYSQL_RES**)thd->alloc(num_dbs * sizeof(MYSQL_RES*)))) { - net_printf(&thd->net, error = ER_OUTOFMEMORY); + net_printf(thd, error = ER_OUTOFMEMORY); goto err; } @@ -754,11 +754,11 @@ int load_master_data(THD* thd) we wait to issue FLUSH TABLES WITH READ LOCK for as long as we can to minimize the lock time. */ - if (mc_mysql_query(&mysql, "FLUSH TABLES WITH READ LOCK", 0) || - mc_mysql_query(&mysql, "SHOW MASTER STATUS",0) || + if (mc_mysql_query(&mysql, "FLUSH TABLES WITH READ LOCK", 27) || + mc_mysql_query(&mysql, "SHOW MASTER STATUS",18) || !(master_status_res = mc_mysql_store_result(&mysql))) { - net_printf(&thd->net, error = ER_QUERY_ON_MASTER, + net_printf(thd, error = ER_QUERY_ON_MASTER, mc_mysql_error(&mysql)); goto err; } @@ -798,16 +798,16 @@ int load_master_data(THD* thd) if (mysql_rm_db(thd, db, 1,1) || mysql_create_db(thd, db, 0, 1)) { - send_error(&thd->net, 0, 0); + send_error(thd, 0, 0); cleanup_mysql_results(db_res, cur_table_res - 1, table_res); goto err; } if (mc_mysql_select_db(&mysql, db) || - mc_mysql_query(&mysql, "show tables", 0) || + mc_mysql_query(&mysql, "SHOW TABLES", 11) || !(*cur_table_res = mc_mysql_store_result(&mysql))) { - net_printf(&thd->net, error = ER_QUERY_ON_MASTER, + net_printf(thd, error = ER_QUERY_ON_MASTER, mc_mysql_error(&mysql)); cleanup_mysql_results(db_res, cur_table_res - 1, table_res); goto err; @@ -848,9 +848,9 @@ int load_master_data(THD* thd) mc_mysql_free_result(master_status_res); } - if (mc_mysql_query(&mysql, "UNLOCK TABLES", 0)) + if (mc_mysql_query(&mysql, "UNLOCK TABLES", 13)) { - net_printf(&thd->net, error = ER_QUERY_ON_MASTER, + net_printf(thd, error = ER_QUERY_ON_MASTER, mc_mysql_error(&mysql)); goto err; } @@ -860,7 +860,7 @@ int load_master_data(THD* thd) 0 /* not only reset, but also reinit */, &errmsg)) { - send_error(&thd->net, 0, "Failed purging old relay logs"); + send_error(thd, 0, "Failed purging old relay logs"); unlock_slave_threads(active_mi); UNLOCK_ACTIVE_MI; return 1; @@ -888,7 +888,7 @@ err: mc_mysql_close(&mysql); // safe to call since we always do mc_mysql_init() if (!error) - send_ok(&thd->net); + send_ok(thd); return error; } diff --git a/sql/set_var.cc b/sql/set_var.cc index 3c71d1d32e3..29c9ac09131 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -24,8 +24,9 @@ - Use one of the 'sys_var... classes from set_var.h or write a specific one for the variable type. - Define it in the 'variable definition list' in this file. - - If the variable should be changeable, it should be added to the - 'list of all variables' list in this file. + - If the variable should be changeable or one should be able to access it + with @@variable_name, it should be added to the 'list of all variables' + list in this file. - If the variable should be changed from the command line, add a definition of it in the my_option structure list in mysqld.dcc - If the variable should show up in 'show variables' add it to the @@ -82,6 +83,8 @@ static void fix_net_retry_count(THD *thd, enum_var_type type); static void fix_max_join_size(THD *thd, enum_var_type type); static void fix_query_cache_size(THD *thd, enum_var_type type); static void fix_key_buffer_size(THD *thd, enum_var_type type); +static byte *get_error_count(THD *thd); +static byte *get_warning_count(THD *thd); /* Variable definition list @@ -147,6 +150,8 @@ sys_var_long_ptr sys_max_connect_errors("max_connect_errors", &max_connect_errors); sys_var_long_ptr sys_max_delayed_threads("max_delayed_threads", &max_insert_delayed_threads); +sys_var_thd_ulong sys_max_error_count("max_error_count", + &SV::max_error_count); sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size", &SV::max_heap_table_size); sys_var_thd_ulong sys_max_join_size("max_join_size", @@ -157,6 +162,8 @@ sys_var_thd_ulong sys_sql_max_join_size("sql_max_join_size", &SV::max_join_size, fix_max_join_size); #endif +sys_var_thd_ulong sys_max_prep_stmt_count("max_prepared_statements", + &SV::max_prep_stmt_count); sys_var_thd_ulong sys_max_sort_length("max_sort_length", &SV::max_sort_length); sys_var_long_ptr sys_max_user_connections("max_user_connections", @@ -220,8 +227,6 @@ sys_var_thd_ulong sys_tmp_table_size("tmp_table_size", &SV::tmp_table_size); sys_var_thd_ulong sys_net_wait_timeout("wait_timeout", &SV::net_wait_timeout); - - /* Variables that are bits in THD */ @@ -283,6 +288,15 @@ static sys_var_timestamp sys_timestamp("timestamp"); static sys_var_last_insert_id sys_last_insert_id("last_insert_id"); static sys_var_last_insert_id sys_identity("identity"); static sys_var_insert_id sys_insert_id("insert_id"); +static sys_var_readonly sys_error_count("error_count", + OPT_SESSION, + SHOW_LONG, + get_error_count); +static sys_var_readonly sys_warning_count("warning_count", + OPT_SESSION, + SHOW_LONG, + get_warning_count); + /* alias for last_insert_id() to be compatible with Sybase */ static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter"); @@ -311,6 +325,7 @@ sys_var *sys_variables[]= &sys_delayed_insert_limit, &sys_delayed_insert_timeout, &sys_delayed_queue_size, + &sys_error_count, &sys_flush, &sys_flush_time, &sys_foreign_key_checks, @@ -333,8 +348,10 @@ sys_var *sys_variables[]= &sys_max_connect_errors, &sys_max_connections, &sys_max_delayed_threads, + &sys_max_error_count, &sys_max_heap_table_size, &sys_max_join_size, + &sys_max_prep_stmt_count, &sys_max_sort_length, &sys_max_tmp_tables, &sys_max_user_connections, @@ -375,7 +392,8 @@ sys_var *sys_variables[]= &sys_timestamp, &sys_tmp_table_size, &sys_tx_isolation, - &sys_unique_checks + &sys_unique_checks, + &sys_warning_count }; @@ -465,9 +483,11 @@ struct show_var_st init_vars[]= { {sys_max_binlog_size.name, (char*) &sys_max_binlog_size, SHOW_SYS}, {sys_max_connections.name, (char*) &sys_max_connections, SHOW_SYS}, {sys_max_connect_errors.name, (char*) &sys_max_connect_errors, SHOW_SYS}, + {sys_max_error_count.name, (char*) &sys_max_error_count, SHOW_SYS}, {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS}, {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS}, {sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS}, + {sys_max_prep_stmt_count.name,(char*) &sys_max_prep_stmt_count, SHOW_SYS}, {sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS}, {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS}, {sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS}, @@ -793,7 +813,7 @@ byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type) bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names) { char buff[80], *value; - String str(buff,sizeof(buff)), *res; + String str(buff, sizeof(buff), system_charset_info), *res; if (var->value->result_type() == STRING_RESULT) { @@ -831,6 +851,10 @@ err: We have to use netprintf() instead of my_error() here as this is called on the parsing stage. + + TODO: + With prepared statements/stored procedures this has to be fixed + to create an item that gets the current value at fix_fields() stage. */ Item *sys_var::item(THD *thd, enum_var_type var_type) @@ -839,7 +863,7 @@ Item *sys_var::item(THD *thd, enum_var_type var_type) { if (var_type != OPT_DEFAULT) { - net_printf(&thd->net, + net_printf(thd, var_type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE, name); return 0; @@ -857,10 +881,10 @@ Item *sys_var::item(THD *thd, enum_var_type var_type) case SHOW_CHAR: { char *str= (char*) value_ptr(thd, var_type); - return new Item_string(str,strlen(str)); + return new Item_string(str, strlen(str), system_charset_info); } default: - net_printf(&thd->net, ER_VAR_CANT_BE_READ, name); + net_printf(thd, ER_VAR_CANT_BE_READ, name); } return 0; } @@ -918,7 +942,7 @@ bool sys_var_thd_conv_charset::check(THD *thd, set_var *var) { CONVERT *tmp; char buff[80]; - String str(buff,sizeof(buff)), *res; + String str(buff,sizeof(buff), system_charset_info), *res; if (!var->value) // Default value { @@ -1100,6 +1124,21 @@ static bool set_log_update(THD *thd, set_var *var) return 0; } +static byte *get_warning_count(THD *thd) +{ + thd->sys_var_tmp.long_value= + (thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] + + thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]); + return (byte*) &thd->sys_var_tmp.long_value; +} + +static byte *get_error_count(THD *thd) +{ + thd->sys_var_tmp.long_value= + thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR]; + return (byte*) &thd->sys_var_tmp.long_value; +} + /**************************************************************************** Main handling of variables: @@ -1161,7 +1200,8 @@ void set_var_init() { extern struct my_option my_long_options[]; // From mysqld - hash_init(&system_variable_hash,array_elements(sys_variables),0,0, + hash_init(&system_variable_hash, system_charset_info, + array_elements(sys_variables),0,0, (hash_get_key) get_sys_var_length,0, HASH_CASE_INSENSITIVE); sys_var **var, **end; for (var= sys_variables, end= sys_variables+array_elements(sys_variables) ; @@ -1212,7 +1252,7 @@ sys_var *find_sys_var(const char *str, uint length) length ? length : strlen(str)); if (!var) - net_printf(¤t_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str); + net_printf(current_thd, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str); return var; } @@ -1286,7 +1326,7 @@ bool set_var::check(THD *thd) return 0; } - if (value->fix_fields(thd,0)) + if (value->fix_fields(thd, 0, &value)) return 1; if (var->check_update_type(value->result_type())) { @@ -1315,7 +1355,7 @@ bool set_var::update(THD *thd) bool set_var_user::check(THD *thd) { - return user_var_item->fix_fields(thd,0); + return user_var_item->fix_fields(thd,0, (Item**) 0); } @@ -1324,7 +1364,7 @@ bool set_var_user::update(THD *thd) if (user_var_item->update()) { /* Give an error if it's not given already */ - send_error(&thd->net, ER_SET_CONSTANTS_ONLY); + send_error(thd, ER_SET_CONSTANTS_ONLY); return 1; } return 0; diff --git a/sql/set_var.h b/sql/set_var.h index cbe479b7902..2c40414f591 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -39,6 +39,7 @@ typedef bool (*sys_check_func)(THD *, set_var *); typedef bool (*sys_update_func)(THD *, set_var *); typedef void (*sys_after_update_func)(THD *,enum_var_type); typedef void (*sys_set_default_func)(THD *, enum_var_type); +typedef byte *(*sys_value_ptr_func)(THD *thd); class sys_var { @@ -350,6 +351,31 @@ public: }; +/* Variable that you can only read from */ + +class sys_var_readonly: public sys_var +{ +public: + enum_var_type var_type; + SHOW_TYPE show_type; + sys_value_ptr_func value_ptr_func; + sys_var_readonly(const char *name_arg, enum_var_type type, + SHOW_TYPE show_type_arg, + sys_value_ptr_func value_ptr_func_arg) + :sys_var(name_arg), var_type(type), + show_type(show_type_arg), value_ptr_func(value_ptr_func_arg) + {} + bool update(THD *thd, set_var *var) { return 1; } + bool check_default(enum_var_type type) { return 1; } + bool check_type(enum_var_type type) { return type != var_type; } + bool check_update_type(Item_result type) { return 1; } + byte *value_ptr(THD *thd, enum_var_type type) + { + return (*value_ptr_func)(thd); + } + SHOW_TYPE type() { return show_type; } +}; + /**************************************************************************** Classes for parsing of the SET command ****************************************************************************/ @@ -388,7 +414,8 @@ public: if (value_arg && value_arg->type() == Item::FIELD_ITEM) { Item_field *item= (Item_field*) value_arg; - if (!(value=new Item_string(item->field_name, strlen(item->field_name)))) + if (!(value=new Item_string(item->field_name, strlen(item->field_name), + system_charset_info))) value=value_arg; /* Give error message later */ } else diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index e9f3b997a96..17651303714 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -206,7 +206,7 @@ "Nezn-Bámá systémová promìnná '%-.64s'", "Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a mìla by být opravena", "Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a poslední (automatická?) oprava se nezdaøila", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 88ab604fbcf..ccb452f0cca 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -197,7 +197,7 @@ "Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", @@ -242,3 +242,4 @@ "Key reference and table reference doesn't match", "Subselect return more than 1 field", "Subselect return more than 1 record", +"Unknown prepared statement handler (%ld) given to %s", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index a344ed2df9e..f9117bdd44e 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -197,7 +197,7 @@ "Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 9e88f2c3e2c..9bf7121d309 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -199,7 +199,7 @@ "Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 07bdcd6bee5..215a30c5062 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -199,7 +199,7 @@ "Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 57f990fdc04..0560442ddb8 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -197,7 +197,7 @@ "Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 37f7f2fac01..bc9f9829945 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -199,7 +199,7 @@ "Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 93f4090d697..2af2e7809b0 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -199,7 +199,7 @@ "Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 3b43ce539c7..93578e6119d 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -201,7 +201,7 @@ "Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index ce237d755d4..cde6ab9a4f4 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -201,7 +201,7 @@ "Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 9912e4c9191..4c5cf834262 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -205,7 +205,7 @@ "Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", +"Some non-transactional changed tables couldn't be rolled back", "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index f6553f247b6..587c9cab406 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -197,7 +197,7 @@ "Okänd system variabel '%-.64s'", "Tabell '%-.64s' är crashad och bör repareras med REPAIR TABLE", "Tabell '%-.64s' är crashad och senast (automatiska?) reparation misslyckades", -"Warning: Några icke transaktionella tabeller kunde inte återställas vid ROLLBACK", +"Några icke transaktionella tabeller kunde inte återställas vid ROLLBACK", "Transaktionen krävde mera än 'max_binlog_cache_size' minne. Utöka denna mysqld variabel och försök på nytt", "Denna operation kan inte göras under replikering; Gör SLAVE STOP först", "Denna operation kan endast göras under replikering; Konfigurera slaven och gör SLAVE START", diff --git a/sql/slave.cc b/sql/slave.cc index 01f6233a2e0..71dbb1fc1a2 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -56,7 +56,6 @@ static int events_till_disconnect = -1; typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE; -void skip_load_data_infile(NET* net); static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev); static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev); static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli); @@ -723,13 +722,22 @@ void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...) rli->last_slave_errno = err_code; } +/* + This is used to tell a 3.23 master to break send_file() +*/ + +void skip_load_data_infile(NET *net) +{ + (void)net_request_file(net, "/dev/null"); + (void)my_net_read(net); // discard response + (void)net_write_command(net, 0, "", 0, "", 0); // Send ok +} + -void skip_load_data_infile(NET* net) +bool net_request_file(NET* net, const char* fname) { - (void)my_net_write(net, "\xfb/dev/null", 10); - (void)net_flush(net); - (void)my_net_read(net); // discard response - send_ok(net); // the master expects it + DBUG_ENTER("net_request_file"); + DBUG_RETURN(net_write_command(net, 251, fname, strlen(fname), "", 0)); } @@ -875,13 +883,13 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, if (packet_len == packet_error) { - send_error(&thd->net, ER_MASTER_NET_READ); + send_error(thd, ER_MASTER_NET_READ); return 1; } if (net->read_pos[0] == 255) // error from master { net->read_pos[packet_len] = 0; - net_printf(&thd->net, ER_MASTER, net->read_pos + 3); + net_printf(thd, ER_MASTER, net->read_pos + 3); return 1; } thd->command = COM_TABLE_DUMP; @@ -889,7 +897,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, if (!thd->query) { sql_print_error("create_table_from_dump: out of memory"); - net_printf(&thd->net, ER_GET_ERRNO, "Out of memory"); + net_printf(thd, ER_GET_ERRNO, "Out of memory"); return 1; } memcpy(thd->query, net->read_pos, packet_len); @@ -919,7 +927,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, thd->proc_info = "Opening master dump table"; if (!open_ltable(thd, &tables, TL_WRITE)) { - send_error(&thd->net,0,0); // Send error from open_ltable + send_error(thd,0,0); // Send error from open_ltable sql_print_error("create_table_from_dump: could not open created table"); goto err; } @@ -928,7 +936,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, thd->proc_info = "Reading master dump table data"; if (file->net_read_dump(net)) { - net_printf(&thd->net, ER_MASTER_NET_READ); + net_printf(thd, ER_MASTER_NET_READ); sql_print_error("create_table_from_dump::failed in\ handler::net_read_dump()"); goto err; @@ -947,7 +955,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, error=file->repair(thd,&check_opt) != 0; thd->net.vio = save_vio; if (error) - net_printf(&thd->net, ER_INDEX_REBUILD,tables.table->real_name); + net_printf(thd, ER_INDEX_REBUILD,tables.table->real_name); err: close_thread_tables(thd); @@ -969,12 +977,12 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name, { if (!(mysql = mc_mysql_init(NULL))) { - send_error(&thd->net); // EOM + send_error(thd); // EOM DBUG_RETURN(1); } if (connect_to_master(thd, mysql, mi)) { - net_printf(&thd->net, ER_CONNECT_TO_MASTER, mc_mysql_error(mysql)); + net_printf(thd, ER_CONNECT_TO_MASTER, mc_mysql_error(mysql)); mc_mysql_close(mysql); DBUG_RETURN(1); } @@ -998,7 +1006,7 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name, if (!called_connected) mc_mysql_close(mysql); if (errmsg && thd->net.vio) - send_error(&thd->net, error, errmsg); + send_error(thd, error, errmsg); DBUG_RETURN(test(error)); // Return 1 on error } @@ -1440,7 +1448,7 @@ int show_master_info(THD* thd, MASTER_INFO* mi) if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length())) DBUG_RETURN(-1); } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } @@ -2222,8 +2230,8 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev) int error = 1; ulong num_bytes; bool cev_not_written; - THD* thd; - NET* net = &mi->mysql->net; + THD *thd = mi->io_thd; + NET *net = &mi->mysql->net; DBUG_ENTER("process_io_create_file"); if (unlikely(!cev->is_valid())) @@ -2237,7 +2245,6 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev) DBUG_RETURN(0); } DBUG_ASSERT(cev->inited_from_old); - thd = mi->io_thd; thd->file_id = cev->file_id = mi->file_id++; thd->server_id = cev->server_id; cev_not_written = 1; @@ -2266,7 +2273,7 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev) } if (unlikely(!num_bytes)) /* eof */ { - send_ok(net); /* 3.23 master wants it */ + net_write_command(net, 0, "", 0, "", 0);/* 3.23 master wants it */ Execute_load_log_event xev(thd); xev.log_pos = mi->master_log_pos; if (unlikely(mi->rli.relay_log.append(&xev))) diff --git a/sql/spatial.h b/sql/spatial.h index c6e30a44fbf..3f09e86e823 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -1,8 +1,22 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef _spatial_h #define _spatial_h -#include "gstream.h" - const uint POINT_DATA_SIZE = 8+8; const uint WKB_HEADER_SIZE = 1+4; @@ -30,7 +44,8 @@ struct MBR ymax=-DBL_MAX; } - MBR(const double &_xmin, const double &_ymin, const double &_xmax, const double &_ymax) + MBR(const double &_xmin, const double &_ymin, + const double &_xmax, const double &_ymax) { xmin=_xmin; ymin=_ymin; @@ -52,7 +67,8 @@ struct MBR double ymax; void add_xy(double x, double y) - { /* Not using "else" for proper one point MBR calculation */ + { + /* Not using "else" for proper one point MBR calculation */ if (xxmin==xmin)&&(mbr->ymin==ymin)&&(mbr->xmax==xmax)&&(mbr->ymax==ymax); + return ((mbr->xmin == xmin) && (mbr->ymin == ymin) && + (mbr->xmax == xmax) && (mbr->ymax == ymax)); } int disjoint(const MBR *mbr) { - return (mbr->xmin>xmax)||(mbr->ymin>ymax)||(mbr->xmaxymaxxmin > xmax) || (mbr->ymin > ymax) || + (mbr->xmax < xmin) || (mbr->ymax < ymin)); } int intersects(const MBR *mbr) @@ -131,24 +150,24 @@ struct MBR int touches(const MBR *mbr) { - return (((mbr->xmin==xmax) || (mbr->xmax==xmin)) && - ((mbr->ymin>=ymin) && (mbr->ymin<=ymax) || - (mbr->ymax>=ymin) && (mbr->ymax<=ymax))) || - (((mbr->ymin==ymax) || (mbr->ymax==ymin)) && - ((mbr->xmin>=xmin) && (mbr->xmin<=xmax) || - (mbr->xmax>=xmin)&&(mbr->xmax<=xmax))); + return ((((mbr->xmin == xmax) || (mbr->xmax == xmin)) && + ((mbr->ymin >= ymin) && (mbr->ymin <= ymax) || + (mbr->ymax >= ymin) && (mbr->ymax <= ymax))) || + (((mbr->ymin == ymax) || (mbr->ymax == ymin)) && + ((mbr->xmin >= xmin) && (mbr->xmin <= xmax) || + (mbr->xmax >= xmin) && (mbr->xmax <= xmax)))); } int within(const MBR *mbr) { - return (mbr->xmin<=xmin) && (mbr->ymin<=ymin) && - (mbr->xmax>=xmax) && (mbr->ymax>=ymax); + return ((mbr->xmin <= xmin) && (mbr->ymin <= ymin) && + (mbr->xmax >= xmax) && (mbr->ymax >= ymax)); } int contains(const MBR *mbr) { - return (mbr->xmin>=xmin) && (mbr->ymin>=ymin) && - (mbr->xmax<=xmax) && (mbr->ymax<=ymax); + return ((mbr->xmin >= xmin) && (mbr->ymin >= ymin) && + (mbr->xmax <= xmax) && (mbr->ymax <= ymax)); } bool inner_point(double x, double y) const @@ -245,45 +264,46 @@ public: 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); } + { return (this->*m_vmt->init_from_text)(trs, wkb); } int get_data_as_text(String *txt) const - { return (this->*m_vmt->get_data_as_text)(txt); } + { return (this->*m_vmt->get_data_as_text)(txt); } int get_mbr(MBR *mbr) const { return (this->*m_vmt->get_mbr)(mbr); } int dimension(uint32 *dim) const - { return (this->*m_vmt->dimension)(dim); } + { return (this->*m_vmt->dimension)(dim); } int get_x(double *x) const { return (this->*m_vmt->get_x)(x); } int get_y(double *y) const { return (this->*m_vmt->get_y)(y); } int length(double *len) const { return (this->*m_vmt->length)(len); } int area(double *ar) const { return (this->*m_vmt->area)(ar); } - int is_closed(int *closed) const { return (this->*m_vmt->is_closed)(closed); } + int is_closed(int *closed) const + { return (this->*m_vmt->is_closed)(closed); } int num_interior_ring(uint32 *n_int_rings) const - { return (this->*m_vmt->num_interior_ring)(n_int_rings); } + { return (this->*m_vmt->num_interior_ring)(n_int_rings); } int num_points(uint32 *n_points) const - { return (this->*m_vmt->num_points)(n_points); } + { return (this->*m_vmt->num_points)(n_points); } int num_geometries(uint32 *num) const - { return (this->*m_vmt->num_geometries)(num); } + { return (this->*m_vmt->num_geometries)(num); } int start_point(String *point) const - { return (this->*m_vmt->start_point)(point); } + { return (this->*m_vmt->start_point)(point); } int end_point(String *point) const - { return (this->*m_vmt->end_point)(point); } + { return (this->*m_vmt->end_point)(point); } int exterior_ring(String *ring) const - { return (this->*m_vmt->exterior_ring)(ring); } + { return (this->*m_vmt->exterior_ring)(ring); } int centroid(String *point) const - { return (this->*m_vmt->centroid)(point); } + { return (this->*m_vmt->centroid)(point); } int point_n(uint32 num, String *result) const - { return (this->*m_vmt->point_n)(num, result); } + { return (this->*m_vmt->point_n)(num, result); } int interior_ring_n(uint32 num, String *result) const - { return (this->*m_vmt->interior_ring_n)(num, result); } + { return (this->*m_vmt->interior_ring_n)(num, result); } int geometry_n(uint32 num, String *result) const - { return (this->*m_vmt->geometry_n)(num, result); } + { return (this->*m_vmt->geometry_n)(num, result); } public: int create_from_wkb(const char *data, uint32 data_len); @@ -301,11 +321,11 @@ public: int as_wkt(String *wkt) const { - if(wkt->reserve(strlen(get_class_info()->m_name) + 2, 512)) + if (wkt->reserve(strlen(get_class_info()->m_name) + 2, 512)) return 1; wkt->qs_append(get_class_info()->m_name); wkt->qs_append('('); - if(get_data_as_text(wkt)) + if (get_data_as_text(wkt)) return 1; wkt->qs_append(')'); return 0; @@ -330,35 +350,37 @@ protected: bool no_data(const char *cur_data, uint32 data_amount) const { - return cur_data + data_amount > m_data_end; + return (cur_data + data_amount > m_data_end); } const char *m_data; const char *m_data_end; }; +#define SIZEOF_STORED_DOUBLE 8 + /***************************** Point *******************************/ 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 get_mbr(MBR *mbr) const; + size_t get_data_size() const; + int init_from_text(GTextReadStream *trs, String *wkb); + int get_data_as_text(String *txt) const; + int get_mbr(MBR *mbr) const; int get_xy(double *x, double *y) const { const char *data = m_data; - if(no_data(data, sizeof(double)) * 2) return 1; + if (no_data(data, SIZEOF_STORED_DOUBLE * 2)) return 1; float8get(*x, data); - float8get(*y, data + sizeof(double)); + float8get(*y, data + SIZEOF_STORED_DOUBLE); return 0; } int get_x(double *x) const { - if(no_data(m_data, sizeof(double))) return 1; + if (no_data(m_data, SIZEOF_STORED_DOUBLE)) return 1; float8get(*x, m_data); return 0; } @@ -366,8 +388,8 @@ public: int get_y(double *y) const { const char *data = m_data; - if(no_data(data, sizeof(double)) * 2) return 1; - float8get(*y, data + sizeof(double)); + if (no_data(data, SIZEOF_STORED_DOUBLE * 2)) return 1; + float8get(*y, data + SIZEOF_STORED_DOUBLE); return 0; } @@ -399,11 +421,11 @@ public: 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 get_mbr(MBR *mbr) const; - + size_t get_data_size() const; + int init_from_text(GTextReadStream *trs, String *wkb); + int get_data_as_text(String *txt) const; + int get_mbr(MBR *mbr) const; + int area(double *ar) const; int exterior_ring(String *result) const; int num_interior_ring(uint32 *n_int_rings) const; @@ -431,11 +453,11 @@ public: 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 get_mbr(MBR *mbr) const; - + size_t get_data_size() const; + int init_from_text(GTextReadStream *trs, String *wkb); + int get_data_as_text(String *txt) const; + int get_mbr(MBR *mbr) const; + int length(double *len) const; int is_closed(int *closed) const; int dimension(uint32 *dim) const { *dim = 1; return 0; } @@ -446,10 +468,10 @@ public: 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 get_mbr(MBR *mbr) const; + size_t get_data_size() const; + int init_from_text(GTextReadStream *trs, String *wkb); + int get_data_as_text(String *txt) const; + int get_mbr(MBR *mbr) const; int area(double *ar) const; int centroid(String *result) const; @@ -462,14 +484,13 @@ public: 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 get_mbr(MBR *mbr) const; + size_t get_data_size() const; + int init_from_text(GTextReadStream *trs, String *wkb); + int get_data_as_text(String *txt) const; + int get_mbr(MBR *mbr) const; int num_geometries(uint32 *num) const; int geometry_n(uint32 num, String *result) const; - int dimension(uint32 *dim) const; }; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 1069e779e86..e6b9a1f532b 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -997,7 +997,7 @@ bool check_change_password(THD *thd, const char *host, const char *user) { if (!initialized) { - send_error(&thd->net, ER_PASSWORD_NOT_ALLOWED); /* purecov: inspected */ + send_error(thd, ER_PASSWORD_NOT_ALLOWED); /* purecov: inspected */ return(1); /* purecov: inspected */ } if (!thd->slave_thread && @@ -1009,7 +1009,7 @@ bool check_change_password(THD *thd, const char *host, const char *user) } if (!thd->slave_thread && !thd->user[0]) { - send_error(&thd->net, ER_PASSWORD_ANONYMOUS_USER); + send_error(thd, ER_PASSWORD_ANONYMOUS_USER); return(1); } return(0); @@ -1036,7 +1036,7 @@ bool change_password(THD *thd, const char *host, const char *user, ACL_USER *acl_user; if (!(acl_user= find_acl_user(host,user))) { - send_error(&thd->net, ER_PASSWORD_NO_MATCH); + send_error(thd, ER_PASSWORD_NO_MATCH); VOID(pthread_mutex_unlock(&acl_cache->lock)); DBUG_RETURN(1); } @@ -1046,7 +1046,7 @@ bool change_password(THD *thd, const char *host, const char *user, new_password)) { VOID(pthread_mutex_unlock(&acl_cache->lock)); /* purecov: deadcode */ - send_error(&thd->net,0); /* purecov: deadcode */ + send_error(thd,0); /* purecov: deadcode */ DBUG_RETURN(1); /* purecov: deadcode */ } get_salt_from_password(acl_user->salt,new_password); @@ -1960,7 +1960,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, if (!initialized) { - send_error(&(thd->net), ER_UNKNOWN_COM_ERROR); /* purecov: inspected */ + send_error(thd, ER_UNKNOWN_COM_ERROR); /* purecov: inspected */ return 1; /* purecov: inspected */ } if (rights & ~TABLE_ACLS) @@ -2026,7 +2026,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, if (!revoke_grant) create_new_users= test_if_create_new_users(thd); int result=0; - pthread_mutex_lock(&LOCK_grant); + rw_wrlock(&LOCK_grant); MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); my_pthread_setspecific_ptr(THR_MALLOC,&memex); @@ -2135,9 +2135,9 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, } grant_option=TRUE; my_pthread_setspecific_ptr(THR_MALLOC,old_root); - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); if (!result) - send_ok(&thd->net); + send_ok(thd); /* Tables are automatically closed */ DBUG_RETURN(result); } @@ -2155,8 +2155,8 @@ int mysql_grant (THD *thd, const char *db, List &list, if (!initialized) { - send_error(&(thd->net), ER_UNKNOWN_COM_ERROR); /* purecov: tested */ - return 1; /* purecov: tested */ + send_error(thd, ER_UNKNOWN_COM_ERROR); /* purecov: tested */ + return 1; /* purecov: tested */ } if (lower_case_table_names && db) @@ -2185,7 +2185,7 @@ int mysql_grant (THD *thd, const char *db, List &list, create_new_users= test_if_create_new_users(thd); // go through users in user_list - pthread_mutex_lock(&LOCK_grant); + rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); grant_version++; @@ -2218,11 +2218,11 @@ int mysql_grant (THD *thd, const char *db, List &list, } } VOID(pthread_mutex_unlock(&acl_cache->lock)); - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); close_thread_tables(thd); if (!result) - send_ok(&thd->net); + send_ok(thd); DBUG_RETURN(result); } @@ -2341,7 +2341,7 @@ void grant_reload(void) // Locked tables are checked by acl_init and doesn't have to be checked here - pthread_mutex_lock(&LOCK_grant); + rw_wrlock(&LOCK_grant); grant_version++; old_hash_tables=hash_tables; old_grant_option = grant_option; @@ -2359,7 +2359,7 @@ void grant_reload(void) hash_free(&old_hash_tables); free_root(&old_mem,MYF(0)); } - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); DBUG_VOID_RETURN; } @@ -2379,7 +2379,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, if (!want_access) return 0; // ok - pthread_mutex_lock(&LOCK_grant); + rw_rdlock(&LOCK_grant); for (table=tables; table ;table=table->next) { if (!(~table->grant.privilege & want_access)) @@ -2413,11 +2413,11 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, goto err; // impossible } } - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); return 0; err: - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); if (!no_errors) // Not a silent skip of table { const char *command=""; @@ -2439,7 +2439,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, command = "index"; else if (want_access & GRANT_ACL) command = "grant"; - net_printf(&thd->net,ER_TABLEACCESS_DENIED_ERROR, + net_printf(thd,ER_TABLEACCESS_DENIED_ERROR, command, thd->priv_user, thd->host_or_ip, @@ -2459,7 +2459,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name, if (!want_access) return 0; // Already checked - pthread_mutex_lock(&LOCK_grant); + rw_rdlock(&LOCK_grant); // reload table if someone has modified any grants @@ -2477,20 +2477,20 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name, grant_column=column_hash_search(grant_table, name, length); if (grant_column && !(~grant_column->rights & want_access)) { - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); return 0; } #ifdef NOT_USED if (show_tables && (grant_column || table->grant.privilege & COL_ACLS)) { - pthread_mutex_unlock(&LOCK_grant); /* purecov: deadcode */ + rw_unlock(&LOCK_grant); /* purecov: deadcode */ return 0; /* purecov: deadcode */ } #endif /* We must use my_printf_error() here! */ err: - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); if (!show_tables) { char command[128]; @@ -2518,7 +2518,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table) if (!want_access) return 0; // Already checked - pthread_mutex_lock(&LOCK_grant); + rw_rdlock(&LOCK_grant); // reload table if someone has modified any grants @@ -2541,12 +2541,12 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table) if (!grant_column || (~grant_column->rights & want_access)) goto err; } - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); return 0; /* We must use my_printf_error() here! */ err: - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); const char *command=""; if (want_access & SELECT_ACL) @@ -2578,7 +2578,7 @@ bool check_grant_db(THD *thd,const char *db) bool error=1; len = (uint) (strmov(strmov(helping,thd->priv_user)+1,db)-helping)+ 1; - pthread_mutex_lock(&LOCK_grant); + rw_rdlock(&LOCK_grant); for (uint idx=0 ; idx < hash_tables.records ; idx++) { @@ -2594,7 +2594,7 @@ bool check_grant_db(THD *thd,const char *db) break; } } - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); return error; } @@ -2608,14 +2608,14 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table) const char *db = table->db ? table->db : thd->db; GRANT_TABLE *grant_table; - pthread_mutex_lock(&LOCK_grant); + rw_rdlock(&LOCK_grant); grant_table = table_hash_search(thd->host,thd->ip,db,user, table->real_name,0); table->grant.grant_table=grant_table; // Remember for column test table->grant.version=grant_version; if (grant_table) table->grant.privilege|= grant_table->privs; - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); return table->grant.privilege; } @@ -2626,7 +2626,7 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field) GRANT_COLUMN *grant_column; ulong priv; - pthread_mutex_lock(&LOCK_grant); + rw_rdlock(&LOCK_grant); // reload table if someone has modified any grants if (table->grant.version != grant_version) { @@ -2648,7 +2648,7 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field) else priv=table->grant.privilege | grant_column->rights; } - pthread_mutex_unlock(&LOCK_grant); + rw_unlock(&LOCK_grant); return priv; } @@ -2683,7 +2683,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) LINT_INIT(acl_user); if (!initialized) { - send_error(&(thd->net), ER_UNKNOWN_COM_ERROR); + send_error(thd, ER_UNKNOWN_COM_ERROR); DBUG_RETURN(-1); } if (!lex_user->host.str) @@ -2990,7 +2990,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } end: VOID(pthread_mutex_unlock(&acl_cache->lock)); - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(error); } diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 91d6b967929..363a194276b 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -89,21 +89,21 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, if ((*param->item)->type() != Item::INT_ITEM || (*param->item)->val() < 0) { - net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name); + net_printf(thd, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name); DBUG_RETURN(0); } pc->max_tree_elements = (uint) (*param->item)->val_int(); param = param->next; if (param->next) // no third parameter possible { - net_printf(&thd->net, ER_WRONG_PARAMCOUNT_TO_PROCEDURE, proc_name); + net_printf(thd, ER_WRONG_PARAMCOUNT_TO_PROCEDURE, proc_name); DBUG_RETURN(0); } // second parameter if ((*param->item)->type() != Item::INT_ITEM || (*param->item)->val() < 0) { - net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name); + net_printf(thd, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name); DBUG_RETURN(0); } pc->max_treemem = (uint) (*param->item)->val_int(); @@ -111,7 +111,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, else if ((*param->item)->type() != Item::INT_ITEM || (*param->item)->val() < 0) { - net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name); + net_printf(thd, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name); DBUG_RETURN(0); } // if only one parameter was given, it will be the value of max_tree_elements @@ -387,8 +387,7 @@ void field_real::add() if ((decs = decimals()) == NOT_FIXED_DEC) { - sprintf(buff, "%g", num); - length = (uint) strlen(buff); + length= my_sprintf(buff, (buff, "%g", num)); if (rint(num) != num) max_notzero_dec_len = 1; } @@ -397,11 +396,11 @@ void field_real::add() #ifdef HAVE_SNPRINTF buff[sizeof(buff)-1]=0; // Safety snprintf(buff, sizeof(buff)-1, "%-.*f", (int) decs, num); + length = (uint) strlen(buff); #else - sprintf(buff, "%-.*f", (int) decs, num); + length= my_sprintf(buff, (buff, "%-.*f", (int) decs, num)); #endif - length = (uint) strlen(buff); // We never need to check further than this end = buff + length - 1 - decs + max_notzero_dec_len; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index a8115c15412..3175193e8ce 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -224,7 +224,7 @@ send_convert_fields(THD *thd,List &list,CONVERT *convert,uint flag) char buff[80]; String tmp((char*) buff,sizeof(buff),default_charset_info); String *res,*packet= &thd->packet; - DBUG_ENTER("send_fields"); + DBUG_ENTER("send_convert_fields"); while ((item=it++)) { @@ -286,10 +286,10 @@ send_convert_fields(THD *thd,List &list,CONVERT *convert,uint flag) if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length())) break; /* purecov: inspected */ } - return 0; + DBUG_RETURN(0); err: - return 1; + DBUG_RETURN(1); } @@ -406,7 +406,8 @@ send_non_convert_fields(THD *thd,List &list,uint flag) bool send_fields(THD *thd, List &list, uint flag) { - CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set; + char buff[9]; // Big enough for store_length + CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->variables.convert_set; DBUG_ENTER("send_fields"); if (thd->fatal_error) // We have got an error @@ -414,7 +415,7 @@ send_fields(THD *thd, List &list, uint flag) if (flag & 1) { // Packet with number of elements - char *pos=net_store_length(buff,(uint) list.elements); + char *pos=net_store_length(buff, (uint) list.elements); (void) my_net_write(&thd->net, buff,(uint) (pos-buff)); } @@ -430,11 +431,11 @@ send_fields(THD *thd, List &list, uint flag) else if (send_non_convert_fields(thd, list, flag)) goto err; - send_eof(&thd->net); - return 0; + send_eof(thd); + DBUG_RETURN(0); err: - send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */ + send_error(thd,ER_OUT_OF_RESOURCES); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 41def4aa1b5..277492bcea6 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -77,14 +77,15 @@ static void free_var(user_var_entry *entry) ** Thread specific functions ****************************************************************************/ -THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), +THD::THD():user_time(0), fatal_error(0), + last_insert_id_used(0), insert_id_used(0), in_lock_tables(0), global_read_lock(0), bootstrap(0) { host=user=priv_user=db=query=ip=0; host_or_ip="unknown ip"; locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password= - query_start_used=safe_to_cache_query=0; + query_start_used=safe_to_cache_query=prepare_command=0; pthread_mutex_lock(&LOCK_global_system_variables); variables= global_system_variables; pthread_mutex_unlock(&LOCK_global_system_variables); @@ -96,7 +97,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), tmp_table=0; lock=locked_tables=0; used_tables=0; - cuted_fields=sent_row_count=0L; + cuted_fields= sent_row_count= current_stmt_id= 0L; start_time=(time_t) 0; current_linfo = 0; slave_thread = 0; @@ -142,10 +143,21 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), bzero((char*) &mem_root,sizeof(mem_root)); bzero((char*) &transaction.mem_root,sizeof(transaction.mem_root)); bzero((char*) &con_root,sizeof(con_root)); + bzero((char*) &warn_root,sizeof(warn_root)); + init_alloc_root(&warn_root, 1024, 0); + bzero((char*) warn_count, sizeof(warn_count)); + warn_list.empty(); user_connect=(USER_CONN *)0; hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, (void (*)(void*)) free_var,0); + + /* Prepared statements */ + last_prepared_stmt= 0; + init_tree(&prepared_statements, 0, 0, sizeof(PREP_STMT), + (qsort_cmp2) compare_prep_stmt, 1, + (tree_element_free) free_prep_stmt, 0); + #ifdef USING_TRANSACTIONS bzero((char*) &transaction,sizeof(transaction)); if (opt_using_transactions) @@ -222,7 +234,9 @@ THD::~THD() safeFree(ip); free_root(&mem_root,MYF(0)); free_root(&con_root,MYF(0)); + free_root(&warn_root,MYF(0)); free_root(&transaction.mem_root,MYF(0)); + delete_tree(&prepared_statements); mysys_var=0; // Safety (shouldn't be needed) pthread_mutex_destroy(&LOCK_delete); #ifndef DBUG_OFF @@ -272,8 +286,7 @@ void THD::awake(bool prepare_to_die) bool THD::store_globals() { return (my_pthread_setspecific_ptr(THR_THD, this) || - my_pthread_setspecific_ptr(THR_MALLOC, &mem_root) || - my_pthread_setspecific_ptr(THR_NET, &net)); + my_pthread_setspecific_ptr(THR_MALLOC, &mem_root)); } @@ -424,7 +437,7 @@ bool select_send::send_eof() { mysql_unlock_tables(thd, thd->lock); thd->lock=0; } - ::send_eof(&thd->net); + ::send_eof(thd); return 0; } @@ -649,7 +662,7 @@ err: void select_export::send_error(uint errcode,const char *err) { - ::send_error(&thd->net,errcode,err); + ::send_error(thd,errcode,err); (void) end_io_cache(&cache); (void) my_close(file,MYF(0)); file= -1; @@ -662,9 +675,9 @@ bool select_export::send_eof() if (my_close(file,MYF(MY_WME))) error=1; if (error) - ::send_error(&thd->net); + ::send_error(thd); else - ::send_ok(&thd->net,row_count); + ::send_ok(thd,row_count); file= -1; return error; } @@ -761,7 +774,7 @@ err: void select_dump::send_error(uint errcode,const char *err) { - ::send_error(&thd->net,errcode,err); + ::send_error(thd,errcode,err); (void) end_io_cache(&cache); (void) my_close(file,MYF(0)); (void) my_delete(path,MYF(0)); // Delete file on error @@ -774,9 +787,9 @@ bool select_dump::send_eof() if (my_close(file,MYF(MY_WME))) error=1; if (error) - ::send_error(&thd->net); + ::send_error(thd); else - ::send_ok(&thd->net,row_count); + ::send_ok(thd,row_count); file= -1; return error; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 8b2e9400613..f1eb4febf0f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -292,31 +292,43 @@ public: i_string_pair():key(0),val(0) { } i_string_pair(char* key_arg, char* val_arg) : key(key_arg),val(val_arg) {} }; -#define MYSQL_DEFAULT_ERROR_COUNT 500 -class mysql_st_error + +class MYSQL_ERROR: public Sql_alloc { public: + enum enum_warning_level + { WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END}; + uint code; - char msg[MYSQL_ERRMSG_SIZE+1]; - char query[NAME_LEN+1]; + enum_warning_level level; + char *msg; - static void *operator new(size_t size) - { - return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE)); - } - static void operator delete(void* ptr_arg, size_t size) - { - my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); - } - mysql_st_error(uint ecode, const char *emsg, const char *equery) + MYSQL_ERROR(uint code_arg, enum_warning_level level_arg, + const char *msg_arg) + :code(code_arg), level(level_arg) { - code = ecode; - strmov(msg, emsg); - strnmov(query, equery ? equery : "", NAME_LEN); + msg=sql_strdup(msg_arg); } }; + +/* This is a struct as it's allocated in tree_insert */ + +typedef struct st_prep_stmt +{ + THD *thd; + Item_param *param; + Item *free_list; + MEM_ROOT mem_root; + ulong stmt_id; + uint param_count; + uint last_errno; + char last_error[MYSQL_ERRMSG_SIZE]; + bool error_in_prepare, long_data_used; +} PREP_STMT; + + class delayed_insert; #define THD_SENTRY_MAGIC 0xfeedd1ff @@ -332,27 +344,27 @@ struct system_variables ulong join_buff_size; ulong long_query_time; ulong max_allowed_packet; + ulong max_error_count; ulong max_heap_table_size; - ulong max_sort_length; ulong max_join_size; + ulong max_prep_stmt_count; + ulong max_sort_length; ulong max_tmp_tables; - ulong max_error_count; - ulong max_warning_count; ulong myisam_sort_buff_size; ulong net_buffer_length; ulong net_interactive_timeout; ulong net_read_timeout; + ulong net_retry_count; ulong net_wait_timeout; ulong net_write_timeout; - ulong net_retry_count; ulong query_cache_type; ulong read_buff_size; ulong read_rnd_buff_size; ulong select_limit; ulong sortbuff_size; + ulong table_type; ulong tmp_table_size; ulong tx_isolation; - ulong table_type; my_bool log_warnings; my_bool low_priority_updates; @@ -372,7 +384,9 @@ public: LEX lex; // parse tree descriptor MEM_ROOT mem_root; // 1 command-life memory pool MEM_ROOT con_root; // connection-life memory + MEM_ROOT warn_root; // For warnings and errors HASH user_vars; // hash for user variables + TREE prepared_statements; String packet; // dynamic buffer for network I/O struct sockaddr_in remote; // client socket address struct rand_struct rand; // used for authentication @@ -408,7 +422,6 @@ public: ulong master_access; /* Global privileges from mysql.user */ ulong db_access; /* Privileges for current db */ - /* open_tables - list of regular tables in use by this thread temporary_tables - list of temp tables in use by this thread @@ -417,9 +430,10 @@ public: */ TABLE *open_tables,*temporary_tables, *handler_tables; // TODO: document the variables below - MYSQL_LOCK *lock; /* Current locks */ - MYSQL_LOCK *locked_tables; /* Tables locked with LOCK */ - ULL *ull; + MYSQL_LOCK *lock; /* Current locks */ + MYSQL_LOCK *locked_tables; /* Tables locked with LOCK */ + ULL *ull; + PREP_STMT *last_prepared_stmt; #ifndef DBUG_OFF uint dbug_sentry; // watch out for memory corruption #endif @@ -466,8 +480,11 @@ public: table_map used_tables; USER_CONN *user_connect; CHARSET_INFO *db_charset; + List warn_list; + uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END]; + uint total_warn_count, old_total_warn_count; ulong query_id, version, options, thread_id, col_access; - ulong param_count,current_param_number; + ulong current_stmt_id; long dbug_thread_id; pthread_t real_id; uint current_tablenr,tmp_table,cond_count; @@ -480,16 +497,15 @@ public: uint8 query_cache_type; // type of query cache processing bool slave_thread; bool set_query_id,locked,count_cuted_fields,some_tables_deleted; - bool no_errors, allow_sum_func, password, fatal_error; + bool no_errors, allow_sum_func, password; + bool fatal_error; bool query_start_used,last_insert_id_used,insert_id_used; bool system_thread,in_lock_tables,global_read_lock; bool query_error, bootstrap, cleanup_done; bool safe_to_cache_query; bool volatile killed; bool prepare_command; - Error err_list; - Error warn_list; - Item_param *current_param; + Item_param *params; // Pointer to array of params /* If we do a purge of binary logs, log index info of the threads @@ -638,7 +654,7 @@ public: class JOIN; -void send_error(NET *net,uint sql_errno=0, const char *err=0); +void send_error(THD *thd, uint sql_errno=0, const char *err=0); class select_result :public Sql_alloc { protected: @@ -657,7 +673,7 @@ public: virtual void initialize_tables (JOIN *join=0) {} virtual void send_error(uint errcode,const char *err) { - ::send_error(&thd->net,errcode,err); + ::send_error(thd,errcode,err); } virtual bool send_eof()=0; virtual void abort() {} diff --git a/sql/sql_db.cc b/sql/sql_db.cc index dee26aae4be..708a016f727 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -25,112 +25,138 @@ #include #endif -#define MY_DB_OPT_FILE ".db.opt" +#define MY_DB_OPT_FILE "db.opt" + +const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS}; +static TYPELIB deletable_extentions= +{array_elements(del_exts)-1,"del_exts", del_exts}; + +const char *known_exts[]= +{".ISM",".ISD",".ISM",".MRG",".MYI",".MYD",".db",NullS}; +static TYPELIB known_extentions= +{array_elements(known_exts)-1,"known_exts", known_exts}; static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, const char *path, uint level); /* - Create database options file: - Currently databse default charset is only stored there. + Create database options file: + + DESCRIPTION + Currently database default charset is only stored there. + + RETURN VALUES + 0 ok + 1 Could not create file or write to it. Error sent through my_error() */ -static int write_db_opt(THD *thd,const char *db,HA_CREATE_INFO *create,char *fn) +static bool write_db_opt(const char *path, HA_CREATE_INFO *create) { register File file; - char buf[256]; // Should be enough - int error=0; + char buf[256]; // Should be enough for one option + bool error=1; - if ((file=my_create(fn,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) + if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) { - sprintf(buf,"default-character-set=%s\n", - (create && create->table_charset) ? - create->table_charset->name : "DEFAULT"); - - if (my_write(file,(byte*)buf,strlen(buf),MYF(MY_NABP+MY_WME))) - { - // QQ : should we send more suitable error message? - my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno); - error = -1; - goto exit; - } + ulong length; + length= my_sprintf(buf,(buf, "default-character-set=%s\n", + (create && create->table_charset) ? + create->table_charset->name : "DEFAULT")); + + /* Error is written by my_write */ + if (!my_write(file,(byte*) buf, length, MYF(MY_NABP+MY_WME))) + error=0; my_close(file,MYF(0)); } - else - { - // QQ : should we send more suitable error message? - my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno); - error = -1; - goto exit; - } exit: return error; } - /* - Load database options file: - */ -static int load_db_opt(THD *thd,const char *db,HA_CREATE_INFO *create,char *fn) -{ - register File file; - char buf[256]=""; +/* + Load database options file - if ((file=my_open(fn,O_RDWR|O_BINARY,MYF(MY_WME))) >= 0) - { - int nbytes=my_read(file,(byte*)buf,sizeof(buf)-1,MYF(0)); - if ( nbytes >= 0 ) - { - char *ln=buf; - char *pe=buf+nbytes; + load_db_opt() + path Path for option file + create Where to store the read options + + DESCRIPTION + For now, only default-character-set is read. - buf[nbytes]='\0'; + RETURN VALUES + 0 File found + 1 No database file or could not open it - for ( ln=buf; ln= 0) + { + IO_CACHE cache; + init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)); + + while ((int) (nbytes= my_b_gets(&cache, (byte*) buf, sizeof(buf))) > 0) + { + char *pos= buf+nbytes-1; + /* Remove end space and control characters */ + while (pos > buf && !my_isgraph(system_charset_info, pos[-1])) + pos--; + *pos=0; + if ((pos= strchr(buf, '='))) { - char *le,*val; - for ( le=ln, val=0 ; letable_charset=get_charset_by_name(pos+1, MYF(0)))) { - case '=': - le[0]='\0'; - val=le+1; - le++; - break; - case '\r': - case '\n': - le[0]='\0'; - le++; - for( ; (le[0]=='\r' || le[0]=='\n') ; le++); - if (!strcmp(ln,"default-character-set") && val && val[0]) - { - create->table_charset=get_charset_by_name(val, MYF(0)); - } - goto cnt; - break; + sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET), + pos+1); } } -cnt: - ln=le; } } + error=0; + end_io_cache(&cache); my_close(file,MYF(0)); } - return 0; + DBUG_RETURN(error); } -/* db-name is already validated when we come here */ -int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent) +/* + Create a database + + SYNOPSIS + mysql_create_db() + thd Thread handler + db Name of database to create + Function assumes that this is already validated. + create_info Database create options (like character set) + silent Used by replication when internally creating a database. + In this case the entry should not be logged. + + RETURN VALUES + 0 ok + -1 Error + +*/ + +int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, + bool silent) { char path[FN_REFLEN+16]; MY_DIR *dirp; long result=1; int error = 0; uint create_options = create_info ? create_info->options : 0; - DBUG_ENTER("mysql_create_db"); VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); @@ -167,34 +193,49 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent } } - strcat(path,"/"); - unpack_dirname(path,path); + unpack_dirname(path, path); strcat(path,MY_DB_OPT_FILE); - if ((error=write_db_opt(thd,db,create_info,path))) - goto exit; + if (write_db_opt(path, create_info)) + { + /* + Could not create options file. + Restore things to beginning. + */ + if (rmdir(path) >= 0) + { + error= -1; + goto exit; + } + /* + We come here when we managed to create the database, but not the option + file. In this case it's best to just continue as if nothing has + happened. (This is a very unlikely senario) + */ + } if (!silent) { - if (!thd->query) + char *query; + uint query_length; + + if (!thd->query) // Only in replication { - thd->query = path; - thd->query_length = (uint) (strxmov(path,"create database ", db, NullS)- - path); + query= path; + query_length= (uint) (strxmov(path,"create database ", db, NullS) - + path); } + else { - mysql_update_log.write(thd,thd->query, thd->query_length); - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query); - mysql_bin_log.write(&qinfo); - } + query= thd->query; + query_length= thd->query_length; } - if (thd->query == path) + mysql_update_log.write(thd, query, query_length); + if (mysql_bin_log.is_open()) { - thd->query = 0; // just in case - thd->query_length = 0; + Query_log_event qinfo(thd, query, query_length); + mysql_bin_log.write(&qinfo); } - send_ok(&thd->net, result); + send_ok(thd, result); } exit: @@ -207,15 +248,15 @@ exit2: /* db-name is already validated when we come here */ -int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent) +int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { - char path[FN_REFLEN+16]; + char path[FN_REFLEN+16]; MY_DIR *dirp; long result=1; int error = 0; - DBUG_ENTER("mysql_create_db"); register File file; uint create_options = create_info ? create_info->options : 0; + DBUG_ENTER("mysql_alter_db"); VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); @@ -227,45 +268,27 @@ int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent) } /* Check directory */ - (void)sprintf(path,"%s/%s", mysql_data_home, db); - strcat(path,"/"); - unpack_dirname(path,path); // Convert if not unix - strcat(path,MY_DB_OPT_FILE); - if ((error=write_db_opt(thd,db,create_info,path))) + (void)sprintf(path,"%s/%s/%s", mysql_data_home, db, MY_DB_OPT_FILE); + fn_format(path, path, "", "", MYF(MY_UNPACK_FILENAME)); + if ((error=write_db_opt(path, create_info))) goto exit; /* - Change options if current - database is being altered + Change options if current database is being altered + TODO: Delete this code */ if (thd->db && !strcmp(thd->db,db)) { thd->db_charset= create_info ? create_info->table_charset : NULL; } - if (!silent) + mysql_update_log.write(thd,thd->query, thd->query_length); + if (mysql_bin_log.is_open()) { - if (!thd->query) - { - thd->query = path; - thd->query_length = (uint) (strxmov(path,"alter database ", db, NullS)- - path); - } - { - mysql_update_log.write(thd,thd->query, thd->query_length); - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length); - mysql_bin_log.write(&qinfo); - } - } - if (thd->query == path) - { - thd->query = 0; // just in case - thd->query_length = 0; - } - send_ok(&thd->net, result); + Query_log_event qinfo(thd, thd->query, thd->query_length); + mysql_bin_log.write(&qinfo); } + send_ok(thd, result); exit: start_waiting_global_read_lock(thd); @@ -275,18 +298,6 @@ exit2: } - - - -const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS}; -static TYPELIB deletable_extentions= -{array_elements(del_exts)-1,"del_exts", del_exts}; - -const char *known_exts[]= -{".ISM",".ISD",".ISM",".MRG",".MYI",".MYD",".db",NullS}; -static TYPELIB known_extentions= -{array_elements(known_exts)-1,"known_exts", known_exts}; - /* Drop all tables in a database. @@ -324,7 +335,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) my_error(ER_DB_DROP_EXISTS,MYF(0),db); } else if (!silent) - send_ok(&thd->net,0); + send_ok(thd,0); goto exit; } pthread_mutex_lock(&LOCK_open); @@ -355,7 +366,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) thd->query = 0; // just in case thd->query_length = 0; } - send_ok(&thd->net,(ulong) deleted); + send_ok(thd,(ulong) deleted); } error = 0; } @@ -503,30 +514,47 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, } -bool mysql_change_db(THD *thd,const char *name) +/* + Change default database. + + SYNOPSIS + mysql_change_db() + thd Thread handler + name Databasename + + DESCRIPTION + Becasue the database name may have been given directly from the + communication packet (in case of 'connect' or 'COM_INIT_DB') + we have to do end space removal in this function. + + RETURN VALUES + 0 ok + 1 error +*/ + +bool mysql_change_db(THD *thd, const char *name) { int length, db_length; char *dbname=my_strdup((char*) name,MYF(MY_WME)); char path[FN_REFLEN]; uint db_access; HA_CREATE_INFO create; - DBUG_ENTER("mysql_change_db"); if (!dbname || !(db_length=strip_sp(dbname))) { x_free(dbname); /* purecov: inspected */ - send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ + send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } if ((db_length > NAME_LEN) || check_db_name(dbname)) { - net_printf(&thd->net,ER_WRONG_DB_NAME, dbname); + net_printf(thd,ER_WRONG_DB_NAME, dbname); x_free(dbname); DBUG_RETURN(1); } if (lower_case_table_names) - casedn_str(dbname); + my_casedn_str(system_charset_info, dbname); DBUG_PRINT("info",("Use database: %s", dbname)); if (test_all_bits(thd->master_access,DB_ACLS)) db_access=DB_ACLS; @@ -536,7 +564,7 @@ bool mysql_change_db(THD *thd,const char *name) thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, + net_printf(thd,ER_DBACCESS_DENIED_ERROR, thd->priv_user, thd->host_or_ip, dbname); @@ -554,49 +582,37 @@ bool mysql_change_db(THD *thd,const char *name) path[length-1]=0; // remove ending '\' if (access(path,F_OK)) { - net_printf(&thd->net,ER_BAD_DB_ERROR,dbname); + net_printf(thd,ER_BAD_DB_ERROR,dbname); my_free(dbname,MYF(0)); DBUG_RETURN(1); } - send_ok(&thd->net); + send_ok(thd); x_free(thd->db); - thd->db=dbname; + thd->db=dbname; // THD::~THD will free this thd->db_length=db_length; thd->db_access=db_access; - strcat(path,"/"); - unpack_dirname(path,path); - strcat(path,MY_DB_OPT_FILE); - bzero(&create,sizeof(create)); - load_db_opt(thd,name,&create,path); + strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE); + load_db_opt(path, &create); thd->db_charset=create.table_charset; DBUG_RETURN(0); } -int mysqld_show_create_db(THD *thd,const char *name) +int mysqld_show_create_db(THD *thd, const char *dbname) { int length, db_length; - char *dbname=my_strdup((char*) name,MYF(MY_WME)); - char path[FN_REFLEN]; + char path[FN_REFLEN], *to; uint db_access; + bool found_libchar; HA_CREATE_INFO create; - CONVERT *convert=thd->convert_set; - + CONVERT *convert=thd->variables.convert_set; DBUG_ENTER("mysql_show_create_db"); - if (!dbname || !(db_length=strip_sp(dbname))) + if (check_db_name(dbname)) { - x_free(dbname); /* purecov: inspected */ - send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ - DBUG_RETURN(1); /* purecov: inspected */ - } - - if ((db_length > NAME_LEN) || check_db_name(dbname)) - { - net_printf(&thd->net,ER_WRONG_DB_NAME, dbname); - x_free(dbname); + net_printf(thd,ER_WRONG_DB_NAME, dbname); DBUG_RETURN(1); } @@ -608,7 +624,7 @@ int mysqld_show_create_db(THD *thd,const char *name) thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, + net_printf(thd,ER_DBACCESS_DENIED_ERROR, thd->priv_user, thd->host_or_ip, dbname); @@ -616,26 +632,26 @@ int mysqld_show_create_db(THD *thd,const char *name) thd->priv_user, thd->host_or_ip, dbname); - my_free(dbname,MYF(0)); DBUG_RETURN(1); } - (void) sprintf(path,"%s/%s",mysql_data_home,dbname); + (void) sprintf(path,"%s/%s",mysql_data_home, dbname); length=unpack_dirname(path,path); // Convert if not unix + found_libchar= 0; if (length && path[length-1] == FN_LIBCHAR) + { + found_libchar= 1; path[length-1]=0; // remove ending '\' + } if (access(path,F_OK)) { - net_printf(&thd->net,ER_BAD_DB_ERROR,dbname); - my_free(dbname,MYF(0)); + net_printf(thd,ER_BAD_DB_ERROR,dbname); DBUG_RETURN(1); } - - strcat(path,"/"); - unpack_dirname(path,path); - strcat(path,MY_DB_OPT_FILE); - bzero(&create,sizeof(create)); - load_db_opt(thd,name,&create,path); + if (found_libchar) + path[length-1]= FN_LIBCHAR; + strmov(path+length, MY_DB_OPT_FILE); + load_db_opt(path, &create); List field_list; field_list.push_back(new Item_empty_string("Database",NAME_LEN)); @@ -646,19 +662,16 @@ int mysqld_show_create_db(THD *thd,const char *name) String *packet = &thd->packet; packet->length(0); - net_store_data(packet, convert, name); - sprintf(path, "CREATE DATABASE %s", name); + net_store_data(packet, convert, dbname); + to= strxmov(path, "CREATE DATABASE `", dbname, "`", NullS); if (create.table_charset) - { - strcat(path," DEFAULT CHARACTER SET "); - strcat(path,create.table_charset->name); - } - net_store_data(packet, convert, path); - - if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) + to= strxmov(to," DEFAULT CHARACTER SET ", create.table_charset->name, + NullS); + net_store_data(packet, convert, path, (uint) (to-path)); + + if (my_net_write(&thd->net,(char*) packet->ptr(), packet->length())) DBUG_RETURN(1); - send_eof(&thd->net); - + send_eof(thd); DBUG_RETURN(0); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index fc98cfb90c5..0581e0b5a3b 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -43,7 +43,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, table_list->db=thd->db; if ((thd->options & OPTION_SAFE_UPDATES) && !conds) { - send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); + send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); DBUG_RETURN(1); } @@ -83,7 +83,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, !limit) { delete select; - send_ok(&thd->net,0L); + send_ok(thd,0L); DBUG_RETURN(0); // Nothing to delete } @@ -94,7 +94,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, if ((thd->options & OPTION_SAFE_UPDATES) && limit == HA_POS_ERROR) { delete select; - send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); + send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); DBUG_RETURN(1); } } @@ -188,10 +188,10 @@ cleanup: } delete select; if (error >= 0) // Fatal error - send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN: 0); + send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0); else { - send_ok(&thd->net,deleted); + send_ok(thd,deleted); DBUG_PRINT("info",("%d records deleted",deleted)); } DBUG_RETURN(0); @@ -354,7 +354,7 @@ void multi_delete::send_error(uint errcode,const char *err) DBUG_ENTER("multi_delete::send_error"); /* First send error what ever it is ... */ - ::send_error(&thd->net,errcode,err); + ::send_error(thd,errcode,err); /* If nothing deleted return */ if (!deleted) @@ -456,7 +456,7 @@ bool multi_delete::send_eof() thd->proc_info="end"; if (error) { - ::send_error(&thd->net); + ::send_error(thd); return 1; } @@ -483,7 +483,7 @@ bool multi_delete::send_eof() { query_cache_invalidate3(thd, delete_tables, 1); } - ::send_ok(&thd->net,deleted); + ::send_ok(thd,deleted); return 0; } @@ -580,7 +580,7 @@ end: Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } - send_ok(&thd->net); // This should return record count + send_ok(thd); // This should return record count } VOID(pthread_mutex_lock(&LOCK_open)); unlock_table_name(thd, table_list); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index fb40a85fd91..6b144d36f53 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -120,7 +120,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) exit: close_thread_tables(thd); if (res > 0) - send_error(&thd->net, ER_UNKNOWN_COM_ERROR); // temporary only ... + send_error(thd, ER_UNKNOWN_COM_ERROR); // temporary only ... } DBUG_RETURN(res); } diff --git a/sql/sql_do.cc b/sql/sql_do.cc index 70124c2d796..2eef088da5b 100644 --- a/sql/sql_do.cc +++ b/sql/sql_do.cc @@ -29,6 +29,6 @@ int mysql_do(THD *thd, List &values) DBUG_RETURN(-1); while ((value = li++)) value->val_int(); - send_ok(&thd->net); + send_ok(thd); DBUG_RETURN(0); } diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 13466f454c5..3d6a0fa24aa 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -18,202 +18,136 @@ /********************************************************************** This file contains the implementation of error and warnings related - - Whenever an error or warning occured, it pushes the same to - the respective list along with sending it to client. + - Whenever an error or warning occurred, it pushes it to a warning list + that the user can retrieve with SHOW WARNINGS or SHOW ERRORS. + + - For each statement, we return the number of warnings generated from this + command. Note that this can be different from @@warning_count as + we reset the warning list only for questions that uses a table. + This is done to allow on to do: + INSERT ...; + SELECT @@warning_count; + SHOW WARNINGS; + (If we would reset after each command, we could not retrieve the number + of warnings) - When client requests the information using SHOW command, then server processes from this list and returns back in the form of resultset. - syntax : SHOW [COUNT(*)] ERRORS [LIMIT [offset,] rows] - SHOW [COUNT(*)] WARNINGS [LIMIT [offset,] rows] + Supported syntaxes: + + SHOW [COUNT(*)] ERRORS [LIMIT [offset,] rows] + SHOW [COUNT(*)] WARNINGS [LIMIT [offset,] rows] + SELECT @@warning_count, @@error_count; ***********************************************************************/ -/* Handles errors and warnings .. */ #include "mysql_priv.h" -/* - Push the error to error list -*/ +/* + Reset all warnings for the thread -void push_error(uint code, const char *msg) -{ - THD *thd=current_thd; + SYNOPSIS + mysql_reset_errors() + thd Thread handle +*/ - mysql_st_error *err = new mysql_st_error(code,msg,(const char*)thd->query); - - if (thd->err_list.elements >= thd->max_error_count) - { - /* Remove the old elements and always maintain the max size - equal to sql_error_count. - - If one max_error_count using sets sql_error_count less than - the current list size, then make sure it always grows upto - sql_error_count size only - - ** BUG ** : Doesn't work in removing the old one - from the list, and thus SET SQL_ERROR_COUNT=x doesn't work - */ - for (uint count=thd->err_list.elements-1; - count <= thd->max_error_count-1; count++) - { - thd->err_list.remove_last(); - } - } - thd->err_list.push_front(err); +void mysql_reset_errors(THD *thd) +{ + free_root(&thd->warn_root,MYF(0)); + bzero((char*) thd->warn_count, sizeof(thd->warn_count)); + thd->warn_list.empty(); } + /* - Push the warning to warning list + Push the warning/error to error list if there is still room in the list + + SYNOPSIS + push_warning() + thd Thread handle + level Severity of warning (note, warning, error ...) + code Error number + msg Clear error message */ -void push_warning(uint code, const char *msg) -{ - THD *thd=current_thd; - - mysql_st_error *warn = new mysql_st_error(code,msg,(const char *)thd->query); - - if (thd->warn_list.elements >= thd->max_warning_count) +void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, + const char *msg) +{ + if (thd->warn_list.elements < thd->variables.max_error_count) { - /* Remove the old elements and always maintian the max size - equal to sql_error_count + /* + The following code is here to change the allocation to not + use the thd->mem_root, which is freed after each query */ - for (uint count=thd->warn_list.elements; - count <= thd->max_warning_count-1; count++) - { - thd->warn_list.remove_last(); - } - } - thd->warn_list.push_front(warn); -} - -/* - List all errors -*/ - -int mysqld_show_errors(THD *thd) -{ - List field_list; - DBUG_ENTER("mysqld_show_errors"); - - field_list.push_back(new Item_int("CODE",0,4)); - field_list.push_back(new Item_empty_string("MESSAGE",MYSQL_ERRMSG_SIZE)); - field_list.push_back(new Item_empty_string("QUERY",NAME_LEN)); - - if (send_fields(thd,field_list,1)) - DBUG_RETURN(1); - - mysql_st_error *err; - SELECT_LEX *sel=&thd->lex.select_lex; - ha_rows offset = sel->offset_limit,limit = sel->select_limit; - uint num_rows = 0; - - Error_iterator it(thd->err_list); - - while(offset-- && (err = it++));/* Should be fixed with overloaded - operator '+' or with new funtion - goto() in list ? - */ - - while((num_rows++ < limit) && (err = it++)) - { - thd->packet.length(0); - net_store_data(&thd->packet,(uint32)err->code); - net_store_data(&thd->packet,err->msg); - net_store_data(&thd->packet,err->query); - - if (my_net_write(&thd->net,(char*)thd->packet.ptr(),thd->packet.length())) - DBUG_RETURN(-1); + MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); + my_pthread_setspecific_ptr(THR_MALLOC, &thd->warn_root); + MYSQL_ERROR *err= new MYSQL_ERROR(code, level, msg); + if (err) + thd->warn_list.push_back(err); + my_pthread_setspecific_ptr(THR_MALLOC, old_root); } - send_eof(&thd->net); - DBUG_RETURN(0); + thd->warn_count[(uint) level]++; + thd->total_warn_count++; } -/* - Return errors count -*/ -int mysqld_show_errors_count(THD *thd) -{ - List field_list; - DBUG_ENTER("mysqld_show_errors_count"); +/* + Send all notes, errors or warnings to the client in a result set - field_list.push_back(new Item_int("COUNT(*)",0,4)); + SYNOPSIS + mysqld_show_warnings() + thd Thread handler + levels_to_show Bitmap for which levels to show - if (send_fields(thd,field_list,1)) - DBUG_RETURN(1); + DESCRIPTION + Takes into account the current LIMIT - thd->packet.length(0); - net_store_data(&thd->packet,(uint32)thd->err_list.elements); + RETURN VALUES + 0 ok + 1 Error sending data to client +*/ - if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) - DBUG_RETURN(-1); +static const char *warning_level_names[]= {"Note", "Warning", "Error", "?"}; - send_eof(&thd->net); - DBUG_RETURN(0); -} -/* - List all warnings -*/ - -int mysqld_show_warnings(THD *thd) -{ +my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show) +{ List field_list; - DBUG_ENTER("mysqld_show_warnings"); + DBUG_ENTER("mysqld_show_errors"); - field_list.push_back(new Item_int("CODE",0,21)); - field_list.push_back(new Item_empty_string("MESSAGE",MYSQL_ERRMSG_SIZE)); - field_list.push_back(new Item_empty_string("QUERY",NAME_LEN)); + field_list.push_back(new Item_empty_string("Level", 7)); + field_list.push_back(new Item_int("Code",0,4)); + field_list.push_back(new Item_empty_string("Message",MYSQL_ERRMSG_SIZE)); if (send_fields(thd,field_list,1)) DBUG_RETURN(1); - mysql_st_error *warn; - + MYSQL_ERROR *err; + SELECT_LEX *sel= &thd->lex.select_lex; + ha_rows offset= sel->offset_limit, limit= sel->select_limit; - SELECT_LEX *sel=&thd->lex.select_lex; - ha_rows offset = sel->offset_limit,limit = sel->select_limit; - uint num_rows = 0; - - Error_iterator it(thd->warn_list); - while(offset-- && (warn = it++)); - while((num_rows++ < limit) && (warn = it++)) + List_iterator_fast it(thd->warn_list); + while ((err= it++)) { + /* Skip levels that the user is not interested in */ + if (!(levels_to_show & ((ulong) 1 << err->level))) + continue; + if (offset) + { + offset--; + continue; + } thd->packet.length(0); - net_store_data(&thd->packet,(uint32)warn->code); - net_store_data(&thd->packet,warn->msg); - net_store_data(&thd->packet,warn->query); - - if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) - DBUG_RETURN(-1); + net_store_data(&thd->packet,warning_level_names[err->level]); + net_store_data(&thd->packet,(uint32) err->code); + net_store_data(&thd->packet,err->msg); + if (my_net_write(&thd->net,(char*)thd->packet.ptr(),thd->packet.length())) + DBUG_RETURN(1); + if (!--limit) + break; } - send_eof(&thd->net); - DBUG_RETURN(0); -} - -/* - Return warnings count -*/ - -int mysqld_show_warnings_count(THD *thd) -{ - List field_list; - DBUG_ENTER("mysqld_show_warnings_count"); - - field_list.push_back(new Item_int("COUNT(*)",0,21)); - - if (send_fields(thd,field_list,1)) - DBUG_RETURN(1); - - thd->packet.length(0); - net_store_data(&thd->packet,(uint32)thd->warn_list.elements); - - if (my_net_write(&thd->net,(char*)thd->packet.ptr(),thd->packet.length())) - DBUG_RETURN(-1); - - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } - diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 7fa24faf6c4..4191973b325 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -62,7 +62,7 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables) return -1; } - send_ok(&thd->net); + send_ok(thd); return 0; } @@ -83,7 +83,7 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) return -1; } if (!dont_send_ok) - send_ok(&thd->net); + send_ok(thd); return 0; } @@ -185,7 +185,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, } if (!(key= (byte*) sql_calloc(ALIGN_SIZE(key_len)))) { - send_error(&thd->net,ER_OUTOFMEMORY); + send_error(thd,ER_OUTOFMEMORY); goto err; } key_copy(key, table, keyno, key_len); @@ -195,7 +195,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, break; } default: - send_error(&thd->net,ER_ILLEGAL_HA); + send_error(thd,ER_ILLEGAL_HA); goto err; } @@ -240,7 +240,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, } ok: mysql_unlock_tables(thd,lock); - send_eof(&thd->net); + send_eof(thd); return 0; err: mysql_unlock_tables(thd,lock); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b02fd99e358..2852ac8b45d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -333,7 +333,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) || !thd->cuted_fields)) - send_ok(&thd->net,info.copied+info.deleted,id); + send_ok(thd,info.copied+info.deleted,id); else { char buff[160]; @@ -345,7 +345,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, else sprintf(buff,ER(ER_INSERT_INFO),info.records,info.deleted, thd->cuted_fields); - ::send_ok(&thd->net,info.copied+info.deleted,(ulonglong)id,buff); + ::send_ok(thd,info.copied+info.deleted,(ulonglong)id,buff); } DBUG_RETURN(0); @@ -667,7 +667,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list) delete tmp; thd->fatal_error=1; pthread_mutex_unlock(&LOCK_delayed_create); - net_printf(&thd->net,ER_CANT_CREATE_THREAD,error); + net_printf(thd,ER_CANT_CREATE_THREAD,error); DBUG_RETURN(0); } @@ -1334,7 +1334,7 @@ bool select_insert::send_data(List &values) void select_insert::send_error(uint errcode,const char *err) { - ::send_error(&thd->net,errcode,err); + ::send_error(thd,errcode,err); table->file->extra(HA_EXTRA_NO_CACHE); table->file->activate_all_index(thd); ha_rollback_stmt(thd); @@ -1360,7 +1360,7 @@ bool select_insert::send_eof() if (error) { table->file->print_error(error,MYF(0)); - ::send_error(&thd->net); + ::send_error(thd); return 1; } else @@ -1374,7 +1374,7 @@ bool select_insert::send_eof() thd->cuted_fields); if (last_insert_id) thd->insert_id(last_insert_id); // For update log - ::send_ok(&thd->net,info.copied,last_insert_id,buff); + ::send_ok(thd,info.copied,last_insert_id,buff); mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index dc9019de2c8..1af8d363fda 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1064,7 +1064,7 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex, // check usage of ORDER BY in union if (sl->order_list.first && sl->next_select() && !sl->braces) { - net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY"); + net_printf(thd,ER_WRONG_USAGE,"UNION","ORDER BY"); return 1; } for (SELECT_LEX_UNIT *inner= sl->first_inner_unit(); @@ -1092,7 +1092,7 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex, if (!(cursor= (TABLE_LIST *) thd->memdup((char*) aux, sizeof(*aux)))) { - send_error(&thd->net,0); + send_error(thd,0); return 1; } *new_table_list= cursor; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 6aef99886e9..dba8216e94c 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -238,7 +238,8 @@ typedef class st_select_lex_unit SELECT_LEX_UNIT; SELECT_LEX - store information of parsed SELECT_LEX statment */ class JOIN; -class st_select_lex: public st_select_lex_node { +class st_select_lex: public st_select_lex_node +{ public: char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */ Item *where, *having; /* WHERE & HAVING clauses */ @@ -342,6 +343,7 @@ typedef struct st_lex enum enum_var_type option_type; uint grant, grant_tot_col, which_columns, union_option; uint fk_delete_opt, fk_update_opt, fk_match_option; + uint param_count; bool drop_primary, drop_if_exists, local_file, olap; bool in_comment, ignore_space, verbose, simple_alter; bool derived_tables; diff --git a/sql/sql_list.h b/sql/sql_list.h index ef8a0c41a1b..56e6528f214 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -362,120 +362,3 @@ public: I_List_iterator(I_List &a) : base_ilist_iterator(a) {} inline T* operator++(int) { return (T*) base_ilist_iterator::next(); } }; - -/* - New error list without mem_root from THD, to have the life of the - allocation becomes connection level . by ovveriding new from Sql_alloc. -*/ -class Error_alloc -{ -public: - static void *operator new(size_t size) - { - return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE)); - } -#if 0 - static void operator delete(void* ptr_arg, size_t size) - { - my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); - } -#endif - friend class error_node; - friend class error_list; -}; - -class error_node :public Error_alloc, public list_node -{ -public: - static void *operator new(size_t size) - { - return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE)); - } -#if 0 - static void operator delete(void* ptr_arg, size_t size) - { - my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); - } -#endif - error_node(void *info_par,list_node *next_par):list_node(info_par,next_par){}; - error_node() : list_node() {}; - friend class error_list; - friend class error_list_iterator; -}; - -class error_list: public Error_alloc, public base_list -{ -public: - inline error_list() : base_list() { }; - inline error_list(const error_list &tmp) : base_list(tmp) - { - elements=tmp.elements; - first=tmp.first; - last=tmp.last; - } - inline bool push_front(void *info) - { - error_node *node=new error_node(info,first); - if (node) - { - if (last == &first) - last= &node->next; - first=node; - elements++; - return 0; - } - return 1; - } - inline void remove_last(void) - { - remove(last); - } -protected: - void after(void *info,list_node *node) - { - error_node *new_node=new error_node(info,node->next); - node->next=new_node; - elements++; - if (last == &(node->next)) - last= &new_node->next; - } -}; - -class error_list_iterator : public base_list_iterator -{ - inline error_list_iterator(base_list &base_ptr): base_list_iterator(base_ptr) {}; -}; - -template class Error :public error_list -{ -public: - inline Error() :error_list() {} - inline Error(const Error &tmp) :error_list(tmp) {} - inline bool push_back(T *a) { return error_list::push_back(a); } - inline bool push_front(T *a) { return error_list::push_front(a); } - inline T* head() {return (T*) error_list::head(); } - inline T** head_ref() {return (T**) error_list::head_ref(); } - inline T* pop() {return (T*) error_list::pop(); } - void delete_elements(void) - { - error_node *element,*next; - for (element=first; element != &error_end_of_list; element=next) - { - next=element->next; - delete (T*) element->info; - } - empty(); - } -}; - -template class Error_iterator :public base_list_iterator -{ -public: - Error_iterator(Error &a) : base_list_iterator(a) {} - inline T* operator++(int) { return (T*) base_list_iterator::next(); } - inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); } - inline T *replace(Error &a) { return (T*) base_list_iterator::replace(a); } - inline void after(T *a) { base_list_iterator::after(a); } - inline T** ref(void) { return (T**) base_list_iterator::ref(); } -}; - diff --git a/sql/sql_load.cc b/sql/sql_load.cc index ad25ef85e75..fe556be98f5 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -293,7 +293,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, } sprintf(name,ER(ER_LOAD_INFO),info.records,info.deleted, info.records-info.copied,thd->cuted_fields); - send_ok(&thd->net,info.copied+info.deleted,0L,name); + send_ok(thd,info.copied+info.deleted,0L,name); // on the slave thd->query is never initialized if (!thd->slave_thread) mysql_update_log.write(thd,thd->query,thd->query_length); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b889b9ee29f..461276900a5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -57,7 +57,7 @@ extern "C" pthread_mutex_t THR_LOCK_keycache; extern "C" int gethostname(char *name, int namelen); #endif -static int check_for_max_user_connections(USER_CONN *uc); +static int check_for_max_user_connections(THD *thd, USER_CONN *uc); static void decrease_user_connections(USER_CONN *uc); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); @@ -77,7 +77,7 @@ const char *command_name[]={ "Prepare", "Prepare Execute", "Long Data" }; -bool volatile abort_slave = 0; +static char empty_c_string[1]= {0}; // Used for not defined 'db' #ifdef HAVE_OPENSSL extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd; @@ -144,7 +144,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, my_malloc(sizeof(struct user_conn) + temp_len+1, MYF(MY_WME))))) { - send_error(¤t_thd->net, 0, NullS); // Out of memory + send_error(thd, 0, NullS); // Out of memory return_val=1; goto end; } @@ -162,7 +162,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, if (hash_insert(&hash_user_connections, (byte*) uc)) { my_free((char*) uc,0); - send_error(¤t_thd->net, 0, NullS); // Out of memory + send_error(thd, 0, NullS); // Out of memory return_val=1; goto end; } @@ -184,14 +184,13 @@ end: static bool check_user(THD *thd,enum_server_command command, const char *user, const char *passwd, const char *db, bool check_count) { - NET *net= &thd->net; thd->db=0; thd->db_length=0; USER_RESOURCES ur; if (!(thd->user = my_strdup(user, MYF(0)))) { - send_error(net,ER_OUT_OF_RESOURCES); + send_error(thd,ER_OUT_OF_RESOURCES); return 1; } thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user, @@ -207,7 +206,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, thd->master_access, thd->db ? thd->db : "*none*")); if (thd->master_access & NO_ACCESS) { - net_printf(net, ER_ACCESS_DENIED_ERROR, + net_printf(thd, ER_ACCESS_DENIED_ERROR, thd->user, thd->host_or_ip, passwd[0] ? ER(ER_YES) : ER(ER_NO)); @@ -225,7 +224,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (tmp) { // Too many connections - send_error(net, ER_CON_COUNT_ERROR); + send_error(thd, ER_CON_COUNT_ERROR); return(1); } } @@ -242,7 +241,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, get_or_create_user_conn(thd,user,thd->host_or_ip,&ur)) return -1; if (thd->user_connect && thd->user_connect->user_resources.connections && - check_for_max_user_connections(thd->user_connect)) + check_for_max_user_connections(thd, thd->user_connect)) return -1; if (db && db[0]) { @@ -252,7 +251,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, return error; } else - send_ok(net); // Ready to handle questions + send_ok(thd); // Ready to handle questions return 0; // ok } @@ -283,7 +282,7 @@ void init_max_user_conn(void) } -static int check_for_max_user_connections(USER_CONN *uc) +static int check_for_max_user_connections(THD *thd, USER_CONN *uc) { int error=0; DBUG_ENTER("check_for_max_user_connections"); @@ -291,7 +290,7 @@ static int check_for_max_user_connections(USER_CONN *uc) if (max_user_connections && (max_user_connections <= (uint) uc->connections)) { - net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, uc->user); + net_printf(thd,ER_TOO_MANY_USER_CONNECTIONS, uc->user); error=1; goto end; } @@ -299,11 +298,10 @@ static int check_for_max_user_connections(USER_CONN *uc) if (uc->user_resources.connections && uc->conn_per_hour++ >= uc->user_resources.connections) { - net_printf(¤t_thd->net, ER_USER_LIMIT_REACHED, uc->user, + net_printf(thd, ER_USER_LIMIT_REACHED, uc->user, "max_connections", (long) uc->user_resources.connections); error=1; - goto end; } end: DBUG_RETURN(error); @@ -363,7 +361,7 @@ static bool check_mqh(THD *thd, uint check_command) if (uc->user_resources.questions && uc->questions++ >= uc->user_resources.questions) { - net_printf(&thd->net, ER_USER_LIMIT_REACHED, uc->user, "max_questions", + net_printf(thd, ER_USER_LIMIT_REACHED, uc->user, "max_questions", (long) uc->user_resources.questions); error=1; goto end; @@ -374,7 +372,7 @@ static bool check_mqh(THD *thd, uint check_command) if (uc->user_resources.updates && uc_update_queries[check_command] && uc->updates++ >= uc->user_resources.updates) { - net_printf(&thd->net, ER_USER_LIMIT_REACHED, uc->user, "max_updates", + net_printf(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates", (long) uc->user_resources.updates); error=1; goto end; @@ -501,7 +499,7 @@ check_connections(THD *thd) int2store(end+3,thd->server_status); bzero(end+5,13); end+=18; - if (net_write_command(net,(uchar) protocol_version, buff, + if (net_write_command(net,(uchar) protocol_version, "", 0, buff, (uint) (end-buff)) || (pkt_len= my_net_read(net)) == packet_error || pkt_len < MIN_HANDSHAKE_SIZE) @@ -629,7 +627,7 @@ pthread_handler_decl(handle_one_connection,arg) if ((error=check_connections(thd))) { // Wrong permissions if (error > 0) - net_printf(net,error,thd->host_or_ip); + net_printf(thd,error,thd->host_or_ip); #ifdef __NT__ if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE) sleep(1); /* must wait after eof() */ @@ -667,7 +665,7 @@ pthread_handler_decl(handle_one_connection,arg) thd->host_or_ip, (net->last_errno ? ER(net->last_errno) : ER(ER_UNKNOWN_ERROR))); - send_error(net,net->last_errno,NullS); + send_error(thd,net->last_errno,NullS); thread_safe_increment(aborted_threads,&LOCK_status); } @@ -765,11 +763,11 @@ end: DBUG_RETURN(0); // Never reached } + /* This works because items are allocated with sql_alloc() */ -inline void free_items(THD *thd) +void free_items(Item *item) { - /* This works because items are allocated with sql_alloc() */ - for (Item *item=thd->free_list ; item ; item=item->next) + for (; item ; item=item->next) delete item; } @@ -793,7 +791,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) if (!db || check_db_name(db)) { - net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); + net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); goto err; } if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege)) @@ -891,7 +889,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_REGISTER_SLAVE: { if (!register_slave(thd, (uchar*)packet, packet_length)) - send_ok(&thd->net); + send_ok(thd); break; } case COM_TABLE_DUMP: @@ -907,7 +905,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, memcpy(tbl_name, packet + db_len + 2, tbl_len); tbl_name[tbl_len] = 0; if (mysql_table_dump(thd, db, tbl_name, -1)) - send_error(&thd->net); // dump to NET + send_error(thd); // dump to NET break; } @@ -929,7 +927,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if ((uint) ((uchar*) db - net->read_pos) > packet_length) { // Check if protocol is ok - send_error(net, ER_UNKNOWN_COM_ERROR); + send_error(thd, ER_UNKNOWN_COM_ERROR); break; } if (check_user(thd, COM_CHANGE_USER, user, passwd, db, 0)) @@ -953,48 +951,26 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_EXECUTE: { - mysql_com_execute(thd); + mysql_stmt_execute(thd, packet); break; } case COM_LONG_DATA: { - mysql_com_longdata(thd); + mysql_stmt_get_longdata(thd, packet, packet_length); break; } case COM_PREPARE: { - mysql_com_prepare(thd,packet,packet_length); + mysql_stmt_prepare(thd, packet, packet_length); break; } case COM_QUERY: { - packet_length--; // Remove end null - /* Remove garage at start and end of query */ - while (my_isspace(system_charset_info,packet[0]) && packet_length > 0) - { - packet++; - packet_length--; - } - char *pos=packet+packet_length; // Point at end null - while (packet_length > 0 && - (pos[-1] == ';' || my_isspace(system_charset_info,pos[-1]))) - { - pos--; - packet_length--; - } - /* We must allocate some extra memory for query cache */ - if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), - packet_length, - thd->db_length+2))) - break; - thd->query[packet_length]=0; - thd->packet.shrink(thd->variables.net_buffer_length);// Reclaim some memory - if (!(specialflag & SPECIAL_NO_PRIOR)) - my_pthread_setprio(pthread_self(),QUERY_PRIOR); + if (alloc_query(thd, packet, packet_length)) + break; // fatal error is set mysql_log.write(thd,command,"%s",thd->query); DBUG_PRINT("query",("%s",thd->query)); - /* thd->query_length is set by mysql_parse() */ - mysql_parse(thd,thd->query,packet_length); + mysql_parse(thd,thd->query, thd->query_length); if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),WAIT_PRIOR); DBUG_PRINT("info",("query ready")); @@ -1002,7 +978,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_FIELD_LIST: // This isn't actually needed #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ break; #else { @@ -1012,7 +988,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, bzero((char*) &table_list,sizeof(table_list)); if (!(table_list.db=thd->db)) { - send_error(net,ER_NO_DB_ERROR); + send_error(thd,ER_NO_DB_ERROR); break; } thd->free_list=0; @@ -1030,7 +1006,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (grant_option && check_grant(thd,SELECT_ACL,&table_list,2)) break; mysqld_list_fields(thd,&table_list,fields); - free_items(thd); + free_items(thd->free_list); break; } #endif @@ -1048,11 +1024,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, // null test to handle EOM if (!db || !strip_sp(db) || check_db_name(db)) { - net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); + net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); break; } if (lower_case_table_names) - casedn_str(db); + my_casedn_str(system_charset_info, db); if (check_access(thd,CREATE_ACL,db,0,1)) break; mysql_log.write(thd,command,packet); @@ -1066,14 +1042,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd, // null test to handle EOM if (!db || !strip_sp(db) || check_db_name(db)) { - net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); + net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); break; } if (lower_case_table_names) - casedn_str(db); + my_casedn_str(system_charset_info, db); if (thd->locked_tables || thd->active_transaction()) { - send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); + send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); break; } mysql_log.write(thd,command,db); @@ -1112,9 +1088,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; mysql_log.write(thd,command,NullS); if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0)) - send_error(net,0); + send_error(thd,0); else - send_eof(net); + send_eof(thd); break; } case COM_SHUTDOWN: @@ -1123,12 +1099,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; /* purecov: inspected */ DBUG_PRINT("quit",("Got shutdown command")); mysql_log.write(thd,command,NullS); - send_eof(net); + send_eof(thd); #ifdef __WIN__ sleep(1); // must wait after eof() #endif #ifndef OS2 - send_eof(net); // This is for 'quit request' + send_eof(thd); // This is for 'quit request' #endif close_connection(net); close_thread_tables(thd); // Free before kill @@ -1161,7 +1137,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_PING: thread_safe_increment(com_other,&LOCK_status); - send_ok(net); // Tell client we are alive + send_ok(thd); // Tell client we are alive break; case COM_PROCESS_INFO: thread_safe_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_status); @@ -1184,14 +1160,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; /* purecov: inspected */ mysql_print_status(thd); mysql_log.write(thd,command,NullS); - send_eof(net); + send_eof(thd); break; case COM_SLEEP: case COM_CONNECT: // Impossible here case COM_TIME: // Impossible from client case COM_DELAYED_INSERT: default: - send_error(net, ER_UNKNOWN_COM_ERROR); + send_error(thd, ER_UNKNOWN_COM_ERROR); break; } if (thd->lock || thd->open_tables) @@ -1201,7 +1177,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } if (thd->fatal_error) - send_error(net,0); // End of memory ? + send_error(thd,0); // End of memory ? time_t start_of_query=thd->start_time; thd->end_time(); // Set start time @@ -1233,22 +1209,80 @@ bool dispatch_command(enum enum_server_command command, THD *thd, DBUG_RETURN(error); } + +/* + Read query from packet and store in thd->query + Used in COM_QUERY and COM_PREPARE + + DESCRIPTION + Sets the following THD variables: + query + query_length + + RETURN VALUES + 0 ok + 1 error; In this case thd->fatal_error is set +*/ + +bool alloc_query(THD *thd, char *packet, ulong packet_length) +{ + packet_length--; // Remove end null + /* Remove garage at start and end of query */ + while (my_isspace(system_charset_info,packet[0]) && packet_length > 0) + { + packet++; + packet_length--; + } + char *pos=packet+packet_length; // Point at end null + while (packet_length > 0 && + (pos[-1] == ';' || my_isspace(system_charset_info,pos[-1]))) + { + pos--; + packet_length--; + } + /* We must allocate some extra memory for query cache */ + if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), + packet_length, + thd->db_length+2))) + return 1; + thd->query[packet_length]=0; + thd->query_length= packet_length; + thd->packet.shrink(thd->variables.net_buffer_length);// Reclaim some memory + + if (!(specialflag & SPECIAL_NO_PRIOR)) + my_pthread_setprio(pthread_self(),QUERY_PRIOR); + return 0; +} + /**************************************************************************** ** mysql_execute_command ** Execute command saved in thd and current_lex->sql_command ****************************************************************************/ void -mysql_execute_command(void) +mysql_execute_command(THD *thd) { int res= 0; - THD *thd= current_thd; LEX *lex= &thd->lex; TABLE_LIST *tables= (TABLE_LIST*) lex->select_lex.table_list.first; SELECT_LEX *select_lex= lex->select; SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); + /* + Reset warning count for each query that uses tables + A better approach would be to reset this for any commands + that is not a SHOW command or a select that only access local + variables, but for now this is probably good enough. + */ + if (tables) + mysql_reset_errors(thd); + /* + Save old warning count to be able to send to client how many warnings we + got + */ + thd->old_total_warn_count= thd->total_warn_count; + if (thd->slave_thread) { /* @@ -1376,7 +1410,7 @@ mysql_execute_command(void) break; case SQLCOM_EMPTY_QUERY: - send_ok(&thd->net); + send_ok(thd); break; case SQLCOM_PURGE: @@ -1388,12 +1422,15 @@ mysql_execute_command(void) } case SQLCOM_SHOW_WARNS: { - res = mysqld_show_warnings(thd); + res= mysqld_show_warnings(thd, (ulong) + ((1L << (uint) MYSQL_ERROR::WARN_LEVEL_NOTE) | + (1L << (uint) MYSQL_ERROR::WARN_LEVEL_WARN))); break; } case SQLCOM_SHOW_ERRORS: { - res = mysqld_show_errors(thd); + res= mysqld_show_warnings(thd, (ulong) + (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR)); break; } case SQLCOM_SHOW_NEW_MASTER: @@ -1499,7 +1536,7 @@ mysql_execute_command(void) } if (strlen(tables->name) > NAME_LEN) { - net_printf(&thd->net,ER_WRONG_TABLE_NAME,tables->name); + net_printf(thd,ER_WRONG_TABLE_NAME,tables->name); break; } LOCK_ACTIVE_MI; @@ -1507,7 +1544,7 @@ mysql_execute_command(void) if (!fetch_master_table(thd, tables->db, tables->real_name, active_mi, 0)) { - send_ok(&thd->net); + send_ok(thd); } UNLOCK_ACTIVE_MI; break; @@ -1535,7 +1572,7 @@ mysql_execute_command(void) } if (strlen(tables->name) > NAME_LEN) { - net_printf(&thd->net,ER_WRONG_TABLE_NAME,tables->name); + net_printf(thd,ER_WRONG_TABLE_NAME,tables->name); res=0; break; } @@ -1559,7 +1596,7 @@ mysql_execute_command(void) if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && check_dup(tables->db, tables->real_name, tables->next)) { - net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name); + net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name); DBUG_VOID_RETURN; } if (tables->next) @@ -1598,7 +1635,7 @@ mysql_execute_command(void) lex->create_list, lex->key_list,0,0,0); // do logging if (!res) - send_ok(&thd->net); + send_ok(thd); } break; } @@ -1631,14 +1668,14 @@ mysql_execute_command(void) } case SQLCOM_ALTER_TABLE: #if defined(DONT_ALLOW_SHOW_COMMANDS) - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ break; #else { ulong priv=0; if (lex->name && strlen(lex->name) > NAME_LEN) { - net_printf(&thd->net,ER_WRONG_TABLE_NAME,lex->name); + net_printf(thd,ER_WRONG_TABLE_NAME,lex->name); res=0; break; } @@ -1721,7 +1758,7 @@ mysql_execute_command(void) } case SQLCOM_SHOW_BINLOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ DBUG_VOID_RETURN; #else { @@ -1733,7 +1770,7 @@ mysql_execute_command(void) #endif case SQLCOM_SHOW_CREATE: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ DBUG_VOID_RETURN; #else { @@ -1805,7 +1842,7 @@ mysql_execute_command(void) goto error; if (select_lex->item_list.elements != lex->value_list.elements) { - send_error(&thd->net,ER_WRONG_VALUE_COUNT); + send_error(thd,ER_WRONG_VALUE_COUNT); DBUG_VOID_RETURN; } if (select_lex->table_list.elements == 1) @@ -1844,7 +1881,7 @@ mysql_execute_command(void) msg="LIMIT"; if (msg) { - net_printf(&thd->net, ER_WRONG_USAGE, "UPDATE", msg); + net_printf(thd, ER_WRONG_USAGE, "UPDATE", msg); res= 1; break; } @@ -1934,7 +1971,7 @@ mysql_execute_command(void) if (check_dup(tables->db, tables->real_name, tables->next)) { - net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name); + net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name); DBUG_VOID_RETURN; } tables->lock_type=TL_WRITE; // update first table @@ -1966,7 +2003,7 @@ mysql_execute_command(void) */ if (thd->locked_tables || thd->active_transaction()) { - send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION,NullS); + send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION,NullS); goto error; } res=mysql_truncate(thd,tables); @@ -2003,7 +2040,7 @@ mysql_execute_command(void) goto error; if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where) { - send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); + send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); goto error; } for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) @@ -2019,7 +2056,7 @@ mysql_execute_command(void) } if (!walk) { - net_printf(&thd->net,ER_NONUNIQ_TABLE,auxi->real_name); + net_printf(thd,ER_NONUNIQ_TABLE,auxi->real_name); goto error; } auxi->lock_type=walk->lock_type=TL_WRITE; @@ -2078,7 +2115,7 @@ mysql_execute_command(void) break; case SQLCOM_SHOW_DATABASES: #if defined(DONT_ALLOW_SHOW_COMMANDS) - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ DBUG_VOID_RETURN; #else if ((specialflag & SPECIAL_SKIP_SHOW_DB) && @@ -2112,7 +2149,7 @@ mysql_execute_command(void) break; case SQLCOM_SHOW_LOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ DBUG_VOID_RETURN; #else { @@ -2125,20 +2162,20 @@ mysql_execute_command(void) case SQLCOM_SHOW_TABLES: /* FALL THROUGH */ #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ DBUG_VOID_RETURN; #else { char *db=select_lex->db ? select_lex->db : thd->db; if (!db) { - send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ + send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ goto error; /* purecov: inspected */ } remove_escape(db); // Fix escaped '_' if (check_db_name(db)) { - net_printf(&thd->net,ER_WRONG_DB_NAME, db); + net_printf(thd,ER_WRONG_DB_NAME, db); goto error; } if (check_access(thd,SELECT_ACL,db,&thd->col_access)) @@ -2161,14 +2198,14 @@ mysql_execute_command(void) break; case SQLCOM_SHOW_FIELDS: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ DBUG_VOID_RETURN; #else { char *db=tables->db; if (!*db) { - send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ + send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ goto error; /* purecov: inspected */ } remove_escape(db); // Fix escaped '_' @@ -2186,14 +2223,14 @@ mysql_execute_command(void) #endif case SQLCOM_SHOW_KEYS: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ DBUG_VOID_RETURN; #else { char *db=tables->db; if (!db) { - send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ + send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ goto error; /* purecov: inspected */ } remove_escape(db); // Fix escaped '_' @@ -2227,7 +2264,7 @@ mysql_execute_command(void) if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) || ! opt_local_infile) { - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); + send_error(thd,ER_NOT_ALLOWED_COMMAND); goto error; } if (check_access(thd,privilege,tables->db,&tables->grant.privilege) || @@ -2242,7 +2279,7 @@ mysql_execute_command(void) if (sql_set_variables(thd, &lex->var_list)) res= -1; else - send_ok(&thd->net); + send_ok(thd); break; case SQLCOM_UNLOCK_TABLES: if (thd->locked_tables) @@ -2257,7 +2294,7 @@ mysql_execute_command(void) } if (thd->global_read_lock) unlock_global_read_lock(thd); - send_ok(&thd->net); + send_ok(thd); break; case SQLCOM_LOCK_TABLES: if (thd->locked_tables) @@ -2276,7 +2313,7 @@ mysql_execute_command(void) { thd->locked_tables=thd->lock; thd->lock=0; - send_ok(&thd->net); + send_ok(thd); } else thd->options&= ~(ulong) (OPTION_TABLE_LOCK); @@ -2286,11 +2323,11 @@ mysql_execute_command(void) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); + net_printf(thd,ER_WRONG_DB_NAME, lex->name); break; } if (lower_case_table_names) - casedn_str(lex->name); + my_casedn_str(system_charset_info, lex->name); if (check_access(thd,CREATE_ACL,lex->name,0,1)) break; res=mysql_create_db(thd,lex->name,&lex->create_info,0); @@ -2300,16 +2337,16 @@ mysql_execute_command(void) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); + net_printf(thd,ER_WRONG_DB_NAME, lex->name); break; } if (lower_case_table_names) - casedn_str(lex->name); + my_casedn_str(system_charset_info, lex->name); if (check_access(thd,DROP_ACL,lex->name,0,1)) break; if (thd->locked_tables || thd->active_transaction()) { - send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); + send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); goto error; } res=mysql_rm_db(thd,lex->name,lex->drop_if_exists,0); @@ -2319,31 +2356,31 @@ mysql_execute_command(void) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); + net_printf(thd,ER_WRONG_DB_NAME, lex->name); break; } if (check_access(thd,ALTER_ACL,lex->name,0,1)) break; if (thd->locked_tables || thd->active_transaction()) { - send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); + send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); goto error; } - res=mysql_alter_db(thd,lex->name,&lex->create_info,0); + res=mysql_alter_db(thd,lex->name,&lex->create_info); break; } case SQLCOM_SHOW_CREATE_DB: { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); + net_printf(thd,ER_WRONG_DB_NAME, lex->name); break; } if (check_access(thd,DROP_ACL,lex->name,0,1)) break; if (thd->locked_tables || thd->active_transaction()) { - send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION); + send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); goto error; } res=mysqld_show_create_db(thd,lex->name); @@ -2354,7 +2391,7 @@ mysql_execute_command(void) break; #ifdef HAVE_DLOPEN if (!(res = mysql_create_function(thd,&lex->udf))) - send_ok(&thd->net); + send_ok(thd); #else res= -1; #endif @@ -2364,7 +2401,7 @@ mysql_execute_command(void) break; #ifdef HAVE_DLOPEN if (!(res = mysql_drop_function(thd,lex->udf.name))) - send_ok(&thd->net); + send_ok(thd); #else res= -1; #endif @@ -2424,7 +2461,7 @@ mysql_execute_command(void) { if (lex->columns.elements) { - send_error(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); + send_error(thd,ER_ILLEGAL_GRANT_FOR_TABLE); res=1; } else @@ -2454,9 +2491,9 @@ mysql_execute_command(void) if (check_global_access(thd,RELOAD_ACL) || check_db_used(thd, tables)) goto error; if (reload_acl_and_cache(thd, lex->type, tables)) - send_error(&thd->net,0); + send_error(thd,0); else - send_ok(&thd->net); + send_ok(thd); break; case SQLCOM_KILL: kill_one_thread(thd,lex->thread_id); @@ -2506,7 +2543,7 @@ mysql_execute_command(void) thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) | OPTION_BEGIN); thd->server_status|= SERVER_STATUS_IN_TRANS; - send_ok(&thd->net); + send_ok(thd); } break; case SQLCOM_COMMIT: @@ -2520,7 +2557,7 @@ mysql_execute_command(void) thd->server_status&= ~SERVER_STATUS_IN_TRANS; if (!ha_commit(thd)) { - send_ok(&thd->net); + send_ok(thd); } else res= -1; @@ -2531,21 +2568,21 @@ mysql_execute_command(void) if (!ha_rollback(thd)) { if (thd->options & OPTION_STATUS_NO_TRANS_UPDATE) - send_warning(&thd->net,ER_WARNING_NOT_COMPLETE_ROLLBACK,0); + send_warning(thd,ER_WARNING_NOT_COMPLETE_ROLLBACK,0); else - send_ok(&thd->net); + send_ok(thd); } else res= -1; thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); break; default: /* Impossible */ - send_ok(&thd->net); + send_ok(thd); break; } thd->proc_info="query end"; // QQ if (res < 0) - send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0); + send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); error: DBUG_VOID_RETURN; @@ -2578,7 +2615,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if ((!db || !db[0]) && !thd->db && !dont_check_global_grants) { if (!no_errors) - send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */ + send_error(thd,ER_NO_DB_ERROR); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -2591,7 +2628,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, ! db && dont_check_global_grants) { // We can never grant this if (!no_errors) - net_printf(&thd->net,ER_ACCESS_DENIED_ERROR, + net_printf(thd,ER_ACCESS_DENIED_ERROR, thd->priv_user, thd->host_or_ip, thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */ @@ -2616,7 +2653,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, !(want_access & ~TABLE_ACLS))) DBUG_RETURN(FALSE); /* Ok */ if (!no_errors) - net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, + net_printf(thd,ER_DBACCESS_DENIED_ERROR, thd->priv_user, thd->host_or_ip, db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */ @@ -2632,7 +2669,7 @@ bool check_global_access(THD *thd, ulong want_access) if ((thd->master_access & want_access) == want_access) return 0; get_privilege_desc(command, sizeof(command), want_access); - net_printf(&thd->net,ER_SPECIFIC_ACCESS_DENIED_ERROR, + net_printf(thd,ER_SPECIFIC_ACCESS_DENIED_ERROR, command); return 1; } @@ -2687,7 +2724,7 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables) { if (!(tables->db=thd->db)) { - send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */ + send_error(thd,ER_NO_DB_ERROR); /* purecov: tested */ return TRUE; /* purecov: tested */ } } @@ -2710,7 +2747,7 @@ static bool check_merge_table_access(THD *thd, char *db, tmp->db=db; else if (strcmp(tmp->db,db)) { - send_error(&thd->net,ER_UNION_TABLES_IN_DIFFERENT_DIR); + send_error(thd,ER_UNION_TABLES_IN_DIFFERENT_DIR); return 1; } } @@ -2799,11 +2836,10 @@ mysql_init_query(THD *thd) thd->lex.olap=0; thd->lex.select->olap= UNSPECIFIED_OLAP_TYPE; thd->fatal_error= 0; // Safety + thd->total_warn_count=0; // Warnings for this query thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; thd->sent_row_count= thd->examined_row_count= 0; thd->safe_to_cache_query= 1; - thd->param_count=0; - thd->prepare_command=false; thd->lex.param_list.empty(); DBUG_VOID_RETURN; } @@ -2850,6 +2886,33 @@ mysql_new_select(LEX *lex, bool move_down) return 0; } +/* + Create a select to return the same output as 'SELECT @@var_name'. + + SYNOPSIS + create_select_for_variable() + var_name Variable name + + DESCRIPTION + Used for SHOW COUNT(*) [ WARNINGS | ERROR] + + This will crash with a core dump if the variable doesn't exists +*/ + +void create_select_for_variable(const char *var_name) +{ + LEX *lex; + LEX_STRING tmp; + DBUG_ENTER("create_select_for_variable"); + lex= current_lex; + mysql_init_select(lex); + lex->sql_command= SQLCOM_SELECT; + tmp.str= (char*) var_name; + tmp.length=strlen(var_name); + add_item_to_list(get_system_var(OPT_SESSION, tmp)); + DBUG_VOID_RETURN; +} + void mysql_init_multi_delete(LEX *lex) { @@ -2881,7 +2944,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) } else { - mysql_execute_command(); + mysql_execute_command(thd); query_cache_end_of_result(&thd->net); } } @@ -2892,7 +2955,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) query_cache_abort(&thd->net); } thd->proc_info="freeing items"; - free_items(thd); /* Free strings used by items */ + free_items(thd->free_list); /* Free strings used by items */ lex_end(lex); } DBUG_VOID_RETURN; @@ -2928,7 +2991,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, if (strlen(field_name) > NAME_LEN) { - net_printf(&thd->net, ER_TOO_LONG_IDENT, field_name); /* purecov: inspected */ + net_printf(thd, ER_TOO_LONG_IDENT, field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } if (type_modifier & PRI_KEY_FLAG) @@ -2951,7 +3014,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG) { - net_printf(&thd->net,ER_INVALID_DEFAULT,field_name); + net_printf(thd,ER_INVALID_DEFAULT,field_name); DBUG_RETURN(1); } default_value=0; @@ -3037,7 +3100,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, res=default_value->val_str(&str); if (res->length()) { - net_printf(&thd->net,ER_BLOB_CANT_HAVE_DEFAULT,field_name); /* purecov: inspected */ + net_printf(thd,ER_BLOB_CANT_HAVE_DEFAULT,field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } new_field->def=0; @@ -3057,7 +3120,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, uint tmp_length=new_field->length; if (tmp_length > PRECISION_FOR_DOUBLE) { - net_printf(&thd->net,ER_WRONG_FIELD_SPEC,field_name); + net_printf(thd,ER_WRONG_FIELD_SPEC,field_name); DBUG_RETURN(1); } else if (tmp_length > PRECISION_FOR_FLOAT) @@ -3111,7 +3174,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, { if (interval->count > sizeof(longlong)*8) { - net_printf(&thd->net,ER_TOO_BIG_SET,field_name); /* purecov: inspected */ + net_printf(thd,ER_TOO_BIG_SET,field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } new_field->pack_length=(interval->count+7)/8; @@ -3133,7 +3196,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, (void) find_set(interval,res->ptr(),res->length()); if (thd->cuted_fields) { - net_printf(&thd->net,ER_INVALID_DEFAULT,field_name); + net_printf(thd,ER_INVALID_DEFAULT,field_name); DBUG_RETURN(1); } } @@ -3156,7 +3219,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, res=default_value->val_str(&str); if (!find_enum(interval,res->ptr(),res->length())) { - net_printf(&thd->net,ER_INVALID_DEFAULT,field_name); + net_printf(thd,ER_INVALID_DEFAULT,field_name); DBUG_RETURN(1); } } @@ -3168,14 +3231,14 @@ bool add_field_to_list(char *field_name, enum_field_types type, (!new_field->length && !(new_field->flags & BLOB_FLAG) && type != FIELD_TYPE_STRING && type != FIELD_TYPE_VAR_STRING)) { - net_printf(&thd->net,ER_TOO_BIG_FIELDLENGTH,field_name, + net_printf(thd,ER_TOO_BIG_FIELDLENGTH,field_name, MAX_FIELD_WIDTH-1); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } type_modifier&= AUTO_INCREMENT_FLAG; if ((~allowed_type_modifier) & type_modifier) { - net_printf(&thd->net,ER_WRONG_FIELD_SPEC,field_name); + net_printf(thd,ER_WRONG_FIELD_SPEC,field_name); DBUG_RETURN(1); } if (!new_field->pack_length) @@ -3286,7 +3349,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, (table->table.length && check_table_name(table->table.str,table->table.length)) || table->db.str && check_db_name(table->db.str)) { - net_printf(&thd->net,ER_WRONG_TABLE_NAME,table->table.str); + net_printf(thd,ER_WRONG_TABLE_NAME,table->table.str); DBUG_RETURN(0); } @@ -3308,7 +3371,8 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, } else { - ptr->db= (char*) ""; + /* The following can't be "" as we may do 'casedn_str()' on it */ + ptr->db= empty_c_string; ptr->db_length= 0; } @@ -3339,7 +3403,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, { if (!strcmp(alias_str,tables->name) && !strcmp(ptr->db, tables->db)) { - net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */ + net_printf(thd,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */ DBUG_RETURN(0); /* purecov: tested */ } } @@ -3487,9 +3551,9 @@ void kill_one_thread(THD *thd, ulong id) } if (!error) - send_ok(&thd->net); + send_ok(thd); else - net_printf(&thd->net,error,id); + net_printf(thd,error,id); } /* Clear most status variables */ @@ -3552,7 +3616,7 @@ bool check_simple_select() char command[80]; strmake(command, thd->lex.yylval->symbol.str, min(thd->lex.yylval->symbol.length, sizeof(command)-1)); - net_printf(&thd->net, ER_CANT_USE_OPTION_HERE, command); + net_printf(thd, ER_CANT_USE_OPTION_HERE, command); return 1; } return 0; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d41aca21fb8..05b3f360caa 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -25,7 +25,7 @@ Prepare: store its information list lex->param_list - Without executing the query, return back to client the total number of parameters along with result-set metadata information - (if any ) + (if any) Prepare-execute: @@ -38,46 +38,132 @@ Prepare-execute: to client Long data handling: - - Server gets the long data in pieces with command type 'COM_LONG_DATA'. - The packet recieved will have the format as: - [type_spec_exists][type][length][data] + [COM_LONG_DATA:1][parameter_number:2][type:2][data] - Checks if the type is specified by client, and if yes reads the type, and stores the data in that format. - - If length == MYSQL_END_OF_DATA, then server sets up the data read ended. + - It's up to the client to check for read data ended. The server doesn't + care. + ***********************************************************************/ #include "mysql_priv.h" #include "sql_acl.h" #include // for DEBUG_ASSERT() -#include // for isspace() +#include // for isspace() -/**************************************************************************/ extern int yyparse(void); static ulong get_param_length(uchar **packet); static uint get_buffer_type(uchar **packet); static bool param_is_null(uchar **packet); static bool setup_param_fields(THD *thd,List ¶ms); -static uchar* setup_param_field(Item_param *item_param, uchar *pos, uint buffer_type); +static uchar* setup_param_field(Item_param *item_param, uchar *pos, + uint buffer_type); static void setup_longdata_field(Item_param *item_param, uchar *pos); static bool setup_longdata(THD *thd,List ¶ms); -static void send_prepare_results(THD *thd); -static void mysql_parse_prepare_query(THD *thd,char *packet,uint length); -static bool mysql_send_insert_fields(THD *thd,TABLE_LIST *table_list, +static bool send_prepare_results(PREP_STMT *stmt); +static bool parse_prepare_query(PREP_STMT *stmt, char *packet, uint length); +static bool mysql_send_insert_fields(PREP_STMT *stmt, TABLE_LIST *table_list, List &fields, - List &values_list,thr_lock_type lock_type); -static bool mysql_test_insert_fields(THD *thd,TABLE_LIST *table_list, + List &values_list, + thr_lock_type lock_type); +static bool mysql_test_insert_fields(PREP_STMT *stmt, TABLE_LIST *table_list, List &fields, - List &values_list,thr_lock_type lock_type); -static bool mysql_test_upd_fields(THD *thd,TABLE_LIST *table_list, + List &values_list, + thr_lock_type lock_type); +static bool mysql_test_upd_fields(PREP_STMT *stmt, TABLE_LIST *table_list, List &fields, List &values, COND *conds,thr_lock_type lock_type); -static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables, - List &fields, List &values, - COND *conds, ORDER *order, ORDER *group, - Item *having,thr_lock_type lock_type); -extern const char *any_db; -/**************************************************************************/ +static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, + List &fields, List &values, + COND *conds, ORDER *order, ORDER *group, + Item *having,thr_lock_type lock_type); + + +/* + Find prepared statement in thd + + SYNOPSIS + find_prepared_statement() + thd Thread handler + stmt_id Statement id server specified to the client on prepare + + RETURN VALUES + 0 error. In this case the error is sent with my_error() + ptr Pointer to statement +*/ + +static PREP_STMT *find_prepared_statement(THD *thd, ulong stmt_id, + const char *when) +{ + PREP_STMT *stmt; + DBUG_ENTER("find_prepared_statement"); + DBUG_PRINT("enter",("stmt_id: %d", stmt_id)); + + if (thd->last_prepared_stmt && thd->last_prepared_stmt->stmt_id == stmt_id) + DBUG_RETURN(thd->last_prepared_stmt); + if ((stmt= (PREP_STMT*) tree_search(&thd->prepared_statements, &stmt_id, + (void*) 0))) + DBUG_RETURN (thd->last_prepared_stmt= stmt); + my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), stmt_id, when); + DBUG_RETURN(0); +} + +/* + Compare two prepared statements; Used to find a prepared statement +*/ + +int compare_prep_stmt(PREP_STMT *a, PREP_STMT *b, void *not_used) +{ + return (a->stmt_id < b->stmt_id) ? -1 : (a->stmt_id == b->stmt_id) ? 0 : 1; +} + + +/* + Free prepared statement. + + SYNOPSIS + standard tree_element_free function. + + DESCRIPTION + We don't have to free the stmt itself as this was stored in the tree + and will be freed when the node is deleted +*/ + +void free_prep_stmt(PREP_STMT *stmt, TREE_FREE mode, void *not_used) +{ + free_root(&stmt->mem_root, MYF(0)); + free_items(stmt->free_list); +} + +/* + Send prepared stmt info to client after prepare +*/ + +bool send_prep_stmt(PREP_STMT *stmt, uint columns) +{ + char buff[8]; + int4store(buff, stmt->stmt_id); + int2store(buff+4, columns); + int2store(buff+6, stmt->param_count); + return my_net_write(&stmt->thd->net, buff, sizeof(buff)); +} + +/* + Send information about all item parameters + + TODO: Not yet ready +*/ + +bool send_item_params(PREP_STMT *stmt) +{ + char buff[1]; + buff[0]=0; + return my_net_write(&stmt->thd->net, buff, sizeof(buff)); +} + + /* Read the buffer type, this happens only first time @@ -90,8 +176,13 @@ static uint get_buffer_type(uchar **packet) return (uint) uint2korr(pos); } + /* Check for NULL param data + + RETURN VALUES + 0 Value was not NULL + 1 Value was NULL */ static bool param_is_null(uchar **packet) @@ -144,8 +235,7 @@ static uchar* setup_param_field(Item_param *item_param, item_param->set_null(); return(pos); } - switch (buffer_type) - { + switch (buffer_type) { case FIELD_TYPE_TINY: item_param->set_int((longlong)(*pos)); pos += 1; @@ -169,7 +259,7 @@ static uchar* setup_param_field(Item_param *item_param, case FIELD_TYPE_FLOAT: float data; float4get(data,pos); - item_param->set_double(data); + item_param->set_double((double) data); pos += 4; break; case FIELD_TYPE_DOUBLE: @@ -193,20 +283,19 @@ static uchar* setup_param_field(Item_param *item_param, from client .. */ -static bool setup_param_fields(THD *thd, List ¶ms) +static bool setup_param_fields(THD *thd, PREP_STMT *stmt) { - reg2 Item_param *item_param; - List_iterator it(params); - NET *net = &thd->net; DBUG_ENTER("setup_param_fields"); - +#ifdef READY_TO_BE_USED + Item_param *item_param; ulong param_count=0; - uchar *pos=(uchar*)net->read_pos+1;// skip command type - - if(*pos++) // No types supplied, read only param data + uchar *pos=(uchar*) thd->net.read_pos+1;// skip command type + + + if (*pos++) // No types supplied, read only param data { while ((item_param=(Item_param *)it++) && - (param_count++ < thd->param_count)) + (param_count++ < stmt->param_count)) { if (item_param->long_data_supplied) continue; @@ -224,68 +313,15 @@ static bool setup_param_fields(THD *thd, List ¶ms) continue; if (!(pos=setup_param_field(item_param,pos, - item_param->buffer_type=(enum_field_types)get_buffer_type(&pos)))) + item_param->buffer_type= + (enum_field_types) get_buffer_type(&pos)))) DBUG_RETURN(1); } } +#endif DBUG_RETURN(0); } -/* - Buffer the long data and update the flags -*/ - -static void setup_longdata_field(Item_param *item_param, uchar *pos) -{ - ulong len; - - if (!*pos++) - item_param->buffer_type=(enum_field_types)get_buffer_type(&pos); - - if (*pos == MYSQL_LONG_DATA_END) - item_param->set_long_end(); - - else - { - len = get_param_length(&pos); - item_param->set_longdata((const char *)pos, len); - } -} - -/* - Store the long data from client in pieces -*/ - -static bool setup_longdata(THD *thd, List ¶ms) -{ - NET *net=&thd->net; - List_iterator it(params); - DBUG_ENTER("setup_longdata"); - - uchar *pos=(uchar*)net->read_pos+1;// skip command type at first position - ulong param_number = get_param_length(&pos); - Item_param *item_param = thd->current_param; - - if (thd->current_param_number != param_number) - { - thd->current_param_number = param_number; - while (param_number--) /* TODO: - Change this loop by either having operator '+' - overloaded to point to desired 'item' or - add another memeber in list as 'goto' with - location count as parameter number, but what - is the best way to traverse ? - */ - { - it++; - } - thd->current_param = item_param = (Item_param *)it++; - } - setup_longdata_field(item_param,pos); - DBUG_RETURN(0); -} - - /* Validates insert fields @@ -337,16 +373,15 @@ static int check_prepare_fields(THD *thd,TABLE *table, List &fields, Validate the following information for INSERT statement: - field existance - fields count - - If there is no column list spec exists, then update the field_list - with all columns from the table, and send fields info back to client */ -static bool mysql_test_insert_fields(THD *thd, TABLE_LIST *table_list, +static bool mysql_test_insert_fields(PREP_STMT *stmt, + TABLE_LIST *table_list, List &fields, List &values_list, thr_lock_type lock_type) { + THD *thd= stmt->thd; TABLE *table; List_iterator_fast its(values_list); List_item *values; @@ -358,7 +393,7 @@ static bool mysql_test_insert_fields(THD *thd, TABLE_LIST *table_list, if ((values= its++)) { uint value_count; - ulong counter=0; + ulong counter= 0; if (check_insert_fields(thd,table,fields,*values,1)) DBUG_RETURN(1); @@ -366,35 +401,20 @@ static bool mysql_test_insert_fields(THD *thd, TABLE_LIST *table_list, value_count= values->elements; its.rewind(); - while ((values = its++)) + while ((values= its++)) { counter++; if (values->elements != value_count) { my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),counter); + MYF(0), counter); DBUG_RETURN(1); } } - if (fields.elements == 0) - { - /* No field listing, so setup all fields */ - List all_fields; - Field **ptr,*field; - for (ptr=table->field; (field= *ptr) ; ptr++) - { - all_fields.push_back(new Item_field(table->table_cache_key, - table->real_name, - field->field_name)); - } - if ((setup_fields(thd,table_list,all_fields,1,0,0) || - send_fields(thd,all_fields,1))) - DBUG_RETURN(1); - } - else if (send_fields(thd,fields,1)) - DBUG_RETURN(1); } + if (send_prep_stmt(stmt, 0) || send_item_params(stmt)) + DBUG_RETURN(1); DBUG_RETURN(0); } @@ -403,15 +423,16 @@ static bool mysql_test_insert_fields(THD *thd, TABLE_LIST *table_list, Validate the following information UPDATE - set and where clause DELETE - where clause - And send update-set cluase column list fields info - back to client. For DELETE, just validate where cluase + And send update-set clause column list fields info + back to client. For DELETE, just validate where clause and return no fields information back to client. */ -static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list, +static bool mysql_test_upd_fields(PREP_STMT *stmt, TABLE_LIST *table_list, List &fields, List &values, COND *conds, thr_lock_type lock_type) { + THD *thd= stmt->thd; TABLE *table; DBUG_ENTER("mysql_test_upd_fields"); @@ -426,9 +447,8 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list, Currently return only column list info only, and we are not sending any info on where clause. */ - if (fields.elements && send_fields(thd,fields,1)) + if (send_prep_stmt(stmt, 0) || send_item_params(stmt)) DBUG_RETURN(1); - DBUG_RETURN(0); } @@ -437,7 +457,7 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list, SELECT - column list - where clause - - orderr clause + - order clause - having clause - group by clause - if no column spec i.e. '*', then setup all fields @@ -445,13 +465,14 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list, And send column list fields info back to client. */ -static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables, +static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, List &fields, List &values, COND *conds, ORDER *order, ORDER *group, Item *having, thr_lock_type lock_type) { TABLE *table; bool hidden_group_fields; + THD *thd= stmt->thd; List all_fields(fields); DBUG_ENTER("mysql_test_select_fields"); @@ -482,13 +503,15 @@ static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables, Currently return only column list info only, and we are not sending any info on where clause. */ - if (fields.elements && send_fields(thd,fields,1)) + if (send_prep_stmt(stmt, fields.elements) || + send_fields(thd,fields,0) || send_item_params(stmt)) DBUG_RETURN(1); DBUG_RETURN(0); } + /* - Check the access privileges + Check the access privileges */ static bool check_prepare_access(THD *thd, TABLE_LIST *tables, @@ -505,42 +528,47 @@ static bool check_prepare_access(THD *thd, TABLE_LIST *tables, Send the prepare query results back to client */ -static void send_prepare_results(THD *thd) +static bool send_prepare_results(PREP_STMT *stmt) { - DBUG_ENTER("send_prepare_results"); + THD *thd= stmt->thd; + LEX *lex= &thd->lex; enum enum_sql_command sql_command = thd->lex.sql_command; - - DBUG_PRINT("enter",("command :%d, param_count :%ld", - sql_command,thd->param_count)); + DBUG_ENTER("send_prepare_results"); + DBUG_PRINT("enter",("command: %d, param_count: %ld", + sql_command, lex->param_count)); - LEX *lex=&thd->lex; + /* Setup prepared stmt */ + stmt->param_count= lex->param_count; + stmt->free_list= thd->free_list; // Save items used in stmt + thd->free_list= 0; + SELECT_LEX *select_lex = lex->select; TABLE_LIST *tables=(TABLE_LIST*) select_lex->table_list.first; - switch(sql_command) { + switch (sql_command) { case SQLCOM_INSERT: - if (mysql_test_insert_fields(thd,tables, lex->field_list, + if (mysql_test_insert_fields(stmt, tables, lex->field_list, lex->many_values, lex->lock_option)) goto abort; break; case SQLCOM_UPDATE: - if (mysql_test_upd_fields(thd,tables, select_lex->item_list, + if (mysql_test_upd_fields(stmt, tables, select_lex->item_list, lex->value_list, select_lex->where, lex->lock_option)) goto abort; break; case SQLCOM_DELETE: - if (mysql_test_upd_fields(thd,tables, select_lex->item_list, + if (mysql_test_upd_fields(stmt, tables, select_lex->item_list, lex->value_list, select_lex->where, lex->lock_option)) goto abort; break; case SQLCOM_SELECT: - if (mysql_test_select_fields(thd,tables, select_lex->item_list, + if (mysql_test_select_fields(stmt, tables, select_lex->item_list, lex->value_list, select_lex->where, (ORDER*) select_lex->order_list.first, (ORDER*) select_lex->group_list.first, @@ -556,42 +584,37 @@ static void send_prepare_results(THD *thd) */ } } - send_ok(&thd->net,thd->param_count,0); - DBUG_VOID_RETURN; + DBUG_RETURN(0); abort: - send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0); - DBUG_VOID_RETURN; + send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); + DBUG_RETURN(1); } /* Parse the prepare query */ -static void mysql_parse_prepare_query(THD *thd, char *packet, uint length) +static bool parse_prepare_query(PREP_STMT *stmt, + char *packet, uint length) { - DBUG_ENTER("mysql_parse_prepare_query"); + bool error= 1; + THD *thd= stmt->thd; + DBUG_ENTER("parse_prepare_query"); mysql_log.write(thd,COM_PREPARE,"%s",packet); mysql_init_query(thd); thd->prepare_command=true; + thd->safe_to_cache_query= 0; - if (query_cache.send_result_to_client(thd, packet, length) <= 0) - { - LEX *lex=lex_start(thd, (uchar*)packet, length); - - if (!yyparse() && !thd->fatal_error) - { - send_prepare_results(thd); - query_cache_end_of_result(&thd->net); - } - else - query_cache_abort(&thd->net); - lex_end(lex); - } - DBUG_VOID_RETURN; + LEX *lex=lex_start(thd, (uchar*) packet, length); + if (!yyparse() && !thd->fatal_error) + error= send_prepare_results(stmt); + lex_end(lex); + DBUG_RETURN(error); } + /* Parse the query and send the total number of parameters and resultset metadata information back to client (if any), @@ -606,52 +629,36 @@ static void mysql_parse_prepare_query(THD *thd, char *packet, uint length) items. */ -void mysql_com_prepare(THD *thd, char *packet, uint packet_length) +bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length) { MEM_ROOT thd_root = thd->mem_root; - DBUG_ENTER("mysql_com_prepare"); - - packet_length--; - - while (isspace(packet[0]) && packet_length > 0) - { - packet++; - packet_length--; - } - char *pos=packet+packet_length; - while (packet_length > 0 && (pos[-1] == ';' || isspace(pos[-1]))) - { - pos--; - packet_length--; - } - /* - Have the prepare items to have a connection level scope or - till next prepare statement by doing all allocations using - connection level memory allocator 'con_root' from THD. - */ - free_root(&thd->con_root,MYF(0)); - init_sql_alloc(&thd->con_root,8192,8192); - thd->mem_root = thd->con_root; - - if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), - packet_length, - thd->db_length+2))) - DBUG_VOID_RETURN; - thd->query[packet_length]=0; - thd->packet.shrink(net_buffer_length); - thd->query_length = packet_length; + PREP_STMT stmt; + bool error; + DBUG_ENTER("mysql_stmt_prepare"); - if (!(specialflag & SPECIAL_NO_PRIOR)) - my_pthread_setprio(pthread_self(),QUERY_PRIOR); - - mysql_parse_prepare_query(thd,thd->query,packet_length); + bzero((char*) &stmt, sizeof(stmt)); + stmt.thd= thd; + stmt.stmt_id= ++thd->current_stmt_id; + init_sql_alloc(&stmt.mem_root, 8192, 8192); + + thd->mem_root= stmt.mem_root; + if (alloc_query(thd, packet, packet_length)) + goto err; + if (parse_prepare_query(&stmt, thd->query, thd->query_length)) + goto err; if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),WAIT_PRIOR); - thd->mem_root = thd_root; // restore main mem_root - DBUG_PRINT("exit",("prepare query ready")); - DBUG_VOID_RETURN; + stmt.mem_root= thd->mem_root; + thd->mem_root= thd_root; // restore main mem_root + DBUG_RETURN(0); + +err: + stmt.mem_root= thd->mem_root; + free_prep_stmt(&stmt, free_free, (void*) 0); + thd->mem_root = thd_root; // restore main mem_root + DBUG_RETURN(1); } @@ -663,47 +670,166 @@ void mysql_com_prepare(THD *thd, char *packet, uint packet_length) execute the query */ -void mysql_com_execute(THD *thd) +void mysql_stmt_execute(THD *thd, char *packet) { - MEM_ROOT thd_root=thd->mem_root; - DBUG_ENTER("mysql_com_execute"); - DBUG_PRINT("enter", ("parameters : %ld", thd->param_count)); + ulong stmt_id= uint4korr(packet); + PREP_STMT *stmt; + DBUG_ENTER("mysql_stmt_execute"); - thd->mem_root = thd->con_root; - if (thd->param_count && setup_param_fields(thd, thd->lex.param_list)) + if (!(stmt=find_prepared_statement(thd, stmt_id, "execute"))) + { + send_error(thd); + DBUG_VOID_RETURN; + } + + /* Check if we got an error when sending long data */ + if (stmt->error_in_prepare) + { + send_error(thd); + DBUG_VOID_RETURN; + } + + if (stmt->param_count && setup_param_fields(thd, stmt)) DBUG_VOID_RETURN; - + + MEM_ROOT thd_root= thd->mem_root; + thd->mem_root = thd->con_root; if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); - /* TODO: + /* + TODO: Also, have checks on basic executions such as mysql_insert(), mysql_delete(), mysql_update() and mysql_select() to not to have re-check on setup_* and other things .. */ - mysql_execute_command(); + mysql_execute_command(thd); if (!(specialflag & SPECIAL_NO_PRIOR)) - my_pthread_setprio(pthread_self(),WAIT_PRIOR); + my_pthread_setprio(pthread_self(), WAIT_PRIOR); - thd->mem_root = (MEM_ROOT )thd_root; - DBUG_PRINT("exit",("prepare-execute done!")); + thd->mem_root= thd_root; DBUG_VOID_RETURN; } + /* - Long data in pieces from client + Reset a prepared statement + + SYNOPSIS + mysql_stmt_reset() + thd Thread handle + packet Packet with stmt handle + + DESCRIPTION + This function is useful when one gets an error after calling + mysql_stmt_getlongdata() and one wants to reset the handle + so that one can call execute again. */ -void mysql_com_longdata(THD *thd) +void mysql_stmt_reset(THD *thd, char *packet) { - DBUG_ENTER("mysql_com_execute"); + ulong stmt_id= uint4korr(packet); + PREP_STMT *stmt; + DBUG_ENTER("mysql_stmt_reset"); - if(thd->param_count && setup_longdata(thd,thd->lex.param_list)) - DBUG_VOID_RETURN; - - send_ok(&thd->net,0,0);// ok status to client - DBUG_PRINT("exit",("longdata-buffering done!")); + if (!(stmt=find_prepared_statement(thd, stmt_id, "close"))) + { + send_error(thd); + DBUG_VOID_RETURN; + } + + stmt->error_in_prepare=0; + Item_param *item= stmt->param, *end= item + stmt->param_count; + + /* Free long data if used */ + if (stmt->long_data_used) + { + stmt->long_data_used= 0; + for (; item < end ; item++) + item->reset(); + } + DBUG_VOID_RETURN; +} + + +/* + Delete a prepared statement from memory +*/ + +void mysql_stmt_close(THD *thd, char *packet) +{ + ulong stmt_id= uint4korr(packet); + PREP_STMT *stmt; + DBUG_ENTER("mysql_stmt_close"); + + if (!(stmt=find_prepared_statement(thd, stmt_id, "close"))) + { + send_error(thd); + DBUG_VOID_RETURN; + } + /* Will call free_prep_stmt() */ + tree_delete(&thd->prepared_statements, (void*) stmt, NULL); + thd->last_prepared_stmt=0; DBUG_VOID_RETURN; } + +/* + Long data in pieces from client + + SYNOPSIS + mysql_stmt_get_longdata() + thd Thread handle + pos String to append + packet_length Length of string + + DESCRIPTION + Get a part of a long data. + To make the protocol efficient, we are not sending any return packages + here. + If something goes wrong, then we will send the error on 'execute' + + We assume that the client takes care of checking that all parts are sent + to the server. (No checking that we get a 'end of column' in the server) +*/ + +void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length) +{ + PREP_STMT *stmt; + DBUG_ENTER("mysql_stmt_get_longdata"); + + /* The following should never happen */ + if (packet_length < 9) + { + my_error(ER_WRONG_ARGUMENTS, MYF(0), "get_longdata"); + DBUG_VOID_RETURN; + } + + pos++; // skip command type at first position + ulong stmt_id= uint4korr(pos); + uint param_number= uint2korr(pos+4); + uint param_type= uint2korr(pos+6); + pos+=8; // Point to data + + if (!(stmt=find_prepared_statement(thd, stmt_id, "get_longdata"))) + { + /* + There is a chance that the client will never see this as + it doesn't expect an answer from this call... + */ + send_error(thd); + DBUG_VOID_RETURN; + } + + if (param_number >= stmt->param_count) + { + stmt->error_in_prepare=1; + stmt->last_errno=ER_WRONG_ARGUMENTS; + sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), "get_longdata"); + DBUG_VOID_RETURN; + } + stmt->param[param_number].set_longdata(pos, packet_length-9); + stmt->long_data_used= 1; + DBUG_VOID_RETURN; +} diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 049690eb318..a9ab1776e19 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -97,7 +97,7 @@ end: Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } - send_ok(&thd->net); + send_ok(thd); } for (TABLE_LIST *table=table_list ; table != lock_table ; table=table->next) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 628b1775778..03b840aebf9 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -283,11 +283,11 @@ binlog purge"; break; if (errmsg) { - send_error(&thd->net, 0, errmsg); + send_error(thd, 0, errmsg); return 1; } else - send_ok(&thd->net); + send_ok(thd); return 0; } @@ -372,7 +372,7 @@ impossible position"; We need to start a packet with something other than 255 to distiquish it from error */ - packet->set("\0", 1); + packet->set("\0", 1, system_charset_info); // if we are at the start of the log if (pos == BIN_LOG_HEADER_SIZE) @@ -383,7 +383,7 @@ impossible position"; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; goto err; } - packet->set("\0", 1); + packet->set("\0", 1, system_charset_info); } while (!net->error && net->vio != 0 && !thd->killed) @@ -418,7 +418,7 @@ impossible position"; goto err; } } - packet->set("\0", 1); + packet->set("\0", 1, system_charset_info); } /* TODO: now that we are logging the offset, check to make sure @@ -538,7 +538,7 @@ Increase max_allowed_packet on master"; goto err; } } - packet->set("\0", 1); + packet->set("\0", 1, system_charset_info); /* No need to net_flush because we will get to flush later when we hit EOF pretty quick @@ -593,7 +593,7 @@ Increase max_allowed_packet on master"; end_io_cache(&log); (void)my_close(file, MYF(MY_WME)); - send_eof(&thd->net); + send_eof(thd); thd->proc_info = "waiting to finalize termination"; pthread_mutex_lock(&LOCK_thread_count); thd->current_linfo = 0; @@ -615,15 +615,15 @@ Increase max_allowed_packet on master"; pthread_mutex_unlock(&LOCK_thread_count); if (file >= 0) (void) my_close(file, MYF(MY_WME)); - send_error(&thd->net, my_errno, errmsg); + send_error(thd, my_errno, errmsg); DBUG_VOID_RETURN; } int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) { int slave_errno = 0; - if (!thd) thd = current_thd; - NET* net = &thd->net; + if (!thd) + thd = current_thd; int thread_mask; DBUG_ENTER("start_slave"); @@ -654,20 +654,21 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) if (slave_errno) { if (net_report) - send_error(net, slave_errno); + send_error(thd, slave_errno); DBUG_RETURN(1); } else if (net_report) - send_ok(net); + send_ok(thd); DBUG_RETURN(0); } + int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report ) { int slave_errno = 0; - if (!thd) thd = current_thd; - NET* net = &thd->net; + if (!thd) + thd = current_thd; if (check_access(thd, SUPER_ACL, any_db)) return 1; @@ -686,11 +687,11 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report ) if (slave_errno) { if (net_report) - send_error(net, slave_errno); + send_error(thd, slave_errno); return 1; } else if (net_report) - send_ok(net); + send_ok(thd); return 0; } @@ -779,7 +780,7 @@ int change_master(THD* thd, MASTER_INFO* mi) restart_thread_mask, 1 /*skip lock*/))) { - send_error(&thd->net,error); + send_error(thd,error); unlock_slave_threads(mi); DBUG_RETURN(1); } @@ -788,7 +789,7 @@ int change_master(THD* thd, MASTER_INFO* mi) // TODO: see if needs re-write if (init_master_info(mi, master_info_file, relay_log_info_file, 0)) { - send_error(&thd->net, 0, "Could not initialize master info"); + send_error(thd, 0, "Could not initialize master info"); unlock_slave_threads(mi); DBUG_RETURN(1); } @@ -850,7 +851,7 @@ int change_master(THD* thd, MASTER_INFO* mi) 0 /* not only reset, but also reinit */, &errmsg)) { - net_printf(&thd->net, 0, "Failed purging old relay logs: %s",errmsg); + net_printf(thd, 0, "Failed purging old relay logs: %s",errmsg); DBUG_RETURN(1); } } @@ -864,7 +865,7 @@ int change_master(THD* thd, MASTER_INFO* mi) 0 /*no data lock*/, &msg)) { - net_printf(&thd->net,0,"Failed initializing relay log position: %s",msg); + net_printf(thd,0,"Failed initializing relay log position: %s",msg); unlock_slave_threads(mi); DBUG_RETURN(1); } @@ -890,9 +891,9 @@ int change_master(THD* thd, MASTER_INFO* mi) unlock_slave_threads(mi); thd->proc_info = 0; if (error) - send_error(&thd->net,error); + send_error(thd,error); else - send_ok(&thd->net); + send_ok(thd); DBUG_RETURN(0); } @@ -1010,12 +1011,12 @@ err: if (errmsg) { - net_printf(&thd->net, ER_ERROR_WHEN_EXECUTING_COMMAND, + net_printf(thd, ER_ERROR_WHEN_EXECUTING_COMMAND, "SHOW BINLOG EVENTS", errmsg); DBUG_RETURN(1); } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } @@ -1045,7 +1046,7 @@ int show_binlog_info(THD* thd) if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length())) DBUG_RETURN(-1); } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } @@ -1098,11 +1099,11 @@ int show_binlogs(THD* thd) goto err; } mysql_bin_log.unlock_index(); - send_eof(net); + send_eof(thd); return 0; err_with_msg: - send_error(net, 0, errmsg); + send_error(thd, ER_UNKNOWN_ERROR, errmsg); err: mysql_bin_log.unlock_index(); return 1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8a64fbf968c..2b737ab65d7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -164,13 +164,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; cursor; cursor=cursor->next) - { - if (cursor->do_redirect) // False if CUBE/ROLLUP - { - cursor->do_redirect=false; - cursor->table= ((TABLE_LIST*) cursor->table)->table; - } - } + cursor->table= ((TABLE_LIST*) cursor->table)->table; } } @@ -226,7 +220,7 @@ int JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, ORDER *order_init, ORDER *group_init, Item *having_init, - ORDER *proc_param_init, SELECT_LEX *select_lex, + ORDER *proc_param_init, SELECT_LEX *select, SELECT_LEX_UNIT *unit) { DBUG_ENTER("JOIN::prepare"); @@ -237,7 +231,8 @@ JOIN::prepare(TABLE_LIST *tables_init, having= having_init; proc_param= proc_param_init; tables_list= tables_init; - select->join= this; + select_lex= select; + select_lex->join= this; union_part= (unit->first_select()->next_select() != 0); /* Check that all tables, fields, conds and order are ok */ @@ -679,16 +674,16 @@ JOIN::exec() result->send_fields(fields_list,1); if (!having || having->val_int()) { - if (do_send_rows && result->send_data(fields_list)) - { - result->send_error(0,NullS); /* purecov: inspected */ - error=1; - } - else - error=(int) result->send_eof(); + if (do_send_rows && result->send_data(fields_list)) + { + result->send_error(0,NullS); /* purecov: inspected */ + error=1; + } + else + error=(int) result->send_eof(); } else - error=(int) result->send_eof(); + error=(int) result->send_eof(); } delete procedure; DBUG_VOID_RETURN; @@ -696,6 +691,7 @@ JOIN::exec() if (zero_result_cause) { + error=0; (void) return_zero_rows(this, result, tables_list, fields_list, tmp_table_param.sum_func_count != 0 && !group_list, @@ -739,7 +735,7 @@ JOIN::exec() thd->proc_info="Creating tmp table"; tmp_table_param.hidden_field_count= (all_fields.elements- - fields.elements); + fields_list.elements); if (!(exec_tmp_table = create_tmp_table(thd, &tmp_table_param, all_fields, ((!simple_group && !procedure && @@ -996,6 +992,8 @@ JOIN::exec() int JOIN::cleanup(THD *thd) { + DBUG_ENTER("JOIN::cleanup"); + lock=0; // It's faster to unlock later join_free(this); if (exec_tmp_table) @@ -1006,6 +1004,7 @@ JOIN::cleanup(THD *thd) for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit(); unit != 0; unit= unit->next_unit()) + { for (SELECT_LEX *sl= unit->first_select(); sl != 0; sl= sl->next_select()) @@ -1018,7 +1017,8 @@ JOIN::cleanup(THD *thd) sl->join= 0; } } - return error; + } + DBUG_RETURN(error); } int @@ -1044,7 +1044,7 @@ mysql_select(THD *thd, TABLE_LIST *tables, List &fields, COND *conds, goto err; } - if(join->global_optimize()) + if (join->global_optimize()) goto err; join->exec(); @@ -7276,7 +7276,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, { KEY *key_info=table->key_info+ tab->ref.key; item_list.push_back(new Item_string(key_info->name, - strlen(key_info->name))); + strlen(key_info->name), + system_charset_info)); item_list.push_back(new Item_int((int32) tab->ref.key_length)); for (store_key **ref=tab->ref.key_copy ; *ref ; ref++) { @@ -7416,5 +7417,5 @@ static void describe_info(JOIN *join, const char *info) packet->length(0); net_store_data(packet,info); if (!my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) - send_eof(&thd->net); + send_eof(thd); } diff --git a/sql/sql_select.h b/sql/sql_select.h index f651f069c13..89dee2a4019 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -149,7 +149,8 @@ class TMP_TABLE_PARAM { } }; -class JOIN :public Sql_alloc{ +class JOIN :public Sql_alloc +{ public: JOIN_TAB *join_tab,**best_ref,**map2table; TABLE **table,**all_tables,*sort_by_table; @@ -222,6 +223,7 @@ class JOIN :public Sql_alloc{ !test(select_options & OPTION_FOUND_ROWS)), all_fields(fields), fields_list(fields), + error(0), select(0), exec_tmp_table(0), test_function_query(0), diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5899fe86024..fb9db707c16 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -76,6 +76,8 @@ mysqld_show_dbs(THD *thd,const char *wild) if (mysql_find_files(thd,&files,NullS,mysql_data_home,wild,1)) DBUG_RETURN(1); List_iterator_fast it(files); + + String *packet= &thd->packet; while ((file_name=it++)) { if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) || @@ -83,19 +85,20 @@ mysqld_show_dbs(THD *thd,const char *wild) thd->priv_user, file_name) || (grant_option && !check_grant_db(thd, file_name))) { - thd->packet.length(0); - net_store_data(&thd->packet, thd->variables.convert_set, file_name); - if (my_net_write(&thd->net, (char*) thd->packet.ptr(), - thd->packet.length())) + packet->length(0); + net_store_data(packet, thd->variables.convert_set, file_name); + if (my_net_write(&thd->net, (char*) packet->ptr(), + packet->length())) DBUG_RETURN(-1); } } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } + /*************************************************************************** -** List all open tables in a database + List all open tables in a database ***************************************************************************/ int mysqld_show_open_tables(THD *thd,const char *wild) @@ -116,19 +119,20 @@ int mysqld_show_open_tables(THD *thd,const char *wild) if (!(open_list=list_open_tables(thd,wild)) && thd->fatal_error) DBUG_RETURN(-1); + String *packet= &thd->packet; for (; open_list ; open_list=open_list->next) { - thd->packet.length(0); - net_store_data(&thd->packet,convert, open_list->db); - net_store_data(&thd->packet,convert, open_list->table); - net_store_data(&thd->packet,open_list->in_use); - net_store_data(&thd->packet,open_list->locked); - if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + packet->length(0); + net_store_data(packet,convert, open_list->db); + net_store_data(packet,convert, open_list->table); + net_store_data(packet,open_list->in_use); + net_store_data(packet,open_list->locked); + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) { DBUG_RETURN(-1); } } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } @@ -160,14 +164,15 @@ int mysqld_show_tables(THD *thd,const char *db,const char *wild) if (mysql_find_files(thd,&files,db,path,wild,0)) DBUG_RETURN(-1); List_iterator_fast it(files); + String *packet= &thd->packet; while ((file_name=it++)) { - thd->packet.length(0); - net_store_data(&thd->packet, thd->variables.convert_set, file_name); - if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + packet->length(0); + net_store_data(packet, thd->variables.convert_set, file_name); + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) DBUG_RETURN(-1); } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } @@ -175,15 +180,33 @@ int mysqld_show_tables(THD *thd,const char *db,const char *wild) ** List all table types supported ***************************************************************************/ -static struct show_table_type_st sys_table_types[]= { - {"MyISAM", (char *)"YES", "Default type from 3.23 with great performance"}, - {"HEAP" , (char *)"YES", "Hash based, stored in memory, useful for temporary tables"}, - {"MERGE", (char *)"YES", "Collection of identical MyISAM tables"}, - {"ISAM", (char*) &have_isam,"Obsolete table type"}, - {"InnoDB", (char*) &have_innodb,"Supports transactions, row-level locking and foreign keys"}, - {"BDB", (char*) &have_berkeley_db, "Supports transactions and page-level locking"}, +struct show_table_type_st { + const char *type; + SHOW_COMP_OPTION *value; + const char *comment; +}; + + +SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES; + +static struct show_table_type_st sys_table_types[]= +{ + {"MyISAM", &have_yes, + "Default type from 3.23 with great performance"}, + {"HEAP" , &have_yes, + "Hash based, stored in memory, useful for temporary tables"}, + {"MERGE", &have_yes, + "Collection of identical MyISAM tables"}, + {"ISAM", &have_isam, + "Obsolete table type; Is replaced by MyISAM"}, + {"InnoDB", &have_innodb, + "Supports transactions, row-level locking and foreign keys"}, + {"BDB", &have_berkeley_db, + "Supports transactions and page-level locking"}, + {NullS, NULL, NullS} }; + int mysqld_show_table_types(THD *thd) { List field_list; @@ -191,76 +214,68 @@ int mysqld_show_table_types(THD *thd) field_list.push_back(new Item_empty_string("Type",10)); field_list.push_back(new Item_empty_string("Support",10)); - field_list.push_back(new Item_empty_string("Comment",NAME_LEN)); + field_list.push_back(new Item_empty_string("Comment",80)); if (send_fields(thd,field_list,1)) DBUG_RETURN(1); - const char *default_type_name=ha_table_typelib.type_names[default_table_type-1]; - show_table_type_st *types = sys_table_types; - - uint i; - for (i = 0; i < 3; i++) - { - thd->packet.length(0); - net_store_data(&thd->packet,types[i].type); - if (!strcasecmp(default_type_name,types[i].type)) - net_store_data(&thd->packet,"DEFAULT"); - else - net_store_data(&thd->packet,types[i].value); - net_store_data(&thd->packet,types[i].comment); - if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) - DBUG_RETURN(-1); - } + const char *default_type_name= ha_table_typelib.type_names[thd->variables.table_type]; - for (; i < sizeof(sys_table_types)/sizeof(sys_table_types[0]); i++) + show_table_type_st *types; + String *packet= &thd->packet; + for (types= sys_table_types; types->type; types++) { - thd->packet.length(0); - net_store_data(&thd->packet,types[i].type); - SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) types[i].value; - - if (tmp == SHOW_OPTION_NO) - net_store_data(&thd->packet,"NO"); - else - { - if (tmp == SHOW_OPTION_YES) - { - if (!strcasecmp(default_type_name,types[i].type)) - net_store_data(&thd->packet,"DEFAULT"); - else - net_store_data(&thd->packet,"YES"); - } - else net_store_data(&thd->packet,"DISABLED"); - } - net_store_data(&thd->packet,types[i].comment); - if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + packet->length(0); + net_store_data(packet, types->type); + const char *option_name= show_comp_option_name[(int) *types->value]; + + if (*types->value == SHOW_OPTION_YES && + !strcasecmp(default_type_name, types->type)) + option_name= "DEFAULT"; + net_store_data(packet, option_name); + net_store_data(packet, types->comment); + if (my_net_write(&thd->net, (char*) packet->ptr(), packet->length())) DBUG_RETURN(-1); } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } + /*************************************************************************** -** List all privileges supported + List all privileges supported ***************************************************************************/ -static struct show_table_type_st sys_privileges[]= { - {"Select", (char *)"Tables", "To retrieve rows from table"}, - {"Insert", (char *)"Tables", "To insert data into tables"}, - {"Update", (char *)"Tables", "To update existing rows "}, - {"Delete", (char *)"Tables", "To delete existing rows"}, - {"Index", (char *)"Tables", "To create or drop indexes"}, - {"Alter", (char *)"Tables", "To alter the table"}, - {"Create", (char *)"Databases,Tables,Indexes", "To create new databases and tables"}, - {"Drop", (char *)"Databases,Tables", "To drop databases and tables"}, - {"Grant", (char *)"Databases,Tables", "To give to other users those privileges you possesed"}, - {"References", (char *)"Databases,Tables", "To have references on tables"}, - {"Reload", (char *)"Server Admin", "To reload or refresh tables, logs and privileges"}, - {"Shutdown",(char *)"Server Admin", "To shutdown the server"}, - {"Process", (char *)"Server Admin", "To view the plain text of currently executing queries"}, - {"File", (char *)"File access on server", "To read and write files on the server"}, +struct show_privileges_st { + const char *privilege; + const char *context; + const char *comment; }; + +/* + TODO: Update with new privileges +*/ +static struct show_privileges_st sys_privileges[]= +{ + {"Select", "Tables", "To retrieve rows from table"}, + {"Insert", "Tables", "To insert data into tables"}, + {"Update", "Tables", "To update existing rows "}, + {"Delete", "Tables", "To delete existing rows"}, + {"Index", "Tables", "To create or drop indexes"}, + {"Alter", "Tables", "To alter the table"}, + {"Create", "Databases,Tables,Indexes", "To create new databases and tables"}, + {"Drop", "Databases,Tables", "To drop databases and tables"}, + {"Grant", "Databases,Tables", "To give to other users those privileges you possess"}, + {"References", "Databases,Tables", "To have references on tables"}, + {"Reload", "Server Admin", "To reload or refresh tables, logs and privileges"}, + {"Shutdown","Server Admin", "To shutdown the server"}, + {"Process", "Server Admin", "To view the plain text of currently executing queries"}, + {"File", "File access on server", "To read and write files on the server"}, + {NullS, NullS, NullS} +}; + + int mysqld_show_privileges(THD *thd) { List field_list; @@ -273,43 +288,48 @@ int mysqld_show_privileges(THD *thd) if (send_fields(thd,field_list,1)) DBUG_RETURN(1); - for (uint i=0; i < sizeof(sys_privileges)/sizeof(sys_privileges[0]); i++) + show_privileges_st *privilege= sys_privileges; + String *packet= &thd->packet; + for (privilege= sys_privileges; privilege->privilege ; privilege++) { - thd->packet.length(0); - net_store_data(&thd->packet,sys_privileges[i].type); - net_store_data(&thd->packet,sys_privileges[i].value); - net_store_data(&thd->packet,sys_privileges[i].comment); - if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + packet->length(0); + net_store_data(packet,privilege->privilege); + net_store_data(packet,privilege->context); + net_store_data(packet,privilege->comment); + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) DBUG_RETURN(-1); } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } /*************************************************************************** -** List all column types + List all column types ***************************************************************************/ -#if 0 -struct show_column_type_st { +struct show_column_type_st +{ const char *type; uint size; - char *min_value; - char *max_value; - uint precision, - uint scale, - char *nullable; - char *auto_increment; - char *unsigned_attr; - char *zerofill; - char *searchable; - char *case_sensitivity; - char *default_value; - char *comment; + const char *min_value; + const char *max_value; + uint precision; + uint scale; + const char *nullable; + const char *auto_increment; + const char *unsigned_attr; + const char *zerofill; + const char *searchable; + const char *case_sensitivity; + const char *default_value; + const char *comment; }; -#endif -static struct show_column_type_st sys_column_types[]= { + +/* TODO: Add remaning types */ + +static struct show_column_type_st sys_column_types[]= +{ {"tinyint", 1, "-128", "127", 0, 0, "YES", "YES", "NO", "YES", "YES", "NO", "NULL,0", @@ -343,30 +363,33 @@ int mysqld_show_column_types(THD *thd) if (send_fields(thd,field_list,1)) DBUG_RETURN(1); + /* TODO: Change the loop to not use 'i' */ + String *packet= &thd->packet; for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++) { - thd->packet.length(0); - net_store_data(&thd->packet,sys_column_types[i].type); - net_store_data(&thd->packet,(longlong)sys_column_types[i].size); - net_store_data(&thd->packet,sys_column_types[i].min_value); - net_store_data(&thd->packet,sys_column_types[i].max_value); - net_store_data(&thd->packet,(uint32)sys_column_types[i].precision); - net_store_data(&thd->packet,(uint32)sys_column_types[i].scale); - net_store_data(&thd->packet,sys_column_types[i].nullable); - net_store_data(&thd->packet,sys_column_types[i].auto_increment); - net_store_data(&thd->packet,sys_column_types[i].unsigned_attr); - net_store_data(&thd->packet,sys_column_types[i].zerofill); - net_store_data(&thd->packet,sys_column_types[i].searchable); - net_store_data(&thd->packet,sys_column_types[i].case_sensitivity); - net_store_data(&thd->packet,sys_column_types[i].default_value); - net_store_data(&thd->packet,sys_column_types[i].comment); - if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) + packet->length(0); + net_store_data(packet,sys_column_types[i].type); + net_store_data(packet,(longlong)sys_column_types[i].size); + net_store_data(packet,sys_column_types[i].min_value); + net_store_data(packet,sys_column_types[i].max_value); + net_store_data(packet,(uint32)sys_column_types[i].precision); + net_store_data(packet,(uint32)sys_column_types[i].scale); + net_store_data(packet,sys_column_types[i].nullable); + net_store_data(packet,sys_column_types[i].auto_increment); + net_store_data(packet,sys_column_types[i].unsigned_attr); + net_store_data(packet,sys_column_types[i].zerofill); + net_store_data(packet,sys_column_types[i].searchable); + net_store_data(packet,sys_column_types[i].case_sensitivity); + net_store_data(packet,sys_column_types[i].default_value); + net_store_data(packet,sys_column_types[i].comment); + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) DBUG_RETURN(-1); } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } + static int mysql_find_files(THD *thd,List *files, const char *db,const char *path, const char *wild, bool dir) @@ -441,8 +464,9 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, DBUG_RETURN(0); } + /*************************************************************************** -** Extended version of mysqld_show_tables + Extended version of mysqld_show_tables ***************************************************************************/ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) @@ -459,7 +483,6 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) (void) sprintf(path,"%s/%s",mysql_data_home,db); (void) unpack_dirname(path,path); -//,default_charset_info field_list.push_back(item=new Item_empty_string("Name",NAME_LEN)); item->maybe_null=1; field_list.push_back(item=new Item_empty_string("Type",10)); @@ -612,14 +635,13 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) packet->length())) DBUG_RETURN(-1); } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } - /*************************************************************************** -** List all columns in a table + List all columns in a table ***************************************************************************/ int @@ -637,7 +659,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, if (!(table = open_ltable(thd, table_list, TL_UNLOCK))) { - send_error(&thd->net); + send_error(thd); DBUG_RETURN(1); } file=table->file; @@ -742,10 +764,11 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, } } } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } + int mysqld_show_create(THD *thd, TABLE_LIST *table_list) { @@ -758,7 +781,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) /* Only one table for now */ if (!(table = open_ltable(thd, table_list, TL_UNLOCK))) { - send_error(&thd->net); + send_error(thd); DBUG_RETURN(1); } @@ -809,7 +832,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) if (my_net_write(&thd->net, (char*)packet->ptr(), packet->length())) DBUG_RETURN(1); } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } @@ -832,7 +855,7 @@ mysqld_show_logs(THD *thd) DBUG_RETURN(-1); #endif - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } @@ -849,7 +872,7 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) if (!(table = open_ltable(thd, table_list, TL_UNLOCK))) { - send_error(&thd->net); + send_error(thd); DBUG_RETURN(1); } @@ -933,14 +956,14 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(1); /* purecov: inspected */ } } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); } /**************************************************************************** -** Return only fields for API mysql_list_fields -** Use "show table wildcard" in mysql instead of this + Return only fields for API mysql_list_fields + Use "show table wildcard" in mysql instead of this ****************************************************************************/ void @@ -952,7 +975,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) if (!(table = open_ltable(thd, table_list, TL_UNLOCK))) { - send_error(&thd->net); + send_error(thd); DBUG_VOID_RETURN; } List field_list; @@ -971,6 +994,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) DBUG_VOID_RETURN; } + int mysqld_dump_create_info(THD *thd, TABLE *table, int fd) { @@ -978,7 +1002,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd) DBUG_ENTER("mysqld_dump_create_info"); DBUG_PRINT("enter",("table: %s",table->real_name)); - String* packet = &thd->packet; + String *packet = &thd->packet; packet->length(0); if (store_create_info(thd,table,packet)) DBUG_RETURN(-1); @@ -1000,6 +1024,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd) DBUG_RETURN(0); } + static void append_identifier(THD *thd, String *packet, const char *name) { @@ -1015,6 +1040,7 @@ append_identifier(THD *thd, String *packet, const char *name) } } + static int store_create_info(THD *thd, TABLE *table, String *packet) { @@ -1215,8 +1241,8 @@ store_create_info(THD *thd, TABLE *table, String *packet) /**************************************************************************** -** Return info about all processes -** returns for each thread: thread id, user, host, db, command, info + Return info about all processes + returns for each thread: thread id, user, host, db, command, info ****************************************************************************/ class thread_info :public ilink { @@ -1357,7 +1383,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) break; /* purecov: inspected */ } - send_eof(&thd->net); + send_eof(thd); DBUG_VOID_RETURN; } @@ -1372,7 +1398,7 @@ int mysqld_show_charsets(THD *thd, const char *wild) char buff[8192]; String packet2(buff,sizeof(buff),default_charset_info); List field_list; - CONVERT *convert=thd->convert_set; + CONVERT *convert=thd->variables.convert_set; CHARSET_INFO *cs; DBUG_ENTER("mysqld_show_charsets"); @@ -1401,7 +1427,7 @@ int mysqld_show_charsets(THD *thd, const char *wild) goto err; } } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); err: DBUG_RETURN(1); @@ -1428,7 +1454,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, for (; variables->name; variables++) { if (!(wild && wild[0] && wild_case_compare(system_charset_info, - variables[i].name,wild))) + variables->name,wild))) { packet2.length(0); net_store_data(&packet2,convert,variables->name); @@ -1461,9 +1487,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, case SHOW_HAVE: { SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value; - net_store_data(&packet2, (tmp == SHOW_OPTION_NO ? "NO" : - tmp == SHOW_OPTION_YES ? "YES" : - "DISABLED")); + net_store_data(&packet2, show_comp_option_name[(int) tmp]); break; } case SHOW_CHAR: @@ -1663,7 +1687,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, } pthread_mutex_unlock(&LOCK_status); /* pthread_mutex_unlock(&THR_LOCK_keycache); */ - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); err: diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6b24999763b..fb0815a1a26 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -82,7 +82,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) if (error) DBUG_RETURN(-1); - send_ok(&thd->net); + send_ok(thd); DBUG_RETURN(0); } @@ -305,8 +305,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } - - for(field_no=0; (sql_field=it++) ; field_no++) + for (field_no=0; (sql_field=it++) ; field_no++) { /* Don't pack keys in old tables if the user has requested this */ if ((sql_field->flags & BLOB_FLAG) || @@ -317,28 +316,35 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } if (!(sql_field->flags & NOT_NULL_FLAG)) null_fields++; - for(dup_no=0; (dup_field=it2++) != sql_field; dup_no++) + + /* Check if we have used the same field name before */ + for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++) { if (my_strcasecmp(system_charset_info, sql_field->field_name, dup_field->field_name) == 0) { - if (field_no=select_field_pos) + /* + If this was a CREATE ... SELECT statement, accept a field + redefinition if we are changing a field in the SELECT part + */ + if (field_no < select_field_pos || dup_no >= select_field_pos) { my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name); DBUG_RETURN(-1); } else { - sql_field->length=dup_field->length; - sql_field->decimals=dup_field->decimals; - sql_field->flags=dup_field->flags; - sql_field->pack_length=dup_field->pack_length; - sql_field->unireg_check=dup_field->unireg_check; - sql_field->sql_type=dup_field->sql_type; - it2.remove(); - select_field_pos--; - break; + /* Field redefined */ + sql_field->length= dup_field->length; + sql_field->decimals= dup_field->decimals; + sql_field->flags= dup_field->flags; + sql_field->pack_length= dup_field->pack_length; + sql_field->unireg_check= dup_field->unireg_check; + sql_field->sql_type= dup_field->sql_type; + it2.remove(); // Remove first (create) definition + select_field_pos--; + break; } } } @@ -749,7 +755,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, create_info->create_statement = thd->query; create_info->table_options=db_options; - if (rea_create_table(path, create_info, fields, key_count, + if (rea_create_table(thd, path, create_info, fields, key_count, key_info_buffer)) { /* my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,my_errno); */ @@ -825,7 +831,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, TABLE tmp_table; // Used during 'create_field()' TABLE *table; tmp_table.table_name=0; - uint select_field_count=0; + uint select_field_count= items->elements; DBUG_ENTER("create_table_from_items"); /* Add selected items to field list */ @@ -859,7 +865,6 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, (Field*) 0)))) DBUG_RETURN(0); extra_fields->push_back(cr_field); - select_field_count++; } /* create and lock table */ /* QQ: This should be done atomic ! */ @@ -1271,7 +1276,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, goto err; } - send_eof(&thd->net); + send_eof(thd); DBUG_RETURN(0); err: close_thread_tables(thd); // Shouldn't be needed @@ -1476,7 +1481,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, Query_log_event qinfo(thd, thd->query, thd->query_length); mysql_bin_log.write(&qinfo); } - send_ok(&thd->net); + send_ok(thd); } DBUG_RETURN(error); } @@ -1994,7 +1999,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, end_temporary: sprintf(tmp_name,ER(ER_INSERT_INFO),(ulong) (copied+deleted), (ulong) deleted, thd->cuted_fields); - send_ok(&thd->net,copied+deleted,0L,tmp_name); + send_ok(thd,copied+deleted,0L,tmp_name); thd->some_tables_deleted=0; DBUG_RETURN(0); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 225c0ea26a4..893f0838a7f 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -342,7 +342,7 @@ int mysql_create_function(THD *thd,udf_func *udf) if (!initialized) { - send_error(&thd->net, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES)); + send_error(thd, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES)); DBUG_RETURN(1); } @@ -353,19 +353,19 @@ int mysql_create_function(THD *thd,udf_func *udf) */ if (strchr(udf->dl, '/')) { - send_error(&thd->net, ER_UDF_NO_PATHS,ER(ER_UDF_NO_PATHS)); + send_error(thd, ER_UDF_NO_PATHS,ER(ER_UDF_NO_PATHS)); DBUG_RETURN(1); } if (udf->name_length > NAME_LEN) { - net_printf(&thd->net, ER_TOO_LONG_IDENT,udf->name); + net_printf(thd, ER_TOO_LONG_IDENT,udf->name); DBUG_RETURN(1); } pthread_mutex_lock(&THR_LOCK_udf); if (hash_search(&udf_hash,(byte*) udf->name, udf->name_length)) { - net_printf(&thd->net, ER_UDF_EXISTS, udf->name); + net_printf(thd, ER_UDF_EXISTS, udf->name); goto err; } if (!(dl = find_udf_dl(udf->dl))) @@ -374,7 +374,7 @@ int mysql_create_function(THD *thd,udf_func *udf) { DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", udf->dl,errno,dlerror())); - net_printf(&thd->net, ER_CANT_OPEN_LIBRARY, udf->dl, errno, dlerror()); + net_printf(thd, ER_CANT_OPEN_LIBRARY, udf->dl, errno, dlerror()); goto err; } new_dl=1; @@ -384,7 +384,7 @@ int mysql_create_function(THD *thd,udf_func *udf) if (udf->func == NULL) { - net_printf(&thd->net, ER_CANT_FIND_DL_ENTRY, udf->name); + net_printf(thd, ER_CANT_FIND_DL_ENTRY, udf->name); goto err; } udf->name=strdup_root(&mem,udf->name); @@ -392,7 +392,7 @@ int mysql_create_function(THD *thd,udf_func *udf) if (!udf->name || !udf->dl || !(u_d=add_udf(udf->name,udf->returns,udf->dl,udf->type))) { - send_error(&thd->net,0); // End of memory + send_error(thd,0); // End of memory goto err; } u_d->dlhandle = dl; @@ -422,7 +422,7 @@ int mysql_create_function(THD *thd,udf_func *udf) close_thread_tables(thd); if (error) { - net_printf(&thd->net, ER_ERROR_ON_WRITE, "func@mysql",error); + net_printf(thd, ER_ERROR_ON_WRITE, "func@mysql",error); del_udf(u_d); goto err; } @@ -445,13 +445,13 @@ int mysql_drop_function(THD *thd,const char *udf_name) DBUG_ENTER("mysql_drop_function"); if (!initialized) { - send_error(&thd->net, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES)); + send_error(thd, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES)); DBUG_RETURN(1); } pthread_mutex_lock(&THR_LOCK_udf); if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name, (uint) strlen(udf_name)))) { - net_printf(&thd->net, ER_FUNCTION_NOT_DEFINED, udf_name); + net_printf(thd, ER_FUNCTION_NOT_DEFINED, udf_name); goto err; } del_udf(udf); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 51f278536de..8244384cc94 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -242,7 +242,7 @@ bool select_union::flush() if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) { table->file->print_error(error,MYF(0)); - ::send_error(&thd->net); + ::send_error(thd); return 1; } return 0; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index f0ca5ad6c7b..ccd4439a9d2 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -127,7 +127,7 @@ int mysql_update(THD *thd, { DBUG_RETURN(-1); // Error in where } - send_ok(&thd->net); // No matching records + send_ok(thd); // No matching records DBUG_RETURN(0); } /* If running in safe sql mode, don't allow updates without keys */ @@ -138,7 +138,7 @@ int mysql_update(THD *thd, { delete select; table->time_stamp=save_time_stamp; - send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); + send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); DBUG_RETURN(1); } } @@ -329,13 +329,13 @@ int mysql_update(THD *thd, delete select; if (error >= 0) - send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */ + send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */ else { char buff[80]; sprintf(buff,ER(ER_UPDATE_INFO), (long) found, (long) updated, (long) thd->cuted_fields); - send_ok(&thd->net, + send_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated, thd->insert_id_used ? thd->insert_id() : 0L,buff); DBUG_PRINT("info",("%d records updated",updated)); @@ -439,7 +439,7 @@ multi_update::prepare(List &values, SELECT_LEX_UNIT *u) } if (!table_ref) { - net_printf(&thd->net, ER_NOT_SUPPORTED_YET, "JOIN SYNTAX WITH MULTI-TABLE UPDATES"); + net_printf(thd, ER_NOT_SUPPORTED_YET, "JOIN SYNTAX WITH MULTI-TABLE UPDATES"); DBUG_RETURN(1); } else @@ -447,7 +447,7 @@ multi_update::prepare(List &values, SELECT_LEX_UNIT *u) } if (!num_updated) { - net_printf(&thd->net, ER_NOT_SUPPORTED_YET, "SET CLAUSE MUST CONTAIN TABLE.FIELD REFERENCE"); + net_printf(thd, ER_NOT_SUPPORTED_YET, "SET CLAUSE MUST CONTAIN TABLE.FIELD REFERENCE"); DBUG_RETURN(1); } @@ -662,7 +662,7 @@ bool multi_update::send_data(List &values) void multi_update::send_error(uint errcode,const char *err) { /* First send error what ever it is ... */ - ::send_error(&thd->net,errcode,err); + ::send_error(thd,errcode,err); /* reset used flags */ // update_tables->table->no_keyread=0; @@ -821,7 +821,7 @@ bool multi_update::send_eof() { query_cache_invalidate3(thd, update_tables, 1); } - ::send_ok(&thd->net, + ::send_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated, thd->insert_id_used ? thd->insert_id() : 0L,buff); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8571cb9af6d..d9662f25c1b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -26,6 +26,7 @@ #include "slave.h" #include "sql_acl.h" #include "lex_symbol.h" +#include "item_create.h" #include #include @@ -356,9 +357,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token COMPRESSED_SYM %token ERRORS -%token SQL_ERROR_COUNT %token WARNINGS -%token SQL_WARNING_COUNT %token BIGINT %token BLOB_SYM @@ -642,7 +641,7 @@ query: if (!thd->bootstrap && (!(thd->lex.select_lex.options & OPTION_FOUND_COMMENT))) { - send_error(¤t_thd->net,ER_EMPTY_QUERY); + send_error(current_thd,ER_EMPTY_QUERY); YYABORT; } else @@ -1128,7 +1127,7 @@ charset: { if (!(Lex->charset=get_charset_by_name($1.str,MYF(0)))) { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$1.str); + net_printf(current_thd,ER_UNKNOWN_CHARACTER_SET,$1.str); YYABORT; } }; @@ -1690,7 +1689,7 @@ expr_expr: { if (!(Lex->charset=get_charset_by_name($3.str,MYF(0)))) { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3.str); + net_printf(current_thd,ER_UNKNOWN_CHARACTER_SET,$3.str); YYABORT; } $$= new Item_func_set_collation($1,Lex->charset); @@ -1921,9 +1920,8 @@ simple_expr: { $$= new Item_func_interval($3,* $5); } | LAST_INSERT_ID '(' ')' { - $$= new Item_int((char*) "last_insert_id()", - current_thd->insert_id(),21); - current_thd->safe_to_cache_query=0; + $$= get_system_var(OPT_SESSION, "last_insert_id", 14, + "last_insert_id()"); } | LAST_INSERT_ID '(' expr ')' { @@ -2409,7 +2407,7 @@ olap_opt: LEX *lex=Lex; lex->olap = true; lex->select->olap= CUBE_TYPE; - net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "CUBE"); + net_printf(lex->thd, ER_NOT_SUPPORTED_YET, "CUBE"); YYABORT; /* To be deleted in 4.1 */ } | WITH ROLLUP_SYM @@ -2417,7 +2415,7 @@ olap_opt: LEX *lex=Lex; lex->olap = true; lex->select->olap= ROLLUP_TYPE; - net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "ROLLUP"); + net_printf(lex->thd, ER_NOT_SUPPORTED_YET, "ROLLUP"); YYABORT; /* To be deleted in 4.1 */ } ; @@ -2436,12 +2434,12 @@ order_clause: LEX *lex=Lex; if (lex->sql_command == SQLCOM_MULTI_UPDATE) { - net_printf(&lex->thd->net, ER_WRONG_USAGE, "UPDATE", "ORDER BY"); + net_printf(lex->thd, ER_WRONG_USAGE, "UPDATE", "ORDER BY"); YYABORT; } if (lex->select->olap != UNSPECIFIED_OLAP_TYPE) { - net_printf(&lex->thd->net, ER_WRONG_USAGE, + net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", "ORDER BY"); YYABORT; @@ -2467,7 +2465,7 @@ limit_clause: LEX *lex=Lex; if (lex->select->olap != UNSPECIFIED_OLAP_TYPE) { - net_printf(&lex->thd->net, ER_WRONG_USAGE, "CUBE/ROLLUP", + net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", "LIMIT"); YYABORT; } @@ -2480,7 +2478,7 @@ limit_clause: LEX *lex=Lex; if (lex->select->olap != UNSPECIFIED_OLAP_TYPE) { - net_printf(&lex->thd->net, ER_WRONG_USAGE, "CUBE/ROLLUP", + net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", "LIMIT"); YYABORT; } @@ -2495,7 +2493,7 @@ delete_limit_clause: LEX *lex=Lex; if (lex->sql_command == SQLCOM_MULTI_UPDATE) { - net_printf(&lex->thd->net, ER_WRONG_USAGE, "DELETE", "LIMIT"); + net_printf(lex->thd, ER_WRONG_USAGE, "DELETE", "LIMIT"); YYABORT; } lex->select->select_limit= HA_POS_ERROR; @@ -2935,9 +2933,9 @@ show_param: lex->sql_command= SQLCOM_SHOW_PRIVILEGES; } | COUNT_SYM '(' '*' ')' WARNINGS - { Lex->sql_command = SQLCOM_SHOW_WARNS_COUNT;} + { (void) create_select_for_variable("warning_count"); } | COUNT_SYM '(' '*' ')' ERRORS - { Lex->sql_command = SQLCOM_SHOW_ERRORS_COUNT;} + { (void) create_select_for_variable("error_count"); } | WARNINGS {Select->offset_limit=0L;} limit_clause { Lex->sql_command = SQLCOM_SHOW_WARNS;} | ERRORS {Select->offset_limit=0L;} limit_clause @@ -3103,7 +3101,7 @@ kill: LEX *lex=Lex; if ($2->fix_fields(lex->thd, 0, &$2)) { - send_error(&lex->thd->net, ER_SET_CONSTANTS_ONLY); + send_error(lex->thd, ER_SET_CONSTANTS_ONLY); YYABORT; } lex->sql_command=SQLCOM_KILL; @@ -3218,10 +3216,11 @@ text_string: param_marker: '?' { - if(current_thd->prepare_command) + LEX *lex=Lex; + if (current_thd->prepare_command) { - Lex->param_list.push_back($$=new Item_param()); - current_thd->param_count++; + lex->param_list.push_back($$=new Item_param()); + lex->param_count++; } else { @@ -3602,8 +3601,8 @@ text_or_password: set_expr_or_default: expr { $$=$1; } | DEFAULT { $$=0; } - | ON { $$=new Item_string("ON",2); } - | ALL { $$=new Item_string("ALL",3); } + | ON { $$=new Item_string("ON", 2, system_charset_info); } + | ALL { $$=new Item_string("ALL", 3, system_charset_info); } ; @@ -3769,7 +3768,7 @@ require_list_element: SUBJECT_SYM TEXT_STRING LEX *lex=Lex; if (lex->x509_subject) { - net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "SUBJECT"); + net_printf(lex->thd,ER_DUP_ARGUMENT, "SUBJECT"); YYABORT; } lex->x509_subject=$2.str; @@ -3779,7 +3778,7 @@ require_list_element: SUBJECT_SYM TEXT_STRING LEX *lex=Lex; if (lex->x509_issuer) { - net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "ISSUER"); + net_printf(lex->thd,ER_DUP_ARGUMENT, "ISSUER"); YYABORT; } lex->x509_issuer=$2.str; @@ -3789,7 +3788,7 @@ require_list_element: SUBJECT_SYM TEXT_STRING LEX *lex=Lex; if (lex->ssl_cipher) { - net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "CIPHER"); + net_printf(lex->thd,ER_DUP_ARGUMENT, "CIPHER"); YYABORT; } lex->ssl_cipher=$2.str; @@ -3805,7 +3804,7 @@ opt_table: lex->grant = DB_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - send_error(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); + send_error(lex->thd,ER_ILLEGAL_GRANT_FOR_TABLE); YYABORT; } } @@ -3817,7 +3816,7 @@ opt_table: lex->grant = DB_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - send_error(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); + send_error(lex->thd,ER_ILLEGAL_GRANT_FOR_TABLE); YYABORT; } } @@ -3829,7 +3828,7 @@ opt_table: lex->grant= GLOBAL_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - send_error(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); + send_error(lex->thd,ER_ILLEGAL_GRANT_FOR_TABLE); YYABORT; } } @@ -3977,15 +3976,15 @@ union_list: if (lex->exchange) { /* Only the last SELECT can have INTO...... */ - net_printf(&lex->thd->net, ER_WRONG_USAGE, "UNION", "INTO"); + net_printf(lex->thd, ER_WRONG_USAGE, "UNION", "INTO"); YYABORT; } if (lex->select->linkage == GLOBAL_OPTIONS_TYPE) { - send_error(&lex->thd->net, ER_SYNTAX_ERROR); + send_error(lex->thd, ER_SYNTAX_ERROR); YYABORT; } - if (mysql_new_select(lex)) + if (mysql_new_select(lex, 0)) YYABORT; lex->select->linkage=UNION_TYPE; } @@ -4003,7 +4002,7 @@ optional_order_or_limit: LEX *lex=Lex; if (!lex->select->braces) { - send_error(&lex->thd->net, ER_SYNTAX_ERROR); + send_error(lex->thd, ER_SYNTAX_ERROR); YYABORT; } lex->select->master_unit()->global_parameters= @@ -4013,7 +4012,7 @@ optional_order_or_limit: SELECT_LEX fields always check linkage type. */ lex->select= (SELECT_LEX*)lex->select->master_unit(); - lex->select->select_limit=lex->thd->default_select_limit; + lex->select->select_limit=lex->thd->variables.select_limit; } opt_order_clause limit_clause ; diff --git a/sql/structs.h b/sql/structs.h index c2ad4ef527e..7873de4db63 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -148,36 +148,18 @@ enum SHOW_TYPE }; enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED}; + +extern const char *show_comp_option_name[]; + typedef int *(*update_var)(THD *, struct show_var_st *); + typedef struct show_var_st { const char *name; char *value; SHOW_TYPE type; } SHOW_VAR; -struct show_table_type_st { - const char *type; - char *value; - const char *comment; -}; - -struct show_column_type_st { - const char *type; - uint size; - const char *min_value; - const char *max_value; - uint precision; - uint scale; - const char *nullable; - const char *auto_increment; - const char *unsigned_attr; - const char *zerofill; - const char *searchable; - const char *case_sensitivity; - const char *default_value; - const char *comment; -}; typedef struct lex_string { char *str; diff --git a/sql/table.cc b/sql/table.cc index 3e41da73109..2cdd62001f1 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -493,7 +493,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (field->key_length() == key_part->length && field->type() != FIELD_TYPE_BLOB) { - if ((index_flags & HA_HAVE_KEY_READ_ONLY) && + if ((index_flags & HA_KEY_READ_ONLY) && (field->key_type() != HA_KEYTYPE_TEXT || (!(ha_option & HA_KEY_READ_WRONG_STR) && !(keyinfo->flags & HA_FULLTEXT)))) @@ -1141,7 +1141,7 @@ bool check_db_name(const char *name) return 1; name++; } - return (uint) (name - start) > NAME_LEN; + return (uint) (name - start) > NAME_LEN || name == start; } diff --git a/sql/uniques.cc b/sql/uniques.cc index 60905567ba0..ed256a4b791 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -53,7 +53,8 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, :max_in_memory_size(max_in_memory_size_arg),elements(0) { my_b_clear(&file); - init_tree(&tree, max_in_memory_size / 16, 0, size, comp_func, 0, NULL, comp_func_fixed_arg); + init_tree(&tree, max_in_memory_size / 16, 0, size, comp_func, 0, NULL, + comp_func_fixed_arg); /* If the following fail's the next add will also fail */ my_init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16); max_elements= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size); diff --git a/sql/unireg.cc b/sql/unireg.cc index 8db9b871a39..344583b56f1 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -46,7 +46,7 @@ static bool make_empty_rec(int file, enum db_type table_type, uint reclength,uint null_fields); -int rea_create_table(my_string file_name, +int rea_create_table(THD *thd, my_string file_name, HA_CREATE_INFO *create_info, List &create_fields, uint keys, KEY *key_info) @@ -67,13 +67,12 @@ int rea_create_table(my_string file_name, if (pack_header(forminfo, create_info->db_type,create_fields,info_length, screens, create_info->table_options, db_file)) { - NET *net=my_pthread_getspecific_ptr(NET*,THR_NET); my_free((gptr) screen_buff,MYF(0)); - if (net->last_errno != ER_TOO_MANY_FIELDS) + if (thd->net.last_errno != ER_TOO_MANY_FIELDS) DBUG_RETURN(1); // Try again without UNIREG screens (to get more columns) - net->last_error[0]=0; + thd->net.last_error[0]=0; if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,1))) DBUG_RETURN(1); if (pack_header(forminfo, create_info->db_type, create_fields,info_length, diff --git a/sql/unireg.h b/sql/unireg.h index 2cfa709bbdc..fd1117a4708 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -63,6 +63,8 @@ #define MAX_SORT_MEMORY (2048*1024-MALLOC_OVERHEAD) #define MIN_SORT_MEMORY (32*1024-MALLOC_OVERHEAD) +#define DEFAULT_ERROR_COUNT 64 +#define DEFAULT_PREP_STMT_COUNT 64 #define EXTRA_RECORDS 10 /* Extra records in sort */ #define SCROLL_EXTRA 5 /* Extra scroll-rows. */ #define FIELD_NAME_USED ((uint) 32768) /* Bit set if fieldname used */ -- cgit v1.2.1 From 1d418629753f58a5a12f8c202383d0195b128ae6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Oct 2002 14:55:02 +0500 Subject: Additional key segment (HA_KEYTYPE_END) creation has been moved from handler to hp_create.c BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/ha_heap.cc | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'sql') diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index f56bfe74265..b41ab648f0b 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -243,11 +243,7 @@ int ha_heap::create(const char *name, TABLE *table, HA_CREATE_INFO *create_info) int error; for (key= parts= 0; key < table->keys; key++) - { parts+= table->key_info[key].key_parts; - if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE) - parts++; /* additional HA_KEYTYPE_END keyseg */ - } if (!(keydef= (HP_KEYDEF*) my_malloc(table->keys * sizeof(HP_KEYDEF) + parts * sizeof(HA_KEYSEG), MYF(MY_WME)))) @@ -299,15 +295,6 @@ int ha_heap::create(const char *name, TABLE *table, HA_CREATE_INFO *create_info) seg->null_pos= 0; } } - if (pos->algorithm == HA_KEY_ALG_BTREE) - { - /* additional HA_KEYTYPE_END keyseg */ - seg->type= HA_KEYTYPE_END; - seg->length= sizeof(byte*); - seg->flag= 0; - seg->null_bit= 0; - seg++; - } } mem_per_row+= MY_ALIGN(table->reclength + 1, sizeof(char*)); max_rows= (ulong) (max_heap_table_size / mem_per_row); -- cgit v1.2.1 From e57cd00a6fd8edddf373348d050723b2d41339f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Oct 2002 16:35:08 +0300 Subject: after merging bugfix --- sql/item.cc | 21 +++++++++++++++------ sql/mysql_priv.h | 5 +++-- sql/sql_base.cc | 23 +++++++++++++---------- sql/sql_lex.cc | 10 +++++----- sql/sql_parse.cc | 2 +- sql/sql_select.cc | 11 ++++------- sql/sql_yacc.yy | 9 ++++++--- 7 files changed, 47 insertions(+), 34 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 946c0f24fe1..47c2926bef4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -432,7 +432,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (!field) // If field is not checked { Field *tmp; - if (!(tmp=find_field_in_tables(thd,this,tables))) + if (!(tmp=find_field_in_tables(thd, this, tables, 0))) { /* We can't find table field in table list of current select, @@ -448,9 +448,14 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) sl && !tmp; sl= sl->outer_select()) tmp=find_field_in_tables(thd, this, - (TABLE_LIST*)(last= sl)->table_list.first); + (TABLE_LIST*)(last= sl)->table_list.first, + 0); if (!tmp) - return 1; + { + // Call to produce appropriate error message + find_field_in_tables(thd, this, tables, 1); + return -1; + } else { depended_from= last; @@ -463,7 +468,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) s= s->outer_select()) if( !s->depended ) { - s->depended= 1; //Select is depended of outer select + s->depended= 1; //Tables will be reopened many times for (TABLE_LIST *tbl= (TABLE_LIST*)s->table_list.first; @@ -780,7 +785,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { if (!ref) { - if (!(ref= find_item_in_list(this,thd->lex.select->item_list))) + if (!(ref= find_item_in_list(this, thd->lex.select->item_list, 0))) { /* We can't find table field in table list of current select, @@ -795,9 +800,13 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) for (SELECT_LEX *sl= thd->lex.select->outer_select(); sl && !ref; sl= sl->outer_select()) - ref= find_item_in_list(this, (last= sl)->item_list); + ref= find_item_in_list(this, (last= sl)->item_list, 0); if (!ref) + { + // Call to report error + find_item_in_list(this, thd->lex.select->item_list, 1); return 1; + } else { depended_from= last; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 4532646b1c2..60505ec0712 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -450,7 +450,8 @@ bool wait_for_tables(THD *thd); bool table_is_used(TABLE *table, bool wait_for_name_lock); bool drop_locked_tables(THD *thd,const char *db, const char *table_name); void abort_locked_tables(THD *thd,const char *db, const char *table_name); -Field *find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables); +Field *find_field_in_tables(THD *thd, Item_field *item, TABLE_LIST *tables, + bool report_error); Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, bool check_grant,bool allow_rowid); #ifdef HAVE_OPENSSL @@ -538,7 +539,7 @@ TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find); SQL_SELECT *make_select(TABLE *head, table_map const_tables, table_map read_tables, COND *conds, int *error); -Item ** find_item_in_list(Item *item,List &items); +Item ** find_item_in_list(Item *item, List &items, bool report_error); bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator *it); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5d3421f5538..59c57006947 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1783,7 +1783,8 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, Field * -find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) +find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables, + bool report_error) { Field *found=0; const char *db=item->db_name; @@ -1820,7 +1821,7 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) } if (found) return found; - if (!found_table) + if (!found_table && report_error) { char buff[NAME_LEN*2+1]; if (db) @@ -1832,8 +1833,9 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) thd->where); } else - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), - item->full_name(),thd->where); + if (report_error) + my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), + item->full_name(),thd->where); return (Field*) 0; } bool allow_rowid= tables && !tables->next; // Only one table @@ -1848,7 +1850,7 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) return (Field*) 0; if (found) { - if (!thd->where) // Returns first found + if (!report_error) // Returns first found break; my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), name,thd->where); @@ -1859,13 +1861,14 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) } if (found) return found; - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR), - MYF(0),item->full_name(),thd->where); + if (report_error) + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), + MYF(0), item->full_name(), thd->where); return (Field*) 0; } Item ** -find_item_in_list(Item *find,List &items) +find_item_in_list(Item *find, List &items, bool report_error) { List_iterator li(items); Item **found=0,*item; @@ -1890,7 +1893,7 @@ find_item_in_list(Item *find,List &items) { if ((*found)->eq(item,0)) continue; // Same field twice (Access?) - if (current_thd->where) + if (report_error) my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), find->full_name(), current_thd->where); return (Item**) 0; @@ -1913,7 +1916,7 @@ find_item_in_list(Item *find,List &items) break; } } - if (!found && current_thd->where) + if (!found && report_error) my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), find->full_name(),current_thd->where); return found; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 1af8d363fda..60ab3344b3f 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -142,11 +142,11 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->next_state=STATE_START; lex->end_of_query=(lex->ptr=buf)+length; lex->yylineno = 1; - lex->select->create_refs=lex->in_comment=0; + lex->select_lex.create_refs=lex->in_comment=0; lex->length=0; - lex->select->in_sum_expr=0; - lex->select->expr_list.empty(); - lex->select->ftfunc_list.empty(); + lex->select_lex.in_sum_expr=0; + lex->select_lex.expr_list.empty(); + lex->select_lex.ftfunc_list.empty(); lex->convert_set=(lex->thd=thd)->variables.convert_set; lex->yacc_yyss=lex->yacc_yyvs=0; lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE); @@ -158,7 +158,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) void lex_end(LEX *lex) { - lex->select->expr_list.delete_elements(); // If error when parsing sql-varargs + lex->select_lex.expr_list.delete_elements(); // If error when parsing sql-varargs x_free(lex->yacc_yyss); x_free(lex->yacc_yyvs); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 461276900a5..580a6796911 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1265,7 +1265,7 @@ mysql_execute_command(THD *thd) int res= 0; LEX *lex= &thd->lex; TABLE_LIST *tables= (TABLE_LIST*) lex->select_lex.table_list.first; - SELECT_LEX *select_lex= lex->select; + SELECT_LEX *select_lex= &lex->select_lex; SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2b737ab65d7..68871d7ace1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6498,9 +6498,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List &fields, return 0; } const char *save_where=thd->where; - thd->where=0; // No error if not found - Item **item=find_item_in_list(*order->item,fields); - thd->where=save_where; + Item **item=find_item_in_list(*order->item, fields, 0); if (item) { order->item=item; // use it @@ -6598,17 +6596,15 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List &fields, DBUG_ENTER("setup_new_fields"); thd->set_query_id=1; // Not really needed, but... - thd->where=0; // Don't give error for (; new_field ; new_field=new_field->next) { - if ((item=find_item_in_list(*new_field->item,fields))) + if ((item= find_item_in_list(*new_field->item, fields, 0))) new_field->item=item; /* Change to shared Item */ else { thd->where="procedure list"; if ((*new_field->item)->fix_fields(thd, tables, new_field->item)) DBUG_RETURN(1); /* purecov: inspected */ - thd->where=0; all_fields.push_front(*new_field->item); new_field->item=all_fields.head_ref(); } @@ -7400,7 +7396,8 @@ static void describe_info(JOIN *join, const char *info) { THD *thd= join->thd; - if (thd->lex.select->next_select()) /* If in UNION */ + /* If lex.select belong to UNION */ + if (thd->lex.select->master_unit()->first_select()->next_select()) { select_describe(join,FALSE,FALSE,FALSE,info); return; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index cc06344304f..f61f970f479 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2436,7 +2436,8 @@ order_clause: net_printf(lex->thd, ER_WRONG_USAGE, "UPDATE", "ORDER BY"); YYABORT; } - if (lex->select->olap != UNSPECIFIED_OLAP_TYPE) + if (lex->select->linkage != GLOBAL_OPTIONS_TYPE && + lex->select->olap != UNSPECIFIED_OLAP_TYPE) { net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", @@ -2462,7 +2463,8 @@ limit_clause: | LIMIT ULONG_NUM { LEX *lex=Lex; - if (lex->select->olap != UNSPECIFIED_OLAP_TYPE) + if (lex->select->linkage != GLOBAL_OPTIONS_TYPE && + lex->select->olap != UNSPECIFIED_OLAP_TYPE) { net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", "LIMIT"); @@ -2475,7 +2477,8 @@ limit_clause: | LIMIT ULONG_NUM ',' ULONG_NUM { LEX *lex=Lex; - if (lex->select->olap != UNSPECIFIED_OLAP_TYPE) + if (lex->select->linkage != GLOBAL_OPTIONS_TYPE && + lex->select->olap != UNSPECIFIED_OLAP_TYPE) { net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", "LIMIT"); -- cgit v1.2.1 From 8f7a2b2785cec83f3c00047b5d3fb76d85ecbe62 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Oct 2002 16:54:26 +0300 Subject: Update after last merge. Fixes some wrong test results. libmysql/libmysql.c: Removed obsolete function (now in strings library) mysql-test/r/rpl_log.result: Updated results for 4.1 mysql-test/r/rpl_log_pos.result: Updated results for 4.1 sql/item_strfunc.cc: Added missing system_charset_info sql/log_event.cc: Portability fixes. More debugging. sql/net_pkg.cc: Added back setting of query_error as slave code is depeneding on this. sql/sql_acl.cc: Update after last merge sql/sql_lex.cc: Update after last merge sql/sql_parse.cc: Update after last merge sql/sql_prepare.cc: Update after last merge sql/time.cc: Update after last merge. More comments --- sql/item_strfunc.cc | 5 +++-- sql/log_event.cc | 11 +++++++---- sql/net_pkg.cc | 2 ++ sql/sql_acl.cc | 18 +++++++++--------- sql/sql_lex.cc | 2 +- sql/sql_parse.cc | 2 +- sql/sql_prepare.cc | 7 ++++--- sql/time.cc | 43 ++++++++++++++++++++++++++++++------------- 8 files changed, 57 insertions(+), 33 deletions(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 29eaf5a4ad9..2ef95bb8746 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -145,7 +145,7 @@ void Item_func_sha::fix_length_and_dec() String *Item_func_aes_encrypt::val_str(String *str) { char key_buff[80]; - String tmp_key_value(key_buff, sizeof(key_buff)); + String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info); String *sptr= args[0]->val_str(str); // String to encrypt String *key= args[1]->val_str(&tmp_key_value); // key int aes_length; @@ -180,7 +180,8 @@ void Item_func_aes_encrypt::fix_length_and_dec() String *Item_func_aes_decrypt::val_str(String *str) { char key_buff[80]; - String tmp_key_value(key_buff, sizeof(key_buff)), *sptr, *key; + String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info); + String *sptr, *key; DBUG_ENTER("Item_func_aes_decrypt::val_str"); sptr= args[0]->val_str(str); // String to decrypt diff --git a/sql/log_event.cc b/sql/log_event.cc index 70fc1a5ff23..1e6fe924682 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1526,7 +1526,7 @@ void Append_block_log_event::pack_info(String* packet) length= (uint) my_sprintf(buf, (buf, ";file_id=%u;block_len=%u", file_id, block_len)); - net_store_data(packet, buf, length); + net_store_data(packet, buf, (int32) length); } @@ -1571,7 +1571,7 @@ void Delete_file_log_event::pack_info(String* packet) char buf[64]; uint length; length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id)); - net_store_data(packet, buf, length); + net_store_data(packet, buf, (int32) length); } #endif @@ -1618,7 +1618,7 @@ void Execute_load_log_event::pack_info(String* packet) char buf[64]; uint length; length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id)); - net_store_data(packet, buf, length); + net_store_data(packet, buf, (int32) length); } #endif @@ -1659,7 +1659,9 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) mysql_log.write(thd,COM_QUERY,"%s",thd->query); DBUG_PRINT("query",("%s",thd->query)); mysql_parse(thd, thd->query, q_len); - if ((expected_error != (actual_error = thd->net.last_errno)) && + DBUG_PRINT("info",("expected_error: %d last_errno: %d", + expected_error, thd->net.last_errno)); + if ((expected_error != (actual_error= thd->net.last_errno)) && expected_error && !ignored_error_code(actual_error) && !ignored_error_code(expected_error)) @@ -1675,6 +1677,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) else if (expected_error == actual_error || ignored_error_code(actual_error)) { + DBUG_PRINT("info",("error ignored")); thd->query_error = 0; *rli->last_slave_error = 0; rli->last_slave_errno = 0; diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index b804724564e..ef90c12586b 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -31,6 +31,7 @@ void send_error(THD *thd, uint sql_errno, const char *err) net->last_error : "NULL")); query_cache_abort(net); + thd->query_error= 1; // needed to catch query errors during replication if (!err) { if (sql_errno) @@ -132,6 +133,7 @@ net_printf(THD *thd, uint errcode, ...) DBUG_ENTER("net_printf"); DBUG_PRINT("enter",("message: %u",errcode)); + thd->query_error= 1; // needed to catch query errors during replication query_cache_abort(net); // Safety va_start(args,errcode); /* diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index aab3e8899ce..5f8cf42c2bf 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -644,7 +644,7 @@ static void acl_update_user(const char *user, const char *host, { if (!acl_user->host.hostname && !host[0] || acl_user->host.hostname && - !my_strcasecmp(host,acl_user->host.hostname)) + !my_strcasecmp(system_charset_info, host, acl_user->host.hostname)) { acl_user->access=privileges; if (mqh->bits & 1) @@ -733,7 +733,8 @@ static void acl_update_db(const char *user, const char *host, const char *db, !strcmp(user,acl_db->user)) { if (!acl_db->host.hostname && !host[0] || - acl_db->host.hostname && !my_strcasecmp(host,acl_db->host.hostname)) + acl_db->host.hostname && + !my_strcasecmp(system_charset_info, host, acl_db->host.hostname)) { if (!acl_db->db && !db[0] || acl_db->db && !strcmp(db,acl_db->db)) @@ -1010,7 +1011,7 @@ bool check_change_password(THD *thd, const char *host, const char *user) } if (!thd->slave_thread && (strcmp(thd->user,user) || - my_strcasecmp(system_charset_info, host,thd->host_or_ip))) + my_strcasecmp(system_charset_info, host, thd->host_or_ip))) { if (check_access(thd, UPDATE_ACL, "mysql",0,1)) return(1); @@ -1662,7 +1663,6 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, char helping [NAME_LEN*2+USERNAME_LENGTH+3]; uint len; GRANT_TABLE *grant_table,*found=0; - safe_mutex_assert_owner(&LOCK_grant); len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1; for (grant_table=(GRANT_TABLE*) hash_search(&hash_tables,(byte*) helping, @@ -1672,7 +1672,8 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, { if (exact) { - if ((host && !my_strcasecmp(host,grant_table->host)) || + if ((host && + !my_strcasecmp(system_charset_info, host, grant_table->host)) || (ip && !strcmp(ip,grant_table->host))) return grant_table; } @@ -1872,7 +1873,6 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, int error=0; ulong store_table_rights, store_col_rights; DBUG_ENTER("replace_table_table"); - safe_mutex_assert_owner(&LOCK_grant); strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS); @@ -2734,7 +2734,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!(host=acl_user->host.hostname)) host="%"; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(lex_user->host.str,host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) break; } if (counter == acl_users.elements) @@ -2881,7 +2881,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) host=""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(lex_user->host.str,host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { want_access=acl_db->access; if (want_access) @@ -2940,7 +2940,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) host=""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(lex_user->host.str,host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { want_access=grant_table->privs; if ((want_access | grant_table->cols) != 0) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index fc6265f05af..a8e9bfb1757 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1082,7 +1082,7 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex, for (cursor= **result; cursor; cursor= cursor->next) if (!strcmp(cursor->db, aux->db) && !strcmp(cursor->real_name, aux->real_name) && - !strcmp(cursor->name, aux->name)) + !strcmp(cursor->alias, aux->alias)) break; if (!cursor) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d00f340c8d6..4b1251c5357 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1460,7 +1460,7 @@ mysql_execute_command(THD *thd) if (check_global_access(thd, REPL_SLAVE_ACL)) goto error; #ifndef WORKING_NEW_MASTER - net_printf(&thd->net, ER_NOT_SUPPORTED_YET, "SHOW NEW MASTER"); + net_printf(thd, ER_NOT_SUPPORTED_YET, "SHOW NEW MASTER"); res= 1; #else res = show_new_master(thd); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 05b3f360caa..a085795fa76 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -351,9 +351,10 @@ static int check_prepare_fields(THD *thd,TABLE *table, List &fields, } TABLE_LIST table_list; bzero((char*) &table_list,sizeof(table_list)); - table_list.name=table->table_name; - table_list.table=table; - table_list.grant=table->grant; + table_list.db= table->table_cache_key; + table_list.real_name= table_list.alias= table->table_name; + table_list.table= table; + table_list.grant= table->grant; thd->dupp_field=0; if (setup_tables(&table_list) || diff --git a/sql/time.cc b/sql/time.cc index e7c9ee82f93..0811b896bfc 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -418,13 +418,28 @@ ulong convert_month_to_period(ulong month) } -/***************************************************************************** -** convert a timestamp string to a TIME value. -** At least the following formats are recogniced (based on number of digits) -** YYMMDD, YYYYMMDD, YYMMDDHHMMSS, YYYYMMDDHHMMSS -** YY-MM-DD, YYYY-MM-DD, YY-MM-DD HH.MM.SS -** Returns the type of string -*****************************************************************************/ +/* + Convert a timestamp string to a TIME value. + + SYNOPSIS + str_to_TIME() + str String to parse + length Length of string + l_time Date is stored here + fuzzy_date 1 if we should allow dates where one part is zero + + DESCRIPTION + At least the following formats are recogniced (based on number of digits) + YYMMDD, YYYYMMDD, YYMMDDHHMMSS, YYYYMMDDHHMMSS + YY-MM-DD, YYYY-MM-DD, YY-MM-DD HH.MM.SS + YYYYMMDDTHHMMSS where T is a the character T (ISO8601) + Also dates where all parts are zero are allowed + + RETURN VALUES + TIMESTAMP_NONE String wasn't a timestamp + TIMESTAMP_DATE DATE string (YY MM and DD parts ok) + TIMESTAMP_FULL Full timestamp +*/ timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) @@ -441,9 +456,9 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) if (str == end) DBUG_RETURN(TIMESTAMP_NONE); /* - ** calculate first number of digits. - ** If length= 8 or >= 14 then year is of format YYYY. - (YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS) + calculate first number of digits. + If length= 8 or >= 14 then year is of format YYYY. + (YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS) */ for (pos=str; pos != end && my_isdigit(system_charset_info,*pos) ; pos++) ; digits= (uint) (pos-str); @@ -453,7 +468,8 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) for (i=0 ; i < 6 && str != end && my_isdigit(system_charset_info,*str) ; i++) { uint tmp_value=(uint) (uchar) (*str++ - '0'); - while (str != end && my_isdigit(system_charset_info,str[0]) && field_length--) + while (str != end && my_isdigit(system_charset_info,str[0]) && + field_length--) { tmp_value=tmp_value*10 + (uint) (uchar) (*str - '0'); str++; @@ -483,7 +499,8 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) str++; uint tmp_value=(uint) (uchar) (*str - '0'); field_length=3; - while (str++ != end && my_isdigit(system_charset_info,str[0]) && field_length--) + while (str++ != end && my_isdigit(system_charset_info,str[0]) && + field_length--) tmp_value=tmp_value*10 + (uint) (uchar) (*str - '0'); date[6]=tmp_value; not_zero_date|= tmp_value; @@ -505,7 +522,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date) { for (; str != end ; str++) { - if (!isspace(*str)) + if (!my_isspace(system_charset_info, *str)) { not_zero_date= 1; // Give warning break; -- cgit v1.2.1 From f094b6af4c5c32bfda7f74461d47675ab61722a0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Oct 2002 18:47:04 +0300 Subject: fixing EXPLAIN select types --- sql/sql_parse.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8166a156b8c..a898df89383 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1443,7 +1443,9 @@ mysql_execute_command(void) { SELECT_LEX *first= sl->master_unit()->first_select(); res= mysql_explain_select(thd, sl, - ((select_lex==sl)?"FIRST": + ((select_lex==sl)? + ((sl->next_select_in_list())?"PRIMARY": + "SIMPLE"): ((sl == first)? ((sl->depended)?"DEPENDENT SUBSELECT": "SUBSELECT"): -- cgit v1.2.1 From e607221a3cd778131cc9250108473819c9b8c8a0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Oct 2002 19:44:46 +0300 Subject: Fixed bug that causes select test to fail Now MySQL 4.1 is up to date with all patches from 4.0.4 and passes the test suite. mysql-test/r/rpl_log_pos.result: Fix results sql/sql_select.cc: Fixed bug that causes select test to fail --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7cc5fd4f9d8..55e07c8bb20 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2173,7 +2173,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, join->positions[idx].table= s; if (!best_key && idx == join->const_tables && s->table == join->sort_by_table && - join->thd->select_limit >= records) + join->unit->select_limit_cnt >= records) join->sort_by_table= (TABLE*) 1; // Must use temporary table /* -- cgit v1.2.1 From 72a3c80dbb131339406ec4a815f423a1bd8926cc Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Oct 2002 00:56:21 +0300 Subject: after merging fix --- sql/net_pkg.cc | 2 ++ sql/sql_parse.cc | 4 ++-- sql/sql_select.cc | 10 ++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index fc8bc77e713..9f91db95052 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -66,6 +66,8 @@ void send_error(THD *thd, uint sql_errno, const char *err) else { length=(uint) strlen(err); + set_if_smaller(length,MYSQL_ERRMSG_SIZE-1); + } VOID(net_write_command(net,(uchar) 255, "", 0, (char*) err,length)); thd->fatal_error=0; // Error message is given thd->net.report_error= 0; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 62744edd763..7902e66043d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1339,7 +1339,7 @@ mysql_execute_command(THD *thd) { if (!(explain_result= new select_send())) { - send_error(&thd->net, ER_OUT_OF_RESOURCES); + send_error(thd, ER_OUT_OF_RESOURCES); DBUG_VOID_RETURN; } //check rights @@ -1478,7 +1478,7 @@ mysql_execute_command(THD *thd) if (!explain_result) if (!(explain_result= new select_send())) { - send_error(&thd->net, ER_OUT_OF_RESOURCES); + send_error(thd, ER_OUT_OF_RESOURCES); DBUG_VOID_RETURN; } else diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c4b100e453e..35703e57d82 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -154,8 +154,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result) { int res; register SELECT_LEX *select_lex = &lex->select_lex; - - if (select_lex->next_select()) + fix_tables_pointers(select_lex); + if (select_lex->next_select()) res=mysql_union(thd,lex,result); else res=mysql_select(thd,(TABLE_LIST*) select_lex->table_list.first, @@ -171,7 +171,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) result->abort(); if (res || thd->net.report_error) { - send_error(&thd->net, 0, MYF(0)); + send_error(thd, 0, MYF(0)); res= 1; } delete result; @@ -7215,6 +7215,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, String tmp2(buff2,sizeof(buff2),default_charset_info); tmp1.length(0); tmp2.length(0); + + item_list.empty(); item_list.push_back(new Item_int((int)thd->lex.select->select_number)); item_list.push_back(new Item_string(thd->lex.select->type, strlen(thd->lex.select->type), @@ -7224,7 +7226,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, if (table->tmp_table == TMP_TABLE && table->derived_select_number != 0) { // Derived table name generation - buff[512]; + char buff[512]; int len= my_snprintf(buff, 512, "", table->derived_select_number); item_list.push_back(new Item_string(buff, len, default_charset_info)); -- cgit v1.2.1 From 9195963f56122b3ca7fa480607b8da9ae969a364 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Oct 2002 17:49:03 +0500 Subject: auto_increment for heap tables test case heap/hp_create.c: auto_increment for heap tables heap/hp_hash.c: auto_increment for heap tables heap/hp_info.c: auto_increment for heap tables heap/hp_test1.c: auto_increment for heap tables heap/hp_test2.c: auto_increment for heap tables heap/hp_update.c: auto_increment for heap tables heap/hp_write.c: auto_increment for heap tables include/heap.h: auto_increment for heap tables mysql-test/r/create.result: auto_increment for heap tables mysql-test/t/create.test: auto_increment for heap tables sql/ha_heap.cc: auto_increment for heap tables sql/ha_heap.h: auto_increment for heap tables --- sql/ha_heap.cc | 35 ++++++++++++++++++++++++++++++++--- sql/ha_heap.h | 5 +++-- 2 files changed, 35 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 5c314462666..6cfd3c881cc 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -35,7 +35,9 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) { if (!(file= heap_open(name, mode)) && my_errno == ENOENT) { - if (!create(name, table, NULL)) + HA_CREATE_INFO create_info; + bzero(&create_info, sizeof(create_info)); + if (!create(name, table, &create_info)) file= heap_open(name, mode); } return (file ? 0 : 1); @@ -51,6 +53,8 @@ int ha_heap::write_row(byte * buf) statistic_increment(ha_write_count,&LOCK_status); if (table->time_stamp) update_timestamp(buf+table->time_stamp-1); + if (table->next_number_field && buf == table->record[0]) + update_auto_increment(); return heap_write(file,buf); } @@ -161,6 +165,8 @@ void ha_heap::info(uint flag) index_file_length=info.index_length; max_data_file_length= info.max_records* info.reclength; delete_length= info.deleted * info.reclength; + if (flag & HA_STATUS_AUTO) + auto_increment_value= info.auto_increment; } int ha_heap::extra(enum ha_extra_function operation) @@ -234,11 +240,11 @@ ha_rows ha_heap::records_in_range(int inx, } } - int ha_heap::create(const char *name, TABLE *table, HA_CREATE_INFO *create_info) { uint key, parts, mem_per_row= 0; + uint auto_key= 0, auto_key_type= 0; ulong max_rows; HP_KEYDEF *keydef; HA_KEYSEG *seg; @@ -296,19 +302,42 @@ int ha_heap::create(const char *name, TABLE *table, seg->null_bit= 0; seg->null_pos= 0; } + if (field->flags & AUTO_INCREMENT_FLAG) + { + auto_key= key + 1; + auto_key_type= field->key_type(); + } } } mem_per_row+= MY_ALIGN(table->reclength + 1, sizeof(char*)); max_rows = (ulong) (current_thd->variables.max_heap_table_size / mem_per_row); + HP_CREATE_INFO hp_create_info; + hp_create_info.auto_key= auto_key; + hp_create_info.auto_key_type= auto_key_type; + hp_create_info.auto_increment= (create_info->auto_increment_value ? + create_info->auto_increment_value - 1 : 0); error= heap_create(fn_format(buff,name,"","",4+2), table->keys,keydef, table->reclength, ((table->max_rows < max_rows && table->max_rows) ? table->max_rows : max_rows), - table->min_rows); + table->min_rows, &hp_create_info); my_free((gptr) keydef, MYF(0)); if (file) info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); ref_length= sizeof(HEAP_PTR); return (error); } + +void ha_heap::update_create_info(HA_CREATE_INFO *create_info) +{ + table->file->info(HA_STATUS_AUTO); + if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) + create_info->auto_increment_value= auto_increment_value; +} + +longlong ha_heap::get_auto_increment() +{ + ha_heap::info(HA_STATUS_AUTO); + return auto_increment_value; +} diff --git a/sql/ha_heap.h b/sql/ha_heap.h index 504f5262bf3..f82a1a460d8 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -40,8 +40,7 @@ class ha_heap: public handler ulong table_flags() const { return (HA_READ_RND_SAME | HA_NO_INDEX | HA_KEYPOS_TO_RNDPOS | - HA_NO_BLOBS | HA_NULL_KEY | HA_REC_NOT_IN_SEQ | - HA_NO_AUTO_INCREMENT); + HA_NO_BLOBS | HA_NULL_KEY | HA_REC_NOT_IN_SEQ); } ulong index_flags(uint inx) const { @@ -63,6 +62,7 @@ class ha_heap: public handler int write_row(byte * buf); int update_row(const byte * old_data, byte * new_data); int delete_row(const byte * buf); + longlong get_auto_increment(); int index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag); int index_read_idx(byte * buf, uint idx, const byte * key, @@ -87,6 +87,7 @@ class ha_heap: public handler int delete_table(const char *from); int rename_table(const char * from, const char * to); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); + void update_create_info(HA_CREATE_INFO *create_info); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); -- cgit v1.2.1 From 31568581c557b8ed8d6b47874e50ddca808227e6 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Oct 2002 22:21:17 +0300 Subject: fixed error handling bug mysql-test/r/subselect.result: test for error handling bug mysql-test/t/subselect.test: test for error handling bug --- sql/item_subselect.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 99fc0bcdb67..7e0b2e201ec 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -119,21 +119,30 @@ Item::Type Item_subselect::type() const double Item_singleval_subselect::val () { if (engine->exec()) + { + assign_null(); return 0; + } return real_value; } longlong Item_singleval_subselect::val_int () { if (engine->exec()) + { + assign_null(); return 0; + } return int_value; } String *Item_singleval_subselect::val_str (String *str) { if (engine->exec() || null_value) + { + assign_null(); return 0; + } return &str_value; } @@ -157,21 +166,30 @@ void Item_exists_subselect::fix_length_and_dec() double Item_exists_subselect::val () { if (engine->exec()) + { + assign_null(); return 0; + } return (double) value; } longlong Item_exists_subselect::val_int () { if (engine->exec()) + { + assign_null(); return 0; + } return value; } String *Item_exists_subselect::val_str(String *str) { if (engine->exec()) + { + assign_null(); return 0; + } str->set(value); return str; } -- cgit v1.2.1 From e8e3f7728fbe66f75b328a56a48059552b0bea15 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Oct 2002 14:50:12 +0300 Subject: fixed couple of bugs in field/reference name resolution fixed error handling in subselect fix_field mysql-test/r/subselect.result: test of name resolution mysql-test/t/subselect.test: test of name resolution sql/item.cc: fixed couple of bugs in field/reference name resolution. sql/item_subselect.cc: fixed error handling sql/mysql_priv.h: fixed couple of bugs in field/reference name resolution. sql/sql_base.cc: fixed couple of bugs in field/reference name resolution. sql/sql_select.cc: new find_item_in_list interface --- sql/item.cc | 43 ++++++++++++++++++-------- sql/item_subselect.cc | 3 +- sql/mysql_priv.h | 7 ++++- sql/sql_base.cc | 85 +++++++++++++++++++++++++++++++++++++++++++-------- sql/sql_select.cc | 4 +-- 5 files changed, 113 insertions(+), 29 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index f1e25fb4d97..6da53b98657 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -432,7 +432,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (!field) // If field is not checked { Field *tmp; - if (!(tmp=find_field_in_tables(thd, this, tables, 0))) + if ((tmp= find_field_in_tables(thd, this, tables, 0)) == not_found_field) { /* We can't find table field in table list of current select, @@ -445,14 +445,18 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) */ SELECT_LEX *last= 0; for (SELECT_LEX *sl= thd->lex.select->outer_select(); - sl && !tmp; + sl; sl= sl->outer_select()) - tmp=find_field_in_tables(thd, this, - (TABLE_LIST*)(last= sl)->table_list.first, - 0); + if ((tmp= find_field_in_tables(thd, this, + (TABLE_LIST*) + (last= sl)->table_list.first, + 0)) != not_found_field) + break; if (!tmp) + return -1; + else if (tmp == not_found_field) { - // Call to produce appropriate error message + // call to return error code find_field_in_tables(thd, this, tables, 1); return -1; } @@ -478,7 +482,10 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) tbl->shared= 1; } } - } + } + else if (!tmp) + return -1; + set_field(tmp); } else if (thd && thd->set_query_id && field->query_id != thd->query_id) @@ -786,7 +793,9 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { if (!ref) { - if (!(ref= find_item_in_list(this, thd->lex.select->item_list, 0))) + if ((ref= find_item_in_list(this, thd->lex.select->item_list, + REPORT_EXCEPT_NOT_FOUND)) == + not_found_item) { /* We can't find table field in table list of current select, @@ -795,17 +804,25 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) of view rules. For example if both tables (outer & current) have field 'field' it is not mistake to refer to this field without mention of table name, but if we join tables in one list it will - cause error ER_NON_UNIQ_ERROR in find_field_in_tables. + cause error ER_NON_UNIQ_ERROR in find_item_in_list. */ SELECT_LEX *last=0; for (SELECT_LEX *sl= thd->lex.select->outer_select(); - sl && !ref; + sl; sl= sl->outer_select()) - ref= find_item_in_list(this, (last= sl)->item_list, 0); + if((ref= find_item_in_list(this, (last= sl)->item_list, + REPORT_EXCEPT_NOT_FOUND)) != + not_found_item) + break; + if (!ref) + { + return 1; + } + else if (ref == not_found_item) { // Call to report error - find_item_in_list(this, thd->lex.select->item_list, 1); + find_item_in_list(this, thd->lex.select->item_list, REPORT_ALL_ERRORS); return 1; } else @@ -831,6 +848,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) } } } + else if (!ref) + return 1; max_length= (*ref)->max_length; maybe_null= (*ref)->maybe_null; decimals= (*ref)->decimals; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 7e0b2e201ec..e8ee6a780ea 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -83,7 +83,8 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 1; } int res= engine->prepare(); - fix_length_and_dec(); + if (!res) + fix_length_and_dec(); return res; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 8e691c8f96c..b74a2da5f6d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -456,6 +456,7 @@ bool wait_for_tables(THD *thd); bool table_is_used(TABLE *table, bool wait_for_name_lock); bool drop_locked_tables(THD *thd,const char *db, const char *table_name); void abort_locked_tables(THD *thd,const char *db, const char *table_name); +extern const Field *not_found_field; Field *find_field_in_tables(THD *thd, Item_field *item, TABLE_LIST *tables, bool report_error); Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, @@ -545,7 +546,11 @@ TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find); SQL_SELECT *make_select(TABLE *head, table_map const_tables, table_map read_tables, COND *conds, int *error); -Item ** find_item_in_list(Item *item, List &items, bool report_error); +enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, + IGNORE_ERRORS}; +extern const Item **not_found_item; +Item ** find_item_in_list(Item *item, List &items, + find_item_error_report_type report_error); bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator *it); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8deae314484..78774b376b1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1781,9 +1781,29 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, return field; } +// Special Field pointer for find_field_in_tables returning +const Field *not_found_field= (Field*) 0x1; +/* + Find field in table list. + + SYNOPSIS + find_field_in_tables() + thd - pointer to current thread structure + item - field item that should be found + tables - tables for scaning + report_error - if FALSE then do not report error if item not found and + return not_found_field; + + RETURN VALUES + 0 - field is not found or field is not unique, error message is + reported + not_found_field - function was called with report_error == FALSE and + field if not found, no error message reported + found field +*/ Field * -find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables, +find_field_in_tables(THD *thd, Item_field *item, TABLE_LIST *tables, bool report_error) { Field *found=0; @@ -1829,13 +1849,18 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables, strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS); table_name=buff; } - my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0),table_name, - thd->where); + if (report_error) + my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), + table_name, thd->where); + else + return (Field*) not_found_field; } else if (report_error) my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), item->full_name(),thd->where); + else + return (Field*) not_found_field; return (Field*) 0; } bool allow_rowid= tables && !tables->next; // Only one table @@ -1850,11 +1875,10 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables, return (Field*) 0; if (found) { - if (!report_error) // Returns first found + if (!thd->where) // Returns first found break; - if (report_error) - my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), - name,thd->where); + my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), + name,thd->where); return (Field*) 0; } found=field; @@ -1865,11 +1889,39 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables, if (report_error) my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), item->full_name(), thd->where); + else + return (Field*) not_found_field; return (Field*) 0; } +// Special Item pointer for find_item_in_list returning +const Item **not_found_item= (const Item**) 0x1; + +/* + Find Item in list of items (find_field_in_tables analog) + + SYNOPSIS + find_item_in_list() + find - item to find + items - list of items + report_error + REPORT_ALL_ERRORS - report errors, return 0 if error + REPORT_EXCEPT_NOT_FOUND - do not report 'not found' error and return not_ found_item, report other errors, return 0 + IGNORE_ERRORS - do not report errors, return 0 if error + + RETURN VALUES + 0 - item is not found or item is not unique, error message is + reported + not_found_item - function was called with report_error == + REPORT_EXCEPT_NOT_FOUND and item if not found, no error + message reported + found field + +*/ + Item ** -find_item_in_list(Item *find, List &items, bool report_error) +find_item_in_list(Item *find, List &items, + find_item_error_report_type report_error) { List_iterator li(items); Item **found=0,*item; @@ -1894,7 +1946,7 @@ find_item_in_list(Item *find, List &items, bool report_error) { if ((*found)->eq(item,0)) continue; // Same field twice (Access?) - if (report_error) + if (report_error != IGNORE_ERRORS) my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), find->full_name(), current_thd->where); return (Item**) 0; @@ -1917,10 +1969,17 @@ find_item_in_list(Item *find, List &items, bool report_error) break; } } - if (!found && report_error) - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - find->full_name(), current_thd->where); - return found; + if (found) + return found; + else if (report_error != REPORT_EXCEPT_NOT_FOUND) + { + if (report_error == REPORT_ALL_ERRORS) + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), + find->full_name(), current_thd->where); + return (Item **) 0; + } + else + return (Item **) not_found_item; } /**************************************************************************** diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 35703e57d82..09d41e2891b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6487,7 +6487,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List &fields, order->in_field_list=1; return 0; } - Item **item=find_item_in_list(*order->item, fields, 0); + Item **item= find_item_in_list(*order->item, fields, IGNORE_ERRORS); if (item) { order->item=item; // use it @@ -6587,7 +6587,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List &fields, thd->set_query_id=1; // Not really needed, but... for (; new_field ; new_field= new_field->next) { - if ((item= find_item_in_list(*new_field->item, fields, 0))) + if ((item= find_item_in_list(*new_field->item, fields, IGNORE_ERRORS))) new_field->item=item; /* Change to shared Item */ else { -- cgit v1.2.1 From 58dc03066c8b8c38cdfa47e1f3c99ee002551b4f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Oct 2002 15:34:39 +0300 Subject: removed compiler warnings --- sql/item.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 6da53b98657..a0cb6f46f06 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -795,7 +795,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { if ((ref= find_item_in_list(this, thd->lex.select->item_list, REPORT_EXCEPT_NOT_FOUND)) == - not_found_item) + (Item **)not_found_item) { /* We can't find table field in table list of current select, @@ -812,14 +812,14 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) sl= sl->outer_select()) if((ref= find_item_in_list(this, (last= sl)->item_list, REPORT_EXCEPT_NOT_FOUND)) != - not_found_item) + (Item **)not_found_item) break; if (!ref) { return 1; } - else if (ref == not_found_item) + else if (ref == (Item **)not_found_item) { // Call to report error find_item_in_list(this, thd->lex.select->item_list, REPORT_ALL_ERRORS); -- cgit v1.2.1 From 81a82f0d6e68879ca68c4894c5832afdb4179487 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Oct 2002 12:39:37 +0000 Subject: support for --tmpdir=dir1:dir2:... --- sql/mysql_priv.h | 5 +++-- sql/mysqld.cc | 27 ++++++++------------------- sql/set_var.cc | 2 +- sql/sql_base.cc | 20 +++++++++++--------- 4 files changed, 23 insertions(+), 31 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 8e691c8f96c..3a22d7f8028 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -635,8 +635,9 @@ bool open_log(MYSQL_LOG *log, const char *hostname, extern time_t start_time; extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], - mysql_real_data_home[], *charsets_list; -extern my_string mysql_tmpdir; + mysql_real_data_home[], *charsets_list, *opt_mysql_tmpdir; +#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list)) +extern MY_TMPDIR mysql_tmpdir_list; extern const char *command_name[]; extern const char *first_keyword, *localhost, *delayed_user; extern const char **errmesg; /* Error messages */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a3a82d96b2e..1b4713706fb 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -395,7 +395,8 @@ const char *myisam_recover_options_str="OFF"; const char *sql_mode_str="OFF"; ulong rpl_recovery_rank=0; -my_string mysql_unix_port=NULL, opt_mysql_tmpdir=NULL, mysql_tmpdir=NULL; +my_string mysql_unix_port=NULL, opt_mysql_tmpdir=NULL; +MY_TMPDIR mysql_tmpdir_list; ulong my_bind_addr; /* the address we bind to */ char *my_bind_addr_str; DATE_FORMAT dayord; @@ -852,7 +853,7 @@ void clean_up(bool print_message) if (defaults_argv) free_defaults(defaults_argv); my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR)); + free_tmpdir(&mysql_tmpdir_list); my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR)); x_free(opt_bin_logname); x_free(opt_relay_logname); @@ -1834,17 +1835,6 @@ int main(int argc, char **argv) load_defaults(MYSQL_CONFIG_NAME,load_default_groups,&argc,&argv); defaults_argv=argv; - /* Get default temporary directory */ - opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */ -#if defined( __WIN__) || defined(OS2) - if (!opt_mysql_tmpdir) - opt_mysql_tmpdir=getenv("TEMP"); - if (!opt_mysql_tmpdir) - opt_mysql_tmpdir=getenv("TMP"); -#endif - if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0]) - opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */ - set_options(); get_options(argc,argv); if (opt_log || opt_update_log || opt_slow_log || opt_bin_log) @@ -3320,12 +3310,13 @@ struct my_option my_long_options[] = "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.", (gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"tmpdir", 't', "Path for temporary files", (gptr*) &opt_mysql_tmpdir, + {"tmpdir", 't', + "Path for temporary files. Several paths may be specified, separated by a colon (:), in this case they are used in a round-robin fashion.", + (gptr*) &opt_mysql_tmpdir, (gptr*) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"transaction-isolation", OPT_TX_ISOLATION, "Default transaction isolation level", 0, 0, 0, GET_NO_ARG, REQUIRED_ARG, 0, - 0, 0, 0, - 0, 0}, + 0, 0, 0, 0, 0}, {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running", (gptr*) &opt_external_locking, (gptr*) &opt_external_locking, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -4498,9 +4489,7 @@ static void fix_paths(void) charsets_dir=mysql_charsets_dir; } - char *end=convert_dirname(buff, opt_mysql_tmpdir, NullS); - if (!(mysql_tmpdir= my_memdup((byte*) buff,(uint) (end-buff)+1, - MYF(MY_FAE)))) + if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir)) exit(1); if (!slave_load_tmpdir) { diff --git a/sql/set_var.cc b/sql/set_var.cc index b221a3f98ff..72579664a3e 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -541,7 +541,7 @@ struct show_var_st init_vars[]= { {"timezone", time_zone, SHOW_CHAR}, #endif {sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS}, - {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR}, + {"tmpdir", (char*) &opt_mysql_tmpdir, SHOW_CHAR_PTR}, {"version", server_version, SHOW_CHAR}, {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout, SHOW_SYS}, {NullS, NullS, SHOW_LONG} diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8deae314484..e81d950e2e4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2227,30 +2227,32 @@ fill_record(Field **ptr,List &values) static void mysql_rm_tmp_tables(void) { - uint idx; - char filePath[FN_REFLEN]; + uint i, idx; + char filePath[FN_REFLEN], *tmpdir; MY_DIR *dirp; FILEINFO *file; DBUG_ENTER("mysql_rm_tmp_tables"); + for (i=0; i<=mysql_tmpdir_list.max; i++) + { + tmpdir=mysql_tmpdir_list.list[i]; /* See if the directory exists */ - if (!(dirp = my_dir(mysql_tmpdir,MYF(MY_WME | MY_DONT_SORT)))) - DBUG_VOID_RETURN; /* purecov: inspected */ + if (!(dirp = my_dir(tmpdir,MYF(MY_WME | MY_DONT_SORT)))) + continue; - /* - ** Remove all SQLxxx tables from directory - */ + /* Remove all SQLxxx tables from directory */ for (idx=2 ; idx < (uint) dirp->number_off_files ; idx++) { file=dirp->dir_entry+idx; if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length)) { - sprintf(filePath,"%s%s",mysql_tmpdir,file->name); /* purecov: inspected */ - VOID(my_delete(filePath,MYF(MY_WME))); /* purecov: inspected */ + sprintf(filePath,"%s%s",tmpdir,file->name); + VOID(my_delete(filePath,MYF(MY_WME))); } } my_dirend(dirp); + } DBUG_VOID_RETURN; } -- cgit v1.2.1 From a7430f38b30436d00cafcb33ce62f2f2efa0bc19 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Oct 2002 14:34:04 +0000 Subject: --tmpdir=dir1:dir2:... support in myisamchk --- sql/ha_myisam.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 4aae044148b..e02252e711f 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -559,7 +559,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) param.tmpfile_createflag = O_RDWR | O_TRUNC; param.using_global_keycache = 1; param.thd=thd; - param.tmpdir=mysql_tmpdir; + param.tmpdir=&mysql_tmpdir_list; param.out_flag=0; strmov(fixed_name,file->filename); @@ -718,7 +718,7 @@ bool ha_myisam::activate_all_index(THD *thd) T_CREATE_MISSING_KEYS); param.myf_rw&= ~MY_WAIT_IF_FULL; param.sort_buffer_length= thd->variables.myisam_sort_buff_size; - param.tmpdir=mysql_tmpdir; + param.tmpdir=&mysql_tmpdir_list; error=repair(thd,param,0) != HA_ADMIN_OK; thd->proc_info=save_proc_info; } -- cgit v1.2.1 From 40c2e7499b40a10ee2b8042e5d672b7c4d4c66fe Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Oct 2002 22:28:24 +0300 Subject: Portability fixes to be able to compile MySQL with VC++ VC++Files/client/mysqlclient.dsp: Updated VC++ files for 4.1 VC++Files/libmysql/libmysql.dsp: Updated VC++ files for 4.1 VC++Files/libmysqld/libmysqld.dsp: Updated VC++ files for 4.1 VC++Files/myisam/myisam.dsp: Updated VC++ files for 4.1 VC++Files/mysys/mysys.dsp: Updated VC++ files for 4.1 VC++Files/sql/mysqld.dsp: Updated VC++ files for 4.1 VC++Files/strings/strings.dsp: Updated VC++ files for 4.1 client/mysql.cc: Update for windows heap/_check.c: Fixed wrong DBUG_PRINT() usage include/mysql.h: Portability fix (uint -> unsigned int) libmysql/libmysql.def: Removed old my_casecmp function sql/ha_innodb.cc: Update for windows sql/init.cc: Removed not used variable sql/log.cc: Removed not used variable sql/net_pkg.cc: Portability fix sql/sql_db.cc: Portability fixes. Removed not used variables sql/sql_lex.h: Portability fix sql/sql_parse.cc: Portability fix sql/sql_prepare.cc: Removed not used variables sql/sql_select.cc: Portability fix sql/sql_show.cc: Portability fix sql/sql_union.cc: Portability fix --- sql/ha_innodb.cc | 4 ++-- sql/init.cc | 1 - sql/log.cc | 1 - sql/net_pkg.cc | 4 ++-- sql/sql_db.cc | 7 ++----- sql/sql_lex.h | 2 +- sql/sql_parse.cc | 5 +++-- sql/sql_prepare.cc | 1 - sql/sql_select.cc | 7 +++---- sql/sql_show.cc | 5 ++--- sql/sql_union.cc | 4 ++-- 11 files changed, 17 insertions(+), 24 deletions(-) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index b684d9dd4dd..824169467af 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3155,8 +3155,8 @@ innobase_drop_database( memcpy(namebuf, ptr, len); namebuf[len] = '/'; namebuf[len + 1] = '\0'; -#ifdef __WIN__ - casedn_str(namebuf); +#ifdef FN_NO_CASE_SENCE + my_casedn_str(system_charset_info, namebuf); #endif trx = trx_allocate_for_mysql(); diff --git a/sql/init.cc b/sql/init.cc index 052ee16925e..8834fd3a89c 100644 --- a/sql/init.cc +++ b/sql/init.cc @@ -24,7 +24,6 @@ void unireg_init(ulong options) { uint i; double nr; - CHARSET_INFO *cs; DBUG_ENTER("unireg_init"); MYSYS_PROGRAM_DONT_USE_CURSES(); diff --git a/sql/log.cc b/sql/log.cc index 59f99e3460e..8cb1577d745 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -973,7 +973,6 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, last_time=skr; struct tm tm_tmp; struct tm *start; - ulong length; localtime_r(&skr,&tm_tmp); start=&tm_tmp; /* Note that my_b_write() assumes it knows the length for this */ diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index 9f91db95052..1da625e776f 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -273,12 +273,12 @@ send_eof(THD *thd, bool no_flush) { if (!no_flush && (thd->client_capabilities & CLIENT_PROTOCOL_41)) { - char buff[5]; + uchar buff[5]; uint tmp= min(thd->total_warn_count, 65535); buff[0]=254; int2store(buff+1, tmp); int2store(buff+3, 0); // No flags yet - VOID(my_net_write(net,buff,5)); + VOID(my_net_write(net,(char*) buff,5)); VOID(net_flush(net)); } else diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 1d843b78d4e..58b12bca00d 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -69,7 +69,6 @@ static bool write_db_opt(const char *path, HA_CREATE_INFO *create) error=0; my_close(file,MYF(0)); } -exit: return error; } @@ -104,7 +103,7 @@ static bool load_db_opt(const char *path, HA_CREATE_INFO *create) IO_CACHE cache; init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)); - while ((int) (nbytes= my_b_gets(&cache, (byte*) buf, sizeof(buf))) > 0) + while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0) { char *pos= buf+nbytes-1; /* Remove end space and control characters */ @@ -251,10 +250,8 @@ exit2: int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { char path[FN_REFLEN+16]; - MY_DIR *dirp; long result=1; int error = 0; - register File file; uint create_options = create_info ? create_info->options : 0; DBUG_ENTER("mysql_alter_db"); @@ -602,7 +599,7 @@ bool mysql_change_db(THD *thd, const char *name) int mysqld_show_create_db(THD *thd, const char *dbname) { - int length, db_length; + int length; char path[FN_REFLEN], *to; uint db_access; bool found_libchar; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index acf73f34d5d..16c45c8300e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -210,7 +210,7 @@ private: SELECT_LEX_UNIT - unit of selects (UNION, INTERSECT, ...) group SELECT_LEXs */ -class st_lex; +struct st_lex; class st_select_lex; class THD; class select_result; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7902e66043d..e096ef7869e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1287,6 +1287,7 @@ mysql_execute_command(THD *thd) int res= 0; LEX *lex= &thd->lex; TABLE_LIST *tables= (TABLE_LIST*) lex->select_lex.table_list.first; + TABLE_LIST *cursor; SELECT_LEX *select_lex= &lex->select_lex; SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); @@ -1343,7 +1344,7 @@ mysql_execute_command(THD *thd) DBUG_VOID_RETURN; } //check rights - for (TABLE_LIST *cursor= tables; + for (cursor= tables; cursor; cursor= cursor->next) if (cursor->derived) @@ -1361,7 +1362,7 @@ mysql_execute_command(THD *thd) } thd->send_explain_fields(explain_result); // EXPLAIN derived tables - for (TABLE_LIST *cursor= tables; + for (cursor= tables; cursor; cursor= cursor->next) if (cursor->derived) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index a085795fa76..bd115f0fc1e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -634,7 +634,6 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length) { MEM_ROOT thd_root = thd->mem_root; PREP_STMT stmt; - bool error; DBUG_ENTER("mysql_stmt_prepare"); bzero((char*) &stmt, sizeof(stmt)); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 09d41e2891b..801a3e556d5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -171,7 +171,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) result->abort(); if (res || thd->net.report_error) { - send_error(thd, 0, MYF(0)); + send_error(thd, 0, NullS); res= 1; } delete result; @@ -7176,7 +7176,6 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, bool distinct,const char *message) { List field_list; - Item *item; List item_list; THD *thd=join->thd; SELECT_LEX *select_lex = &(join->thd->lex.select_lex); @@ -7190,7 +7189,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, if (message) { - item_list.push_back(new Item_int((int)thd->lex.select->select_number)); + item_list.push_back(new Item_int((int32) thd->lex.select->select_number)); item_list.push_back(new Item_string(thd->lex.select->type, strlen(thd->lex.select->type), default_charset_info)); @@ -7217,7 +7216,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, tmp2.length(0); item_list.empty(); - item_list.push_back(new Item_int((int)thd->lex.select->select_number)); + item_list.push_back(new Item_int((int32) thd->lex.select->select_number)); item_list.push_back(new Item_string(thd->lex.select->type, strlen(thd->lex.select->type), default_charset_info)); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 827067c27d7..8c4c104d180 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -230,7 +230,7 @@ int mysqld_show_table_types(THD *thd) const char *option_name= show_comp_option_name[(int) *types->value]; if (*types->value == SHOW_OPTION_YES && - !strcasecmp(default_type_name, types->type)) + !my_strcasecmp(system_charset_info, default_type_name, types->type)) option_name= "DEFAULT"; net_store_data(packet, option_name); net_store_data(packet, types->comment); @@ -1398,7 +1398,6 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) int mysqld_show_charsets(THD *thd, const char *wild) { - uint i; char buff[8192]; String packet2(buff,sizeof(buff),default_charset_info); List field_list; @@ -1425,7 +1424,7 @@ int mysqld_show_charsets(THD *thd, const char *wild) net_store_data(&packet2,convert,cs->name); net_store_data(&packet2,(uint32) cs->number); net_store_data(&packet2,(uint32) cs->strxfrm_multiply); - net_store_data(&packet2,(uint32) cs->mbmaxlen ? cs->mbmaxlen : 1); + net_store_data(&packet2,(uint32) (cs->mbmaxlen ? cs->mbmaxlen : 1)); if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length())) goto err; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 1a18759eb5b..c2ef25ce6a1 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -111,7 +111,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) DBUG_ENTER("st_select_lex_unit::prepare"); this->thd= thd; this->result= result; - SELECT_LEX *lex_select_save= thd->lex.select; + SELECT_LEX *lex_select_save= thd->lex.select, *sl; /* Global option */ if (((void*)(global_parameters)) == ((void*)this)) @@ -179,7 +179,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) // prepare selects joins.empty(); - for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + for (sl= first_select(); sl; sl= sl->next_select()) { JOIN *join= new JOIN(thd, sl->item_list, sl->options | thd->options | SELECT_NO_UNLOCK | -- cgit v1.2.1 From ac97cce4617a52d100cb2b5fa6c6c972c3510702 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Oct 2002 23:49:59 +0300 Subject: removed 'this' pointer from initialization list of constructors --- sql/item_subselect.cc | 29 ++++++++++++++++++----------- sql/item_subselect.h | 11 +++++++++-- 2 files changed, 27 insertions(+), 13 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index e8ee6a780ea..2d08b9cb6b5 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -32,11 +32,22 @@ SUBSELECT TODO: #include "mysql_priv.h" #include "sql_select.h" -Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex, - select_subselect *result): +Item_subselect::Item_subselect(): Item(), engine_owner(1), value_assigned(0) { - DBUG_ENTER("Item_subselect::Item_subselect"); + assign_null(); + /* + item value is NULL if select_subselect not changed this value + (i.e. some rows will be found returned) + */ + null_value= 1; +} + +void Item_subselect::init(THD *thd, st_select_lex *select_lex, + select_subselect *result) +{ + + DBUG_ENTER("Item_subselect::init"); DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex)); if (select_lex->next_select()) @@ -45,12 +56,6 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex, else engine= new subselect_single_select_engine(thd, select_lex, result, this); - assign_null(); - /* - item value is NULL if select_subselect not changed this value - (i.e. some rows will be found returned) - */ - null_value= 1; DBUG_VOID_RETURN; } @@ -100,8 +105,9 @@ inline table_map Item_subselect::used_tables() const Item_singleval_subselect::Item_singleval_subselect(THD *thd, st_select_lex *select_lex): - Item_subselect(thd, select_lex, new select_singleval_subselect(this)) + Item_subselect() { + init(thd, select_lex, new select_singleval_subselect(this)); max_columns= 1; maybe_null= 1; } @@ -149,8 +155,9 @@ String *Item_singleval_subselect::val_str (String *str) Item_exists_subselect::Item_exists_subselect(THD *thd, st_select_lex *select_lex): - Item_subselect(thd, select_lex, new select_exists_subselect(this)) + Item_subselect() { + init(thd, select_lex, new select_exists_subselect(this)); max_columns= UINT_MAX; null_value= 0; //can't be NULL maybe_null= 0; //can't be NULL diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 92839eb0e5f..5d070871b49 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -39,8 +39,7 @@ protected: uint max_columns; public: - Item_subselect(THD *thd, st_select_lex *select_lex, - select_subselect* result); + Item_subselect(); Item_subselect(Item_subselect *item) { null_value= item->null_value; @@ -50,6 +49,14 @@ public: engine_owner= 0; name= item->name; } + + /* + We need this method, because some compilers do not allow 'this' + pointer in constructor initialization list, but we need pass pointer + to subselect Item class to select_subselect classes constructor. + */ + void init (THD *thd, st_select_lex *select_lex, select_subselect *result); + ~Item_subselect(); virtual void assign_null() { -- cgit v1.2.1 From edb8ae0f3876d88c2ea8479afdc546ec3a18ea3b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 Oct 2002 15:40:57 +0500 Subject: Simple charsets now have strncoll() field too --- sql/field.cc | 6 +++--- sql/filesort.cc | 10 +++++----- sql/opt_range.cc | 2 +- sql/sql_string.cc | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 336bc9d7cc2..a65e9c4f7a4 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3841,7 +3841,7 @@ void Field_string::sort_string(char *to,uint length) else { #ifdef USE_STRCOLL - if (use_strcoll(field_charset)) { + if (use_strnxfrm(field_charset)) { uint tmp=my_strnxfrm(field_charset, (unsigned char *)to, length, (unsigned char *) ptr, field_length); @@ -4045,7 +4045,7 @@ void Field_varstring::sort_string(char *to,uint length) else { #ifdef USE_STRCOLL - if (use_strcoll(field_charset)) + if (use_strnxfrm(field_charset)) tot_length=my_strnxfrm(field_charset, (unsigned char *) to, length, (unsigned char *)ptr+2, tot_length); @@ -4536,7 +4536,7 @@ void Field_blob::sort_string(char *to,uint length) else { #ifdef USE_STRCOLL - if (use_strcoll(field_charset)) + if (use_strnxfrm(field_charset)) { blob_length=my_strnxfrm(field_charset, (unsigned char *)to, length, diff --git a/sql/filesort.cc b/sql/filesort.cc index 4d877c92dba..81629684a87 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -140,7 +140,7 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length, records=param.max_rows; /* purecov: inspected */ #ifdef USE_STRCOLL - if (use_strcoll(charset) && + if (use_strnxfrm(charset) && !(param.tmp_buffer=my_malloc(param.sort_length,MYF(MY_WME)))) goto err; #endif @@ -511,7 +511,7 @@ static void make_sortkey(register SORTPARAM *param, length=sort_field->length; } #ifdef USE_STRCOLL - if(use_strcoll(cs)) + if(use_strnxfrm(cs)) { if (item->binary) { @@ -541,7 +541,7 @@ static void make_sortkey(register SORTPARAM *param, memcpy(to,res->ptr(),length); bzero((char *)to+length,diff); if (!item->binary) - case_sort(cs, (char*) to,length); + my_tosort(cs, (char*) to,length); #ifdef USE_STRCOLL } #endif @@ -946,7 +946,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length) if (!sortorder->field->binary()) { CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); - if (use_strcoll(cs)) + if (use_strnxfrm(cs)) sortorder->length= sortorder->length*cs->strxfrm_multiply; } #endif @@ -966,7 +966,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length) if (!sortorder->item->binary) { CHARSET_INFO *cs=sortorder->item->str_value.charset(); - if (use_strcoll(cs)) + if (use_strnxfrm(cs)) sortorder->length= sortorder->length*cs->strxfrm_multiply; } #endif diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ed5b2b0a230..2b0ac08fe95 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -978,7 +978,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, { CHARSET_INFO *charset=((Field_str*)(field))->charset(); #ifdef USE_STRCOLL - if (use_strcoll(charset)) + if (use_strnxfrm(charset)) like_error= my_like_range(charset, res->ptr(),res->length(),wild_prefix, field_length, min_str+maybe_null, diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 6a42078cbcd..d2d14d4e7a2 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -505,7 +505,7 @@ int sortcmp(const String *x,const String *y) uint32 x_len=x->length(),y_len=y->length(),len=min(x_len,y_len); #ifdef USE_STRCOLL - if (use_strcoll(x->str_charset)) + if (use_strnxfrm(x->str_charset)) { #ifndef CMP_ENDSPACE while (x_len && my_isspace(x->str_charset,s[x_len-1])) -- cgit v1.2.1 From 1b623a4032eeeb62e42a0f9c21cfe83c02c8ed4f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 Oct 2002 16:33:35 +0500 Subject: my_sortcmp -> my_strnncoll BitKeeper/deleted/.del-mf_casecnv.c~c269ed3dcafea441: Delete: mysys/mf_casecnv.c --- sql/field.cc | 36 +++++++++++++++++++++++++++--------- sql/ha_innodb.cc | 6 +++--- sql/item_sum.cc | 4 +++- sql/key.cc | 5 +++-- 4 files changed, 36 insertions(+), 15 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index a65e9c4f7a4..cdbe05669d0 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3831,7 +3831,9 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) if (binary_flag) return memcmp(a_ptr,b_ptr,field_length); else - return my_sortcmp(field_charset,a_ptr,b_ptr,field_length); + return my_strnncoll(field_charset, + (const uchar*)a_ptr,field_length, + (const uchar*)b_ptr,field_length); } void Field_string::sort_string(char *to,uint length) @@ -3907,7 +3909,9 @@ int Field_string::pack_cmp(const char *a, const char *b, uint length) int cmp= memcmp(a,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(field_charset, a,a_length, b,b_length); + return my_strnncoll(field_charset, + (const uchar*)a,a_length, + (const uchar*)b,b_length); } @@ -3924,7 +3928,9 @@ int Field_string::pack_cmp(const char *b, uint length) int cmp= memcmp(ptr,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(field_charset, ptr,a_length, b, b_length); + return my_strnncoll(field_charset, + (const uchar*)ptr,a_length, + (const uchar*)b, b_length); } @@ -4033,7 +4039,9 @@ int Field_varstring::cmp(const char *a_ptr, const char *b_ptr) if (binary_flag) diff=memcmp(a_ptr+2,b_ptr+2,min(a_length,b_length)); else - diff=my_sortcmp(field_charset, a_ptr+2,b_ptr+2,min(a_length,b_length)); + diff=my_strnncoll(field_charset, + (const uchar*)a_ptr+2,min(a_length,b_length), + (const uchar*)b_ptr+2,min(a_length,b_length)); return diff ? diff : (int) (a_length - b_length); } @@ -4134,7 +4142,9 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length) int cmp= memcmp(a,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(field_charset, a,a_length, b,b_length); + return my_strnncoll(field_charset, + (const uchar *)a,a_length, + (const uchar *)b,b_length); } int Field_varstring::pack_cmp(const char *b, uint key_length) @@ -4155,7 +4165,9 @@ int Field_varstring::pack_cmp(const char *b, uint key_length) int cmp= memcmp(a,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(field_charset, a,a_length, b,b_length); + return my_strnncoll(field_charset, + (const uchar *)a,a_length, + (const uchar *)b,b_length); } uint Field_varstring::packed_col_length(const char *ptr, uint length) @@ -4382,7 +4394,9 @@ int Field_blob::cmp(const char *a,uint32 a_length, const char *b, if (binary_flag) diff=memcmp(a,b,min(a_length,b_length)); else - diff=my_sortcmp(field_charset, a,b,min(a_length,b_length)); + diff=my_strnncoll(field_charset, + (const uchar*)a,min(a_length,b_length), + (const uchar*)b,min(a_length,b_length)); return diff ? diff : (int) (a_length - b_length); } @@ -4631,7 +4645,9 @@ int Field_blob::pack_cmp(const char *a, const char *b, uint key_length) int cmp= memcmp(a,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(field_charset, a,a_length, b,b_length); + return my_strnncoll(field_charset, + (const uchar *)a,a_length, + (const uchar *)b,b_length); } @@ -4657,7 +4673,9 @@ int Field_blob::pack_cmp(const char *b, uint key_length) int cmp= memcmp(a,b,min(a_length,b_length)); return cmp ? cmp : (int) (a_length - b_length); } - return my_sortncmp(field_charset, a,a_length, b,b_length); + return my_strnncoll(field_charset, + (const uchar *)a,a_length, + (const uchar *)b,b_length); } /* Create a packed key that will be used for storage from a MySQL row */ diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index b684d9dd4dd..02f1d33b1dc 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1366,9 +1366,9 @@ innobase_mysql_cmp( case FIELD_TYPE_VAR_STRING: // BAR TODO: Discuss with heikki.tuuri@innodb.com // so that he sends CHARSET_INFO for the field to this function. - ret = my_sortncmp(default_charset_info, - (const char*) a, a_length, - (const char*) b, b_length); + ret = my_strnncoll(default_charset_info, + a, a_length, + b, b_length); if (ret < 0) { return(-1); } else if (ret > 0) { diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 93ced79005f..4d25098bb88 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -866,7 +866,9 @@ static int simple_raw_key_cmp(void* arg, byte* key1, byte* key2) static int simple_str_key_cmp(void* arg, byte* key1, byte* key2) { /* BAR TODO: remove default_charset_info */ - return my_sortcmp(default_charset_info,(char*) key1, (char*) key2, *(uint*) arg); + return my_strnncoll(default_charset_info, + (const uchar*) key1, *(uint*) arg, + (const uchar*) key2, *(uint*) arg); } /* diff --git a/sql/key.cc b/sql/key.cc index fa09a0a6d44..84669808b92 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -193,8 +193,9 @@ int key_cmp(TABLE *table,const byte *key,uint idx,uint key_length) FIELDFLAG_PACK))) { /* BAR TODO: I'm not sure this should be system_charset_info */ - if (my_sortcmp(system_charset_info,(char*) key, - (char*) table->record[0]+key_part->offset,length)) + if (my_strnncoll(system_charset_info, + (const uchar*) key, length, + (const uchar*) table->record[0]+key_part->offset,length)) return 1; } else if (memcmp(key,table->record[0]+key_part->offset,length)) -- cgit v1.2.1 From b9bb3534f1ca2af09f636253650b68b0f2840f65 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 10 Oct 2002 15:52:32 +0500 Subject: Some reorganization to use less memory as well as to hide some implementation aspects into *.c files from *.h files. Some steps to get closer to generating *.c files from *.conf files again. --- sql/sql_show.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 827067c27d7..214cd321562 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1403,7 +1403,7 @@ int mysqld_show_charsets(THD *thd, const char *wild) String packet2(buff,sizeof(buff),default_charset_info); List field_list; CONVERT *convert=thd->variables.convert_set; - CHARSET_INFO *cs; + CHARSET_INFO **cs; DBUG_ENTER("mysqld_show_charsets"); field_list.push_back(new Item_empty_string("Name",30)); @@ -1416,16 +1416,16 @@ int mysqld_show_charsets(THD *thd, const char *wild) for (cs=all_charsets ; cs < all_charsets+255 ; cs++ ) { - if (!cs->name) + if (!cs[0]) continue; if (!(wild && wild[0] && - wild_case_compare(system_charset_info,cs->name,wild))) + wild_case_compare(system_charset_info,cs[0]->name,wild))) { packet2.length(0); - net_store_data(&packet2,convert,cs->name); - net_store_data(&packet2,(uint32) cs->number); - net_store_data(&packet2,(uint32) cs->strxfrm_multiply); - net_store_data(&packet2,(uint32) cs->mbmaxlen ? cs->mbmaxlen : 1); + net_store_data(&packet2,convert,cs[0]->name); + net_store_data(&packet2,(uint32) cs[0]->number); + net_store_data(&packet2,(uint32) cs[0]->strxfrm_multiply); + net_store_data(&packet2,(uint32) cs[0]->mbmaxlen ? cs[0]->mbmaxlen : 1); if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length())) goto err; -- cgit v1.2.1 From 261c22a87a7214264b67eed7fb12608baafdfbc4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 11 Oct 2002 17:00:11 +0300 Subject: fixed bug in subselect value storing mysql-test/r/subselect.result: test for bug in subselect value storing mysql-test/t/subselect.test: test for bug in subselect value storing --- sql/item_subselect.cc | 2 ++ sql/item_subselect.h | 13 ++++++++++--- sql/sql_class.cc | 11 ++++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 2d08b9cb6b5..26cc376739a 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -150,6 +150,8 @@ String *Item_singleval_subselect::val_str (String *str) assign_null(); return 0; } + // Assign temporary buffer with stored value + str_value.set(string_value, 0, string_value.length()); return &str_value; } diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 5d070871b49..79b6b3a4292 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -80,10 +80,16 @@ public: class Item_singleval_subselect :public Item_subselect { protected: - longlong int_value; /* here stored integer value of this item */ - double real_value; /* here stored real value of this item */ + longlong int_value; /* Here stored integer value of this item */ + double real_value; /* Here stored real value of this item */ + /* + Here stored string value of this item. + (str_value used only as temporary buffer, because it can be changed + by Item::save_field) + */ + String string_value; enum Item_result res_type; /* type of results */ - + public: Item_singleval_subselect(THD *thd, st_select_lex *select_lex); Item_singleval_subselect(Item_singleval_subselect *item): @@ -91,6 +97,7 @@ public: { int_value= item->int_value; real_value= item->real_value; + string_value.set(item->string_value, 0, item->string_value.length()); max_length= item->max_length; decimals= item->decimals; res_type= item->res_type; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 648e05c1610..f778a721f54 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -884,9 +884,14 @@ bool select_singleval_subselect::send_data(List &items) it->decimals= val_item->decimals; it->binary= val_item->binary; it->int_value= val_item->val_int(); - String *s= val_item->val_str(&it->str_value); - if (s != &it->str_value) - it->str_value.set(*s, 0, s->length()); + String *s= val_item->val_str(&it->string_value); + if (s != &it->string_value) + { + it->string_value.set(*s, 0, s->length()); + } + // TODO: remove when correct charset handling appeared for Item + it->str_value.set(*s, 0, s->length()); // store charset + it->res_type= val_item->result_type(); } it->assigned(1); -- cgit v1.2.1 From 102cec14653cf1bacbcff81eee9b726a85c145b1 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 12 Oct 2002 01:09:47 +0300 Subject: fixed subselect * bug mysql-test/r/subselect.result: test of subselect * bug mysql-test/t/subselect.test: test of subselect * bug --- sql/item_subselect.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 26cc376739a..cd4403ad0b8 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -81,15 +81,17 @@ void Item_subselect::make_field (Send_field *tmp_field) bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { - // Is it one field subselect? - if (engine->cols() > max_columns) - { - my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0)); - return 1; - } int res= engine->prepare(); if (!res) + { + // Is it one field subselect? + if (engine->cols() > max_columns) + { + my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0)); + return 1; + } fix_length_and_dec(); + } return res; } -- cgit v1.2.1 From 2b70d7e56763e4b79feaf7f948ca2844a084861e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 12 Oct 2002 17:43:40 +0000 Subject: --tmpdir=dir1:dir2... uses (is_windows ? ";" : ":") as a delimiter --- sql/mysqld.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1b4713706fb..8497fe90758 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2931,13 +2931,13 @@ struct my_option my_long_options[] = #endif /* HAVE_BERKELEY_DB */ {"skip-bdb", OPT_BDB_SKIP, "Don't use berkeley db (will save memory)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"big-tables", OPT_BIG_TABLES, + {"big-tables", OPT_BIG_TABLES, "Allow big result sets by saving all temporary sets on file (Solves most 'table full' errors)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"binlog-do-db", OPT_BINLOG_DO_DB, "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB, + {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB, "Tells the master that updates to the given database should not be logged tothe binary log", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to", @@ -3306,12 +3306,18 @@ struct my_option my_long_options[] = #ifdef HAVE_OPENSSL #include "sslopt-longopts.h" #endif - {"temp-pool", OPT_TEMP_POOL, + {"temp-pool", OPT_TEMP_POOL, "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.", (gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"tmpdir", 't', - "Path for temporary files. Several paths may be specified, separated by a colon (:), in this case they are used in a round-robin fashion.", + "Path for temporary files. Several paths may be specified, separated by a " +#if defined( __WIN__) || defined(OS2) + "semicolon (;)" +#else + "colon (:)" +#endif + ", in this case they are used in a round-robin fashion.", (gptr*) &opt_mysql_tmpdir, (gptr*) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"transaction-isolation", OPT_TX_ISOLATION, -- cgit v1.2.1 From a299a27021a7bdd65f93f99f9eb0003f082b305d Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 13 Oct 2002 14:25:16 +0300 Subject: fixed bug of multi-level EXPLAIN mysql-test/r/subselect.result: test of multi-level EXPLAIN mysql-test/t/subselect.test: test of multi-level EXPLAIN --- sql/item_subselect.cc | 5 ++++- sql/item_subselect.h | 3 ++- sql/sql_lex.cc | 2 +- sql/sql_lex.h | 1 + sql/sql_union.cc | 7 ++++++- 5 files changed, 14 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index cd4403ad0b8..de9c7e11313 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -212,7 +212,7 @@ subselect_single_select_engine::subselect_single_select_engine(THD *thd, select_subselect *result, Item_subselect *item): subselect_engine(thd, item, result), - executed(0), optimized(0) + prepared(0), optimized(0), executed(0) { select_lex= select; SELECT_LEX_UNIT *unit= select_lex->master_unit(); @@ -251,6 +251,9 @@ subselect_union_engine::subselect_union_engine(THD *thd, int subselect_single_select_engine::prepare() { + if (prepared) + return 0; + prepared= 1; SELECT_LEX *save_select= thd->lex.select; thd->lex.select= select_lex; if(join->prepare((TABLE_LIST*) select_lex->table_list.first, diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 79b6b3a4292..33f82982708 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -179,8 +179,9 @@ public: class subselect_single_select_engine: public subselect_engine { - my_bool executed; /* simple subselect is executed */ + my_bool prepared; /* simple subselect is prepared */ my_bool optimized; /* simple subselect is optimized */ + my_bool executed; /* simple subselect is executed */ st_select_lex *select_lex; /* corresponding select_lex */ JOIN * join; /* corresponding JOIN structure */ public: diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 122ceeedc54..46206079084 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -944,7 +944,7 @@ void st_select_lex_unit::init_query() global_parameters= this; select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; - optimized= 0; + prepared= optimized= 0; item= 0; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index acf73f34d5d..fe708d3b782 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -227,6 +227,7 @@ protected: select_result *result; int res; bool describe, found_rows_for_union, + prepared, //prepare phase already performed for UNION (unit) optimized; // optimize phase already performed for UNION (unit) public: /* diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 1a18759eb5b..74cb8f6ffea 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -104,11 +104,16 @@ bool select_union::flush() typedef JOIN * JOIN_P; int st_select_lex_unit::prepare(THD *thd, select_result *result) { + DBUG_ENTER("st_select_lex_unit::prepare"); + + if (prepared) + DBUG_RETURN(0); + prepared= 1; + describe=(first_select()->options & SELECT_DESCRIBE) ? 1 : 0; res= 0; found_rows_for_union= false; TMP_TABLE_PARAM tmp_table_param; - DBUG_ENTER("st_select_lex_unit::prepare"); this->thd= thd; this->result= result; SELECT_LEX *lex_select_save= thd->lex.select; -- cgit v1.2.1 From 8290f609a7a407a86c4442c3c4a0322b736b871e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Oct 2002 14:33:42 +0300 Subject: fixed cteate temporary field of subselect bug mysql-test/r/subselect.result: test of cteate temporary field of subselect bug mysql-test/t/subselect.test: test of cteate temporary field of subselect bug --- sql/sql_select.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 09d41e2891b..f7d585e85f8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3605,6 +3605,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::COND_ITEM: case Item::FIELD_AVG_ITEM: case Item::FIELD_STD_ITEM: + case Item::SUBSELECT_ITEM: /* The following can only happen with 'CREATE TABLE ... SELECT' */ case Item::INT_ITEM: case Item::REAL_ITEM: -- cgit v1.2.1 From 57ec26c1e41d0d73dabb9a467cdf361811626bc6 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Oct 2002 11:55:28 +0000 Subject: bad merge fixed --- sql/sql_cache.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 9fa534da799..5bdefbaaa30 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1401,13 +1401,13 @@ ulong Query_cache::init_cache() VOID(hash_init(&queries,system_charset_info,def_query_hash_size, 0, 0, query_cache_query_get_key, 0, 0)); #ifndef FN_NO_CASE_SENCE - VOID(hash_init(&tables,def_table_hash_size, 0, 0, + VOID(hash_init(&tables,system_charset_info,def_table_hash_size, 0, 0, query_cache_table_get_key, 0, 0)); #else // windows, OS/2 or other case insensitive file names work around - VOID(hash_init(&tables,def_table_hash_size, 0, 0, + VOID(hash_init(&tables,system_charset_info,def_table_hash_size, 0, 0, query_cache_table_get_key, 0, - (lower_case_table_names?0:HASH_CASE_INSENSITIVE))); + (lower_case_table_names?0:HASH_CASE_INSENSITIVE))); #endif queries_in_cache = 0; -- cgit v1.2.1 From 5dcaaf4e04f19f9dc6a4ae4e1ef9746a3ff3cf6b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Oct 2002 22:41:42 +0300 Subject: removed annecessary assignment found by Monty --- sql/item_subselect.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index de9c7e11313..456ce5f22ba 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -152,9 +152,7 @@ String *Item_singleval_subselect::val_str (String *str) assign_null(); return 0; } - // Assign temporary buffer with stored value - str_value.set(string_value, 0, string_value.length()); - return &str_value; + return &string_value; } Item_exists_subselect::Item_exists_subselect(THD *thd, -- cgit v1.2.1 From aee5ef8516ce0599402ca8e8a6b72f3eca36739b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 16 Oct 2002 17:21:47 +0300 Subject: Added THD as parameter to filesort. Removed not used 'special' argument. sql/mysql_priv.h: Fix for changed parameters to filesort sql/sql_delete.cc: Fix for changed parameters to filesort sql/sql_select.cc: Fix for changed parameters to filesort sql/sql_table.cc: Fix for changed parameters to filesort sql/sql_test.cc: Removed not used special parameter sql/sql_update.cc: Fix for changed parameters to filesort --- sql/filesort.cc | 29 +++++++---------------------- sql/mysql_priv.h | 8 ++++---- sql/sql_delete.cc | 4 ++-- sql/sql_select.cc | 19 ++++++++++--------- sql/sql_table.cc | 4 ++-- sql/sql_test.cc | 4 +--- sql/sql_update.cc | 4 ++-- 7 files changed, 28 insertions(+), 44 deletions(-) (limited to 'sql') diff --git a/sql/filesort.cc b/sql/filesort.cc index 81629684a87..e1c673aca0b 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -63,24 +63,21 @@ static uint sortlength(SORT_FIELD *sortorder,uint length); table->record_pointers */ -ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length, - SQL_SELECT *select, ha_rows special, ha_rows max_rows, - ha_rows *examined_rows) +ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, + SQL_SELECT *select, ha_rows max_rows, ha_rows *examined_rows) { int error; ulong memavl; uint maxbuffer; + uint i; BUFFPEK *buffpek; ha_rows records; uchar **sort_keys; IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile; SORTPARAM param; - THD *thd= current_thd; - - DBUG_ENTER("filesort"); - DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length,special);); CHARSET_INFO *charset=table->table_charset; - uint i; + DBUG_ENTER("filesort"); + DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length);); #ifdef SKIP_DBUG_IN_FILESORT DBUG_PUSH(""); /* No DBUG here */ #endif @@ -111,27 +108,15 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length, { statistic_increment(filesort_scan_count, &LOCK_status); } - if (select && my_b_inited(&select->file)) - { - records=special=select->records; /* purecov: deadcode */ - selected_records_file= &select->file; /* purecov: deadcode */ - reinit_io_cache(selected_records_file,READ_CACHE,0L,0,0); /* purecov: deadcode */ - } - else if (special) - { - records=special; /* purecov: deadcode */ - selected_records_file= outfile; /* purecov: deadcode */ - reinit_io_cache(selected_records_file,READ_CACHE,0L,0,0); /* purecov: deadcode */ - } #ifdef CAN_TRUST_RANGE - else if (select && select->quick && select->quick->records > 0L) + if (select && select->quick && select->quick->records > 0L) { records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2), table->file->records)+EXTRA_RECORDS; selected_records_file=0; } -#endif else +#endif { records=table->file->estimate_number_of_rows(); selected_records_file= 0; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d8281af6bd1..6b8c4fd1f14 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -611,7 +611,7 @@ pthread_handler_decl(handle_manager, arg); #ifndef DBUG_OFF void print_where(COND *cond,const char *info); void print_cached_tables(void); -void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special); +void TEST_filesort(SORT_FIELD *sortorder,uint s_length); #endif void mysql_print_status(THD *thd); /* key.cc */ @@ -792,9 +792,9 @@ void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, SQL_SELECT *select, int use_record_cache, bool print_errors); void end_read_record(READ_RECORD *info); -ha_rows filesort(TABLE *form,struct st_sort_field *sortorder, uint s_length, - SQL_SELECT *select, ha_rows special,ha_rows max_rows, - ha_rows *examined_rows); +ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder, + uint s_length, SQL_SELECT *select, + ha_rows max_rows, ha_rows *examined_rows); void change_double_for_sort(double nr,byte *to); int get_quick_record(SQL_SELECT *select); int calc_weekday(long daynr,bool sunday_first_day_of_week); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 686fee0abe6..cb1a9db70cd 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -117,8 +117,8 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, MYF(MY_FAE | MY_ZEROFILL)); if (setup_order(thd, &tables, fields, all_fields, order) || !(sortorder=make_unireg_sortorder(order, &length)) || - (table->found_records = filesort(table, sortorder, length, - (SQL_SELECT *) 0, 0L, HA_POS_ERROR, + (table->found_records = filesort(thd, table, sortorder, length, + (SQL_SELECT *) 0, HA_POS_ERROR, &examined_rows)) == HA_POS_ERROR) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c120dc9d16f..399bbbb5e66 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -112,7 +112,8 @@ static Item* part_of_refkey(TABLE *form,Field *field); static uint find_shortest_key(TABLE *table, key_map usable_keys); static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order, ha_rows select_limit, bool no_changes); -static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit); +static int create_sort_index(THD *thd, JOIN_TAB *tab,ORDER *order, + ha_rows select_limit); static int remove_duplicates(JOIN *join,TABLE *entry,List &fields, Item *having); static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field, @@ -748,7 +749,7 @@ JOIN::exec() { DBUG_PRINT("info",("Sorting for group")); thd->proc_info="Sorting for group"; - if (create_sort_index(&join_tab[const_tables], group_list, + if (create_sort_index(thd, &join_tab[const_tables], group_list, HA_POS_ERROR) || make_sum_func_list(this, all_fields) || alloc_group_fields(this, group_list)) @@ -763,7 +764,7 @@ JOIN::exec() { DBUG_PRINT("info",("Sorting for order")); thd->proc_info="Sorting for order"; - if (create_sort_index(&join_tab[const_tables], order, + if (create_sort_index(thd, &join_tab[const_tables], order, HA_POS_ERROR)) DBUG_VOID_RETURN; order=0; @@ -866,7 +867,7 @@ JOIN::exec() if (group_list) { thd->proc_info="Creating sort index"; - if (create_sort_index(join_tab, group_list, HA_POS_ERROR) || + if (create_sort_index(thd, join_tab, group_list, HA_POS_ERROR) || alloc_group_fields(this, group_list)) { free_tmp_table(thd,tmp_table2); /* purecov: inspected */ @@ -962,7 +963,7 @@ JOIN::exec() DBUG_EXECUTE("where",print_where(conds,"having after sort");); } } - if (create_sort_index(&join_tab[const_tables], + if (create_sort_index(thd, &join_tab[const_tables], group_list ? group_list : order, (having_list || group_list || (select_options & OPTION_FOUND_ROWS)) ? @@ -5795,7 +5796,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, *****************************************************************************/ static int -create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) +create_sort_index(THD *thd, JOIN_TAB *tab,ORDER *order,ha_rows select_limit) { SORT_FIELD *sortorder; uint length; @@ -5839,8 +5840,8 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) } if (table->tmp_table) table->file->info(HA_STATUS_VARIABLE); // Get record count - table->found_records=filesort(table,sortorder,length, - select, 0L, select_limit, &examined_rows); + table->found_records=filesort(thd, table,sortorder, length, + select, select_limit, &examined_rows); tab->records=table->found_records; // For SQL_CALC_ROWS delete select; // filesort did select tab->select=0; @@ -5938,7 +5939,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List &fields, Item *having) int error; ulong reclength,offset; uint field_count; - THD *thd= current_thd; + THD *thd= join->thd; DBUG_ENTER("remove_duplicates"); entry->reginfo.lock_type=TL_WRITE; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a71f555cdd7..bff07809861 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2099,8 +2099,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, if (setup_order(thd, &tables, fields, all_fields, order) || !(sortorder=make_unireg_sortorder(order, &length)) || - (from->found_records = filesort(from, sortorder, length, - (SQL_SELECT *) 0, 0L, HA_POS_ERROR, + (from->found_records = filesort(thd, from, sortorder, length, + (SQL_SELECT *) 0, HA_POS_ERROR, &examined_rows)) == HA_POS_ERROR) goto err; diff --git a/sql/sql_test.cc b/sql/sql_test.cc index ef26a1f45fe..538417f43ea 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -97,7 +97,7 @@ void print_cached_tables(void) } -void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special) +void TEST_filesort(SORT_FIELD *sortorder,uint s_length) { char buff[256],buff2[256]; String str(buff,sizeof(buff),default_charset_info); @@ -131,8 +131,6 @@ void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special) out.append('\0'); // Purify doesn't like c_ptr() DBUG_LOCK_FILE; VOID(fputs("\nInfo about FILESORT\n",DBUG_FILE)); - if (special) - fprintf(DBUG_FILE,"Records to sort: %ld\n",special); fprintf(DBUG_FILE,"Sortorder: %s\n",out.ptr()); DBUG_UNLOCK_FILE; DBUG_VOID_RETURN; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index f530c87dd61..c146b07284f 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -190,8 +190,8 @@ int mysql_update(THD *thd, MYF(MY_FAE | MY_ZEROFILL)); if (setup_order(thd, &tables, fields, all_fields, order) || !(sortorder=make_unireg_sortorder(order, &length)) || - (table->found_records = filesort(table, sortorder, length, - (SQL_SELECT *) 0, 0L, + (table->found_records = filesort(thd, table, sortorder, length, + (SQL_SELECT *) 0, HA_POS_ERROR, &examined_rows)) == HA_POS_ERROR) { -- cgit v1.2.1