Commit 2697018c authored by ingo@mysql.com's avatar ingo@mysql.com

Merge mysql.com:/home/mydev/mysql-5.1

into  mysql.com:/home/mydev/mysql-5.1-aid
parents 745dd7fd a663acb1
...@@ -465,8 +465,7 @@ sub mtr_kill_leftovers () { ...@@ -465,8 +465,7 @@ sub mtr_kill_leftovers () {
if ( kill(0, @pids) ) # Check if some left if ( kill(0, @pids) ) # Check if some left
{ {
# FIXME maybe just mtr_warning() ? mtr_warning("can't kill process(es) " . join(" ", @pids));
mtr_error("can't kill process(es) " . join(" ", @pids));
} }
} }
} }
...@@ -479,7 +478,7 @@ sub mtr_kill_leftovers () { ...@@ -479,7 +478,7 @@ sub mtr_kill_leftovers () {
{ {
if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) ) if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) )
{ {
mtr_error("can't kill old mysqld holding port $srv->{'port'}"); mtr_warning("can't kill old mysqld holding port $srv->{'port'}");
} }
} }
} }
......
...@@ -719,3 +719,11 @@ lily ...@@ -719,3 +719,11 @@ lily
river river
drop table t1; drop table t1;
deallocate prepare stmt; deallocate prepare stmt;
create table t1(a blob, b text charset utf8, c text charset ucs2);
select data_type, character_octet_length, character_maximum_length
from information_schema.columns where table_name='t1';
data_type character_octet_length character_maximum_length
blob 65535 65535
text 65535 65535
text 65535 32767
drop table t1;
...@@ -106,7 +106,6 @@ drop event if exists event3; ...@@ -106,7 +106,6 @@ drop event if exists event3;
Warnings: Warnings:
Note 1305 Event event3 does not exist Note 1305 Event event3 does not exist
create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand());
set max_allowed_packet=128000000;
select count(*) from t_event3; select count(*) from t_event3;
count(*) count(*)
0 0
...@@ -232,6 +231,9 @@ Db Name Definer Type Execute at Interval value Interval field Starts Ends Status ...@@ -232,6 +231,9 @@ Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
CREATE TABLE event_like LIKE mysql.event; CREATE TABLE event_like LIKE mysql.event;
INSERT INTO event_like SELECT * FROM mysql.event; INSERT INTO event_like SELECT * FROM mysql.event;
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default ''; ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default '';
SHOW CREATE TABLE mysql.event; SHOW CREATE TABLE mysql.event;
Table Create Table Table Create Table
......
CREATE DATABASE IF NOT EXISTS events_test;
USE events_test;
CREATE TABLE table_1(a int);
CREATE TABLE table_2(a int);
CREATE TABLE table_3(a int);
CREATE TABLE table_4(a int);
SET GLOBAL event_scheduler=1;
CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1);
CREATE EVENT start_n_end
ON SCHEDULE EVERY 1 SECOND
ENDS NOW() + INTERVAL 6 SECOND
ON COMPLETION PRESERVE
DO INSERT INTO table_2 VALUES(1);
CREATE EVENT only_one_time ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_3 VALUES(1);
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_4 VALUES(1);
SELECT IF(SUM(a) >= 4, 'OK', 'ERROR') FROM table_1;
IF(SUM(a) >= 4, 'OK', 'ERROR')
OK
SELECT IF(SUM(a) >= 5, 'OK', 'ERROR') FROM table_2;
IF(SUM(a) >= 5, 'OK', 'ERROR')
OK
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_3;
IF(SUM(a) > 0, 'OK', 'ERROR')
OK
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_4;
IF(SUM(a) > 0, 'OK', 'ERROR')
OK
DROP EVENT two_sec;
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR')
OK
SELECT IF(LAST_EXECUTED-ENDS < 2, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
IF(LAST_EXECUTED-ENDS < 2, 'OK', 'ERROR')
OK
DROP EVENT start_n_end;
"Already dropped because ended. Therefore an error."
DROP EVENT only_one_time;
ERROR HY000: Unknown event 'only_one_time'
"Already dropped because ended. Therefore an error."
DROP EVENT two_time;
ERROR HY000: Unknown event 'two_time'
DROP TABLE table_1;
DROP TABLE table_2;
DROP TABLE table_3;
DROP TABLE table_4;
DROP DATABASE events_test;
...@@ -626,3 +626,8 @@ latin1 ...@@ -626,3 +626,8 @@ latin1
latin1 latin1
drop table t1, t2, t3; drop table t1, t2, t3;
set names default; set names default;
create table t1 (c1 varchar(10), c2 int);
select charset(group_concat(c1 order by c2)) from t1;
charset(group_concat(c1 order by c2))
latin1
drop table t1;
...@@ -360,6 +360,42 @@ extract(SECOND FROM "1999-01-02 10:11:12") ...@@ -360,6 +360,42 @@ extract(SECOND FROM "1999-01-02 10:11:12")
select extract(MONTH FROM "2001-02-00"); select extract(MONTH FROM "2001-02-00");
extract(MONTH FROM "2001-02-00") extract(MONTH FROM "2001-02-00")
2 2
SELECT EXTRACT(QUARTER FROM '2004-01-15') AS quarter;
quarter
1
SELECT EXTRACT(QUARTER FROM '2004-02-15') AS quarter;
quarter
1
SELECT EXTRACT(QUARTER FROM '2004-03-15') AS quarter;
quarter
1
SELECT EXTRACT(QUARTER FROM '2004-04-15') AS quarter;
quarter
2
SELECT EXTRACT(QUARTER FROM '2004-05-15') AS quarter;
quarter
2
SELECT EXTRACT(QUARTER FROM '2004-06-15') AS quarter;
quarter
2
SELECT EXTRACT(QUARTER FROM '2004-07-15') AS quarter;
quarter
3
SELECT EXTRACT(QUARTER FROM '2004-08-15') AS quarter;
quarter
3
SELECT EXTRACT(QUARTER FROM '2004-09-15') AS quarter;
quarter
3
SELECT EXTRACT(QUARTER FROM '2004-10-15') AS quarter;
quarter
4
SELECT EXTRACT(QUARTER FROM '2004-11-15') AS quarter;
quarter
4
SELECT EXTRACT(QUARTER FROM '2004-12-15') AS quarter;
quarter
4
SELECT "1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND; SELECT "1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND;
"1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND "1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND
1968-01-20 03:14:08 1968-01-20 03:14:08
......
...@@ -1084,14 +1084,6 @@ select 1 from (select 1 from test.t1) a; ...@@ -1084,14 +1084,6 @@ select 1 from (select 1 from test.t1) a;
1 1
use test; use test;
drop table t1; drop table t1;
create table t1(a blob, b text charset utf8, c text charset ucs2);
select data_type, character_octet_length, character_maximum_length
from information_schema.columns where table_name='t1';
data_type character_octet_length character_maximum_length
blob 65535 65535
text 65535 65535
text 65535 32767
drop table t1;
create table t1 (f1 int(11)); create table t1 (f1 int(11));
create view v1 as select * from t1; create view v1 as select * from t1;
drop table t1; drop table t1;
......
...@@ -455,3 +455,11 @@ execute stmt using @param1; ...@@ -455,3 +455,11 @@ execute stmt using @param1;
select utext from t1 where utext like '%%'; select utext from t1 where utext like '%%';
drop table t1; drop table t1;
deallocate prepare stmt; deallocate prepare stmt;
#
# Bug #14290: character_maximum_length for text fields
#
create table t1(a blob, b text charset utf8, c text charset ucs2);
select data_type, character_octet_length, character_maximum_length
from information_schema.columns where table_name='t1';
drop table t1;
...@@ -101,7 +101,6 @@ set global event_scheduler = 0; ...@@ -101,7 +101,6 @@ set global event_scheduler = 0;
create table t_event3 (a int, b float); create table t_event3 (a int, b float);
drop event if exists event3; drop event if exists event3;
create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand());
set max_allowed_packet=128000000;
select count(*) from t_event3; select count(*) from t_event3;
drop event event3; drop event event3;
drop table t_event3; drop table t_event3;
...@@ -202,6 +201,9 @@ CREATE TABLE event_like LIKE mysql.event; ...@@ -202,6 +201,9 @@ CREATE TABLE event_like LIKE mysql.event;
INSERT INTO event_like SELECT * FROM mysql.event; INSERT INTO event_like SELECT * FROM mysql.event;
#sleep a bit or we won't catch the change of time #sleep a bit or we won't catch the change of time
--sleep 1 --sleep 1
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
--error ER_CANNOT_LOAD_FROM_TABLE
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default ''; ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default '';
#wait a bit or we won't see the difference because of seconds resolution #wait a bit or we won't see the difference because of seconds resolution
--sleep 1 --sleep 1
...@@ -220,6 +222,7 @@ ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default ''; ...@@ -220,6 +222,7 @@ ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--sleep 1 --sleep 1
ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default ''; ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default '';
--sleep 1
--error ER_CANNOT_LOAD_FROM_TABLE --error ER_CANNOT_LOAD_FROM_TABLE
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--sleep 1 --sleep 1
...@@ -412,7 +415,8 @@ select 1; ...@@ -412,7 +415,8 @@ select 1;
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space'; select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
drop event white_space; drop event white_space;
create event white_space on schedule every 10 hour disable do create event white_space on schedule every 10 hour disable do
select 2;
select 2;
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space'; select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
drop event white_space; drop event white_space;
create event white_space on schedule every 10 hour disable do select 3; create event white_space on schedule every 10 hour disable do select 3;
...@@ -422,7 +426,7 @@ drop event white_space; ...@@ -422,7 +426,7 @@ drop event white_space;
# END: BUG #17453: Creating Event crash the server # END: BUG #17453: Creating Event crash the server
# #
# ##set global event_scheduler=1;
# Bug#17403 "Events: packets out of order with show create event" # Bug#17403 "Events: packets out of order with show create event"
# #
create event e1 on schedule every 1 year do set @a = 5; create event e1 on schedule every 1 year do set @a = 5;
...@@ -436,7 +440,7 @@ drop event e1; ...@@ -436,7 +440,7 @@ drop event e1;
##select get_lock("test_lock3", 20); ##select get_lock("test_lock3", 20);
##create event закачка on schedule every 10 hour do select get_lock("test_lock3", 20); ##create event закачка on schedule every 10 hour do select get_lock("test_lock3", 20);
##select sleep(2); ##select sleep(2);
##select /*7*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; ##show processlist;
##drop event закачка; ##drop event закачка;
##select release_lock("test_lock3"); ##select release_lock("test_lock3");
...@@ -446,13 +450,14 @@ drop event e1; ...@@ -446,13 +450,14 @@ drop event e1;
##select get_lock("test_lock4", 20); ##select get_lock("test_lock4", 20);
##create event закачка4 on schedule every 1 second do select get_lock("test_lock4", 20); ##create event закачка4 on schedule every 1 second do select get_lock("test_lock4", 20);
##select sleep(3); ##select sleep(3);
##select /*8*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; ##--replace_column 1 # 6 #
##drop event закачка4; ##drop event закачка4;
##select release_lock("test_lock4"); ##select release_lock("test_lock4");
##set global event_scheduler=0; ##set global event_scheduler=0;
##select sleep(2); ##select sleep(2);
##select /*9*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; ##--replace_column 1 # 6 #
##select count(*) from mysql.event; ##select count(*) from mysql.event;
drop database events_test; drop database events_test;
CREATE DATABASE IF NOT EXISTS events_test;
USE events_test;
CREATE TABLE table_1(a int);
CREATE TABLE table_2(a int);
CREATE TABLE table_3(a int);
CREATE TABLE table_4(a int);
SET GLOBAL event_scheduler=1;
CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1);
CREATE EVENT start_n_end
ON SCHEDULE EVERY 1 SECOND
ENDS NOW() + INTERVAL 6 SECOND
ON COMPLETION PRESERVE
DO INSERT INTO table_2 VALUES(1);
--sleep 5
CREATE EVENT only_one_time ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_3 VALUES(1);
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_4 VALUES(1);
--sleep 5
SELECT IF(SUM(a) >= 4, 'OK', 'ERROR') FROM table_1;
SELECT IF(SUM(a) >= 5, 'OK', 'ERROR') FROM table_2;
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_3;
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_4;
DROP EVENT two_sec;
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
SELECT IF(LAST_EXECUTED-ENDS < 2, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
DROP EVENT start_n_end;
--echo "Already dropped because ended. Therefore an error."
--error ER_EVENT_DOES_NOT_EXIST
DROP EVENT only_one_time;
--echo "Already dropped because ended. Therefore an error."
--error ER_EVENT_DOES_NOT_EXIST
DROP EVENT two_time;
DROP TABLE table_1;
DROP TABLE table_2;
DROP TABLE table_3;
DROP TABLE table_4;
DROP DATABASE events_test;
...@@ -414,3 +414,11 @@ select charset(a) from t2; ...@@ -414,3 +414,11 @@ select charset(a) from t2;
select charset(a) from t3; select charset(a) from t3;
drop table t1, t2, t3; drop table t1, t2, t3;
set names default; set names default;
#
# Bug#18281 group_concat changes charset to binary
#
create table t1 (c1 varchar(10), c2 int);
select charset(group_concat(c1 order by c2)) from t1;
drop table t1;
...@@ -139,6 +139,24 @@ select extract(MINUTE_SECOND FROM "10:11:12"); ...@@ -139,6 +139,24 @@ select extract(MINUTE_SECOND FROM "10:11:12");
select extract(SECOND FROM "1999-01-02 10:11:12"); select extract(SECOND FROM "1999-01-02 10:11:12");
select extract(MONTH FROM "2001-02-00"); select extract(MONTH FROM "2001-02-00");
#
# test EXTRACT QUARTER (Bug #18100)
#
SELECT EXTRACT(QUARTER FROM '2004-01-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-02-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-03-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-04-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-05-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-06-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-07-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-08-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-09-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-10-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-11-15') AS quarter;
SELECT EXTRACT(QUARTER FROM '2004-12-15') AS quarter;
# #
# Test big intervals (Bug #3498) # Test big intervals (Bug #3498)
# #
......
...@@ -742,15 +742,6 @@ select 1 from (select 1 from test.t1) a; ...@@ -742,15 +742,6 @@ select 1 from (select 1 from test.t1) a;
use test; use test;
drop table t1; drop table t1;
#
# Bug #14290: character_maximum_length for text fields
#
create table t1(a blob, b text charset utf8, c text charset ucs2);
select data_type, character_octet_length, character_maximum_length
from information_schema.columns where table_name='t1';
drop table t1;
# #
# Bug#14476 `information_schema`.`TABLES`.`TABLE_TYPE` with empty value # Bug#14476 `information_schema`.`TABLES`.`TABLE_TYPE` with empty value
# #
......
...@@ -2,5 +2,6 @@ ...@@ -2,5 +2,6 @@
# By JBM 2006-02-14 Test wrapping to # # By JBM 2006-02-14 Test wrapping to #
# Share test code between engine tests # # Share test code between engine tests #
######################################### #########################################
--source include/have_ndb.inc
let $engine_type=NDB; let $engine_type=NDB;
-- source extra/rpl_tests/rpl_delete_no_where.test -- source extra/rpl_tests/rpl_delete_no_where.test
AUTHORS file example for a plugin
ChangeLog file example for a plugin
#Makefile.am example for a plugin
pkglibdir=$(libdir)/mysql
INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include
noinst_LTLIBRARIES= mypluglib.la noinst_LTLIBRARIES= mypluglib.la
#pkglib_LTLIBRARIES= mypluglib.la
mypluglib_la_SOURCES= plugin_example.c mypluglib_la_SOURCES= plugin_example.c
mypluglib_la_LDFLAGS= -module -rpath $(pkglibdir) mypluglib_la_LDFLAGS= -module -rpath $(pkglibdir)
NEWS file example for a plugin
README file example for a plugin
# configure.in example for a plugin
AC_INIT(plugin_example, 0.1)
AM_INIT_AUTOMAKE
AC_PROG_LIBTOOL
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
...@@ -1051,13 +1051,6 @@ evex_load_and_compile_event(THD * thd, sp_name *spn, LEX_STRING definer, ...@@ -1051,13 +1051,6 @@ evex_load_and_compile_event(THD * thd, sp_name *spn, LEX_STRING definer,
thd->restore_backup_open_tables_state(&backup); thd->restore_backup_open_tables_state(&backup);
if (ret) if (ret)
goto done; goto done;
/*
allocate on evex_mem_root. if you call without evex_mem_root
then sphead will not be cleared!
*/
if ((ret= ett->compile(thd, &evex_mem_root)))
goto done;
ett->compute_next_execution_time(); ett->compute_next_execution_time();
if (use_lock) if (use_lock)
......
...@@ -42,6 +42,8 @@ pthread_mutex_t LOCK_event_arrays, // mutex for when working with t ...@@ -42,6 +42,8 @@ pthread_mutex_t LOCK_event_arrays, // mutex for when working with t
LOCK_workers_count, // mutex for when inc/dec uint workers_count LOCK_workers_count, // mutex for when inc/dec uint workers_count
LOCK_evex_running; // mutes for managing bool evex_is_running LOCK_evex_running; // mutes for managing bool evex_is_running
static pthread_mutex_t LOCK_evex_main_thread; // mutex for when working with the queue
bool scheduler_main_thread_running= false;
bool evex_is_running= false; bool evex_is_running= false;
...@@ -111,6 +113,7 @@ evex_init_mutexes() ...@@ -111,6 +113,7 @@ evex_init_mutexes()
pthread_mutex_init(&LOCK_event_arrays, MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_event_arrays, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&LOCK_workers_count, MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_workers_count, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&LOCK_evex_running, MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_evex_running, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&LOCK_evex_main_thread, MY_MUTEX_INIT_FAST);
event_executor_running_global_var= opt_event_executor; event_executor_running_global_var= opt_event_executor;
} }
...@@ -241,6 +244,7 @@ shutdown_events() ...@@ -241,6 +244,7 @@ shutdown_events()
pthread_mutex_destroy(&LOCK_event_arrays); pthread_mutex_destroy(&LOCK_event_arrays);
pthread_mutex_destroy(&LOCK_workers_count); pthread_mutex_destroy(&LOCK_workers_count);
pthread_mutex_destroy(&LOCK_evex_running); pthread_mutex_destroy(&LOCK_evex_running);
pthread_mutex_destroy(&LOCK_evex_main_thread);
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -351,6 +355,7 @@ executor_wait_till_next_event_exec(THD *thd) ...@@ -351,6 +355,7 @@ executor_wait_till_next_event_exec(THD *thd)
t2sleep= evex_time_diff(&et->execute_at, &time_now); t2sleep= evex_time_diff(&et->execute_at, &time_now);
VOID(pthread_mutex_unlock(&LOCK_event_arrays)); VOID(pthread_mutex_unlock(&LOCK_event_arrays));
t2sleep*=20;
DBUG_PRINT("evex main thread",("unlocked LOCK_event_arrays")); DBUG_PRINT("evex main thread",("unlocked LOCK_event_arrays"));
if (t2sleep > 0) if (t2sleep > 0)
{ {
...@@ -366,7 +371,7 @@ executor_wait_till_next_event_exec(THD *thd) ...@@ -366,7 +371,7 @@ executor_wait_till_next_event_exec(THD *thd)
modified)) modified))
{ {
DBUG_PRINT("evex main thread",("will sleep a bit more.")); DBUG_PRINT("evex main thread",("will sleep a bit more."));
my_sleep(1000000); my_sleep(50000);
} }
DBUG_PRINT("info",("saved_modified=%llu current=%llu", modified, DBUG_PRINT("info",("saved_modified=%llu current=%llu", modified,
evex_queue_num_elements(EVEX_EQ_NAME)? evex_queue_num_elements(EVEX_EQ_NAME)?
...@@ -407,10 +412,23 @@ event_executor_main(void *arg) ...@@ -407,10 +412,23 @@ event_executor_main(void *arg)
THD *thd; /* needs to be first for thread_stack */ THD *thd; /* needs to be first for thread_stack */
uint i=0, j=0; uint i=0, j=0;
my_ulonglong cnt= 0; my_ulonglong cnt= 0;
DBUG_ENTER("event_executor_main"); DBUG_ENTER("event_executor_main");
DBUG_PRINT("event_executor_main", ("EVEX thread started")); DBUG_PRINT("event_executor_main", ("EVEX thread started"));
pthread_mutex_lock(&LOCK_evex_main_thread);
if (!scheduler_main_thread_running)
scheduler_main_thread_running= true;
else
{
DBUG_PRINT("event_executor_main", ("already running. thd_id=%d",
evex_main_thread_id));
pthread_mutex_unlock(&LOCK_evex_main_thread);
my_thread_end();
pthread_exit(0);
DBUG_RETURN(0); // Can't return anything here
}
pthread_mutex_unlock(&LOCK_evex_main_thread);
/* init memory root */ /* init memory root */
init_alloc_root(&evex_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); init_alloc_root(&evex_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
...@@ -489,7 +507,7 @@ event_executor_main(void *arg) ...@@ -489,7 +507,7 @@ event_executor_main(void *arg)
if (!evex_queue_num_elements(EVEX_EQ_NAME)) if (!evex_queue_num_elements(EVEX_EQ_NAME))
{ {
my_sleep(1000000);// sleep 1s my_sleep(100000);// sleep 0.1s
continue; continue;
} }
...@@ -652,12 +670,17 @@ finish: ...@@ -652,12 +670,17 @@ finish:
err_no_thd: err_no_thd:
VOID(pthread_mutex_lock(&LOCK_evex_running)); VOID(pthread_mutex_lock(&LOCK_evex_running));
evex_is_running= false; evex_is_running= false;
event_executor_running_global_var= false;
VOID(pthread_mutex_unlock(&LOCK_evex_running)); VOID(pthread_mutex_unlock(&LOCK_evex_running));
free_root(&evex_mem_root, MYF(0)); free_root(&evex_mem_root, MYF(0));
sql_print_information("SCHEDULER: Stopped."); sql_print_information("SCHEDULER: Stopped.");
#ifndef DBUG_FAULTY_THR #ifndef DBUG_FAULTY_THR
pthread_mutex_lock(&LOCK_evex_main_thread);
scheduler_main_thread_running= false;
pthread_mutex_unlock(&LOCK_evex_main_thread);
my_thread_end(); my_thread_end();
pthread_exit(0); pthread_exit(0);
#endif #endif
......
This diff is collapsed.
...@@ -3249,7 +3249,10 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) ...@@ -3249,7 +3249,10 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref)
} }
if (agg_item_charsets(collation, func_name(), if (agg_item_charsets(collation, func_name(),
args, arg_count, MY_COLL_ALLOW_CONV)) args,
/* skip charset aggregation for order columns */
arg_count - arg_count_order,
MY_COLL_ALLOW_CONV))
return 1; return 1;
result.set_charset(collation.collation); result.set_charset(collation.collation);
......
...@@ -772,81 +772,6 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, ...@@ -772,81 +772,6 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
} }
/*
Calculate difference between two datetime values as seconds + microseconds.
SYNOPSIS
calc_time_diff()
l_time1 - TIME/DATE/DATETIME value
l_time2 - TIME/DATE/DATETIME value
l_sign - 1 absolute values are substracted,
-1 absolute values are added.
seconds_out - Out parameter where difference between
l_time1 and l_time2 in seconds is stored.
microseconds_out- Out parameter where microsecond part of difference
between l_time1 and l_time2 is stored.
NOTE
This function calculates difference between l_time1 and l_time2 absolute
values. So one should set l_sign and correct result if he want to take
signs into account (i.e. for TIME values).
RETURN VALUES
Returns sign of difference.
1 means negative result
0 means positive result
*/
static bool calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign,
longlong *seconds_out, long *microseconds_out)
{
long days;
bool neg;
longlong microseconds;
/*
We suppose that if first argument is MYSQL_TIMESTAMP_TIME
the second argument should be TIMESTAMP_TIME also.
We should check it before calc_time_diff call.
*/
if (l_time1->time_type == MYSQL_TIMESTAMP_TIME) // Time value
days= (long)l_time1->day - l_sign * (long)l_time2->day;
else
{
days= calc_daynr((uint) l_time1->year,
(uint) l_time1->month,
(uint) l_time1->day);
if (l_time2->time_type == MYSQL_TIMESTAMP_TIME)
days-= l_sign * (long)l_time2->day;
else
days-= l_sign*calc_daynr((uint) l_time2->year,
(uint) l_time2->month,
(uint) l_time2->day);
}
microseconds= ((longlong)days*LL(86400) +
(longlong)(l_time1->hour*3600L +
l_time1->minute*60L +
l_time1->second) -
l_sign*(longlong)(l_time2->hour*3600L +
l_time2->minute*60L +
l_time2->second)) * LL(1000000) +
(longlong)l_time1->second_part -
l_sign*(longlong)l_time2->second_part;
neg= 0;
if (microseconds < 0)
{
microseconds= -microseconds;
neg= 1;
}
*seconds_out= microseconds/1000000L;
*microseconds_out= (long) (microseconds%1000000L);
return neg;
}
longlong Item_func_period_add::val_int() longlong Item_func_period_add::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
...@@ -2031,16 +1956,13 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date) ...@@ -2031,16 +1956,13 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
INTERVAL interval; INTERVAL interval;
if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE) || if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE) ||
get_interval_value(args[1],int_type,&value,&interval)) get_interval_value(args[1], int_type, &value, &interval))
goto null_date; return (null_value=1);
if (date_sub_interval) if (date_sub_interval)
interval.neg = !interval.neg; interval.neg = !interval.neg;
return (null_value= date_add_interval(ltime, int_type, interval)); return (null_value= date_add_interval(ltime, int_type, interval));
null_date:
return (null_value=1);
} }
...@@ -2168,7 +2090,7 @@ longlong Item_extract::val_int() ...@@ -2168,7 +2090,7 @@ longlong Item_extract::val_int()
switch (int_type) { switch (int_type) {
case INTERVAL_YEAR: return ltime.year; case INTERVAL_YEAR: return ltime.year;
case INTERVAL_YEAR_MONTH: return ltime.year*100L+ltime.month; case INTERVAL_YEAR_MONTH: return ltime.year*100L+ltime.month;
case INTERVAL_QUARTER: return ltime.month/3 + 1; case INTERVAL_QUARTER: return (ltime.month+2)/3;
case INTERVAL_MONTH: return ltime.month; case INTERVAL_MONTH: return ltime.month;
case INTERVAL_WEEK: case INTERVAL_WEEK:
{ {
......
...@@ -396,6 +396,7 @@ static SYMBOL symbols[] = { ...@@ -396,6 +396,7 @@ static SYMBOL symbols[] = {
{ "PASSWORD", SYM(PASSWORD)}, { "PASSWORD", SYM(PASSWORD)},
{ "PHASE", SYM(PHASE_SYM)}, { "PHASE", SYM(PHASE_SYM)},
{ "PLUGIN", SYM(PLUGIN_SYM)}, { "PLUGIN", SYM(PLUGIN_SYM)},
{ "PLUGINS", SYM(PLUGINS_SYM)},
{ "POINT", SYM(POINT_SYM)}, { "POINT", SYM(POINT_SYM)},
{ "POLYGON", SYM(POLYGON)}, { "POLYGON", SYM(POLYGON)},
{ "PRECISION", SYM(PRECISION)}, { "PRECISION", SYM(PRECISION)},
......
...@@ -1549,6 +1549,8 @@ void make_truncated_value_warning(THD *thd, const char *str_val, ...@@ -1549,6 +1549,8 @@ void make_truncated_value_warning(THD *thd, const char *str_val,
const char *field_name); const char *field_name);
bool date_add_interval(TIME *ltime, interval_type int_type, INTERVAL interval); bool date_add_interval(TIME *ltime, interval_type int_type, INTERVAL interval);
bool calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign,
longlong *seconds_out, long *microseconds_out);
extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type, extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
const char *format_str, const char *format_str,
......
...@@ -123,8 +123,11 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) ...@@ -123,8 +123,11 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
If the storage manager of 'tl' gives exact row count, compute the total If the storage manager of 'tl' gives exact row count, compute the total
number of rows. If there are no outer table dependencies, this count number of rows. If there are no outer table dependencies, this count
may be used as the real count. may be used as the real count.
Schema tables are filled after this function is invoked, so we can't
get row count
*/ */
if (tl->table->file->table_flags() & HA_NOT_EXACT_COUNT) if ((tl->table->file->table_flags() & HA_NOT_EXACT_COUNT) ||
tl->schema_table)
{ {
is_exact_count= FALSE; is_exact_count= FALSE;
count= 1; // ensure count != 0 count= 1; // ensure count != 0
...@@ -149,31 +152,15 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) ...@@ -149,31 +152,15 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
switch (item_sum->sum_func()) { switch (item_sum->sum_func()) {
case Item_sum::COUNT_FUNC: case Item_sum::COUNT_FUNC:
/* /*
If the expr in count(expr) can never be null we can change this If the expr in COUNT(expr) can never be null we can change this
to the number of rows in the tables if this number is exact and to the number of rows in the tables if this number is exact and
there are no outer joins. there are no outer joins.
*/ */
if (!conds && !((Item_sum_count*) item)->args[0]->maybe_null && if (!conds && !((Item_sum_count*) item)->args[0]->maybe_null &&
!outer_tables && is_exact_count) !outer_tables && is_exact_count)
{ {
longlong count= 1; ((Item_sum_count*) item)->make_const(count);
TABLE_LIST *table; recalc_const_item= 1;
for (table= tables; table; table= table->next_leaf)
{
if (outer_tables || (table->table->file->table_flags() &
HA_NOT_EXACT_COUNT) || table->schema_table)
{
const_result= 0; // Can't optimize left join
break;
}
tables->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
count*= table->table->file->records;
}
if (!table)
{
((Item_sum_count*) item)->make_const(count);
recalc_const_item= 1;
}
} }
else else
const_result= 0; const_result= 0;
......
...@@ -3980,7 +3980,7 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) ...@@ -3980,7 +3980,7 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0))) if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0)))
DBUG_RETURN(0); DBUG_RETURN(0);
//->field[0] is EVENT_CATALOG and is by default NULL /* ->field[0] is EVENT_CATALOG and is by default NULL */
sch_table->field[1]->store(et.dbname.str, et.dbname.length, scs); sch_table->field[1]->store(et.dbname.str, et.dbname.length, scs);
sch_table->field[2]->store(et.name.str, et.name.length, scs); sch_table->field[2]->store(et.name.str, et.name.length, scs);
...@@ -4000,12 +4000,9 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) ...@@ -4000,12 +4000,9 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
if (et.expression) if (et.expression)
{ {
String show_str; String show_str;
//type /* type */
sch_table->field[5]->store(STRING_WITH_LEN("RECURRING"), scs); sch_table->field[5]->store(STRING_WITH_LEN("RECURRING"), scs);
/* execute_at */
sch_table->field[6]->set_null();
/* interval_value */
//interval_type
if (event_reconstruct_interval_expression(&show_str, et.interval, if (event_reconstruct_interval_expression(&show_str, et.interval,
et.expression)) et.expression))
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -4058,9 +4055,10 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) ...@@ -4058,9 +4055,10 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
sch_table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); sch_table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
if (et.last_executed.year) if (et.last_executed.year)
{
sch_table->field[16]->set_notnull();
sch_table->field[16]->store_time(&et.last_executed,MYSQL_TIMESTAMP_DATETIME); sch_table->field[16]->store_time(&et.last_executed,MYSQL_TIMESTAMP_DATETIME);
else }
sch_table->field[16]->set_null();
sch_table->field[17]->store(et.comment.str, et.comment.length, scs); sch_table->field[17]->store(et.comment.str, et.comment.length, scs);
......
...@@ -501,6 +501,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -501,6 +501,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token PARAM_MARKER %token PARAM_MARKER
%token PHASE_SYM %token PHASE_SYM
%token PLUGIN_SYM %token PLUGIN_SYM
%token PLUGINS_SYM
%token POINTFROMTEXT %token POINTFROMTEXT
%token POINT_SYM %token POINT_SYM
%token POLYFROMTEXT %token POLYFROMTEXT
...@@ -8173,6 +8174,15 @@ show_param: ...@@ -8173,6 +8174,15 @@ show_param:
YYABORT; YYABORT;
} }
| PLUGIN_SYM | PLUGIN_SYM
{
LEX *lex= Lex;
WARN_DEPRECATED(yythd, "5.2", "SHOW PLUGIN", "'SHOW PLUGINS'");
lex->sql_command= SQLCOM_SELECT;
lex->orig_sql_command= SQLCOM_SHOW_PLUGINS;
if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
YYABORT;
}
| PLUGINS_SYM
{ {
LEX *lex= Lex; LEX *lex= Lex;
lex->sql_command= SQLCOM_SELECT; lex->sql_command= SQLCOM_SELECT;
...@@ -9361,7 +9371,6 @@ keyword: ...@@ -9361,7 +9371,6 @@ keyword:
| OPEN_SYM {} | OPEN_SYM {}
| PARSER_SYM {} | PARSER_SYM {}
| PARTITION_SYM {} | PARTITION_SYM {}
| PLUGIN_SYM {}
| PREPARE_SYM {} | PREPARE_SYM {}
| REMOVE_SYM {} | REMOVE_SYM {}
| REPAIR {} | REPAIR {}
...@@ -9542,6 +9551,8 @@ keyword_sp: ...@@ -9542,6 +9551,8 @@ keyword_sp:
| PARTITIONS_SYM {} | PARTITIONS_SYM {}
| PASSWORD {} | PASSWORD {}
| PHASE_SYM {} | PHASE_SYM {}
| PLUGIN_SYM {}
| PLUGINS_SYM {}
| POINT_SYM {} | POINT_SYM {}
| POLYGON {} | POLYGON {}
| PRESERVE_SYM {} | PRESERVE_SYM {}
...@@ -9555,7 +9566,7 @@ keyword_sp: ...@@ -9555,7 +9566,7 @@ keyword_sp:
| REBUILD_SYM {} | REBUILD_SYM {}
| RECOVER_SYM {} | RECOVER_SYM {}
| REDO_BUFFER_SIZE_SYM {} | REDO_BUFFER_SIZE_SYM {}
| REDOFILE_SYM {} | REDOFILE_SYM {}
| REDUNDANT_SYM {} | REDUNDANT_SYM {}
| RELAY_LOG_FILE_SYM {} | RELAY_LOG_FILE_SYM {}
| RELAY_LOG_POS_SYM {} | RELAY_LOG_POS_SYM {}
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
void open_table_error(TABLE_SHARE *share, int error, int db_errno, void open_table_error(TABLE_SHARE *share, int error, int db_errno,
myf errortype, int errarg); myf errortype, int errarg);
static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, static int open_binary_frm(THD *thd, TABLE_SHARE *share,
File file); uchar *head, File file);
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type, static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
uint types, char **names); uint types, char **names);
static uint find_field(Field **fields, uint start, uint length); static uint find_field(Field **fields, uint start, uint length);
...@@ -717,8 +717,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, ...@@ -717,8 +717,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
keyinfo->parser= plugin_lock(&parser_name, MYSQL_FTPARSER_PLUGIN); keyinfo->parser= plugin_lock(&parser_name, MYSQL_FTPARSER_PLUGIN);
if (! keyinfo->parser) if (! keyinfo->parser)
{ {
my_free(buff, MYF(0));
my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str); my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str);
my_free(buff, MYF(0));
goto err; goto err;
} }
} }
......
...@@ -833,4 +833,80 @@ invalid_date: ...@@ -833,4 +833,80 @@ invalid_date:
} }
/*
Calculate difference between two datetime values as seconds + microseconds.
SYNOPSIS
calc_time_diff()
l_time1 - TIME/DATE/DATETIME value
l_time2 - TIME/DATE/DATETIME value
l_sign - 1 absolute values are substracted,
-1 absolute values are added.
seconds_out - Out parameter where difference between
l_time1 and l_time2 in seconds is stored.
microseconds_out- Out parameter where microsecond part of difference
between l_time1 and l_time2 is stored.
NOTE
This function calculates difference between l_time1 and l_time2 absolute
values. So one should set l_sign and correct result if he want to take
signs into account (i.e. for TIME values).
RETURN VALUES
Returns sign of difference.
1 means negative result
0 means positive result
*/
bool
calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign, longlong *seconds_out,
long *microseconds_out)
{
long days;
bool neg;
longlong microseconds;
/*
We suppose that if first argument is MYSQL_TIMESTAMP_TIME
the second argument should be TIMESTAMP_TIME also.
We should check it before calc_time_diff call.
*/
if (l_time1->time_type == MYSQL_TIMESTAMP_TIME) // Time value
days= (long)l_time1->day - l_sign * (long)l_time2->day;
else
{
days= calc_daynr((uint) l_time1->year,
(uint) l_time1->month,
(uint) l_time1->day);
if (l_time2->time_type == MYSQL_TIMESTAMP_TIME)
days-= l_sign * (long)l_time2->day;
else
days-= l_sign*calc_daynr((uint) l_time2->year,
(uint) l_time2->month,
(uint) l_time2->day);
}
microseconds= ((longlong)days*LL(86400) +
(longlong)(l_time1->hour*3600L +
l_time1->minute*60L +
l_time1->second) -
l_sign*(longlong)(l_time2->hour*3600L +
l_time2->minute*60L +
l_time2->second)) * LL(1000000) +
(longlong)l_time1->second_part -
l_sign*(longlong)l_time2->second_part;
neg= 0;
if (microseconds < 0)
{
microseconds= -microseconds;
neg= 1;
}
*seconds_out= microseconds/1000000L;
*microseconds_out= (long) (microseconds%1000000L);
return neg;
}
#endif #endif
...@@ -160,6 +160,7 @@ static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b) ...@@ -160,6 +160,7 @@ static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b)
typedef struct st_my_ftb_param typedef struct st_my_ftb_param
{ {
MYSQL_FTPARSER_PARAM *up;
FTB *ftb; FTB *ftb;
FTB_EXPR *ftbe; FTB_EXPR *ftbe;
byte *up_quot; byte *up_quot;
...@@ -280,7 +281,7 @@ static int ftb_parse_query_internal(void *param, char *query, int len) ...@@ -280,7 +281,7 @@ static int ftb_parse_query_internal(void *param, char *query, int len)
info.prev= ' '; info.prev= ' ';
info.quot= 0; info.quot= 0;
while (ft_get_word(cs, start, end, &w, &info)) while (ft_get_word(cs, start, end, &w, &info))
ftb_query_add_word(param, w.pos, w.len, &info); ftb_param->up->mysql_add_word(param, w.pos, w.len, &info);
return(0); return(0);
} }
...@@ -295,14 +296,15 @@ static void _ftb_parse_query(FTB *ftb, byte *query, uint len, ...@@ -295,14 +296,15 @@ static void _ftb_parse_query(FTB *ftb, byte *query, uint len,
if (ftb->state != UNINITIALIZED) if (ftb->state != UNINITIALIZED)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr, 0)))
DBUG_VOID_RETURN;
ftb_param.up= param;
ftb_param.ftb= ftb; ftb_param.ftb= ftb;
ftb_param.depth= 0; ftb_param.depth= 0;
ftb_param.ftbe= ftb->root; ftb_param.ftbe= ftb->root;
ftb_param.up_quot= 0; ftb_param.up_quot= 0;
if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr)))
DBUG_VOID_RETURN;
param->mysql_parse= ftb_parse_query_internal; param->mysql_parse= ftb_parse_query_internal;
param->mysql_add_word= ftb_query_add_word; param->mysql_add_word= ftb_query_add_word;
param->mysql_ftparam= (void *)&ftb_param; param->mysql_ftparam= (void *)&ftb_param;
...@@ -313,7 +315,7 @@ static void _ftb_parse_query(FTB *ftb, byte *query, uint len, ...@@ -313,7 +315,7 @@ static void _ftb_parse_query(FTB *ftb, byte *query, uint len,
parser->parse(param); parser->parse(param);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
static int _ftb_no_dupes_cmp(void* not_used __attribute__((unused)), static int _ftb_no_dupes_cmp(void* not_used __attribute__((unused)),
const void *a,const void *b) const void *a,const void *b)
...@@ -569,6 +571,7 @@ err: ...@@ -569,6 +571,7 @@ err:
typedef struct st_my_ftb_phrase_param typedef struct st_my_ftb_phrase_param
{ {
MYSQL_FTPARSER_PARAM *up;
LIST *phrase; LIST *phrase;
LIST *document; LIST *document;
CHARSET_INFO *cs; CHARSET_INFO *cs;
...@@ -615,7 +618,7 @@ static int ftb_check_phrase_internal(void *param, char *document, int len) ...@@ -615,7 +618,7 @@ static int ftb_check_phrase_internal(void *param, char *document, int len)
const char *docend= document + len; const char *docend= document + len;
while (ft_simple_get_word(phrase_param->cs, &document, docend, &word, FALSE)) while (ft_simple_get_word(phrase_param->cs, &document, docend, &word, FALSE))
{ {
ftb_phrase_add_word(param, word.pos, word.len, 0); phrase_param->up->mysql_add_word(param, word.pos, word.len, 0);
if (phrase_param->match) if (phrase_param->match)
return 1; return 1;
} }
...@@ -644,8 +647,11 @@ static int _ftb_check_phrase(FTB *ftb, const byte *document, uint len, ...@@ -644,8 +647,11 @@ static int _ftb_check_phrase(FTB *ftb, const byte *document, uint len,
MYSQL_FTPARSER_PARAM *param; MYSQL_FTPARSER_PARAM *param;
DBUG_ENTER("_ftb_check_phrase"); DBUG_ENTER("_ftb_check_phrase");
DBUG_ASSERT(parser); DBUG_ASSERT(parser);
if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr)))
if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr, 1)))
DBUG_RETURN(0); DBUG_RETURN(0);
ftb_param.up= param;
ftb_param.phrase= ftbe->phrase; ftb_param.phrase= ftbe->phrase;
ftb_param.document= ftbe->document; ftb_param.document= ftbe->document;
ftb_param.cs= ftb->charset; ftb_param.cs= ftb->charset;
...@@ -814,6 +820,7 @@ err: ...@@ -814,6 +820,7 @@ err:
typedef struct st_my_ftb_find_param typedef struct st_my_ftb_find_param
{ {
MYSQL_FTPARSER_PARAM *up;
FT_INFO *ftb; FT_INFO *ftb;
FT_SEG_ITERATOR *ftsi; FT_SEG_ITERATOR *ftsi;
} MY_FTB_FIND_PARAM; } MY_FTB_FIND_PARAM;
...@@ -854,11 +861,12 @@ static int ftb_find_relevance_add_word(void *param, char *word, int len, ...@@ -854,11 +861,12 @@ static int ftb_find_relevance_add_word(void *param, char *word, int len,
static int ftb_find_relevance_parse(void *param, char *doc, int len) static int ftb_find_relevance_parse(void *param, char *doc, int len)
{ {
FT_INFO *ftb= ((MY_FTB_FIND_PARAM *)param)->ftb; MY_FTB_FIND_PARAM *ftb_param=(MY_FTB_FIND_PARAM *)param;
FT_INFO *ftb= ftb_param->ftb;
char *end= doc + len; char *end= doc + len;
FT_WORD w; FT_WORD w;
while (ft_simple_get_word(ftb->charset, &doc, end, &w, TRUE)) while (ft_simple_get_word(ftb->charset, &doc, end, &w, TRUE))
ftb_find_relevance_add_word(param, w.pos, w.len, 0); ftb_param->up->mysql_add_word(param, w.pos, w.len, 0);
return(0); return(0);
} }
...@@ -878,7 +886,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) ...@@ -878,7 +886,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
return -2.0; return -2.0;
if (!ftb->queue.elements) if (!ftb->queue.elements)
return 0; return 0;
if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr))) if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr, 0)))
return 0; return 0;
if (ftb->state != INDEX_SEARCH && docid <= ftb->lastpos) if (ftb->state != INDEX_SEARCH && docid <= ftb->lastpos)
...@@ -902,19 +910,18 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) ...@@ -902,19 +910,18 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
_mi_ft_segiterator_init(ftb->info, ftb->keynr, record, &ftsi); _mi_ft_segiterator_init(ftb->info, ftb->keynr, record, &ftsi);
memcpy(&ftsi2, &ftsi, sizeof(ftsi)); memcpy(&ftsi2, &ftsi, sizeof(ftsi));
ftb_param.up= param;
ftb_param.ftb= ftb; ftb_param.ftb= ftb;
ftb_param.ftsi= &ftsi2; ftb_param.ftsi= &ftsi2;
param->mysql_parse= ftb_find_relevance_parse;
param->mysql_add_word= ftb_find_relevance_add_word;
param->mysql_ftparam= (void *)&ftb_param;
param->cs= ftb->charset;
param->mode= MYSQL_FTPARSER_SIMPLE_MODE;
while (_mi_ft_segiterator(&ftsi)) while (_mi_ft_segiterator(&ftsi))
{ {
if (!ftsi.pos) if (!ftsi.pos)
continue; continue;
/* Since subsequent call to _ftb_check_phrase overwrites param elements,
it must be reinitialized at each iteration _inside_ the loop. */
param->mysql_parse= ftb_find_relevance_parse;
param->mysql_add_word= ftb_find_relevance_add_word;
param->mysql_ftparam= (void *)&ftb_param;
param->cs= ftb->charset;
param->mode= MYSQL_FTPARSER_SIMPLE_MODE;
param->doc= (byte *)ftsi.pos; param->doc= (byte *)ftsi.pos;
param->length= ftsi.len; param->length= ftsi.len;
parser->parse(param); parser->parse(param);
......
...@@ -226,7 +226,7 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query, ...@@ -226,7 +226,7 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query,
aio.charset=info->s->keyinfo[keynr].seg->charset; aio.charset=info->s->keyinfo[keynr].seg->charset;
aio.keybuff=info->lastkey+info->s->base.max_key_length; aio.keybuff=info->lastkey+info->s->base.max_key_length;
parser= info->s->keyinfo[keynr].parser; parser= info->s->keyinfo[keynr].parser;
if (! (ftparser_param= ftparser_call_initializer(info, keynr))) if (! (ftparser_param= ftparser_call_initializer(info, keynr, 0)))
goto err; goto err;
bzero(&wtree,sizeof(wtree)); bzero(&wtree,sizeof(wtree));
......
...@@ -27,6 +27,7 @@ typedef struct st_ft_docstat { ...@@ -27,6 +27,7 @@ typedef struct st_ft_docstat {
typedef struct st_my_ft_parser_param typedef struct st_my_ft_parser_param
{ {
MYSQL_FTPARSER_PARAM *up;
TREE *wtree; TREE *wtree;
my_bool with_alloc; my_bool with_alloc;
} MY_FT_PARSER_PARAM; } MY_FT_PARSER_PARAM;
...@@ -268,16 +269,16 @@ static int ft_add_word(void *param, byte *word, uint word_len, ...@@ -268,16 +269,16 @@ static int ft_add_word(void *param, byte *word, uint word_len,
} }
static int ft_parse_internal(void *param, byte *doc, uint doc_len) static int ft_parse_internal(void *param, byte *doc, int doc_len)
{ {
byte *end=doc+doc_len; byte *end=doc+doc_len;
MY_FT_PARSER_PARAM *ft_param=(MY_FT_PARSER_PARAM *)param;
TREE *wtree= ft_param->wtree;
FT_WORD w; FT_WORD w;
TREE *wtree;
DBUG_ENTER("ft_parse_internal"); DBUG_ENTER("ft_parse_internal");
wtree= ((MY_FT_PARSER_PARAM *)param)->wtree;
while (ft_simple_get_word(wtree->custom_arg, &doc, end, &w, TRUE)) while (ft_simple_get_word(wtree->custom_arg, &doc, end, &w, TRUE))
if (ft_add_word(param, w.pos, w.len, 0)) if (ft_param->up->mysql_add_word(param, w.pos, w.len, 0))
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -290,6 +291,8 @@ int ft_parse(TREE *wtree, byte *doc, int doclen, my_bool with_alloc, ...@@ -290,6 +291,8 @@ int ft_parse(TREE *wtree, byte *doc, int doclen, my_bool with_alloc,
MY_FT_PARSER_PARAM my_param; MY_FT_PARSER_PARAM my_param;
DBUG_ENTER("ft_parse"); DBUG_ENTER("ft_parse");
DBUG_ASSERT(parser); DBUG_ASSERT(parser);
my_param.up= param;
my_param.wtree= wtree; my_param.wtree= wtree;
my_param.with_alloc= with_alloc; my_param.with_alloc= with_alloc;
...@@ -300,11 +303,12 @@ int ft_parse(TREE *wtree, byte *doc, int doclen, my_bool with_alloc, ...@@ -300,11 +303,12 @@ int ft_parse(TREE *wtree, byte *doc, int doclen, my_bool with_alloc,
param->doc= doc; param->doc= doc;
param->length= doclen; param->length= doclen;
param->mode= MYSQL_FTPARSER_SIMPLE_MODE; param->mode= MYSQL_FTPARSER_SIMPLE_MODE;
DBUG_RETURN(parser->parse(param)); DBUG_RETURN(parser->parse(param));
} }
#define MAX_PARAM_NR 2
MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info, uint keynr) MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info,
uint keynr, uint paramnr)
{ {
uint32 ftparser_nr; uint32 ftparser_nr;
struct st_mysql_ftparser *parser; struct st_mysql_ftparser *parser;
...@@ -343,8 +347,14 @@ MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info, uint keynr) ...@@ -343,8 +347,14 @@ MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info, uint keynr)
} }
info->s->ftparsers= ftparsers; info->s->ftparsers= ftparsers;
} }
/*
We have to allocate two MYSQL_FTPARSER_PARAM structures per plugin
because in a boolean search a parser is called recursively
ftb_find_relevance* calls ftb_check_phrase*
(MAX_PARAM_NR=2)
*/
info->ftparser_param= (MYSQL_FTPARSER_PARAM *) info->ftparser_param= (MYSQL_FTPARSER_PARAM *)
my_malloc(sizeof(MYSQL_FTPARSER_PARAM) * my_malloc(MAX_PARAM_NR * sizeof(MYSQL_FTPARSER_PARAM) *
info->s->ftparsers, MYF(MY_WME|MY_ZEROFILL)); info->s->ftparsers, MYF(MY_WME|MY_ZEROFILL));
if (! info->ftparser_param) if (! info->ftparser_param)
return 0; return 0;
...@@ -359,6 +369,8 @@ MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info, uint keynr) ...@@ -359,6 +369,8 @@ MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info, uint keynr)
ftparser_nr= info->s->keyinfo[keynr].ftparser_nr; ftparser_nr= info->s->keyinfo[keynr].ftparser_nr;
parser= info->s->keyinfo[keynr].parser; parser= info->s->keyinfo[keynr].parser;
} }
DBUG_ASSERT(paramnr < MAX_PARAM_NR);
ftparser_nr= ftparser_nr*MAX_PARAM_NR + paramnr;
if (! info->ftparser_param[ftparser_nr].mysql_add_word) if (! info->ftparser_param[ftparser_nr].mysql_add_word)
{ {
/* Note, that mysql_add_word is used here as a flag: /* Note, that mysql_add_word is used here as a flag:
...@@ -372,22 +384,27 @@ MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info, uint keynr) ...@@ -372,22 +384,27 @@ MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info, uint keynr)
return &info->ftparser_param[ftparser_nr]; return &info->ftparser_param[ftparser_nr];
} }
void ftparser_call_deinitializer(MI_INFO *info) void ftparser_call_deinitializer(MI_INFO *info)
{ {
uint i, keys= info->s->state.header.keys; uint i, j, keys= info->s->state.header.keys;
if (! info->ftparser_param) if (! info->ftparser_param)
return; return;
for (i= 0; i < keys; i++) for (i= 0; i < keys; i++)
{ {
MI_KEYDEF *keyinfo= &info->s->keyinfo[i]; MI_KEYDEF *keyinfo= &info->s->keyinfo[i];
MYSQL_FTPARSER_PARAM *ftparser_param= for (j=0; j < MAX_PARAM_NR; j++)
&info->ftparser_param[keyinfo->ftparser_nr];
if (keyinfo->flag & HA_FULLTEXT && ftparser_param->mysql_add_word)
{ {
if (keyinfo->parser->deinit) MYSQL_FTPARSER_PARAM *ftparser_param=
keyinfo->parser->deinit(ftparser_param); &info->ftparser_param[keyinfo->ftparser_nr*MAX_PARAM_NR + j];
ftparser_param->mysql_add_word= 0; if (keyinfo->flag & HA_FULLTEXT && ftparser_param->mysql_add_word)
{
if (keyinfo->parser->deinit)
keyinfo->parser->deinit(ftparser_param);
ftparser_param->mysql_add_word= 0;
}
else
break;
} }
} }
} }
...@@ -122,7 +122,7 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, const byte *record) ...@@ -122,7 +122,7 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, const byte *record)
TREE ptree; TREE ptree;
MYSQL_FTPARSER_PARAM *param; MYSQL_FTPARSER_PARAM *param;
DBUG_ENTER("_mi_ft_parserecord"); DBUG_ENTER("_mi_ft_parserecord");
if (! (param= ftparser_call_initializer(info, keynr))) if (! (param= ftparser_call_initializer(info, keynr, 0)))
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
bzero((char*) &ptree, sizeof(ptree)); bzero((char*) &ptree, sizeof(ptree));
if (_mi_ft_parse(&ptree, info, keynr, record, 0, param)) if (_mi_ft_parse(&ptree, info, keynr, record, 0, param))
......
...@@ -145,5 +145,6 @@ float ft_boolean_get_relevance(FT_INFO *); ...@@ -145,5 +145,6 @@ float ft_boolean_get_relevance(FT_INFO *);
my_off_t ft_boolean_get_docid(FT_INFO *); my_off_t ft_boolean_get_docid(FT_INFO *);
void ft_boolean_reinit_search(FT_INFO *); void ft_boolean_reinit_search(FT_INFO *);
extern MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info, extern MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info,
uint keynr); uint keynr,
uint paramnr);
extern void ftparser_call_deinitializer(MI_INFO *info); extern void ftparser_call_deinitializer(MI_INFO *info);
...@@ -72,6 +72,10 @@ else ...@@ -72,6 +72,10 @@ else
libexecdir="$basedir/libexec" libexecdir="$basedir/libexec"
fi fi
# datadir_set is used to determine if datadir was set (and so should be
# *not* set inside of the --basedir= handler.)
datadir_set=
# #
# Use LSB init script functions for printing messages, if possible # Use LSB init script functions for printing messages, if possible
# #
...@@ -105,11 +109,15 @@ parse_server_arguments() { ...@@ -105,11 +109,15 @@ parse_server_arguments() {
case "$arg" in case "$arg" in
--basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'` --basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'`
bindir="$basedir/bin" bindir="$basedir/bin"
datadir="$basedir/data" if test -z "$datadir_set"; then
datadir="$basedir/data"
fi
sbindir="$basedir/sbin" sbindir="$basedir/sbin"
libexecdir="$basedir/libexec" libexecdir="$basedir/libexec"
;; ;;
--datadir=*) datadir=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; --datadir=*) datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`
datadir_set=1
;;
--user=*) user=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; --user=*) user=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
--pid-file=*) server_pid_file=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; --pid-file=*) server_pid_file=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
--use-mysqld_safe) use_mysqld_safe=1;; --use-mysqld_safe) use_mysqld_safe=1;;
......
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