From: Date: May 5 2007 8:35am Subject: bk commit into 5.1 tree (acurtis:1.2513) List-Archive: http://lists.mysql.com/commits/26161 Message-Id: <200705050635.l456ZYUb023281@mail.mysql.com> Below is the list of changes that have just been committed into a local 5.1 repository of antony. When antony does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet@stripped, 2007-05-04 23:35:14-07:00, acurtis@stripped +17 -0 Merge xiphis.org:/home/antony/work2/mysql-5.1-engines into xiphis.org:/home/antony/work2/mysql-5.1-engines.merge MERGE: 1.2479.2.24 include/my_global.h@stripped, 2007-05-04 23:20:31-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.163.1.4 mysql-test/mysql-test-run.pl@stripped, 2007-05-04 23:20:31-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.296.1.1 scripts/mysql_install_db.sh@stripped, 2007-05-04 23:20:31-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.76.1.1 sql/ha_ndbcluster.cc@stripped, 2007-05-04 23:20:31-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.441.1.1 sql/item_func.cc@stripped, 2007-05-04 23:20:31-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.380.1.3 sql/item_sum.cc@stripped, 2007-05-04 23:20:31-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.214.1.9 sql/mysql_priv.h@stripped, 2007-05-04 23:20:32-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.501.1.2 sql/sql_base.cc@stripped, 2007-05-04 23:20:32-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.396.1.1 sql/sql_lex.h@stripped, 2007-05-04 23:20:32-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.271.1.2 sql/sql_parse.cc@stripped, 2007-05-04 23:20:32-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.662.1.1 sql/sql_select.cc@stripped, 2007-05-04 23:20:33-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.515.1.2 sql/sql_show.cc@stripped, 2007-05-04 23:20:33-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.407.1.1 sql/sql_table.cc@stripped, 2007-05-04 23:20:33-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.409.1.2 sql/sql_yacc.yy@stripped, 2007-05-04 23:20:33-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.564.1.1 sql/table.cc@stripped, 2007-05-04 23:20:34-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.286.1.1 sql/table.h@stripped, 2007-05-04 23:20:34-07:00, acurtis@stripped +0 -0 Auto merged MERGE: 1.166.1.1 storage/innobase/handler/ha_innodb.cc@stripped, 2007-05-04 23:35:10-07:00, acurtis@stripped +8 -11 manual change to new api MERGE: 1.333.1.2 # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: acurtis # Host: ltamd64.xiphis.org # Root: /home/antony/work2/mysql-5.1-engines.merge/RESYNC --- 1.78/scripts/mysql_install_db.sh 2007-05-04 23:35:32 -07:00 +++ 1.79/scripts/mysql_install_db.sh 2007-05-04 23:35:32 -07:00 @@ -274,8 +274,8 @@ # Peform the install of system tables mysqld_bootstrap="${MYSQLD_BOOTSTRAP-$mysqld}" mysqld_install_cmd_line="$mysqld_bootstrap $defaults $mysqld_opt --bootstrap \ ---basedir=$basedir --datadir=$ldata --skip-innodb \ ---skip-ndbcluster $args --max_allowed_packet=8M \ +--basedir=$basedir --datadir=$ldata --loose-skip-innodb \ +--loose-skip-ndbcluster $args --max_allowed_packet=8M \ --net_buffer_length=16K" # Pipe mysql_system_tables.sql to "mysqld --bootstrap" --- 1.381/sql/item_func.cc 2007-05-04 23:35:32 -07:00 +++ 1.382/sql/item_func.cc 2007-05-04 23:35:32 -07:00 @@ -620,6 +620,14 @@ return copy_or_same(thd); } +double Item_int_func::val_real() +{ + DBUG_ASSERT(fixed == 1); + + return unsigned_flag ? (double) ((ulonglong) val_int()) : (double) val_int(); +} + + String *Item_int_func::val_str(String *str) { DBUG_ASSERT(fixed == 1); @@ -802,7 +810,10 @@ return result; } case INT_RESULT: - return (double)int_op(); + { + longlong result= int_op(); + return unsigned_flag ? (double) ((ulonglong) result) : (double) result; + } case REAL_RESULT: return real_op(); case STRING_RESULT: @@ -1362,6 +1373,8 @@ DBUG_ASSERT(fixed == 1); longlong value= args[0]->val_int(); longlong val2= args[1]->val_int(); + longlong result; + if ((null_value= args[0]->null_value || args[1]->null_value)) return 0; /* purecov: inspected */ if (val2 == 0) @@ -1371,9 +1384,13 @@ } if (args[0]->unsigned_flag) - return ((ulonglong) value) % val2; + result= args[1]->unsigned_flag ? + ((ulonglong) value) % ((ulonglong) val2) : ((ulonglong) value) % val2; + else + result= args[1]->unsigned_flag ? + value % ((ulonglong) val2) : value % val2; - return value % val2; + return result; } double Item_func_mod::real_op() @@ -1428,6 +1445,7 @@ { Item_num_op::fix_length_and_dec(); maybe_null= 1; + unsigned_flag= args[0]->unsigned_flag; } @@ -1506,8 +1524,9 @@ longlong Item_func_abs::int_op() { longlong value= args[0]->val_int(); - null_value= args[0]->null_value; - return value >= 0 ? value : -value; + if ((null_value= args[0]->null_value)) + return 0; + return (value >= 0) || unsigned_flag ? value : -value; } @@ -1528,6 +1547,7 @@ void Item_func_abs::fix_length_and_dec() { Item_func_num1::fix_length_and_dec(); + unsigned_flag= args[0]->unsigned_flag; } @@ -1902,6 +1922,10 @@ void Item_func_round::fix_length_and_dec() { + int decimals_to_set; + longlong val1; + bool val1_unsigned; + unsigned_flag= args[0]->unsigned_flag; if (!args[1]->const_item()) { @@ -1910,8 +1934,14 @@ hybrid_type= REAL_RESULT; return; } - - int decimals_to_set= max((int)args[1]->val_int(), 0); + + val1= args[1]->val_int(); + val1_unsigned= args[1]->unsigned_flag; + if (val1 < 0) + decimals_to_set= val1_unsigned ? INT_MAX : 0; + else + decimals_to_set= (val1 > INT_MAX) ? INT_MAX : (int) val1; + if (args[0]->decimals == NOT_FIXED_DEC) { max_length= args[0]->max_length; @@ -1928,10 +1958,9 @@ max_length= float_length(decimals); break; case INT_RESULT: - if (!decimals_to_set && - (truncate || (args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS))) + if ((!decimals_to_set && truncate) || (args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS)) { - int length_can_increase= test(!truncate && (args[1]->val_int() < 0)); + int length_can_increase= test(!truncate && (val1 < 0) && !val1_unsigned); max_length= args[0]->max_length + length_can_increase; /* Here we can keep INT_RESULT */ hybrid_type= INT_RESULT; @@ -1957,10 +1986,12 @@ } } -double my_double_round(double value, int dec, bool truncate) +double my_double_round(double value, longlong dec, bool dec_unsigned, + bool truncate) { double tmp; - uint abs_dec= abs(dec); + bool dec_negative= (dec < 0) && !dec_unsigned; + ulonglong abs_dec= dec_negative ? -dec : dec; /* tmp2 is here to avoid return the value with 80 bit precision This will fix that the test round(0.1,1) = round(0.1,1) is true @@ -1970,7 +2001,11 @@ tmp=(abs_dec < array_elements(log_10) ? log_10[abs_dec] : pow(10.0,(double) abs_dec)); - if (truncate) + if (dec_negative && isinf(tmp)) + tmp2= 0; + else if (!dec_negative && isinf(value * tmp)) + tmp2= value; + else if (truncate) { if (value >= 0) tmp2= dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp; @@ -1986,24 +2021,35 @@ double Item_func_round::real_op() { double value= args[0]->val_real(); - int dec= (int) args[1]->val_int(); if (!(null_value= args[0]->null_value || args[1]->null_value)) - return my_double_round(value, dec, truncate); + return my_double_round(value, args[1]->val_int(), args[1]->unsigned_flag, + truncate); return 0.0; } +/* + Rounds a given value to a power of 10 specified as the 'to' argument, + avoiding overflows when the value is close to the ulonglong range boundary. +*/ + +static inline ulonglong my_unsigned_round(ulonglong value, ulonglong to) +{ + ulonglong tmp= value / to * to; + return (value - tmp < (to >> 1)) ? tmp : tmp + to; +} + longlong Item_func_round::int_op() { longlong value= args[0]->val_int(); - int dec=(int) args[1]->val_int(); + longlong dec= args[1]->val_int(); decimals= 0; - uint abs_dec; + ulonglong abs_dec; if ((null_value= args[0]->null_value || args[1]->null_value)) return 0; - if (dec >= 0) + if ((dec >= 0) || args[1]->unsigned_flag) return value; // integer have not digits after point abs_dec= -dec; @@ -2015,21 +2061,12 @@ tmp= log_10_int[abs_dec]; if (truncate) - { - if (unsigned_flag) - value= (ulonglong(value)/tmp)*tmp; - else - value= (value/tmp)*tmp; - } + value= (unsigned_flag) ? + ((ulonglong) value / tmp) * tmp : (value / tmp) * tmp; else - { - if (unsigned_flag) - value= ((ulonglong(value)+(tmp>>1))/tmp)*tmp; - else if ( value >= 0) - value= ((value+(tmp>>1))/tmp)*tmp; - else - value= ((value-(tmp>>1))/tmp)*tmp; - } + value= (unsigned_flag || value >= 0) ? + my_unsigned_round((ulonglong) value, tmp) : + -(longlong) my_unsigned_round((ulonglong) -value, tmp); return value; } @@ -2037,14 +2074,18 @@ my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value) { my_decimal val, *value= args[0]->val_decimal(&val); - int dec=(int) args[1]->val_int(); - if (dec > 0) + longlong dec= args[1]->val_int(); + if (dec > 0 || (dec < 0 && args[1]->unsigned_flag)) { - decimals= min(dec, DECIMAL_MAX_SCALE); // to get correct output + dec= min((ulonglong) dec, DECIMAL_MAX_SCALE); + decimals= (uint8) dec; // to get correct output } + else if (dec < INT_MIN) + dec= INT_MIN; + if (!(null_value= (args[0]->null_value || args[1]->null_value || - my_decimal_round(E_DEC_FATAL_ERROR, value, dec, truncate, - decimal_value) > 1))) + my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec, + truncate, decimal_value) > 1))) return decimal_value; return 0; } --- 1.217/sql/item_sum.cc 2007-05-04 23:35:32 -07:00 +++ 1.218/sql/item_sum.cc 2007-05-04 23:35:32 -07:00 @@ -175,13 +175,25 @@ MYF(0)); return TRUE; } - if (in_sum_func && in_sum_func->nest_level == nest_level) + if (in_sum_func) { /* If the set function is nested adjust the value of max_sum_func_level for the nesting set function. + We take into account only enclosed set functions that are to be + aggregated on the same level or above of the nest level of + the enclosing set function. + But we must always pass up the max_sum_func_level because it is + the maximum nested level of all directly and indirectly enclosed + set functions. We must do that even for set functions that are + aggregated inside of their enclosing set function's nest level + because the enclosing function may contain another enclosing + function that is to be aggregated outside or on the same level + as its parent's nest level. */ - set_if_bigger(in_sum_func->max_sum_func_level, aggr_level); + if (in_sum_func->nest_level >= aggr_level) + set_if_bigger(in_sum_func->max_sum_func_level, aggr_level); + set_if_bigger(in_sum_func->max_sum_func_level, max_sum_func_level); } update_used_tables(); thd->lex->in_sum_func= in_sum_func; --- 1.503/sql/mysql_priv.h 2007-05-04 23:35:32 -07:00 +++ 1.504/sql/mysql_priv.h 2007-05-04 23:35:32 -07:00 @@ -1882,7 +1882,8 @@ ha_rows *examined_rows); void filesort_free_buffers(TABLE *table, bool full); void change_double_for_sort(double nr,byte *to); -double my_double_round(double value, int dec, bool truncate); +double my_double_round(double value, longlong dec, bool dec_unsigned, + bool truncate); int get_quick_record(SQL_SELECT *select); int calc_weekday(long daynr,bool sunday_first_day_of_week); --- 1.397/sql/sql_base.cc 2007-05-04 23:35:32 -07:00 +++ 1.398/sql/sql_base.cc 2007-05-04 23:35:32 -07:00 @@ -5575,6 +5575,7 @@ */ arena= thd->activate_stmt_arena_if_needed(&backup); + thd->lex->current_select->cur_pos_in_select_list= 0; while (wild_num && (item= it++)) { if (item->type() == Item::FIELD_ITEM && @@ -5616,7 +5617,10 @@ } wild_num--; } + else + thd->lex->current_select->cur_pos_in_select_list++; } + thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS; if (arena) { /* make * substituting permanent */ @@ -6099,6 +6103,7 @@ } else thd->used_tables|= item->used_tables(); + thd->lex->current_select->cur_pos_in_select_list++; } /* In case of stored tables, all fields are considered as used, --- 1.273/sql/sql_lex.h 2007-05-04 23:35:32 -07:00 +++ 1.274/sql/sql_lex.h 2007-05-04 23:35:32 -07:00 @@ -796,7 +796,6 @@ }; typedef class st_select_lex SELECT_LEX; - inline bool st_select_lex_unit::is_union () { return first_select()->next_select() && --- 1.664/sql/sql_parse.cc 2007-05-04 23:35:32 -07:00 +++ 1.665/sql/sql_parse.cc 2007-05-04 23:35:32 -07:00 @@ -5966,7 +5966,7 @@ fake_select_lex->context.resolve_in_select_list= TRUE; fake_select_lex->context.select_lex= fake_select_lex; - if (!first_sl->next_select()) + if (!is_union()) { /* This works only for --- 1.516/sql/sql_select.cc 2007-05-04 23:35:32 -07:00 +++ 1.517/sql/sql_select.cc 2007-05-04 23:35:32 -07:00 @@ -231,7 +231,8 @@ register SELECT_LEX *select_lex = &lex->select_lex; DBUG_ENTER("handle_select"); - if (select_lex->next_select() || select_lex->master_unit()->fake_select_lex) + if (select_lex->master_unit()->is_union() || + select_lex->master_unit()->fake_select_lex) res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option); else { @@ -442,7 +443,7 @@ select_lex= select_lex_arg; select_lex->join= this; join_list= &select_lex->top_join_list; - union_part= (unit_arg->first_select()->next_select() != 0); + union_part= unit_arg->is_union(); thd->lex->current_select->is_item_list_lookup= 1; /* @@ -1191,7 +1192,7 @@ if (!group_list && !order && unit->item && unit->item->substype() == Item_subselect::IN_SUBS && tables == 1 && conds && - !unit->first_select()->next_select()) + !unit->is_union()) { if (!having) { @@ -3165,7 +3166,7 @@ if (!join->group_list && !join->order && join->unit->item && join->unit->item->substype() == Item_subselect::IN_SUBS && - !join->unit->first_select()->next_select()) + !join->unit->is_union()) { KEY_FIELD *save= *key_fields; add_key_fields(join, key_fields, and_level, cond_arg, usable_tables, @@ -5614,8 +5615,9 @@ for (uint i=join->const_tables ; i < join->tables ; i++) { JOIN_TAB *tab=join->join_tab+i; - if ((tab->type == JT_REF || tab->type == JT_REF_OR_NULL) && - !tab->table->maybe_null) + if ((tab->type == JT_REF || tab->type == JT_EQ_REF || + tab->type == JT_REF_OR_NULL) && + !tab->table->maybe_null) { for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++) { @@ -8856,17 +8858,13 @@ test_if_equality_guarantees_uniqueness(Item *l, Item *r) { return r->const_item() && - /* elements must be of the same result type */ - (r->result_type() == l->result_type() || - /* or dates compared to longs */ - (((l->type() == Item::FIELD_ITEM && - ((Item_field *)l)->field->can_be_compared_as_longlong()) || - (l->type() == Item::FUNC_ITEM && - ((Item_func *)l)->result_as_longlong())) && - r->result_type() == INT_RESULT)) - /* and must have the same collation if compared as strings */ - && (l->result_type() != STRING_RESULT || - l->collation.collation == r->collation.collation); + /* elements must be compared as dates */ + (Arg_comparator::can_compare_as_dates(l, r, 0) || + /* or of the same result type */ + (r->result_type() == l->result_type() && + /* and must have the same collation if compared as strings */ + (l->result_type() != STRING_RESULT || + l->collation.collation == r->collation.collation))); } /* @@ -14814,7 +14812,7 @@ for (j=0 ; j < fields_list.elements ; j++) rollup.fields[i].push_back(rollup.null_items[i]); } - List_iterator_fast it(all_fields); + List_iterator it(all_fields); Item *item; while ((item= it++)) { @@ -14827,6 +14825,32 @@ { item->maybe_null= 1; found_in_group= 1; + if (item->const_item()) + { + /* + For ROLLUP queries each constant item referenced in GROUP BY list + is wrapped up into an Item_func object yielding the same value + as the constant item. The objects of the wrapper class are never + considered as constant items and besides they inherit all + properties of the Item_result_field class. + This wrapping allows us to ensure writing constant items + into temporary tables whenever the result of the ROLLUP + operation has to be written into a temporary table, e.g. when + ROLLUP is used together with DISTINCT in the SELECT list. + Usually when creating temporary tables for a intermidiate + result we do not include fields for constant expressions. + */ + Item* new_item= new Item_func_rollup_const(item); + if (!new_item) + return 1; + new_item->fix_fields(thd, (Item **) 0); + thd->change_item_tree(it.ref(), new_item); + for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next) + { + if (*tmp->item == item) + thd->change_item_tree(tmp->item, new_item); + } + } } } if (item->type() == Item::FUNC_ITEM && !found_in_group) @@ -15531,7 +15555,7 @@ "UNION"))); sl->options|= SELECT_DESCRIBE; } - if (first->next_select()) + if (unit->is_union()) { unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization unit->fake_select_lex->type= "UNION RESULT"; --- 1.408/sql/sql_show.cc 2007-05-04 23:35:32 -07:00 +++ 1.409/sql/sql_show.cc 2007-05-04 23:35:32 -07:00 @@ -79,24 +79,24 @@ ** List all table types supported ***************************************************************************/ -static my_bool show_handlerton(THD *thd, st_plugin_int *plugin, +static my_bool show_handlerton(THD *thd, plugin_ref plugin, void *arg) { handlerton *default_type= (handlerton *) arg; Protocol *protocol= thd->protocol; - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (!(hton->flags & HTON_HIDDEN)) { protocol->prepare_for_resend(); - protocol->store(plugin->name.str, plugin->name.length, + protocol->store(plugin_name(plugin)->str, plugin_name(plugin)->length, system_charset_info); const char *option_name= show_comp_option_name[(int) hton->state]; if (hton->state == SHOW_OPTION_YES && default_type == hton) option_name= "DEFAULT"; protocol->store(option_name, system_charset_info); - protocol->store(plugin->plugin->descr, system_charset_info); + protocol->store(plugin_decl(plugin)->descr, system_charset_info); protocol->store(hton->commit ? "YES" : "NO", system_charset_info); protocol->store(hton->prepare ? "YES" : "NO", system_charset_info); protocol->store(hton->savepoint_set ? "YES" : "NO", system_charset_info); @@ -124,7 +124,7 @@ DBUG_RETURN(TRUE); if (plugin_foreach(thd, show_handlerton, - MYSQL_STORAGE_ENGINE_PLUGIN, thd->variables.table_type)) + MYSQL_STORAGE_ENGINE_PLUGIN, ha_default_handlerton(thd))) DBUG_RETURN(TRUE); send_eof(thd); @@ -136,24 +136,26 @@ return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff); } -static my_bool show_plugins(THD *thd, st_plugin_int *plugin, +static my_bool show_plugins(THD *thd, plugin_ref plugin, void *arg) { TABLE *table= (TABLE*) arg; - struct st_mysql_plugin *plug= plugin->plugin; + struct st_mysql_plugin *plug= plugin_decl(plugin); + struct st_plugin_dl *plugin_dl= plugin_dlib(plugin); CHARSET_INFO *cs= system_charset_info; char version_buf[20]; restore_record(table, s->default_values); - table->field[0]->store(plugin->name.str, plugin->name.length, cs); + table->field[0]->store(plugin_name(plugin)->str, + plugin_name(plugin)->length, cs); table->field[1]->store(version_buf, make_version_string(version_buf, sizeof(version_buf), plug->version), cs); - switch (plugin->state) { + switch (plugin_state(plugin)) { /* case PLUGIN_IS_FREED: does not happen */ case PLUGIN_IS_DELETED: table->field[2]->store(STRING_WITH_LEN("DELETED"), cs); @@ -175,14 +177,13 @@ make_version_string(version_buf, sizeof(version_buf), *(uint *)plug->info), cs); - if (plugin->plugin_dl) + if (plugin_dl) { - table->field[5]->store(plugin->plugin_dl->dl.str, - plugin->plugin_dl->dl.length, cs); + table->field[5]->store(plugin_dl->dl.str, plugin_dl->dl.length, cs); table->field[5]->set_notnull(); table->field[6]->store(version_buf, make_version_string(version_buf, sizeof(version_buf), - plugin->plugin_dl->version), + plugin_dl->version), cs); table->field[6]->set_notnull(); } @@ -1239,9 +1240,9 @@ store_key_options(thd, packet, table, key_info); if (key_info->parser) { + LEX_STRING *parser_name= plugin_name(key_info->parser); packet->append(STRING_WITH_LEN(" /*!50100 WITH PARSER ")); - append_identifier(thd, packet, key_info->parser->name.str, - key_info->parser->name.length); + append_identifier(thd, packet, parser_name->str, parser_name->length); packet->append(STRING_WITH_LEN(" */ ")); } } @@ -1936,6 +1937,18 @@ sort_dynamic(&all_status_vars, show_var_cmp); } +void reset_status_vars() +{ + SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer; + SHOW_VAR *last= ptr + all_status_vars.elements; + for (; ptr < last; ptr++) + { + /* Note that SHOW_LONG_NOFLUSH variables are not reset */ + if (ptr->type == SHOW_LONG) + *(ulong*) ptr->value= 0; + } +} + /* catch-all cleanup function, cleans up everything no matter what @@ -2066,6 +2079,8 @@ char *value=var->value; const char *pos, *end; // We assign a lot of const's + pthread_mutex_lock(&LOCK_global_system_variables); + if (show_type == SHOW_SYS) { show_type= ((sys_var*) value)->show_type(); @@ -2148,6 +2163,9 @@ system_charset_info); table->field[1]->store(pos, (uint32) (end - pos), system_charset_info); table->field[1]->set_notnull(); + + pthread_mutex_unlock(&LOCK_global_system_variables); + if (schema_table_store_record(thd, table)) DBUG_RETURN(TRUE); } @@ -2457,13 +2475,13 @@ const char *wild; }; -static my_bool add_schema_table(THD *thd, st_plugin_int *plugin, +static my_bool add_schema_table(THD *thd, plugin_ref plugin, void* p_data) { st_add_schema_table *data= (st_add_schema_table *)p_data; List *file_list= data->files; const char *wild= data->wild; - ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data; + ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *); DBUG_ENTER("add_schema_table"); if (schema_table->hidden) @@ -3011,7 +3029,7 @@ ha_row_type[(uint) share->row_type], NullS); #ifdef WITH_PARTITION_STORAGE_ENGINE - if (show_table->s->db_type == partition_hton && + if (show_table->s->db_type() == partition_hton && show_table->part_info != NULL && show_table->part_info->no_parts > 0) ptr= strmov(ptr, " partitioned"); @@ -3286,19 +3304,20 @@ } -static my_bool iter_schema_engines(THD *thd, st_plugin_int *plugin, +static my_bool iter_schema_engines(THD *thd, plugin_ref plugin, void *ptable) { TABLE *table= (TABLE *) ptable; - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; CHARSET_INFO *scs= system_charset_info; DBUG_ENTER("iter_schema_engines"); if (!(hton->flags & HTON_HIDDEN)) { + LEX_STRING *name= plugin_name(plugin); if (!(wild && wild[0] && - wild_case_compare(scs, plugin->name.str,wild))) + wild_case_compare(scs, name->str,wild))) { LEX_STRING state[2]= {{ C_STRING_WITH_LEN("ENABLED") }, { C_STRING_WITH_LEN("DISABLED") }}; @@ -3307,11 +3326,11 @@ LEX_STRING *tmp; restore_record(table, s->default_values); - table->field[0]->store(plugin->name.str, plugin->name.length, scs); + table->field[0]->store(name->str, name->length, scs); tmp= &state[test(hton->state)]; table->field[1]->store(tmp->str, tmp->length, scs); - table->field[2]->store(plugin->plugin->descr, - strlen(plugin->plugin->descr), scs); + table->field[2]->store(plugin_decl(plugin)->descr, + strlen(plugin_decl(plugin)->descr), scs); tmp= &yesno[test(hton->commit)]; table->field[3]->store(tmp->str, tmp->length, scs); tmp= &yesno[test(hton->prepare)]; @@ -4497,10 +4516,10 @@ int res= 0; LEX *lex= thd->lex; const char *wild= lex->wild ? lex->wild->ptr() : NullS; - pthread_mutex_lock(&LOCK_global_system_variables); - res= show_status_array(thd, wild, init_vars, + rw_rdlock(&LOCK_system_variables_hash); + res= show_status_array(thd, wild, enumerate_sys_vars(thd, TRUE), lex->option_type, 0, "", tables->table, 0); - pthread_mutex_unlock(&LOCK_global_system_variables); + rw_unlock(&LOCK_system_variables_hash); DBUG_RETURN(res); } @@ -4616,12 +4635,12 @@ 0 table not found 1 found the schema table */ -static my_bool find_schema_table_in_plugin(THD *thd, st_plugin_int *plugin, +static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin, void* p_table) { schema_table_ref *p_schema_table= (schema_table_ref *)p_table; const char* table_name= p_schema_table->table_name; - ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data; + ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *); DBUG_ENTER("find_schema_table_in_plugin"); if (!my_strcasecmp(system_charset_info, @@ -5184,12 +5203,12 @@ COND *cond; }; -static my_bool run_hton_fill_schema_files(THD *thd, st_plugin_int *plugin, +static my_bool run_hton_fill_schema_files(THD *thd, plugin_ref plugin, void *arg) { struct run_hton_fill_schema_files_args *args= (run_hton_fill_schema_files_args *) arg; - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if(hton->fill_files_table && hton->state == SHOW_OPTION_YES) hton->fill_files_table(hton, thd, args->tables, args->cond); return false; @@ -5355,10 +5374,10 @@ int res= 0; DBUG_ENTER("fill_schema_global_variables"); - pthread_mutex_lock(&LOCK_global_system_variables); - res= show_status_array(thd, "", init_vars, OPT_GLOBAL, + rw_rdlock(&LOCK_system_variables_hash); + res= show_status_array(thd, "", enumerate_sys_vars(thd, FALSE), OPT_GLOBAL, NULL, "", tables->table, 1); - pthread_mutex_unlock(&LOCK_global_system_variables); + rw_unlock(&LOCK_system_variables_hash); DBUG_RETURN(res); } @@ -5368,10 +5387,10 @@ int res= 0; DBUG_ENTER("fill_schema_session_variables"); - pthread_mutex_lock(&LOCK_global_system_variables); - res= show_status_array(thd, "", init_vars, OPT_SESSION, + rw_rdlock(&LOCK_system_variables_hash); + res= show_status_array(thd, "", enumerate_sys_vars(thd, FALSE), OPT_SESSION, NULL, "", tables->table, 1); - pthread_mutex_unlock(&LOCK_global_system_variables); + rw_unlock(&LOCK_system_variables_hash); DBUG_RETURN(res); } --- 1.413/sql/sql_table.cc 2007-05-04 23:35:32 -07:00 +++ 1.414/sql/sql_table.cc 2007-05-04 23:35:32 -07:00 @@ -40,8 +40,7 @@ enum enum_enable_or_disable keys_onoff); static bool prepare_blob_field(THD *thd, create_field *sql_field); -static bool check_engine(THD *thd, const char *table_name, - HA_CREATE_INFO *create_info); +static bool check_engine(THD *, const char *, HA_CREATE_INFO *); static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, List *fields, List *keys, bool tmp_table, @@ -665,16 +664,14 @@ frm_action= TRUE; else { - TABLE_SHARE dummy; - - hton= ha_resolve_by_name(thd, &handler_name); - if (!hton) + plugin_ref plugin= ha_resolve_by_name(thd, &handler_name); + if (!plugin) { my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name); goto error; } - bzero(&dummy, sizeof(TABLE_SHARE)); - file= get_new_handler(&dummy, &mem_root, hton); + hton= plugin_data(plugin, handlerton*); + file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton); if (!file) { mem_alloc_error(sizeof(handler)); @@ -1638,7 +1635,7 @@ TABLE_SHARE *share; table->db_type= NULL; if ((share= get_cached_table_share(table->db, table->table_name))) - table->db_type= share->db_type; + table->db_type= share->db_type(); /* Disable drop of enabled log tables */ if (share && share->log_table && @@ -5080,7 +5077,7 @@ See BUG#6236. */ if (table->s->fields != create_list->elements || - table->s->db_type != create_info->db_type || + table->s->db_type() != create_info->db_type || table->s->tmp_table || create_info->used_fields & HA_CREATE_USED_ENGINE || create_info->used_fields & HA_CREATE_USED_CHARSET || @@ -5539,7 +5536,7 @@ new_name= table_name; } - old_db_type= table->s->db_type; + old_db_type= table->s->db_type(); if (!create_info->db_type) { #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -6059,7 +6056,7 @@ } if (thd->variables.old_alter_table - || (table->s->db_type != create_info->db_type) + || (table->s->db_type() != create_info->db_type) #ifdef WITH_PARTITION_STORAGE_ENGINE || partition_changed #endif @@ -6097,8 +6094,8 @@ uint *idx_p; uint *idx_end_p; - if (table->s->db_type->alter_table_flags) - alter_flags= table->s->db_type->alter_table_flags(alter_info->flags); + if (table->s->db_type()->alter_table_flags) + alter_flags= table->s->db_type()->alter_table_flags(alter_info->flags); DBUG_PRINT("info", ("alter_flags: %lu", alter_flags)); /* Check dropped indexes. */ for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count; @@ -7115,7 +7112,7 @@ if (req_engine && req_engine != *new_engine) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_WARN_USING_OTHER_HANDLER, ER(ER_WARN_USING_OTHER_HANDLER), ha_resolve_storage_engine_name(*new_engine), @@ -7127,7 +7124,7 @@ if (create_info->used_fields & HA_CREATE_USED_ENGINE) { my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0), - hton2plugin[(*new_engine)->slot]->name.str, "TEMPORARY"); + ha_resolve_storage_engine_name(*new_engine), "TEMPORARY"); *new_engine= 0; return TRUE; } --- 1.565/sql/sql_yacc.yy 2007-05-04 23:35:32 -07:00 +++ 1.566/sql/sql_yacc.yy 2007-05-04 23:35:32 -07:00 @@ -7843,7 +7843,7 @@ yet. */ SELECT_LEX *first_sl= unit->first_select(); - if (!first_sl->next_select() && + if (!unit->is_union() && (first_sl->order_list.elements || first_sl->select_limit) && unit->add_fake_select_lex(lex->thd)) --- 1.287/sql/table.cc 2007-05-04 23:35:32 -07:00 +++ 1.288/sql/table.cc 2007-05-04 23:35:32 -07:00 @@ -3587,7 +3587,16 @@ Item *Field_iterator_table::create_item(THD *thd) { - return new Item_field(thd, &thd->lex->current_select->context, *ptr); + SELECT_LEX *select= thd->lex->current_select; + + Item_field *item= new Item_field(thd, &select->context, *ptr); + if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && + !thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS) + { + select->non_agg_fields.push_back(item); + item->marker= select->cur_pos_in_select_list; + } + return item; } --- 1.167/sql/table.h 2007-05-04 23:35:32 -07:00 +++ 1.168/sql/table.h 2007-05-04 23:35:32 -07:00 @@ -559,13 +559,17 @@ }; +#define MY_I_S_MAYBE_NULL 1 +#define MY_I_S_UNSIGNED 2 + + typedef struct st_field_info { const char* field_name; uint field_length; enum enum_field_types field_type; int value; - bool maybe_null; + uint field_flags; // Field atributes(maybe_null, signed, unsigned etc.) const char* old_name; } ST_FIELD_INFO; --- 1.301/mysql-test/mysql-test-run.pl 2007-05-04 23:35:32 -07:00 +++ 1.302/mysql-test/mysql-test-run.pl 2007-05-04 23:35:32 -07:00 @@ -3441,6 +3441,10 @@ return 1; } } + elsif ($glob_use_embedded_server) + { + run_master_init_script($tinfo); + } # ---------------------------------------------------------------------- # If --start-and-exit or --start-dirty given, stop here to let user manually @@ -3616,6 +3620,23 @@ } +sub run_master_init_script ($) { + my ($tinfo)= @_; + my $init_script= $tinfo->{'master_sh'}; + + # Run master initialization shell script if one exists + if ( $init_script ) + { + my $ret= mtr_run("/bin/sh", [$init_script], "", "", "", ""); + if ( $ret != 0 ) + { + # FIXME rewrite those scripts to return 0 if successful + # mtr_warning("$init_script exited with code $ret"); + } + } +} + + ############################################################################## # # Start and stop servers @@ -3627,7 +3648,6 @@ my ($tinfo)= @_; my $tname= $tinfo->{'name'}; - my $init_script= $tinfo->{'master_sh'}; # FIXME what about second master..... @@ -3643,16 +3663,7 @@ unlink("$master->[1]->{'path_myddir'}/master.info"); unlink("$master->[1]->{'path_myddir'}/relay-log.info"); - # Run master initialization shell script if one exists - if ( $init_script ) - { - my $ret= mtr_run("/bin/sh", [$init_script], "", "", "", ""); - if ( $ret != 0 ) - { - # FIXME rewrite those scripts to return 0 if successful - # mtr_warning("$init_script exited with code $ret"); - } - } + run_master_init_script($tinfo); } --- 1.443/sql/ha_ndbcluster.cc 2007-05-04 23:35:32 -07:00 +++ 1.444/sql/ha_ndbcluster.cc 2007-05-04 23:35:33 -07:00 @@ -2668,7 +2668,7 @@ DBUG_RETURN(peek_res); } - statistic_increment(thd->status_var.ha_write_count, &LOCK_status); + ha_statistic_increment(&SSV::ha_write_count); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); @@ -2897,7 +2897,7 @@ DBUG_RETURN(peek_res); } - statistic_increment(thd->status_var.ha_update_count, &LOCK_status); + ha_statistic_increment(&SSV::ha_update_count); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) { table->timestamp_field->set_time(); @@ -3077,7 +3077,7 @@ DBUG_ENTER("delete_row"); m_write_op= TRUE; - statistic_increment(thd->status_var.ha_delete_count,&LOCK_status); + ha_statistic_increment(&SSV::ha_delete_count); m_rows_changed++; if (m_use_partition_function && @@ -3471,8 +3471,7 @@ int ha_ndbcluster::index_next(byte *buf) { DBUG_ENTER("ha_ndbcluster::index_next"); - statistic_increment(current_thd->status_var.ha_read_next_count, - &LOCK_status); + ha_statistic_increment(&SSV::ha_read_next_count); DBUG_RETURN(next_result(buf)); } @@ -3480,8 +3479,7 @@ int ha_ndbcluster::index_prev(byte *buf) { DBUG_ENTER("ha_ndbcluster::index_prev"); - statistic_increment(current_thd->status_var.ha_read_prev_count, - &LOCK_status); + ha_statistic_increment(&SSV::ha_read_prev_count); DBUG_RETURN(next_result(buf)); } @@ -3489,8 +3487,7 @@ int ha_ndbcluster::index_first(byte *buf) { DBUG_ENTER("ha_ndbcluster::index_first"); - statistic_increment(current_thd->status_var.ha_read_first_count, - &LOCK_status); + ha_statistic_increment(&SSV::ha_read_first_count); // Start the ordered index scan and fetch the first row // Only HA_READ_ORDER indexes get called by index_first @@ -3501,7 +3498,7 @@ int ha_ndbcluster::index_last(byte *buf) { DBUG_ENTER("ha_ndbcluster::index_last"); - statistic_increment(current_thd->status_var.ha_read_last_count,&LOCK_status); + ha_statistic_increment(&SSV::ha_read_last_count); DBUG_RETURN(ordered_index_scan(0, 0, TRUE, TRUE, buf, NULL)); } @@ -3687,8 +3684,7 @@ int ha_ndbcluster::rnd_next(byte *buf) { DBUG_ENTER("rnd_next"); - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, - &LOCK_status); + ha_statistic_increment(&SSV::ha_read_rnd_next_count); if (!m_active_cursor) DBUG_RETURN(full_table_scan(buf)); @@ -3706,8 +3702,7 @@ int ha_ndbcluster::rnd_pos(byte *buf, byte *pos) { DBUG_ENTER("rnd_pos"); - statistic_increment(current_thd->status_var.ha_read_rnd_count, - &LOCK_status); + ha_statistic_increment(&SSV::ha_read_rnd_count); // The primary key for the record is stored in pos // Perform a pk_read using primary key "index" { @@ -7028,6 +7023,7 @@ } extern int ndb_dictionary_is_mysqld; +extern pthread_mutex_t LOCK_plugin; static int ndbcluster_init(void *p) { @@ -7037,6 +7033,13 @@ if (ndbcluster_inited) DBUG_RETURN(FALSE); + /* + Below we create new THD's. They'll need LOCK_plugin, but it's taken now by + plugin initialization code. Release it to avoid deadlocks. It's safe, as + there're no threads that may concurrently access plugin control structures. + */ + pthread_mutex_unlock(&LOCK_plugin); + pthread_mutex_init(&ndbcluster_mutex,MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_ndb_util_thread, MY_MUTEX_INIT_FAST); pthread_cond_init(&COND_ndb_util_thread, NULL); @@ -7048,7 +7051,7 @@ { handlerton *h= ndbcluster_hton; - h->state= have_ndbcluster; + h->state= SHOW_OPTION_YES; h->db_type= DB_TYPE_NDBCLUSTER; h->close_connection= ndbcluster_close_connection; h->commit= ndbcluster_commit; @@ -7070,9 +7073,6 @@ h->table_exists_in_engine= ndbcluster_table_exists_in_engine; } - if (have_ndbcluster != SHOW_OPTION_YES) - DBUG_RETURN(0); // nothing else to do - // Initialize ndb interface ndb_init_internal(); @@ -7180,6 +7180,8 @@ goto ndbcluster_init_error; } + pthread_mutex_lock(&LOCK_plugin); + ndbcluster_inited= 1; DBUG_RETURN(FALSE); @@ -7190,9 +7192,10 @@ if (g_ndb_cluster_connection) delete g_ndb_cluster_connection; g_ndb_cluster_connection= NULL; - have_ndbcluster= SHOW_OPTION_DISABLED; // If we couldn't use handler ndbcluster_hton->state= SHOW_OPTION_DISABLED; // If we couldn't use handler + pthread_mutex_lock(&LOCK_plugin); + DBUG_RETURN(TRUE); } @@ -9212,10 +9215,6 @@ uint buflen; DBUG_ENTER("ndbcluster_show_status"); - if (have_ndbcluster != SHOW_OPTION_YES) - { - DBUG_RETURN(FALSE); - } if (stat_type != HA_ENGINE_STATUS) { DBUG_RETURN(FALSE); --- 1.337/storage/innobase/handler/ha_innodb.cc 2007-05-04 23:35:33 -07:00 +++ 1.338/storage/innobase/handler/ha_innodb.cc 2007-05-04 23:35:33 -07:00 @@ -3474,27 +3474,30 @@ /* This call will update the counter according to the value that was inserted in the table */ - dict_table_autoinc_update(prebuilt->table, auto_inc); - } - } + dict_table_autoinc_update(prebuilt->table, auto_inc); + } + } - /* A REPLACE command and LOAD DATA INFILE REPLACE handle a duplicate - key error themselves, and we must update the autoinc counter if we are - performing those statements. */ + /* A REPLACE command and LOAD DATA INFILE REPLACE handle a duplicate + key error themselves, and we must update the autoinc counter if we are + performing those statements. */ - if (error == DB_DUPLICATE_KEY && auto_inc_used - && (thd_sql_command(thd) == SQLCOM_REPLACE - || thd_sql_command(thd) == SQLCOM_REPLACE_SELECT - || (thd_sql_command(thd) == SQLCOM_LOAD - && prebuilt->trx->allow_duplicates - && prebuilt->trx->replace_duplicates))) { + if (error == DB_DUPLICATE_KEY && auto_inc_used + && (thd_sql_command(user_thd) == SQLCOM_REPLACE + || thd_sql_command(user_thd) == SQLCOM_REPLACE_SELECT + || (thd_sql_command(user_thd) == SQLCOM_INSERT + && prebuilt->trx->allow_duplicates + && !prebuilt->trx->replace_duplicates) + || (thd_sql_command(user_thd) == SQLCOM_LOAD + && prebuilt->trx->allow_duplicates + && prebuilt->trx->replace_duplicates))) { - auto_inc = table->next_number_field->val_int(); + auto_inc = table->next_number_field->val_int(); - if (auto_inc != 0) { - dict_table_autoinc_update(prebuilt->table, auto_inc); - } - } + if (auto_inc != 0) { + dict_table_autoinc_update(prebuilt->table, auto_inc); + } + } innodb_srv_conc_exit_innodb(prebuilt->trx); --- 1.167/include/my_global.h 2007-05-04 23:35:33 -07:00 +++ 1.168/include/my_global.h 2007-05-04 23:35:33 -07:00 @@ -859,13 +859,20 @@ #define SSIZE_MAX ((~((size_t) 0)) / 2) #endif +#ifndef HAVE_FINITE +#define finite(x) (1.0 / fabs(x) > 0.0) +#endif + +#ifndef HAVE_ISNAN +#define isnan(x) ((x) != (x)) +#endif + #if !defined(HAVE_ISINF) /* The configure check for "isinf with math.h" has failed */ #ifdef isinf #undef isinf #endif -/* Define isinf to never say that X is infinite */ -#define isinf(X) 0 +#define isinf(X) (!finite(X) && !isnan(X)) #endif /* Define missing math constants. */