mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge mysql.com:/home/mydev/mysql-5.0-bug5390
into mysql.com:/home/mydev/mysql-5.1-bug5390 mysql-test/r/information_schema.result: Auto merged mysql-test/t/information_schema.test: Auto merged sql/item.cc: Auto merged sql/share/charsets/Index.xml: Auto merged sql/sql_insert.cc: Auto merged sql/table.h: Auto merged storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp: Auto merged storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: Auto merged sql/lock.cc: BUG#5390 - problems with merge tables Manual merge from 5.0.
This commit is contained in:
@ -214,34 +214,34 @@ latin1 cp1252 West European latin1_swedish_ci 1
|
||||
select * from information_schema.COLLATIONS
|
||||
where COLLATION_NAME like 'latin1%';
|
||||
COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN
|
||||
latin1_german1_ci latin1 5 0
|
||||
latin1_swedish_ci latin1 8 Yes Yes 1
|
||||
latin1_danish_ci latin1 15 0
|
||||
latin1_german2_ci latin1 31 Yes 2
|
||||
latin1_bin latin1 47 Yes 1
|
||||
latin1_general_ci latin1 48 0
|
||||
latin1_general_cs latin1 49 0
|
||||
latin1_spanish_ci latin1 94 0
|
||||
latin1_german1_ci latin1 5 # 1
|
||||
latin1_swedish_ci latin1 8 Yes # 1
|
||||
latin1_danish_ci latin1 15 # 1
|
||||
latin1_german2_ci latin1 31 # 2
|
||||
latin1_bin latin1 47 # 1
|
||||
latin1_general_ci latin1 48 # 1
|
||||
latin1_general_cs latin1 49 # 1
|
||||
latin1_spanish_ci latin1 94 # 1
|
||||
SHOW COLLATION LIKE 'latin1%';
|
||||
Collation Charset Id Default Compiled Sortlen
|
||||
latin1_german1_ci latin1 5 0
|
||||
latin1_swedish_ci latin1 8 Yes Yes 1
|
||||
latin1_danish_ci latin1 15 0
|
||||
latin1_german2_ci latin1 31 Yes 2
|
||||
latin1_bin latin1 47 Yes 1
|
||||
latin1_general_ci latin1 48 0
|
||||
latin1_general_cs latin1 49 0
|
||||
latin1_spanish_ci latin1 94 0
|
||||
latin1_german1_ci latin1 5 # 1
|
||||
latin1_swedish_ci latin1 8 Yes # 1
|
||||
latin1_danish_ci latin1 15 # 1
|
||||
latin1_german2_ci latin1 31 # 2
|
||||
latin1_bin latin1 47 # 1
|
||||
latin1_general_ci latin1 48 # 1
|
||||
latin1_general_cs latin1 49 # 1
|
||||
latin1_spanish_ci latin1 94 # 1
|
||||
SHOW COLLATION WHERE collation like 'latin1%';
|
||||
Collation Charset Id Default Compiled Sortlen
|
||||
latin1_german1_ci latin1 5 0
|
||||
latin1_swedish_ci latin1 8 Yes Yes 1
|
||||
latin1_danish_ci latin1 15 0
|
||||
latin1_german2_ci latin1 31 Yes 2
|
||||
latin1_bin latin1 47 Yes 1
|
||||
latin1_general_ci latin1 48 0
|
||||
latin1_general_cs latin1 49 0
|
||||
latin1_spanish_ci latin1 94 0
|
||||
latin1_german1_ci latin1 5 # 1
|
||||
latin1_swedish_ci latin1 8 Yes # 1
|
||||
latin1_danish_ci latin1 15 # 1
|
||||
latin1_german2_ci latin1 31 # 2
|
||||
latin1_bin latin1 47 # 1
|
||||
latin1_general_ci latin1 48 # 1
|
||||
latin1_general_cs latin1 49 # 1
|
||||
latin1_spanish_ci latin1 94 # 1
|
||||
select * from information_schema.COLLATION_CHARACTER_SET_APPLICABILITY
|
||||
where COLLATION_NAME like 'latin1%';
|
||||
COLLATION_NAME CHARACTER_SET_NAME
|
||||
|
@ -47,6 +47,17 @@ unlock tables;
|
||||
lock tables t1 write, t1 as t1_alias read;
|
||||
insert into t1 select index1,nr from t1 as t1_alias;
|
||||
drop table t1,t2;
|
||||
create table t1 (c1 int);
|
||||
create table t2 (c1 int);
|
||||
create table t3 (c1 int);
|
||||
lock tables t1 write, t2 write, t3 write;
|
||||
drop table t2, t3, t1;
|
||||
create table t1 (c1 int);
|
||||
create table t2 (c1 int);
|
||||
create table t3 (c1 int);
|
||||
lock tables t1 write, t2 write, t3 write, t1 as t4 read;
|
||||
alter table t2 add column c2 int;
|
||||
drop table t1, t2, t3;
|
||||
create table t1 ( a int(11) not null auto_increment, primary key(a));
|
||||
create table t2 ( a int(11) not null auto_increment, primary key(a));
|
||||
lock tables t1 write, t2 read;
|
||||
|
@ -97,9 +97,12 @@ SHOW CHARACTER SET WHERE charset like 'latin1%';
|
||||
# Test for information_schema.COLLATIONS &
|
||||
# SHOW COLLATION
|
||||
|
||||
--replace_column 5 #
|
||||
select * from information_schema.COLLATIONS
|
||||
where COLLATION_NAME like 'latin1%';
|
||||
--replace_column 5 #
|
||||
SHOW COLLATION LIKE 'latin1%';
|
||||
--replace_column 5 #
|
||||
SHOW COLLATION WHERE collation like 'latin1%';
|
||||
|
||||
select * from information_schema.COLLATION_CHARACTER_SET_APPLICABILITY
|
||||
|
@ -61,6 +61,24 @@ insert into t1 select index1,nr from t1 as t1_alias;
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# BUG#5390 - problems with merge tables
|
||||
# Supplement test for the after-fix optimization
|
||||
# Check that a dropped table is correctly removed from a lock.
|
||||
create table t1 (c1 int);
|
||||
create table t2 (c1 int);
|
||||
create table t3 (c1 int);
|
||||
lock tables t1 write, t2 write, t3 write;
|
||||
# This removes one table after the other from the lock.
|
||||
drop table t2, t3, t1;
|
||||
#
|
||||
# Check that a lock merge works.
|
||||
create table t1 (c1 int);
|
||||
create table t2 (c1 int);
|
||||
create table t3 (c1 int);
|
||||
lock tables t1 write, t2 write, t3 write, t1 as t4 read;
|
||||
alter table t2 add column c2 int;
|
||||
drop table t1, t2, t3;
|
||||
|
||||
# Bug7241 - Invalid response when DELETE .. USING and LOCK TABLES used.
|
||||
#
|
||||
create table t1 ( a int(11) not null auto_increment, primary key(a));
|
||||
|
312
sql/lock.cc
312
sql/lock.cc
@ -68,20 +68,20 @@ TODO:
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include <hash.h>
|
||||
#include "ha_myisammrg.h"
|
||||
#ifndef MASTER
|
||||
#include "../srclib/myisammrg/myrg_def.h"
|
||||
#else
|
||||
#include "../storage/myisammrg/myrg_def.h"
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
extern HASH open_cache;
|
||||
|
||||
/* flags for get_lock_data */
|
||||
#define GET_LOCK_UNLOCK 1
|
||||
#define GET_LOCK_STORE_LOCKS 2
|
||||
|
||||
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
|
||||
bool unlock, TABLE **write_locked);
|
||||
uint flags, TABLE **write_locked);
|
||||
static int lock_external(THD *thd, TABLE **table,uint count);
|
||||
static int unlock_external(THD *thd, TABLE **table,uint count);
|
||||
static void print_lock_error(int error, const char *);
|
||||
|
||||
|
||||
/*
|
||||
Lock tables.
|
||||
|
||||
@ -122,7 +122,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!(sql_lock = get_lock_data(thd,tables,count, 0,&write_lock_used)))
|
||||
if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
|
||||
&write_lock_used)))
|
||||
break;
|
||||
|
||||
if (global_read_lock && write_lock_used &&
|
||||
@ -156,7 +157,12 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
|
||||
thd->proc_info="Table lock";
|
||||
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
|
||||
thd->locked=1;
|
||||
rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks,
|
||||
/* Copy the lock data array. thr_multi_lock() reorders its contens. */
|
||||
memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
|
||||
sql_lock->lock_count * sizeof(*sql_lock->locks));
|
||||
/* Lock on the copied half of the lock data array. */
|
||||
rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
|
||||
sql_lock->lock_count,
|
||||
sql_lock->lock_count,
|
||||
thd->lock_id)];
|
||||
if (rc > 1) /* a timeout or a deadlock */
|
||||
@ -269,7 +275,8 @@ void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
|
||||
{
|
||||
MYSQL_LOCK *sql_lock;
|
||||
TABLE *write_lock_used;
|
||||
if ((sql_lock = get_lock_data(thd, table, count, 1, &write_lock_used)))
|
||||
if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK,
|
||||
&write_lock_used)))
|
||||
mysql_unlock_tables(thd, sql_lock);
|
||||
}
|
||||
|
||||
@ -306,6 +313,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
||||
TABLE **table=sql_lock->table;
|
||||
for (i=found=0 ; i < sql_lock->table_count ; i++)
|
||||
{
|
||||
DBUG_ASSERT(sql_lock->table[i]->lock_position == i);
|
||||
if ((uint) sql_lock->table[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ)
|
||||
{
|
||||
swap_variables(TABLE *, *table, sql_lock->table[i]);
|
||||
@ -319,6 +327,17 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
||||
VOID(unlock_external(thd,table,i-found));
|
||||
sql_lock->table_count=found;
|
||||
}
|
||||
/* Fix the lock positions in TABLE */
|
||||
table= sql_lock->table;
|
||||
found= 0;
|
||||
for (i= 0; i < sql_lock->table_count; i++)
|
||||
{
|
||||
TABLE *tbl= *table;
|
||||
tbl->lock_position= table - sql_lock->table;
|
||||
tbl->lock_data_start= found;
|
||||
found+= tbl->lock_count;
|
||||
table++;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -334,20 +353,51 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table)
|
||||
{
|
||||
if (locked->table[i] == table)
|
||||
{
|
||||
locked->table_count--;
|
||||
uint j, removed_locks, old_tables;
|
||||
TABLE *tbl;
|
||||
uint lock_data_end;
|
||||
|
||||
DBUG_ASSERT(table->lock_position == i);
|
||||
|
||||
/* Decrement table_count in advance, making below expressions easier */
|
||||
old_tables= --locked->table_count;
|
||||
|
||||
/* The table has 'removed_locks' lock data elements in locked->locks */
|
||||
removed_locks= table->lock_count;
|
||||
|
||||
/* Move down all table pointers above 'i'. */
|
||||
bmove((char*) (locked->table+i),
|
||||
(char*) (locked->table+i+1),
|
||||
(locked->table_count-i)* sizeof(TABLE*));
|
||||
(old_tables - i) * sizeof(TABLE*));
|
||||
|
||||
lock_data_end= table->lock_data_start + table->lock_count;
|
||||
/* Move down all lock data pointers above 'table->lock_data_end-1' */
|
||||
bmove((char*) (locked->locks + table->lock_data_start),
|
||||
(char*) (locked->locks + lock_data_end),
|
||||
(locked->lock_count - lock_data_end) *
|
||||
sizeof(THR_LOCK_DATA*));
|
||||
|
||||
/*
|
||||
Fix moved table elements.
|
||||
lock_position is the index in the 'locked->table' array,
|
||||
it must be fixed by one.
|
||||
table->lock_data_start is pointer to the lock data for this table
|
||||
in the 'locked->locks' array, they must be fixed by 'removed_locks',
|
||||
the lock data count of the removed table.
|
||||
*/
|
||||
for (j= i ; j < old_tables; j++)
|
||||
{
|
||||
tbl= locked->table[j];
|
||||
tbl->lock_position--;
|
||||
DBUG_ASSERT(tbl->lock_position == j);
|
||||
tbl->lock_data_start-= removed_locks;
|
||||
}
|
||||
|
||||
/* Finally adjust lock_count. */
|
||||
locked->lock_count-= removed_locks;
|
||||
break;
|
||||
}
|
||||
}
|
||||
THR_LOCK_DATA **prev=locked->locks;
|
||||
for (i=0 ; i < locked->lock_count ; i++)
|
||||
{
|
||||
if (locked->locks[i]->type != TL_UNLOCK)
|
||||
*prev++ = locked->locks[i];
|
||||
}
|
||||
locked->lock_count=(uint) (prev - locked->locks);
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,7 +425,8 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
|
||||
TABLE *write_lock_used;
|
||||
DBUG_ENTER("mysql_lock_abort");
|
||||
|
||||
if ((locked = get_lock_data(thd,&table,1,1,&write_lock_used)))
|
||||
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
|
||||
&write_lock_used)))
|
||||
{
|
||||
for (uint i=0; i < locked->lock_count; i++)
|
||||
thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
|
||||
@ -405,7 +456,8 @@ bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
|
||||
bool result= FALSE;
|
||||
DBUG_ENTER("mysql_lock_abort_for_thread");
|
||||
|
||||
if ((locked = get_lock_data(thd,&table,1,1,&write_lock_used)))
|
||||
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
|
||||
&write_lock_used)))
|
||||
{
|
||||
for (uint i=0; i < locked->lock_count; i++)
|
||||
{
|
||||
@ -422,7 +474,9 @@ bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
|
||||
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
|
||||
{
|
||||
MYSQL_LOCK *sql_lock;
|
||||
TABLE **table, **end_table;
|
||||
DBUG_ENTER("mysql_lock_merge");
|
||||
|
||||
if (!(sql_lock= (MYSQL_LOCK*)
|
||||
my_malloc(sizeof(*sql_lock)+
|
||||
sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
|
||||
@ -438,6 +492,21 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
|
||||
memcpy(sql_lock->table,a->table,a->table_count*sizeof(*a->table));
|
||||
memcpy(sql_lock->table+a->table_count,b->table,
|
||||
b->table_count*sizeof(*b->table));
|
||||
|
||||
/*
|
||||
Now adjust lock_position and lock_data_start for all objects that was
|
||||
moved in 'b' (as there is now all objects in 'a' before these).
|
||||
*/
|
||||
for (table= sql_lock->table + a->table_count,
|
||||
end_table= table + b->table_count;
|
||||
table < end_table;
|
||||
table++)
|
||||
{
|
||||
(*table)->lock_position+= a->table_count;
|
||||
(*table)->lock_data_start+= a->lock_count;
|
||||
}
|
||||
|
||||
/* Delete old, not needed locks */
|
||||
my_free((gptr) a,MYF(0));
|
||||
my_free((gptr) b,MYF(0));
|
||||
DBUG_RETURN(sql_lock);
|
||||
@ -456,112 +525,96 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
|
||||
NOTE
|
||||
This is mainly meant for MERGE tables in INSERT ... SELECT
|
||||
situations. The 'real', underlying tables can be found only after
|
||||
the table is opened. The easier way is to check this after the
|
||||
tables are locked.
|
||||
the MERGE tables are opened. This function assumes that the tables are
|
||||
already locked.
|
||||
|
||||
Temporary tables are ignored here like they are ignored in
|
||||
get_lock_data(). If we allow two opens on temporary tables later,
|
||||
both functions should be checked.
|
||||
|
||||
RETURN
|
||||
1 A table from 'tables' matches a lock on 'table'.
|
||||
0 No duplicate lock is present.
|
||||
-1 Error.
|
||||
NULL No duplicate lock found.
|
||||
! NULL First table from 'haystack' that matches a lock on 'needle'.
|
||||
*/
|
||||
|
||||
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
||||
TABLE_LIST *haystack)
|
||||
{
|
||||
uint count;
|
||||
uint dup_pos;
|
||||
TABLE *write_lock_used; /* dummy */
|
||||
TABLE **tables1;
|
||||
TABLE **tables2;
|
||||
TABLE **table_ptr;
|
||||
TABLE_LIST *tlist_ptr;
|
||||
MYSQL_LOCK *sql_lock1;
|
||||
MYSQL_LOCK *sql_lock2;
|
||||
THR_LOCK_DATA **lock_data1;
|
||||
THR_LOCK_DATA **end_data1;
|
||||
MYSQL_LOCK *mylock;
|
||||
TABLE **lock_tables;
|
||||
TABLE *table;
|
||||
TABLE *table2;
|
||||
THR_LOCK_DATA **lock_locks;
|
||||
THR_LOCK_DATA **table_lock_data;
|
||||
THR_LOCK_DATA **end_data;
|
||||
THR_LOCK_DATA **lock_data2;
|
||||
THR_LOCK_DATA **end_data2;
|
||||
THR_LOCK *lock1;
|
||||
DBUG_ENTER("mysql_lock_have_duplicate");
|
||||
|
||||
/* Table may not be defined for derived or view tables. */
|
||||
if (! needle->table)
|
||||
DBUG_RETURN(NULL);
|
||||
|
||||
/* Get lock(s) for needle. */
|
||||
tables1= &needle->table;
|
||||
if (! (sql_lock1= get_lock_data(thd, tables1, 1, 1, &write_lock_used)))
|
||||
goto err0;
|
||||
|
||||
/* Count real tables in list. */
|
||||
count=0;
|
||||
for (tlist_ptr = haystack; tlist_ptr; tlist_ptr= tlist_ptr->next_global)
|
||||
if (! tlist_ptr->placeholder() && ! tlist_ptr->schema_table)
|
||||
count++;
|
||||
/* Allocate a table array. */
|
||||
if (! (tables2= (TABLE**) sql_alloc(sizeof(TABLE*) * count)))
|
||||
goto err1;
|
||||
table_ptr= tables2;
|
||||
/* Assign table pointers. */
|
||||
for (tlist_ptr = haystack; tlist_ptr; tlist_ptr= tlist_ptr->next_global)
|
||||
if (! tlist_ptr->placeholder() && ! tlist_ptr->schema_table)
|
||||
*(table_ptr++)= tlist_ptr->table;
|
||||
/* Get lock(s) for haystack. */
|
||||
if (! (sql_lock2= get_lock_data(thd, tables2, count, 1, &write_lock_used)))
|
||||
goto err1;
|
||||
|
||||
/* Initialize duplicate position to an impossible value. */
|
||||
dup_pos= UINT_MAX;
|
||||
/*
|
||||
Find a duplicate lock.
|
||||
In case of merge tables, sql_lock1 can have more than 1 lock.
|
||||
Table may not be defined for derived or view tables.
|
||||
Table may not be part of a lock for delayed operations.
|
||||
*/
|
||||
for (lock_data1= sql_lock1->locks,
|
||||
end_data1= lock_data1 + sql_lock1->lock_count;
|
||||
lock_data1 < end_data1;
|
||||
lock_data1++)
|
||||
if (! (table= needle->table) || ! table->lock_count)
|
||||
goto end;
|
||||
|
||||
/* A temporary table does not have locks. */
|
||||
if (table->s->tmp_table == TMP_TABLE)
|
||||
goto end;
|
||||
|
||||
/* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
|
||||
if (! (mylock= thd->lock ? thd->lock : thd->locked_tables))
|
||||
goto end;
|
||||
|
||||
/* If we have less than two tables, we cannot have duplicates. */
|
||||
if (mylock->table_count < 2)
|
||||
goto end;
|
||||
|
||||
lock_locks= mylock->locks;
|
||||
lock_tables= mylock->table;
|
||||
|
||||
/* Prepare table related variables that don't change in loop. */
|
||||
DBUG_ASSERT((table->lock_position < mylock->table_count) &&
|
||||
(table == lock_tables[table->lock_position]));
|
||||
table_lock_data= lock_locks + table->lock_data_start;
|
||||
end_data= table_lock_data + table->lock_count;
|
||||
|
||||
for (; haystack; haystack= haystack->next_global)
|
||||
{
|
||||
lock1= (*lock_data1)->lock;
|
||||
for (lock_data2= sql_lock2->locks,
|
||||
end_data2= lock_data2 + sql_lock2->lock_count;
|
||||
if (haystack->placeholder() || haystack->schema_table)
|
||||
continue;
|
||||
table2= haystack->table;
|
||||
if (table2->s->tmp_table == TMP_TABLE)
|
||||
continue;
|
||||
|
||||
/* All tables in list must be in lock. */
|
||||
DBUG_ASSERT((table2->lock_position < mylock->table_count) &&
|
||||
(table2 == lock_tables[table2->lock_position]));
|
||||
|
||||
for (lock_data2= lock_locks + table2->lock_data_start,
|
||||
end_data2= lock_data2 + table2->lock_count;
|
||||
lock_data2 < end_data2;
|
||||
lock_data2++)
|
||||
{
|
||||
if ((*lock_data2)->lock == lock1)
|
||||
THR_LOCK_DATA **lock_data;
|
||||
THR_LOCK *lock2= (*lock_data2)->lock;
|
||||
|
||||
for (lock_data= table_lock_data;
|
||||
lock_data < end_data;
|
||||
lock_data++)
|
||||
{
|
||||
DBUG_PRINT("ingo", ("duplicate lock found"));
|
||||
/* Change duplicate position to the real value. */
|
||||
dup_pos= lock_data2 - sql_lock2->locks;
|
||||
goto end;
|
||||
if ((*lock_data)->lock == lock2)
|
||||
{
|
||||
DBUG_PRINT("info", ("haystack match: '%s'", haystack->table_name));
|
||||
DBUG_RETURN(haystack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
tlist_ptr= NULL; /* In case that no duplicate was found. */
|
||||
if (dup_pos != UINT_MAX)
|
||||
{
|
||||
/* Duplicate found. Search the matching TABLE_LIST object. */
|
||||
count= 0;
|
||||
for (tlist_ptr = haystack; tlist_ptr; tlist_ptr= tlist_ptr->next_global)
|
||||
{
|
||||
if (! tlist_ptr->placeholder() && ! tlist_ptr->schema_table)
|
||||
{
|
||||
count+= tlist_ptr->table->file->lock_count();
|
||||
if (count > dup_pos)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
my_free((gptr) sql_lock2, MYF(0));
|
||||
my_free((gptr) sql_lock1, MYF(0));
|
||||
DBUG_RETURN(tlist_ptr);
|
||||
|
||||
err1:
|
||||
my_free((gptr) sql_lock1, MYF(0));
|
||||
err0:
|
||||
/* This non-null but special value indicates error, if caller cares. */
|
||||
DBUG_RETURN(needle);
|
||||
DBUG_PRINT("info", ("no duplicate found"));
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -591,17 +644,27 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
|
||||
|
||||
|
||||
/*
|
||||
** Get lock structures from table structs and initialize locks
|
||||
Get lock structures from table structs and initialize locks
|
||||
|
||||
SYNOPSIS
|
||||
get_lock_data()
|
||||
thd Thread handler
|
||||
table_ptr Pointer to tables that should be locks
|
||||
flags One of:
|
||||
GET_LOCK_UNLOCK: If we should send TL_IGNORE to
|
||||
store lock
|
||||
GET_LOCK_STORE_LOCKS: Store lock info in TABLE
|
||||
write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
|
||||
*/
|
||||
|
||||
|
||||
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||
bool get_old_locks, TABLE **write_lock_used)
|
||||
uint flags, TABLE **write_lock_used)
|
||||
{
|
||||
uint i,tables,lock_count;
|
||||
MYSQL_LOCK *sql_lock;
|
||||
THR_LOCK_DATA **locks;
|
||||
TABLE **to;
|
||||
THR_LOCK_DATA **locks, **locks_buf, **locks_start;
|
||||
TABLE **to, **table_buf;
|
||||
DBUG_ENTER("get_lock_data");
|
||||
|
||||
DBUG_PRINT("info", ("count %d", count));
|
||||
@ -625,13 +688,20 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
Allocating twice the number of pointers for lock data for use in
|
||||
thr_mulit_lock(). This function reorders the lock data, but cannot
|
||||
update the table values. So the second part of the array is copied
|
||||
from the first part immediately before calling thr_multi_lock().
|
||||
*/
|
||||
if (!(sql_lock= (MYSQL_LOCK*)
|
||||
my_malloc(sizeof(*sql_lock)+
|
||||
sizeof(THR_LOCK_DATA*)*tables+sizeof(table_ptr)*lock_count,
|
||||
my_malloc(sizeof(*sql_lock) +
|
||||
sizeof(THR_LOCK_DATA*) * tables * 2 +
|
||||
sizeof(table_ptr) * lock_count,
|
||||
MYF(0))))
|
||||
DBUG_RETURN(0);
|
||||
locks=sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
|
||||
to=sql_lock->table=(TABLE**) (locks+tables);
|
||||
locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
|
||||
to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2);
|
||||
sql_lock->table_count=lock_count;
|
||||
sql_lock->lock_count=tables;
|
||||
DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d",
|
||||
@ -640,10 +710,11 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||
for (i=0 ; i < count ; i++)
|
||||
{
|
||||
TABLE *table;
|
||||
enum thr_lock_type lock_type;
|
||||
|
||||
if ((table=table_ptr[i])->s->tmp_table == TMP_TABLE)
|
||||
continue;
|
||||
*to++=table;
|
||||
enum thr_lock_type lock_type= table->reginfo.lock_type;
|
||||
lock_type= table->reginfo.lock_type;
|
||||
if (lock_type >= TL_WRITE_ALLOW_WRITE)
|
||||
{
|
||||
*write_lock_used=table;
|
||||
@ -655,8 +726,17 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||
}
|
||||
}
|
||||
THR_LOCK_DATA **org_locks = locks;
|
||||
locks=table->file->store_lock(thd, locks, get_old_locks ? TL_IGNORE :
|
||||
locks_start= locks;
|
||||
locks= table->file->store_lock(thd, locks,
|
||||
(flags & GET_LOCK_UNLOCK) ? TL_IGNORE :
|
||||
lock_type);
|
||||
if (flags & GET_LOCK_STORE_LOCKS)
|
||||
{
|
||||
table->lock_position= (uint) (to - table_buf);
|
||||
table->lock_data_start= (uint) (locks_start - locks_buf);
|
||||
table->lock_count= (uint) (locks - locks_start);
|
||||
}
|
||||
*to++= table;
|
||||
if (locks)
|
||||
for ( ; org_locks != locks ; org_locks++)
|
||||
(*org_locks)->debug_print_param= (void *) table;
|
||||
|
@ -115,7 +115,10 @@ To make maintaining easier please:
|
||||
<alias>l1</alias>
|
||||
<alias>latin1</alias>
|
||||
<collation name="latin1_german1_ci" id="5" order="German Duden"/>
|
||||
<collation name="latin1_swedish_ci" id="8" order="Finnish, Swedish" flag="primary"/>
|
||||
<collation name="latin1_swedish_ci" id="8" order="Finnish, Swedish">
|
||||
<flag>primary</flag>
|
||||
<flag>compiled</flag>
|
||||
</collation>
|
||||
<collation name="latin1_danish_ci" id="15" order="Danish"/>
|
||||
<collation name="latin1_german2_ci" id="31" order="German Phonebook" flag="compiled"/>
|
||||
<collation name="latin1_spanish_ci" id="94" order="Spanish"/>
|
||||
|
@ -33,14 +33,14 @@
|
||||
01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10
|
||||
10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02
|
||||
02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20
|
||||
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
|
||||
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00
|
||||
00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01
|
||||
48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
|
||||
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
|
||||
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
|
||||
01 01 01 01 01 01 01 00 01 01 01 01 01 01 01 02
|
||||
01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02
|
||||
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
|
||||
02 02 02 02 02 02 02 00 02 02 02 02 02 02 02 02
|
||||
02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02
|
||||
</map>
|
||||
</ctype>
|
||||
|
||||
@ -99,8 +99,8 @@
|
||||
0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F
|
||||
0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F
|
||||
0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F
|
||||
0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 008A 008B 008C 008D 008E 008F
|
||||
0090 0091 0092 0093 0094 0095 0096 0097 0098 0099 009A 009B 009C 009D 009E 009F
|
||||
20AC 0081 201A 0192 201E 2026 2020 2021 02C6 2030 0160 2039 0152 008D 017D 008F
|
||||
0090 2018 2019 201C 201D 2022 2013 2014 02DC 2122 0161 203A 0153 009D 017E 0178
|
||||
00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF
|
||||
00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF
|
||||
00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF
|
||||
|
@ -1572,6 +1572,9 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
|
||||
/* Adjust in_use for pointing to client thread */
|
||||
copy->in_use= client_thd;
|
||||
|
||||
/* Adjust lock_count. This table object is not part of a lock. */
|
||||
copy->lock_count= 0;
|
||||
|
||||
return copy;
|
||||
|
||||
/* Got fatal error */
|
||||
|
@ -278,6 +278,9 @@ struct st_table {
|
||||
timestamp_auto_set_type timestamp_field_type;
|
||||
table_map map; /* ID bit of table (1,2,4,8,16...) */
|
||||
|
||||
uint lock_position; /* Position in MYSQL_LOCK.table */
|
||||
uint lock_data_start; /* Start pos. in MYSQL_LOCK.locks */
|
||||
uint lock_count; /* Number of locks */
|
||||
uint tablenr,used_fields;
|
||||
uint temp_pool_slot; /* Used by intern temp tables */
|
||||
uint status; /* What's in record[0] */
|
||||
|
@ -221,13 +221,17 @@ void dispcset(FILE *f,CHARSET_INFO *cs)
|
||||
}
|
||||
|
||||
fprintf(f," NULL, /* from_uni */\n");
|
||||
fprintf(f," my_unicase_default, /* caseinfo */\n");
|
||||
fprintf(f," NULL, /* state map */\n");
|
||||
fprintf(f," NULL, /* ident map */\n");
|
||||
fprintf(f," 1, /* strxfrm_multiply*/\n");
|
||||
fprintf(f," 1, /* caseup_multiply*/\n");
|
||||
fprintf(f," 1, /* casedn_multiply*/\n");
|
||||
fprintf(f," 1, /* mbminlen */\n");
|
||||
fprintf(f," 1, /* mbmaxlen */\n");
|
||||
fprintf(f," 0, /* min_sort_char */\n");
|
||||
fprintf(f," 255, /* max_sort_char */\n");
|
||||
fprintf(f," ' ', /* pad_char */\n");
|
||||
fprintf(f," 0, /* escape_with_backslash_is_dangerous */\n");
|
||||
|
||||
fprintf(f," &my_charset_8bit_handler,\n");
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user