Commit 73189969 authored by kostja@bodhi.local's avatar kostja@bodhi.local

Merge bodhi.local:/opt/local/work/tmp_merge

into  bodhi.local:/opt/local/work/mysql-5.1-runtime-merge
parents bea33049 bd183d42
*-t
*.Plo
*.Po
*.a
*.bb
*.bbg
......@@ -12,6 +14,7 @@
*.gcov
*.idb
*.la
*.lai
*.lib
*.lo
*.map
......@@ -23,6 +26,7 @@
*.res
*.sbr
*.so
*.so.*
*.spec
*/*_pure_*warnings
*/.pure
......@@ -283,6 +287,7 @@ build_tags.sh
client/#mysql.cc#
client/*.ds?
client/*.vcproj
client/.libs -prune
client/completion_hash.cpp
client/decimal.c
client/insert_test
......@@ -578,6 +583,7 @@ libmysqld/sql_insert.cc
libmysqld/sql_lex.cc
libmysqld/sql_list.cc
libmysqld/sql_load.cc
libmysqld/sql_locale.cc
libmysqld/sql_manager.cc
libmysqld/sql_map.cc
libmysqld/sql_olap.cc
......@@ -1755,6 +1761,7 @@ test1/*
test_xml
tests/*.ds?
tests/*.vcproj
tests/.libs -prune
tests/client_test
tests/connect_test
tests/mysql_client_test
......@@ -1762,6 +1769,7 @@ thr_insert_test/*
thr_test/*
thread_test
tmp/*
tools/.libs -prune
tools/my_vsnprintf.c
tools/mysqlmanager
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 \
protocol.cc net_serv.cc opt_range.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_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 \
......
......@@ -498,6 +498,22 @@ f1 f2
Warnings:
Warning 1292 Truncated incorrect date value: '2003-04-05 g'
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);
insert into t1 (f1) values ("2005-01-01");
insert into t1 (f1) values ("2005-02-01");
......
......@@ -22,3 +22,117 @@ set GLOBAL init_connect="adsfsdfsdfs";
select @a;
Got one of the listed errors
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;
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;
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;
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);
show create table t1;
Table Create Table
......
......@@ -661,3 +661,56 @@ DROP VIEW test2.t3;
DROP TABLE test2.t1, test1.t0;
DROP DATABASE test2;
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;
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;
--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
#
......
......@@ -1366,25 +1366,6 @@ drop table federated.t1, federated.t2;
connection master;
--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
# update trigger on NDB table". SQL-layer didn't properly inform
......@@ -1479,5 +1460,26 @@ drop table federated.t1, federated.t2;
connection slave;
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;
......@@ -35,4 +35,205 @@ select @a;
connection con0;
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
#
# 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;
DROP TABLE t1;
# End of 4.1 tests
#
# Test varchar
#
......@@ -817,6 +815,42 @@ alter table t1 enable keys;
show keys from 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
......@@ -828,6 +862,8 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
create table t4 (c1 int) engine=myisam pack_keys=2;
drop table t1, t2, t3;
--echo End of 5.0 tests
#
# 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));
--error 1064
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 v2 as select qty from v1;
--echo mysqldump {
--exec $MYSQL_DUMP --compact -F --tab . test
--exec cat v1.sql
--exec $MYSQL_DUMP --compact -F --tab $MYSQLTEST_VARDIR/tmp test
--exec cat $MYSQLTEST_VARDIR/tmp/v1.sql
--echo } mysqldump {
--exec cat v2.sql
--exec cat $MYSQLTEST_VARDIR/tmp/v2.sql
--echo } mysqldump
--rm v.sql t.sql t.txt
drop view v1;
drop view v2;
drop table t;
......
......@@ -872,3 +872,65 @@ DROP VIEW test2.t3;
DROP TABLE test2.t1, test1.t0;
DROP DATABASE test2;
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 \
set_var.cc sql_parse.cc sql_yacc.yy \
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 \
procedure.cc item_uniq.cc sql_test.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);
}
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)
{
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_pi(void);
Item *create_func_pow(Item* a, Item *b);
Item *create_func_current_user(void);
Item *create_func_radians(Item *a);
Item *create_func_release_lock(Item* a);
Item *create_func_repeat(Item* a, Item *b);
......
......@@ -2505,8 +2505,7 @@ void udf_handler::cleanup()
{
if (u_d->func_deinit != NULL)
{
void (*deinit)(UDF_INIT *) = (void (*)(UDF_INIT*))
u_d->func_deinit;
Udf_func_deinit deinit= u_d->func_deinit;
(*deinit)(&initid);
}
free_udf(u_d);
......@@ -2651,9 +2650,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
}
}
thd->net.last_error[0]=0;
my_bool (*init)(UDF_INIT *, UDF_ARGS *, char *)=
(my_bool (*)(UDF_INIT *, UDF_ARGS *, char *))
u_d->func_init;
Udf_func_init init= u_d->func_init;
if ((error=(uchar) init(&initid, &f_args, thd->net.last_error)))
{
my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
......
......@@ -1670,42 +1670,51 @@ String *Item_func_database::val_str(String *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);
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
// For system threads (e.g. replication SQL thread) user may be empty
if (user)
{
user= thd->main_security_ctx.user;
host= thd->main_security_ctx.host_or_ip;
}
CHARSET_INFO *cs= str_value.charset();
uint res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
// For system threads (e.g. replication SQL thread) user may be empty
if (!user)
return &my_empty_string;
res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
if (str_value.alloc(res_length))
{
null_value=1;
return TRUE;
}
if (str->alloc(res_length))
{
null_value=1;
return 0;
res_length=cs->cset->snprintf(cs, (char*)str_value.ptr(), res_length,
"%s@%s", user, host);
str_value.length(res_length);
str_value.mark_as_const();
}
res_length=cs->cset->snprintf(cs, (char*)str->ptr(), res_length, "%s@%s",
user, host);
str->length(res_length);
str->set_charset(cs);
return str;
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
{
bool is_current;
protected:
bool init (const char *user, const char *host);
public:
Item_func_user(bool is_current_arg)
:Item_func_sysconst(), is_current(is_current_arg) {}
String *val_str(String *);
Item_func_user()
{
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()
{
max_length= ((USERNAME_LENGTH + HOSTNAME_LENGTH + 1) *
system_charset_info->mbmaxlen);
}
const char *func_name() const
{ return is_current ? "current_user" : "user"; }
const char *fully_qualified_func_name() const
{ return is_current ? "current_user()" : "user()"; }
const char *func_name() const { return "user"; }
const char *fully_qualified_func_name() const { return "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 */
#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:
- 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;
break;
case 'M':
if ((l_time->month= check_word(my_locale_en_US.month_names,
val, val_end, &val)) <= 0)
goto err;
break;
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)
goto err;
break;
......@@ -299,8 +284,11 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
/* Exotic things */
case 'W':
if ((weekday= check_word(my_locale_en_US.day_names, val, val_end, &val)) <= 0)
goto err;
break;
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;
break;
case 'w':
......@@ -502,9 +490,16 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
uint weekday;
ulong length;
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->set_charset(&my_charset_bin);
locale = thd->variables.lc_time_names;
if (l_time->neg)
str->append('-');
......@@ -520,26 +515,38 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
case 'M':
if (!l_time->month)
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;
case 'b':
if (!l_time->month)
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;
case 'W':
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
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;
case 'a':
if (type == MYSQL_TIMESTAMP_TIME)
return 1;
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
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;
case 'D':
if (type == MYSQL_TIMESTAMP_TIME)
......@@ -872,6 +879,7 @@ String* Item_func_monthname::val_str(String* str)
DBUG_ASSERT(fixed == 1);
const char *month_name;
uint month= (uint) val_int();
THD *thd= current_thd;
if (null_value || !month)
{
......@@ -879,7 +887,7 @@ String* Item_func_monthname::val_str(String* str)
return (String*) 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);
return str;
}
......@@ -1004,11 +1012,12 @@ String* Item_func_dayname::val_str(String* str)
DBUG_ASSERT(fixed == 1);
uint weekday=(uint) val_int(); // Always Item_func_daynr()
const char *name;
THD *thd= current_thd;
if (null_value)
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);
return str;
}
......@@ -1652,7 +1661,7 @@ uint Item_func_date_format::format_length(const String *format)
switch(*++ptr) {
case 'M': /* month, textual */
case 'W': /* day (of the week), textual */
size += 9;
size += 64; /* large for UTF8 locale data */
break;
case 'D': /* day (of the month), numeric plus english suffix */
case 'Y': /* year, numeric, 4 digits */
......@@ -1662,6 +1671,8 @@ uint Item_func_date_format::format_length(const String *format)
break;
case 'a': /* locale's abbreviated weekday name (Sun..Sat) */
case 'b': /* locale's abbreviated month name (Jan.Dec) */
size += 32; /* large for UTF8 locale data */
break;
case 'j': /* day of year (001..366) */
size += 3;
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 *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
****************************************************************************/
......@@ -588,6 +605,7 @@ struct Query_cache_query_flags
ulong sql_mode;
ulong max_sort_length;
ulong group_concat_max_len;
MY_LOCALE *lc_time_names;
};
#define QUERY_CACHE_FLAGS_SIZE sizeof(Query_cache_query_flags)
#include "sql_cache.h"
......
......@@ -109,7 +109,6 @@ extern ulong ndb_report_thresh_binlog_mem_usage;
static HASH system_variable_hash;
const char *bool_type_names[]= { "OFF", "ON", NullS };
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_last_insert_id sys_last_insert_id("last_insert_id");
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_readonly sys_error_count("error_count",
OPT_SESSION,
......@@ -871,6 +873,7 @@ SHOW_VAR init_vars[]= {
{"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
{"large_page_size", (char*) &opt_large_page_size, SHOW_INT},
{"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_local_infile.name, (char*) &sys_local_infile, SHOW_SYS},
#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);
}
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
......
......@@ -28,6 +28,8 @@
class sys_var;
class set_var;
typedef struct system_variables SV;
typedef struct my_locale_st MY_LOCALE;
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
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
{
/* We need a derived class only to have a warn_deprecated() */
......@@ -964,6 +985,7 @@ public:
handlerton *hton;
DATE_TIME_FORMAT *date_time_format;
Time_zone *time_zone;
MY_LOCALE *locale_value;
} save_result;
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.sql_mode= thd->variables.sql_mode;
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;
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, \
......@@ -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.max_sort_length= thd->variables.max_sort_length;
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, \
CS client: %u, CS result: %u, CS conn: %u, limit: %lu, TZ: 0x%lx, \
sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
......
......@@ -350,6 +350,7 @@ void THD::init(void)
reset_current_stmt_binlog_row_based();
#endif /*HAVE_ROW_BASED_REPLICATION*/
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_or_ip= "connecting host";
priv_host[0]= '\0';
#ifndef NO_EMBEDDED_ACCESS_CHECKS
db_access= NO_ACCESS;
#endif
......
......@@ -266,6 +266,9 @@ struct system_variables
CHARSET_INFO *collation_database;
CHARSET_INFO *collation_connection;
/* Locale Support */
MY_LOCALE *lc_time_names;
Time_zone *time_zone;
/* 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)
{
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;
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<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;
Item_sum *in_sum_func;
udf_func udf;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1298,6 +1298,12 @@ pthread_handler_t handle_bootstrap(void *arg)
thd->security_ctx->priv_user=
thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
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;
thd->init_for_queries();
......@@ -3502,7 +3508,7 @@ end_with_restore_list:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
TABLE_LIST *aux_tables=
(TABLE_LIST *)thd->lex->auxilliary_table_list.first;
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
multi_delete *result;
if (!thd->locked_tables &&
......@@ -6024,7 +6030,7 @@ void mysql_init_multi_delete(LEX *lex)
mysql_init_select(lex);
lex->select_lex.select_limit= 0;
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->query_tables= 0;
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;
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;
DBUG_ENTER("multi_delete_precheck");
......@@ -7496,7 +7502,7 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
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)
{
lex->table_count++;
......
......@@ -57,7 +57,7 @@ static char *init_syms(udf_func *tmp, char *nm)
{
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;
end=strmov(nm,tmp->name.str);
......@@ -65,18 +65,18 @@ static char *init_syms(udf_func *tmp, char *nm)
if (tmp->type == UDFTYPE_AGGREGATE)
{
(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;
(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;
}
(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");
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
......
......@@ -23,6 +23,15 @@
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
{
LEX_STRING name;
......@@ -30,11 +39,11 @@ typedef struct st_udf_func
Item_udftype type;
char *dl;
void *dlhandle;
void *func;
void *func_init;
void *func_deinit;
void *func_clear;
void *func_add;
Udf_func_any func;
Udf_func_init func_init;
Udf_func_deinit func_deinit;
Udf_func_clear func_clear;
Udf_func_add func_add;
ulong usage_count;
} udf_func;
......@@ -76,8 +85,7 @@ class udf_handler :public Sql_alloc
*null_value=1;
return 0.0;
}
double (*func)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)=
(double (*)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)) u_d->func;
Udf_func_double func= (Udf_func_double) u_d->func;
double tmp=func(&initid, &f_args, &is_null, &error);
if (is_null || error)
{
......@@ -95,8 +103,7 @@ class udf_handler :public Sql_alloc
*null_value=1;
return LL(0);
}
longlong (*func)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)=
(longlong (*)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)) u_d->func;
Udf_func_longlong func= (Udf_func_longlong) u_d->func;
longlong tmp=func(&initid, &f_args, &is_null, &error);
if (is_null || error)
{
......@@ -110,8 +117,7 @@ class udf_handler :public Sql_alloc
void clear()
{
is_null= 0;
void (*func)(UDF_INIT *, uchar *, uchar *)=
(void (*)(UDF_INIT *, uchar *, uchar *)) u_d->func_clear;
Udf_func_clear func= u_d->func_clear;
func(&initid, &is_null, &error);
}
void add(my_bool *null_value)
......@@ -121,8 +127,7 @@ class udf_handler :public Sql_alloc
*null_value=1;
return;
}
void (*func)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)=
(void (*)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *)) u_d->func_add;
Udf_func_add func= u_d->func_add;
func(&initid, &f_args, &is_null, &error);
*null_value= (my_bool) (is_null || error);
}
......
......@@ -459,7 +459,7 @@ int mysql_update(THD *thd,
can_compare_record= (!(table->file->ha_table_flags() &
HA_PARTIAL_COLUMN_READ) ||
bitmap_is_subset(table->write_set, table->read_set));
while (!(error=info.read_record(&info)) && !thd->killed)
{
if (!(select && select->skip_record()))
......
......@@ -6159,7 +6159,10 @@ simple_expr:
Lex->safe_to_cache_query=0;
}
| 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 ')'
{ $$= new Item_date_add_interval($3,$5,$6,0); }
| DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')'
......@@ -6518,7 +6521,7 @@ simple_expr:
| UNIX_TIMESTAMP '(' expr ')'
{ $$= new Item_func_unix_timestamp($3); }
| 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
{ $$= new Item_func_curdate_utc(); Lex->safe_to_cache_query=0;}
| 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, '.');
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
MY_UNPACK_FILENAME| (have_iext ? MY_REPLACE_EXT :MY_APPEND_EXT));
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,
MY_UNPACK_FILENAME | (have_iext ? MY_REPLACE_EXT :
MY_APPEND_EXT));
}
fn_format(linkname, name, "", MI_NAME_IEXT,
MY_UNPACK_FILENAME|MY_APPEND_EXT);
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, '.');
int have_dext= dext && !strcmp(dext, MI_NAME_DEXT);
fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
MY_UNPACK_FILENAME |
(have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
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,
MY_UNPACK_FILENAME |
(have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
}
fn_format(linkname, name, "",MI_NAME_DEXT,
MY_UNPACK_FILENAME | MY_APPEND_EXT);
linkname_ptr=linkname;
......
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