Commit e6fffedb authored by Alexander Nozdrin's avatar Alexander Nozdrin

Manual merge from mysql-5.1.

parents 5ae8ae3a a765de73
...@@ -995,11 +995,13 @@ static struct my_option my_long_options[] = ...@@ -995,11 +995,13 @@ static struct my_option my_long_options[] =
/* 'unspec' is not mentioned because it is just a placeholder. */ /* 'unspec' is not mentioned because it is just a placeholder. */
"Determine when the output statements should be base64-encoded BINLOG " "Determine when the output statements should be base64-encoded BINLOG "
"statements: 'never' disables it and works only for binlogs without " "statements: 'never' disables it and works only for binlogs without "
"row-based events; 'auto' prints base64 only when necessary (i.e., " "row-based events; 'decode-rows' decodes row events into commented SQL "
"for row-based events and format description events); 'always' prints " "statements if the --verbose option is also given; 'auto' prints base64 "
"base64 whenever possible. 'always' is for debugging only and should " "only when necessary (i.e., for row-based events and format description "
"not be used in a production system. If this argument is not given, " "events); 'always' prints base64 whenever possible. 'always' is for "
"the default is 'auto'; if it is given with no argument, 'always' is used." "debugging only and should not be used in a production system. If this "
"argument is not given, the default is 'auto'; if it is given with no "
"argument, 'always' is used."
,(uchar**) &opt_base64_output_mode_str, ,(uchar**) &opt_base64_output_mode_str,
(uchar**) &opt_base64_output_mode_str, (uchar**) &opt_base64_output_mode_str,
0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
......
...@@ -432,6 +432,10 @@ typedef struct st_mi_check_param ...@@ -432,6 +432,10 @@ typedef struct st_mi_check_param
const char *db_name, *table_name; const char *db_name, *table_name;
const char *op_name; const char *op_name;
enum_mi_stats_method stats_method; enum_mi_stats_method stats_method;
#ifdef THREAD
pthread_mutex_t print_msg_mutex;
my_bool need_print_msg_lock;
#endif
} MI_CHECK; } MI_CHECK;
typedef struct st_sort_ft_buf typedef struct st_sort_ft_buf
......
...@@ -19,81 +19,10 @@ test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL ...@@ -19,81 +19,10 @@ test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL
test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL
test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
create table t2 select * from t1 procedure analyse(); create table t2 select * from t1 procedure analyse();
select * from t2; ERROR HY000: Incorrect usage of PROCEDURE and non-SELECT
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype drop table t1;
test.t1.i 1 7 1 1 0 0 4.0000 2.2361 ENUM('1','3','5','7') NOT NULL
test.t1.j 2 8 1 1 0 0 5.0000 2.2361 ENUM('2','4','6','8') NOT NULL
test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL
test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL
test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
drop table t1,t2;
EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(); EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE();
ERROR HY000: Incorrect usage of PROCEDURE and subquery ERROR HY000: Incorrect usage of PROCEDURE and subquery
create table t1 (a int not null);
create table t2 select * from t1 where 0=1 procedure analyse();
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`Field_name` varbinary(255) NOT NULL DEFAULT '',
`Min_value` varbinary(255) DEFAULT NULL,
`Max_value` varbinary(255) DEFAULT NULL,
`Min_length` bigint(11) NOT NULL DEFAULT '0',
`Max_length` bigint(11) NOT NULL DEFAULT '0',
`Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0',
`Nulls` bigint(11) NOT NULL DEFAULT '0',
`Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '',
`Std` varbinary(255) DEFAULT NULL,
`Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t1 where 0=1 procedure analyse();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
insert into t1 values(1);
drop table t2;
create table t2 select * from t1 where 0=1 procedure analyse();
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`Field_name` varbinary(255) NOT NULL DEFAULT '',
`Min_value` varbinary(255) DEFAULT NULL,
`Max_value` varbinary(255) DEFAULT NULL,
`Min_length` bigint(11) NOT NULL DEFAULT '0',
`Max_length` bigint(11) NOT NULL DEFAULT '0',
`Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0',
`Nulls` bigint(11) NOT NULL DEFAULT '0',
`Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '',
`Std` varbinary(255) DEFAULT NULL,
`Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t2;
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
insert into t2 select * from t1 procedure analyse();
select * from t2;
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t1.a 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
insert into t1 values(2);
drop table t2;
create table t2 select * from t1 where 0=1 procedure analyse();
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`Field_name` varbinary(255) NOT NULL DEFAULT '',
`Min_value` varbinary(255) DEFAULT NULL,
`Max_value` varbinary(255) DEFAULT NULL,
`Min_length` bigint(11) NOT NULL DEFAULT '0',
`Max_length` bigint(11) NOT NULL DEFAULT '0',
`Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0',
`Nulls` bigint(11) NOT NULL DEFAULT '0',
`Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '',
`Std` varbinary(255) DEFAULT NULL,
`Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t2;
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
insert into t2 select * from t1 procedure analyse();
select * from t2;
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t1.a 1 2 1 1 0 0 1.5000 0.5000 ENUM('1','2') NOT NULL
drop table t1,t2;
create table t1 (v varchar(128)); create table t1 (v varchar(128));
insert into t1 values ('abc'),('abc\'def\\hij\"klm\0opq'),('\''),('\"'),('\\'),('a\0'),('b\''),('c\"'),('d\\'),('\'b'),('\"c'),('\\d'),('a\0\0\0b'),('a\'\'\'\'b'),('a\"\"\"\"b'),('a\\\\\\\\b'),('\'\0\\\"'),('\'\''),('\"\"'),('\\\\'),('The\ZEnd'); insert into t1 values ('abc'),('abc\'def\\hij\"klm\0opq'),('\''),('\"'),('\\'),('a\0'),('b\''),('c\"'),('d\\'),('\'b'),('\"c'),('\\d'),('a\0\0\0b'),('a\'\'\'\'b'),('a\"\"\"\"b'),('a\\\\\\\\b'),('\'\0\\\"'),('\'\''),('\"\"'),('\\\\'),('The\ZEnd');
select * from t1 procedure analyse(); select * from t1 procedure analyse();
...@@ -157,3 +86,40 @@ SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE(); ...@@ -157,3 +86,40 @@ SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE();
ERROR HY000: Incorrect usage of PROCEDURE and subquery ERROR HY000: Incorrect usage of PROCEDURE and subquery
DROP TABLE t1; DROP TABLE t1;
End of 4.1 tests End of 4.1 tests
#
# Bug #48293: crash with procedure analyse, view with > 10 columns,
# having clause...
#
CREATE TABLE t1(a INT, b INT, c INT, d INT, e INT,
f INT, g INT, h INT, i INT, j INT,k INT);
INSERT INTO t1 VALUES (),();
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
#should have a derived table
EXPLAIN SELECT * FROM v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ALL NULL NULL NULL NULL 2
#should not crash
SELECT * FROM v1 PROCEDURE analyse();
ERROR HY000: Incorrect usage of PROCEDURE and view
#should not crash
SELECT * FROM t1 a, v1, t1 b PROCEDURE analyse();
ERROR HY000: Incorrect usage of PROCEDURE and view
#should not crash
SELECT * FROM (SELECT * FROM t1 having a > 1) x PROCEDURE analyse();
ERROR HY000: Incorrect usage of PROCEDURE and subquery
#should not crash
SELECT * FROM t1 a, (SELECT * FROM t1 having a > 1) x, t1 b PROCEDURE analyse();
ERROR HY000: Incorrect usage of PROCEDURE and subquery
#should not crash
SELECT 1 FROM t1 group by a having a > 1 order by 1 PROCEDURE analyse();
ERROR HY000: Can't use ORDER clause with this procedure
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1),(2);
# should not crash
CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE();
ERROR HY000: Incorrect usage of PROCEDURE and non-SELECT
DROP TABLE t1;
End of 5.0 tests
...@@ -26,4 +26,27 @@ SELECT * FROM t1; ...@@ -26,4 +26,27 @@ SELECT * FROM t1;
a b a b
1070109 99 1070109 99
DROP TABLE t2, t1; DROP TABLE t2, t1;
End of 5.0 tests # End of 5.0 tests
#
# Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT
# FOR UPDATE
#
drop table if exists t1;
create table t1 (a int primary key auto_increment,
b int, index(b)) engine=innodb;
insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
set autocommit=0;
begin;
select * from t1 where b=5 for update;
a b
5 5
insert ignore into t1 (b) select a as b from t1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
# Cleanup
#
commit;
set autocommit=default;
drop table t1;
#
# End of 5.1 tests
#
...@@ -1063,6 +1063,60 @@ a b c d ...@@ -1063,6 +1063,60 @@ a b c d
127 NULL 127 NULL 127 NULL 127 NULL
128 NULL 128 NULL 128 NULL 128 NULL
DROP TABLE IF EXISTS t1,t2; DROP TABLE IF EXISTS t1,t2;
#
# Bug #42116: Mysql crash on specific query
#
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT);
CREATE TABLE t3 (a INT, INDEX (a));
CREATE TABLE t4 (a INT);
CREATE TABLE t5 (a INT);
CREATE TABLE t6 (a INT);
INSERT INTO t1 VALUES (1), (1), (1);
INSERT INTO t2 VALUES
(2), (2), (2), (2), (2), (2), (2), (2), (2), (2);
INSERT INTO t3 VALUES
(3), (3), (3), (3), (3), (3), (3), (3), (3), (3);
EXPLAIN
SELECT *
FROM
t1 JOIN t2 ON t1.a = t2.a
LEFT JOIN
(
(
t3 LEFT JOIN t4 ON t3.a = t4.a
)
LEFT JOIN
(
t5 LEFT JOIN t6 ON t5.a = t6.a
)
ON t4.a = t5.a
)
ON t1.a = t3.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
1 SIMPLE t3 ref a a 5 test.t1.a 2 Using index
1 SIMPLE t4 ALL NULL NULL NULL NULL 0
1 SIMPLE t5 ALL NULL NULL NULL NULL 0
1 SIMPLE t6 ALL NULL NULL NULL NULL 0
1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer
SELECT *
FROM
t1 JOIN t2 ON t1.a = t2.a
LEFT JOIN
(
(
t3 LEFT JOIN t4 ON t3.a = t4.a
)
LEFT JOIN
(
t5 LEFT JOIN t6 ON t5.a = t6.a
)
ON t4.a = t5.a
)
ON t1.a = t3.a;
a a a a a a
DROP TABLE t1,t2,t3,t4,t5,t6;
End of 5.0 tests. End of 5.0 tests.
CREATE TABLE t1 (f1 int); CREATE TABLE t1 (f1 int);
CREATE TABLE t2 (f1 int); CREATE TABLE t2 (f1 int);
......
...@@ -2290,6 +2290,12 @@ Table Op Msg_type Msg_text ...@@ -2290,6 +2290,12 @@ Table Op Msg_type Msg_text
test.t1 repair error myisam_sort_buffer_size is too small test.t1 repair error myisam_sort_buffer_size is too small
test.t1 repair warning Number of rows changed from 0 to 7168 test.t1 repair warning Number of rows changed from 0 to 7168
test.t1 repair status OK test.t1 repair status OK
SET myisam_repair_threads=2;
REPAIR TABLE t1;
SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1; DROP TABLE t1;
End of 5.1 tests End of 5.1 tests
...@@ -4415,6 +4415,18 @@ SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a); ...@@ -4415,6 +4415,18 @@ SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
1 1
1 1
DROP TABLE t1; DROP TABLE t1;
#
# Bug #48291 : crash with row() operator,select into @var, and
# subquery returning multiple rows
#
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (2),(3);
# Should not crash
SELECT 1 FROM t1 WHERE a <> 1 AND NOT
ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE 1=2),(SELECT 1 FROM t1))
INTO @var0;
ERROR 21000: Subquery returns more than 1 row
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
create table t1(a INT, KEY (a)); create table t1(a INT, KEY (a));
INSERT INTO t1 VALUES (1),(2),(3),(4),(5); INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
......
...@@ -75,7 +75,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); ...@@ -75,7 +75,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1)); select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
ERROR HY000: Incorrect usage of PROCEDURE and subquery ERROR HY000: Incorrect usage of PROCEDURE and subquery
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1)); SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
ERROR HY000: Incorrect usage of PROCEDURE and subquery ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
ERROR 42S22: Unknown column 'a' in 'field list' ERROR 42S22: Unknown column 'a' in 'field list'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL; SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
......
...@@ -130,7 +130,7 @@ NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI ...@@ -130,7 +130,7 @@ NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
NULL mysql procs_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references NULL mysql procs_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
NULL mysql procs_priv Proc_priv 7 NO set 27 81 NULL NULL utf8 utf8_general_ci set('Execute','Alter Routine','Grant') select,insert,update,references NULL mysql procs_priv Proc_priv 7 NO set 27 81 NULL NULL utf8 utf8_general_ci set('Execute','Alter Routine','Grant') select,insert,update,references
NULL mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references NULL mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
NULL mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI select,insert,update,references NULL mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
NULL mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references NULL mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
NULL mysql procs_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references NULL mysql procs_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
...@@ -411,7 +411,7 @@ NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp ...@@ -411,7 +411,7 @@ NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
3.0000 mysql procs_priv Host char 60 180 utf8 utf8_bin char(60) 3.0000 mysql procs_priv Host char 60 180 utf8 utf8_bin char(60)
3.0000 mysql procs_priv Db char 64 192 utf8 utf8_bin char(64) 3.0000 mysql procs_priv Db char 64 192 utf8 utf8_bin char(64)
3.0000 mysql procs_priv User char 16 48 utf8 utf8_bin char(16) 3.0000 mysql procs_priv User char 16 48 utf8 utf8_bin char(16)
3.0000 mysql procs_priv Routine_name char 64 192 utf8 utf8_bin char(64) 3.0000 mysql procs_priv Routine_name char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql procs_priv Routine_type enum 9 27 utf8 utf8_bin enum('FUNCTION','PROCEDURE') 3.0000 mysql procs_priv Routine_type enum 9 27 utf8 utf8_bin enum('FUNCTION','PROCEDURE')
3.0000 mysql procs_priv Grantor char 77 231 utf8 utf8_bin char(77) 3.0000 mysql procs_priv Grantor char 77 231 utf8 utf8_bin char(77)
3.0000 mysql procs_priv Proc_priv set 27 81 utf8 utf8_general_ci set('Execute','Alter Routine','Grant') 3.0000 mysql procs_priv Proc_priv set 27 81 utf8 utf8_general_ci set('Execute','Alter Routine','Grant')
......
...@@ -166,8 +166,8 @@ NULL db_datadict_2 t4 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH ...@@ -166,8 +166,8 @@ NULL db_datadict_2 t4 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH
SHOW GRANTS FOR 'testuser1'@'localhost'; SHOW GRANTS FOR 'testuser1'@'localhost';
Grants for testuser1@localhost Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost' GRANT USAGE ON *.* TO 'testuser1'@'localhost'
GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
GRANT SELECT ON `db_datadict`.`t1` TO 'testuser1'@'localhost' WITH GRANT OPTION GRANT SELECT ON `db_datadict`.`t1` TO 'testuser1'@'localhost' WITH GRANT OPTION
GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
SHOW GRANTS FOR 'testuser2'@'localhost'; SHOW GRANTS FOR 'testuser2'@'localhost';
Grants for testuser2@localhost Grants for testuser2@localhost
GRANT USAGE ON *.* TO 'testuser2'@'localhost' GRANT USAGE ON *.* TO 'testuser2'@'localhost'
...@@ -185,8 +185,8 @@ NULL db_datadict_2 t3 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH ...@@ -185,8 +185,8 @@ NULL db_datadict_2 t3 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH
SHOW GRANTS FOR 'testuser1'@'localhost'; SHOW GRANTS FOR 'testuser1'@'localhost';
Grants for testuser1@localhost Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost' GRANT USAGE ON *.* TO 'testuser1'@'localhost'
GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
GRANT SELECT ON `db_datadict`.`t1` TO 'testuser1'@'localhost' WITH GRANT OPTION GRANT SELECT ON `db_datadict`.`t1` TO 'testuser1'@'localhost' WITH GRANT OPTION
GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
SHOW GRANTS FOR 'testuser2'@'localhost'; SHOW GRANTS FOR 'testuser2'@'localhost';
ERROR 42000: Access denied for user 'testuser1'@'localhost' to database 'mysql' ERROR 42000: Access denied for user 'testuser1'@'localhost' to database 'mysql'
# Switch to connection testuser2 # Switch to connection testuser2
......
...@@ -4,8 +4,10 @@ reset master; ...@@ -4,8 +4,10 @@ reset master;
reset slave; reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
call mtr.add_suppression("Slave I/O: .* failed with error: Lost connection to MySQL server at 'reading initial communication packet'"); call mtr.add_suppression("Get master clock failed with error: ");
call mtr.add_suppression("Get master SERVER_ID failed with error: ");
call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again"); call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again");
call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*");
SELECT IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP"); SELECT IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP");
IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP") IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP")
1 1
......
...@@ -19,6 +19,9 @@ source include/have_debug.inc; ...@@ -19,6 +19,9 @@ source include/have_debug.inc;
call mtr.add_suppression("Slave I/O: .* failed with error: Lost connection to MySQL server at 'reading initial communication packet'"); call mtr.add_suppression("Slave I/O: .* failed with error: Lost connection to MySQL server at 'reading initial communication packet'");
call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again"); call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again");
call mtr.add_suppression("Get master clock failed with error: ");
call mtr.add_suppression("Get master SERVER_ID failed with error: ");
call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*");
#Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection #Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection
connection slave; connection slave;
......
...@@ -10,36 +10,13 @@ insert into t1 values (1,2,"","Y","2002-03-03"), (3,4,"","N","2002-03-04"), (5,6 ...@@ -10,36 +10,13 @@ insert into t1 values (1,2,"","Y","2002-03-03"), (3,4,"","N","2002-03-04"), (5,6
select count(*) from t1 procedure analyse(); select count(*) from t1 procedure analyse();
select * from t1 procedure analyse(); select * from t1 procedure analyse();
select * from t1 procedure analyse(2); select * from t1 procedure analyse(2);
--error ER_WRONG_USAGE
create table t2 select * from t1 procedure analyse(); create table t2 select * from t1 procedure analyse();
select * from t2; drop table t1;
drop table t1,t2;
--error ER_WRONG_USAGE --error ER_WRONG_USAGE
EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(); EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE();
#
# Test with impossible where
#
create table t1 (a int not null);
create table t2 select * from t1 where 0=1 procedure analyse();
show create table t2;
select * from t1 where 0=1 procedure analyse();
insert into t1 values(1);
drop table t2;
create table t2 select * from t1 where 0=1 procedure analyse();
show create table t2;
select * from t2;
insert into t2 select * from t1 procedure analyse();
select * from t2;
insert into t1 values(2);
drop table t2;
create table t2 select * from t1 where 0=1 procedure analyse();
show create table t2;
select * from t2;
insert into t2 select * from t1 procedure analyse();
select * from t2;
drop table t1,t2;
# #
# Bug#2813 - analyse does not quote string values in enums from string # Bug#2813 - analyse does not quote string values in enums from string
# #
...@@ -113,3 +90,46 @@ SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE(); ...@@ -113,3 +90,46 @@ SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE();
DROP TABLE t1; DROP TABLE t1;
--echo End of 4.1 tests --echo End of 4.1 tests
--echo #
--echo # Bug #48293: crash with procedure analyse, view with > 10 columns,
--echo # having clause...
--echo #
CREATE TABLE t1(a INT, b INT, c INT, d INT, e INT,
f INT, g INT, h INT, i INT, j INT,k INT);
INSERT INTO t1 VALUES (),();
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
--echo #should have a derived table
EXPLAIN SELECT * FROM v1;
--echo #should not crash
--error ER_WRONG_USAGE
SELECT * FROM v1 PROCEDURE analyse();
--echo #should not crash
--error ER_WRONG_USAGE
SELECT * FROM t1 a, v1, t1 b PROCEDURE analyse();
--echo #should not crash
--error ER_WRONG_USAGE
SELECT * FROM (SELECT * FROM t1 having a > 1) x PROCEDURE analyse();
--echo #should not crash
--error ER_WRONG_USAGE
SELECT * FROM t1 a, (SELECT * FROM t1 having a > 1) x, t1 b PROCEDURE analyse();
--echo #should not crash
--error ER_ORDER_WITH_PROC
SELECT 1 FROM t1 group by a having a > 1 order by 1 PROCEDURE analyse();
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1),(2);
--echo # should not crash
--error ER_WRONG_USAGE
CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE();
DROP TABLE t1;
--echo End of 5.0 tests
...@@ -43,4 +43,33 @@ DISCONNECT addconroot; ...@@ -43,4 +43,33 @@ DISCONNECT addconroot;
DROP TABLE t2, t1; DROP TABLE t2, t1;
--echo End of 5.0 tests --echo # End of 5.0 tests
--echo #
--echo # Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT
--echo # FOR UPDATE
--echo #
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int primary key auto_increment,
b int, index(b)) engine=innodb;
insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
set autocommit=0;
begin;
select * from t1 where b=5 for update;
connect (con1, localhost, root,,);
connection con1;
--error ER_LOCK_WAIT_TIMEOUT
insert ignore into t1 (b) select a as b from t1;
connection default;
--echo # Cleanup
--echo #
disconnect con1;
commit;
set autocommit=default;
drop table t1;
--echo #
--echo # End of 5.1 tests
--echo #
...@@ -730,6 +730,60 @@ SELECT * FROM t1 JOIN t2 ON a=c ORDER BY a; ...@@ -730,6 +730,60 @@ SELECT * FROM t1 JOIN t2 ON a=c ORDER BY a;
DROP TABLE IF EXISTS t1,t2; DROP TABLE IF EXISTS t1,t2;
--echo #
--echo # Bug #42116: Mysql crash on specific query
--echo #
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT);
CREATE TABLE t3 (a INT, INDEX (a));
CREATE TABLE t4 (a INT);
CREATE TABLE t5 (a INT);
CREATE TABLE t6 (a INT);
INSERT INTO t1 VALUES (1), (1), (1);
INSERT INTO t2 VALUES
(2), (2), (2), (2), (2), (2), (2), (2), (2), (2);
INSERT INTO t3 VALUES
(3), (3), (3), (3), (3), (3), (3), (3), (3), (3);
EXPLAIN
SELECT *
FROM
t1 JOIN t2 ON t1.a = t2.a
LEFT JOIN
(
(
t3 LEFT JOIN t4 ON t3.a = t4.a
)
LEFT JOIN
(
t5 LEFT JOIN t6 ON t5.a = t6.a
)
ON t4.a = t5.a
)
ON t1.a = t3.a;
SELECT *
FROM
t1 JOIN t2 ON t1.a = t2.a
LEFT JOIN
(
(
t3 LEFT JOIN t4 ON t3.a = t4.a
)
LEFT JOIN
(
t5 LEFT JOIN t6 ON t5.a = t6.a
)
ON t4.a = t5.a
)
ON t1.a = t3.a;
DROP TABLE t1,t2,t3,t4,t5,t6;
--echo End of 5.0 tests. --echo End of 5.0 tests.
......
...@@ -1539,14 +1539,14 @@ INSERT INTO t1 SELECT a+5120,b FROM t1; ...@@ -1539,14 +1539,14 @@ INSERT INTO t1 SELECT a+5120,b FROM t1;
SET myisam_sort_buffer_size=4; SET myisam_sort_buffer_size=4;
REPAIR TABLE t1; REPAIR TABLE t1;
# !!! Disabled until additional fix for BUG#47073 is pushed. SET myisam_repair_threads=2;
#SET myisam_repair_threads=2;
# May report different values depending on threads activity. # May report different values depending on threads activity.
#--replace_regex /changed from [0-9]+/changed from #/ --disable_result_log
#REPAIR TABLE t1; REPAIR TABLE t1;
#SET myisam_repair_threads=@@global.myisam_repair_threads; --enable_result_log
SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
CHECK TABLE t1;
DROP TABLE t1; DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests
......
...@@ -3755,7 +3755,24 @@ EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a); ...@@ -3755,7 +3755,24 @@ EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a); SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug #48291 : crash with row() operator,select into @var, and
--echo # subquery returning multiple rows
--echo #
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (2),(3);
--echo # Should not crash
--error ER_SUBQUERY_NO_1_ROW
SELECT 1 FROM t1 WHERE a <> 1 AND NOT
ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE 1=2),(SELECT 1 FROM t1))
INTO @var0;
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
# #
......
...@@ -30,7 +30,7 @@ SELECT 1 IN (SELECT 1); ...@@ -30,7 +30,7 @@ SELECT 1 IN (SELECT 1);
SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
-- error ER_WRONG_USAGE -- error ER_WRONG_USAGE
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1)); select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
-- error ER_WRONG_USAGE -- error ER_WRONG_PARAMETERS_TO_PROCEDURE
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1)); SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
-- error ER_BAD_FIELD_ERROR -- error ER_BAD_FIELD_ERROR
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
......
...@@ -2723,9 +2723,11 @@ bool select_dumpvar::send_data(List<Item> &items) ...@@ -2723,9 +2723,11 @@ bool select_dumpvar::send_data(List<Item> &items)
else else
{ {
Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item); Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
suv->fix_fields(thd, 0); if (suv->fix_fields(thd, 0))
DBUG_RETURN (1);
suv->save_item_result(item); suv->save_item_result(item);
suv->update(); if (suv->update())
DBUG_RETURN (1);
} }
} }
DBUG_RETURN(thd->is_error()); DBUG_RETURN(thd->is_error());
...@@ -3215,6 +3217,16 @@ void mark_transaction_to_rollback(THD *thd, bool all) ...@@ -3215,6 +3217,16 @@ void mark_transaction_to_rollback(THD *thd, bool all)
{ {
thd->is_fatal_sub_stmt_error= TRUE; thd->is_fatal_sub_stmt_error= TRUE;
thd->transaction_rollback_request= all; thd->transaction_rollback_request= all;
/*
Aborted transactions can not be IGNOREd.
Switch off the IGNORE flag for the current
SELECT_LEX. This should allow my_error()
to report the error and abort the execution
flow, even in presence
of IGNORE clause.
*/
if (thd->lex->current_select)
thd->lex->current_select->no_error= FALSE;
} }
} }
/*************************************************************************** /***************************************************************************
......
...@@ -636,6 +636,18 @@ JOIN::prepare(Item ***rref_pointer_array, ...@@ -636,6 +636,18 @@ JOIN::prepare(Item ***rref_pointer_array,
MYF(0)); /* purecov: inspected */ MYF(0)); /* purecov: inspected */
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
} }
if (thd->lex->derived_tables)
{
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE",
thd->lex->derived_tables & DERIVED_VIEW ?
"view" : "subquery");
goto err;
}
if (thd->lex->sql_command != SQLCOM_SELECT)
{
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "non-SELECT");
goto err;
}
} }
if (!procedure && result && result->prepare(fields_list, unit_arg)) if (!procedure && result && result->prepare(fields_list, unit_arg))
...@@ -8967,7 +8979,10 @@ static void restore_prev_nj_state(JOIN_TAB *last) ...@@ -8967,7 +8979,10 @@ static void restore_prev_nj_state(JOIN_TAB *last)
join->cur_embedding_map&= ~last_emb->nested_join->nj_map; join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
else if (last_emb->nested_join->join_list.elements-1 == else if (last_emb->nested_join->join_list.elements-1 ==
last_emb->nested_join->counter) last_emb->nested_join->counter)
{
join->cur_embedding_map|= last_emb->nested_join->nj_map; join->cur_embedding_map|= last_emb->nested_join->nj_map;
break;
}
else else
break; break;
last_emb= last_emb->embedding; last_emb= last_emb->embedding;
...@@ -11192,6 +11207,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, ...@@ -11192,6 +11207,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
bool not_used_in_distinct=join_tab->not_used_in_distinct; bool not_used_in_distinct=join_tab->not_used_in_distinct;
ha_rows found_records=join->found_records; ha_rows found_records=join->found_records;
COND *select_cond= join_tab->select_cond; COND *select_cond= join_tab->select_cond;
bool select_cond_result= TRUE;
if (error > 0 || (join->thd->is_error())) // Fatal error if (error > 0 || (join->thd->is_error())) // Fatal error
return NESTED_LOOP_ERROR; return NESTED_LOOP_ERROR;
...@@ -11203,7 +11219,17 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, ...@@ -11203,7 +11219,17 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
return NESTED_LOOP_KILLED; /* purecov: inspected */ return NESTED_LOOP_KILLED; /* purecov: inspected */
} }
DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond)); DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond));
if (!select_cond || select_cond->val_int())
if (select_cond)
{
select_cond_result= test(select_cond->val_int());
/* check for errors evaluating the condition */
if (join->thd->is_error())
return NESTED_LOOP_ERROR;
}
if (!select_cond || select_cond_result)
{ {
/* /*
There is no select condition or the attached pushed down There is no select condition or the attached pushed down
......
...@@ -9082,8 +9082,7 @@ procedure_clause: ...@@ -9082,8 +9082,7 @@ procedure_clause:
MYSQL_YYABORT; MYSQL_YYABORT;
} }
if (&lex->select_lex != lex->current_select || if (&lex->select_lex != lex->current_select)
lex->select_lex.get_table_list()->derived)
{ {
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery"); my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
MYSQL_YYABORT; MYSQL_YYABORT;
......
...@@ -116,6 +116,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, ...@@ -116,6 +116,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
Also we likely need to lock mutex here (in both cases with protocol and Also we likely need to lock mutex here (in both cases with protocol and
push_warning). push_warning).
*/ */
#ifdef THREAD
if (param->need_print_msg_lock)
pthread_mutex_lock(&param->print_msg_mutex);
#endif
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store(name, length, system_charset_info); protocol->store(name, length, system_charset_info);
protocol->store(param->op_name, system_charset_info); protocol->store(param->op_name, system_charset_info);
...@@ -124,6 +128,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, ...@@ -124,6 +128,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
if (protocol->write()) if (protocol->write())
sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n", sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
msgbuf); msgbuf);
#ifdef THREAD
if (param->need_print_msg_lock)
pthread_mutex_unlock(&param->print_msg_mutex);
#endif
return; return;
} }
......
...@@ -104,6 +104,9 @@ void myisamchk_init(MI_CHECK *param) ...@@ -104,6 +104,9 @@ void myisamchk_init(MI_CHECK *param)
param->max_record_length= LONGLONG_MAX; param->max_record_length= LONGLONG_MAX;
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE; param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL; param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
#ifdef THREAD
param->need_print_msg_lock= 0;
#endif
} }
/* Check the status flags for the table */ /* Check the status flags for the table */
...@@ -2703,6 +2706,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, ...@@ -2703,6 +2706,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
/* Initialize pthread structures before goto err. */ /* Initialize pthread structures before goto err. */
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST); pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&sort_info.cond, 0); pthread_cond_init(&sort_info.cond, 0);
pthread_mutex_init(&param->print_msg_mutex, MY_MUTEX_INIT_FAST);
param->need_print_msg_lock= 1;
if (!(sort_info.key_block= if (!(sort_info.key_block=
alloc_key_blocks(param, (uint) param->sort_key_blocks, alloc_key_blocks(param, (uint) param->sort_key_blocks,
...@@ -3108,6 +3113,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, ...@@ -3108,6 +3113,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
pthread_cond_destroy (&sort_info.cond); pthread_cond_destroy (&sort_info.cond);
pthread_mutex_destroy(&sort_info.mutex); pthread_mutex_destroy(&sort_info.mutex);
pthread_mutex_destroy(&param->print_msg_mutex);
param->need_print_msg_lock= 0;
my_free((uchar*) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR)); my_free((uchar*) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR));
my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR)); my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
......
...@@ -466,8 +466,12 @@ pthread_handler_t thr_find_all_keys(void *arg) ...@@ -466,8 +466,12 @@ pthread_handler_t thr_find_all_keys(void *arg)
Detach from the share if the writer is involved. Avoid others to Detach from the share if the writer is involved. Avoid others to
be blocked. This includes a flush of the write buffer. This will be blocked. This includes a flush of the write buffer. This will
also indicate EOF to the readers. also indicate EOF to the readers.
That means that a writer always gets here first and readers -
only when they see EOF. But if a reader finishes prematurely
because of an error it may reach this earlier - don't allow it
to detach the writer thread.
*/ */
if (sort_param->sort_info->info->rec_cache.share) if (sort_param->master && sort_param->sort_info->info->rec_cache.share)
remove_io_thread(&sort_param->sort_info->info->rec_cache); remove_io_thread(&sort_param->sort_info->info->rec_cache);
/* Readers detach from the share if any. Avoid others to be blocked. */ /* Readers detach from the share if any. Avoid others to be blocked. */
...@@ -789,6 +793,7 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys, ...@@ -789,6 +793,7 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
close_cached_file(to_file); /* This holds old result */ close_cached_file(to_file); /* This holds old result */
if (to_file == t_file) if (to_file == t_file)
{ {
DBUG_ASSERT(t_file2.type == WRITE_CACHE);
*t_file=t_file2; /* Copy result file */ *t_file=t_file2; /* Copy result file */
t_file->current_pos= &t_file->write_pos; t_file->current_pos= &t_file->write_pos;
t_file->current_end= &t_file->write_end; t_file->current_end= &t_file->write_end;
......
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