diff options
author | unknown <monty@mysql.com> | 2005-07-03 14:17:52 +0300 |
---|---|---|
committer | unknown <monty@mysql.com> | 2005-07-03 14:17:52 +0300 |
commit | eeee5fb10b59f6580ebcb08ebd82d0b75c66aa8f (patch) | |
tree | bf06496ea5d097316e5972a5cf4c4d5f674fb90b /sql | |
parent | 6d9bc9c8b71acd82aa79ae580271e7dc4012e5a4 (diff) | |
parent | c7ab92c28a535d2419ffa906042fff7e476df972 (diff) | |
download | mariadb-git-eeee5fb10b59f6580ebcb08ebd82d0b75c66aa8f.tar.gz |
Merge with 4.1
Makefile.am:
Auto merged
myisam/mi_create.c:
Auto merged
myisam/mi_open.c:
Auto merged
mysql-test/r/ctype_utf8.result:
Auto merged
mysys/thr_alarm.c:
Auto merged
VC++Files/sql/mysqld.dsp:
Keep old
client/mysqldump.c:
Manual merge
client/mysqltest.c:
Automatic merge
configure.in:
Manual merge
mysql-test/r/ctype_ucs.result:
Auto merge
mysql-test/r/func_str.result:
Auto merge
mysql-test/r/group_by.result:
Auto merge
mysql-test/r/insert_select.result:
Auto merge
mysql-test/r/insert_update.result:
Auto merge
mysql-test/r/lowercase_table2.result:
Auto merge
mysql-test/r/select.result:
Manual merge
mysql-test/r/variables.result:
Auto merge
mysql-test/t/ctype_ucs.test:
Auto merge
mysql-test/t/func_str.test:
Auto merge
mysql-test/t/group_by.test:
Auto merge
mysql-test/t/insert_select.test:
Auto merge
mysql-test/t/insert_update.test:
Auto merge
mysql-test/t/ndb_alter_table.test:
Auto merge
mysql-test/t/select.test:
Auto merge
mysql-test/t/variables.test:
Auto merge
mysys/my_access.c:
Auto merge
scripts/make_win_src_distribution.sh:
Auto merge
sql/field.cc:
Manual merge
sql/ha_ndbcluster.cc:
Auto merge
sql/handler.cc:
Auto merge
sql/item.cc:
Auto merge
sql/item.h:
Manual merge
sql/item_cmpfunc.h:
Auto merge
sql/item_strfunc.cc:
Auto merge
sql/item_strfunc.h:
Auto merge
sql/mysql_priv.h:
manual merge
sql/mysqld.cc:
manual merge
sql/opt_range.cc:
manual merge
sql/set_var.cc:
Auto merge
sql/sql_base.cc:
manual merge
Restore processing of ON DUPLICATE KEY UPDATE
sql/sql_insert.cc:
manual merge
Restore processing of ON DUPLICATE KEY UPDATE
Simplify mysql_prepare_insert by using local variable for select_lex and save old values just before they are changed
sql/sql_parse.cc:
Restore processing of ON DUPLICATE KEY UPDATE
sql/sql_prepare.cc:
New ON DUPLICATE KEY UPDATE handling
sql/sql_select.cc:
manual merge
sql/sql_table.cc:
auto merge
sql/sql_yacc.yy:
auto merge
strings/ctype-ucs2.c:
auto merge
strings/ctype-utf8.c:
auto merge
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 9 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 4 | ||||
-rw-r--r-- | sql/handler.cc | 16 | ||||
-rw-r--r-- | sql/item.cc | 4 | ||||
-rw-r--r-- | sql/item.h | 11 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 6 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 6 | ||||
-rw-r--r-- | sql/item_strfunc.h | 1 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 5 | ||||
-rw-r--r-- | sql/set_var.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 42 | ||||
-rw-r--r-- | sql/sql_insert.cc | 85 | ||||
-rw-r--r-- | sql/sql_parse.cc | 10 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 43 | ||||
-rw-r--r-- | sql/sql_table.cc | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 15 |
18 files changed, 139 insertions, 126 deletions
diff --git a/sql/field.cc b/sql/field.cc index fb244de4275..56bb40e0f8f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1444,6 +1444,7 @@ my_decimal *Field_str::val_decimal(my_decimal *decimal_value) uint Field::fill_cache_field(CACHE_FIELD *copy) { + uint store_length; copy->str=ptr; copy->length=pack_length(); copy->blob_field=0; @@ -1457,10 +1458,16 @@ uint Field::fill_cache_field(CACHE_FIELD *copy) else if (!zero_pack() && (type() == MYSQL_TYPE_STRING && copy->length >= 4 && copy->length < 256)) + { copy->strip=1; /* Remove end space */ + store_length= 2; + } else + { copy->strip=0; - return copy->length+(int) copy->strip; + store_length= 0; + } + return copy->length+ store_length; } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 1ce0ede7164..89b81f684a3 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -515,8 +515,10 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans) if (m_rows_to_insert == 1) m_dupkey= table->s->primary_key; else - // We are batching inserts, offending key is not available + { + /* We are batching inserts, offending key is not available */ m_dupkey= (uint) -1; + } } DBUG_RETURN(res); } diff --git a/sql/handler.cc b/sql/handler.cc index 46a80770024..a61dce35501 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1949,14 +1949,12 @@ int ha_create_table_from_engine(THD* thd, HA_CREATE_INFO create_info; TABLE table; DBUG_ENTER("ha_create_table_from_engine"); - DBUG_PRINT("enter", ("name '%s'.'%s'", - db, name)); + DBUG_PRINT("enter", ("name '%s'.'%s'", db, name)); bzero((char*) &create_info,sizeof(create_info)); - - if(error= ha_discover(thd, db, name, &frmblob, &frmlen)) + if ((error= ha_discover(thd, db, name, &frmblob, &frmlen))) { - // Table could not be discovered and thus not created + /* Table could not be discovered and thus not created */ DBUG_RETURN(error); } @@ -1967,11 +1965,10 @@ int ha_create_table_from_engine(THD* thd, (void)strxnmov(path,FN_REFLEN,mysql_data_home,"/",db,"/",name,NullS); // Save the frm file - if (writefrm(path, frmblob, frmlen)) - { - my_free((char*) frmblob, MYF(MY_ALLOW_ZERO_PTR)); + error= writefrm(path, frmblob, frmlen); + my_free((char*) frmblob, MYF(0)); + if (error) DBUG_RETURN(2); - } if (openfrm(thd, path,"",0,(uint) READ_ALL, 0, &table)) DBUG_RETURN(3); @@ -1987,7 +1984,6 @@ int ha_create_table_from_engine(THD* thd, } error=table.file->create(path,&table,&create_info); VOID(closefrm(&table)); - my_free((char*) frmblob, MYF(MY_ALLOW_ZERO_PTR)); DBUG_RETURN(error != 0); } diff --git a/sql/item.cc b/sql/item.cc index 766d40f209e..8bc71ae5693 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -338,7 +338,6 @@ Item::Item(): place == IN_HAVING) thd->lex->current_select->select_n_having_items++; } - item_flags= 0; } /* @@ -359,8 +358,7 @@ Item::Item(THD *thd, Item *item): unsigned_flag(item->unsigned_flag), with_sum_func(item->with_sum_func), fixed(item->fixed), - collation(item->collation), - item_flags(item->item_flags) + collation(item->collation) { next= thd->free_list; // Put in free list thd->free_list= this; diff --git a/sql/item.h b/sql/item.h index d5d4edb84d5..560f1124fb4 100644 --- a/sql/item.h +++ b/sql/item.h @@ -312,13 +312,8 @@ struct Name_resolution_context typedef bool (Item::*Item_processor)(byte *arg); typedef Item* (Item::*Item_transformer) (byte *arg); - typedef void (*Cond_traverser) (const Item *item, void *arg); -/* - See comments for sql_yacc.yy: insert_update_elem rule - */ -#define MY_ITEM_PREFER_1ST_TABLE 1 class Item { Item(const Item &); /* Prevent use of these */ @@ -369,7 +364,6 @@ public: my_bool is_autogenerated_name; /* indicate was name of this Item autogenerated or set by user */ DTCollation collation; - uint8 item_flags; /* Flags on how item should be processed */ // alloc & destruct is done as start of select using sql_alloc Item(); @@ -684,11 +678,6 @@ public: cleanup(); delete this; } - virtual bool set_flags_processor(byte *args) - { - this->item_flags|= *((uint8*)args); - return false; - } virtual bool is_splocal() { return 0; } /* Needed for error checking */ }; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 16dab3c1b46..4ed04e89ce3 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -849,6 +849,12 @@ class Item_func_in :public Item_int_func bool nulls_in_row(); bool is_bool_func() { return 1; } CHARSET_INFO *compare_collation() { return cmp_collation.collation; } + /* + IN() protect from NULL only first argument, if construction like + "expression IN ()" will be allowed, we will need to check number of + argument here, because "NOT(NULL IN ())" is TRUE. + */ + table_map not_null_tables() const { return args[0]->not_null_tables(); } }; /* Functions used by where clause */ diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 40c4c501222..1ad65fb6208 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -371,8 +371,8 @@ String *Item_func_des_encrypt::val_str(String *str) uint key_number, res_length, tail; String *res= args[0]->val_str(str); - if ((null_value=args[0]->null_value)) - goto error; + if ((null_value= args[0]->null_value)) + return 0; // ENCRYPT(NULL) == NULL if ((res_length=res->length()) == 0) return &my_empty_string; @@ -464,7 +464,7 @@ String *Item_func_des_decrypt::val_str(String *str) uint length= 0, tail; if ((null_value=args[0]->null_value)) - goto error; + return 0; length=res->length(); if (length < 9 || (length % 8) != 1 || !((*res)[0] & 128)) return res; // Skip decryption if not encrypted diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index b8696895047..d85210984d9 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -95,6 +95,7 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "concat_ws"; } + table_map not_null_tables() const { return 0; } }; class Item_func_reverse :public Item_str_func diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 9a3684c3865..daa3618808b 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -717,7 +717,8 @@ bool mysql_multi_update(THD *thd, TABLE_LIST *table_list, COND *conds, ulong options, enum enum_duplicates handle_duplicates, bool ignore, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex); -bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, +bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, + TABLE_LIST *dup_table_list, TABLE *table, List<Item> &fields, List_item *values, List<Item> &update_fields, List<Item> &update_values, enum_duplicates duplic, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index bc4cc81506e..b24d42cbcfd 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5388,7 +5388,7 @@ The minimum value for this variable is 4096.", "Default pointer size to be used for MyISAM tables.", (gptr*) &myisam_data_pointer_size, (gptr*) &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG, - 6, 2, 8, 0, 1, 0}, + 6, 2, 7, 0, 1, 0}, {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, "Deprecated option", (gptr*) &global_system_variables.myisam_max_extra_sort_file_size, @@ -6360,9 +6360,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case (int) OPT_SLOW_QUERY_LOG: opt_slow_log=1; break; - case (int) OPT_LOG_SLOW_ADMIN_STATEMENTS: - opt_log_slow_admin_statements= 1; - break; case (int) OPT_SKIP_NEW: opt_specialflag|= SPECIAL_NO_NEW_FUNC; delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE; diff --git a/sql/set_var.cc b/sql/set_var.cc index fbf3332a37a..3f991713eb7 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1617,7 +1617,7 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names) { if (!(res= var->value->val_str(&str))) { - strmake(buff, "NULL", 4); + strmov(buff, "NULL"); goto err; } var->save_result.ulong_value= ((ulong) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index ef3ccf794b0..0d19a45c438 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2619,7 +2619,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, const char *name=item->field_name; uint length=(uint) strlen(name); char name_buff[NAME_LEN+1]; - + bool allow_rowid; if (item->cached_table) { /* @@ -2686,13 +2686,10 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, db= name_buff; } - bool search_global= item->item_flags & MY_ITEM_PREFER_1ST_TABLE; if (table_name && table_name[0]) { /* Qualified field */ - bool found_table=0; - uint table_idx= 0; - for (; tables; tables= search_global?tables->next_global:tables->next_local, - table_idx++) + bool found_table= 0; + for (; tables; tables= tables->next_local), { /* TODO; Ensure that db and tables->db always points to something ! */ if (!my_strcasecmp(table_alias_charset, tables->alias, table_name) && @@ -2728,8 +2725,6 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, return (Field*) 0; } found=find; - if (table_idx == 0 && item->item_flags & MY_ITEM_PREFER_1ST_TABLE) - break; } } } @@ -2754,11 +2749,10 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, return (Field*) not_found_field; return (Field*) 0; } - bool allow_rowid= tables && !tables->next_local; // Only one table - uint table_idx= 0; - for (; tables ; tables= search_global?tables->next_global:tables->next_local, - table_idx++) + allow_rowid= tables && !tables->next_local; // Only one table + for (; tables ; tables= tables->next_local) { + Field *field; if (!tables->table && !tables->ancestor) { if (report_error == REPORT_ALL_ERRORS || @@ -2767,17 +2761,17 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, return (Field*) not_found_field; } - Field *field= find_field_in_table(thd, tables, name, item->name, - length, ref, - (tables->table && - test(tables->table->grant. - want_privilege) && - check_privileges), - (test(tables->grant.want_privilege) && - check_privileges), - allow_rowid, - &(item->cached_field_index), - register_tree_change); + field= find_field_in_table(thd, tables, name, item->name, + length, ref, + (tables->table && + test(tables->table->grant. + want_privilege) && + check_privileges), + (test(tables->grant.want_privilege) && + check_privileges), + allow_rowid, + &(item->cached_field_index), + register_tree_change); if (field) { if (field == WRONG_GRANT) @@ -2793,8 +2787,6 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, return (Field*) 0; } found= field; - if (table_idx == 0 && item->item_flags & MY_ITEM_PREFER_1ST_TABLE) - break; } } if (found) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 53c47706734..adb1eb01292 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -327,7 +327,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, thd->used_tables=0; values= its++; - if (mysql_prepare_insert(thd, table_list, table, fields, values, + if (mysql_prepare_insert(thd, table_list, table_list, table, fields, values, update_fields, update_values, duplic, &unused_conds, FALSE)) goto abort; @@ -734,28 +734,43 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, mysql_prepare_insert() thd Thread handler table_list Global/local table list - table Table to insert into (can be NULL if table should be taken from - table_list->table) + dup_table_list Tables to be used in ON DUPLICATE KEY + It's either all global tables or only the table we + insert into, depending on if we are using GROUP BY + in the SELECT clause). + table Table to insert into (can be NULL if table should + be taken from table_list->table) where Where clause (for insert ... select) select_insert TRUE if INSERT ... SELECT statement + TODO (in far future) + In cases of: + INSERT INTO t1 SELECT a, sum(a) as sum1 from t2 GROUP BY a + ON DUPLICATE KEY ... + we should be able to refer to sum1 in the ON DUPLICATE KEY part + + WARNING + You MUST set table->insert_values to 0 after calling this function + before releasing the table object. + RETURN VALUE FALSE OK TRUE error */ -bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, +bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, + TABLE_LIST *dup_table_list, TABLE *table, List<Item> &fields, List_item *values, List<Item> &update_fields, List<Item> &update_values, enum_duplicates duplic, COND **where, bool select_insert) { - TABLE_LIST *save_table_list= thd->lex->select_lex.context.table_list; + SELECT_LEX= &thd->lex->select_lex; + TABLE_LIST *save_table_list; + TABLE_LIST *save_next_local; bool insert_into_view= (table_list->view != 0); - bool save_resolve_in_select_list= - thd->lex->select_lex.context.resolve_in_select_list; + bool save_resolve_in_select_list; bool res; - TABLE_LIST *next_local; DBUG_ENTER("mysql_prepare_insert"); DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d", (ulong)table_list, (ulong)table, @@ -768,7 +783,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, */ if (!select_insert) { - for (SELECT_LEX_UNIT *un= thd->lex->select_lex.first_inner_unit(); + for (SELECT_LEX_UNIT *un= select_lex->first_inner_unit(); un; un= un->next_unit()) { @@ -792,23 +807,30 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, select_insert)) DBUG_RETURN(TRUE); - next_local= table_list->next_local; + save_table_list= select_lex->context.table_list; + save_resolve_in_select_list= select_lex->context.resolve_in_select_list; + save_next_local= table_list->next_local; + table_list->next_local= 0; - thd->lex->select_lex.context.resolve_in_table_list_only(table_list); + select_lex->context.resolve_in_table_list_only(table_list); if ((values && check_insert_fields(thd, table_list, fields, *values, !insert_into_view)) || (values && setup_fields(thd, 0, *values, 0, 0, 0)) || - (duplic == DUP_UPDATE && - ((thd->lex->select_lex.no_wrap_view_item= TRUE, - (res= check_update_fields(thd, table_list, update_fields)), - thd->lex->select_lex.no_wrap_view_item= FALSE, - res) || - setup_fields(thd, 0, update_values, 1, 0, 0)))) - DBUG_RETURN(TRUE); - table_list->next_local= next_local; - thd->lex->select_lex.context.table_list= save_table_list; - thd->lex->select_lex.context.resolve_in_select_list= - save_resolve_in_select_list; + setup_fields(thd, 0, update_values, 1, 0, 0)) + res= TRUE; + else if (duplic == DUP_UPDATE) + { + select_lex->context.resolve_in_table_list_only(dup_table_list); + select_lex->no_wrap_view_item= TRUE; + res= check_update_fields(thd, table_list, update_fields); + select_lex->no_wrap_view_item= FALSE; + } + table_list->next_local= save_next_local; + select_lex->context.table_list= save_table_list; + select_lex->context.resolve_in_select_list= save_resolve_in_select_list; + if (res) + DBUG_RETURN(res); + if (!table) table= table_list->table; @@ -820,8 +842,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name); DBUG_RETURN(TRUE); } - thd->lex->select_lex.fix_prepare_information(thd, &fake_conds); - thd->lex->select_lex.first_execution= 0; + select_lex->fix_prepare_information(thd, &fake_conds); + select_lex->first_execution= 0; } if (duplic == DUP_UPDATE || duplic == DUP_REPLACE) table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); @@ -1992,12 +2014,25 @@ bool mysql_insert_select_prepare(THD *thd) { LEX *lex= thd->lex; TABLE_LIST *first_select_leaf_table; + TABLE_LIST dup_tables; DBUG_ENTER("mysql_insert_select_prepare"); + /* SELECT_LEX do not belong to INSERT statement, so we can't add WHERE clause if table is VIEW */ - if (mysql_prepare_insert(thd, lex->query_tables, + + dup_tables= *lex->query_tables; + if (lex->select_lex->group_list.elements != 0) + { + /* + When we are using GROUP BY we can't refere to other tables in the + ON DUPLICATE KEY part + */ + dup_tables.local_next= 0; + } + + if (mysql_prepare_insert(thd, lex->query_tables, &dup_tables lex->query_tables->table, lex->field_list, 0, lex->update_list, lex->value_list, lex->duplicates, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 057d2f23ed3..d9e50cba9e4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3236,6 +3236,7 @@ end_with_restore_list: case SQLCOM_REPLACE_SELECT: case SQLCOM_INSERT_SELECT: { + select_result *result; DBUG_ASSERT(first_table == all_tables && first_table != 0); if ((res= insert_precheck(thd, all_tables))) break; @@ -3247,9 +3248,7 @@ end_with_restore_list: /* Don't unlock tables until command is written to binary log */ select_lex->options|= SELECT_NO_UNLOCK; - select_result *result; unit->set_limit(select_lex); - if (!(res= open_and_lock_tables(thd, all_tables))) { /* Skip first table, which is the table we are inserting in */ @@ -6405,9 +6404,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, */ /* - Writing this command to the binlog may result in infinite loops when doing - mysqlbinlog|mysql, and anyway it does not really make sense to log it - automatically (would cause more trouble to users than it would help them) + Writing this command to the binlog may result in infinite loops + when doing mysqlbinlog|mysql, and anyway it does not really make + sense to log it automatically (would cause more trouble to users + than it would help them) */ tmp_write_to_binlog= 0; mysql_log.new_file(1); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 136854a4eaf..61f9ab9e00d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -939,7 +939,7 @@ static bool mysql_test_insert(Prepared_statement *stmt, table_list->table->insert_values=(byte *)1; } - if (mysql_prepare_insert(thd, table_list, table_list->table, fields, + if (mysql_prepare_insert(thd, table_list, table_list, table_list->table, fields, values, update_fields, update_values, duplic, &unused_conds, FALSE)) goto error; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d7ef692e8c3..2e6794dd983 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -28,8 +28,6 @@ #include <hash.h> #include <ft_global.h> -typedef uint32 cache_rec_length_type; - const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref", "MAYBE_REF","ALL","range","index","fulltext", "ref_or_null","unique_subquery","index_subquery", @@ -184,8 +182,8 @@ static void read_cached_record(JOIN_TAB *tab); static bool cmp_buffer_with_ref(JOIN_TAB *tab); static bool setup_new_fields(THD *thd, List<Item> &fields, List<Item> &all_fields, ORDER *new_order); -static ORDER *create_distinct_group(THD *thd, ORDER *order, - List<Item> &fields, +static ORDER *create_distinct_group(THD *thd, Item **ref_pointer_array, + ORDER *order, List<Item> &fields, bool *all_order_by_fields_used); static bool test_if_subpart(ORDER *a,ORDER *b); static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables); @@ -781,7 +779,8 @@ JOIN::optimize() bool all_order_fields_used; if (order) skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1); - if ((group_list=create_distinct_group(thd, order, fields_list, + if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array, + order, fields_list, &all_order_fields_used))) { bool skip_group= (skip_sort_order && @@ -11638,7 +11637,7 @@ used_blob_length(CACHE_FIELD **ptr) static bool store_record_in_cache(JOIN_CACHE *cache) { - cache_rec_length_type length; + uint length; uchar *pos; CACHE_FIELD *copy,*end_field; bool last_record; @@ -11683,9 +11682,9 @@ store_record_in_cache(JOIN_CACHE *cache) end > str && end[-1] == ' ' ; end--) ; length=(uint) (end-str); - memcpy(pos+sizeof(length), str, length); - memcpy_fixed(pos, &length, sizeof(length)); - pos+= length+sizeof(length); + memcpy(pos+2, str, length); + int2store(pos, length); + pos+= length+2; } else { @@ -11719,7 +11718,7 @@ static void read_cached_record(JOIN_TAB *tab) { uchar *pos; - cache_rec_length_type length; + uint length; bool last_record; CACHE_FIELD *copy,*end_field; @@ -11748,10 +11747,10 @@ read_cached_record(JOIN_TAB *tab) { if (copy->strip) { - memcpy_fixed(&length, pos, sizeof(length)); - memcpy(copy->str, pos+sizeof(length), length); + length= uint2korr(pos); + memcpy(copy->str, pos+2, length); memset(copy->str+length, ' ', copy->length-length); - pos+= sizeof(length)+length; + pos+= 2 + length; } else { @@ -11788,12 +11787,10 @@ cp_buffer_from_ref(THD *thd, TABLE_REF *ref) thd->count_cuted_fields= CHECK_FIELD_IGNORE; for (store_key **copy=ref->key_copy ; *copy ; copy++) { - int res; - if ((res= (*copy)->copy())) + if ((*copy)->copy() & 1) { thd->count_cuted_fields= save_count_cuted_fields; - if ((res= res & 1)) - return res; // Something went wrong + return 1; // Something went wrong } } thd->count_cuted_fields= save_count_cuted_fields; @@ -12093,12 +12090,14 @@ setup_new_fields(THD *thd, List<Item> &fields, */ static ORDER * -create_distinct_group(THD *thd, ORDER *order_list, List<Item> &fields, +create_distinct_group(THD *thd, Item **ref_pointer_array, + ORDER *order_list, List<Item> &fields, bool *all_order_by_fields_used) { List_iterator<Item> li(fields); Item *item; ORDER *order,*group,**prev; + uint index= 0; *all_order_by_fields_used= 1; while ((item=li++)) @@ -12130,11 +12129,17 @@ create_distinct_group(THD *thd, ORDER *order_list, List<Item> &fields, ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER)); if (!ord) return 0; - ord->item=li.ref(); + /* + We have here only field_list (not all_field_list), so we can use + simple indexing of ref_pointer_array (order in the array and in the + list are same) + */ + ord->item= ref_pointer_array + index; ord->asc=1; *prev=ord; prev= &ord->next; } + index++; } *prev=0; return group; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5903576947d..b050d46f358 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -267,7 +267,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, table->table_name); else error= 1; - } else { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b1438f1c571..4fc9819d0e1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6148,24 +6148,9 @@ insert_update_elem: simple_ident_nospvar equal expr_or_default { LEX *lex= Lex; - uint8 tmp= MY_ITEM_PREFER_1ST_TABLE; if (lex->update_list.push_back($1) || lex->value_list.push_back($3)) YYABORT; - /* - INSERT INTO a1(a) SELECT b1.a FROM b1 ON DUPLICATE KEY - UPDATE a= a + b1.b - - Set MY_ITEM_PREFER_1ST_TABLE flag to $1 and $3 items - to prevent find_field_in_tables() doing further item searching - if it finds item occurence in first table in insert_table_list. - This allows to avoid ambiguity in resolving 'a' field in - example above. - */ - $1->walk(&Item::set_flags_processor, - (byte *) &tmp); - $3->walk(&Item::set_flags_processor, - (byte *) &tmp); }; opt_low_priority: |