summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2005-07-03 14:17:52 +0300
committerunknown <monty@mysql.com>2005-07-03 14:17:52 +0300
commiteeee5fb10b59f6580ebcb08ebd82d0b75c66aa8f (patch)
treebf06496ea5d097316e5972a5cf4c4d5f674fb90b /sql
parent6d9bc9c8b71acd82aa79ae580271e7dc4012e5a4 (diff)
parentc7ab92c28a535d2419ffa906042fff7e476df972 (diff)
downloadmariadb-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.cc9
-rw-r--r--sql/ha_ndbcluster.cc4
-rw-r--r--sql/handler.cc16
-rw-r--r--sql/item.cc4
-rw-r--r--sql/item.h11
-rw-r--r--sql/item_cmpfunc.h6
-rw-r--r--sql/item_strfunc.cc6
-rw-r--r--sql/item_strfunc.h1
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/mysqld.cc5
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/sql_base.cc42
-rw-r--r--sql/sql_insert.cc85
-rw-r--r--sql/sql_parse.cc10
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc43
-rw-r--r--sql/sql_table.cc1
-rw-r--r--sql/sql_yacc.yy15
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: