Commit 94169d93 authored by lars@mysql.com's avatar lars@mysql.com

Merge mysql.com:/users/lthalmann/bkroot/mysql-5.0

into  mysql.com:/users/lthalmann/bk/mysql-5.0
parents bdf57377 57f36732
......@@ -31,8 +31,8 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
HA_KEYSEG *last_used_keyseg;
uint pack_key_length, use_key_length, nextflag;
DBUG_ENTER("mi_rkey");
DBUG_PRINT("enter", ("base: %p buf: %p inx: %d search_flag: %d",
info, buf, inx, search_flag));
DBUG_PRINT("enter", ("base: %lx buf: %lx inx: %d search_flag: %d",
(long) info, (long) buf, inx, search_flag));
if ((inx = _mi_check_index(info,inx)) < 0)
DBUG_RETURN(my_errno);
......
......@@ -259,15 +259,16 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
{
mi_print_error(info->s, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_PRINT("error",("Found wrong key: length: %u page: %p end: %p",
length, page, end));
DBUG_PRINT("error",("Found wrong key: length: %u page: %lx end: %lx",
length, (long) page, (long) end));
DBUG_RETURN(MI_FOUND_WRONG_KEY);
}
if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
&not_used)) >= 0)
break;
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("page: %p key: '%s' flag: %d", page, t_buff, flag));
DBUG_PRINT("loop",("page: %lx key: '%s' flag: %d", (long) page, t_buff,
flag));
#endif
memcpy(buff,t_buff,length);
*ret_pos=page;
......@@ -275,7 +276,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
if (flag == 0)
memcpy(buff,t_buff,length); /* Result is first key */
*last_key= page == end;
DBUG_PRINT("exit",("flag: %d ret_pos: %p", flag, *ret_pos));
DBUG_PRINT("exit",("flag: %d ret_pos: %lx", flag, (long) *ret_pos));
DBUG_RETURN(flag);
} /* _mi_seq_search */
......@@ -415,8 +416,8 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
{
mi_print_error(info->s, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_PRINT("error",("Found wrong key: length: %u page: %p end: %p",
length, page, end));
DBUG_PRINT("error",("Found wrong key: length: %u page: %lx end: %lx",
length, (long) page, (long) end));
DBUG_RETURN(MI_FOUND_WRONG_KEY);
}
......@@ -550,7 +551,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
*last_key= page == end;
DBUG_PRINT("exit",("flag: %d ret_pos: %p", flag, *ret_pos));
DBUG_PRINT("exit",("flag: %d ret_pos: %lx", flag, (long) *ret_pos));
DBUG_RETURN(flag);
} /* _mi_prefix_search */
......@@ -812,8 +813,8 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
if (length > keyseg->length)
{
DBUG_PRINT("error",
("Found too long null packed key: %u of %u at %p",
length, keyseg->length, *page_pos));
("Found too long null packed key: %u of %u at %lx",
length, keyseg->length, (long) *page_pos));
DBUG_DUMP("key",(char*) *page_pos,16);
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
......@@ -869,8 +870,8 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
}
if (length > (uint) keyseg->length)
{
DBUG_PRINT("error",("Found too long packed key: %u of %u at %p",
length, keyseg->length, *page_pos));
DBUG_PRINT("error",("Found too long packed key: %u of %u at %lx",
length, keyseg->length, (long) *page_pos));
DBUG_DUMP("key",(char*) *page_pos,16);
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
......@@ -935,8 +936,8 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
{
if (length > keyinfo->maxlength)
{
DBUG_PRINT("error",("Found too long binary packed key: %u of %u at %p",
length, keyinfo->maxlength, *page_pos));
DBUG_PRINT("error",("Found too long binary packed key: %u of %u at %lx",
length, keyinfo->maxlength, (long) *page_pos));
DBUG_DUMP("key",(char*) *page_pos,16);
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
......@@ -983,8 +984,8 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
length-=tmp;
from=page; from_end=page_end;
}
DBUG_PRINT("info",("key: %p from: %p length: %u",
key, from, length));
DBUG_PRINT("info",("key: %lx from: %lx length: %u",
(long) key, (long) from, length));
memcpy_overlap((byte*) key, (byte*) from, (size_t) length);
key+=length;
from+=length;
......@@ -1041,7 +1042,8 @@ uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
}
}
}
DBUG_PRINT("exit",("page: %p length: %u", page, *return_key_length));
DBUG_PRINT("exit",("page: %lx length: %u", (long) page,
*return_key_length));
DBUG_RETURN(page);
} /* _mi_get_key */
......@@ -1093,7 +1095,7 @@ uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
uint nod_flag;
uchar *lastpos;
DBUG_ENTER("_mi_get_last_key");
DBUG_PRINT("enter",("page: %p endpos: %p", page, endpos));
DBUG_PRINT("enter",("page: %lx endpos: %lx", (long) page, (long) endpos));
nod_flag=mi_test_if_nod(page);
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
......@@ -1113,14 +1115,16 @@ uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
*return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,lastkey);
if (*return_key_length == 0)
{
DBUG_PRINT("error",("Couldn't find last key: page: %p", page));
DBUG_PRINT("error",("Couldn't find last key: page: %lx",
(long) page));
mi_print_error(info->s, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0);
}
}
}
DBUG_PRINT("exit",("lastpos: %p length: %u", lastpos, *return_key_length));
DBUG_PRINT("exit",("lastpos: %lx length: %u", (long) lastpos,
*return_key_length));
DBUG_RETURN(lastpos);
} /* _mi_get_last_key */
......@@ -1659,7 +1663,8 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
ref_length=0;
next_length_pack=0;
}
DBUG_PRINT("test",("length: %d next_key: %p", length, next_key));
DBUG_PRINT("test",("length: %d next_key: %lx", length,
(long) next_key));
{
uint tmp_length;
......
......@@ -122,3 +122,75 @@ SELECT * FROM t1;
i j x y z
1 2 23 24 71
DROP TABLE t1, t2, t3;
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
DROP TABLE IF EXISTS t2;
Warnings:
Note 1051 Unknown table 't2'
CREATE TABLE t1 (
idp int(11) NOT NULL default '0',
idpro int(11) default NULL,
price decimal(19,4) default NULL,
PRIMARY KEY (idp)
);
CREATE TABLE t2 (
idpro int(11) NOT NULL default '0',
price decimal(19,4) default NULL,
nbprice int(11) default NULL,
PRIMARY KEY (idpro)
);
INSERT INTO t1 VALUES
(1,1,'3.0000'),
(2,2,'1.0000'),
(3,1,'1.0000'),
(4,1,'4.0000'),
(5,3,'2.0000'),
(6,2,'4.0000');
INSERT INTO t2 VALUES
(1,'0.0000',0),
(2,'0.0000',0),
(3,'0.0000',0);
update
t2
join
( select idpro, min(price) as min_price, count(*) as nbr_price
from t1
where idpro>0 and price>0
group by idpro
) as table_price
on t2.idpro = table_price.idpro
set t2.price = table_price.min_price,
t2.nbprice = table_price.nbr_price;
select "-- MASTER AFTER JOIN --" as "";
-- MASTER AFTER JOIN --
select * from t1;
idp idpro price
1 1 3.0000
2 2 1.0000
3 1 1.0000
4 1 4.0000
5 3 2.0000
6 2 4.0000
select * from t2;
idpro price nbprice
1 1.0000 3
2 1.0000 2
3 2.0000 1
select "-- SLAVE AFTER JOIN --" as "";
-- SLAVE AFTER JOIN --
select * from t1;
idp idpro price
1 1 3.0000
2 2 1.0000
3 1 1.0000
4 1 4.0000
5 3 2.0000
6 2 4.0000
select * from t2;
idpro price nbprice
1 1.0000 3
2 1.0000 2
3 2.0000 1
......@@ -14,6 +14,7 @@ DOCID VARCHAR(32)BINARY NOT NULL
, PRIMARY KEY ( DOCID )
) ENGINE=InnoDB
;
INSERT INTO t1 (DOCID) VALUES ("1"), ("2");
CREATE TABLE t2
(
DOCID VARCHAR(32)BINARY NOT NULL
......
......@@ -158,4 +158,63 @@ SELECT * FROM t1;
connection master;
DROP TABLE t1, t2, t3;
##############################################################################
#
# BUG#12618
#
# TEST: Replication of a statement containing a join in a multi-update.
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 (
idp int(11) NOT NULL default '0',
idpro int(11) default NULL,
price decimal(19,4) default NULL,
PRIMARY KEY (idp)
);
CREATE TABLE t2 (
idpro int(11) NOT NULL default '0',
price decimal(19,4) default NULL,
nbprice int(11) default NULL,
PRIMARY KEY (idpro)
);
INSERT INTO t1 VALUES
(1,1,'3.0000'),
(2,2,'1.0000'),
(3,1,'1.0000'),
(4,1,'4.0000'),
(5,3,'2.0000'),
(6,2,'4.0000');
INSERT INTO t2 VALUES
(1,'0.0000',0),
(2,'0.0000',0),
(3,'0.0000',0);
# This update sets t2 to the minimal prices for each product
update
t2
join
( select idpro, min(price) as min_price, count(*) as nbr_price
from t1
where idpro>0 and price>0
group by idpro
) as table_price
on t2.idpro = table_price.idpro
set t2.price = table_price.min_price,
t2.nbprice = table_price.nbr_price;
select "-- MASTER AFTER JOIN --" as "";
select * from t1;
select * from t2;
sync_slave_with_master;
select "-- SLAVE AFTER JOIN --" as "";
select * from t1;
select * from t2;
# End of 4.1 tests
......@@ -2189,6 +2189,10 @@ create table t2(f3 int);
select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,1));
select f1 from t1,t2 where f1=f2 and (f1,NULL) = ((1,1));
select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,NULL));
insert into t1 values(1,1),(2,null);
insert into t2 values(2);
select * from t1,t2 where f1=f3 and (f1,f2) = (2,null);
select * from t1,t2 where f1=f3 and (f1,f2) <=> (2,null);
drop table t1,t2;
# End of 4.1 tests
......
......@@ -25,6 +25,8 @@ DOCID VARCHAR(32)BINARY NOT NULL
) ENGINE=InnoDB
;
INSERT INTO t1 (DOCID) VALUES ("1"), ("2");
CREATE TABLE t2
(
DOCID VARCHAR(32)BINARY NOT NULL
......
......@@ -565,8 +565,12 @@ InitConfigFileParser::storeSection(Context& ctx){
}
}
}
if(ctx.type == InitConfigFileParser::DefaultSection)
require(ctx.m_defaults->put(ctx.pname, ctx.m_currentSection));
if(ctx.type == InitConfigFileParser::DefaultSection &&
!ctx.m_defaults->put(ctx.pname, ctx.m_currentSection))
{
ctx.reportError("Duplicate default section not allowed");
return false;
}
if(ctx.type == InitConfigFileParser::Section)
require(ctx.m_config->put(ctx.pname, ctx.m_currentSection));
delete ctx.m_currentSection; ctx.m_currentSection = NULL;
......
......@@ -226,6 +226,7 @@ copyfileto $BASE/mysql-test \
$CP mysql-test/lib/*.pl $BASE/mysql-test/lib
$CP mysql-test/lib/*.sql $BASE/mysql-test/lib
$CP mysql-test/t/*.def $BASE/mysql-test/t
$CP mysql-test/include/*.inc $BASE/mysql-test/include
$CP mysql-test/t/*.def $BASE/mysql-test/t
$CP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \
......
......@@ -5236,32 +5236,21 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
}
case ROW_RESULT:
{
Item_row *item_row= (Item_row*) item;
Item_row *comp_item_row= (Item_row*) comp_item;
uint col;
new_item= 0;
/*
If item and comp_item are both Item_rows and have same number of cols
then process items in Item_row one by one. If Item_row contain nulls
substitute it by Item_null. Otherwise just return.
then process items in Item_row one by one.
We can't ignore NULL values here as this item may be used with <=>, in
which case NULL's are significant.
*/
if (item->result_type() == comp_item->result_type() &&
((Item_row*)item)->cols() == ((Item_row*)comp_item)->cols())
{
Item_row *item_row= (Item_row*)item,*comp_item_row= (Item_row*)comp_item;
if (item_row->null_inside())
new_item= (Item*) new Item_null(name);
else
{
int i= item_row->cols() - 1;
for (; i >= 0; i--)
{
if (item_row->maybe_null && item_row->el(i)->is_null())
{
new_item= (Item*) new Item_null(name);
break;
}
resolve_const_item(thd, item_row->addr(i), comp_item_row->el(i));
}
}
}
DBUG_ASSERT(item->result_type() == comp_item->result_type());
DBUG_ASSERT(item_row->cols() == comp_item_row->cols());
col= item_row->cols();
while (col-- > 0)
resolve_const_item(thd, item_row->addr(col), comp_item_row->el(col));
break;
}
case REAL_RESULT:
......
......@@ -2317,8 +2317,6 @@ mysql_execute_command(THD *thd)
LEX *lex= thd->lex;
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
SELECT_LEX *select_lex= &lex->select_lex;
bool slave_fake_lock= 0;
MYSQL_LOCK *fake_prev_lock= 0;
/* first table of first SELECT_LEX */
TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first;
/* list of all tables in query */
......@@ -2367,34 +2365,21 @@ mysql_execute_command(THD *thd)
#ifdef HAVE_REPLICATION
if (thd->slave_thread)
{
if (lex->sql_command == SQLCOM_UPDATE_MULTI)
{
DBUG_PRINT("info",("need faked locked tables"));
if (check_multi_update_lock(thd))
goto error;
/* Fix for replication, the tables are opened and locked,
now we pretend that we have performed a LOCK TABLES action */
fake_prev_lock= thd->locked_tables;
if (thd->lock)
thd->locked_tables= thd->lock;
thd->lock= 0;
slave_fake_lock= 1;
}
/*
Skip if we are in the slave thread, some table rules have been
given and the table list says the query should not be replicated.
Check if statment should be skipped because of slave filtering
rules
Exceptions are:
- UPDATE MULTI: For this statement, we want to check the filtering
rules later in the code
- SET: we always execute it (Not that many SET commands exists in
the binary log anyway -- only 4.1 masters write SET statements,
in 5.0 there are no SET statements in the binary log)
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
have stale files on slave caused by exclusion of one tmp table).
*/
if (!(lex->sql_command == SQLCOM_SET_OPTION) &&
if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
!(lex->sql_command == SQLCOM_SET_OPTION) &&
!(lex->sql_command == SQLCOM_DROP_TABLE &&
lex->drop_temporary && lex->drop_if_exists) &&
all_tables_not_ok(thd, all_tables))
......@@ -3220,6 +3205,17 @@ end_with_restore_list:
else
res= 0;
if ((res= mysql_multi_update_prepare(thd)))
break;
/* Check slave filtering rules */
if (thd->slave_thread && all_tables_not_ok(thd,tables))
{
/* we warn the slave SQL thread */
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
break;
}
res= mysql_multi_update(thd, all_tables,
&select_lex->item_list,
&lex->value_list,
......@@ -4774,14 +4770,6 @@ error:
res= 1;
cleanup:
if (unlikely(slave_fake_lock))
{
DBUG_PRINT("info",("undoing faked lock"));
thd->lock= thd->locked_tables;
thd->locked_tables= fake_prev_lock;
if (thd->lock == thd->locked_tables)
thd->lock= 0;
}
DBUG_RETURN(res || thd->net.report_error);
}
......@@ -6914,57 +6902,6 @@ bool check_simple_select()
return 0;
}
/*
Setup locking for multi-table updates. Used by the replication slave.
Replication slave SQL thread examines (all_tables_not_ok()) the
locking state of referenced tables to determine if the query has to
be executed or ignored. Since in multi-table update, the
'default' lock is read-only, this lock is corrected early enough by
calling this function, before the slave decides to execute/ignore.
SYNOPSIS
check_multi_update_lock()
thd Current thread
RETURN VALUES
0 ok
1 error
*/
static bool check_multi_update_lock(THD *thd)
{
bool res= 1;
LEX *lex= thd->lex;
TABLE_LIST *table, *tables= lex->query_tables;
DBUG_ENTER("check_multi_update_lock");
if (check_db_used(thd, tables))
goto error;
/*
Ensure that we have UPDATE or SELECT privilege for each table
The exact privilege is checked in mysql_multi_update()
*/
for (table= tables ; table ; table= table->next_local)
{
TABLE_LIST *save= table->next_local;
table->next_local= 0;
if ((check_access(thd, UPDATE_ACL, table->db,
&table->grant.privilege,0,1, test(table->schema_table)) ||
(grant_option && check_grant(thd, UPDATE_ACL, table,0,1,1))) &&
check_one_table_access(thd, SELECT_ACL, table))
goto error;
table->next_local= save;
}
if (mysql_multi_update_prepare(thd))
goto error;
res= 0;
error:
DBUG_RETURN(res);
}
Comp_creator *comp_eq_creator(bool invert)
{
......
......@@ -841,9 +841,6 @@ bool mysql_multi_update(THD *thd,
multi_update *result;
DBUG_ENTER("mysql_multi_update");
if (mysql_multi_update_prepare(thd))
DBUG_RETURN(TRUE);
if (!(result= new multi_update(table_list,
thd->lex->select_lex.leaf_tables,
fields, values,
......
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