Merge bodhi.local:/opt/local/work/tmp_merge
into bodhi.local:/opt/local/work/mysql-5.1-runtime-merge
This commit is contained in:
commit
73189969f3
@ -1,4 +1,6 @@
|
|||||||
*-t
|
*-t
|
||||||
|
*.Plo
|
||||||
|
*.Po
|
||||||
*.a
|
*.a
|
||||||
*.bb
|
*.bb
|
||||||
*.bbg
|
*.bbg
|
||||||
@ -12,6 +14,7 @@
|
|||||||
*.gcov
|
*.gcov
|
||||||
*.idb
|
*.idb
|
||||||
*.la
|
*.la
|
||||||
|
*.lai
|
||||||
*.lib
|
*.lib
|
||||||
*.lo
|
*.lo
|
||||||
*.map
|
*.map
|
||||||
@ -23,6 +26,7 @@
|
|||||||
*.res
|
*.res
|
||||||
*.sbr
|
*.sbr
|
||||||
*.so
|
*.so
|
||||||
|
*.so.*
|
||||||
*.spec
|
*.spec
|
||||||
*/*_pure_*warnings
|
*/*_pure_*warnings
|
||||||
*/.pure
|
*/.pure
|
||||||
@ -283,6 +287,7 @@ build_tags.sh
|
|||||||
client/#mysql.cc#
|
client/#mysql.cc#
|
||||||
client/*.ds?
|
client/*.ds?
|
||||||
client/*.vcproj
|
client/*.vcproj
|
||||||
|
client/.libs -prune
|
||||||
client/completion_hash.cpp
|
client/completion_hash.cpp
|
||||||
client/decimal.c
|
client/decimal.c
|
||||||
client/insert_test
|
client/insert_test
|
||||||
@ -578,6 +583,7 @@ libmysqld/sql_insert.cc
|
|||||||
libmysqld/sql_lex.cc
|
libmysqld/sql_lex.cc
|
||||||
libmysqld/sql_list.cc
|
libmysqld/sql_list.cc
|
||||||
libmysqld/sql_load.cc
|
libmysqld/sql_load.cc
|
||||||
|
libmysqld/sql_locale.cc
|
||||||
libmysqld/sql_manager.cc
|
libmysqld/sql_manager.cc
|
||||||
libmysqld/sql_map.cc
|
libmysqld/sql_map.cc
|
||||||
libmysqld/sql_olap.cc
|
libmysqld/sql_olap.cc
|
||||||
@ -1755,6 +1761,7 @@ test1/*
|
|||||||
test_xml
|
test_xml
|
||||||
tests/*.ds?
|
tests/*.ds?
|
||||||
tests/*.vcproj
|
tests/*.vcproj
|
||||||
|
tests/.libs -prune
|
||||||
tests/client_test
|
tests/client_test
|
||||||
tests/connect_test
|
tests/connect_test
|
||||||
tests/mysql_client_test
|
tests/mysql_client_test
|
||||||
@ -1762,6 +1769,7 @@ thr_insert_test/*
|
|||||||
thr_test/*
|
thr_test/*
|
||||||
thread_test
|
thread_test
|
||||||
tmp/*
|
tmp/*
|
||||||
|
tools/.libs -prune
|
||||||
tools/my_vsnprintf.c
|
tools/my_vsnprintf.c
|
||||||
tools/mysqlmanager
|
tools/mysqlmanager
|
||||||
tools/mysqlmngd
|
tools/mysqlmngd
|
||||||
|
@ -56,7 +56,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
|
|||||||
key.cc lock.cc log.cc log_event.cc sql_state.c \
|
key.cc lock.cc log.cc log_event.cc sql_state.c \
|
||||||
protocol.cc net_serv.cc opt_range.cc \
|
protocol.cc net_serv.cc opt_range.cc \
|
||||||
opt_sum.cc procedure.cc records.cc sql_acl.cc \
|
opt_sum.cc procedure.cc records.cc sql_acl.cc \
|
||||||
sql_load.cc discover.cc \
|
sql_load.cc discover.cc sql_locale.cc \
|
||||||
sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
|
sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
|
||||||
sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
|
sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
|
||||||
sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc sql_parse.cc \
|
sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc sql_parse.cc \
|
||||||
|
@ -498,6 +498,22 @@ f1 f2
|
|||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Truncated incorrect date value: '2003-04-05 g'
|
Warning 1292 Truncated incorrect date value: '2003-04-05 g'
|
||||||
Warning 1292 Truncated incorrect datetime value: '2003-04-05 10:11:12.101010234567'
|
Warning 1292 Truncated incorrect datetime value: '2003-04-05 10:11:12.101010234567'
|
||||||
|
set names latin1;
|
||||||
|
select date_format('2004-01-01','%W (%a), %e %M (%b) %Y');
|
||||||
|
date_format('2004-01-01','%W (%a), %e %M (%b) %Y')
|
||||||
|
Thursday (Thu), 1 January (Jan) 2004
|
||||||
|
set lc_time_names=ru_RU;
|
||||||
|
set names koi8r;
|
||||||
|
select date_format('2004-01-01','%W (%a), %e %M (%b) %Y');
|
||||||
|
date_format('2004-01-01','%W (%a), %e %M (%b) %Y')
|
||||||
|
þÅÔ×ÅÒÇ (þÔ×), 1 ñÎ×ÁÒÑ (ñÎ×) 2004
|
||||||
|
set lc_time_names=de_DE;
|
||||||
|
set names latin1;
|
||||||
|
select date_format('2004-01-01','%W (%a), %e %M (%b) %Y');
|
||||||
|
date_format('2004-01-01','%W (%a), %e %M (%b) %Y')
|
||||||
|
Donnerstag (Do), 1 Januar (Jan) 2004
|
||||||
|
set names latin1;
|
||||||
|
set lc_time_names=en_US;
|
||||||
create table t1 (f1 datetime);
|
create table t1 (f1 datetime);
|
||||||
insert into t1 (f1) values ("2005-01-01");
|
insert into t1 (f1) values ("2005-01-01");
|
||||||
insert into t1 (f1) values ("2005-02-01");
|
insert into t1 (f1) values ("2005-02-01");
|
||||||
|
@ -22,3 +22,117 @@ set GLOBAL init_connect="adsfsdfsdfs";
|
|||||||
select @a;
|
select @a;
|
||||||
Got one of the listed errors
|
Got one of the listed errors
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
End of 4.1 tests
|
||||||
|
create table t1 (x int);
|
||||||
|
insert into t1 values (3), (5), (7);
|
||||||
|
create table t2 (y int);
|
||||||
|
create user mysqltest1@localhost;
|
||||||
|
grant all privileges on test.* to mysqltest1@localhost;
|
||||||
|
set global init_connect="create procedure p1() select * from t1";
|
||||||
|
call p1();
|
||||||
|
x
|
||||||
|
3
|
||||||
|
5
|
||||||
|
7
|
||||||
|
drop procedure p1;
|
||||||
|
set global init_connect="create procedure p1(x int)\
|
||||||
|
begin\
|
||||||
|
select count(*) from t1;\
|
||||||
|
select * from t1;\
|
||||||
|
set @x = x;
|
||||||
|
end";
|
||||||
|
call p1(42);
|
||||||
|
count(*)
|
||||||
|
3
|
||||||
|
x
|
||||||
|
3
|
||||||
|
5
|
||||||
|
7
|
||||||
|
select @x;
|
||||||
|
@x
|
||||||
|
42
|
||||||
|
set global init_connect="call p1(4711)";
|
||||||
|
select @x;
|
||||||
|
@x
|
||||||
|
4711
|
||||||
|
set global init_connect="drop procedure if exists p1";
|
||||||
|
call p1();
|
||||||
|
ERROR 42000: PROCEDURE test.p1 does not exist
|
||||||
|
create procedure p1(out sum int)
|
||||||
|
begin
|
||||||
|
declare n int default 0;
|
||||||
|
declare c cursor for select * from t1;
|
||||||
|
declare exit handler for not found
|
||||||
|
begin
|
||||||
|
close c;
|
||||||
|
set sum = n;
|
||||||
|
end;
|
||||||
|
open c;
|
||||||
|
loop
|
||||||
|
begin
|
||||||
|
declare x int;
|
||||||
|
fetch c into x;
|
||||||
|
if x > 3 then
|
||||||
|
set n = n + x;
|
||||||
|
end if;
|
||||||
|
end;
|
||||||
|
end loop;
|
||||||
|
end|
|
||||||
|
set global init_connect="call p1(@sum)";
|
||||||
|
select @sum;
|
||||||
|
@sum
|
||||||
|
12
|
||||||
|
drop procedure p1;
|
||||||
|
create procedure p1(tbl char(10), v int)
|
||||||
|
begin
|
||||||
|
set @s = concat('insert into ', tbl, ' values (?)');
|
||||||
|
set @v = v;
|
||||||
|
prepare stmt1 from @s;
|
||||||
|
execute stmt1 using @v;
|
||||||
|
deallocate prepare stmt1;
|
||||||
|
end|
|
||||||
|
set global init_connect="call p1('t1', 11)";
|
||||||
|
select * from t1;
|
||||||
|
x
|
||||||
|
3
|
||||||
|
5
|
||||||
|
7
|
||||||
|
11
|
||||||
|
drop procedure p1;
|
||||||
|
create function f1() returns int
|
||||||
|
begin
|
||||||
|
declare n int;
|
||||||
|
select count(*) into n from t1;
|
||||||
|
return n;
|
||||||
|
end|
|
||||||
|
set global init_connect="set @x = f1()";
|
||||||
|
select @x;
|
||||||
|
@x
|
||||||
|
4
|
||||||
|
set global init_connect="create view v1 as select f1()";
|
||||||
|
select * from v1;
|
||||||
|
f1()
|
||||||
|
4
|
||||||
|
set global init_connect="drop view v1";
|
||||||
|
select * from v1;
|
||||||
|
ERROR 42S02: Table 'test.v1' doesn't exist
|
||||||
|
drop function f1;
|
||||||
|
create trigger trg1
|
||||||
|
after insert on t2
|
||||||
|
for each row
|
||||||
|
insert into t1 values (new.y);
|
||||||
|
set global init_connect="insert into t2 values (13), (17), (19)";
|
||||||
|
select * from t1;
|
||||||
|
x
|
||||||
|
3
|
||||||
|
5
|
||||||
|
7
|
||||||
|
11
|
||||||
|
13
|
||||||
|
17
|
||||||
|
19
|
||||||
|
drop trigger trg1;
|
||||||
|
set global init_connect=default;
|
||||||
|
revoke all privileges, grant option from mysqltest1@localhost;
|
||||||
|
drop user mysqltest1@localhost;
|
||||||
|
drop table t1, t2;
|
||||||
|
@ -1 +1,16 @@
|
|||||||
ok
|
ok
|
||||||
|
end of 4.1 tests
|
||||||
|
select * from t1;
|
||||||
|
x
|
||||||
|
3
|
||||||
|
5
|
||||||
|
7
|
||||||
|
11
|
||||||
|
13
|
||||||
|
select * from t2;
|
||||||
|
y
|
||||||
|
30
|
||||||
|
3
|
||||||
|
11
|
||||||
|
13
|
||||||
|
drop table t1, t2;
|
||||||
|
@ -1442,6 +1442,19 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
|
|||||||
create table t4 (c1 int) engine=myisam pack_keys=2;
|
create table t4 (c1 int) engine=myisam pack_keys=2;
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2' at line 1
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
show create table t1;
|
||||||
|
show create table t1;
|
||||||
|
create table t1 (a int) engine=myisam select 42 a;
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
9
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
99
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
42
|
||||||
|
drop table t1;
|
||||||
create table t1 (a int not null, key `a` (a) key_block_size=1024);
|
create table t1 (a int not null, key `a` (a) key_block_size=1024);
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
|
@ -661,3 +661,56 @@ DROP VIEW test2.t3;
|
|||||||
DROP TABLE test2.t1, test1.t0;
|
DROP TABLE test2.t1, test1.t0;
|
||||||
DROP DATABASE test2;
|
DROP DATABASE test2;
|
||||||
DROP DATABASE test1;
|
DROP DATABASE test1;
|
||||||
|
DROP VIEW IF EXISTS v1;
|
||||||
|
DROP VIEW IF EXISTS v2;
|
||||||
|
DROP VIEW IF EXISTS v3;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP FUNCTION IF EXISTS f2;
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
CREATE SQL SECURITY DEFINER VIEW v1 AS SELECT CURRENT_USER() AS cu;
|
||||||
|
CREATE FUNCTION f1() RETURNS VARCHAR(77) SQL SECURITY INVOKER
|
||||||
|
RETURN CURRENT_USER();
|
||||||
|
CREATE SQL SECURITY DEFINER VIEW v2 AS SELECT f1() AS cu;
|
||||||
|
CREATE PROCEDURE p1(OUT cu VARCHAR(77)) SQL SECURITY INVOKER
|
||||||
|
SET cu= CURRENT_USER();
|
||||||
|
CREATE FUNCTION f2() RETURNS VARCHAR(77) SQL SECURITY INVOKER
|
||||||
|
BEGIN
|
||||||
|
DECLARE cu VARCHAR(77);
|
||||||
|
CALL p1(cu);
|
||||||
|
RETURN cu;
|
||||||
|
END|
|
||||||
|
CREATE SQL SECURITY DEFINER VIEW v3 AS SELECT f2() AS cu;
|
||||||
|
CREATE USER mysqltest_u1@localhost;
|
||||||
|
GRANT ALL ON test.* TO mysqltest_u1@localhost;
|
||||||
|
|
||||||
|
The following tests should all return 1.
|
||||||
|
|
||||||
|
SELECT CURRENT_USER() = 'mysqltest_u1@localhost';
|
||||||
|
CURRENT_USER() = 'mysqltest_u1@localhost'
|
||||||
|
1
|
||||||
|
SELECT f1() = 'mysqltest_u1@localhost';
|
||||||
|
f1() = 'mysqltest_u1@localhost'
|
||||||
|
1
|
||||||
|
CALL p1(@cu);
|
||||||
|
SELECT @cu = 'mysqltest_u1@localhost';
|
||||||
|
@cu = 'mysqltest_u1@localhost'
|
||||||
|
1
|
||||||
|
SELECT f2() = 'mysqltest_u1@localhost';
|
||||||
|
f2() = 'mysqltest_u1@localhost'
|
||||||
|
1
|
||||||
|
SELECT cu = 'root@localhost' FROM v1;
|
||||||
|
cu = 'root@localhost'
|
||||||
|
1
|
||||||
|
SELECT cu = 'root@localhost' FROM v2;
|
||||||
|
cu = 'root@localhost'
|
||||||
|
1
|
||||||
|
SELECT cu = 'root@localhost' FROM v3;
|
||||||
|
cu = 'root@localhost'
|
||||||
|
1
|
||||||
|
DROP VIEW v3;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP VIEW v2;
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP USER mysqltest_u1@localhost;
|
||||||
|
@ -1 +1,29 @@
|
|||||||
select * from mysql.user as t1, mysql.user as t2, mysql.user as t3;
|
select * from mysql.user as t1, mysql.user as t2, mysql.user as t3;
|
||||||
|
use test;
|
||||||
|
|
||||||
|
drop table if exists t1;
|
||||||
|
create table t1 (x int);
|
||||||
|
drop table if exists t2;
|
||||||
|
create table t2 (y int);
|
||||||
|
|
||||||
|
drop procedure if exists p1;
|
||||||
|
create definer=root@localhost procedure p1() select * from t1;
|
||||||
|
call p1();
|
||||||
|
drop procedure p1;
|
||||||
|
|
||||||
|
create definer=root@localhost procedure p1() insert into t1 values (3),(5),(7);
|
||||||
|
call p1();
|
||||||
|
|
||||||
|
drop function if exists f1;
|
||||||
|
create definer=root@localhost function f1() returns int return (select count(*) from t1);
|
||||||
|
insert into t2 set y = f1()*10;
|
||||||
|
|
||||||
|
drop view if exists v1;
|
||||||
|
create definer=root@localhost view v1 as select f1();
|
||||||
|
insert into t2 (y) select * from v1;
|
||||||
|
|
||||||
|
create trigger trg1 after insert on t2 for each row insert into t1 values (new.y);
|
||||||
|
insert into t2 values (11), (13);
|
||||||
|
drop procedure p1;
|
||||||
|
drop function f1;
|
||||||
|
drop view v1;
|
||||||
|
@ -264,6 +264,20 @@ select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1,
|
|||||||
str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;
|
str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;
|
||||||
--enable_ps_protocol
|
--enable_ps_protocol
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test of locale dependent date format (WL#2928 Date Translation NRE)
|
||||||
|
#
|
||||||
|
set names latin1;
|
||||||
|
select date_format('2004-01-01','%W (%a), %e %M (%b) %Y');
|
||||||
|
set lc_time_names=ru_RU;
|
||||||
|
set names koi8r;
|
||||||
|
select date_format('2004-01-01','%W (%a), %e %M (%b) %Y');
|
||||||
|
set lc_time_names=de_DE;
|
||||||
|
set names latin1;
|
||||||
|
select date_format('2004-01-01','%W (%a), %e %M (%b) %Y');
|
||||||
|
set names latin1;
|
||||||
|
set lc_time_names=en_US;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #14016
|
# Bug #14016
|
||||||
#
|
#
|
||||||
|
@ -1366,25 +1366,6 @@ drop table federated.t1, federated.t2;
|
|||||||
connection master;
|
connection master;
|
||||||
--enable_parsing
|
--enable_parsing
|
||||||
|
|
||||||
#
|
|
||||||
# Bug #16494: Updates that set a column to NULL fail sometimes
|
|
||||||
#
|
|
||||||
connection slave;
|
|
||||||
create table t1 (id int not null auto_increment primary key, val int);
|
|
||||||
connection master;
|
|
||||||
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
|
||||||
eval create table t1
|
|
||||||
(id int not null auto_increment primary key, val int) engine=federated
|
|
||||||
connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
|
|
||||||
insert into t1 values (1,0),(2,0);
|
|
||||||
update t1 set val = NULL where id = 1;
|
|
||||||
select * from t1;
|
|
||||||
connection slave;
|
|
||||||
select * from t1;
|
|
||||||
drop table t1;
|
|
||||||
connection master;
|
|
||||||
drop table t1;
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Additional test for bug#18437 "Wrong values inserted with a before
|
# Additional test for bug#18437 "Wrong values inserted with a before
|
||||||
# update trigger on NDB table". SQL-layer didn't properly inform
|
# update trigger on NDB table". SQL-layer didn't properly inform
|
||||||
@ -1479,5 +1460,26 @@ drop table federated.t1, federated.t2;
|
|||||||
|
|
||||||
connection slave;
|
connection slave;
|
||||||
drop table federated.t1, federated.t2;
|
drop table federated.t1, federated.t2;
|
||||||
|
#
|
||||||
|
# Bug #16494: Updates that set a column to NULL fail sometimes
|
||||||
|
#
|
||||||
|
connection slave;
|
||||||
|
create table t1 (id int not null auto_increment primary key, val int);
|
||||||
|
connection master;
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval create table t1
|
||||||
|
(id int not null auto_increment primary key, val int) engine=federated
|
||||||
|
connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
|
||||||
|
insert into t1 values (1,0),(2,0);
|
||||||
|
update t1 set val = NULL where id = 1;
|
||||||
|
select * from t1;
|
||||||
|
connection slave;
|
||||||
|
select * from t1;
|
||||||
|
drop table t1;
|
||||||
|
connection master;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
source include/federated_cleanup.inc;
|
source include/federated_cleanup.inc;
|
||||||
|
|
||||||
|
@ -35,4 +35,205 @@ select @a;
|
|||||||
connection con0;
|
connection con0;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
disconnect con1;
|
||||||
|
disconnect con2;
|
||||||
|
disconnect con3;
|
||||||
|
disconnect con4;
|
||||||
|
disconnect con5;
|
||||||
|
|
||||||
|
--echo End of 4.1 tests
|
||||||
|
#
|
||||||
|
# Test 5.* features
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (x int);
|
||||||
|
insert into t1 values (3), (5), (7);
|
||||||
|
create table t2 (y int);
|
||||||
|
|
||||||
|
create user mysqltest1@localhost;
|
||||||
|
grant all privileges on test.* to mysqltest1@localhost;
|
||||||
|
#
|
||||||
|
# Create a simple procedure
|
||||||
|
#
|
||||||
|
set global init_connect="create procedure p1() select * from t1";
|
||||||
|
connect (con1,localhost,mysqltest1,,);
|
||||||
|
connection con1;
|
||||||
|
call p1();
|
||||||
|
drop procedure p1;
|
||||||
|
|
||||||
|
connection con0;
|
||||||
|
disconnect con1;
|
||||||
|
#
|
||||||
|
# Create a multi-result set procedure
|
||||||
|
#
|
||||||
|
set global init_connect="create procedure p1(x int)\
|
||||||
|
begin\
|
||||||
|
select count(*) from t1;\
|
||||||
|
select * from t1;\
|
||||||
|
set @x = x;
|
||||||
|
end";
|
||||||
|
connect (con1,localhost,mysqltest1,,);
|
||||||
|
connection con1;
|
||||||
|
call p1(42);
|
||||||
|
select @x;
|
||||||
|
|
||||||
|
connection con0;
|
||||||
|
disconnect con1;
|
||||||
|
#
|
||||||
|
# Just call it - this will not generate any output
|
||||||
|
#
|
||||||
|
set global init_connect="call p1(4711)";
|
||||||
|
connect (con1,localhost,mysqltest1,,);
|
||||||
|
connection con1;
|
||||||
|
select @x;
|
||||||
|
|
||||||
|
connection con0;
|
||||||
|
disconnect con1;
|
||||||
|
#
|
||||||
|
# Drop the procedure
|
||||||
|
#
|
||||||
|
set global init_connect="drop procedure if exists p1";
|
||||||
|
connect (con1,localhost,mysqltest1,,);
|
||||||
|
connection con1;
|
||||||
|
--error ER_SP_DOES_NOT_EXIST
|
||||||
|
call p1();
|
||||||
|
|
||||||
|
connection con0;
|
||||||
|
disconnect con1;
|
||||||
|
#
|
||||||
|
# Execution of a more complex procedure
|
||||||
|
#
|
||||||
|
delimiter |;
|
||||||
|
create procedure p1(out sum int)
|
||||||
|
begin
|
||||||
|
declare n int default 0;
|
||||||
|
declare c cursor for select * from t1;
|
||||||
|
declare exit handler for not found
|
||||||
|
begin
|
||||||
|
close c;
|
||||||
|
set sum = n;
|
||||||
|
end;
|
||||||
|
|
||||||
|
open c;
|
||||||
|
loop
|
||||||
|
begin
|
||||||
|
declare x int;
|
||||||
|
|
||||||
|
fetch c into x;
|
||||||
|
if x > 3 then
|
||||||
|
set n = n + x;
|
||||||
|
end if;
|
||||||
|
end;
|
||||||
|
end loop;
|
||||||
|
end|
|
||||||
|
delimiter ;|
|
||||||
|
# Call the procedure with a cursor
|
||||||
|
set global init_connect="call p1(@sum)";
|
||||||
|
connect (con1,localhost,mysqltest1,,);
|
||||||
|
connection con1;
|
||||||
|
select @sum;
|
||||||
|
|
||||||
|
connection con0;
|
||||||
|
disconnect con1;
|
||||||
|
drop procedure p1;
|
||||||
|
#
|
||||||
|
# Test Dynamic SQL
|
||||||
|
#
|
||||||
|
delimiter |;
|
||||||
|
create procedure p1(tbl char(10), v int)
|
||||||
|
begin
|
||||||
|
set @s = concat('insert into ', tbl, ' values (?)');
|
||||||
|
set @v = v;
|
||||||
|
prepare stmt1 from @s;
|
||||||
|
execute stmt1 using @v;
|
||||||
|
deallocate prepare stmt1;
|
||||||
|
end|
|
||||||
|
delimiter ;|
|
||||||
|
# Call the procedure with prepared statements
|
||||||
|
set global init_connect="call p1('t1', 11)";
|
||||||
|
connect (con1,localhost,mysqltest1,,);
|
||||||
|
connection con1;
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
connection con0;
|
||||||
|
disconnect con1;
|
||||||
|
drop procedure p1;
|
||||||
|
#
|
||||||
|
# Stored functions
|
||||||
|
#
|
||||||
|
delimiter |;
|
||||||
|
create function f1() returns int
|
||||||
|
begin
|
||||||
|
declare n int;
|
||||||
|
|
||||||
|
select count(*) into n from t1;
|
||||||
|
return n;
|
||||||
|
end|
|
||||||
|
delimiter ;|
|
||||||
|
# Invoke a function
|
||||||
|
set global init_connect="set @x = f1()";
|
||||||
|
connect (con1,localhost,mysqltest1,,);
|
||||||
|
connection con1;
|
||||||
|
select @x;
|
||||||
|
|
||||||
|
connection con0;
|
||||||
|
disconnect con1;
|
||||||
|
#
|
||||||
|
# Create a view
|
||||||
|
#
|
||||||
|
set global init_connect="create view v1 as select f1()";
|
||||||
|
connect (con1,localhost,mysqltest1,,);
|
||||||
|
connection con1;
|
||||||
|
select * from v1;
|
||||||
|
|
||||||
|
connection con0;
|
||||||
|
disconnect con1;
|
||||||
|
#
|
||||||
|
# Drop the view
|
||||||
|
#
|
||||||
|
set global init_connect="drop view v1";
|
||||||
|
connect (con1,localhost,mysqltest1,,);
|
||||||
|
connection con1;
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
select * from v1;
|
||||||
|
|
||||||
|
connection con0;
|
||||||
|
disconnect con1;
|
||||||
|
drop function f1;
|
||||||
|
|
||||||
|
# We can't test "create trigger", since this requires super privileges
|
||||||
|
# in 5.0, but with super privileges, init_connect is not executed.
|
||||||
|
# (However, this can be tested in 5.1)
|
||||||
|
#
|
||||||
|
#set global init_connect="create trigger trg1\
|
||||||
|
# after insert on t2\
|
||||||
|
# for each row\
|
||||||
|
# insert into t1 values (new.y)";
|
||||||
|
#connect (con1,localhost,mysqltest1,,);
|
||||||
|
#connection con1;
|
||||||
|
#insert into t2 values (2), (4);
|
||||||
|
#select * from t1;
|
||||||
|
#
|
||||||
|
#connection con0;
|
||||||
|
#disconnect con1;
|
||||||
|
|
||||||
|
create trigger trg1
|
||||||
|
after insert on t2
|
||||||
|
for each row
|
||||||
|
insert into t1 values (new.y);
|
||||||
|
|
||||||
|
# Invoke trigger
|
||||||
|
set global init_connect="insert into t2 values (13), (17), (19)";
|
||||||
|
connect (con1,localhost,mysqltest1,,);
|
||||||
|
connection con1;
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
connection con0;
|
||||||
|
disconnect con1;
|
||||||
|
|
||||||
|
drop trigger trg1;
|
||||||
|
set global init_connect=default;
|
||||||
|
|
||||||
|
revoke all privileges, grant option from mysqltest1@localhost;
|
||||||
|
drop user mysqltest1@localhost;
|
||||||
|
drop table t1, t2;
|
||||||
|
@ -6,5 +6,15 @@
|
|||||||
# mysql-test/t/init_file-master.opt for the actual test
|
# mysql-test/t/init_file-master.opt for the actual test
|
||||||
#
|
#
|
||||||
|
|
||||||
# End of 4.1 tests
|
--echo ok
|
||||||
echo ok;
|
--echo end of 4.1 tests
|
||||||
|
#
|
||||||
|
# Chec 5.x features
|
||||||
|
#
|
||||||
|
# Expected:
|
||||||
|
# 3, 5, 7, 11, 13
|
||||||
|
select * from t1;
|
||||||
|
# Expected:
|
||||||
|
# 30, 3, 11, 13
|
||||||
|
select * from t2;
|
||||||
|
drop table t1, t2;
|
||||||
|
@ -718,8 +718,6 @@ UPDATE t1 AS ta1,t1 AS ta2 SET ta1.b='aaaaaa',ta2.b='bbbbbb';
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test varchar
|
# Test varchar
|
||||||
#
|
#
|
||||||
@ -817,6 +815,42 @@ alter table t1 enable keys;
|
|||||||
show keys from t1;
|
show keys from t1;
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# Bug#8706 - temporary table with data directory option fails
|
||||||
|
#
|
||||||
|
connect (session1,localhost,root,,);
|
||||||
|
connect (session2,localhost,root,,);
|
||||||
|
|
||||||
|
connection session1;
|
||||||
|
disable_query_log;
|
||||||
|
eval create temporary table t1 (a int) engine=myisam data directory="$MYSQLTEST_VARDIR/tmp" select 9 a;
|
||||||
|
enable_query_log;
|
||||||
|
disable_result_log;
|
||||||
|
show create table t1;
|
||||||
|
enable_result_log;
|
||||||
|
|
||||||
|
connection session2;
|
||||||
|
disable_query_log;
|
||||||
|
eval create temporary table t1 (a int) engine=myisam data directory="$MYSQLTEST_VARDIR/tmp" select 99 a;
|
||||||
|
enable_query_log;
|
||||||
|
disable_result_log;
|
||||||
|
show create table t1;
|
||||||
|
enable_result_log;
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
create table t1 (a int) engine=myisam select 42 a;
|
||||||
|
|
||||||
|
connection session1;
|
||||||
|
select * from t1;
|
||||||
|
disconnect session1;
|
||||||
|
connection session2;
|
||||||
|
select * from t1;
|
||||||
|
disconnect session2;
|
||||||
|
connection default;
|
||||||
|
select * from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
--echo End of 4.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#10056 - PACK_KEYS option take values greater than 1 while creating table
|
# Bug#10056 - PACK_KEYS option take values greater than 1 while creating table
|
||||||
@ -828,6 +862,8 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
|
|||||||
create table t4 (c1 int) engine=myisam pack_keys=2;
|
create table t4 (c1 int) engine=myisam pack_keys=2;
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
|
||||||
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test of key_block_size
|
# Test of key_block_size
|
||||||
#
|
#
|
||||||
@ -890,3 +926,5 @@ drop table t1;
|
|||||||
create table t1 (a int not null, key key_block_size=1024 (a));
|
create table t1 (a int not null, key key_block_size=1024 (a));
|
||||||
--error 1064
|
--error 1064
|
||||||
create table t1 (a int not null, key `a` key_block_size=1024 (a));
|
create table t1 (a int not null, key `a` key_block_size=1024 (a));
|
||||||
|
|
||||||
|
--echo End of 5.1 tests
|
||||||
|
@ -1168,12 +1168,11 @@ insert into t values(5, 51);
|
|||||||
create view v1 as select qty, price, qty*price as value from t;
|
create view v1 as select qty, price, qty*price as value from t;
|
||||||
create view v2 as select qty from v1;
|
create view v2 as select qty from v1;
|
||||||
--echo mysqldump {
|
--echo mysqldump {
|
||||||
--exec $MYSQL_DUMP --compact -F --tab . test
|
--exec $MYSQL_DUMP --compact -F --tab $MYSQLTEST_VARDIR/tmp test
|
||||||
--exec cat v1.sql
|
--exec cat $MYSQLTEST_VARDIR/tmp/v1.sql
|
||||||
--echo } mysqldump {
|
--echo } mysqldump {
|
||||||
--exec cat v2.sql
|
--exec cat $MYSQLTEST_VARDIR/tmp/v2.sql
|
||||||
--echo } mysqldump
|
--echo } mysqldump
|
||||||
--rm v.sql t.sql t.txt
|
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop view v2;
|
drop view v2;
|
||||||
drop table t;
|
drop table t;
|
||||||
|
@ -872,3 +872,65 @@ DROP VIEW test2.t3;
|
|||||||
DROP TABLE test2.t1, test1.t0;
|
DROP TABLE test2.t1, test1.t0;
|
||||||
DROP DATABASE test2;
|
DROP DATABASE test2;
|
||||||
DROP DATABASE test1;
|
DROP DATABASE test1;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#20570: CURRENT_USER() in a VIEW with SQL SECURITY DEFINER
|
||||||
|
# returns invoker name
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
DROP VIEW IF EXISTS v1;
|
||||||
|
DROP VIEW IF EXISTS v2;
|
||||||
|
DROP VIEW IF EXISTS v3;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP FUNCTION IF EXISTS f2;
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE SQL SECURITY DEFINER VIEW v1 AS SELECT CURRENT_USER() AS cu;
|
||||||
|
|
||||||
|
CREATE FUNCTION f1() RETURNS VARCHAR(77) SQL SECURITY INVOKER
|
||||||
|
RETURN CURRENT_USER();
|
||||||
|
CREATE SQL SECURITY DEFINER VIEW v2 AS SELECT f1() AS cu;
|
||||||
|
|
||||||
|
CREATE PROCEDURE p1(OUT cu VARCHAR(77)) SQL SECURITY INVOKER
|
||||||
|
SET cu= CURRENT_USER();
|
||||||
|
delimiter |;
|
||||||
|
CREATE FUNCTION f2() RETURNS VARCHAR(77) SQL SECURITY INVOKER
|
||||||
|
BEGIN
|
||||||
|
DECLARE cu VARCHAR(77);
|
||||||
|
CALL p1(cu);
|
||||||
|
RETURN cu;
|
||||||
|
END|
|
||||||
|
delimiter ;|
|
||||||
|
CREATE SQL SECURITY DEFINER VIEW v3 AS SELECT f2() AS cu;
|
||||||
|
|
||||||
|
CREATE USER mysqltest_u1@localhost;
|
||||||
|
GRANT ALL ON test.* TO mysqltest_u1@localhost;
|
||||||
|
|
||||||
|
connect (conn1, localhost, mysqltest_u1,,);
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo The following tests should all return 1.
|
||||||
|
--echo
|
||||||
|
SELECT CURRENT_USER() = 'mysqltest_u1@localhost';
|
||||||
|
SELECT f1() = 'mysqltest_u1@localhost';
|
||||||
|
CALL p1(@cu);
|
||||||
|
SELECT @cu = 'mysqltest_u1@localhost';
|
||||||
|
SELECT f2() = 'mysqltest_u1@localhost';
|
||||||
|
SELECT cu = 'root@localhost' FROM v1;
|
||||||
|
SELECT cu = 'root@localhost' FROM v2;
|
||||||
|
SELECT cu = 'root@localhost' FROM v3;
|
||||||
|
|
||||||
|
disconnect conn1;
|
||||||
|
connection default;
|
||||||
|
|
||||||
|
DROP VIEW v3;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP VIEW v2;
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP USER mysqltest_u1@localhost;
|
||||||
|
|
||||||
|
# End of 5.0 tests.
|
||||||
|
@ -80,7 +80,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
|
|||||||
mysqld.cc password.c hash_filo.cc hostname.cc \
|
mysqld.cc password.c hash_filo.cc hostname.cc \
|
||||||
set_var.cc sql_parse.cc sql_yacc.yy \
|
set_var.cc sql_parse.cc sql_yacc.yy \
|
||||||
sql_base.cc table.cc sql_select.cc sql_insert.cc \
|
sql_base.cc table.cc sql_select.cc sql_insert.cc \
|
||||||
sql_prepare.cc sql_error.cc \
|
sql_prepare.cc sql_error.cc sql_locale.cc \
|
||||||
sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
|
sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
|
||||||
procedure.cc item_uniq.cc sql_test.cc \
|
procedure.cc item_uniq.cc sql_test.cc \
|
||||||
log.cc log_event.cc init.cc derror.cc sql_acl.cc \
|
log.cc log_event.cc init.cc derror.cc sql_acl.cc \
|
||||||
|
@ -296,12 +296,6 @@ Item *create_func_pow(Item* a, Item *b)
|
|||||||
return new Item_func_pow(a,b);
|
return new Item_func_pow(a,b);
|
||||||
}
|
}
|
||||||
|
|
||||||
Item *create_func_current_user()
|
|
||||||
{
|
|
||||||
current_thd->lex->safe_to_cache_query= 0;
|
|
||||||
return new Item_func_user(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
Item *create_func_radians(Item *a)
|
Item *create_func_radians(Item *a)
|
||||||
{
|
{
|
||||||
return new Item_func_units((char*) "radians",a,M_PI/180,0.0);
|
return new Item_func_units((char*) "radians",a,M_PI/180,0.0);
|
||||||
|
@ -73,7 +73,6 @@ Item *create_func_period_add(Item* a, Item *b);
|
|||||||
Item *create_func_period_diff(Item* a, Item *b);
|
Item *create_func_period_diff(Item* a, Item *b);
|
||||||
Item *create_func_pi(void);
|
Item *create_func_pi(void);
|
||||||
Item *create_func_pow(Item* a, Item *b);
|
Item *create_func_pow(Item* a, Item *b);
|
||||||
Item *create_func_current_user(void);
|
|
||||||
Item *create_func_radians(Item *a);
|
Item *create_func_radians(Item *a);
|
||||||
Item *create_func_release_lock(Item* a);
|
Item *create_func_release_lock(Item* a);
|
||||||
Item *create_func_repeat(Item* a, Item *b);
|
Item *create_func_repeat(Item* a, Item *b);
|
||||||
|
@ -2505,8 +2505,7 @@ void udf_handler::cleanup()
|
|||||||
{
|
{
|
||||||
if (u_d->func_deinit != NULL)
|
if (u_d->func_deinit != NULL)
|
||||||
{
|
{
|
||||||
void (*deinit)(UDF_INIT *) = (void (*)(UDF_INIT*))
|
Udf_func_deinit deinit= u_d->func_deinit;
|
||||||
u_d->func_deinit;
|
|
||||||
(*deinit)(&initid);
|
(*deinit)(&initid);
|
||||||
}
|
}
|
||||||
free_udf(u_d);
|
free_udf(u_d);
|
||||||
@ -2651,9 +2650,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
thd->net.last_error[0]=0;
|
thd->net.last_error[0]=0;
|
||||||
my_bool (*init)(UDF_INIT *, UDF_ARGS *, char *)=
|
Udf_func_init init= u_d->func_init;
|
||||||
(my_bool (*)(UDF_INIT *, UDF_ARGS *, char *))
|
|
||||||
u_d->func_init;
|
|
||||||
if ((error=(uchar) init(&initid, &f_args, thd->net.last_error)))
|
if ((error=(uchar) init(&initid, &f_args, thd->net.last_error)))
|
||||||
{
|
{
|
||||||
my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
|
my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
|
||||||
|
@ -1670,42 +1670,51 @@ String *Item_func_database::val_str(String *str)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make USER() replicate properly (currently it is replicated to "")
|
|
||||||
|
|
||||||
String *Item_func_user::val_str(String *str)
|
/*
|
||||||
|
TODO: make USER() replicate properly (currently it is replicated to "")
|
||||||
|
*/
|
||||||
|
bool Item_func_user::init(const char *user, const char *host)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
THD *thd=current_thd;
|
|
||||||
CHARSET_INFO *cs= system_charset_info;
|
|
||||||
const char *host, *user;
|
|
||||||
uint res_length;
|
|
||||||
|
|
||||||
if (is_current)
|
|
||||||
{
|
|
||||||
user= thd->security_ctx->priv_user;
|
|
||||||
host= thd->security_ctx->priv_host;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
user= thd->main_security_ctx.user;
|
|
||||||
host= thd->main_security_ctx.host_or_ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For system threads (e.g. replication SQL thread) user may be empty
|
// For system threads (e.g. replication SQL thread) user may be empty
|
||||||
if (!user)
|
if (user)
|
||||||
return &my_empty_string;
|
{
|
||||||
res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
|
CHARSET_INFO *cs= str_value.charset();
|
||||||
|
uint res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
|
||||||
|
|
||||||
if (str->alloc(res_length))
|
if (str_value.alloc(res_length))
|
||||||
{
|
{
|
||||||
null_value=1;
|
null_value=1;
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
res_length=cs->cset->snprintf(cs, (char*)str->ptr(), res_length, "%s@%s",
|
|
||||||
user, host);
|
res_length=cs->cset->snprintf(cs, (char*)str_value.ptr(), res_length,
|
||||||
str->length(res_length);
|
"%s@%s", user, host);
|
||||||
str->set_charset(cs);
|
str_value.length(res_length);
|
||||||
return str;
|
str_value.mark_as_const();
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_func_user::fix_fields(THD *thd, Item **ref)
|
||||||
|
{
|
||||||
|
return (Item_func_sysconst::fix_fields(thd, ref) ||
|
||||||
|
init(thd->main_security_ctx.user,
|
||||||
|
thd->main_security_ctx.host_or_ip));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_func_current_user::fix_fields(THD *thd, Item **ref)
|
||||||
|
{
|
||||||
|
if (Item_func_sysconst::fix_fields(thd, ref))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
Security_context *ctx= (context->security_ctx
|
||||||
|
? context->security_ctx : thd->security_ctx);
|
||||||
|
return init(ctx->priv_user, ctx->priv_host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -393,21 +393,40 @@ public:
|
|||||||
|
|
||||||
class Item_func_user :public Item_func_sysconst
|
class Item_func_user :public Item_func_sysconst
|
||||||
{
|
{
|
||||||
bool is_current;
|
protected:
|
||||||
|
bool init (const char *user, const char *host);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item_func_user(bool is_current_arg)
|
Item_func_user()
|
||||||
:Item_func_sysconst(), is_current(is_current_arg) {}
|
{
|
||||||
String *val_str(String *);
|
str_value.set("", 0, system_charset_info);
|
||||||
|
}
|
||||||
|
String *val_str(String *)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
return (null_value ? 0 : &str_value);
|
||||||
|
}
|
||||||
|
bool fix_fields(THD *thd, Item **ref);
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec()
|
||||||
{
|
{
|
||||||
max_length= ((USERNAME_LENGTH + HOSTNAME_LENGTH + 1) *
|
max_length= ((USERNAME_LENGTH + HOSTNAME_LENGTH + 1) *
|
||||||
system_charset_info->mbmaxlen);
|
system_charset_info->mbmaxlen);
|
||||||
}
|
}
|
||||||
const char *func_name() const
|
const char *func_name() const { return "user"; }
|
||||||
{ return is_current ? "current_user" : "user"; }
|
const char *fully_qualified_func_name() const { return "user()"; }
|
||||||
const char *fully_qualified_func_name() const
|
};
|
||||||
{ return is_current ? "current_user()" : "user()"; }
|
|
||||||
|
|
||||||
|
class Item_func_current_user :public Item_func_user
|
||||||
|
{
|
||||||
|
Name_resolution_context *context;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Item_func_current_user(Name_resolution_context *context_arg)
|
||||||
|
: context(context_arg) {}
|
||||||
|
bool fix_fields(THD *thd, Item **ref);
|
||||||
|
const char *func_name() const { return "current_user"; }
|
||||||
|
const char *fully_qualified_func_name() const { return "current_user()"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,25 +30,6 @@
|
|||||||
/* Day number for Dec 31st, 9999 */
|
/* Day number for Dec 31st, 9999 */
|
||||||
#define MAX_DAY_NUMBER 3652424L
|
#define MAX_DAY_NUMBER 3652424L
|
||||||
|
|
||||||
static const char *month_names[]=
|
|
||||||
{
|
|
||||||
"January", "February", "March", "April", "May", "June", "July", "August",
|
|
||||||
"September", "October", "November", "December", NullS
|
|
||||||
};
|
|
||||||
|
|
||||||
TYPELIB month_names_typelib=
|
|
||||||
{ array_elements(month_names)-1,"", month_names, NULL };
|
|
||||||
|
|
||||||
static const char *day_names[]=
|
|
||||||
{
|
|
||||||
"Monday", "Tuesday", "Wednesday",
|
|
||||||
"Thursday", "Friday", "Saturday" ,"Sunday", NullS
|
|
||||||
};
|
|
||||||
|
|
||||||
TYPELIB day_names_typelib=
|
|
||||||
{ array_elements(day_names)-1,"", day_names, NULL};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
OPTIMIZATION TODO:
|
OPTIMIZATION TODO:
|
||||||
- Replace the switch with a function that should be called for each
|
- Replace the switch with a function that should be called for each
|
||||||
@ -223,8 +204,12 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
|||||||
val= tmp;
|
val= tmp;
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
|
if ((l_time->month= check_word(my_locale_en_US.month_names,
|
||||||
|
val, val_end, &val)) <= 0)
|
||||||
|
goto err;
|
||||||
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
if ((l_time->month= check_word(&month_names_typelib,
|
if ((l_time->month= check_word(my_locale_en_US.ab_month_names,
|
||||||
val, val_end, &val)) <= 0)
|
val, val_end, &val)) <= 0)
|
||||||
goto err;
|
goto err;
|
||||||
break;
|
break;
|
||||||
@ -299,8 +284,11 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
|||||||
|
|
||||||
/* Exotic things */
|
/* Exotic things */
|
||||||
case 'W':
|
case 'W':
|
||||||
|
if ((weekday= check_word(my_locale_en_US.day_names, val, val_end, &val)) <= 0)
|
||||||
|
goto err;
|
||||||
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
if ((weekday= check_word(&day_names_typelib, val, val_end, &val)) <= 0)
|
if ((weekday= check_word(my_locale_en_US.ab_day_names, val, val_end, &val)) <= 0)
|
||||||
goto err;
|
goto err;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
@ -502,9 +490,16 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
|
|||||||
uint weekday;
|
uint weekday;
|
||||||
ulong length;
|
ulong length;
|
||||||
const char *ptr, *end;
|
const char *ptr, *end;
|
||||||
|
MY_LOCALE *locale;
|
||||||
|
THD *thd= current_thd;
|
||||||
|
char buf[STRING_BUFFER_USUAL_SIZE];
|
||||||
|
String tmp(buf, sizeof(buf), thd->variables.character_set_results);
|
||||||
|
uint errors= 0;
|
||||||
|
|
||||||
|
tmp.length(0);
|
||||||
str->length(0);
|
str->length(0);
|
||||||
str->set_charset(&my_charset_bin);
|
str->set_charset(&my_charset_bin);
|
||||||
|
locale = thd->variables.lc_time_names;
|
||||||
|
|
||||||
if (l_time->neg)
|
if (l_time->neg)
|
||||||
str->append('-');
|
str->append('-');
|
||||||
@ -520,26 +515,38 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
|
|||||||
case 'M':
|
case 'M':
|
||||||
if (!l_time->month)
|
if (!l_time->month)
|
||||||
return 1;
|
return 1;
|
||||||
str->append(month_names[l_time->month-1]);
|
tmp.copy(locale->month_names->type_names[l_time->month-1],
|
||||||
|
strlen(locale->month_names->type_names[l_time->month-1]),
|
||||||
|
system_charset_info, tmp.charset(), &errors);
|
||||||
|
str->append(tmp.ptr(), tmp.length());
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
if (!l_time->month)
|
if (!l_time->month)
|
||||||
return 1;
|
return 1;
|
||||||
str->append(month_names[l_time->month-1],3);
|
tmp.copy(locale->ab_month_names->type_names[l_time->month-1],
|
||||||
|
strlen(locale->ab_month_names->type_names[l_time->month-1]),
|
||||||
|
system_charset_info, tmp.charset(), &errors);
|
||||||
|
str->append(tmp.ptr(), tmp.length());
|
||||||
break;
|
break;
|
||||||
case 'W':
|
case 'W':
|
||||||
if (type == MYSQL_TIMESTAMP_TIME)
|
if (type == MYSQL_TIMESTAMP_TIME)
|
||||||
return 1;
|
return 1;
|
||||||
weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
|
weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
|
||||||
l_time->day),0);
|
l_time->day),0);
|
||||||
str->append(day_names[weekday]);
|
tmp.copy(locale->day_names->type_names[weekday],
|
||||||
|
strlen(locale->day_names->type_names[weekday]),
|
||||||
|
system_charset_info, tmp.charset(), &errors);
|
||||||
|
str->append(tmp.ptr(), tmp.length());
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
if (type == MYSQL_TIMESTAMP_TIME)
|
if (type == MYSQL_TIMESTAMP_TIME)
|
||||||
return 1;
|
return 1;
|
||||||
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
|
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
|
||||||
l_time->day),0);
|
l_time->day),0);
|
||||||
str->append(day_names[weekday],3);
|
tmp.copy(locale->ab_day_names->type_names[weekday],
|
||||||
|
strlen(locale->ab_day_names->type_names[weekday]),
|
||||||
|
system_charset_info, tmp.charset(), &errors);
|
||||||
|
str->append(tmp.ptr(), tmp.length());
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
if (type == MYSQL_TIMESTAMP_TIME)
|
if (type == MYSQL_TIMESTAMP_TIME)
|
||||||
@ -872,6 +879,7 @@ String* Item_func_monthname::val_str(String* str)
|
|||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
const char *month_name;
|
const char *month_name;
|
||||||
uint month= (uint) val_int();
|
uint month= (uint) val_int();
|
||||||
|
THD *thd= current_thd;
|
||||||
|
|
||||||
if (null_value || !month)
|
if (null_value || !month)
|
||||||
{
|
{
|
||||||
@ -879,7 +887,7 @@ String* Item_func_monthname::val_str(String* str)
|
|||||||
return (String*) 0;
|
return (String*) 0;
|
||||||
}
|
}
|
||||||
null_value=0;
|
null_value=0;
|
||||||
month_name= month_names[month-1];
|
month_name= thd->variables.lc_time_names->month_names->type_names[month-1];
|
||||||
str->set(month_name, strlen(month_name), system_charset_info);
|
str->set(month_name, strlen(month_name), system_charset_info);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@ -1004,11 +1012,12 @@ String* Item_func_dayname::val_str(String* str)
|
|||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
uint weekday=(uint) val_int(); // Always Item_func_daynr()
|
uint weekday=(uint) val_int(); // Always Item_func_daynr()
|
||||||
const char *name;
|
const char *name;
|
||||||
|
THD *thd= current_thd;
|
||||||
|
|
||||||
if (null_value)
|
if (null_value)
|
||||||
return (String*) 0;
|
return (String*) 0;
|
||||||
|
|
||||||
name= day_names[weekday];
|
name= thd->variables.lc_time_names->day_names->type_names[weekday];
|
||||||
str->set(name, strlen(name), system_charset_info);
|
str->set(name, strlen(name), system_charset_info);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@ -1652,7 +1661,7 @@ uint Item_func_date_format::format_length(const String *format)
|
|||||||
switch(*++ptr) {
|
switch(*++ptr) {
|
||||||
case 'M': /* month, textual */
|
case 'M': /* month, textual */
|
||||||
case 'W': /* day (of the week), textual */
|
case 'W': /* day (of the week), textual */
|
||||||
size += 9;
|
size += 64; /* large for UTF8 locale data */
|
||||||
break;
|
break;
|
||||||
case 'D': /* day (of the month), numeric plus english suffix */
|
case 'D': /* day (of the month), numeric plus english suffix */
|
||||||
case 'Y': /* year, numeric, 4 digits */
|
case 'Y': /* year, numeric, 4 digits */
|
||||||
@ -1662,6 +1671,8 @@ uint Item_func_date_format::format_length(const String *format)
|
|||||||
break;
|
break;
|
||||||
case 'a': /* locale's abbreviated weekday name (Sun..Sat) */
|
case 'a': /* locale's abbreviated weekday name (Sun..Sat) */
|
||||||
case 'b': /* locale's abbreviated month name (Jan.Dec) */
|
case 'b': /* locale's abbreviated month name (Jan.Dec) */
|
||||||
|
size += 32; /* large for UTF8 locale data */
|
||||||
|
break;
|
||||||
case 'j': /* day of year (001..366) */
|
case 'j': /* day of year (001..366) */
|
||||||
size += 3;
|
size += 3;
|
||||||
break;
|
break;
|
||||||
|
@ -101,6 +101,23 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
|
|||||||
extern CHARSET_INFO *system_charset_info, *files_charset_info ;
|
extern CHARSET_INFO *system_charset_info, *files_charset_info ;
|
||||||
extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct my_locale_st
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const char *description;
|
||||||
|
const bool is_ascii;
|
||||||
|
TYPELIB *month_names;
|
||||||
|
TYPELIB *ab_month_names;
|
||||||
|
TYPELIB *day_names;
|
||||||
|
TYPELIB *ab_day_names;
|
||||||
|
} MY_LOCALE;
|
||||||
|
|
||||||
|
extern MY_LOCALE my_locale_en_US;
|
||||||
|
extern MY_LOCALE *my_locales[];
|
||||||
|
|
||||||
|
MY_LOCALE *my_locale_by_name(const char *name);
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
Configuration parameters
|
Configuration parameters
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -588,6 +605,7 @@ struct Query_cache_query_flags
|
|||||||
ulong sql_mode;
|
ulong sql_mode;
|
||||||
ulong max_sort_length;
|
ulong max_sort_length;
|
||||||
ulong group_concat_max_len;
|
ulong group_concat_max_len;
|
||||||
|
MY_LOCALE *lc_time_names;
|
||||||
};
|
};
|
||||||
#define QUERY_CACHE_FLAGS_SIZE sizeof(Query_cache_query_flags)
|
#define QUERY_CACHE_FLAGS_SIZE sizeof(Query_cache_query_flags)
|
||||||
#include "sql_cache.h"
|
#include "sql_cache.h"
|
||||||
|
@ -109,7 +109,6 @@ extern ulong ndb_report_thresh_binlog_mem_usage;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static HASH system_variable_hash;
|
static HASH system_variable_hash;
|
||||||
const char *bool_type_names[]= { "OFF", "ON", NullS };
|
const char *bool_type_names[]= { "OFF", "ON", NullS };
|
||||||
TYPELIB bool_typelib=
|
TYPELIB bool_typelib=
|
||||||
@ -631,6 +630,9 @@ static sys_var_thd_ha_rows sys_select_limit("sql_select_limit",
|
|||||||
static sys_var_timestamp sys_timestamp("timestamp");
|
static sys_var_timestamp sys_timestamp("timestamp");
|
||||||
static sys_var_last_insert_id sys_last_insert_id("last_insert_id");
|
static sys_var_last_insert_id sys_last_insert_id("last_insert_id");
|
||||||
static sys_var_last_insert_id sys_identity("identity");
|
static sys_var_last_insert_id sys_identity("identity");
|
||||||
|
|
||||||
|
static sys_var_thd_lc_time_names sys_lc_time_names("lc_time_names");
|
||||||
|
|
||||||
static sys_var_insert_id sys_insert_id("insert_id");
|
static sys_var_insert_id sys_insert_id("insert_id");
|
||||||
static sys_var_readonly sys_error_count("error_count",
|
static sys_var_readonly sys_error_count("error_count",
|
||||||
OPT_SESSION,
|
OPT_SESSION,
|
||||||
@ -871,6 +873,7 @@ SHOW_VAR init_vars[]= {
|
|||||||
{"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
|
{"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
|
||||||
{"large_page_size", (char*) &opt_large_page_size, SHOW_INT},
|
{"large_page_size", (char*) &opt_large_page_size, SHOW_INT},
|
||||||
{"large_pages", (char*) &opt_large_pages, SHOW_MY_BOOL},
|
{"large_pages", (char*) &opt_large_pages, SHOW_MY_BOOL},
|
||||||
|
{sys_lc_time_names.name, (char*) &sys_lc_time_names, SHOW_SYS},
|
||||||
{sys_license.name, (char*) &sys_license, SHOW_SYS},
|
{sys_license.name, (char*) &sys_license, SHOW_SYS},
|
||||||
{sys_local_infile.name, (char*) &sys_local_infile, SHOW_SYS},
|
{sys_local_infile.name, (char*) &sys_local_infile, SHOW_SYS},
|
||||||
#ifdef HAVE_MLOCKALL
|
#ifdef HAVE_MLOCKALL
|
||||||
@ -3011,6 +3014,40 @@ byte *sys_var_max_user_conn::value_ptr(THD *thd, enum_var_type type,
|
|||||||
return (byte*) &(max_user_connections);
|
return (byte*) &(max_user_connections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var)
|
||||||
|
{
|
||||||
|
char *locale_str =var->value->str_value.c_ptr();
|
||||||
|
MY_LOCALE *locale_match= my_locale_by_name(locale_str);
|
||||||
|
|
||||||
|
if (locale_match == NULL)
|
||||||
|
{
|
||||||
|
my_printf_error(ER_UNKNOWN_ERROR,
|
||||||
|
"Unknown locale: '%s'", MYF(0), locale_str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
var->save_result.locale_value= locale_match;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool sys_var_thd_lc_time_names::update(THD *thd, set_var *var)
|
||||||
|
{
|
||||||
|
thd->variables.lc_time_names= var->save_result.locale_value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte *sys_var_thd_lc_time_names::value_ptr(THD *thd, enum_var_type type,
|
||||||
|
LEX_STRING *base)
|
||||||
|
{
|
||||||
|
return (byte *)(thd->variables.lc_time_names->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type)
|
||||||
|
{
|
||||||
|
thd->variables.lc_time_names = &my_locale_en_US;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Functions to update thd->options bits
|
Functions to update thd->options bits
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
class sys_var;
|
class sys_var;
|
||||||
class set_var;
|
class set_var;
|
||||||
typedef struct system_variables SV;
|
typedef struct system_variables SV;
|
||||||
|
typedef struct my_locale_st MY_LOCALE;
|
||||||
|
|
||||||
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
|
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
|
||||||
|
|
||||||
typedef int (*sys_check_func)(THD *, set_var *);
|
typedef int (*sys_check_func)(THD *, set_var *);
|
||||||
@ -903,6 +905,25 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class sys_var_thd_lc_time_names :public sys_var_thd
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sys_var_thd_lc_time_names(const char *name_arg):
|
||||||
|
sys_var_thd(name_arg)
|
||||||
|
{}
|
||||||
|
bool check(THD *thd, set_var *var);
|
||||||
|
SHOW_TYPE type() { return SHOW_CHAR; }
|
||||||
|
bool check_update_type(Item_result type)
|
||||||
|
{
|
||||||
|
return type != STRING_RESULT; /* Only accept strings */
|
||||||
|
}
|
||||||
|
bool check_default(enum_var_type type) { return 0; }
|
||||||
|
bool update(THD *thd, set_var *var);
|
||||||
|
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
||||||
|
virtual void set_default(THD *thd, enum_var_type type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class sys_var_event_scheduler :public sys_var_long_ptr
|
class sys_var_event_scheduler :public sys_var_long_ptr
|
||||||
{
|
{
|
||||||
/* We need a derived class only to have a warn_deprecated() */
|
/* We need a derived class only to have a warn_deprecated() */
|
||||||
@ -964,6 +985,7 @@ public:
|
|||||||
handlerton *hton;
|
handlerton *hton;
|
||||||
DATE_TIME_FORMAT *date_time_format;
|
DATE_TIME_FORMAT *date_time_format;
|
||||||
Time_zone *time_zone;
|
Time_zone *time_zone;
|
||||||
|
MY_LOCALE *locale_value;
|
||||||
} save_result;
|
} save_result;
|
||||||
LEX_STRING base; /* for structs */
|
LEX_STRING base; /* for structs */
|
||||||
|
|
||||||
|
@ -814,6 +814,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
|
|||||||
flags.time_zone= thd->variables.time_zone;
|
flags.time_zone= thd->variables.time_zone;
|
||||||
flags.sql_mode= thd->variables.sql_mode;
|
flags.sql_mode= thd->variables.sql_mode;
|
||||||
flags.max_sort_length= thd->variables.max_sort_length;
|
flags.max_sort_length= thd->variables.max_sort_length;
|
||||||
|
flags.lc_time_names= thd->variables.lc_time_names;
|
||||||
flags.group_concat_max_len= thd->variables.group_concat_max_len;
|
flags.group_concat_max_len= thd->variables.group_concat_max_len;
|
||||||
DBUG_PRINT("qcache", ("long %d, 4.1: %d, more results %d, pkt_nr: %d, \
|
DBUG_PRINT("qcache", ("long %d, 4.1: %d, more results %d, pkt_nr: %d, \
|
||||||
CS client: %u, CS result: %u, CS conn: %u, limit: %lu, TZ: 0x%lx, \
|
CS client: %u, CS result: %u, CS conn: %u, limit: %lu, TZ: 0x%lx, \
|
||||||
@ -1049,6 +1050,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
|
|||||||
flags.sql_mode= thd->variables.sql_mode;
|
flags.sql_mode= thd->variables.sql_mode;
|
||||||
flags.max_sort_length= thd->variables.max_sort_length;
|
flags.max_sort_length= thd->variables.max_sort_length;
|
||||||
flags.group_concat_max_len= thd->variables.group_concat_max_len;
|
flags.group_concat_max_len= thd->variables.group_concat_max_len;
|
||||||
|
flags.lc_time_names= thd->variables.lc_time_names;
|
||||||
DBUG_PRINT("qcache", ("long %d, 4.1: %d, more results %d, pkt_nr: %d, \
|
DBUG_PRINT("qcache", ("long %d, 4.1: %d, more results %d, pkt_nr: %d, \
|
||||||
CS client: %u, CS result: %u, CS conn: %u, limit: %lu, TZ: 0x%lx, \
|
CS client: %u, CS result: %u, CS conn: %u, limit: %lu, TZ: 0x%lx, \
|
||||||
sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
|
sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
|
||||||
|
@ -350,6 +350,7 @@ void THD::init(void)
|
|||||||
reset_current_stmt_binlog_row_based();
|
reset_current_stmt_binlog_row_based();
|
||||||
#endif /*HAVE_ROW_BASED_REPLICATION*/
|
#endif /*HAVE_ROW_BASED_REPLICATION*/
|
||||||
bzero((char *) &status_var, sizeof(status_var));
|
bzero((char *) &status_var, sizeof(status_var));
|
||||||
|
variables.lc_time_names = &my_locale_en_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2040,6 +2041,7 @@ void Security_context::init()
|
|||||||
{
|
{
|
||||||
host= user= priv_user= ip= 0;
|
host= user= priv_user= ip= 0;
|
||||||
host_or_ip= "connecting host";
|
host_or_ip= "connecting host";
|
||||||
|
priv_host[0]= '\0';
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
db_access= NO_ACCESS;
|
db_access= NO_ACCESS;
|
||||||
#endif
|
#endif
|
||||||
|
@ -266,6 +266,9 @@ struct system_variables
|
|||||||
CHARSET_INFO *collation_database;
|
CHARSET_INFO *collation_database;
|
||||||
CHARSET_INFO *collation_connection;
|
CHARSET_INFO *collation_connection;
|
||||||
|
|
||||||
|
/* Locale Support */
|
||||||
|
MY_LOCALE *lc_time_names;
|
||||||
|
|
||||||
Time_zone *time_zone;
|
Time_zone *time_zone;
|
||||||
|
|
||||||
/* DATE, DATETIME and TIME formats */
|
/* DATE, DATETIME and TIME formats */
|
||||||
|
@ -428,7 +428,7 @@ extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
|
|||||||
bool mysql_multi_delete_prepare(THD *thd)
|
bool mysql_multi_delete_prepare(THD *thd)
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxilliary_table_list.first;
|
TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxiliary_table_list.first;
|
||||||
TABLE_LIST *target_tbl;
|
TABLE_LIST *target_tbl;
|
||||||
DBUG_ENTER("mysql_multi_delete_prepare");
|
DBUG_ENTER("mysql_multi_delete_prepare");
|
||||||
|
|
||||||
|
@ -937,7 +937,7 @@ typedef struct st_lex : public Query_tables_list
|
|||||||
List<Name_resolution_context> context_stack;
|
List<Name_resolution_context> context_stack;
|
||||||
List<LEX_STRING> db_list;
|
List<LEX_STRING> db_list;
|
||||||
|
|
||||||
SQL_LIST proc_list, auxilliary_table_list, save_list;
|
SQL_LIST proc_list, auxiliary_table_list, save_list;
|
||||||
create_field *last_field;
|
create_field *last_field;
|
||||||
Item_sum *in_sum_func;
|
Item_sum *in_sum_func;
|
||||||
udf_func udf;
|
udf_func udf;
|
||||||
|
1607
sql/sql_locale.cc
Normal file
1607
sql/sql_locale.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -1298,6 +1298,12 @@ pthread_handler_t handle_bootstrap(void *arg)
|
|||||||
thd->security_ctx->priv_user=
|
thd->security_ctx->priv_user=
|
||||||
thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
|
thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
|
||||||
thd->security_ctx->priv_host[0]=0;
|
thd->security_ctx->priv_host[0]=0;
|
||||||
|
/*
|
||||||
|
Make the "client" handle multiple results. This is necessary
|
||||||
|
to enable stored procedures with SELECTs and Dynamic SQL
|
||||||
|
in init-file.
|
||||||
|
*/
|
||||||
|
thd->client_capabilities|= CLIENT_MULTI_RESULTS;
|
||||||
|
|
||||||
buff= (char*) thd->net.buff;
|
buff= (char*) thd->net.buff;
|
||||||
thd->init_for_queries();
|
thd->init_for_queries();
|
||||||
@ -3502,7 +3508,7 @@ end_with_restore_list:
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
TABLE_LIST *aux_tables=
|
TABLE_LIST *aux_tables=
|
||||||
(TABLE_LIST *)thd->lex->auxilliary_table_list.first;
|
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
|
||||||
multi_delete *result;
|
multi_delete *result;
|
||||||
|
|
||||||
if (!thd->locked_tables &&
|
if (!thd->locked_tables &&
|
||||||
@ -6024,7 +6030,7 @@ void mysql_init_multi_delete(LEX *lex)
|
|||||||
mysql_init_select(lex);
|
mysql_init_select(lex);
|
||||||
lex->select_lex.select_limit= 0;
|
lex->select_lex.select_limit= 0;
|
||||||
lex->unit.select_limit_cnt= HA_POS_ERROR;
|
lex->unit.select_limit_cnt= HA_POS_ERROR;
|
||||||
lex->select_lex.table_list.save_and_clear(&lex->auxilliary_table_list);
|
lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
|
||||||
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->query_tables= 0;
|
lex->query_tables= 0;
|
||||||
lex->query_tables_last= &lex->query_tables;
|
lex->query_tables_last= &lex->query_tables;
|
||||||
@ -7443,7 +7449,7 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
|
|||||||
{
|
{
|
||||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||||
TABLE_LIST *aux_tables=
|
TABLE_LIST *aux_tables=
|
||||||
(TABLE_LIST *)thd->lex->auxilliary_table_list.first;
|
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
|
||||||
TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
|
TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
|
||||||
DBUG_ENTER("multi_delete_precheck");
|
DBUG_ENTER("multi_delete_precheck");
|
||||||
|
|
||||||
@ -7496,7 +7502,7 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
|
|||||||
|
|
||||||
lex->table_count= 0;
|
lex->table_count= 0;
|
||||||
|
|
||||||
for (target_tbl= (TABLE_LIST *)lex->auxilliary_table_list.first;
|
for (target_tbl= (TABLE_LIST *)lex->auxiliary_table_list.first;
|
||||||
target_tbl; target_tbl= target_tbl->next_local)
|
target_tbl; target_tbl= target_tbl->next_local)
|
||||||
{
|
{
|
||||||
lex->table_count++;
|
lex->table_count++;
|
||||||
|
@ -57,7 +57,7 @@ static char *init_syms(udf_func *tmp, char *nm)
|
|||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
if (!((tmp->func= dlsym(tmp->dlhandle, tmp->name.str))))
|
if (!((tmp->func= (Udf_func_any) dlsym(tmp->dlhandle, tmp->name.str))))
|
||||||
return tmp->name.str;
|
return tmp->name.str;
|
||||||
|
|
||||||
end=strmov(nm,tmp->name.str);
|
end=strmov(nm,tmp->name.str);
|
||||||
@ -65,18 +65,18 @@ static char *init_syms(udf_func *tmp, char *nm)
|
|||||||
if (tmp->type == UDFTYPE_AGGREGATE)
|
if (tmp->type == UDFTYPE_AGGREGATE)
|
||||||
{
|
{
|
||||||
(void)strmov(end, "_clear");
|
(void)strmov(end, "_clear");
|
||||||
if (!((tmp->func_clear= dlsym(tmp->dlhandle, nm))))
|
if (!((tmp->func_clear= (Udf_func_clear) dlsym(tmp->dlhandle, nm))))
|
||||||
return nm;
|
return nm;
|
||||||
(void)strmov(end, "_add");
|
(void)strmov(end, "_add");
|
||||||
if (!((tmp->func_add= dlsym(tmp->dlhandle, nm))))
|
if (!((tmp->func_add= (Udf_func_add) dlsym(tmp->dlhandle, nm))))
|
||||||
return nm;
|
return nm;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) strmov(end,"_deinit");
|
(void) strmov(end,"_deinit");
|
||||||
tmp->func_deinit= dlsym(tmp->dlhandle, nm);
|
tmp->func_deinit= (Udf_func_deinit) dlsym(tmp->dlhandle, nm);
|
||||||
|
|
||||||
(void) strmov(end,"_init");
|
(void) strmov(end,"_init");
|
||||||
tmp->func_init= dlsym(tmp->dlhandle, nm);
|
tmp->func_init= (Udf_func_init) dlsym(tmp->dlhandle, nm);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
to prefent loading "udf" from, e.g. libc.so
|
to prefent loading "udf" from, e.g. libc.so
|
||||||
|
@ -23,6 +23,15 @@
|
|||||||
|
|
||||||
enum Item_udftype {UDFTYPE_FUNCTION=1,UDFTYPE_AGGREGATE};
|
enum Item_udftype {UDFTYPE_FUNCTION=1,UDFTYPE_AGGREGATE};
|
||||||
|
|
||||||
|
typedef void (*Udf_func_clear)(UDF_INIT *, uchar *, uchar *);
|
||||||
|
typedef void (*Udf_func_add)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *);
|
||||||
|
typedef void (*Udf_func_deinit)(UDF_INIT*);
|
||||||
|
typedef my_bool (*Udf_func_init)(UDF_INIT *, UDF_ARGS *, char *);
|
||||||
|
typedef void (*Udf_func_any)();
|
||||||
|
typedef double (*Udf_func_double)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *);
|
||||||
|
typedef longlong (*Udf_func_longlong)(UDF_INIT *, UDF_ARGS *, uchar *,
|
||||||
|
uchar *);
|
||||||
|
|
||||||
typedef struct st_udf_func
|
typedef struct st_udf_func
|
||||||
{
|
{
|
||||||
LEX_STRING name;
|
LEX_STRING name;
|
||||||
@ -30,11 +39,11 @@ typedef struct st_udf_func
|
|||||||
Item_udftype type;
|
Item_udftype type;
|
||||||
char *dl;
|
char *dl;
|
||||||
void *dlhandle;
|
void *dlhandle;
|
||||||
void *func;
|
Udf_func_any func;
|
||||||
void *func_init;
|
Udf_func_init func_init;
|
||||||
void *func_deinit;
|
Udf_func_deinit func_deinit;
|
||||||
void *func_clear;
|
Udf_func_clear func_clear;
|
||||||
void *func_add;
|
Udf_func_add func_add;
|
||||||
ulong usage_count;
|
ulong usage_count;
|
||||||
} udf_func;
|
} udf_func;
|
||||||
|
|
||||||
@ -76,8 +85,7 @@ class udf_handler :public Sql_alloc
|
|||||||
*null_value=1;
|
*null_value=1;
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
double (*func)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)=
|
Udf_func_double func= (Udf_func_double) u_d->func;
|
||||||
(double (*)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)) u_d->func;
|
|
||||||
double tmp=func(&initid, &f_args, &is_null, &error);
|
double tmp=func(&initid, &f_args, &is_null, &error);
|
||||||
if (is_null || error)
|
if (is_null || error)
|
||||||
{
|
{
|
||||||
@ -95,8 +103,7 @@ class udf_handler :public Sql_alloc
|
|||||||
*null_value=1;
|
*null_value=1;
|
||||||
return LL(0);
|
return LL(0);
|
||||||
}
|
}
|
||||||
longlong (*func)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)=
|
Udf_func_longlong func= (Udf_func_longlong) u_d->func;
|
||||||
(longlong (*)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)) u_d->func;
|
|
||||||
longlong tmp=func(&initid, &f_args, &is_null, &error);
|
longlong tmp=func(&initid, &f_args, &is_null, &error);
|
||||||
if (is_null || error)
|
if (is_null || error)
|
||||||
{
|
{
|
||||||
@ -110,8 +117,7 @@ class udf_handler :public Sql_alloc
|
|||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
is_null= 0;
|
is_null= 0;
|
||||||
void (*func)(UDF_INIT *, uchar *, uchar *)=
|
Udf_func_clear func= u_d->func_clear;
|
||||||
(void (*)(UDF_INIT *, uchar *, uchar *)) u_d->func_clear;
|
|
||||||
func(&initid, &is_null, &error);
|
func(&initid, &is_null, &error);
|
||||||
}
|
}
|
||||||
void add(my_bool *null_value)
|
void add(my_bool *null_value)
|
||||||
@ -121,8 +127,7 @@ class udf_handler :public Sql_alloc
|
|||||||
*null_value=1;
|
*null_value=1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void (*func)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)=
|
Udf_func_add func= u_d->func_add;
|
||||||
(void (*)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)) u_d->func_add;
|
|
||||||
func(&initid, &f_args, &is_null, &error);
|
func(&initid, &f_args, &is_null, &error);
|
||||||
*null_value= (my_bool) (is_null || error);
|
*null_value= (my_bool) (is_null || error);
|
||||||
}
|
}
|
||||||
|
@ -6159,7 +6159,10 @@ simple_expr:
|
|||||||
Lex->safe_to_cache_query=0;
|
Lex->safe_to_cache_query=0;
|
||||||
}
|
}
|
||||||
| CURRENT_USER optional_braces
|
| CURRENT_USER optional_braces
|
||||||
{ $$= create_func_current_user(); }
|
{
|
||||||
|
$$= new Item_func_current_user(Lex->current_context());
|
||||||
|
Lex->safe_to_cache_query= 0;
|
||||||
|
}
|
||||||
| DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')'
|
| DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')'
|
||||||
{ $$= new Item_date_add_interval($3,$5,$6,0); }
|
{ $$= new Item_date_add_interval($3,$5,$6,0); }
|
||||||
| DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')'
|
| DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')'
|
||||||
@ -6518,7 +6521,7 @@ simple_expr:
|
|||||||
| UNIX_TIMESTAMP '(' expr ')'
|
| UNIX_TIMESTAMP '(' expr ')'
|
||||||
{ $$= new Item_func_unix_timestamp($3); }
|
{ $$= new Item_func_unix_timestamp($3); }
|
||||||
| USER '(' ')'
|
| USER '(' ')'
|
||||||
{ $$= new Item_func_user(FALSE); Lex->safe_to_cache_query=0; }
|
{ $$= new Item_func_user(); Lex->safe_to_cache_query=0; }
|
||||||
| UTC_DATE_SYM optional_braces
|
| UTC_DATE_SYM optional_braces
|
||||||
{ $$= new Item_func_curdate_utc(); Lex->safe_to_cache_query=0;}
|
{ $$= new Item_func_curdate_utc(); Lex->safe_to_cache_query=0;}
|
||||||
| UTC_TIME_SYM optional_braces
|
| UTC_TIME_SYM optional_braces
|
||||||
|
@ -574,9 +574,22 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
{
|
{
|
||||||
char *iext= strrchr(ci->index_file_name, '.');
|
char *iext= strrchr(ci->index_file_name, '.');
|
||||||
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
|
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
|
||||||
|
if (options & HA_OPTION_TMP_TABLE)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
/* chop off the table name, tempory tables use generated name */
|
||||||
|
if ((path= strrchr(ci->index_file_name, FN_LIBCHAR)))
|
||||||
|
*path= '\0';
|
||||||
|
fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
|
||||||
|
MY_REPLACE_DIR | MY_UNPACK_FILENAME |
|
||||||
|
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
|
fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
|
||||||
MY_UNPACK_FILENAME| (have_iext ? MY_REPLACE_EXT :MY_APPEND_EXT));
|
MY_UNPACK_FILENAME | (have_iext ? MY_REPLACE_EXT :
|
||||||
|
MY_APPEND_EXT));
|
||||||
|
}
|
||||||
fn_format(linkname, name, "", MI_NAME_IEXT,
|
fn_format(linkname, name, "", MI_NAME_IEXT,
|
||||||
MY_UNPACK_FILENAME|MY_APPEND_EXT);
|
MY_UNPACK_FILENAME|MY_APPEND_EXT);
|
||||||
linkname_ptr=linkname;
|
linkname_ptr=linkname;
|
||||||
@ -639,9 +652,23 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
char *dext= strrchr(ci->data_file_name, '.');
|
char *dext= strrchr(ci->data_file_name, '.');
|
||||||
int have_dext= dext && !strcmp(dext, MI_NAME_DEXT);
|
int have_dext= dext && !strcmp(dext, MI_NAME_DEXT);
|
||||||
|
|
||||||
|
if (options & HA_OPTION_TMP_TABLE)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
/* chop off the table name, tempory tables use generated name */
|
||||||
|
if ((path= strrchr(ci->data_file_name, FN_LIBCHAR)))
|
||||||
|
*path= '\0';
|
||||||
|
fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
|
||||||
|
MY_REPLACE_DIR | MY_UNPACK_FILENAME |
|
||||||
|
(have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
|
fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
|
||||||
MY_UNPACK_FILENAME |
|
MY_UNPACK_FILENAME |
|
||||||
(have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
|
(have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
|
||||||
|
}
|
||||||
|
|
||||||
fn_format(linkname, name, "",MI_NAME_DEXT,
|
fn_format(linkname, name, "",MI_NAME_DEXT,
|
||||||
MY_UNPACK_FILENAME | MY_APPEND_EXT);
|
MY_UNPACK_FILENAME | MY_APPEND_EXT);
|
||||||
linkname_ptr=linkname;
|
linkname_ptr=linkname;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user