Commit 78da7196 authored by monty@mysql.com's avatar monty@mysql.com

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/home/my/mysql-4.1
parents f455778f 1bd22faa
drop table if exists t1; drop table if exists t1;
drop database if exists mysqltest; drop database if exists mysqltest;
drop database if exists client_test_db;
drop table t1; drop table t1;
ERROR 42S02: Unknown table 't1' ERROR 42S02: Unknown table 't1'
create table t1(n int); create table t1(n int);
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1;
drop database if exists mysqltest; drop database if exists mysqltest;
# If earlier test failed
drop database if exists client_test_db;
--enable_warnings --enable_warnings
--error 1051; --error 1051;
......
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
--disable_warnings --disable_warnings
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3;
drop database if exists mysqltest; drop database if exists mysqltest;
--error 0,1141 --error 0,1141,1147
revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
--error 0,1141 --error 0,1141,1147
revoke all privileges on mysqltest.* from mysqltest_1@localhost; revoke all privileges on mysqltest.* from mysqltest_1@localhost;
delete from mysql.user where user=_binary'mysqltest_1'; delete from mysql.user where user=_binary'mysqltest_1';
--enable_warnings --enable_warnings
......
...@@ -1418,7 +1418,7 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex, ...@@ -1418,7 +1418,7 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
const char *db_arg, const char *table_name_arg, const char *db_arg, const char *table_name_arg,
List<Item> &fields_arg, List<Item> &fields_arg,
enum enum_duplicates handle_dup, enum enum_duplicates handle_dup,
bool using_trans) bool ignore, bool using_trans)
:Log_event(thd_arg, !thd_arg->tmp_table_used ? :Log_event(thd_arg, !thd_arg->tmp_table_used ?
0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans), 0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans),
thread_id(thd_arg->thread_id), thread_id(thd_arg->thread_id),
...@@ -1456,9 +1456,6 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex, ...@@ -1456,9 +1456,6 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
sql_ex.empty_flags= 0; sql_ex.empty_flags= 0;
switch (handle_dup) { switch (handle_dup) {
case DUP_IGNORE:
sql_ex.opt_flags|= IGNORE_FLAG;
break;
case DUP_REPLACE: case DUP_REPLACE:
sql_ex.opt_flags|= REPLACE_FLAG; sql_ex.opt_flags|= REPLACE_FLAG;
break; break;
...@@ -1466,6 +1463,8 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex, ...@@ -1466,6 +1463,8 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
case DUP_ERROR: case DUP_ERROR:
break; break;
} }
if (ignore)
sql_ex.opt_flags|= IGNORE_FLAG;
if (!ex->field_term->length()) if (!ex->field_term->length())
sql_ex.empty_flags |= FIELD_TERM_EMPTY; sql_ex.empty_flags |= FIELD_TERM_EMPTY;
...@@ -1791,6 +1790,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, ...@@ -1791,6 +1790,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
{ {
char llbuff[22]; char llbuff[22];
enum enum_duplicates handle_dup; enum enum_duplicates handle_dup;
bool ignore= 0;
/* /*
Make a simplified LOAD DATA INFILE query, for the information of the Make a simplified LOAD DATA INFILE query, for the information of the
user in SHOW PROCESSLIST. Note that db is known in the 'db' column. user in SHOW PROCESSLIST. Note that db is known in the 'db' column.
...@@ -1807,21 +1807,24 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, ...@@ -1807,21 +1807,24 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
if (sql_ex.opt_flags & REPLACE_FLAG) if (sql_ex.opt_flags & REPLACE_FLAG)
handle_dup= DUP_REPLACE; handle_dup= DUP_REPLACE;
else if (sql_ex.opt_flags & IGNORE_FLAG) else if (sql_ex.opt_flags & IGNORE_FLAG)
handle_dup= DUP_IGNORE; {
ignore= 1;
handle_dup= DUP_ERROR;
}
else else
{ {
/* /*
When replication is running fine, if it was DUP_ERROR on the When replication is running fine, if it was DUP_ERROR on the
master then we could choose DUP_IGNORE here, because if DUP_ERROR master then we could choose IGNORE here, because if DUP_ERROR
suceeded on master, and data is identical on the master and slave, suceeded on master, and data is identical on the master and slave,
then there should be no uniqueness errors on slave, so DUP_IGNORE is then there should be no uniqueness errors on slave, so IGNORE is
the same as DUP_ERROR. But in the unlikely case of uniqueness errors the same as DUP_ERROR. But in the unlikely case of uniqueness errors
(because the data on the master and slave happen to be different (because the data on the master and slave happen to be different
(user error or bug), we want LOAD DATA to print an error message on (user error or bug), we want LOAD DATA to print an error message on
the slave to discover the problem. the slave to discover the problem.
If reading from net (a 3.23 master), mysql_load() will change this If reading from net (a 3.23 master), mysql_load() will change this
to DUP_IGNORE. to IGNORE.
*/ */
handle_dup= DUP_ERROR; handle_dup= DUP_ERROR;
} }
...@@ -1855,7 +1858,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, ...@@ -1855,7 +1858,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
*/ */
thd->net.pkt_nr = net->pkt_nr; thd->net.pkt_nr = net->pkt_nr;
} }
if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0, if (mysql_load(thd, &ex, &tables, field_list, handle_dup, ignore, net != 0,
TL_WRITE)) TL_WRITE))
thd->query_error = 1; thd->query_error = 1;
if (thd->cuted_fields) if (thd->cuted_fields)
...@@ -2747,8 +2750,9 @@ Create_file_log_event:: ...@@ -2747,8 +2750,9 @@ Create_file_log_event::
Create_file_log_event(THD* thd_arg, sql_exchange* ex, Create_file_log_event(THD* thd_arg, sql_exchange* ex,
const char* db_arg, const char* table_name_arg, const char* db_arg, const char* table_name_arg,
List<Item>& fields_arg, enum enum_duplicates handle_dup, List<Item>& fields_arg, enum enum_duplicates handle_dup,
bool ignore,
char* block_arg, uint block_len_arg, bool using_trans) char* block_arg, uint block_len_arg, bool using_trans)
:Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
using_trans), using_trans),
fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg), fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
file_id(thd_arg->file_id = mysql_bin_log.next_file_id()) file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
......
...@@ -599,7 +599,7 @@ class Load_log_event: public Log_event ...@@ -599,7 +599,7 @@ class Load_log_event: public Log_event
Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg, Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
const char* table_name_arg, const char* table_name_arg,
List<Item>& fields_arg, enum enum_duplicates handle_dup, List<Item>& fields_arg, enum enum_duplicates handle_dup, bool ignore,
bool using_trans); bool using_trans);
void set_fields(const char* db, List<Item> &fields_arg); void set_fields(const char* db, List<Item> &fields_arg);
const char* get_db() { return db; } const char* get_db() { return db; }
...@@ -908,7 +908,7 @@ class Create_file_log_event: public Load_log_event ...@@ -908,7 +908,7 @@ class Create_file_log_event: public Load_log_event
Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg, Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
const char* table_name_arg, const char* table_name_arg,
List<Item>& fields_arg, List<Item>& fields_arg,
enum enum_duplicates handle_dup, enum enum_duplicates handle_dup, bool ignore,
char* block_arg, uint block_len_arg, char* block_arg, uint block_len_arg,
bool using_trans); bool using_trans);
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
......
...@@ -538,6 +538,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, ...@@ -538,6 +538,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
List<Key> &keys, List<Key> &keys,
uint order_num, ORDER *order, uint order_num, ORDER *order,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates,
bool ignore,
ALTER_INFO *alter_info, bool do_send_ok=1); ALTER_INFO *alter_info, bool do_send_ok=1);
int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok);
int mysql_create_like_table(THD *thd, TABLE_LIST *table, int mysql_create_like_table(THD *thd, TABLE_LIST *table,
...@@ -557,11 +558,11 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list, ...@@ -557,11 +558,11 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields, int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &values,COND *conds, List<Item> &values,COND *conds,
uint order_num, ORDER *order, ha_rows limit, uint order_num, ORDER *order, ha_rows limit,
enum enum_duplicates handle_duplicates); enum enum_duplicates handle_duplicates, bool ignore);
int mysql_multi_update(THD *thd, TABLE_LIST *table_list, int mysql_multi_update(THD *thd, TABLE_LIST *table_list,
List<Item> *fields, List<Item> *values, List<Item> *fields, List<Item> *values,
COND *conds, ulong options, COND *conds, ulong options,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates, bool ignore,
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex); SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex);
int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
TABLE_LIST *insert_table_list, TABLE *table, TABLE_LIST *insert_table_list, TABLE *table,
...@@ -570,7 +571,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, ...@@ -570,7 +571,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
List<Item> &update_values, enum_duplicates duplic); List<Item> &update_values, enum_duplicates duplic);
int mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields, int mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields, List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag); List<Item> &update_values, enum_duplicates flag, bool ignore);
int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds); int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds);
int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order, int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order,
ha_rows rows, ulong options); ha_rows rows, ulong options);
...@@ -759,6 +760,7 @@ bool eval_const_cond(COND *cond); ...@@ -759,6 +760,7 @@ bool eval_const_cond(COND *cond);
/* sql_load.cc */ /* sql_load.cc */
int mysql_load(THD *thd,sql_exchange *ex, TABLE_LIST *table_list, int mysql_load(THD *thd,sql_exchange *ex, TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates, List<Item> &fields, enum enum_duplicates handle_duplicates,
bool ignore,
bool local_file,thr_lock_type lock_type); bool local_file,thr_lock_type lock_type);
int write_record(TABLE *table,COPY_INFO *info); int write_record(TABLE *table,COPY_INFO *info);
......
...@@ -29,7 +29,7 @@ class Slave_log_event; ...@@ -29,7 +29,7 @@ class Slave_log_event;
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME }; enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME };
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE, DUP_UPDATE }; enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE };
enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN}; enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN};
enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
DELAY_KEY_WRITE_ALL }; DELAY_KEY_WRITE_ALL };
...@@ -201,7 +201,8 @@ typedef struct st_copy_info { ...@@ -201,7 +201,8 @@ typedef struct st_copy_info {
ha_rows error_count; ha_rows error_count;
enum enum_duplicates handle_duplicates; enum enum_duplicates handle_duplicates;
int escape_char, last_errno; int escape_char, last_errno;
/* for INSERT ... UPDATE */ bool ignore;
/* for INSERT ... UPDATE */
List<Item> *update_fields; List<Item> *update_fields;
List<Item> *update_values; List<Item> *update_values;
} COPY_INFO; } COPY_INFO;
...@@ -1232,19 +1233,21 @@ class select_insert :public select_result_interceptor { ...@@ -1232,19 +1233,21 @@ class select_insert :public select_result_interceptor {
COPY_INFO info; COPY_INFO info;
select_insert(TABLE *table_par, List<Item> *fields_par, select_insert(TABLE *table_par, List<Item> *fields_par,
enum_duplicates duplic) enum_duplicates duplic, bool ignore)
:table(table_par), fields(fields_par), last_insert_id(0) :table(table_par), fields(fields_par), last_insert_id(0)
{ {
bzero((char*) &info,sizeof(info)); bzero((char*) &info,sizeof(info));
info.ignore= ignore;
info.handle_duplicates=duplic; info.handle_duplicates=duplic;
} }
select_insert(TABLE *table_par, List<Item> *fields_par, select_insert(TABLE *table_par, List<Item> *fields_par,
List<Item> *update_fields, List<Item> *update_values, List<Item> *update_fields, List<Item> *update_values,
enum_duplicates duplic) enum_duplicates duplic, bool ignore)
:table(table_par), fields(fields_par), last_insert_id(0) :table(table_par), fields(fields_par), last_insert_id(0)
{ {
bzero((char*) &info,sizeof(info)); bzero((char*) &info,sizeof(info));
info.handle_duplicates=duplic; info.ignore= ignore;
info.handle_duplicates= duplic;
info.update_fields= update_fields; info.update_fields= update_fields;
info.update_values= update_values; info.update_values= update_values;
} }
...@@ -1273,8 +1276,8 @@ class select_create: public select_insert { ...@@ -1273,8 +1276,8 @@ class select_create: public select_insert {
HA_CREATE_INFO *create_info_par, HA_CREATE_INFO *create_info_par,
List<create_field> &fields_par, List<create_field> &fields_par,
List<Key> &keys_par, List<Key> &keys_par,
List<Item> &select_fields,enum_duplicates duplic) List<Item> &select_fields,enum_duplicates duplic, bool ignore)
:select_insert (NULL, &select_fields, duplic), db(db_name), :select_insert (NULL, &select_fields, duplic, ignore), db(db_name),
name(table_name), extra_fields(&fields_par),keys(&keys_par), name(table_name), extra_fields(&fields_par),keys(&keys_par),
create_info(create_info_par), lock(0) create_info(create_info_par), lock(0)
{} {}
...@@ -1525,11 +1528,11 @@ class multi_update :public select_result_interceptor ...@@ -1525,11 +1528,11 @@ class multi_update :public select_result_interceptor
uint table_count; uint table_count;
Copy_field *copy_field; Copy_field *copy_field;
enum enum_duplicates handle_duplicates; enum enum_duplicates handle_duplicates;
bool do_update, trans_safe, transactional_tables, log_delayed; bool do_update, trans_safe, transactional_tables, log_delayed, ignore;
public: public:
multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> *fields, multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> *fields,
List<Item> *values, enum_duplicates handle_duplicates); List<Item> *values, enum_duplicates handle_duplicates, bool ignore);
~multi_update(); ~multi_update();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
......
...@@ -57,8 +57,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, ...@@ -57,8 +57,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (thd->lex->duplicates == DUP_IGNORE) thd->lex->select_lex.no_error= thd->lex->ignore;
thd->lex->select_lex.no_error= 1;
/* Test if the user wants to delete all rows */ /* Test if the user wants to delete all rows */
if (!using_limit && const_cond && (!conds || conds->val_int()) && if (!using_limit && const_cond && (!conds || conds->val_int()) &&
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
static int check_null_fields(THD *thd,TABLE *entry); static int check_null_fields(THD *thd,TABLE *entry);
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list); static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list);
static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup, static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup, bool ignore,
char *query, uint query_length, int log_on); char *query, uint query_length, int log_on);
static void end_delayed_insert(THD *thd); static void end_delayed_insert(THD *thd);
extern "C" pthread_handler_decl(handle_delayed_insert,arg); extern "C" pthread_handler_decl(handle_delayed_insert,arg);
...@@ -111,7 +111,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -111,7 +111,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
List<List_item> &values_list, List<List_item> &values_list,
List<Item> &update_fields, List<Item> &update_fields,
List<Item> &update_values, List<Item> &update_values,
enum_duplicates duplic) enum_duplicates duplic,
bool ignore)
{ {
int error, res; int error, res;
/* /*
...@@ -222,9 +223,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -222,9 +223,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
*/ */
info.records= info.deleted= info.copied= info.updated= 0; info.records= info.deleted= info.copied= info.updated= 0;
info.ignore= ignore;
info.handle_duplicates=duplic; info.handle_duplicates=duplic;
info.update_fields=&update_fields; info.update_fields= &update_fields;
info.update_values=&update_values; info.update_values= &update_values;
/* /*
Count warnings for all inserts. Count warnings for all inserts.
For single line insert, generate an error if try to set a NOT NULL field For single line insert, generate an error if try to set a NOT NULL field
...@@ -289,7 +291,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -289,7 +291,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
if (lock_type == TL_WRITE_DELAYED) if (lock_type == TL_WRITE_DELAYED)
{ {
error=write_delayed(thd,table,duplic,query, thd->query_length, log_on); error=write_delayed(thd, table, duplic, ignore, query, thd->query_length, log_on);
query=0; query=0;
} }
else else
...@@ -395,7 +397,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -395,7 +397,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
else else
{ {
char buff[160]; char buff[160];
if (duplic == DUP_IGNORE) if (ignore)
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(lock_type == TL_WRITE_DELAYED) ? (ulong) 0 : (lock_type == TL_WRITE_DELAYED) ? (ulong) 0 :
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields); (ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
...@@ -591,7 +593,7 @@ int write_record(TABLE *table,COPY_INFO *info) ...@@ -591,7 +593,7 @@ int write_record(TABLE *table,COPY_INFO *info)
} }
else if ((error=table->file->write_row(table->record[0]))) else if ((error=table->file->write_row(table->record[0])))
{ {
if (info->handle_duplicates != DUP_IGNORE || if (!info->ignore ||
(error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)) (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE))
goto err; goto err;
} }
...@@ -647,14 +649,14 @@ class delayed_row :public ilink { ...@@ -647,14 +649,14 @@ class delayed_row :public ilink {
char *record,*query; char *record,*query;
enum_duplicates dup; enum_duplicates dup;
time_t start_time; time_t start_time;
bool query_start_used,last_insert_id_used,insert_id_used; bool query_start_used,last_insert_id_used,insert_id_used, ignore;
int log_query; int log_query;
ulonglong last_insert_id; ulonglong last_insert_id;
timestamp_auto_set_type timestamp_field_type; timestamp_auto_set_type timestamp_field_type;
uint query_length; uint query_length;
delayed_row(enum_duplicates dup_arg, int log_query_arg) delayed_row(enum_duplicates dup_arg, bool ignore_arg, int log_query_arg)
:record(0),query(0),dup(dup_arg),log_query(log_query_arg) {} :record(0),query(0),dup(dup_arg),ignore(ignore_arg),log_query(log_query_arg) {}
~delayed_row() ~delayed_row()
{ {
x_free(record); x_free(record);
...@@ -966,7 +968,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd) ...@@ -966,7 +968,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
/* Put a question in queue */ /* Put a question in queue */
static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, bool ignore,
char *query, uint query_length, int log_on) char *query, uint query_length, int log_on)
{ {
delayed_row *row=0; delayed_row *row=0;
...@@ -979,7 +981,7 @@ static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, ...@@ -979,7 +981,7 @@ static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic,
pthread_cond_wait(&di->cond_client,&di->mutex); pthread_cond_wait(&di->cond_client,&di->mutex);
thd->proc_info="storing row into queue"; thd->proc_info="storing row into queue";
if (thd->killed || !(row= new delayed_row(duplic, log_on))) if (thd->killed || !(row= new delayed_row(duplic, ignore, log_on)))
goto err; goto err;
if (!query) if (!query)
...@@ -1340,8 +1342,9 @@ bool delayed_insert::handle_inserts(void) ...@@ -1340,8 +1342,9 @@ bool delayed_insert::handle_inserts(void)
thd.insert_id_used=row->insert_id_used; thd.insert_id_used=row->insert_id_used;
table->timestamp_field_type= row->timestamp_field_type; table->timestamp_field_type= row->timestamp_field_type;
info.ignore= row->ignore;
info.handle_duplicates= row->dup; info.handle_duplicates= row->dup;
if (info.handle_duplicates == DUP_IGNORE || if (info.ignore ||
info.handle_duplicates == DUP_REPLACE) info.handle_duplicates == DUP_REPLACE)
{ {
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
...@@ -1459,7 +1462,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -1459,7 +1462,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
restore_record(table,default_values); // Get empty record restore_record(table,default_values); // Get empty record
table->next_number_field=table->found_next_number_field; table->next_number_field=table->found_next_number_field;
thd->cuted_fields=0; thd->cuted_fields=0;
if (info.handle_duplicates == DUP_IGNORE || if (info.ignore ||
info.handle_duplicates == DUP_REPLACE) info.handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);
...@@ -1601,7 +1604,7 @@ bool select_insert::send_eof() ...@@ -1601,7 +1604,7 @@ bool select_insert::send_eof()
DBUG_RETURN(1); DBUG_RETURN(1);
} }
char buff[160]; char buff[160];
if (info.handle_duplicates == DUP_IGNORE) if (info.ignore)
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields); (ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
else else
...@@ -1645,7 +1648,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -1645,7 +1648,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
restore_record(table,default_values); // Get empty record restore_record(table,default_values); // Get empty record
thd->cuted_fields=0; thd->cuted_fields=0;
if (info.handle_duplicates == DUP_IGNORE || if (info.ignore ||
info.handle_duplicates == DUP_REPLACE) info.handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);
......
...@@ -158,6 +158,7 @@ void lex_start(THD *thd, uchar *buf,uint length) ...@@ -158,6 +158,7 @@ void lex_start(THD *thd, uchar *buf,uint length)
lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE); lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
lex->sql_command=SQLCOM_END; lex->sql_command=SQLCOM_END;
lex->duplicates= DUP_ERROR; lex->duplicates= DUP_ERROR;
lex->ignore= 0;
lex->proc_list.first= 0; lex->proc_list.first= 0;
} }
......
...@@ -618,7 +618,7 @@ typedef struct st_lex ...@@ -618,7 +618,7 @@ typedef struct st_lex
bool in_comment, ignore_space, verbose, no_write_to_binlog; bool in_comment, ignore_space, verbose, no_write_to_binlog;
bool derived_tables; bool derived_tables;
bool safe_to_cache_query; bool safe_to_cache_query;
bool subqueries; bool subqueries, ignore;
ALTER_INFO alter_info; ALTER_INFO alter_info;
/* Prepared statements SQL syntax:*/ /* Prepared statements SQL syntax:*/
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */ LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
......
...@@ -80,6 +80,7 @@ static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, ...@@ -80,6 +80,7 @@ static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates, List<Item> &fields, enum enum_duplicates handle_duplicates,
bool ignore,
bool read_file_from_client,thr_lock_type lock_type) bool read_file_from_client,thr_lock_type lock_type)
{ {
char name[FN_REFLEN]; char name[FN_REFLEN];
...@@ -165,7 +166,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -165,7 +166,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
/* We can't give an error in the middle when using LOCAL files */ /* We can't give an error in the middle when using LOCAL files */
if (read_file_from_client && handle_duplicates == DUP_ERROR) if (read_file_from_client && handle_duplicates == DUP_ERROR)
handle_duplicates=DUP_IGNORE; ignore= 1;
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
if (read_file_from_client) if (read_file_from_client)
...@@ -216,6 +217,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -216,6 +217,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
COPY_INFO info; COPY_INFO info;
bzero((char*) &info,sizeof(info)); bzero((char*) &info,sizeof(info));
info.ignore= ignore;
info.handle_duplicates=handle_duplicates; info.handle_duplicates=handle_duplicates;
info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX; info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX;
...@@ -237,6 +239,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -237,6 +239,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
lf_info.db = db; lf_info.db = db;
lf_info.table_name = table_list->real_name; lf_info.table_name = table_list->real_name;
lf_info.fields = &fields; lf_info.fields = &fields;
lf_info.ignore= ignore;
lf_info.handle_dup = handle_duplicates; lf_info.handle_dup = handle_duplicates;
lf_info.wrote_create_file = 0; lf_info.wrote_create_file = 0;
lf_info.last_pos_in_file = HA_POS_ERROR; lf_info.last_pos_in_file = HA_POS_ERROR;
...@@ -267,7 +270,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -267,7 +270,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
table->next_number_field=table->found_next_number_field; table->next_number_field=table->found_next_number_field;
if (handle_duplicates == DUP_IGNORE || if (ignore ||
handle_duplicates == DUP_REPLACE) handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
ha_enable_transaction(thd, FALSE); ha_enable_transaction(thd, FALSE);
......
...@@ -2393,7 +2393,8 @@ mysql_execute_command(THD *thd) ...@@ -2393,7 +2393,8 @@ mysql_execute_command(THD *thd)
&lex->create_info, &lex->create_info,
lex->create_list, lex->create_list,
lex->key_list, lex->key_list,
select_lex->item_list,lex->duplicates))) select_lex->item_list, lex->duplicates,
lex->ignore)))
{ {
/* /*
CREATE from SELECT give its SELECT_LEX for SELECT, CREATE from SELECT give its SELECT_LEX for SELECT,
...@@ -2533,7 +2534,7 @@ mysql_execute_command(THD *thd) ...@@ -2533,7 +2534,7 @@ mysql_execute_command(THD *thd)
lex->key_list, lex->key_list,
select_lex->order_list.elements, select_lex->order_list.elements,
(ORDER *) select_lex->order_list.first, (ORDER *) select_lex->order_list.first,
lex->duplicates, &lex->alter_info); lex->duplicates, lex->ignore, &lex->alter_info);
} }
break; break;
} }
...@@ -2695,7 +2696,7 @@ mysql_execute_command(THD *thd) ...@@ -2695,7 +2696,7 @@ mysql_execute_command(THD *thd)
select_lex->order_list.elements, select_lex->order_list.elements,
(ORDER *) select_lex->order_list.first, (ORDER *) select_lex->order_list.first,
select_lex->select_limit, select_lex->select_limit,
lex->duplicates); lex->duplicates, lex->ignore);
if (thd->net.report_error) if (thd->net.report_error)
res= -1; res= -1;
break; break;
...@@ -2708,7 +2709,7 @@ mysql_execute_command(THD *thd) ...@@ -2708,7 +2709,7 @@ mysql_execute_command(THD *thd)
&lex->value_list, &lex->value_list,
select_lex->where, select_lex->where,
select_lex->options, select_lex->options,
lex->duplicates, unit, select_lex); lex->duplicates, lex->ignore, unit, select_lex);
break; break;
} }
case SQLCOM_REPLACE: case SQLCOM_REPLACE:
...@@ -2716,9 +2717,9 @@ mysql_execute_command(THD *thd) ...@@ -2716,9 +2717,9 @@ mysql_execute_command(THD *thd)
{ {
if ((res= insert_precheck(thd, tables))) if ((res= insert_precheck(thd, tables)))
break; break;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values, res= mysql_insert(thd,tables,lex->field_list,lex->many_values,
lex->update_list, lex->value_list, lex->update_list, lex->value_list,
lex->duplicates); lex->duplicates, lex->ignore);
if (thd->net.report_error) if (thd->net.report_error)
res= -1; res= -1;
break; break;
...@@ -2756,7 +2757,7 @@ mysql_execute_command(THD *thd) ...@@ -2756,7 +2757,7 @@ mysql_execute_command(THD *thd)
lex->duplicates)) && lex->duplicates)) &&
(result= new select_insert(tables->table, &lex->field_list, (result= new select_insert(tables->table, &lex->field_list,
&lex->update_list, &lex->value_list, &lex->update_list, &lex->value_list,
lex->duplicates))) lex->duplicates, lex->ignore)))
{ {
TABLE *table= tables->table; TABLE *table= tables->table;
/* Skip first table, which is the table we are inserting in */ /* Skip first table, which is the table we are inserting in */
...@@ -3066,7 +3067,7 @@ mysql_execute_command(THD *thd) ...@@ -3066,7 +3067,7 @@ mysql_execute_command(THD *thd)
goto error; goto error;
} }
res=mysql_load(thd, lex->exchange, tables, lex->field_list, res=mysql_load(thd, lex->exchange, tables, lex->field_list,
lex->duplicates, (bool) lex->local_file, lex->lock_option); lex->duplicates, lex->ignore, (bool) lex->local_file, lex->lock_option);
break; break;
} }
...@@ -5119,7 +5120,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) ...@@ -5119,7 +5120,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list, &create_info, table_list,
fields, keys, 0, (ORDER*)0, fields, keys, 0, (ORDER*)0,
DUP_ERROR, &alter_info)); DUP_ERROR, 0, &alter_info));
} }
...@@ -5138,7 +5139,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) ...@@ -5138,7 +5139,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info)
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list, &create_info, table_list,
fields, keys, 0, (ORDER*)0, fields, keys, 0, (ORDER*)0,
DUP_ERROR, alter_info)); DUP_ERROR, 0, alter_info));
} }
......
...@@ -1380,7 +1380,7 @@ int show_binlogs(THD* thd) ...@@ -1380,7 +1380,7 @@ int show_binlogs(THD* thd)
int log_loaded_block(IO_CACHE* file) int log_loaded_block(IO_CACHE* file)
{ {
LOAD_FILE_INFO* lf_info; LOAD_FILE_INFO *lf_info;
uint block_len ; uint block_len ;
/* file->request_pos contains position where we started last read */ /* file->request_pos contains position where we started last read */
...@@ -1402,7 +1402,7 @@ int log_loaded_block(IO_CACHE* file) ...@@ -1402,7 +1402,7 @@ int log_loaded_block(IO_CACHE* file)
{ {
Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db, Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db,
lf_info->table_name, *lf_info->fields, lf_info->table_name, *lf_info->fields,
lf_info->handle_dup, buffer, lf_info->handle_dup, lf_info->ignore, buffer,
block_len, lf_info->log_delayed); block_len, lf_info->log_delayed);
mysql_bin_log.write(&c); mysql_bin_log.write(&c);
lf_info->wrote_create_file = 1; lf_info->wrote_create_file = 1;
......
...@@ -67,7 +67,7 @@ typedef struct st_load_file_info ...@@ -67,7 +67,7 @@ typedef struct st_load_file_info
enum enum_duplicates handle_dup; enum enum_duplicates handle_dup;
char* db; char* db;
char* table_name; char* table_name;
bool wrote_create_file, log_delayed; bool wrote_create_file, log_delayed, ignore;
} LOAD_FILE_INFO; } LOAD_FILE_INFO;
int log_loaded_block(IO_CACHE* file); int log_loaded_block(IO_CACHE* file);
......
...@@ -468,7 +468,7 @@ JOIN::optimize() ...@@ -468,7 +468,7 @@ JOIN::optimize()
optimized= 1; optimized= 1;
// Ignore errors of execution if option IGNORE present // Ignore errors of execution if option IGNORE present
if (thd->lex->duplicates == DUP_IGNORE) if (thd->lex->ignore)
thd->lex->current_select->no_error= 1; thd->lex->current_select->no_error= 1;
#ifdef HAVE_REF_TO_FIELDS // Not done yet #ifdef HAVE_REF_TO_FIELDS // Not done yet
/* Add HAVING to WHERE if possible */ /* Add HAVING to WHERE if possible */
......
...@@ -36,6 +36,7 @@ static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end); ...@@ -36,6 +36,7 @@ static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
static int copy_data_between_tables(TABLE *from,TABLE *to, static int copy_data_between_tables(TABLE *from,TABLE *to,
List<create_field> &create, List<create_field> &create,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates,
bool ignore,
uint order_num, ORDER *order, uint order_num, ORDER *order,
ha_rows *copied,ha_rows *deleted); ha_rows *copied,ha_rows *deleted);
...@@ -2686,7 +2687,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2686,7 +2687,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
TABLE_LIST *table_list, TABLE_LIST *table_list,
List<create_field> &fields, List<Key> &keys, List<create_field> &fields, List<Key> &keys,
uint order_num, ORDER *order, uint order_num, ORDER *order,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates, bool ignore,
ALTER_INFO *alter_info, bool do_send_ok) ALTER_INFO *alter_info, bool do_send_ok)
{ {
TABLE *table,*new_table; TABLE *table,*new_table;
...@@ -3205,7 +3206,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -3205,7 +3206,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
copied=deleted=0; copied=deleted=0;
if (!new_table->is_view) if (!new_table->is_view)
error=copy_data_between_tables(table,new_table,create_list, error=copy_data_between_tables(table,new_table,create_list,
handle_duplicates, handle_duplicates, ignore,
order_num, order, &copied, &deleted); order_num, order, &copied, &deleted);
thd->last_insert_id=next_insert_id; // Needed for correct log thd->last_insert_id=next_insert_id; // Needed for correct log
thd->count_cuted_fields= CHECK_FIELD_IGNORE; thd->count_cuted_fields= CHECK_FIELD_IGNORE;
...@@ -3425,6 +3426,7 @@ static int ...@@ -3425,6 +3426,7 @@ static int
copy_data_between_tables(TABLE *from,TABLE *to, copy_data_between_tables(TABLE *from,TABLE *to,
List<create_field> &create, List<create_field> &create,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates,
bool ignore,
uint order_num, ORDER *order, uint order_num, ORDER *order,
ha_rows *copied, ha_rows *copied,
ha_rows *deleted) ha_rows *deleted)
...@@ -3518,7 +3520,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -3518,7 +3520,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
current query id */ current query id */
from->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); from->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1); init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
if (handle_duplicates == DUP_IGNORE || if (ignore ||
handle_duplicates == DUP_REPLACE) handle_duplicates == DUP_REPLACE)
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY); to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
thd->row_count= 0; thd->row_count= 0;
...@@ -3544,7 +3546,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -3544,7 +3546,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
} }
if ((error=to->file->write_row((byte*) to->record[0]))) if ((error=to->file->write_row((byte*) to->record[0])))
{ {
if ((handle_duplicates != DUP_IGNORE && if ((!ignore &&
handle_duplicates != DUP_REPLACE) || handle_duplicates != DUP_REPLACE) ||
(error != HA_ERR_FOUND_DUPP_KEY && (error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE)) error != HA_ERR_FOUND_DUPP_UNIQUE))
...@@ -3620,7 +3622,7 @@ int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, ...@@ -3620,7 +3622,7 @@ int mysql_recreate_table(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info, DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
table_list, lex->create_list, table_list, lex->create_list,
lex->key_list, 0, (ORDER *) 0, lex->key_list, 0, (ORDER *) 0,
DUP_ERROR, &lex->alter_info, do_send_ok)); DUP_ERROR, 0, &lex->alter_info, do_send_ok));
} }
......
...@@ -45,10 +45,10 @@ select_union::select_union(TABLE *table_par) ...@@ -45,10 +45,10 @@ select_union::select_union(TABLE *table_par)
{ {
bzero((char*) &info,sizeof(info)); bzero((char*) &info,sizeof(info));
/* /*
We can always use DUP_IGNORE because the temporary table will only We can always use IGNORE because the temporary table will only
contain a unique key if we are using not using UNION ALL contain a unique key if we are using not using UNION ALL
*/ */
info.handle_duplicates= DUP_IGNORE; info.ignore= 1;
} }
select_union::~select_union() select_union::~select_union()
......
...@@ -54,7 +54,8 @@ int mysql_update(THD *thd, ...@@ -54,7 +54,8 @@ int mysql_update(THD *thd,
COND *conds, COND *conds,
uint order_num, ORDER *order, uint order_num, ORDER *order,
ha_rows limit, ha_rows limit,
enum enum_duplicates handle_duplicates) enum enum_duplicates handle_duplicates,
bool ignore)
{ {
bool using_limit=limit != HA_POS_ERROR; bool using_limit=limit != HA_POS_ERROR;
bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool safe_update= thd->options & OPTION_SAFE_UPDATES;
...@@ -274,7 +275,7 @@ int mysql_update(THD *thd, ...@@ -274,7 +275,7 @@ int mysql_update(THD *thd,
} }
} }
if (handle_duplicates == DUP_IGNORE) if (ignore)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
init_read_record(&info,thd,table,select,0,1); init_read_record(&info,thd,table,select,0,1);
...@@ -299,8 +300,7 @@ int mysql_update(THD *thd, ...@@ -299,8 +300,7 @@ int mysql_update(THD *thd,
{ {
updated++; updated++;
} }
else if (handle_duplicates != DUP_IGNORE || else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY)
error != HA_ERR_FOUND_DUPP_KEY)
{ {
thd->fatal_error(); // Force error message thd->fatal_error(); // Force error message
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));
...@@ -476,7 +476,7 @@ int mysql_multi_update(THD *thd, ...@@ -476,7 +476,7 @@ int mysql_multi_update(THD *thd,
List<Item> *values, List<Item> *values,
COND *conds, COND *conds,
ulong options, ulong options,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates, bool ignore,
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex) SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
{ {
int res; int res;
...@@ -667,7 +667,7 @@ int mysql_multi_update(THD *thd, ...@@ -667,7 +667,7 @@ int mysql_multi_update(THD *thd,
} }
if (!(result=new multi_update(thd, update_list, fields, values, if (!(result=new multi_update(thd, update_list, fields, values,
handle_duplicates))) handle_duplicates, ignore)))
DBUG_RETURN(-1); DBUG_RETURN(-1);
res= mysql_select(thd, &select_lex->ref_pointer_array, res= mysql_select(thd, &select_lex->ref_pointer_array,
...@@ -684,11 +684,11 @@ int mysql_multi_update(THD *thd, ...@@ -684,11 +684,11 @@ int mysql_multi_update(THD *thd,
multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list, multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list,
List<Item> *field_list, List<Item> *value_list, List<Item> *field_list, List<Item> *value_list,
enum enum_duplicates handle_duplicates_arg) enum enum_duplicates handle_duplicates_arg, bool ignore_arg)
:all_tables(table_list), update_tables(0), thd(thd_arg), tmp_tables(0), :all_tables(table_list), update_tables(0), thd(thd_arg), tmp_tables(0),
updated(0), found(0), fields(field_list), values(value_list), updated(0), found(0), fields(field_list), values(value_list),
table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg), table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg),
do_update(1), trans_safe(0), transactional_tables(1) do_update(1), trans_safe(0), transactional_tables(1), ignore(ignore_arg)
{} {}
...@@ -1021,8 +1021,7 @@ bool multi_update::send_data(List<Item> &not_used_values) ...@@ -1021,8 +1021,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
table->record[0]))) table->record[0])))
{ {
updated--; updated--;
if (handle_duplicates != DUP_IGNORE || if (!ignore || error != HA_ERR_FOUND_DUPP_KEY)
error != HA_ERR_FOUND_DUPP_KEY)
{ {
thd->fatal_error(); // Force error message thd->fatal_error(); // Force error message
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));
...@@ -1154,8 +1153,7 @@ int multi_update::do_updates(bool from_send_error) ...@@ -1154,8 +1153,7 @@ int multi_update::do_updates(bool from_send_error)
if ((local_error=table->file->update_row(table->record[1], if ((local_error=table->file->update_row(table->record[1],
table->record[0]))) table->record[0])))
{ {
if (local_error != HA_ERR_FOUND_DUPP_KEY || if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY)
handle_duplicates != DUP_IGNORE)
goto err; goto err;
} }
updated++; updated++;
......
...@@ -1849,8 +1849,9 @@ alter: ...@@ -1849,8 +1849,9 @@ alter:
{ {
THD *thd= YYTHD; THD *thd= YYTHD;
LEX *lex= thd->lex; LEX *lex= thd->lex;
lex->sql_command = SQLCOM_ALTER_TABLE; lex->sql_command= SQLCOM_ALTER_TABLE;
lex->name=0; lex->name= 0;
lex->duplicates= DUP_ERROR;
if (!lex->select_lex.add_table_to_list(thd, $4, NULL, if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
TL_OPTION_UPDATING)) TL_OPTION_UPDATING))
YYABORT; YYABORT;
...@@ -2035,8 +2036,9 @@ opt_column: ...@@ -2035,8 +2036,9 @@ opt_column:
| COLUMN_SYM {}; | COLUMN_SYM {};
opt_ignore: opt_ignore:
/* empty */ { Lex->duplicates=DUP_ERROR; } /* empty */ { Lex->ignore= 0;}
| IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; | IGNORE_SYM { Lex->ignore= 1;}
;
opt_restrict: opt_restrict:
/* empty */ {} /* empty */ {}
...@@ -4012,7 +4014,8 @@ insert: ...@@ -4012,7 +4014,8 @@ insert:
INSERT INSERT
{ {
LEX *lex= Lex; LEX *lex= Lex;
lex->sql_command = SQLCOM_INSERT; lex->sql_command= SQLCOM_INSERT;
lex->duplicates= DUP_ERROR;
/* for subselects */ /* for subselects */
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
...@@ -4174,6 +4177,7 @@ update: ...@@ -4174,6 +4177,7 @@ update:
mysql_init_select(lex); mysql_init_select(lex);
lex->sql_command= SQLCOM_UPDATE; lex->sql_command= SQLCOM_UPDATE;
lex->lock_option= TL_UNLOCK; /* Will be set later */ lex->lock_option= TL_UNLOCK; /* Will be set later */
lex->duplicates= DUP_ERROR;
} }
opt_low_priority opt_ignore join_table_list opt_low_priority opt_ignore join_table_list
SET update_list SET update_list
...@@ -4233,6 +4237,7 @@ delete: ...@@ -4233,6 +4237,7 @@ delete:
LEX *lex= Lex; LEX *lex= Lex;
lex->sql_command= SQLCOM_DELETE; lex->sql_command= SQLCOM_DELETE;
lex->lock_option= lex->thd->update_lock_default; lex->lock_option= lex->thd->update_lock_default;
lex->ignore= 0;
lex->select_lex.init_order(); lex->select_lex.init_order();
} }
opt_delete_options single_multi {} opt_delete_options single_multi {}
...@@ -4289,7 +4294,7 @@ opt_delete_options: ...@@ -4289,7 +4294,7 @@ opt_delete_options:
opt_delete_option: opt_delete_option:
QUICK { Select->options|= OPTION_QUICK; } QUICK { Select->options|= OPTION_QUICK; }
| LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
| IGNORE_SYM { Lex->duplicates= DUP_IGNORE; }; | IGNORE_SYM { Lex->ignore= 1; };
truncate: truncate:
TRUNCATE_SYM opt_table_sym table_name TRUNCATE_SYM opt_table_sym table_name
...@@ -4698,6 +4703,8 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING_sys ...@@ -4698,6 +4703,8 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING_sys
lex->sql_command= SQLCOM_LOAD; lex->sql_command= SQLCOM_LOAD;
lex->lock_option= $3; lex->lock_option= $3;
lex->local_file= $4; lex->local_file= $4;
lex->duplicates= DUP_ERROR;
lex->ignore= 0;
if (!(lex->exchange= new sql_exchange($6.str,0))) if (!(lex->exchange= new sql_exchange($6.str,0)))
YYABORT; YYABORT;
lex->field_list.empty(); lex->field_list.empty();
...@@ -4735,7 +4742,7 @@ load_data_lock: ...@@ -4735,7 +4742,7 @@ load_data_lock:
opt_duplicate: opt_duplicate:
/* empty */ { Lex->duplicates=DUP_ERROR; } /* empty */ { Lex->duplicates=DUP_ERROR; }
| REPLACE { Lex->duplicates=DUP_REPLACE; } | REPLACE { Lex->duplicates=DUP_REPLACE; }
| IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; | IGNORE_SYM { Lex->ignore= 1; };
opt_field_term: opt_field_term:
/* empty */ /* empty */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment