Below is the list of changes that have just been committed into a local
5.0 repository of svoj. When svoj does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2006-10-02 14:52:09+05:00, svoj@stripped +7 -0
Merge svojtovich@stripped:/home/bk/mysql-5.0
into mysql.com:/home/svoj/devel/mysql/merge/mysql-5.0-engines
MERGE: 1.2276.1.16
BitKeeper/etc/ignore@stripped, 2006-10-02 14:52:00+05:00, svoj@stripped +0 -0
auto-union
MERGE: 1.232.1.1
mysql-test/r/myisam.result@stripped, 2006-10-02 14:52:04+05:00, svoj@stripped +0 -0
Auto merged
MERGE: 1.84.1.1
mysql-test/t/myisam.test@stripped, 2006-10-02 14:52:04+05:00, svoj@stripped +0 -0
Auto merged
MERGE: 1.66.1.1
sql/share/errmsg.txt@stripped, 2006-10-02 14:52:05+05:00, svoj@stripped +0 -0
Auto merged
MERGE: 1.71.1.1
sql/sql_insert.cc@stripped, 2006-10-02 14:52:04+05:00, svoj@stripped +0 -0
Auto merged
MERGE: 1.201.1.1
sql/sql_select.cc@stripped, 2006-10-02 14:52:04+05:00, svoj@stripped +0 -0
Auto merged
MERGE: 1.454.2.1
sql/table.cc@stripped, 2006-10-02 14:52:05+05:00, svoj@stripped +0 -0
Auto merged
MERGE: 1.232.1.1
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: svoj
# Host: april.(none)
# Root: /home/svoj/devel/mysql/merge/mysql-5.0-engines/RESYNC
--- 1.202/sql/sql_insert.cc 2006-10-02 14:52:14 +05:00
+++ 1.203/sql/sql_insert.cc 2006-10-02 14:52:14 +05:00
@@ -1303,6 +1303,9 @@ public:
time_t start_time;
bool query_start_used,last_insert_id_used,insert_id_used, ignore, log_query;
ulonglong last_insert_id;
+ ulonglong next_insert_id;
+ ulong auto_increment_increment;
+ ulong auto_increment_offset;
timestamp_auto_set_type timestamp_field_type;
uint query_length;
@@ -1684,6 +1687,22 @@ static int write_delayed(THD *thd,TABLE
row->last_insert_id= thd->last_insert_id;
row->timestamp_field_type= table->timestamp_field_type;
+ /* The session variable settings can always be copied. */
+ row->auto_increment_increment= thd->variables.auto_increment_increment;
+ row->auto_increment_offset= thd->variables.auto_increment_offset;
+ /*
+ Next insert id must be set for the first value in a multi-row insert
+ only. So clear it after the first use. Assume a multi-row insert.
+ Since the user thread doesn't really execute the insert,
+ thd->next_insert_id is left untouched between the rows. If we copy
+ the same insert id to every row of the multi-row insert, the delayed
+ insert thread would copy this before inserting every row. Thus it
+ tries to insert all rows with the same insert id. This fails on the
+ unique constraint. So just the first row would be really inserted.
+ */
+ row->next_insert_id= thd->next_insert_id;
+ thd->next_insert_id= 0;
+
di->rows.push_back(row);
di->stacked_inserts++;
di->status=1;
@@ -2055,6 +2074,14 @@ bool delayed_insert::handle_inserts(void
thd.insert_id_used=row->insert_id_used;
table->timestamp_field_type= row->timestamp_field_type;
+ /* The session variable settings can always be copied. */
+ thd.variables.auto_increment_increment= row->auto_increment_increment;
+ thd.variables.auto_increment_offset= row->auto_increment_offset;
+ /* Next insert id must be used only if non-zero. */
+ if (row->next_insert_id)
+ thd.next_insert_id= row->next_insert_id;
+ DBUG_PRINT("loop", ("next_insert_id: %lu", (ulong) thd.next_insert_id));
+
info.ignore= row->ignore;
info.handle_duplicates= row->dup;
if (info.ignore ||
@@ -2076,6 +2103,20 @@ bool delayed_insert::handle_inserts(void
info.error_count++; // Ignore errors
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
row->log_query = 0;
+ /*
+ We must reset next_insert_id. Otherwise all following rows may
+ become duplicates. If write_record() failed on a duplicate and
+ next_insert_id would be left unchanged, the next rows would also
+ be tried with the same insert id and would fail. Since the end
+ of a multi-row statement is unknown here, all following rows in
+ the queue would be dropped, regardless which thread added them.
+ After the queue is used up, next_insert_id is cleared and the
+ next run will succeed. This could even happen if these come from
+ the same multi-row statement as the current queue contents. That
+ way it would look somewhat random which rows are rejected after
+ a duplicate.
+ */
+ thd.next_insert_id= 0;
}
if (using_ignore)
{
@@ -2121,6 +2162,7 @@ bool delayed_insert::handle_inserts(void
/* This should never happen */
table->file->print_error(error,MYF(0));
sql_print_error("%s",thd.net.last_error);
+ DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
goto err;
}
query_cache_invalidate3(&thd, table, 1);
@@ -2146,6 +2188,7 @@ bool delayed_insert::handle_inserts(void
{ // This shouldn't happen
table->file->print_error(error,MYF(0));
sql_print_error("%s",thd.net.last_error);
+ DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
goto err;
}
query_cache_invalidate3(&thd, table, 1);
@@ -2153,13 +2196,16 @@ bool delayed_insert::handle_inserts(void
DBUG_RETURN(0);
err:
+ DBUG_EXECUTE("error", max_rows= 0;);
/* Remove all not used rows */
while ((row=rows.get()))
{
delete row;
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
stacked_inserts--;
+ DBUG_EXECUTE("error", max_rows++;);
}
+ DBUG_PRINT("error", ("dropped %lu rows after an error", max_rows));
thread_safe_increment(delayed_insert_errors, &LOCK_delayed_status);
pthread_mutex_lock(&mutex);
DBUG_RETURN(1);
--- 1.233/sql/table.cc 2006-10-02 14:52:14 +05:00
+++ 1.234/sql/table.cc 2006-10-02 14:52:14 +05:00
@@ -1592,7 +1592,7 @@ char *get_field(MEM_ROOT *mem, Field *fi
bool check_db_name(char *name)
{
- uint name_length= 0; // name length in symbols
+ char *start= name;
/* Used to catch empty names and names with end space */
bool last_char_is_space= TRUE;
@@ -1609,7 +1609,6 @@ bool check_db_name(char *name)
name+system_charset_info->mbmaxlen);
if (len)
{
- name_length++;
name += len;
continue;
}
@@ -1617,13 +1616,12 @@ bool check_db_name(char *name)
#else
last_char_is_space= *name==' ';
#endif
- name_length++;
if (*name == '/' || *name == '\\' || *name == FN_LIBCHAR ||
*name == FN_EXTCHAR)
return 1;
name++;
}
- return (last_char_is_space || name_length > NAME_LEN);
+ return last_char_is_space || (uint) (name - start) > NAME_LEN;
}
--- 1.72/sql/share/errmsg.txt 2006-10-02 14:52:14 +05:00
+++ 1.73/sql/share/errmsg.txt 2006-10-02 14:52:14 +05:00
@@ -5631,3 +5631,6 @@ ER_HOSTNAME
eng "host name"
ER_WRONG_STRING_LENGTH
eng "String '%-.70s' is too long for %s (should be no longer than %d)"
+ER_NON_INSERTABLE_TABLE
+ eng "The target table %-.100s of the %s is not insertable-into"
+
| Thread |
|---|
| • bk commit into 5.0 tree (svoj:1.2287) | Sergey Vojtovich | 2 Oct |