Commit a0658437 authored by pem@mysql.com's avatar pem@mysql.com

Merge mysql.com:/extern/mysql/5.0/generic/mysql-5.0

into  mysql.com:/extern/mysql/5.1/generic/mysql-5.1-new
parents 6feaef75 7f4b27cf
......@@ -185,6 +185,7 @@ void tee_fprintf(FILE *file, const char *fmt, ...);
void tee_fputs(const char *s, FILE *file);
void tee_puts(const char *s, FILE *file);
void tee_putc(int c, FILE *file);
static void tee_print_sized_data(const char *data, unsigned int length, unsigned int width);
/* The names of functions that actually do the manipulation. */
static int get_options(int argc,char **argv);
static int com_quit(String *str,char*),
......@@ -2308,20 +2309,29 @@ print_table_data(MYSQL_RES *result)
for (uint off= 0; off < mysql_num_fields(result); off++)
{
const char *str= cur[off] ? cur[off] : "NULL";
uint currlength;
uint maxlength;
uint numcells;
field= mysql_fetch_field(result);
uint maxlength= field->max_length;
maxlength= field->max_length;
currlength= (uint) lengths[off];
numcells= charset_info->cset->numcells(charset_info,
str, str + currlength);
if (maxlength > MAX_COLUMN_LENGTH)
{
tee_fputs(str, PAGER);
tee_fputs(" |", PAGER);
tee_print_sized_data(str, currlength, maxlength);
tee_fputs(" |", PAGER);
}
else
{
uint currlength= (uint) lengths[off];
uint numcells= charset_info->cset->numcells(charset_info,
str, str + currlength);
tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|",
maxlength + currlength - numcells, str);
if (num_flag[off] != 0)
tee_fprintf(PAGER, " %-*s|", maxlength + currlength - numcells, str);
else
{
tee_print_sized_data(str, currlength, maxlength);
tee_fputs(" |", PAGER);
}
}
}
(void) tee_fputs("\n", PAGER);
......@@ -2331,6 +2341,35 @@ print_table_data(MYSQL_RES *result)
}
static void
tee_print_sized_data(const char *data, unsigned int length, unsigned int width)
{
/*
It is not a number, so print each character justified to the left.
For '\0's print ASCII spaces instead, as '\0' is eaten by (at
least my) console driver, and that messes up the pretty table
grid. (The \0 is also the reason we can't use fprintf() .)
*/
unsigned int i;
const char *p;
tee_putc(' ', PAGER);
for (i= 0, p= data; i < length; i+= 1, p+= 1)
{
if (*p == '\0')
tee_putc((int)' ', PAGER);
else
tee_putc((int)*p, PAGER);
}
i+= 1;
for ( ; i < width; i+= 1)
tee_putc((int)' ', PAGER);
}
static void
print_table_data_html(MYSQL_RES *result)
{
......
......@@ -1558,6 +1558,49 @@ id
3
4
5
DROP TABLE IF EXISTS federated.bug_17377_table;
CREATE TABLE federated.bug_17377_table (
`fld_cid` bigint(20) NOT NULL auto_increment,
`fld_name` varchar(255) NOT NULL default '',
`fld_parentid` bigint(20) NOT NULL default '0',
`fld_delt` int(1) NOT NULL default '0',
PRIMARY KEY (`fld_cid`),
KEY `fld_parentid` (`fld_parentid`),
KEY `fld_delt` (`fld_delt`),
KEY `fld_cid` (`fld_cid`)
) ENGINE=MyISAM;
insert into federated.bug_17377_table( fld_name )
values
("Mats"), ("Sivert"), ("Sigvard"), ("Torgny"), ("Torkel");
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`fld_cid` bigint(20) NOT NULL auto_increment,
`fld_name` varchar(255) NOT NULL default '',
`fld_parentid` bigint(20) NOT NULL default '0',
`fld_delt` int(1) NOT NULL default '0',
PRIMARY KEY (`fld_cid`),
KEY `fld_parentid` (`fld_parentid`),
KEY `fld_delt` (`fld_delt`),
KEY `fld_cid` (`fld_cid`)
) ENGINE=FEDERATED
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/bug_17377_table';
select * from federated.t1 where fld_parentid=0 and fld_delt=0
order by fld_name;
fld_cid fld_name fld_parentid fld_delt
1 Mats 0 0
3 Sigvard 0 0
2 Sivert 0 0
4 Torgny 0 0
5 Torkel 0 0
select * from federated.t1 where fld_parentid=0 and fld_delt=0;
fld_cid fld_name fld_parentid fld_delt
1 Mats 0 0
2 Sivert 0 0
3 Sigvard 0 0
4 Torgny 0 0
5 Torkel 0 0
DROP TABLE federated.t1;
DROP TABLE federated.bug_17377_table;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1;
......
......@@ -218,3 +218,23 @@ truncate(-5000111000111000155,-1)
select truncate(15000111000111000155,-1);
truncate(15000111000111000155,-1)
15000111000111000150
set names utf8;
create table t1
(f1 varchar(32) not null,
f2 smallint(5) unsigned not null,
f3 int(10) unsigned not null default '0')
engine=myisam default charset=utf8;
insert into t1 values ('zombie',0,0),('gold',1,10000),('silver',2,10000);
create table t2
(f1 int(10) unsigned not null,
f2 int(10) unsigned not null,
f3 smallint(5) unsigned not null)
engine=myisam default charset=utf8;
insert into t2 values (16777216,16787215,1),(33554432,33564431,2);
select format(t2.f2-t2.f1+1,0) from t1,t2
where t1.f2 = t2.f3 order by t1.f1;
format(t2.f2-t2.f1+1,0)
10,000
10,000
drop table t1, t2;
set names default;
......@@ -626,3 +626,21 @@ drop user mysqltest_7@;
flush privileges;
show grants for mysqltest_7@;
ERROR 42000: There is no such grant defined for user 'mysqltest_7' on host ''
create database mysqltest;
use mysqltest;
create table t1(f1 int);
GRANT DELETE ON mysqltest.t1 TO mysqltest1@'%';
GRANT SELECT ON mysqltest.t1 TO mysqltest1@'192.%';
show grants for mysqltest1@'192.%';
Grants for mysqltest1@192.%
GRANT USAGE ON *.* TO 'mysqltest1'@'192.%'
GRANT SELECT ON `mysqltest`.`t1` TO 'mysqltest1'@'192.%'
show grants for mysqltest1@'%';
Grants for mysqltest1@%
GRANT USAGE ON *.* TO 'mysqltest1'@'%'
GRANT DELETE ON `mysqltest`.`t1` TO 'mysqltest1'@'%'
delete from mysql.user where user='mysqltest1';
delete from mysql.db where user='mysqltest1';
delete from mysql.tables_priv where user='mysqltest1';
flush privileges;
drop database mysqltest;
......@@ -475,6 +475,22 @@ b c a c b y
1 10 2 3 1 2
1 3 2 3 1 11
1 3 2 3 1 2
select * from t5 natural join ((t1 natural join t2), (t3 natural join t4));
y z b c a c b
11 4 1 10 2 3 1
11 4 1 3 2 3 1
select * from ((t1 natural join t2), (t3 natural join t4)) natural join t5;
y b c a c b z
11 1 10 2 3 1 4
11 1 3 2 3 1 4
select * from t5 natural join ((t1 natural join t2) cross join (t3 natural join t4));
y z b c a c b
11 4 1 10 2 3 1
11 4 1 3 2 3 1
select * from ((t1 natural join t2) cross join (t3 natural join t4)) natural join t5;
y b c a c b z
11 1 10 2 3 1 4
11 1 3 2 3 1 4
select * from (t1 join t2 using (b)) join (t3 join t4 using (c)) using (c);
c b a b y
3 1 2 1 11
......@@ -665,6 +681,8 @@ select * from ((t1 natural join t2), (t3 natural join t4)) natural join t6;
ERROR 23000: Column 'c' in from clause is ambiguous
select * from ((t1 natural join t2), (t3 natural join t4)) natural join t6;
ERROR 23000: Column 'c' in from clause is ambiguous
select * from t6 natural join ((t1 natural join t2), (t3 natural join t4));
ERROR 23000: Column 'c' in from clause is ambiguous
select * from (t1 join t2 on t1.b=t2.b) natural join (t3 natural join t4);
ERROR 23000: Column 'b' in from clause is ambiguous
select * from (t3 natural join t4) natural join (t1 join t2 on t1.b=t2.b);
......@@ -673,6 +691,8 @@ select * from (t3 join (t4 natural join t5) on (b < z))
natural join
(t1 natural join t2);
ERROR 23000: Column 'c' in from clause is ambiguous
select * from (t1 natural join t2) natural join (t3 join (t4 natural join t5) on (b < z));
ERROR 23000: Column 'c' in from clause is ambiguous
select t1.b from v1a;
ERROR 42S22: Unknown column 't1.b' in 'field list'
select * from v1a join v1b on t1.b = t2.b;
......@@ -697,3 +717,30 @@ drop view v2b;
drop view v3a;
drop view v3b;
drop view v4;
create table t1 (a1 int, a2 int);
create table t2 (a1 int, b int);
create table t3 (c1 int, c2 int);
create table t4 (c2 int);
insert into t1 values (1,1);
insert into t2 values (1,1);
insert into t3 values (1,1);
insert into t4 values (1);
select * from t1 join t2 using (a1) join t3 on b=c1 join t4 using (c2);
c2 a1 a2 b c1
1 1 1 1 1
select * from t3 join (t1 join t2 using (a1)) on b=c1 join t4 using (c2);
c2 c1 a1 a2 b
1 1 1 1 1
select a2 from t1 join t2 using (a1) join t3 on b=c1 join t4 using (c2);
a2
1
select a2 from t3 join (t1 join t2 using (a1)) on b=c1 join t4 using (c2);
a2
1
select a2 from ((t1 join t2 using (a1)) join t3 on b=c1) join t4 using (c2);
a2
1
select a2 from ((t1 natural join t2) join t3 on b=c1) natural join t4;
a2
1
drop table t1,t2,t3,t4;
......@@ -69,3 +69,10 @@ c_cp932
+----------------------+------------+--------+
| concat('>',col1,'<') | col2 | col3 |
+----------------------+------------+--------+
| >a < | b | 123421 |
| >a < | 0123456789 | 4 |
| >abcd< | | 4 |
+----------------------+------------+--------+
......@@ -4811,4 +4811,60 @@ date_format(t3.d, pDateFormat) count(*)
2005-02 2
drop table t3|
drop procedure bug17476|
drop table if exists t3|
drop procedure if exists bug16887|
create table t3 ( c varchar(1) )|
insert into t3 values
(' '),('.'),(';'),(','),('-'),('_'),('('),(')'),('/'),('\\')|
create procedure bug16887()
begin
declare i int default 10;
again:
while i > 0 do
begin
declare breakchar varchar(1);
declare done int default 0;
declare t3_cursor cursor for select c from t3;
declare continue handler for not found set done = 1;
set i = i - 1;
select i;
if i = 3 then
iterate again;
end if;
open t3_cursor;
loop
fetch t3_cursor into breakchar;
if done = 1 then
begin
close t3_cursor;
iterate again;
end;
end if;
end loop;
end;
end while;
end|
call bug16887()|
i
9
i
8
i
7
i
6
i
5
i
4
i
3
i
2
i
1
i
0
drop table t3|
drop procedure bug16887|
drop table t1,t2;
......@@ -787,46 +787,52 @@ drop trigger t1_bi;
ERROR 3D000: No database selected
create table t1 (id int);
create trigger t1_bi before insert on t1 for each row set @a:=new.id;
create trigger t1_ai after insert on test.t1 for each row set @b:=new.id;
insert into t1 values (101);
select @a;
@a
101
select @a, @b;
@a @b
101 101
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
trigger_schema trigger_name event_object_schema event_object_table action_statement
test t1_bi test t1 set @a:=new.id
test t1_ai test t1 set @b:=new.id
rename table t1 to t2;
insert into t2 values (102);
select @a;
@a
102
select @a, @b;
@a @b
102 102
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
trigger_schema trigger_name event_object_schema event_object_table action_statement
test t1_bi test t2 set @a:=new.id
test t1_ai test t2 set @b:=new.id
alter table t2 rename to t3;
insert into t3 values (103);
select @a;
@a
103
select @a, @b;
@a @b
103 103
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
trigger_schema trigger_name event_object_schema event_object_table action_statement
test t1_bi test t3 set @a:=new.id
test t1_ai test t3 set @b:=new.id
alter table t3 rename to t4, add column val int default 0;
insert into t4 values (104, 1);
select @a;
@a
104
select @a, @b;
@a @b
104 104
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
trigger_schema trigger_name event_object_schema event_object_table action_statement
test t1_bi test t4 set @a:=new.id
test t1_ai test t4 set @b:=new.id
drop trigger t1_bi;
drop trigger t1_ai;
drop table t4;
create database mysqltest;
use mysqltest;
......
......@@ -772,3 +772,10 @@ productid zlevelprice
003trans 39.98
004trans 31.18
drop table t1, t2;
create table t1 (f1 decimal(5));
insert into t1 values (40);
flush tables;
select f1 from t1 where f1 in (select f1 from t1);
f1
40
drop table t1;
......@@ -1257,4 +1257,59 @@ INSERT INTO federated.t1 VALUES ();
SELECT LAST_INSERT_ID();
SELECT * FROM federated.t1;
#
# Bug#17377 Federated Engine returns wrong Data, always the rows
# with the highest ID
#
connection slave;
--disable_warnings
DROP TABLE IF EXISTS federated.bug_17377_table;
--enable_warnings
CREATE TABLE federated.bug_17377_table (
`fld_cid` bigint(20) NOT NULL auto_increment,
`fld_name` varchar(255) NOT NULL default '',
`fld_parentid` bigint(20) NOT NULL default '0',
`fld_delt` int(1) NOT NULL default '0',
PRIMARY KEY (`fld_cid`),
KEY `fld_parentid` (`fld_parentid`),
KEY `fld_delt` (`fld_delt`),
KEY `fld_cid` (`fld_cid`)
) ENGINE=MyISAM;
# Insert some test-data
insert into federated.bug_17377_table( fld_name )
values
("Mats"), ("Sivert"), ("Sigvard"), ("Torgny"), ("Torkel");
connection master;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
--enable_warnings
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (
`fld_cid` bigint(20) NOT NULL auto_increment,
`fld_name` varchar(255) NOT NULL default '',
`fld_parentid` bigint(20) NOT NULL default '0',
`fld_delt` int(1) NOT NULL default '0',
PRIMARY KEY (`fld_cid`),
KEY `fld_parentid` (`fld_parentid`),
KEY `fld_delt` (`fld_delt`),
KEY `fld_cid` (`fld_cid`)
) ENGINE=FEDERATED
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/bug_17377_table';
select * from federated.t1 where fld_parentid=0 and fld_delt=0
order by fld_name;
select * from federated.t1 where fld_parentid=0 and fld_delt=0;
DROP TABLE federated.t1;
connection slave;
DROP TABLE federated.bug_17377_table;
source include/federated_cleanup.inc;
......@@ -155,3 +155,25 @@ select truncate(-5000111000111000155,-1);
# truncate on unsigned bigint
select truncate(15000111000111000155,-1);
#
# Bug#16678 FORMAT gives wrong result if client run with default-character-set=utf8
#
set names utf8;
create table t1
(f1 varchar(32) not null,
f2 smallint(5) unsigned not null,
f3 int(10) unsigned not null default '0')
engine=myisam default charset=utf8;
insert into t1 values ('zombie',0,0),('gold',1,10000),('silver',2,10000);
create table t2
(f1 int(10) unsigned not null,
f2 int(10) unsigned not null,
f3 smallint(5) unsigned not null)
engine=myisam default charset=utf8;
insert into t2 values (16777216,16787215,1),(33554432,33564431,2);
select format(t2.f2-t2.f1+1,0) from t1,t2
where t1.f2 = t2.f3 order by t1.f1;
drop table t1, t2;
set names default;
......@@ -511,4 +511,20 @@ flush privileges; # BUG#16297(flush should be removed when that bug is fixed)
--error 1141
show grants for mysqltest_7@;
#
# Bug#14385: GRANT and mapping to correct user account problems
#
create database mysqltest;
use mysqltest;
create table t1(f1 int);
GRANT DELETE ON mysqltest.t1 TO mysqltest1@'%';
GRANT SELECT ON mysqltest.t1 TO mysqltest1@'192.%';
show grants for mysqltest1@'192.%';
show grants for mysqltest1@'%';
delete from mysql.user where user='mysqltest1';
delete from mysql.db where user='mysqltest1';
delete from mysql.tables_priv where user='mysqltest1';
flush privileges;
drop database mysqltest;
# End of 4.1 tests
......@@ -408,11 +408,10 @@ select * from t1 natural join (t2 natural join (t3 natural join t4));
select * from t5 natural right join (t4 natural right join ((t2 natural right join t1) natural right join t3));
select * from (t1 natural join t2), (t3 natural join t4);
-- MySQL extension - nested comma ',' operator instead of cross join.
-- BUG#15357 - natural join with nested cross-join results in incorrect columns
-- select * from t5 natural join ((t1 natural join t2), (t3 natural join t4));
-- select * from ((t1 natural join t2), (t3 natural join t4)) natural join t5;
-- select * from t5 natural join ((t1 natural join t2) cross join (t3 natural join t4));
-- select * from ((t1 natural join t2) cross join (t3 natural join t4)) natural join t5;
select * from t5 natural join ((t1 natural join t2), (t3 natural join t4));
select * from ((t1 natural join t2), (t3 natural join t4)) natural join t5;
select * from t5 natural join ((t1 natural join t2) cross join (t3 natural join t4));
select * from ((t1 natural join t2) cross join (t3 natural join t4)) natural join t5;
select * from (t1 join t2 using (b)) join (t3 join t4 using (c)) using (c);
select * from (t1 join t2 using (b)) natural join (t3 join t4 using (c));
......@@ -500,8 +499,7 @@ select * from ((t1 natural join t2), (t3 natural join t4)) natural join t6;
-- error 1052
select * from ((t1 natural join t2), (t3 natural join t4)) natural join t6;
-- error 1052
-- BUG#15357: doesn't detect non-unique column 'c', as in the above query.
-- select * from t6 natural join ((t1 natural join t2), (t3 natural join t4));
select * from t6 natural join ((t1 natural join t2), (t3 natural join t4));
-- error 1052
select * from (t1 join t2 on t1.b=t2.b) natural join (t3 natural join t4);
-- error 1052
......@@ -512,11 +510,7 @@ select * from (t3 join (t4 natural join t5) on (b < z))
natural join
(t1 natural join t2);
-- error 1052
-- BUG#15357: this query should return an ambiguous column error
-- Expected result: the query must return error with duplicate column 'c'
--select * from (t1 natural join t2)
-- natural join
-- (t3 join (t4 natural join t5) on (b < z));
select * from (t1 natural join t2) natural join (t3 join (t4 natural join t5) on (b < z));
-- error 1054
select t1.b from v1a;
......@@ -546,4 +540,27 @@ drop view v3a;
drop view v3b;
drop view v4;
#
# BUG#15229 - columns of nested joins that are not natural joins incorrectly
# materialized
#
create table t1 (a1 int, a2 int);
create table t2 (a1 int, b int);
create table t3 (c1 int, c2 int);
create table t4 (c2 int);
insert into t1 values (1,1);
insert into t2 values (1,1);
insert into t3 values (1,1);
insert into t4 values (1);
select * from t1 join t2 using (a1) join t3 on b=c1 join t4 using (c2);
select * from t3 join (t1 join t2 using (a1)) on b=c1 join t4 using (c2);
select a2 from t1 join t2 using (a1) join t3 on b=c1 join t4 using (c2);
select a2 from t3 join (t1 join t2 using (a1)) on b=c1 join t4 using (c2);
select a2 from ((t1 join t2 using (a1)) join t3 on b=c1) join t4 using (c2);
select a2 from ((t1 natural join t2) join t3 on b=c1) natural join t4;
drop table t1,t2,t3,t4;
# End of tests for WL#2486 - natural/using join
......@@ -56,3 +56,8 @@ drop table t1;
--exec $MYSQL --default-character-set=utf8 test -e "charset cp932; set character_set_client= cp932; select '\'"
--exec $MYSQL --default-character-set=utf8 test -e "/*charset cp932 */; set character_set_client= cp932; select '\'"
--exec $MYSQL --default-character-set=utf8 test -e "/*!\C cp932 */; set character_set_client= cp932; select '\'"
#
# Bug#16859 -- NULLs in columns must not truncate data as if a C-language "string".
#
--exec $MYSQL -t test -e "create table t1 (col1 binary(4), col2 varchar(10), col3 int); insert into t1 values ('a', 'b', 123421),('a ', '0123456789', 4), ('abcd', '', 4); select concat('>',col1,'<'), col2, col3 from t1; drop table t1;" 2>&1
......@@ -5643,6 +5643,7 @@ drop function bug17615|
drop table t3|
#
# BUG#17476: Stored procedure not returning data when it is called first
# time per connection
#
......@@ -5667,6 +5668,60 @@ drop table t3|
drop procedure bug17476|
#
# BUG#16887: Cursor causes server segfault
#
--disable_warnings
drop table if exists t3|
drop procedure if exists bug16887|
--enable_warnings
create table t3 ( c varchar(1) )|
insert into t3 values
(' '),('.'),(';'),(','),('-'),('_'),('('),(')'),('/'),('\\')|
create procedure bug16887()
begin
declare i int default 10;
again:
while i > 0 do
begin
declare breakchar varchar(1);
declare done int default 0;
declare t3_cursor cursor for select c from t3;
declare continue handler for not found set done = 1;
set i = i - 1;
select i;
if i = 3 then
iterate again;
end if;
open t3_cursor;
loop
fetch t3_cursor into breakchar;
if done = 1 then
begin
close t3_cursor;
iterate again;
end;
end if;
end loop;
end;
end while;
end|
call bug16887()|
drop table t3|
drop procedure bug16887|
#
# BUG#NNNN: New bug synopsis
#
......
......@@ -960,38 +960,42 @@ drop trigger t1_bi;
connection default;
#
# Test for bug #13525 "Rename table does not keep info of triggers"
# Tests for bug #13525 "Rename table does not keep info of triggers"
# and bug #17866 "Problem with renaming table with triggers with fully
# qualified subject table".
#
create table t1 (id int);
create trigger t1_bi before insert on t1 for each row set @a:=new.id;
create trigger t1_ai after insert on test.t1 for each row set @b:=new.id;
insert into t1 values (101);
select @a;
select @a, @b;
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
rename table t1 to t2;
# Trigger should work after rename
insert into t2 values (102);
select @a;
select @a, @b;
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
# Let us check that the same works for simple ALTER TABLE ... RENAME
alter table t2 rename to t3;
insert into t3 values (103);
select @a;
select @a, @b;
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
# And for more complex ALTER TABLE
alter table t3 rename to t4, add column val int default 0;
insert into t4 values (104, 1);
select @a;
select @a, @b;
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
# .TRN file should be updated with new table name
drop trigger t1_bi;
drop trigger t1_ai;
drop table t4;
# Rename between different databases if triggers exist should fail
create database mysqltest;
......
......@@ -377,3 +377,11 @@ insert INTO t2 SELECT * FROM t1;
select * from t2;
drop table t1, t2;
#
# Bug #17826 'type_decimal' fails with ps-protocol
#
create table t1 (f1 decimal(5));
insert into t1 values (40);
flush tables;
select f1 from t1 where f1 in (select f1 from t1);
drop table t1;
......@@ -758,7 +758,7 @@ error:
ha_federated::ha_federated(TABLE_SHARE *table_arg)
:handler(&federated_hton, table_arg),
mysql(0), stored_result(0), scan_flag(0),
mysql(0), stored_result(0),
ref_length(sizeof(MYSQL_ROW_OFFSET)), current_position(0)
{
trx_next= 0;
......@@ -2238,7 +2238,7 @@ int ha_federated::rnd_init(bool scan)
containing the correct record, hence update the wrong row!
*/
scan_flag= scan;
if (scan)
{
DBUG_PRINT("info", ("share->select_query %s", share->select_query));
......@@ -2362,24 +2362,13 @@ void ha_federated::position(const byte *record)
int ha_federated::rnd_pos(byte *buf, byte *pos)
{
DBUG_ENTER("ha_federated::rnd_pos");
/*
we do not need to do any of this if there has been a scan performed
already, or if this is an update and index_read_idx already has a result
set in which to build it's update query from
*/
if (scan_flag)
{
int retval;
statistic_increment(table->in_use->status_var.ha_read_rnd_count,
&LOCK_status);
memcpy_fixed(&current_position, pos, sizeof(MYSQL_ROW_OFFSET)); // pos
/* is not aligned */
stored_result->current_row= 0;
stored_result->data_cursor= current_position;
retval= rnd_next(buf);
DBUG_RETURN(retval);
}
DBUG_RETURN(0);
statistic_increment(table->in_use->status_var.ha_read_rnd_count,
&LOCK_status);
memcpy_fixed(&current_position, pos, sizeof(MYSQL_ROW_OFFSET));
stored_result->current_row= 0;
stored_result->data_cursor= current_position;
DBUG_RETURN(rnd_next(buf));
}
......
......@@ -153,7 +153,6 @@ class ha_federated: public handler
FEDERATED_SHARE *share; /* Shared lock info */
MYSQL *mysql; /* MySQL connection */
MYSQL_RES *stored_result;
bool scan_flag;
uint ref_length;
uint fetch_num; // stores the fetch num
MYSQL_ROW_OFFSET current_position; // Current position used by ::position()
......
......@@ -61,7 +61,7 @@ bool hostname_cache_init()
if (!(hostname_cache=new hash_filo(HOST_CACHE_SIZE, offset,
sizeof(struct in_addr),NULL,
(hash_free_key) free,
&my_charset_latin1)))
&my_charset_bin)))
return 1;
hostname_cache->clear();
(void) pthread_mutex_init(&LOCK_hostname,MY_MUTEX_INIT_SLOW);
......
......@@ -698,12 +698,6 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
return 1;
cache->setup(args[0]);
/*
If it is preparation PS only then we do not know values of parameters =>
cant't get there values and do not need that values.
*/
if (!thd->stmt_arena->is_stmt_prepare())
cache->store(args[0]);
if (cache->cols() == 1)
{
if ((used_tables_cache= args[0]->used_tables()))
......
......@@ -471,7 +471,9 @@ public:
void fix_length_and_dec()
{
collation.set(default_charset());
max_length=args[0]->max_length+(args[0]->max_length-args[0]->decimals)/3;
uint char_length= args[0]->max_length/args[0]->collation.collation->mbmaxlen;
max_length= ((char_length + (char_length-args[0]->decimals)/3) *
collation.collation->mbmaxlen);
}
const char *func_name() const { return "format"; }
void print(String *);
......
......@@ -122,30 +122,38 @@ sp_pcontext::pop_context()
}
uint
sp_pcontext::diff_handlers(sp_pcontext *ctx)
sp_pcontext::diff_handlers(sp_pcontext *ctx, bool exclusive)
{
uint n= 0;
sp_pcontext *pctx= this;
sp_pcontext *last_ctx= NULL;
while (pctx && pctx != ctx)
{
n+= pctx->m_handlers;
last_ctx= pctx;
pctx= pctx->parent_context();
}
if (pctx)
return n;
return (exclusive && last_ctx ? n - last_ctx->m_handlers : n);
return 0; // Didn't find ctx
}
uint
sp_pcontext::diff_cursors(sp_pcontext *ctx)
sp_pcontext::diff_cursors(sp_pcontext *ctx, bool exclusive)
{
uint n= 0;
sp_pcontext *pctx= this;
sp_pcontext *last_ctx= NULL;
while (pctx && pctx != ctx)
{
n+= pctx->m_cursor.elements;
last_ctx= pctx;
pctx= pctx->parent_context();
}
if (pctx)
return ctx->current_cursors() - pctx->current_cursors();
return (exclusive && last_ctx ? n - last_ctx->m_cursor.elements : n);
return 0; // Didn't find ctx
}
......
......@@ -119,11 +119,15 @@ class sp_pcontext : public Sql_alloc
return m_parent;
}
/*
Number of handlers/cursors to pop between this context and 'ctx'.
If 'exclusive' is true, don't count the last block we are leaving;
this is used for LEAVE where we will jump to the cpop/hpop instructions.
*/
uint
diff_handlers(sp_pcontext *ctx);
diff_handlers(sp_pcontext *ctx, bool exclusive);
uint
diff_cursors(sp_pcontext *ctx);
diff_cursors(sp_pcontext *ctx, bool exclusive);
//
......
......@@ -2387,7 +2387,10 @@ static GRANT_NAME *name_hash_search(HASH *name_hash,
{
if (exact)
{
if (compare_hostname(&grant_name->host, host, ip))
if ((host &&
!my_strcasecmp(system_charset_info, host,
grant_name->host.hostname)) ||
(ip && !strcmp(ip, grant_name->host.hostname)))
return grant_name;
}
else
......
......@@ -4431,8 +4431,18 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
Field_iterator_table_ref it_1, it_2;
Natural_join_column *nj_col_1, *nj_col_2;
Query_arena *arena, backup;
bool add_columns= TRUE;
bool result= TRUE;
bool first_outer_loop= TRUE;
/*
Leaf table references to which new natural join columns are added
if the leaves are != NULL.
*/
TABLE_LIST *leaf_1= (table_ref_1->nested_join &&
!table_ref_1->is_natural_join) ?
NULL : table_ref_1;
TABLE_LIST *leaf_2= (table_ref_2->nested_join &&
!table_ref_2->is_natural_join) ?
NULL : table_ref_2;
DBUG_ENTER("mark_common_columns");
DBUG_PRINT("info", ("operand_1: %s operand_2: %s",
......@@ -4441,36 +4451,14 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
*found_using_fields= 0;
arena= thd->activate_stmt_arena_if_needed(&backup);
/*
TABLE_LIST::join_columns could be allocated by the previous call to
store_natural_using_join_columns() for the lower level of nested tables.
*/
if (!table_ref_1->join_columns)
{
if (!(table_ref_1->join_columns= new List<Natural_join_column>))
goto err;
table_ref_1->is_join_columns_complete= FALSE;
}
if (!table_ref_2->join_columns)
{
if (!(table_ref_2->join_columns= new List<Natural_join_column>))
goto err;
table_ref_2->is_join_columns_complete= FALSE;
}
for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next())
{
bool is_created_1;
bool found= FALSE;
const char *field_name_1;
if (!(nj_col_1= it_1.get_or_create_column_ref(&is_created_1)))
if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1)))
goto err;
field_name_1= nj_col_1->name();
/* If nj_col_1 was just created add it to the list of join columns. */
if (is_created_1)
table_ref_1->join_columns->push_back(nj_col_1);
/*
Find a field with the same name in table_ref_2.
......@@ -4481,17 +4469,12 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
nj_col_2= NULL;
for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next())
{
bool is_created_2;
Natural_join_column *cur_nj_col_2;
const char *cur_field_name_2;
if (!(cur_nj_col_2= it_2.get_or_create_column_ref(&is_created_2)))
if (!(cur_nj_col_2= it_2.get_or_create_column_ref(leaf_2)))
goto err;
cur_field_name_2= cur_nj_col_2->name();
/* If nj_col_1 was just created add it to the list of join columns. */
if (add_columns && is_created_2)
table_ref_2->join_columns->push_back(cur_nj_col_2);
/*
Compare the two columns and check for duplicate common fields.
A common field is duplicate either if it was already found in
......@@ -4510,9 +4493,15 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
found= TRUE;
}
}
/* Force it_2.set() to use table_ref_2->join_columns. */
table_ref_2->is_join_columns_complete= TRUE;
add_columns= FALSE;
if (first_outer_loop && leaf_2)
{
/*
Make sure that the next inner loop "knows" that all columns
are materialized already.
*/
leaf_2->is_join_columns_complete= TRUE;
first_outer_loop= FALSE;
}
if (!found)
continue; // No matching field
......@@ -4600,7 +4589,8 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
++(*found_using_fields);
}
}
table_ref_1->is_join_columns_complete= TRUE;
if (leaf_1)
leaf_1->is_join_columns_complete= TRUE;
/*
Everything is OK.
......@@ -5460,16 +5450,15 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
if (tables->is_natural_join)
{
bool is_created;
TABLE *field_table;
/*
In this case we are sure that the column ref will not be created
because it was already created and stored with the natural join.
*/
Natural_join_column *nj_col;
if (!(nj_col= field_iterator.get_or_create_column_ref(&is_created)))
if (!(nj_col= field_iterator.get_natural_column_ref()))
DBUG_RETURN(TRUE);
DBUG_ASSERT(nj_col->table_field && !is_created);
DBUG_ASSERT(nj_col->table_field);
field_table= nj_col->table_ref->table;
if (field_table)
{
......
......@@ -1213,6 +1213,7 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd,
buff.append(def->str, before_on_len);
buff.append(STRING_WITH_LEN("ON "));
append_identifier(thd, &buff, new_table_name->str, new_table_name->length);
buff.append(STRING_WITH_LEN(" "));
on_q_table_name_len= buff.length() - before_on_len;
buff.append(on_table_name->str + on_table_name->length,
def->length - (before_on_len + on_table_name->length));
......
......@@ -2463,10 +2463,10 @@ sp_proc_stmt_leave:
uint ip= sp->instructions();
uint n;
n= ctx->diff_handlers(lab->ctx);
n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */
if (n)
sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
n= ctx->diff_cursors(lab->ctx);
n= ctx->diff_cursors(lab->ctx, TRUE); /* Exclusive the dest. */
if (n)
sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
i= new sp_instr_jump(ip, ctx);
......@@ -2495,10 +2495,10 @@ sp_proc_stmt_iterate:
uint ip= sp->instructions();
uint n;
n= ctx->diff_handlers(lab->ctx);
n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */
if (n)
sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
n= ctx->diff_cursors(lab->ctx);
n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */
if (n)
sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
......@@ -10927,7 +10927,7 @@ view_check_option:
trigger_tail:
TRIGGER_SYM remember_name sp_name trg_action_time trg_event
ON remember_name table_ident remember_end FOR_SYM EACH_SYM ROW_SYM
ON remember_name table_ident FOR_SYM remember_name EACH_SYM ROW_SYM
{
LEX *lex= Lex;
sp_head *sp;
......@@ -10945,7 +10945,7 @@ trigger_tail:
lex->trigger_definition_begin= $2;
lex->ident.str= $7;
lex->ident.length= $9 - $7;
lex->ident.length= $10 - $7;
sp->m_type= TYPE_ENUM_TRIGGER;
lex->sphead= sp;
......
......@@ -3575,11 +3575,31 @@ GRANT_INFO *Field_iterator_table_ref::grant()
SYNOPSIS
Field_iterator_table_ref::get_or_create_column_ref()
is_created [out] set to TRUE if the column was created,
FALSE if we return an already created colum
parent_table_ref the parent table reference over which the
iterator is iterating
DESCRIPTION
TODO
Create a new natural join column for the current field of the
iterator if no such column was created, or return an already
created natural join column. The former happens for base tables or
views, and the latter for natural/using joins. If a new field is
created, then the field is added to 'parent_table_ref' if it is
given, or to the original table referene of the field if
parent_table_ref == NULL.
NOTES
This method is designed so that when a Field_iterator_table_ref
walks through the fields of a table reference, all its fields
are created and stored as follows:
- If the table reference being iterated is a stored table, view or
natural/using join, store all natural join columns in a list
attached to that table reference.
- If the table reference being iterated is a nested join that is
not natural/using join, then do not materialize its result
fields. This is OK because for such table references
Field_iterator_table_ref iterates over the fields of the nested
table references (recursively). In this way we avoid the storage
of unnecessay copies of result columns of nested joins.
RETURN
# Pointer to a column of a natural join (or its operand)
......@@ -3587,22 +3607,28 @@ GRANT_INFO *Field_iterator_table_ref::grant()
*/
Natural_join_column *
Field_iterator_table_ref::get_or_create_column_ref(bool *is_created)
Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref)
{
Natural_join_column *nj_col;
bool is_created= TRUE;
uint field_count;
TABLE_LIST *add_table_ref= parent_table_ref ?
parent_table_ref : table_ref;
*is_created= TRUE;
if (field_it == &table_field_it)
{
/* The field belongs to a stored table. */
Field *field= table_field_it.field();
nj_col= new Natural_join_column(field, table_ref);
field_count= table_ref->table->s->fields;
}
else if (field_it == &view_field_it)
{
/* The field belongs to a merge view or information schema table. */
Field_translator *translated_field= view_field_it.field_translator();
nj_col= new Natural_join_column(translated_field, table_ref);
field_count= table_ref->field_translation_end -
table_ref->field_translation;
}
else
{
......@@ -3611,12 +3637,43 @@ Field_iterator_table_ref::get_or_create_column_ref(bool *is_created)
already created via one of the two constructor calls above. In this case
we just return the already created column reference.
*/
*is_created= FALSE;
DBUG_ASSERT(table_ref->is_join_columns_complete);
is_created= FALSE;
nj_col= natural_join_it.column_ref();
DBUG_ASSERT(nj_col);
}
DBUG_ASSERT(!nj_col->table_field ||
nj_col->table_ref->table == nj_col->table_field->table);
/*
If the natural join column was just created add it to the list of
natural join columns of either 'parent_table_ref' or to the table
reference that directly contains the original field.
*/
if (is_created)
{
/* Make sure not all columns were materialized. */
DBUG_ASSERT(!add_table_ref->is_join_columns_complete);
if (!add_table_ref->join_columns)
{
/* Create a list of natural join columns on demand. */
if (!(add_table_ref->join_columns= new List<Natural_join_column>))
return NULL;
add_table_ref->is_join_columns_complete= FALSE;
}
add_table_ref->join_columns->push_back(nj_col);
/*
If new fields are added to their original table reference, mark if
all fields were added. We do it here as the caller has no easy way
of knowing when to do it.
If the fields are being added to parent_table_ref, then the caller
must take care to mark when all fields are created/added.
*/
if (!parent_table_ref &&
add_table_ref->join_columns->elements == field_count)
add_table_ref->is_join_columns_complete= TRUE;
}
return nj_col;
}
......
......@@ -834,7 +834,7 @@ public:
GRANT_INFO *grant();
Item *create_item(THD *thd) { return field_it->create_item(thd); }
Field *field() { return field_it->field(); }
Natural_join_column *get_or_create_column_ref(bool *is_created);
Natural_join_column *get_or_create_column_ref(TABLE_LIST *parent_table_ref);
Natural_join_column *get_natural_column_ref();
};
......
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