Automerge.

This commit is contained in:
Davi Arnaut 2009-11-25 11:09:12 -02:00
commit 40767bf54a
110 changed files with 3524 additions and 1047 deletions

View file

@ -4474,9 +4474,7 @@ server_version_string(MYSQL *con)
*/
if (server_version == NULL)
{
server_version= strdup(mysql_get_server_info(con));
}
server_version= my_strdup(mysql_get_server_info(con), MYF(MY_WME));
}
return server_version ? server_version : "";

View file

@ -6827,10 +6827,8 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
MYSQL_STMT *stmt;
DYNAMIC_STRING ds_prepare_warnings;
DYNAMIC_STRING ds_execute_warnings;
ulonglong affected_rows;
DBUG_ENTER("run_query_stmt");
DBUG_PRINT("query", ("'%-.60s'", query));
LINT_INIT(affected_rows);
/*
Init a new stmt if it's not already one created for this connection
@ -6966,8 +6964,7 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
warnings here
*/
{
ulonglong affected_rows;
LINT_INIT(affected_rows);
ulonglong UNINIT_VAR(affected_rows);
if (!disable_info)
affected_rows= mysql_affected_rows(mysql);

View file

@ -10,12 +10,12 @@ AC_CANONICAL_SYSTEM
#
# When changing major version number please also check switch statement
# in mysqlbinlog::check_master_version().
AM_INIT_AUTOMAKE(mysql, 5.1.41)
AM_INIT_AUTOMAKE(mysql, 5.1.42)
AM_CONFIG_HEADER([include/config.h:config.h.in])
# Request support for automake silent-rules if available.
# Default to verbose output. One can use the configure-time
# option --enable-silent-rules or make V=1 to activate
# option --enable-silent-rules or make V=0 to activate
# silent rules.
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([no])])

View file

@ -660,7 +660,7 @@ static ha_checksum checksum_format_specifier(const char* msg)
case 'u':
case 'x':
case 's':
chksum= my_checksum(chksum, start, (uint) (p - start));
chksum= my_checksum(chksum, start, (uint) (p + 1 - start));
start= 0; /* Not in format specifier anymore */
break;
@ -1030,8 +1030,10 @@ static char *parse_text_line(char *pos)
{
int i, nr;
char *row= pos;
size_t len;
DBUG_ENTER("parse_text_line");
len= strlen (pos);
while (*pos)
{
if (*pos == '\\')
@ -1039,11 +1041,11 @@ static char *parse_text_line(char *pos)
switch (*++pos) {
case '\\':
case '"':
VOID(strmov(pos - 1, pos));
VOID(memmove (pos - 1, pos, len - (row - pos)));
break;
case 'n':
pos[-1]= '\n';
VOID(strmov(pos, pos + 1));
VOID(memmove (pos, pos + 1, len - (row - pos)));
break;
default:
if (*pos >= '0' && *pos < '8')
@ -1053,10 +1055,10 @@ static char *parse_text_line(char *pos)
nr= nr * 8 + (*(pos++) - '0');
pos -= i;
pos[-1]= nr;
VOID(strmov(pos, pos + i));
VOID(memmove (pos, pos + i, len - (row - pos)));
}
else if (*pos)
VOID(strmov(pos - 1, pos)); /* Remove '\' */
VOID(memmove (pos - 1, pos, len - (row - pos))); /* Remove '\' */
}
}
else

View file

@ -557,16 +557,6 @@ unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
char *to,const char *from,
unsigned long length);
void STDCALL mysql_debug(const char *debug);
char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
char *to,
unsigned long to_length,
const char *from,
unsigned long from_length,
void *param,
char *
(*extend_buffer)
(void *, char *to,
unsigned long *length));
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int STDCALL mysql_thread_safe(void);
my_bool STDCALL mysql_embedded(void);

View file

@ -518,16 +518,6 @@ unsigned long mysql_real_escape_string(MYSQL *mysql,
char *to,const char *from,
unsigned long length);
void mysql_debug(const char *debug);
char * mysql_odbc_escape_string(MYSQL *mysql,
char *to,
unsigned long to_length,
const char *from,
unsigned long from_length,
void *param,
char *
(*extend_buffer)
(void *, char *to,
unsigned long *length));
void myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int mysql_thread_safe(void);
my_bool mysql_embedded(void);

View file

@ -224,8 +224,8 @@ struct st_vio
#endif /* HAVE_SMEM */
#ifdef _WIN32
OVERLAPPED pipe_overlapped;
DWORD read_timeout_millis;
DWORD write_timeout_millis;
DWORD read_timeout_ms;
DWORD write_timeout_ms;
#endif
};
#endif /* vio_violite_h_ */

View file

@ -1629,20 +1629,6 @@ mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
return (uint) escape_string_for_mysql(mysql->charset, to, 0, from, length);
}
char * STDCALL
mysql_odbc_escape_string(MYSQL *mysql __attribute__((unused)),
char *to __attribute__((unused)),
ulong to_length __attribute__((unused)),
const char *from __attribute__((unused)),
ulong from_length __attribute__((unused)),
void *param __attribute__((unused)),
char * (*extend_buffer)(void *, char *, ulong *)
__attribute__((unused)))
{
return NULL;
}
void STDCALL
myodbc_remove_escape(MYSQL *mysql,char *name)
{

View file

@ -78,7 +78,6 @@ EXPORTS
mysql_next_result
mysql_num_fields
mysql_num_rows
mysql_odbc_escape_string
mysql_options
mysql_stmt_param_count
mysql_stmt_param_metadata

View file

@ -50,7 +50,6 @@ EXPORTS
mysql_next_result
mysql_num_fields
mysql_num_rows
mysql_odbc_escape_string
mysql_options
mysql_ping
mysql_query

View file

@ -407,37 +407,57 @@ sync_slave_with_master;
###########################################
# Bug#22234, Bug#23907 Extra Slave Col is not
# erroring on extra col with no default values.
########################################################
###############################################################
# Error reaction is up to sql_mode of the slave sql (bug#38173)
#--echo *** Create t9 on slave ***
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t9 (a INT KEY, b BLOB, c CHAR(5),
d TIMESTAMP,
e INT NOT NULL) ENGINE=$engine_type;
# Please, check BUG#47741 to see why you are not testing NDB.
if (`SELECT $engine_type != 'NDB'`)
{
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t9 (a INT KEY, b BLOB, c CHAR(5),
d TIMESTAMP,
e INT NOT NULL,
f text not null,
g text,
h blob not null,
i blob) ENGINE=$engine_type;
--echo *** Create t9 on Master ***
connection master;
eval CREATE TABLE t9 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
--echo *** Create t9 on Master ***
connection master;
eval CREATE TABLE t9 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
) ENGINE=$engine_type;
RESET MASTER;
RESET MASTER;
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo *** Master Data Insert ***
connection master;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t9 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
--echo *** Master Data Insert ***
connection master;
set @b1 = 'b1b1b1b1';
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
set @b1 = concat(@b1,@b1);
INSERT INTO t9 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
# the test would stop slave if @@sql_mode for the sql thread
# was set to strict. Otherwise, as with this tests setup,
# the implicit defaults will be inserted into fields even though
# they are declared without DEFAULT clause.
sync_slave_with_master;
select * from t9;
# todo: fix Bug #43992 slave sql thread can't tune own sql_mode ...
# and add/restore waiting for stop test
#--source include/wait_for_slave_sql_to_stop.inc
#--replace_result $MASTER_MYPORT MASTER_PORT
#--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
#--query_vertical SHOW SLAVE STATUS
#SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
#START SLAVE;
}
#--echo *** Drop t9 ***
#connection master;

View file

@ -0,0 +1,364 @@
#################################################################################
# This test checks if the replication between "null" fields to either "null"
# fields or "not null" fields works properly. In the first case, the execution
# should work fine. In the second case, it may fail according to the sql_mode
# being used.
#
# The test is devided in three main parts:
#
# 1 - NULL --> NULL (no failures)
# 2 - NULL --> NOT NULL ( sql-mode = STRICT and failures)
# 3 - NULL --> NOT NULL ( sql-mode != STRICT and no failures)
#
#################################################################################
connection master;
SET SQL_LOG_BIN= 0;
eval CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
`c` INT DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
eval CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
eval CREATE TABLE t3(`a` INT, `b` DATE DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
eval CREATE TABLE t4(`a` INT, `b` DATE DEFAULT NULL,
`c` INT DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
SET SQL_LOG_BIN= 1;
connection slave;
eval CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
`c` INT DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
eval CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
eval CREATE TABLE t3(`a` INT, `b` DATE DEFAULT '0000-00-00',
`c` INT DEFAULT 500,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
eval CREATE TABLE t4(`a` INT, `b` DATE DEFAULT '0000-00-00',
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
--echo ************* EXECUTION WITH INSERTS *************
connection master;
INSERT INTO t1(a,b,c) VALUES (1, null, 1);
INSERT INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
INSERT INTO t1(a,b) VALUES (3, null);
INSERT INTO t1(a,c) VALUES (4, 4);
INSERT INTO t1(a) VALUES (5);
INSERT INTO t2(a,b) VALUES (1, null);
INSERT INTO t2(a,b) VALUES (2,'1111-11-11');
INSERT INTO t2(a) VALUES (3);
INSERT INTO t3(a,b) VALUES (1, null);
INSERT INTO t3(a,b) VALUES (2,'1111-11-11');
INSERT INTO t3(a) VALUES (3);
INSERT INTO t4(a,b,c) VALUES (1, null, 1);
INSERT INTO t4(a,b,c) VALUES (2,'1111-11-11', 2);
INSERT INTO t4(a,b) VALUES (3, null);
INSERT INTO t4(a,c) VALUES (4, 4);
INSERT INTO t4(a) VALUES (5);
--echo ************* SHOWING THE RESULT SETS WITH INSERTS *************
sync_slave_with_master;
--echo TABLES t1 and t2 must be equal otherwise an error will be thrown.
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
let $diff_table_1=master:test.t2;
let $diff_table_2=slave:test.t2;
source include/diff_tables.inc;
--echo TABLES t2 and t3 must be different.
connection master;
SELECT * FROM t3 ORDER BY a;
connection slave;
SELECT * FROM t3 ORDER BY a;
connection master;
SELECT * FROM t4 ORDER BY a;
connection slave;
SELECT * FROM t4 ORDER BY a;
--echo ************* EXECUTION WITH UPDATES and REPLACES *************
connection master;
DELETE FROM t1;
INSERT INTO t1(a,b,c) VALUES (1,'1111-11-11', 1);
REPLACE INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
UPDATE t1 set b= NULL, c= 300 where a= 1;
REPLACE INTO t1(a,b,c) VALUES (2, NULL, 300);
--echo ************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
sync_slave_with_master;
--echo TABLES t1 and t2 must be equal otherwise an error will be thrown.
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
--echo ************* CLEANING *************
connection master;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
sync_slave_with_master;
connection master;
SET SQL_LOG_BIN= 0;
eval CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT NULL, `c` BIT DEFAULT NULL,
PRIMARY KEY (`a`)) ENGINE= $engine;
SET SQL_LOG_BIN= 1;
connection slave;
eval CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT b'01', `c` BIT DEFAULT NULL,
PRIMARY KEY (`a`)) ENGINE= $engine;
--echo ************* EXECUTION WITH INSERTS *************
connection master;
INSERT INTO t1(a,b,c) VALUES (1, null, b'01');
INSERT INTO t1(a,b,c) VALUES (2,b'00', b'01');
INSERT INTO t1(a,b) VALUES (3, null);
INSERT INTO t1(a,c) VALUES (4, b'01');
INSERT INTO t1(a) VALUES (5);
--echo ************* SHOWING THE RESULT SETS WITH INSERTS *************
--echo TABLES t1 and t2 must be different.
sync_slave_with_master;
connection master;
SELECT a,b+0,c+0 FROM t1 ORDER BY a;
connection slave;
SELECT a,b+0,c+0 FROM t1 ORDER BY a;
--echo ************* EXECUTION WITH UPDATES and REPLACES *************
connection master;
DELETE FROM t1;
INSERT INTO t1(a,b,c) VALUES (1,b'00', b'01');
REPLACE INTO t1(a,b,c) VALUES (2,b'00',b'01');
UPDATE t1 set b= NULL, c= b'00' where a= 1;
REPLACE INTO t1(a,b,c) VALUES (2, NULL, b'00');
--echo ************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
--echo TABLES t1 and t2 must be equal otherwise an error will be thrown.
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
connection master;
DROP TABLE t1;
sync_slave_with_master;
--echo ################################################################################
--echo # NULL ---> NOT NULL (STRICT MODE)
--echo # UNCOMMENT THIS AFTER FIXING BUG#43992
--echo ################################################################################
#connection slave;
#SET GLOBAL sql_mode="TRADITIONAL";
#
#STOP SLAVE;
#--source include/wait_for_slave_to_stop.inc
#START SLAVE;
#--source include/wait_for_slave_to_start.inc
#
#let $y=0;
#while (`select $y < 6`)
#{
# connection master;
#
# SET SQL_LOG_BIN= 0;
# eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
# eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
# eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
# SET SQL_LOG_BIN= 1;
#
# connection slave;
#
# eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
# `c` INT NOT NULL,
# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
# eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
# `c` INT,
# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
# eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
# `c` INT DEFAULT 500,
# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
#
# if (`select $y=0`)
# {
# --echo ************* EXECUTION WITH INSERTS *************
# connection master;
# INSERT INTO t1(a) VALUES (1);
# }
#
# if (`select $y=1`)
# {
# --echo ************* EXECUTION WITH INSERTS *************
# connection master;
# INSERT INTO t1(a, b) VALUES (1, NULL);
# }
#
# if (`select $y=2`)
# {
# --echo ************* EXECUTION WITH UPDATES *************
# connection master;
# INSERT INTO t3(a, b) VALUES (1, 1);
# INSERT INTO t3(a, b) VALUES (2, 1);
# UPDATE t3 SET b = NULL where a= 1;
# }
#
# if (`select $y=3`)
# {
# --echo ************* EXECUTION WITH INSERTS/REPLACES *************
# connection master;
# REPLACE INTO t3(a, b) VALUES (1, null);
# }
#
# if (`select $y=4`)
# {
# --echo ************* EXECUTION WITH UPDATES/REPLACES *************
# connection master;
# INSERT INTO t3(a, b) VALUES (1, 1);
# REPLACE INTO t3(a, b) VALUES (1, null);
# }
#
# if (`select $y=5`)
# {
# --echo ************* EXECUTION WITH MULTI-ROW INSERTS *************
# connection master;
#
# SET SQL_LOG_BIN= 0;
# INSERT INTO t2(a, b) VALUES (1, 1);
# INSERT INTO t2(a, b) VALUES (2, 1);
# INSERT INTO t2(a, b) VALUES (3, null);
# INSERT INTO t2(a, b) VALUES (4, 1);
# INSERT INTO t2(a, b) VALUES (5, 1);
# SET SQL_LOG_BIN= 1;
#
# INSERT INTO t2 SELECT a + 10, b from t2;
# --echo The statement below is just executed to stop processing
# INSERT INTO t1(a) VALUES (1);
# }
#
# --echo ************* SHOWING THE RESULT SETS *************
# connection slave;
# --source include/wait_for_slave_sql_to_stop.inc
# connection master;
# SELECT * FROM t1 ORDER BY a;
# connection slave;
# SELECT * FROM t1 ORDER BY a;
# connection master;
# SELECT * FROM t2 ORDER BY a;
# connection slave;
# SELECT * FROM t2 ORDER BY a;
# connection master;
# SELECT * FROM t3 ORDER BY a;
# connection slave;
# SELECT * FROM t3 ORDER BY a;
# --source include/reset_master_and_slave.inc
#
# connection master;
#
# DROP TABLE t1;
# DROP TABLE t2;
# DROP TABLE t3;
#
# sync_slave_with_master;
#
# inc $y;
#}
#connection slave;
#SET GLOBAL sql_mode="";
#
#STOP SLAVE;
#source include/wait_for_slave_to_stop.inc;
#START SLAVE;
#--source include/wait_for_slave_to_start.inc
--echo ################################################################################
--echo # NULL ---> NOT NULL (NON-STRICT MODE)
--echo ################################################################################
connection master;
SET SQL_LOG_BIN= 0;
eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
SET SQL_LOG_BIN= 1;
connection slave;
eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
`c` INT NOT NULL,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
`c` INT,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
`c` INT DEFAULT 500,
PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1;
--echo ************* EXECUTION WITH INSERTS *************
connection master;
INSERT INTO t1(a) VALUES (1);
INSERT INTO t1(a, b) VALUES (2, NULL);
INSERT INTO t1(a, b) VALUES (3, 1);
INSERT INTO t2(a) VALUES (1);
INSERT INTO t2(a, b) VALUES (2, NULL);
INSERT INTO t2(a, b) VALUES (3, 1);
INSERT INTO t3(a) VALUES (1);
INSERT INTO t3(a, b) VALUES (2, NULL);
INSERT INTO t3(a, b) VALUES (3, 1);
INSERT INTO t3(a, b) VALUES (4, 1);
REPLACE INTO t3(a, b) VALUES (5, null);
REPLACE INTO t3(a, b) VALUES (3, null);
UPDATE t3 SET b = NULL where a = 4;
--echo ************* SHOWING THE RESULT SETS *************
connection master;
sync_slave_with_master;
connection master;
SELECT * FROM t1 ORDER BY a;
connection slave;
SELECT * FROM t1 ORDER BY a;
connection master;
SELECT * FROM t2 ORDER BY a;
connection slave;
SELECT * FROM t2 ORDER BY a;
connection master;
SELECT * FROM t3 ORDER BY a;
connection slave;
SELECT * FROM t3 ORDER BY a;
connection master;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
sync_slave_with_master;

View file

@ -111,21 +111,18 @@ SELECT a,b,x FROM t1_int ORDER BY a;
SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit ORDER BY a;
SELECT a,b,x FROM t1_char ORDER BY a;
# Each of these inserts should generate an error and stop the slave
connection master;
INSERT INTO t9 VALUES (2);
sync_slave_with_master;
# Now slave is guaranteed to be running
connection master;
INSERT INTO t1_nodef VALUES (1,2);
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 20 <Last_Error> 22 # 23 # 33 # 35 <Last_IO_Errno> 36 <Last_IO_Error> 38 <Last_SQL_Error>
--query_vertical SHOW SLAVE STATUS
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
# Last insert on wider slave table succeeds while slave sql sql_mode permits.
# The previous version of the above test expected slave sql to stop.
# bug#38173 relaxed conditions to stop only with the strict mode.
sync_slave_with_master;
select count(*) from t1_nodef;
#
# Replicating to tables with fewer columns at the end works as of WL#3228

View file

@ -1,6 +1,11 @@
-- source include/have_binlog_format_mixed_or_statement.inc
# Requires binlog_format=statement format since query involving
# get_lock() is logged in row format if binlog_format=mixed or row.
-- source include/have_binlog_format_statement.inc
-- source include/master-slave.inc
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
# Load some data into t1
create table t1 (word char(20) not null);
load data infile '../../std_data/words.dat' into table t1;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
@ -10,9 +15,7 @@ select * from t1 limit 10;
#
# Test slave with wrong password
#
save_master_pos;
connection slave;
sync_with_master;
sync_slave_with_master;
stop slave;
connection master;
set password for root@"localhost" = password('foo');
@ -29,16 +32,12 @@ sleep 2;
create table t3(n int);
insert into t3 values(1),(2);
save_master_pos;
connection slave;
sync_with_master;
sync_slave_with_master;
select * from t3;
select sum(length(word)) from t1;
connection master;
drop table t1,t3;
save_master_pos;
connection slave;
sync_with_master;
sync_slave_with_master;
# Test if the slave SQL thread can be more than 16K behind the slave
# I/O thread (> IO_SIZE)
@ -77,12 +76,13 @@ unlock tables;
connection master;
create table t2(id int);
insert into t2 values(connection_id());
save_master_pos;
connection master1;
# Avoid generating result
create temporary table t3(n int);
--disable_warnings
insert into t3 select get_lock('crash_lock%20C', 1) from t2;
--enable_warnings
connection master;
send update t1 set n = n + get_lock('crash_lock%20C', 2);
@ -93,8 +93,11 @@ kill @id;
# We don't drop t3 as this is a temporary table
drop table t2;
connection master;
# The get_lock function causes warning for unsafe statement.
--disable_warnings
--error 1317,2013
reap;
--enable_warnings
connection slave;
# The SQL slave thread should now have stopped because the query was killed on
# the master (so it has a non-zero error code in the binlog).
@ -117,16 +120,12 @@ insert into mysql.user (Host, User, Password)
select select_priv,user from mysql.user where user = _binary'blafasel2';
update mysql.user set Select_priv = "Y" where User= _binary"blafasel2";
select select_priv,user from mysql.user where user = _binary'blafasel2';
save_master_pos;
connection slave;
sync_with_master;
sync_slave_with_master;
select n from t1;
select select_priv,user from mysql.user where user = _binary'blafasel2';
connection master1;
drop table t1;
delete from mysql.user where user="blafasel2";
save_master_pos;
connection slave;
sync_with_master;
sync_slave_with_master;
# End of 4.1 tests

View file

@ -310,4 +310,16 @@ a b
2 2
drop table t1;
set global low_priority_updates = @old_delayed_updates;
#
# Bug #47682 strange behaviour of INSERT DELAYED
#
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (f1 integer);
CREATE TABLE t2 (f1 integer);
FLUSH TABLES WITH READ LOCK;
LOCK TABLES t1 READ;
INSERT DELAYED INTO t2 VALUES (1);
Got one of the listed errors
UNLOCK TABLES;
DROP TABLE t1, t2;
End of 5.1 tests

View file

@ -324,3 +324,16 @@ a
1
2
DROP TABLE t1, t2, t3;
#
# Bug #46425 crash in Diagnostics_area::set_ok_status,
# empty statement, DELETE IGNORE
#
CREATE table t1 (i INTEGER);
INSERT INTO t1 VALUES (1);
CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW
BEGIN
INSERT INTO t1 SELECT * FROM t1 AS A;
END |
DELETE IGNORE FROM t1;
ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
DROP TABLE t1;

View file

@ -885,7 +885,7 @@ cast(sum(distinct df) as signed)
3
select cast(min(df) as signed) from t1;
cast(min(df) as signed)
0
1
select 1e8 * sum(distinct df) from t1;
1e8 * sum(distinct df)
330000000
@ -1520,4 +1520,197 @@ max i
# Cleanup
#
DROP TABLE t1;
#
# Bug#43668: Wrong comparison and MIN/MAX for YEAR(2)
#
create table t1 (f1 year(2), f2 year(4), f3 date, f4 datetime);
insert into t1 values
(98,1998,19980101,"1998-01-01 00:00:00"),
(00,2000,20000101,"2000-01-01 00:00:01"),
(02,2002,20020101,"2002-01-01 23:59:59"),
(60,2060,20600101,"2060-01-01 11:11:11"),
(70,1970,19700101,"1970-11-11 22:22:22"),
(NULL,NULL,NULL,NULL);
select min(f1),max(f1) from t1;
min(f1) max(f1)
70 60
select min(f2),max(f2) from t1;
min(f2) max(f2)
1970 2060
select min(f3),max(f3) from t1;
min(f3) max(f3)
1970-01-01 2060-01-01
select min(f4),max(f4) from t1;
min(f4) max(f4)
1970-11-11 22:22:22 2060-01-01 11:11:11
select a.f1 as a, b.f1 as b, a.f1 > b.f1 as gt,
a.f1 < b.f1 as lt, a.f1<=>b.f1 as eq
from t1 a, t1 b;
a b gt lt eq
98 98 0 0 1
00 98 1 0 0
02 98 1 0 0
60 98 1 0 0
70 98 0 1 0
NULL 98 NULL NULL 0
98 00 0 1 0
00 00 0 0 1
02 00 1 0 0
60 00 1 0 0
70 00 0 1 0
NULL 00 NULL NULL 0
98 02 0 1 0
00 02 0 1 0
02 02 0 0 1
60 02 1 0 0
70 02 0 1 0
NULL 02 NULL NULL 0
98 60 0 1 0
00 60 0 1 0
02 60 0 1 0
60 60 0 0 1
70 60 0 1 0
NULL 60 NULL NULL 0
98 70 1 0 0
00 70 1 0 0
02 70 1 0 0
60 70 1 0 0
70 70 0 0 1
NULL 70 NULL NULL 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
select a.f1 as a, b.f2 as b, a.f1 > b.f2 as gt,
a.f1 < b.f2 as lt, a.f1<=>b.f2 as eq
from t1 a, t1 b;
a b gt lt eq
98 1998 0 0 1
00 1998 1 0 0
02 1998 1 0 0
60 1998 1 0 0
70 1998 0 1 0
NULL 1998 NULL NULL 0
98 2000 0 1 0
00 2000 0 0 1
02 2000 1 0 0
60 2000 1 0 0
70 2000 0 1 0
NULL 2000 NULL NULL 0
98 2002 0 1 0
00 2002 0 1 0
02 2002 0 0 1
60 2002 1 0 0
70 2002 0 1 0
NULL 2002 NULL NULL 0
98 2060 0 1 0
00 2060 0 1 0
02 2060 0 1 0
60 2060 0 0 1
70 2060 0 1 0
NULL 2060 NULL NULL 0
98 1970 1 0 0
00 1970 1 0 0
02 1970 1 0 0
60 1970 1 0 0
70 1970 0 0 1
NULL 1970 NULL NULL 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
select a.f1 as a, b.f3 as b, a.f1 > b.f3 as gt,
a.f1 < b.f3 as lt, a.f1<=>b.f3 as eq
from t1 a, t1 b;
a b gt lt eq
98 1998-01-01 0 1 0
00 1998-01-01 1 0 0
02 1998-01-01 1 0 0
60 1998-01-01 1 0 0
70 1998-01-01 0 1 0
NULL 1998-01-01 NULL NULL 0
98 2000-01-01 0 1 0
00 2000-01-01 0 1 0
02 2000-01-01 1 0 0
60 2000-01-01 1 0 0
70 2000-01-01 0 1 0
NULL 2000-01-01 NULL NULL 0
98 2002-01-01 0 1 0
00 2002-01-01 0 1 0
02 2002-01-01 0 1 0
60 2002-01-01 1 0 0
70 2002-01-01 0 1 0
NULL 2002-01-01 NULL NULL 0
98 2060-01-01 0 1 0
00 2060-01-01 0 1 0
02 2060-01-01 0 1 0
60 2060-01-01 0 1 0
70 2060-01-01 0 1 0
NULL 2060-01-01 NULL NULL 0
98 1970-01-01 1 0 0
00 1970-01-01 1 0 0
02 1970-01-01 1 0 0
60 1970-01-01 1 0 0
70 1970-01-01 0 1 0
NULL 1970-01-01 NULL NULL 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
select a.f1 as a, b.f4 as b, a.f1 > b.f4 as gt,
a.f1 < b.f4 as lt, a.f1<=>b.f4 as eq
from t1 a, t1 b;
a b gt lt eq
98 1998-01-01 00:00:00 0 1 0
00 1998-01-01 00:00:00 1 0 0
02 1998-01-01 00:00:00 1 0 0
60 1998-01-01 00:00:00 1 0 0
70 1998-01-01 00:00:00 0 1 0
NULL 1998-01-01 00:00:00 NULL NULL 0
98 2000-01-01 00:00:01 0 1 0
00 2000-01-01 00:00:01 0 1 0
02 2000-01-01 00:00:01 1 0 0
60 2000-01-01 00:00:01 1 0 0
70 2000-01-01 00:00:01 0 1 0
NULL 2000-01-01 00:00:01 NULL NULL 0
98 2002-01-01 23:59:59 0 1 0
00 2002-01-01 23:59:59 0 1 0
02 2002-01-01 23:59:59 0 1 0
60 2002-01-01 23:59:59 1 0 0
70 2002-01-01 23:59:59 0 1 0
NULL 2002-01-01 23:59:59 NULL NULL 0
98 2060-01-01 11:11:11 0 1 0
00 2060-01-01 11:11:11 0 1 0
02 2060-01-01 11:11:11 0 1 0
60 2060-01-01 11:11:11 0 1 0
70 2060-01-01 11:11:11 0 1 0
NULL 2060-01-01 11:11:11 NULL NULL 0
98 1970-11-11 22:22:22 1 0 0
00 1970-11-11 22:22:22 1 0 0
02 1970-11-11 22:22:22 1 0 0
60 1970-11-11 22:22:22 1 0 0
70 1970-11-11 22:22:22 0 1 0
NULL 1970-11-11 22:22:22 NULL NULL 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
select *, f1 = f2 from t1;
f1 f2 f3 f4 f1 = f2
98 1998 1998-01-01 1998-01-01 00:00:00 1
00 2000 2000-01-01 2000-01-01 00:00:01 1
02 2002 2002-01-01 2002-01-01 23:59:59 1
60 2060 2060-01-01 2060-01-01 11:11:11 1
70 1970 1970-01-01 1970-11-11 22:22:22 1
NULL NULL NULL NULL NULL
drop table t1;
#
End of 5.1 tests

View file

@ -443,3 +443,30 @@ DROP TABLE db1.t1, db1.t2;
DROP USER mysqltest1@localhost;
DROP DATABASE db1;
End of 5.0 tests
USE mysql;
SELECT LEFT(CURRENT_USER(),INSTR(CURRENT_USER(),'@')-1) INTO @u;
SELECT MID(CURRENT_USER(),INSTR(CURRENT_USER(),'@')+1) INTO @h;
SELECT password FROM user WHERE user=@u AND host=@h INTO @pwd;
SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
user host password insert_priv
root localhost Y
UPDATE user SET insert_priv='N' WHERE user=@u AND host=@h;
SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
user host password insert_priv
root localhost N
GRANT INSERT ON *.* TO CURRENT_USER();
SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
user host password insert_priv
root localhost Y
UPDATE user SET insert_priv='N' WHERE user=@u AND host=@h;
GRANT INSERT ON *.* TO CURRENT_USER() IDENTIFIED BY 'keksdose';
SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
user host password insert_priv
root localhost *0BB7188CF0DE9B403BA66E9DD810D82652D002EB Y
UPDATE user SET password=@pwd WHERE user=@u AND host=@h;
SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
user host password insert_priv
root localhost Y
FLUSH PRIVILEGES;
USE test;
End of 5.1 tests

View file

@ -2501,6 +2501,17 @@ SELECT a, MAX(b) FROM t WHERE b > 0 AND b < 2 GROUP BY a;
a MAX(b)
2 1
DROP TABLE t;
#
# Bug #48472: Loose index scan inappropriately chosen for some WHERE
# conditions
#
CREATE TABLE t (a INT, b INT, INDEX (a,b));
INSERT INTO t VALUES (2,0), (2,0), (2,1), (2,1);
INSERT INTO t SELECT * FROM t;
SELECT a, MAX(b) FROM t WHERE 0=b+0 GROUP BY a;
a MAX(b)
2 0
DROP TABLE t;
End of 5.0 tests
#
# Bug #46607: Assertion failed: (cond_type == Item::FUNC_ITEM) results in

View file

@ -1,4 +1,10 @@
drop table if exists t1, t2;
CREATE TABLE t1 (a INT, b INT)
PARTITION BY LIST (a)
SUBPARTITION BY HASH (b)
(PARTITION p1 VALUES IN (1));
ALTER TABLE t1 ADD COLUMN c INT;
DROP TABLE t1;
CREATE TABLE t1 (
a int NOT NULL,
b int NOT NULL);
@ -50,6 +56,13 @@ t1 CREATE TABLE `t1` (
PARTITION p3 VALUES LESS THAN (733969) ENGINE = MyISAM,
PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
DROP TABLE t1;
create table t1 (a int NOT NULL, b varchar(5) NOT NULL)
default charset=utf8
partition by list (a)
subpartition by key (b)
(partition p0 values in (1),
partition p1 values in (2));
drop table t1;
create table t1 (a int, b int, key(a))
partition by list (a)
( partition p0 values in (1),
@ -2045,10 +2058,15 @@ DROP TABLE t1;
#
# Bug #45807: crash accessing partitioned table and sql_mode
# contains ONLY_FULL_GROUP_BY
# Bug#46923: select count(*) from partitioned table fails with
# ONLY_FULL_GROUP_BY
#
SET SESSION SQL_MODE='ONLY_FULL_GROUP_BY';
CREATE TABLE t1(id INT,KEY(id)) ENGINE=MYISAM
PARTITION BY HASH(id) PARTITIONS 2;
SELECT COUNT(*) FROM t1;
COUNT(*)
0
DROP TABLE t1;
SET SESSION SQL_MODE=DEFAULT;
#

View file

@ -1603,4 +1603,21 @@ SELECT str_to_date('', '%Y-%m-%d');
str_to_date('', '%Y-%m-%d')
0000-00-00
DROP TABLE t1, t2;
#
# Bug #48665: sql-bench's insert test fails due to wrong result
#
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a));
INSERT INTO t1 VALUES (0,0), (1,1);
EXPLAIN
SELECT * FROM t1 FORCE INDEX (PRIMARY)
WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
id select_type table type possible_keys key key_len ref rows Extra
@ @ @ range @ @ @ @ @ @
# Should return 2 rows
SELECT * FROM t1 FORCE INDEX (PRIMARY)
WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
a b
0 0
1 1
DROP TABLE t1;
End of 5.1 tests

View file

@ -4591,4 +4591,22 @@ field2
15:13:38
drop table A,AA,B,BB;
#end of test for bug#45266
#
# BUG#48052: Valgrind warning - uninitialized value in init_read_record()
#
CREATE TABLE t1 (
pk int(11) NOT NULL,
i int(11) DEFAULT NULL,
v varchar(1) DEFAULT NULL,
PRIMARY KEY (pk)
);
INSERT INTO t1 VALUES (2,7,'m');
INSERT INTO t1 VALUES (3,9,'m');
SELECT v
FROM t1
WHERE NOT pk > 0
HAVING v <= 't'
ORDER BY pk;
v
DROP TABLE t1;
End of 5.1 tests

View file

@ -1,3 +1,4 @@
call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted");
use test;
drop procedure if exists bug14233;
drop function if exists bug14233;
@ -11,11 +12,13 @@ create table t1 (id int);
create trigger t1_ai after insert on t1 for each row call bug14233();
alter table mysql.proc drop type;
call bug14233();
ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
create view v1 as select bug14233_f();
ERROR HY000: Failed to load routine test.bug14233_f. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
insert into t1 values (0);
ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
show procedure status;
ERROR HY000: Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted
flush table mysql.proc;
call bug14233();
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
@ -88,3 +91,28 @@ show procedure status where db=DATABASE();
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
show function status where db=DATABASE();
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
DROP TABLE IF EXISTS proc_backup;
DROP PROCEDURE IF EXISTS p1;
# Backup the proc table
RENAME TABLE mysql.proc TO proc_backup;
CREATE TABLE mysql.proc LIKE proc_backup;
FLUSH TABLE mysql.proc;
# Test with a valid table.
CREATE PROCEDURE p1()
SET @foo = 10;
CALL p1();
SHOW PROCEDURE STATUS;
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
test p1 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
# Modify a field of the table.
ALTER TABLE mysql.proc MODIFY comment CHAR (32);
CREATE PROCEDURE p2()
SET @foo = 10;
ERROR HY000: Cannot load from mysql.proc. The table is probably corrupted
# Procedure loaded from the cache
CALL p1();
SHOW PROCEDURE STATUS;
ERROR HY000: Cannot load from mysql.proc. The table is probably corrupted
DROP TABLE mysql.proc;
RENAME TABLE proc_backup TO mysql.proc;
FLUSH TABLE mysql.proc;

View file

@ -1630,3 +1630,287 @@ SELECT my_col FROM t1;
my_col
0.012345687012345687012345687012
DROP TABLE t1;
#
# Bug#45261: Crash, stored procedure + decimal
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 SELECT
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
AS c1;
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,0) NO 0
SELECT * FROM t1;
c1
99999999999999999999999999999999999999999999999999999999999999999
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
AS c1;
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,0) NO 0
SELECT * FROM t1;
c1
99999999999999999999999999999999999999999999999999999999999999999
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
AS c1;
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,0) NO 0
SELECT * FROM t1;
c1
99999999999999999999999999999999999999999999999999999999999999999
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
AS c1;
Warnings:
Error 1292 Truncated incorrect DECIMAL value: ''
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,0) NO 0
SELECT * FROM t1;
c1
99999999999999999999999999999999999999999999999999999999999999999
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
AS c1;
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,30) NO 0.000000000000000000000000000000
SELECT * FROM t1;
c1
99999999999999999999999999999999999.999999999999999999999999999999
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
AS c1;
DESC t1;
Field Type Null Key Default Extra
c1 decimal(31,30) NO 0.000000000000000000000000000000
SELECT * FROM t1;
c1
1.100000000000000000000000000000
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
AS c1;
DESC t1;
Field Type Null Key Default Extra
c1 decimal(31,30) NO 0.000000000000000000000000000000
SELECT * FROM t1;
c1
1.100000000000000000000000000000
DROP TABLE t1;
CREATE TABLE t1 SELECT
.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
AS c1;
Warnings:
Note 1265 Data truncated for column 'c1' at row 1
DESC t1;
Field Type Null Key Default Extra
c1 decimal(30,30) NO 0.000000000000000000000000000000
SELECT * FROM t1;
c1
0.100000000000000000000000000000
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
AS c1;
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,30) NO 0.000000000000000000000000000000
SELECT * FROM t1;
c1
99999999999999999999999999999999999.999999999999999999999999999999
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
AS c1;
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,1) NO 0.0
SELECT * FROM t1;
c1
9999999999999999999999999999999999999999999999999999999999999999.9
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
AS c1;
Warnings:
Warning 1264 Out of range value for column 'c1' at row 1
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,1) NO 0.0
SELECT * FROM t1;
c1
9999999999999999999999999999999999999999999999999999999999999999.9
DROP TABLE t1;
CREATE TABLE t1 SELECT
.123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
AS c1;
Warnings:
Note 1265 Data truncated for column 'c1' at row 1
DESC t1;
Field Type Null Key Default Extra
c1 decimal(30,30) NO 0.000000000000000000000000000000
SELECT * FROM t1;
c1
0.123456789012345678901234567890
DROP TABLE t1;
CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
Warnings:
Note 1265 Data truncated for column 'c1' at row 1
DESC t1;
Field Type Null Key Default Extra
c1 decimal(33,30) NO 0.000000000000000000000000000000
SELECT * FROM t1;
c1
123.123456789012345678901234567890
DROP TABLE t1;
CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,30) NO 0.000000000000000000000000000000
SELECT * FROM t1;
c1
2.100000000000000000000000000000
DROP TABLE t1;
#
# Test that the integer and decimal parts are properly calculated.
#
CREATE TABLE t1 (a DECIMAL(30,30));
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
Warnings:
Note 1265 Data truncated for column 'c1' at row 3
DESC t2;
Field Type Null Key Default Extra
c1 decimal(32,30) YES NULL
DROP TABLE t1,t2;
CREATE TABLE t1 (a DECIMAL(30,30));
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
Warnings:
Note 1265 Data truncated for column 'c1' at row 1
Note 1265 Data truncated for column 'c1' at row 2
Note 1265 Data truncated for column 'c1' at row 3
DESC t2;
Field Type Null Key Default Extra
c1 decimal(34,0) YES NULL
DROP TABLE t1,t2;
CREATE TABLE t1 (a DECIMAL(30,30));
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
Warnings:
Note 1265 Data truncated for column 'c1' at row 1
DESC t2;
Field Type Null Key Default Extra
c1 decimal(65,30) YES NULL
DROP TABLE t1,t2;
#
# Test that variables get maximum precision.
#
SET @decimal= 1.1;
CREATE TABLE t1 SELECT @decimal AS c1;
DESC t1;
Field Type Null Key Default Extra
c1 decimal(65,30) YES NULL
SELECT * FROM t1;
c1
1.100000000000000000000000000000
DROP TABLE t1;
#
# Bug #45261 : Crash, stored procedure + decimal
# Original test by the reporter.
#
# should not crash
CREATE TABLE t1
SELECT .123456789012345678901234567890123456789012345678901234567890123456 AS a;
Warnings:
Note 1265 Data truncated for column 'a' at row 1
DROP TABLE t1;
CREATE PROCEDURE test_proc()
BEGIN
# The las non critical CUSER definition is:
# DECLARE mycursor CURSOR FOR SELECT 1 %
# .12345678912345678912345678912345678912345678912345678912345678912 AS my_col;
DECLARE mycursor CURSOR FOR
SELECT 1 %
.123456789123456789123456789123456789123456789123456789123456789123456789123456789
AS my_col;
OPEN mycursor;
CLOSE mycursor;
END|
# should not crash
CALL test_proc();
DROP PROCEDURE test_proc;
#
# Bug #48370 Absolutely wrong calculations with GROUP BY and
# decimal fields when using IF
#
CREATE TABLE currencies (id int, rate decimal(16,4),
PRIMARY KEY (id), KEY (rate));
INSERT INTO currencies VALUES (11,0.7028);
INSERT INTO currencies VALUES (1,1);
CREATE TABLE payments (
id int,
supplier_id int,
status int,
currency_id int,
vat decimal(7,4),
PRIMARY KEY (id),
KEY currency_id (currency_id),
KEY supplier_id (supplier_id)
);
INSERT INTO payments (id,status,vat,supplier_id,currency_id) VALUES
(3001,2,0.0000,344,11), (1,2,0.0000,1,1);
CREATE TABLE sub_tasks (
id int,
currency_id int,
price decimal(16,4),
discount decimal(10,4),
payment_id int,
PRIMARY KEY (id),
KEY currency_id (currency_id),
KEY payment_id (payment_id)
) ;
INSERT INTO sub_tasks (id, price, discount, payment_id, currency_id) VALUES
(52, 12.60, 0, 3001, 11), (56, 14.58, 0, 3001, 11);
# should return 1 and the same values in col 2 and 3
select STRAIGHT_JOIN
(1 + PAY.vat) AS mult,
SUM(ROUND((SUB.price - ROUND(ROUND(SUB.price, 2) * SUB.discount, 2)) *
CUR.rate / CUR.rate, 2)
) v_net_with_discount,
SUM(ROUND((SUB.price - ROUND(ROUND(SUB.price, 2) * SUB.discount, 1)) *
CUR.rate / CUR.rate , 2)
* (1 + PAY.vat)
) v_total
from
currencies CUR, payments PAY, sub_tasks SUB
where
SUB.payment_id = PAY.id and
PAY.currency_id = CUR.id and
PAY.id > 2
group by PAY.id + 1;
mult v_net_with_discount v_total
1.0000 27.18 27.180000
DROP TABLE currencies, payments, sub_tasks;
End of 5.1 tests

View file

@ -1,3 +1,4 @@
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
drop table if exists t1, t2;
create table t1 (a int) engine=innodb;
create table t2 (a int) engine=myisam;
@ -224,6 +225,8 @@ create table t0 (n int);
insert t0 select * from t1;
set autocommit=1;
insert into t0 select GET_LOCK("lock1",null);
Warnings:
Note 1592 Statement may not be safe to log in statement format.
set autocommit=0;
create table t2 (n int) engine=innodb;
insert into t2 values (3);

View file

@ -1,3 +1,4 @@
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
set @saved_global_binlog_format = @@global.binlog_format;
@ -29,6 +30,8 @@ SELECT RELEASE_LOCK('Bug#34306');
RELEASE_LOCK('Bug#34306')
1
# con2
Warnings:
Note 1592 Statement may not be safe to log in statement format.
SELECT RELEASE_LOCK('Bug#34306');
RELEASE_LOCK('Bug#34306')
1

View file

@ -327,4 +327,86 @@ Warnings:
Note 1592 Statement may not be safe to log in statement format.
DROP TABLE t1, t2;
SET @@SESSION.SQL_MODE = @save_sql_mode;
CREATE TABLE t1 (a VARCHAR(1000));
INSERT INTO t1 VALUES (CURRENT_USER());
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (FOUND_ROWS());
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (GET_LOCK('tmp', 1));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp'));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (IS_USED_LOCK('tmp'));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat'));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (RELEASE_LOCK('tmp'));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (ROW_COUNT());
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (SESSION_USER());
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (SLEEP(1));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (SYSDATE());
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (SYSTEM_USER());
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (USER());
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (UUID());
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (UUID_SHORT());
Warnings:
Note 1592 Statement may not be safe to log in statement format.
INSERT INTO t1 VALUES (VERSION());
Warnings:
Note 1592 Statement may not be safe to log in statement format.
DELETE FROM t1;
SET TIMESTAMP=1000000;
INSERT INTO t1 VALUES
(CURDATE()),
(CURRENT_DATE()),
(CURRENT_TIME()),
(CURRENT_TIMESTAMP()),
(CURTIME()),
(LOCALTIME()),
(LOCALTIMESTAMP()),
(NOW()),
(UNIX_TIMESTAMP()),
(UTC_DATE()),
(UTC_TIME()),
(UTC_TIMESTAMP());
SELECT * FROM t1;
a
1970-01-12
1970-01-12
16:46:40
1970-01-12 16:46:40
16:46:40
1970-01-12 16:46:40
1970-01-12 16:46:40
1970-01-12 16:46:40
1000000
1970-01-12
13:46:40
1970-01-12 13:46:40
DROP TABLE t1;
"End of tests"

View file

@ -1,5 +1,5 @@
-- source include/have_innodb.inc
-- source include/have_binlog_format_mixed_or_statement.inc
-- source include/have_binlog_format_statement.inc
# You cannot use `KILL' with the Embedded MySQL Server library,
# because the embedded server merely runs inside the threads of the host

View file

@ -2,6 +2,9 @@
# For both statement and row based bin logs 9/19/2005 [jbm]
-- source include/have_binlog_format_statement.inc
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
-- source extra/binlog_tests/mix_innodb_myisam_binlog.test
set @@session.binlog_format=statement;

View file

@ -1,5 +1,8 @@
--source include/have_log_bin.inc
--source include/have_binlog_format_row_or_statement.inc
# Test sets its own binlog_format, so we restrict it to run only once
--source include/have_binlog_format_row.inc
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
# Get rid of previous tests binlog
--disable_query_log

View file

@ -388,4 +388,56 @@ DELETE FROM t1 LIMIT 1;
DROP TABLE t1, t2;
SET @@SESSION.SQL_MODE = @save_sql_mode;
#
# BUG#47995: Mark user functions as unsafe
#
# Test that the system functions that are supposed to be marked unsafe
# generate a warning. Each INSERT statement below should generate a
# warning.
#
CREATE TABLE t1 (a VARCHAR(1000));
INSERT INTO t1 VALUES (CURRENT_USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (FOUND_ROWS()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (GET_LOCK('tmp', 1));
INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp'));
INSERT INTO t1 VALUES (IS_USED_LOCK('tmp'));
INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat')); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1));
INSERT INTO t1 VALUES (RELEASE_LOCK('tmp'));
INSERT INTO t1 VALUES (ROW_COUNT()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (SESSION_USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (SLEEP(1));
INSERT INTO t1 VALUES (SYSDATE());
INSERT INTO t1 VALUES (SYSTEM_USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (UUID()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (UUID_SHORT()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (VERSION());
DELETE FROM t1;
# Since we replicate the TIMESTAMP variable, functions affected by the
# TIMESTAMP variable are safe to replicate. So we check that the
# following following functions depend on the TIMESTAMP variable and
# don't generate a warning.
SET TIMESTAMP=1000000;
INSERT INTO t1 VALUES
(CURDATE()),
(CURRENT_DATE()),
(CURRENT_TIME()),
(CURRENT_TIMESTAMP()),
(CURTIME()),
(LOCALTIME()),
(LOCALTIMESTAMP()),
(NOW()),
(UNIX_TIMESTAMP()),
(UTC_DATE()),
(UTC_TIME()),
(UTC_TIMESTAMP());
SELECT * FROM t1;
DROP TABLE t1;
--echo "End of tests"

View file

@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
create table t1 (a int primary key);
create table t4 (a int primary key);
insert into t1 values (1),(1);

View file

@ -404,7 +404,11 @@ STOP SLAVE;
RESET SLAVE;
CREATE TABLE t9 (a INT KEY, b BLOB, c CHAR(5),
d TIMESTAMP,
e INT NOT NULL) ENGINE='InnoDB';
e INT NOT NULL,
f text not null,
g text,
h blob not null,
i blob) ENGINE='InnoDB';
*** Create t9 on Master ***
CREATE TABLE t9 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
) ENGINE='InnoDB';
@ -415,47 +419,11 @@ START SLAVE;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t9 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
SHOW SLAVE STATUS;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port #
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos #
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1364
Last_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 330
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1364
Last_SQL_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 330
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
select * from t9;
a b c d e f g h i
1 b1b1b1b1b1b1b1b1 Kyle 0000-00-00 00:00:00 0 NULL NULL
2 b1b1b1b1b1b1b1b1 JOE 0000-00-00 00:00:00 0 NULL NULL
3 b1b1b1b1b1b1b1b1 QA 0000-00-00 00:00:00 0 NULL NULL
*** Create t10 on slave ***
STOP SLAVE;
RESET SLAVE;

View file

@ -404,7 +404,11 @@ STOP SLAVE;
RESET SLAVE;
CREATE TABLE t9 (a INT KEY, b BLOB, c CHAR(5),
d TIMESTAMP,
e INT NOT NULL) ENGINE='MyISAM';
e INT NOT NULL,
f text not null,
g text,
h blob not null,
i blob) ENGINE='MyISAM';
*** Create t9 on Master ***
CREATE TABLE t9 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
) ENGINE='MyISAM';
@ -415,47 +419,11 @@ START SLAVE;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t9 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
SHOW SLAVE STATUS;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port #
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos #
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1364
Last_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 330
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1364
Last_SQL_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 330
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
select * from t9;
a b c d e f g h i
1 b1b1b1b1b1b1b1b1 Kyle 0000-00-00 00:00:00 0 NULL NULL
2 b1b1b1b1b1b1b1b1 JOE 0000-00-00 00:00:00 0 NULL NULL
3 b1b1b1b1b1b1b1b1 QA 0000-00-00 00:00:00 0 NULL NULL
*** Create t10 on slave ***
STOP SLAVE;
RESET SLAVE;

View file

@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
create table t1(n int);
insert into t1 values(get_lock("lock",2));
select get_lock("lock",2);

View file

@ -0,0 +1,26 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CREATE TABLE t1 (a VARCHAR(1000));
INSERT INTO t1 VALUES (CONNECTION_ID());
INSERT INTO t1 VALUES (CONNECTION_ID());
INSERT INTO t1 VALUES
(CURDATE()),
(CURRENT_DATE()),
(CURRENT_TIME()),
(CURRENT_TIMESTAMP()),
(CURTIME()),
(LOCALTIME()),
(LOCALTIMESTAMP()),
(NOW()),
(UNIX_TIMESTAMP()),
(UTC_DATE()),
(UTC_TIME()),
(UTC_TIMESTAMP());
INSERT INTO t1 VALUES (RAND());
INSERT INTO t1 VALUES (LAST_INSERT_ID());
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;

View file

@ -0,0 +1,202 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
SET SQL_LOG_BIN= 0;
CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
`c` INT DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
CREATE TABLE t3(`a` INT, `b` DATE DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
CREATE TABLE t4(`a` INT, `b` DATE DEFAULT NULL,
`c` INT DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
SET SQL_LOG_BIN= 1;
CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
`c` INT DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
CREATE TABLE t3(`a` INT, `b` DATE DEFAULT '0000-00-00',
`c` INT DEFAULT 500,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
CREATE TABLE t4(`a` INT, `b` DATE DEFAULT '0000-00-00',
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
************* EXECUTION WITH INSERTS *************
INSERT INTO t1(a,b,c) VALUES (1, null, 1);
INSERT INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
INSERT INTO t1(a,b) VALUES (3, null);
INSERT INTO t1(a,c) VALUES (4, 4);
INSERT INTO t1(a) VALUES (5);
INSERT INTO t2(a,b) VALUES (1, null);
INSERT INTO t2(a,b) VALUES (2,'1111-11-11');
INSERT INTO t2(a) VALUES (3);
INSERT INTO t3(a,b) VALUES (1, null);
INSERT INTO t3(a,b) VALUES (2,'1111-11-11');
INSERT INTO t3(a) VALUES (3);
INSERT INTO t4(a,b,c) VALUES (1, null, 1);
INSERT INTO t4(a,b,c) VALUES (2,'1111-11-11', 2);
INSERT INTO t4(a,b) VALUES (3, null);
INSERT INTO t4(a,c) VALUES (4, 4);
INSERT INTO t4(a) VALUES (5);
************* SHOWING THE RESULT SETS WITH INSERTS *************
TABLES t1 and t2 must be equal otherwise an error will be thrown.
Comparing tables master:test.t1 and slave:test.t1
Comparing tables master:test.t2 and slave:test.t2
TABLES t2 and t3 must be different.
SELECT * FROM t3 ORDER BY a;
a b
1 NULL
2 1111-11-11
3 NULL
SELECT * FROM t3 ORDER BY a;
a b c
1 NULL 500
2 1111-11-11 500
3 NULL 500
SELECT * FROM t4 ORDER BY a;
a b c
1 NULL 1
2 1111-11-11 2
3 NULL NULL
4 NULL 4
5 NULL NULL
SELECT * FROM t4 ORDER BY a;
a b
1 NULL
2 1111-11-11
3 NULL
4 NULL
5 NULL
************* EXECUTION WITH UPDATES and REPLACES *************
DELETE FROM t1;
INSERT INTO t1(a,b,c) VALUES (1,'1111-11-11', 1);
REPLACE INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
UPDATE t1 set b= NULL, c= 300 where a= 1;
REPLACE INTO t1(a,b,c) VALUES (2, NULL, 300);
************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
TABLES t1 and t2 must be equal otherwise an error will be thrown.
Comparing tables master:test.t1 and slave:test.t1
************* CLEANING *************
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
SET SQL_LOG_BIN= 0;
CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT NULL, `c` BIT DEFAULT NULL,
PRIMARY KEY (`a`)) ENGINE= Innodb;
SET SQL_LOG_BIN= 1;
CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT b'01', `c` BIT DEFAULT NULL,
PRIMARY KEY (`a`)) ENGINE= Innodb;
************* EXECUTION WITH INSERTS *************
INSERT INTO t1(a,b,c) VALUES (1, null, b'01');
INSERT INTO t1(a,b,c) VALUES (2,b'00', b'01');
INSERT INTO t1(a,b) VALUES (3, null);
INSERT INTO t1(a,c) VALUES (4, b'01');
INSERT INTO t1(a) VALUES (5);
************* SHOWING THE RESULT SETS WITH INSERTS *************
TABLES t1 and t2 must be different.
SELECT a,b+0,c+0 FROM t1 ORDER BY a;
a b+0 c+0
1 NULL 1
2 0 1
3 NULL NULL
4 NULL 1
5 NULL NULL
SELECT a,b+0,c+0 FROM t1 ORDER BY a;
a b+0 c+0
1 NULL 1
2 0 1
3 NULL NULL
4 NULL 1
5 NULL NULL
************* EXECUTION WITH UPDATES and REPLACES *************
DELETE FROM t1;
INSERT INTO t1(a,b,c) VALUES (1,b'00', b'01');
REPLACE INTO t1(a,b,c) VALUES (2,b'00',b'01');
UPDATE t1 set b= NULL, c= b'00' where a= 1;
REPLACE INTO t1(a,b,c) VALUES (2, NULL, b'00');
************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
TABLES t1 and t2 must be equal otherwise an error will be thrown.
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
################################################################################
# NULL ---> NOT NULL (STRICT MODE)
# UNCOMMENT THIS AFTER FIXING BUG#43992
################################################################################
################################################################################
# NULL ---> NOT NULL (NON-STRICT MODE)
################################################################################
SET SQL_LOG_BIN= 0;
CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
SET SQL_LOG_BIN= 1;
CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
`c` INT NOT NULL,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
`c` INT,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
`c` INT DEFAULT 500,
PRIMARY KEY(`a`)) ENGINE=Innodb DEFAULT CHARSET=LATIN1;
************* EXECUTION WITH INSERTS *************
INSERT INTO t1(a) VALUES (1);
INSERT INTO t1(a, b) VALUES (2, NULL);
INSERT INTO t1(a, b) VALUES (3, 1);
INSERT INTO t2(a) VALUES (1);
INSERT INTO t2(a, b) VALUES (2, NULL);
INSERT INTO t2(a, b) VALUES (3, 1);
INSERT INTO t3(a) VALUES (1);
INSERT INTO t3(a, b) VALUES (2, NULL);
INSERT INTO t3(a, b) VALUES (3, 1);
INSERT INTO t3(a, b) VALUES (4, 1);
REPLACE INTO t3(a, b) VALUES (5, null);
REPLACE INTO t3(a, b) VALUES (3, null);
UPDATE t3 SET b = NULL where a = 4;
************* SHOWING THE RESULT SETS *************
SELECT * FROM t1 ORDER BY a;
a b
1 NULL
2 NULL
3 1
SELECT * FROM t1 ORDER BY a;
a b c
1 0 0
2 0 0
3 1 0
SELECT * FROM t2 ORDER BY a;
a b
1 NULL
2 NULL
3 1
SELECT * FROM t2 ORDER BY a;
a b c
1 0 NULL
2 0 NULL
3 1 NULL
SELECT * FROM t3 ORDER BY a;
a b
1 NULL
2 NULL
3 NULL
4 NULL
5 NULL
SELECT * FROM t3 ORDER BY a;
a b c
1 0 500
2 0 500
3 0 500
4 0 500
5 0 500
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;

View file

@ -0,0 +1,202 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
SET SQL_LOG_BIN= 0;
CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
`c` INT DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
CREATE TABLE t3(`a` INT, `b` DATE DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
CREATE TABLE t4(`a` INT, `b` DATE DEFAULT NULL,
`c` INT DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
SET SQL_LOG_BIN= 1;
CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL,
`c` INT DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
CREATE TABLE t3(`a` INT, `b` DATE DEFAULT '0000-00-00',
`c` INT DEFAULT 500,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
CREATE TABLE t4(`a` INT, `b` DATE DEFAULT '0000-00-00',
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
************* EXECUTION WITH INSERTS *************
INSERT INTO t1(a,b,c) VALUES (1, null, 1);
INSERT INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
INSERT INTO t1(a,b) VALUES (3, null);
INSERT INTO t1(a,c) VALUES (4, 4);
INSERT INTO t1(a) VALUES (5);
INSERT INTO t2(a,b) VALUES (1, null);
INSERT INTO t2(a,b) VALUES (2,'1111-11-11');
INSERT INTO t2(a) VALUES (3);
INSERT INTO t3(a,b) VALUES (1, null);
INSERT INTO t3(a,b) VALUES (2,'1111-11-11');
INSERT INTO t3(a) VALUES (3);
INSERT INTO t4(a,b,c) VALUES (1, null, 1);
INSERT INTO t4(a,b,c) VALUES (2,'1111-11-11', 2);
INSERT INTO t4(a,b) VALUES (3, null);
INSERT INTO t4(a,c) VALUES (4, 4);
INSERT INTO t4(a) VALUES (5);
************* SHOWING THE RESULT SETS WITH INSERTS *************
TABLES t1 and t2 must be equal otherwise an error will be thrown.
Comparing tables master:test.t1 and slave:test.t1
Comparing tables master:test.t2 and slave:test.t2
TABLES t2 and t3 must be different.
SELECT * FROM t3 ORDER BY a;
a b
1 NULL
2 1111-11-11
3 NULL
SELECT * FROM t3 ORDER BY a;
a b c
1 NULL 500
2 1111-11-11 500
3 NULL 500
SELECT * FROM t4 ORDER BY a;
a b c
1 NULL 1
2 1111-11-11 2
3 NULL NULL
4 NULL 4
5 NULL NULL
SELECT * FROM t4 ORDER BY a;
a b
1 NULL
2 1111-11-11
3 NULL
4 NULL
5 NULL
************* EXECUTION WITH UPDATES and REPLACES *************
DELETE FROM t1;
INSERT INTO t1(a,b,c) VALUES (1,'1111-11-11', 1);
REPLACE INTO t1(a,b,c) VALUES (2,'1111-11-11', 2);
UPDATE t1 set b= NULL, c= 300 where a= 1;
REPLACE INTO t1(a,b,c) VALUES (2, NULL, 300);
************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
TABLES t1 and t2 must be equal otherwise an error will be thrown.
Comparing tables master:test.t1 and slave:test.t1
************* CLEANING *************
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
SET SQL_LOG_BIN= 0;
CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT NULL, `c` BIT DEFAULT NULL,
PRIMARY KEY (`a`)) ENGINE= MyISAM;
SET SQL_LOG_BIN= 1;
CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT b'01', `c` BIT DEFAULT NULL,
PRIMARY KEY (`a`)) ENGINE= MyISAM;
************* EXECUTION WITH INSERTS *************
INSERT INTO t1(a,b,c) VALUES (1, null, b'01');
INSERT INTO t1(a,b,c) VALUES (2,b'00', b'01');
INSERT INTO t1(a,b) VALUES (3, null);
INSERT INTO t1(a,c) VALUES (4, b'01');
INSERT INTO t1(a) VALUES (5);
************* SHOWING THE RESULT SETS WITH INSERTS *************
TABLES t1 and t2 must be different.
SELECT a,b+0,c+0 FROM t1 ORDER BY a;
a b+0 c+0
1 NULL 1
2 0 1
3 NULL NULL
4 NULL 1
5 NULL NULL
SELECT a,b+0,c+0 FROM t1 ORDER BY a;
a b+0 c+0
1 NULL 1
2 0 1
3 NULL NULL
4 NULL 1
5 NULL NULL
************* EXECUTION WITH UPDATES and REPLACES *************
DELETE FROM t1;
INSERT INTO t1(a,b,c) VALUES (1,b'00', b'01');
REPLACE INTO t1(a,b,c) VALUES (2,b'00',b'01');
UPDATE t1 set b= NULL, c= b'00' where a= 1;
REPLACE INTO t1(a,b,c) VALUES (2, NULL, b'00');
************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES *************
TABLES t1 and t2 must be equal otherwise an error will be thrown.
Comparing tables master:test.t1 and slave:test.t1
DROP TABLE t1;
################################################################################
# NULL ---> NOT NULL (STRICT MODE)
# UNCOMMENT THIS AFTER FIXING BUG#43992
################################################################################
################################################################################
# NULL ---> NOT NULL (NON-STRICT MODE)
################################################################################
SET SQL_LOG_BIN= 0;
CREATE TABLE t1(`a` INT NOT NULL, `b` INT,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
CREATE TABLE t2(`a` INT NOT NULL, `b` INT,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
CREATE TABLE t3(`a` INT NOT NULL, `b` INT,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
SET SQL_LOG_BIN= 1;
CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL,
`c` INT NOT NULL,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL,
`c` INT,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL,
`c` INT DEFAULT 500,
PRIMARY KEY(`a`)) ENGINE=MyISAM DEFAULT CHARSET=LATIN1;
************* EXECUTION WITH INSERTS *************
INSERT INTO t1(a) VALUES (1);
INSERT INTO t1(a, b) VALUES (2, NULL);
INSERT INTO t1(a, b) VALUES (3, 1);
INSERT INTO t2(a) VALUES (1);
INSERT INTO t2(a, b) VALUES (2, NULL);
INSERT INTO t2(a, b) VALUES (3, 1);
INSERT INTO t3(a) VALUES (1);
INSERT INTO t3(a, b) VALUES (2, NULL);
INSERT INTO t3(a, b) VALUES (3, 1);
INSERT INTO t3(a, b) VALUES (4, 1);
REPLACE INTO t3(a, b) VALUES (5, null);
REPLACE INTO t3(a, b) VALUES (3, null);
UPDATE t3 SET b = NULL where a = 4;
************* SHOWING THE RESULT SETS *************
SELECT * FROM t1 ORDER BY a;
a b
1 NULL
2 NULL
3 1
SELECT * FROM t1 ORDER BY a;
a b c
1 0 0
2 0 0
3 1 0
SELECT * FROM t2 ORDER BY a;
a b
1 NULL
2 NULL
3 1
SELECT * FROM t2 ORDER BY a;
a b c
1 0 NULL
2 0 NULL
3 1 NULL
SELECT * FROM t3 ORDER BY a;
a b
1 NULL
2 NULL
3 NULL
4 NULL
5 NULL
SELECT * FROM t3 ORDER BY a;
a b c
1 0 500
2 0 500
3 0 500
4 0 500
5 0 500
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;

View file

@ -105,47 +105,9 @@ a b x
2 10 Foo is a bar
INSERT INTO t9 VALUES (2);
INSERT INTO t1_nodef VALUES (1,2);
SHOW SLAVE STATUS;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port #
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos #
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1364
Last_Error <Last_Error>
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno <Last_IO_Errno>
Last_IO_Error <Last_IO_Error>
Last_SQL_Errno 1364
Last_SQL_Error <Last_SQL_Error>
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
select count(*) from t1_nodef;
count(*)
1
INSERT INTO t9 VALUES (2);
**** On Master ****
INSERT INTO t2 VALUES (2,4);

View file

@ -105,47 +105,9 @@ a b x
2 10 Foo is a bar
INSERT INTO t9 VALUES (2);
INSERT INTO t1_nodef VALUES (1,2);
SHOW SLAVE STATUS;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port #
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos #
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1364
Last_Error <Last_Error>
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno <Last_IO_Errno>
Last_IO_Error <Last_IO_Error>
Last_SQL_Errno 1364
Last_SQL_Error <Last_SQL_Error>
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
select count(*) from t1_nodef;
count(*)
1
INSERT INTO t9 VALUES (2);
**** On Master ****
INSERT INTO t2 VALUES (2,4);

View file

@ -0,0 +1,29 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CREATE TEMPORARY TABLE t1(c1 INTEGER);
CREATE TABLE t2(c1 INTEGER);
CREATE TABLE t1(c1 INTEGER);
INSERT INTO t1 VALUES(1), (2);
INSERT INTO t2 VALUES(1), (2);
SELECT * FROM t1;
c1
1
2
SELECT * FROM t2;
c1
1
2
TRUNCATE t1;
TRUNCATE t2;
SELECT * FROM t1;
c1
1
2
SELECT * FROM t2;
c1
DROP TABLE t1;
DROP TABLE t2;

View file

@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
create table t1 (word char(20) not null);
load data infile '../../std_data/words.dat' into table t1;
load data local infile 'MYSQL_TEST_DIR/std_data/words.dat' into table t1;

View file

@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;

View file

@ -7,6 +7,8 @@
-- source include/master-slave.inc
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
connection master;
create table t1 (a int primary key);
create table t4 (a int primary key);
@ -14,19 +16,15 @@ create table t4 (a int primary key);
--error 1022, ER_DUP_ENTRY
insert into t1 values (1),(1);
insert into t4 values (1),(2);
save_master_pos;
connection slave;
# as the t1 table is ignored on the slave, the slave should be able to sync
sync_with_master;
sync_slave_with_master;
# check that the table has been ignored, because otherwise the test is nonsense
show tables like 't1';
show tables like 't4';
SELECT * FROM test.t4 ORDER BY a;
connection master;
drop table t1;
save_master_pos;
connection slave;
sync_with_master;
sync_slave_with_master;
# Now test that even critical errors (connection killed)
# are ignored if rules allow it.
@ -50,18 +48,17 @@ kill @id;
drop table t2,t3;
insert into t4 values (3),(4);
connection master;
# The get_lock function causes warning for unsafe statement.
--disable_warnings
--error 0,1317,2013
reap;
--enable_warnings
connection master1;
save_master_pos;
connection slave;
sync_with_master;
sync_slave_with_master;
SELECT * FROM test.t4 ORDER BY a;
connection master1;
DROP TABLE test.t4;
save_master_pos;
connection slave;
sync_with_master;
sync_slave_with_master;
# End of 4.1 tests
# Adding comment for force manual merge 5.0 -> wl1012. delete me if needed

View file

@ -1,7 +1,12 @@
source include/master-slave.inc;
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
create table t1(n int);
# Use of get_lock gives a warning for unsafeness if binlog_format=statement
--disable_warnings
insert into t1 values(get_lock("lock",2));
--enable_warnings
dirty_close master;
connection master1;
select get_lock("lock",2);

View file

@ -0,0 +1,53 @@
# ==== Purpose ====
#
# Test that nondeterministic system functions are correctly replicated.
#
# (Some functions are only correctly replicated if binlog_format=MIXED
# or ROW. See binlog_unsafe.test for a test that those variables are
# indeed unsafe.)
#
# ==== Implementation ====
#
# We insert the values of each unsafe function into a table. Then we
# replicate and check that the table is identical on slave.
#
# ==== Related bugs ====
#
# BUG#47995
--source include/master-slave.inc
CREATE TABLE t1 (a VARCHAR(1000));
# We replicate the connection_id in the query_log_event
INSERT INTO t1 VALUES (CONNECTION_ID());
--connection master1
INSERT INTO t1 VALUES (CONNECTION_ID());
# We replicate the TIMESTAMP variable, so the following functions that
# are affected by the TIMESTAMP variable should be safe to replicate.
INSERT INTO t1 VALUES
(CURDATE()),
(CURRENT_DATE()),
(CURRENT_TIME()),
(CURRENT_TIMESTAMP()),
(CURTIME()),
(LOCALTIME()),
(LOCALTIMESTAMP()),
(NOW()),
(UNIX_TIMESTAMP()),
(UTC_DATE()),
(UTC_TIME()),
(UTC_TIMESTAMP());
# We replicate the random seed in a rand_log_event
INSERT INTO t1 VALUES (RAND());
# We replicate the last_insert_id in an intvar_log_event
INSERT INTO t1 VALUES (LAST_INSERT_ID());
--sync_slave_with_master
--let $diff_table_1= master:test.t1
--let $diff_table_2= slave:test.t1
--source include/diff_tables.inc
DROP TABLE t1;

View file

@ -0,0 +1,19 @@
#################################################################################
# This test checks if the replication between "null" fields to either "null"
# fields or "not null" fields works properly. In the first case, the execution
# should work fine. In the second case, it may fail according to the sql_mode
# being used.
#
# The test is devided in three main parts:
#
# 1 - NULL --> NULL (no failures)
# 2 - NULL --> NOT NULL ( sql-mode = STRICT and failures)
# 3 - NULL --> NOT NULL ( sql-mode != STRICT and no failures)
#
#################################################################################
--source include/master-slave.inc
--source include/have_innodb.inc
--source include/have_binlog_format_row.inc
let $engine=Innodb;
--source extra/rpl_tests/rpl_not_null.test

View file

@ -0,0 +1,18 @@
#################################################################################
# This test checks if the replication between "null" fields to either "null"
# fields or "not null" fields works properly. In the first case, the execution
# should work fine. In the second case, it may fail according to the sql_mode
# being used.
#
# The test is devided in three main parts:
#
# 1 - NULL --> NULL (no failures)
# 2 - NULL --> NOT NULL ( sql-mode = STRICT and failures)
# 3 - NULL --> NOT NULL ( sql-mode != STRICT and no failures)
#
#################################################################################
--source include/master-slave.inc
--source include/have_binlog_format_row.inc
let $engine=MyISAM;
--source extra/rpl_tests/rpl_not_null.test

View file

@ -0,0 +1,35 @@
#
# Bug#48350 truncate temporary table crashes replication
#
# All statements operating on temporary tables should not be binlogged in RBR.
# However, before fix of bug#48350, 'TRUNCATE ...' statement on a temporary
# table was binlogged in RBR.
#
--source include/master-slave.inc
--source include/have_binlog_format_row.inc
#This statement is not binlogged in RBR.
CREATE TEMPORARY TABLE t1(c1 INTEGER);
CREATE TABLE t2(c1 INTEGER);
sync_slave_with_master;
CREATE TABLE t1(c1 INTEGER);
INSERT INTO t1 VALUES(1), (2);
INSERT INTO t2 VALUES(1), (2);
SELECT * FROM t1;
SELECT * FROM t2;
connection master;
TRUNCATE t1;
TRUNCATE t2;
sync_slave_with_master;
# t1 will have nothing, if 'TRUNCATE t1' has been replicate from master to
# slave.
SELECT * FROM t1;
SELECT * FROM t2;
DROP TABLE t1;
connection master;
DROP TABLE t2;
--source include/master-slave-end.inc

View file

@ -5,6 +5,8 @@
--source include/have_binlog_format_mixed_or_statement.inc
--source include/master-slave.inc
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
@ -89,7 +91,11 @@ end
|
delimiter ;|
# The trigger causes a warning for unsafe statement when
# binlog_format=statement since it uses get_lock.
--disable_warnings
insert into t1 set a = now();
--enable_warnings
select a=b && a=c from t1;
let $time=`select a from t1`;
@ -135,7 +141,11 @@ disconnect con2;
truncate table t1;
drop trigger t1_first;
# The trigger causes a warning for unsafe statement when
# binlog_format=statement since it uses get_lock.
--disable_warnings
insert into t1 values ("2003-03-03","2003-03-03","2003-03-03"),(bug12480(),bug12480(),bug12480()),(now(),now(),now());
--enable_warnings
select a=b && a=c from t1;
drop function bug12480;

View file

@ -400,62 +400,6 @@ set @b1 = concat(@b1,@b1);
INSERT INTO t8 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
*** Drop t8 ***
DROP TABLE t8;
STOP SLAVE;
RESET SLAVE;
CREATE TABLE t9 (a INT KEY, b BLOB, c CHAR(5),
d TIMESTAMP,
e INT NOT NULL) ENGINE='NDB';
*** Create t9 on Master ***
CREATE TABLE t9 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
) ENGINE='NDB';
RESET MASTER;
*** Start Slave ***
START SLAVE;
*** Master Data Insert ***
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t9 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
SHOW SLAVE STATUS;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port #
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos #
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running No
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table #
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1364
Last_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 447
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1364
Last_SQL_Error Could not execute Write_rows event on table test.t9; Field 'e' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 447
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
*** Create t10 on slave ***
STOP SLAVE;
RESET SLAVE;

View file

@ -328,4 +328,28 @@ drop table t1;
set global low_priority_updates = @old_delayed_updates;
--echo #
--echo # Bug #47682 strange behaviour of INSERT DELAYED
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE TABLE t1 (f1 integer);
CREATE TABLE t2 (f1 integer);
FLUSH TABLES WITH READ LOCK;
LOCK TABLES t1 READ;
# ER_CANT_UPDATE_WITH_READLOCK with normal execution
# ER_TABLE_NOT_LOCKED when executed as prepared statement
--error ER_CANT_UPDATE_WITH_READLOCK, ER_TABLE_NOT_LOCKED
INSERT DELAYED INTO t2 VALUES (1);
UNLOCK TABLES;
DROP TABLE t1, t2;
--echo End of 5.1 tests

View file

@ -336,3 +336,25 @@ SELECT * FROM t2;
SELECT * FROM t3;
DROP TABLE t1, t2, t3;
--echo #
--echo # Bug #46425 crash in Diagnostics_area::set_ok_status,
--echo # empty statement, DELETE IGNORE
--echo #
CREATE table t1 (i INTEGER);
INSERT INTO t1 VALUES (1);
--delimiter |
CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW
BEGIN
INSERT INTO t1 SELECT * FROM t1 AS A;
END |
--delimiter ;
--error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
DELETE IGNORE FROM t1;
DROP TABLE t1;

View file

@ -1053,4 +1053,35 @@ ORDER BY max;
--echo #
DROP TABLE t1;
--echo #
--echo # Bug#43668: Wrong comparison and MIN/MAX for YEAR(2)
--echo #
create table t1 (f1 year(2), f2 year(4), f3 date, f4 datetime);
insert into t1 values
(98,1998,19980101,"1998-01-01 00:00:00"),
(00,2000,20000101,"2000-01-01 00:00:01"),
(02,2002,20020101,"2002-01-01 23:59:59"),
(60,2060,20600101,"2060-01-01 11:11:11"),
(70,1970,19700101,"1970-11-11 22:22:22"),
(NULL,NULL,NULL,NULL);
select min(f1),max(f1) from t1;
select min(f2),max(f2) from t1;
select min(f3),max(f3) from t1;
select min(f4),max(f4) from t1;
select a.f1 as a, b.f1 as b, a.f1 > b.f1 as gt,
a.f1 < b.f1 as lt, a.f1<=>b.f1 as eq
from t1 a, t1 b;
select a.f1 as a, b.f2 as b, a.f1 > b.f2 as gt,
a.f1 < b.f2 as lt, a.f1<=>b.f2 as eq
from t1 a, t1 b;
select a.f1 as a, b.f3 as b, a.f1 > b.f3 as gt,
a.f1 < b.f3 as lt, a.f1<=>b.f3 as eq
from t1 a, t1 b;
select a.f1 as a, b.f4 as b, a.f1 > b.f4 as gt,
a.f1 < b.f4 as lt, a.f1<=>b.f4 as eq
from t1 a, t1 b;
select *, f1 = f2 from t1;
drop table t1;
--echo #
--echo End of 5.1 tests

View file

@ -632,5 +632,40 @@ DROP DATABASE db1;
--echo End of 5.0 tests
#
# Bug #48319: Server crashes on "GRANT/REVOKE ... TO CURRENT_USER"
#
# work out who we are.
USE mysql;
SELECT LEFT(CURRENT_USER(),INSTR(CURRENT_USER(),'@')-1) INTO @u;
SELECT MID(CURRENT_USER(),INSTR(CURRENT_USER(),'@')+1) INTO @h;
SELECT password FROM user WHERE user=@u AND host=@h INTO @pwd;
# show current privs.
SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
# toggle INSERT
UPDATE user SET insert_priv='N' WHERE user=@u AND host=@h;
SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
# show that GRANT ... TO CURRENT_USER() no longer crashes
GRANT INSERT ON *.* TO CURRENT_USER();
SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
UPDATE user SET insert_priv='N' WHERE user=@u AND host=@h;
# show that GRANT ... TO CURRENT_USER() IDENTIFIED BY ... works now
GRANT INSERT ON *.* TO CURRENT_USER() IDENTIFIED BY 'keksdose';
SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
UPDATE user SET password=@pwd WHERE user=@u AND host=@h;
SELECT user,host,password,insert_priv FROM user WHERE user=@u AND host=@h;
FLUSH PRIVILEGES;
USE test;
--echo End of 5.1 tests
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc

View file

@ -1016,6 +1016,18 @@ SELECT a, MAX(b) FROM t WHERE b > 0 AND b < 2 GROUP BY a;
DROP TABLE t;
--echo #
--echo # Bug #48472: Loose index scan inappropriately chosen for some WHERE
--echo # conditions
--echo #
CREATE TABLE t (a INT, b INT, INDEX (a,b));
INSERT INTO t VALUES (2,0), (2,0), (2,1), (2,1);
INSERT INTO t SELECT * FROM t;
SELECT a, MAX(b) FROM t WHERE 0=b+0 GROUP BY a;
DROP TABLE t;
--echo End of 5.0 tests

View file

@ -14,6 +14,15 @@
drop table if exists t1, t2;
--enable_warnings
#
# Bug#48276: can't add column if subpartition exists
CREATE TABLE t1 (a INT, b INT)
PARTITION BY LIST (a)
SUBPARTITION BY HASH (b)
(PARTITION p1 VALUES IN (1));
ALTER TABLE t1 ADD COLUMN c INT;
DROP TABLE t1;
#
# Bug#46639: 1030 (HY000): Got error 124 from storage engine on
# INSERT ... SELECT ...
@ -61,6 +70,17 @@ SELECT * FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
#
# Bug#45904: Error when CHARSET=utf8 and subpartitioning
#
create table t1 (a int NOT NULL, b varchar(5) NOT NULL)
default charset=utf8
partition by list (a)
subpartition by key (b)
(partition p0 values in (1),
partition p1 values in (2));
drop table t1;
#
# Bug#44059: rec_per_key on empty partition gives weird optimiser results
#
@ -2031,11 +2051,14 @@ DROP TABLE t1;
--echo #
--echo # Bug #45807: crash accessing partitioned table and sql_mode
--echo # contains ONLY_FULL_GROUP_BY
--echo # Bug#46923: select count(*) from partitioned table fails with
--echo # ONLY_FULL_GROUP_BY
--echo #
SET SESSION SQL_MODE='ONLY_FULL_GROUP_BY';
CREATE TABLE t1(id INT,KEY(id)) ENGINE=MYISAM
PARTITION BY HASH(id) PARTITIONS 2;
SELECT COUNT(*) FROM t1;
DROP TABLE t1;
SET SESSION SQL_MODE=DEFAULT;

View file

@ -1260,4 +1260,25 @@ SELECT str_to_date('', '%Y-%m-%d');
DROP TABLE t1, t2;
--echo #
--echo # Bug #48665: sql-bench's insert test fails due to wrong result
--echo #
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a));
INSERT INTO t1 VALUES (0,0), (1,1);
--replace_column 1 @ 2 @ 3 @ 5 @ 6 @ 7 @ 8 @ 9 @ 10 @
EXPLAIN
SELECT * FROM t1 FORCE INDEX (PRIMARY)
WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
--echo # Should return 2 rows
SELECT * FROM t1 FORCE INDEX (PRIMARY)
WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
DROP TABLE t1;
--echo End of 5.1 tests

View file

@ -3931,4 +3931,37 @@ SELECT table1 .`time_key` field2 FROM B table1 LEFT JOIN BB JOIN A table5 ON
drop table A,AA,B,BB;
--echo #end of test for bug#45266
--echo #
--echo # BUG#48052: Valgrind warning - uninitialized value in init_read_record()
--echo #
# Needed in 6.0 codebase
#--echo # Disable Index condition pushdown
#--replace_column 1 #
#SELECT @old_icp:=@@engine_condition_pushdown;
#SET SESSION engine_condition_pushdown = 'OFF';
CREATE TABLE t1 (
pk int(11) NOT NULL,
i int(11) DEFAULT NULL,
v varchar(1) DEFAULT NULL,
PRIMARY KEY (pk)
);
INSERT INTO t1 VALUES (2,7,'m');
INSERT INTO t1 VALUES (3,9,'m');
SELECT v
FROM t1
WHERE NOT pk > 0
HAVING v <= 't'
ORDER BY pk;
# Needed in 6.0 codebase
#--echo # Restore old value for Index condition pushdown
#SET SESSION engine_condition_pushdown=@old_icp;
DROP TABLE t1;
--echo End of 5.1 tests

View file

@ -12,6 +12,9 @@
# mysqltest should be fixed to allow REPLACE_RESULT in error message
-- source include/not_embedded.inc
# Supress warnings written to the log file
call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted");
# Backup proc table
let $MYSQLD_DATADIR= `select @@datadir`;
--copy_file $MYSQLD_DATADIR/mysql/proc.frm $MYSQLTEST_VARDIR/tmp/proc.frm
@ -38,15 +41,14 @@ create trigger t1_ai after insert on t1 for each row call bug14233();
# Unsupported tampering with the mysql.proc definition
alter table mysql.proc drop type;
--replace_result $MYSQL_TEST_DIR .
--error ER_SP_PROC_TABLE_CORRUPT
--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
call bug14233();
--replace_result $MYSQL_TEST_DIR .
--error ER_SP_PROC_TABLE_CORRUPT
--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
create view v1 as select bug14233_f();
--replace_result $MYSQL_TEST_DIR .
--error ER_SP_PROC_TABLE_CORRUPT
--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
insert into t1 values (0);
--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
show procedure status;
flush table mysql.proc;
@ -155,3 +157,43 @@ drop procedure bug14233_3;
# Assert: These should show nothing.
show procedure status where db=DATABASE();
show function status where db=DATABASE();
#
# Bug#41726 upgrade from 5.0 to 5.1.30 crashes if you didn't run mysql_upgrade
#
--disable_warnings
DROP TABLE IF EXISTS proc_backup;
DROP PROCEDURE IF EXISTS p1;
--enable_warnings
--echo # Backup the proc table
RENAME TABLE mysql.proc TO proc_backup;
CREATE TABLE mysql.proc LIKE proc_backup;
FLUSH TABLE mysql.proc;
--echo # Test with a valid table.
CREATE PROCEDURE p1()
SET @foo = 10;
CALL p1();
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
SHOW PROCEDURE STATUS;
--echo # Modify a field of the table.
ALTER TABLE mysql.proc MODIFY comment CHAR (32);
--error ER_CANNOT_LOAD_FROM_TABLE
CREATE PROCEDURE p2()
SET @foo = 10;
--echo # Procedure loaded from the cache
CALL p1();
--error ER_CANNOT_LOAD_FROM_TABLE
SHOW PROCEDURE STATUS;
DROP TABLE mysql.proc;
RENAME TABLE proc_backup TO mysql.proc;
FLUSH TABLE mysql.proc;

View file

@ -1286,3 +1286,229 @@ CREATE TABLE t1 SELECT 1 % .1234567891234567891234567891234567891234567891234567
DESCRIBE t1;
SELECT my_col FROM t1;
DROP TABLE t1;
--echo #
--echo # Bug#45261: Crash, stored procedure + decimal
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 SELECT
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
/* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT
.123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Test that the integer and decimal parts are properly calculated.
--echo #
CREATE TABLE t1 (a DECIMAL(30,30));
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
DESC t2;
DROP TABLE t1,t2;
CREATE TABLE t1 (a DECIMAL(30,30));
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
DESC t2;
DROP TABLE t1,t2;
CREATE TABLE t1 (a DECIMAL(30,30));
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
DESC t2;
DROP TABLE t1,t2;
--echo #
--echo # Test that variables get maximum precision.
--echo #
SET @decimal= 1.1;
CREATE TABLE t1 SELECT @decimal AS c1;
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Bug #45261 : Crash, stored procedure + decimal
--echo # Original test by the reporter.
--echo #
--echo # should not crash
CREATE TABLE t1
SELECT .123456789012345678901234567890123456789012345678901234567890123456 AS a;
DROP TABLE t1;
delimiter |;
CREATE PROCEDURE test_proc()
BEGIN
# The las non critical CUSER definition is:
# DECLARE mycursor CURSOR FOR SELECT 1 %
# .12345678912345678912345678912345678912345678912345678912345678912 AS my_col;
DECLARE mycursor CURSOR FOR
SELECT 1 %
.123456789123456789123456789123456789123456789123456789123456789123456789123456789
AS my_col;
OPEN mycursor;
CLOSE mycursor;
END|
delimiter ;|
--echo # should not crash
CALL test_proc();
DROP PROCEDURE test_proc;
--echo #
--echo # Bug #48370 Absolutely wrong calculations with GROUP BY and
--echo # decimal fields when using IF
--echo #
CREATE TABLE currencies (id int, rate decimal(16,4),
PRIMARY KEY (id), KEY (rate));
INSERT INTO currencies VALUES (11,0.7028);
INSERT INTO currencies VALUES (1,1);
CREATE TABLE payments (
id int,
supplier_id int,
status int,
currency_id int,
vat decimal(7,4),
PRIMARY KEY (id),
KEY currency_id (currency_id),
KEY supplier_id (supplier_id)
);
INSERT INTO payments (id,status,vat,supplier_id,currency_id) VALUES
(3001,2,0.0000,344,11), (1,2,0.0000,1,1);
CREATE TABLE sub_tasks (
id int,
currency_id int,
price decimal(16,4),
discount decimal(10,4),
payment_id int,
PRIMARY KEY (id),
KEY currency_id (currency_id),
KEY payment_id (payment_id)
) ;
INSERT INTO sub_tasks (id, price, discount, payment_id, currency_id) VALUES
(52, 12.60, 0, 3001, 11), (56, 14.58, 0, 3001, 11);
--echo # should return 1 and the same values in col 2 and 3
select STRAIGHT_JOIN
(1 + PAY.vat) AS mult,
SUM(ROUND((SUB.price - ROUND(ROUND(SUB.price, 2) * SUB.discount, 2)) *
CUR.rate / CUR.rate, 2)
) v_net_with_discount,
SUM(ROUND((SUB.price - ROUND(ROUND(SUB.price, 2) * SUB.discount, 1)) *
CUR.rate / CUR.rate , 2)
* (1 + PAY.vat)
) v_total
from
currencies CUR, payments PAY, sub_tasks SUB
where
SUB.payment_id = PAY.id and
PAY.currency_id = CUR.id and
PAY.id > 2
group by PAY.id + 1;
DROP TABLE currencies, payments, sub_tasks;
--echo End of 5.1 tests

View file

@ -184,7 +184,7 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
i= x;
while (*x && *x != field_separator)
x++;
if (x[0] && x[1]) // skip separator if found
if (x[0] && x[1]) /* skip separator if found */
x++;
if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
DBUG_RETURN(0);

View file

@ -340,7 +340,7 @@ mkdir $DESTDIR/mysql-test
cp mysql-test/mysql-test-run.pl $DESTDIR/mysql-test/
cp mysql-test/mysql-stress-test.pl $DESTDIR/mysql-test/
cp mysql-test/README $DESTDIR/mysql-test/
cp -R mysql-test/{t,r,include,suite,std_data,lib} $DESTDIR/mysql-test/
cp -R mysql-test/{t,r,include,suite,std_data,lib,collections} $DESTDIR/mysql-test/
# Note that this will not copy "extra" if a soft link
if [ -d mysql-test/extra ] ; then

View file

@ -26,7 +26,7 @@
*/
static
const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] =
const TABLE_FIELD_TYPE event_table_fields[ET_FIELD_COUNT] =
{
{
{ C_STRING_WITH_LEN("db") },
@ -151,6 +151,24 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] =
}
};
static const TABLE_FIELD_DEF
event_table_def= {ET_FIELD_COUNT, event_table_fields};
class Event_db_intact : public Table_check_intact
{
protected:
void report_error(uint, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
error_log_print(ERROR_LEVEL, fmt, args);
va_end(args);
}
};
/** In case of an error, a message is printed to the error log. */
static Event_db_intact table_intact;
/**
Puts some data common to CREATE and ALTER EVENT into a row.
@ -1117,10 +1135,8 @@ Event_db_repository::check_system_tables(THD *thd)
}
else
{
if (table_check_intact(tables.table, MYSQL_DB_FIELD_COUNT,
mysql_db_table_fields))
if (table_intact.check(tables.table, &mysql_db_table_def))
ret= 1;
/* in case of an error, the message is printed inside table_check_intact */
close_thread_tables(thd);
}
@ -1154,9 +1170,8 @@ Event_db_repository::check_system_tables(THD *thd)
}
else
{
if (table_check_intact(tables.table, ET_FIELD_COUNT, event_table_fields))
if (table_intact.check(tables.table, &event_table_def))
ret= 1;
/* in case of an error, the message is printed inside table_check_intact */
close_thread_tables(thd);
}

View file

@ -2486,6 +2486,50 @@ Field_new_decimal::Field_new_decimal(uint32 len_arg,
}
Field *Field_new_decimal::create_from_item (Item *item)
{
uint8 dec= item->decimals;
uint8 intg= item->decimal_precision() - dec;
uint32 len= item->max_length;
DBUG_ASSERT (item->result_type() == DECIMAL_RESULT);
/*
Trying to put too many digits overall in a DECIMAL(prec,dec)
will always throw a warning. We must limit dec to
DECIMAL_MAX_SCALE however to prevent an assert() later.
*/
if (dec > 0)
{
signed int overflow;
dec= min(dec, DECIMAL_MAX_SCALE);
/*
If the value still overflows the field with the corrected dec,
we'll throw out decimals rather than integers. This is still
bad and of course throws a truncation warning.
+1: for decimal point
*/
const int required_length=
my_decimal_precision_to_length(intg + dec, dec,
item->unsigned_flag);
overflow= required_length - len;
if (overflow > 0)
dec= max(0, dec - overflow); // too long, discard fract
else
/* Corrected value fits. */
len= required_length;
}
return new Field_new_decimal(len, item->maybe_null, item->name,
dec, item->unsigned_flag);
}
int Field_new_decimal::reset(void)
{
store_value(&decimal_zero);

View file

@ -807,6 +807,7 @@ public:
uint is_equal(Create_field *new_field);
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
static Field *create_from_item (Item *);
};

View file

@ -4899,9 +4899,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
switch (field_type()) {
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
field= new Field_new_decimal((uchar*) 0, max_length, null_ptr, 0,
Field::NONE, name, decimals, 0,
unsigned_flag);
field= Field_new_decimal::create_from_item(this);
break;
case MYSQL_TYPE_TINY:
field= new Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
@ -6957,7 +6955,7 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
{
switch (type) {
case INT_RESULT:
return new Item_cache_int();
return new Item_cache_int(item->field_type());
case REAL_RESULT:
return new Item_cache_real();
case DECIMAL_RESULT:
@ -6975,8 +6973,9 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
void Item_cache::store(Item *item)
{
if (item)
example= item;
example= item;
if (!item)
null_value= TRUE;
value_cached= FALSE;
}
@ -6990,12 +6989,15 @@ void Item_cache::print(String *str, enum_query_type query_type)
str->append(')');
}
void Item_cache_int::cache_value()
bool Item_cache_int::cache_value()
{
if (!example)
return FALSE;
value_cached= TRUE;
value= example->val_int_result();
null_value= example->null_value;
unsigned_flag= example->unsigned_flag;
return TRUE;
}
@ -7012,8 +7014,8 @@ void Item_cache_int::store(Item *item, longlong val_arg)
String *Item_cache_int::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return NULL;
str->set(value, default_charset());
return str;
}
@ -7022,8 +7024,8 @@ String *Item_cache_int::val_str(String *str)
my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return NULL;
int2my_decimal(E_DEC_FATAL_ERROR, value, unsigned_flag, decimal_val);
return decimal_val;
}
@ -7031,40 +7033,43 @@ my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
double Item_cache_int::val_real()
{
DBUG_ASSERT(fixed == 1);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return 0.0;
return (double) value;
}
longlong Item_cache_int::val_int()
{
DBUG_ASSERT(fixed == 1);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return 0;
return value;
}
void Item_cache_real::cache_value()
bool Item_cache_real::cache_value()
{
if (!example)
return FALSE;
value_cached= TRUE;
value= example->val_result();
null_value= example->null_value;
return TRUE;
}
double Item_cache_real::val_real()
{
DBUG_ASSERT(fixed == 1);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return 0.0;
return value;
}
longlong Item_cache_real::val_int()
{
DBUG_ASSERT(fixed == 1);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return 0;
return (longlong) rint(value);
}
@ -7072,8 +7077,8 @@ longlong Item_cache_real::val_int()
String* Item_cache_real::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return NULL;
str->set_real(value, decimals, default_charset());
return str;
}
@ -7082,27 +7087,30 @@ String* Item_cache_real::val_str(String *str)
my_decimal *Item_cache_real::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return NULL;
double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
return decimal_val;
}
void Item_cache_decimal::cache_value()
bool Item_cache_decimal::cache_value()
{
if (!example)
return FALSE;
value_cached= TRUE;
my_decimal *val= example->val_decimal_result(&decimal_value);
if (!(null_value= example->null_value) && val != &decimal_value)
my_decimal2decimal(val, &decimal_value);
return TRUE;
}
double Item_cache_decimal::val_real()
{
DBUG_ASSERT(fixed);
double res;
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return NULL;
my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &res);
return res;
}
@ -7111,8 +7119,8 @@ longlong Item_cache_decimal::val_int()
{
DBUG_ASSERT(fixed);
longlong res;
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return 0;
my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &res);
return res;
}
@ -7120,8 +7128,8 @@ longlong Item_cache_decimal::val_int()
String* Item_cache_decimal::val_str(String *str)
{
DBUG_ASSERT(fixed);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return NULL;
my_decimal_round(E_DEC_FATAL_ERROR, &decimal_value, decimals, FALSE,
&decimal_value);
my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, str);
@ -7131,14 +7139,16 @@ String* Item_cache_decimal::val_str(String *str)
my_decimal *Item_cache_decimal::val_decimal(my_decimal *val)
{
DBUG_ASSERT(fixed);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return NULL;
return &decimal_value;
}
void Item_cache_str::cache_value()
bool Item_cache_str::cache_value()
{
if (!example)
return FALSE;
value_cached= TRUE;
value_buff.set(buffer, sizeof(buffer), example->collation.collation);
value= example->str_result(&value_buff);
@ -7157,6 +7167,7 @@ void Item_cache_str::cache_value()
value_buff.copy(*value);
value= &value_buff;
}
return TRUE;
}
double Item_cache_str::val_real()
@ -7164,8 +7175,8 @@ double Item_cache_str::val_real()
DBUG_ASSERT(fixed == 1);
int err_not_used;
char *end_not_used;
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return 0.0;
if (value)
return my_strntod(value->charset(), (char*) value->ptr(),
value->length(), &end_not_used, &err_not_used);
@ -7177,8 +7188,8 @@ longlong Item_cache_str::val_int()
{
DBUG_ASSERT(fixed == 1);
int err;
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return 0;
if (value)
return my_strntoll(value->charset(), value->ptr(),
value->length(), 10, (char**) 0, &err);
@ -7190,8 +7201,8 @@ longlong Item_cache_str::val_int()
String* Item_cache_str::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return 0;
return value;
}
@ -7199,8 +7210,8 @@ String* Item_cache_str::val_str(String *str)
my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return NULL;
if (value)
string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
else
@ -7211,8 +7222,8 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
int Item_cache_str::save_in_field(Field *field, bool no_conversions)
{
if (!value_cached)
cache_value();
if (!value_cached && !cache_value())
return 0;
int res= Item_cache::save_in_field(field, no_conversions);
return (is_varbinary && field->type() == MYSQL_TYPE_STRING &&
value->length() < field->field_length) ? 1 : res;
@ -7247,13 +7258,21 @@ bool Item_cache_row::setup(Item * item)
void Item_cache_row::store(Item * item)
{
example= item;
if (!item)
{
null_value= TRUE;
return;
}
for (uint i= 0; i < item_count; i++)
values[i]->store(item->element_index(i));
}
void Item_cache_row::cache_value()
bool Item_cache_row::cache_value()
{
if (!example)
return FALSE;
value_cached= TRUE;
null_value= 0;
example->bring_value();
@ -7262,6 +7281,7 @@ void Item_cache_row::cache_value()
values[i]->cache_value();
null_value|= values[i]->null_value;
}
return TRUE;
}

View file

@ -2138,6 +2138,23 @@ public:
save_in_field(result_field, no_conversions);
}
void cleanup();
/*
This method is used for debug purposes to print the name of an
item to the debug log. The second use of this method is as
a helper function of print() and error messages, where it is
applicable. To suit both goals it should return a meaningful,
distinguishable and sintactically correct string. This method
should not be used for runtime type identification, use enum
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
instead.
Added here, to the parent class of both Item_func and Item_sum_func.
NOTE: for Items inherited from Item_sum, func_name() return part of
function name till first argument (including '(') to make difference in
names for functions with 'distinct' clause and without 'distinct' and
also to make printing of items inherited from Item_sum uniform.
*/
virtual const char *func_name() const= 0;
};
@ -2947,7 +2964,7 @@ public:
return this == item;
}
virtual void store(Item *item);
virtual void cache_value()= 0;
virtual bool cache_value()= 0;
};
@ -2968,7 +2985,7 @@ public:
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type() const { return INT_RESULT; }
bool result_as_longlong() { return TRUE; }
void cache_value();
bool cache_value();
};
@ -2984,7 +3001,7 @@ public:
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type() const { return REAL_RESULT; }
void cache_value();
bool cache_value();
};
@ -3000,7 +3017,7 @@ public:
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type() const { return DECIMAL_RESULT; }
void cache_value();
bool cache_value();
};
@ -3025,7 +3042,7 @@ public:
enum Item_result result_type() const { return STRING_RESULT; }
CHARSET_INFO *charset() const { return value->charset(); };
int save_in_field(Field *field, bool no_conversions);
void cache_value();
bool cache_value();
};
class Item_cache_row: public Item_cache
@ -3094,7 +3111,7 @@ public:
values= 0;
DBUG_VOID_RETURN;
}
void cache_value();
bool cache_value();
};

View file

@ -30,6 +30,9 @@
#include "sql_select.h"
static bool convert_constant_item(THD *, Item_field *, Item **);
static longlong
get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null);
static Item_result item_store_type(Item_result a, Item *item,
my_bool unsigned_flag)
@ -533,11 +536,12 @@ void Item_bool_func2::fix_length_and_dec()
}
int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type)
{
owner= item;
func= comparator_matrix[type]
[test(owner->functype() == Item_func::EQUAL_FUNC)];
[is_owner_equal_func()];
switch (type) {
case ROW_RESULT:
{
@ -557,7 +561,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
return 1;
}
if (comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i)))
if (comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i),
set_null))
return 1;
}
break;
@ -571,7 +576,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
if (cmp_collation.set((*a)->collation, (*b)->collation) ||
cmp_collation.derivation == DERIVATION_NONE)
{
my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
my_coll_agg_error((*a)->collation, (*b)->collation,
owner->func_name());
return 1;
}
if (cmp_collation.collation == &my_charset_bin)
@ -881,7 +887,7 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
}
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
Item **a1, Item **a2,
Item_result type)
{
@ -891,6 +897,8 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
owner= owner_arg;
a= a1;
b= a2;
owner= owner_arg;
thd= current_thd;
if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
{
@ -921,9 +929,10 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
b= (Item **)&b_cache;
}
}
is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
is_nulls_eq= is_owner_equal_func();
func= &Arg_comparator::compare_datetime;
get_value_func= &get_datetime_value;
get_value_a_func= &get_datetime_value;
get_value_b_func= &get_datetime_value;
return 0;
}
else if (type == STRING_RESULT && (*a)->field_type() == MYSQL_TYPE_TIME &&
@ -932,9 +941,10 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
/* Compare TIME values as integers. */
a_cache= 0;
b_cache= 0;
is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
is_nulls_eq= is_owner_equal_func();
func= &Arg_comparator::compare_datetime;
get_value_func= &get_time_value;
get_value_a_func= &get_time_value;
get_value_b_func= &get_time_value;
return 0;
}
else if (type == STRING_RESULT &&
@ -943,9 +953,42 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
{
DTCollation coll;
coll.set((*a)->collation.collation);
if (agg_item_set_converter(coll, owner_arg->func_name(),
if (agg_item_set_converter(coll, owner->func_name(),
b, 1, MY_COLL_CMP_CONV, 1))
return 1;
} else if (type != ROW_RESULT && ((*a)->field_type() == MYSQL_TYPE_YEAR ||
(*b)->field_type() == MYSQL_TYPE_YEAR))
{
is_nulls_eq= is_owner_equal_func();
year_as_datetime= FALSE;
if ((*a)->is_datetime())
{
year_as_datetime= TRUE;
get_value_a_func= &get_datetime_value;
} else if ((*a)->field_type() == MYSQL_TYPE_YEAR)
get_value_a_func= &get_year_value;
else
{
/*
Because convert_constant_item is called only for EXECUTE in PS mode
the value of get_value_x_func set in PREPARE might be not
valid for EXECUTE.
*/
get_value_a_func= NULL;
}
if ((*b)->is_datetime())
{
year_as_datetime= TRUE;
get_value_b_func= &get_datetime_value;
} else if ((*b)->field_type() == MYSQL_TYPE_YEAR)
get_value_b_func= &get_year_value;
else
get_value_b_func= NULL;
func= &Arg_comparator::compare_year;
return 0;
}
a= cache_converted_constant(thd, a, &a_cache, type);
@ -988,11 +1031,11 @@ Item** Arg_comparator::cache_converted_constant(THD *thd, Item **value,
}
void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
void Arg_comparator::set_datetime_cmp_func(Item_result_field *owner_arg,
Item **a1, Item **b1)
{
thd= current_thd;
/* A caller will handle null values by itself. */
owner= NULL;
owner= owner_arg;
a= a1;
b= b1;
a_type= (*a)->field_type();
@ -1001,7 +1044,8 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
b_cache= 0;
is_nulls_eq= FALSE;
func= &Arg_comparator::compare_datetime;
get_value_func= &get_datetime_value;
get_value_a_func= &get_datetime_value;
get_value_b_func= &get_datetime_value;
}
@ -1101,6 +1145,51 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
return value;
}
/*
Retrieves YEAR value of 19XX form from given item.
SYNOPSIS
get_year_value()
thd thread handle
item_arg [in/out] item to retrieve YEAR value from
cache_arg [in/out] pointer to place to store the caching item to
warn_item [in] item for issuing the conversion warning
is_null [out] TRUE <=> the item_arg is null
DESCRIPTION
Retrieves the YEAR value of 19XX form from given item for comparison by the
compare_year() function.
RETURN
obtained value
*/
static longlong
get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null)
{
longlong value= 0;
Item *item= **item_arg;
value= item->val_int();
*is_null= item->null_value;
if (*is_null)
return ~(ulonglong) 0;
/*
Coerce value to the 19XX form in order to correctly compare
YEAR(2) & YEAR(4) types.
*/
if (value < 70)
value+= 100;
if (value <= 1900)
value+= 1900;
return value;
}
/*
Compare items values as dates.
@ -1133,25 +1222,25 @@ int Arg_comparator::compare_datetime()
longlong a_value, b_value;
/* Get DATE/DATETIME/TIME value of the 'a' item. */
a_value= (*get_value_func)(thd, &a, &a_cache, *b, &a_is_null);
a_value= (*get_value_a_func)(thd, &a, &a_cache, *b, &a_is_null);
if (!is_nulls_eq && a_is_null)
{
if (owner)
if (set_null)
owner->null_value= 1;
return -1;
}
/* Get DATE/DATETIME/TIME value of the 'b' item. */
b_value= (*get_value_func)(thd, &b, &b_cache, *a, &b_is_null);
b_value= (*get_value_b_func)(thd, &b, &b_cache, *a, &b_is_null);
if (a_is_null || b_is_null)
{
if (owner)
if (set_null)
owner->null_value= is_nulls_eq ? 0 : 1;
return is_nulls_eq ? (a_is_null == b_is_null) : -1;
}
/* Here we have two not-NULL values. */
if (owner)
if (set_null)
owner->null_value= 0;
/* Compare values. */
@ -1164,15 +1253,17 @@ int Arg_comparator::compare_datetime()
int Arg_comparator::compare_string()
{
String *res1,*res2;
if ((res1= (*a)->val_str(&owner->tmp_value1)))
if ((res1= (*a)->val_str(&value1)))
{
if ((res2= (*b)->val_str(&owner->tmp_value2)))
if ((res2= (*b)->val_str(&value2)))
{
owner->null_value= 0;
if (set_null)
owner->null_value= 0;
return sortcmp(res1,res2,cmp_collation.collation);
}
}
owner->null_value= 1;
if (set_null)
owner->null_value= 1;
return -1;
}
@ -1191,18 +1282,20 @@ int Arg_comparator::compare_string()
int Arg_comparator::compare_binary_string()
{
String *res1,*res2;
if ((res1= (*a)->val_str(&owner->tmp_value1)))
if ((res1= (*a)->val_str(&value1)))
{
if ((res2= (*b)->val_str(&owner->tmp_value2)))
if ((res2= (*b)->val_str(&value2)))
{
owner->null_value= 0;
if (set_null)
owner->null_value= 0;
uint res1_length= res1->length();
uint res2_length= res2->length();
int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
return cmp ? cmp : (int) (res1_length - res2_length);
}
}
owner->null_value= 1;
if (set_null)
owner->null_value= 1;
return -1;
}
@ -1215,8 +1308,8 @@ int Arg_comparator::compare_binary_string()
int Arg_comparator::compare_e_string()
{
String *res1,*res2;
res1= (*a)->val_str(&owner->tmp_value1);
res2= (*b)->val_str(&owner->tmp_value2);
res1= (*a)->val_str(&value1);
res2= (*b)->val_str(&value2);
if (!res1 || !res2)
return test(res1 == res2);
return test(sortcmp(res1, res2, cmp_collation.collation) == 0);
@ -1226,8 +1319,8 @@ int Arg_comparator::compare_e_string()
int Arg_comparator::compare_e_binary_string()
{
String *res1,*res2;
res1= (*a)->val_str(&owner->tmp_value1);
res2= (*b)->val_str(&owner->tmp_value2);
res1= (*a)->val_str(&value1);
res2= (*b)->val_str(&value2);
if (!res1 || !res2)
return test(res1 == res2);
return test(stringcmp(res1, res2) == 0);
@ -1248,13 +1341,15 @@ int Arg_comparator::compare_real()
val2= (*b)->val_real();
if (!(*b)->null_value)
{
owner->null_value= 0;
if (set_null)
owner->null_value= 0;
if (val1 < val2) return -1;
if (val1 == val2) return 0;
return 1;
}
}
owner->null_value= 1;
if (set_null)
owner->null_value= 1;
return -1;
}
@ -1268,11 +1363,13 @@ int Arg_comparator::compare_decimal()
my_decimal *val2= (*b)->val_decimal(&value2);
if (!(*b)->null_value)
{
owner->null_value= 0;
if (set_null)
owner->null_value= 0;
return my_decimal_cmp(val1, val2);
}
}
owner->null_value= 1;
if (set_null)
owner->null_value= 1;
return -1;
}
@ -1310,7 +1407,8 @@ int Arg_comparator::compare_real_fixed()
val2= (*b)->val_real();
if (!(*b)->null_value)
{
owner->null_value= 0;
if (set_null)
owner->null_value= 0;
if (val1 == val2 || fabs(val1 - val2) < precision)
return 0;
if (val1 < val2)
@ -1318,7 +1416,8 @@ int Arg_comparator::compare_real_fixed()
return 1;
}
}
owner->null_value= 1;
if (set_null)
owner->null_value= 1;
return -1;
}
@ -1341,13 +1440,15 @@ int Arg_comparator::compare_int_signed()
longlong val2= (*b)->val_int();
if (!(*b)->null_value)
{
owner->null_value= 0;
if (set_null)
owner->null_value= 0;
if (val1 < val2) return -1;
if (val1 == val2) return 0;
return 1;
}
}
owner->null_value= 1;
if (set_null)
owner->null_value= 1;
return -1;
}
@ -1364,13 +1465,15 @@ int Arg_comparator::compare_int_unsigned()
ulonglong val2= (*b)->val_int();
if (!(*b)->null_value)
{
owner->null_value= 0;
if (set_null)
owner->null_value= 0;
if (val1 < val2) return -1;
if (val1 == val2) return 0;
return 1;
}
}
owner->null_value= 1;
if (set_null)
owner->null_value= 1;
return -1;
}
@ -1387,7 +1490,8 @@ int Arg_comparator::compare_int_signed_unsigned()
ulonglong uval2= (ulonglong)(*b)->val_int();
if (!(*b)->null_value)
{
owner->null_value= 0;
if (set_null)
owner->null_value= 0;
if (sval1 < 0 || (ulonglong)sval1 < uval2)
return -1;
if ((ulonglong)sval1 == uval2)
@ -1395,7 +1499,8 @@ int Arg_comparator::compare_int_signed_unsigned()
return 1;
}
}
owner->null_value= 1;
if (set_null)
owner->null_value= 1;
return -1;
}
@ -1412,7 +1517,8 @@ int Arg_comparator::compare_int_unsigned_signed()
longlong sval2= (*b)->val_int();
if (!(*b)->null_value)
{
owner->null_value= 0;
if (set_null)
owner->null_value= 0;
if (sval2 < 0)
return 1;
if (uval1 < (ulonglong)sval2)
@ -1422,7 +1528,8 @@ int Arg_comparator::compare_int_unsigned_signed()
return 1;
}
}
owner->null_value= 1;
if (set_null)
owner->null_value= 1;
return -1;
}
@ -1458,10 +1565,11 @@ int Arg_comparator::compare_row()
for (uint i= 0; i<n; i++)
{
res= comparators[i].compare();
if (owner->null_value)
/* Aggregate functions don't need special null handling. */
if (owner->null_value && owner->type() == Item::FUNC_ITEM)
{
// NULL was compared
switch (owner->functype()) {
switch (((Item_func*)owner)->functype()) {
case Item_func::NE_FUNC:
break; // NE never aborts on NULL even if abort_on_null is set
case Item_func::LT_FUNC:
@ -1470,7 +1578,7 @@ int Arg_comparator::compare_row()
case Item_func::GE_FUNC:
return -1; // <, <=, > and >= always fail on NULL
default: // EQ_FUNC
if (owner->abort_on_null)
if (((Item_bool_func2*)owner)->abort_on_null)
return -1; // We do not need correct NULL returning
}
was_null= 1;
@ -1507,6 +1615,67 @@ int Arg_comparator::compare_e_row()
}
/**
Compare values as YEAR.
@details
Compare items as YEAR for EQUAL_FUNC and for other comparison functions.
The YEAR values of form 19XX are obtained with help of the get_year_value()
function.
If one of arguments is of DATE/DATETIME type its value is obtained
with help of the get_datetime_value function. In this case YEAR values
prior to comparison are converted to the ulonglong YYYY-00-00 00:00:00
DATETIME form.
If an argument type neither YEAR nor DATE/DATEIME then val_int function
is used to obtain value for comparison.
RETURN
If is_nulls_eq is TRUE:
1 if items are equal or both are null
0 otherwise
If is_nulls_eq is FALSE:
-1 a < b
0 a == b or at least one of items is null
1 a > b
See the table:
is_nulls_eq | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
a_is_null | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
b_is_null | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
result | 1 | 0 | 0 |0/1| 0 | 0 | 0 |-1/0/1|
*/
int Arg_comparator::compare_year()
{
bool a_is_null, b_is_null;
ulonglong val1= get_value_a_func ?
(*get_value_a_func)(thd, &a, &a_cache, *b, &a_is_null) :
(*a)->val_int();
ulonglong val2= get_value_b_func ?
(*get_value_b_func)(thd, &b, &b_cache, *a, &b_is_null) :
(*b)->val_int();
if (!(*a)->null_value)
{
if (!(*b)->null_value)
{
if (set_null)
owner->null_value= 0;
/* Convert year to DATETIME of form YYYY-00-00 00:00:00 when necessary. */
if((*a)->field_type() == MYSQL_TYPE_YEAR && year_as_datetime)
val1*= 10000000000LL;
if((*b)->field_type() == MYSQL_TYPE_YEAR && year_as_datetime)
val2*= 10000000000LL;
if (val1 < val2) return is_nulls_eq ? 0 : -1;
if (val1 == val2) return is_nulls_eq ? 1 : 0;
return is_nulls_eq ? 0 : 1;
}
}
if (set_null)
owner->null_value= is_nulls_eq ? 0 : 1;
return (is_nulls_eq && (*a)->null_value == (*b)->null_value) ? 1 : 0;
}
void Item_func_truth::fix_length_and_dec()
{
maybe_null= 0;
@ -1794,8 +1963,8 @@ longlong Item_func_lt::val_int()
longlong Item_func_strcmp::val_int()
{
DBUG_ASSERT(fixed == 1);
String *a=args[0]->val_str(&tmp_value1);
String *b=args[1]->val_str(&tmp_value2);
String *a=args[0]->val_str(&cmp.value1);
String *b=args[1]->val_str(&cmp.value2);
if (!a || !b)
{
null_value=1;
@ -2078,8 +2247,8 @@ void Item_func_between::fix_length_and_dec()
if (compare_as_dates)
{
ge_cmp.set_datetime_cmp_func(args, args + 1);
le_cmp.set_datetime_cmp_func(args, args + 2);
ge_cmp.set_datetime_cmp_func(this, args, args + 1);
le_cmp.set_datetime_cmp_func(this, args, args + 2);
}
else if (time_items_found == 3)
{
@ -4407,13 +4576,13 @@ void Item_func_isnotnull::print(String *str, enum_query_type query_type)
longlong Item_func_like::val_int()
{
DBUG_ASSERT(fixed == 1);
String* res = args[0]->val_str(&tmp_value1);
String* res = args[0]->val_str(&cmp.value1);
if (args[0]->null_value)
{
null_value=1;
return 0;
}
String* res2 = args[1]->val_str(&tmp_value2);
String* res2 = args[1]->val_str(&cmp.value2);
if (args[1]->null_value)
{
null_value=1;
@ -4437,7 +4606,7 @@ Item_func::optimize_type Item_func_like::select_optimize() const
{
if (args[1]->const_item())
{
String* res2= args[1]->val_str((String *)&tmp_value2);
String* res2= args[1]->val_str((String *)&cmp.value2);
if (!res2)
return OPTIMIZE_NONE;
@ -4468,7 +4637,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
if (escape_item->const_item())
{
/* If we are on execution stage */
String *escape_str= escape_item->val_str(&tmp_value1);
String *escape_str= escape_item->val_str(&cmp.value1);
if (escape_str)
{
if (escape_used_in_parsing && (
@ -4523,7 +4692,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
!(specialflag & SPECIAL_NO_NEW_FUNC))
{
String* res2 = args[1]->val_str(&tmp_value2);
String* res2 = args[1]->val_str(&cmp.value2);
if (!res2)
return FALSE; // Null argument

View file

@ -32,7 +32,7 @@ class Arg_comparator: public Sql_alloc
{
Item **a, **b;
arg_cmp_func func;
Item_bool_func2 *owner;
Item_result_field *owner;
Arg_comparator *comparators; // used only for compare_row()
double precision;
/* Fields used in DATE/DATETIME comparison. */
@ -40,30 +40,42 @@ class Arg_comparator: public Sql_alloc
enum_field_types a_type, b_type; // Types of a and b items
Item *a_cache, *b_cache; // Cached values of a and b items
bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
bool set_null; // TRUE <=> set owner->null_value
// when one of arguments is NULL.
bool year_as_datetime; // TRUE <=> convert YEAR value to
// the YYYY-00-00 00:00:00 DATETIME
// format. See compare_year.
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
longlong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null);
longlong (*get_value_a_func)(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null);
longlong (*get_value_b_func)(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null);
public:
DTCollation cmp_collation;
/* Allow owner function to use string buffers. */
String value1, value2;
Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
Arg_comparator(): thd(0), a_cache(0), b_cache(0), set_null(0),
year_as_datetime(0), get_value_a_func(0), get_value_b_func(0) {};
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
a_cache(0), b_cache(0) {};
a_cache(0), b_cache(0), set_null(0), year_as_datetime(0),
get_value_a_func(0), get_value_b_func(0) {};
int set_compare_func(Item_bool_func2 *owner, Item_result type);
inline int set_compare_func(Item_bool_func2 *owner_arg)
int set_compare_func(Item_result_field *owner, Item_result type);
inline int set_compare_func(Item_result_field *owner_arg)
{
return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
(*b)->result_type()));
}
int set_cmp_func(Item_bool_func2 *owner_arg,
int set_cmp_func(Item_result_field *owner_arg,
Item **a1, Item **a2,
Item_result type);
inline int set_cmp_func(Item_bool_func2 *owner_arg,
Item **a1, Item **a2)
inline int set_cmp_func(Item_result_field *owner_arg,
Item **a1, Item **a2, bool set_null_arg)
{
set_null= set_null_arg;
return set_cmp_func(owner_arg, a1, a2,
item_cmp_type((*a1)->result_type(),
(*a2)->result_type()));
@ -89,14 +101,20 @@ public:
int compare_real_fixed();
int compare_e_real_fixed();
int compare_datetime(); // compare args[0] & args[1] as DATETIMEs
int compare_year();
static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
ulonglong *const_val_arg);
void set_datetime_cmp_func(Item **a1, Item **b1);
Item** cache_converted_constant(THD *thd, Item **value, Item **cache,
Item_result type);
void set_datetime_cmp_func(Item_result_field *owner_arg, Item **a1, Item **b1);
static arg_cmp_func comparator_matrix [5][2];
inline bool is_owner_equal_func()
{
return (owner->type() == Item::FUNC_ITEM &&
((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
}
friend class Item_func;
};
@ -326,7 +344,6 @@ class Item_bool_func2 :public Item_int_func
{ /* Bool with 2 string args */
protected:
Arg_comparator cmp;
String tmp_value1,tmp_value2;
bool abort_on_null;
public:
@ -335,7 +352,7 @@ public:
void fix_length_and_dec();
void set_cmp_func()
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1);
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, TRUE);
}
optimize_type select_optimize() const { return OPTIMIZE_OP; }
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }

View file

@ -3524,6 +3524,7 @@ Create_func_get_lock Create_func_get_lock::s_singleton;
Item*
Create_func_get_lock::create(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_get_lock(arg1, arg2);
}
@ -3635,6 +3636,7 @@ Create_func_is_free_lock Create_func_is_free_lock::s_singleton;
Item*
Create_func_is_free_lock::create(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_is_free_lock(arg1);
}
@ -3645,6 +3647,7 @@ Create_func_is_used_lock Create_func_is_used_lock::s_singleton;
Item*
Create_func_is_used_lock::create(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_is_used_lock(arg1);
}
@ -3961,6 +3964,8 @@ Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name,
Item *func= NULL;
int arg_count= 0;
thd->lex->set_stmt_unsafe();
if (item_list != NULL)
arg_count= item_list->elements;
@ -4203,6 +4208,7 @@ Create_func_release_lock Create_func_release_lock::s_singleton;
Item*
Create_func_release_lock::create(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_release_lock(arg1);
}
@ -4325,6 +4331,7 @@ Create_func_sleep Create_func_sleep::s_singleton;
Item*
Create_func_sleep::create(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_sleep(arg1);
}
@ -4591,6 +4598,7 @@ Create_func_version Create_func_version::s_singleton;
Item*
Create_func_version::create(THD *thd)
{
thd->lex->set_stmt_unsafe();
return new (thd->mem_root) Item_static_string_func("version()",
server_version,
(uint) strlen(server_version),

View file

@ -451,45 +451,8 @@ Field *Item_func::tmp_table_field(TABLE *table)
return make_string_field(table);
break;
case DECIMAL_RESULT:
{
uint8 dec= decimals;
uint8 intg= decimal_precision() - dec;
uint32 len= max_length;
/*
Trying to put too many digits overall in a DECIMAL(prec,dec)
will always throw a warning. We must limit dec to
DECIMAL_MAX_SCALE however to prevent an assert() later.
*/
if (dec > 0)
{
int overflow;
dec= min(dec, DECIMAL_MAX_SCALE);
/*
If the value still overflows the field with the corrected dec,
we'll throw out decimals rather than integers. This is still
bad and of course throws a truncation warning.
*/
const int required_length=
my_decimal_precision_to_length(intg + dec, dec,
unsigned_flag);
overflow= required_length - len;
if (overflow > 0)
dec= max(0, dec - overflow); // too long, discard fract
else
/* Corrected value fits. */
len= required_length;
}
field= new Field_new_decimal(len, maybe_null, name, dec, unsigned_flag);
field= Field_new_decimal::create_from_item(this);
break;
}
case ROW_RESULT:
default:
// This case should never be chosen

View file

@ -124,17 +124,6 @@ public:
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
virtual bool have_rev_func() const { return 0; }
virtual Item *key_item() const { return args[0]; }
/*
This method is used for debug purposes to print the name of an
item to the debug log. The second use of this method is as
a helper function of print(), where it is applicable.
To suit both goals it should return a meaningful,
distinguishable and sintactically correct string. This method
should not be used for runtime type identification, use enum
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
instead.
*/
virtual const char *func_name() const= 0;
virtual bool const_item() const { return const_item_cache; }
inline Item **arguments() const { return args; }
void set_arguments(List<Item> &list);

View file

@ -511,8 +511,8 @@ err:
longlong Item_func_spatial_rel::val_int()
{
DBUG_ASSERT(fixed == 1);
String *res1= args[0]->val_str(&tmp_value1);
String *res2= args[1]->val_str(&tmp_value2);
String *res1= args[0]->val_str(&cmp.value1);
String *res2= args[1]->val_str(&cmp.value2);
Geometry_buffer buffer1, buffer2;
Geometry *g1, *g2;
MBR mbr1, mbr2;

View file

@ -1827,8 +1827,9 @@ String *Item_func_database::val_str(String *str)
/**
@todo
make USER() replicate properly (currently it is replicated to "")
@note USER() is replicated correctly if binlog_format=ROW or (as of
BUG#28086) binlog_format=MIXED, but is incorrectly replicated to ''
if binlog_format=STATEMENT.
*/
bool Item_func_user::init(const char *user, const char *host)
{

View file

@ -132,6 +132,7 @@ public:
@return the SELECT_LEX structure associated with this Item
*/
st_select_lex* get_select_lex();
const char *func_name() const { DBUG_ASSERT(0); return "subselect"; }
friend class select_subselect;
friend class Item_in_optimizer;

View file

@ -517,8 +517,7 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
name, table->s, collation.collation);
break;
case DECIMAL_RESULT:
field= new Field_new_decimal(max_length, maybe_null, name,
decimals, unsigned_flag);
field= Field_new_decimal::create_from_item(this);
break;
case ROW_RESULT:
default:
@ -615,35 +614,6 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
}
Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
:Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
was_values(item->was_values)
{
/* copy results from old value */
switch (hybrid_type) {
case INT_RESULT:
sum_int= item->sum_int;
break;
case DECIMAL_RESULT:
my_decimal2decimal(&item->sum_dec, &sum_dec);
break;
case REAL_RESULT:
sum= item->sum;
break;
case STRING_RESULT:
/*
This can happen with ROLLUP. Note that the value is already
copied at function call.
*/
break;
case ROW_RESULT:
default:
DBUG_ASSERT(0);
}
collation.set(item->collation);
}
bool
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
{
@ -663,15 +633,12 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
switch (hybrid_type= item->result_type()) {
case INT_RESULT:
max_length= 20;
sum_int= 0;
break;
case DECIMAL_RESULT:
max_length= item->max_length;
my_decimal_set_zero(&sum_dec);
break;
case REAL_RESULT:
max_length= float_length(decimals);
sum= 0.0;
break;
case STRING_RESULT:
max_length= item->max_length;
@ -680,10 +647,10 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
default:
DBUG_ASSERT(0);
};
setup(args[0], NULL);
/* MIN/MAX can return NULL for empty set indepedent of the used column */
maybe_null= 1;
unsigned_flag=item->unsigned_flag;
collation.set(item->collation);
result_field=0;
null_value=1;
fix_length_and_dec();
@ -701,6 +668,30 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
return FALSE;
}
/**
MIN/MAX function setup.
@param item argument of MIN/MAX function
@param value_arg calculated value of MIN/MAX function
@details
Setup cache/comparator of MIN/MAX functions. When called by the
copy_or_same function value_arg parameter contains calculated value
of the original MIN/MAX object and it is saved in this object's cache.
*/
void Item_sum_hybrid::setup(Item *item, Item *value_arg)
{
value= Item_cache::get_cache(item);
value->setup(item);
value->store(value_arg);
cmp= new Arg_comparator();
cmp->set_cmp_func(this, args, (Item**)&value, FALSE);
collation.set(item->collation);
}
Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
uint convert_blob_length)
{
@ -1270,8 +1261,7 @@ Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table,
0, name, &my_charset_bin);
}
else if (hybrid_type == DECIMAL_RESULT)
field= new Field_new_decimal(max_length, maybe_null, name,
decimals, unsigned_flag);
field= Field_new_decimal::create_from_item(this);
else
field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
if (field)
@ -1592,19 +1582,7 @@ void Item_sum_variance::update_field()
void Item_sum_hybrid::clear()
{
switch (hybrid_type) {
case INT_RESULT:
sum_int= 0;
break;
case DECIMAL_RESULT:
my_decimal_set_zero(&sum_dec);
break;
case REAL_RESULT:
sum= 0.0;
break;
default:
value.length(0);
}
value->null_value= 1;
null_value= 1;
}
@ -1613,30 +1591,7 @@ double Item_sum_hybrid::val_real()
DBUG_ASSERT(fixed == 1);
if (null_value)
return 0.0;
switch (hybrid_type) {
case STRING_RESULT:
{
char *end_not_used;
int err_not_used;
String *res; res=val_str(&str_value);
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
&end_not_used, &err_not_used) : 0.0);
}
case INT_RESULT:
if (unsigned_flag)
return ulonglong2double(sum_int);
return (double) sum_int;
case DECIMAL_RESULT:
my_decimal2double(E_DEC_FATAL_ERROR, &sum_dec, &sum);
return sum;
case REAL_RESULT:
return sum;
case ROW_RESULT:
default:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
}
return value->val_real();
}
longlong Item_sum_hybrid::val_int()
@ -1644,18 +1599,7 @@ longlong Item_sum_hybrid::val_int()
DBUG_ASSERT(fixed == 1);
if (null_value)
return 0;
switch (hybrid_type) {
case INT_RESULT:
return sum_int;
case DECIMAL_RESULT:
{
longlong result;
my_decimal2int(E_DEC_FATAL_ERROR, &sum_dec, unsigned_flag, &result);
return sum_int;
}
default:
return (longlong) rint(Item_sum_hybrid::val_real());
}
return value->val_int();
}
@ -1664,26 +1608,7 @@ my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
DBUG_ASSERT(fixed == 1);
if (null_value)
return 0;
switch (hybrid_type) {
case STRING_RESULT:
string2my_decimal(E_DEC_FATAL_ERROR, &value, val);
break;
case REAL_RESULT:
double2my_decimal(E_DEC_FATAL_ERROR, sum, val);
break;
case DECIMAL_RESULT:
val= &sum_dec;
break;
case INT_RESULT:
int2my_decimal(E_DEC_FATAL_ERROR, sum_int, unsigned_flag, val);
break;
case ROW_RESULT:
default:
// This case should never be choosen
DBUG_ASSERT(0);
break;
}
return val; // Keep compiler happy
return value->val_decimal(val);
}
@ -1693,25 +1618,7 @@ Item_sum_hybrid::val_str(String *str)
DBUG_ASSERT(fixed == 1);
if (null_value)
return 0;
switch (hybrid_type) {
case STRING_RESULT:
return &value;
case REAL_RESULT:
str->set_real(sum,decimals, &my_charset_bin);
break;
case DECIMAL_RESULT:
my_decimal2string(E_DEC_FATAL_ERROR, &sum_dec, 0, 0, 0, str);
return str;
case INT_RESULT:
str->set_int(sum_int, unsigned_flag, &my_charset_bin);
break;
case ROW_RESULT:
default:
// This case should never be choosen
DBUG_ASSERT(0);
break;
}
return str; // Keep compiler happy
return value->val_str(str);
}
@ -1720,7 +1627,9 @@ void Item_sum_hybrid::cleanup()
DBUG_ENTER("Item_sum_hybrid::cleanup");
Item_sum::cleanup();
forced_const= FALSE;
if (cmp)
delete cmp;
cmp= 0;
/*
by default it is TRUE to avoid TRUE reporting by
Item_func_not_all/Item_func_nop_all if this item was never called.
@ -1741,63 +1650,22 @@ void Item_sum_hybrid::no_rows_in_result()
Item *Item_sum_min::copy_or_same(THD* thd)
{
return new (thd->mem_root) Item_sum_min(thd, this);
Item_sum_min *item= new (thd->mem_root) Item_sum_min(thd, this);
item->setup(args[0], value);
return item;
}
bool Item_sum_min::add()
{
switch (hybrid_type) {
case STRING_RESULT:
/* args[0] < value */
int res= cmp->compare();
if (!args[0]->null_value &&
(null_value || res < 0))
{
String *result=args[0]->val_str(&tmp_value);
if (!args[0]->null_value &&
(null_value || sortcmp(&value,result,collation.collation) > 0))
{
value.copy(*result);
null_value=0;
}
}
break;
case INT_RESULT:
{
longlong nr=args[0]->val_int();
if (!args[0]->null_value && (null_value ||
(unsigned_flag &&
(ulonglong) nr < (ulonglong) sum_int) ||
(!unsigned_flag && nr < sum_int)))
{
sum_int=nr;
null_value=0;
}
}
break;
case DECIMAL_RESULT:
{
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
if (!args[0]->null_value &&
(null_value || (my_decimal_cmp(&sum_dec, val) > 0)))
{
my_decimal2decimal(val, &sum_dec);
null_value= 0;
}
}
break;
case REAL_RESULT:
{
double nr= args[0]->val_real();
if (!args[0]->null_value && (null_value || nr < sum))
{
sum=nr;
null_value=0;
}
}
break;
case ROW_RESULT:
default:
// This case should never be choosen
DBUG_ASSERT(0);
break;
value->store(args[0]);
value->cache_value();
null_value= 0;
}
return 0;
}
@ -1805,63 +1673,22 @@ bool Item_sum_min::add()
Item *Item_sum_max::copy_or_same(THD* thd)
{
return new (thd->mem_root) Item_sum_max(thd, this);
Item_sum_max *item= new (thd->mem_root) Item_sum_max(thd, this);
item->setup(args[0], value);
return item;
}
bool Item_sum_max::add()
{
switch (hybrid_type) {
case STRING_RESULT:
/* args[0] > value */
int res= cmp->compare();
if (!args[0]->null_value &&
(null_value || res > 0))
{
String *result=args[0]->val_str(&tmp_value);
if (!args[0]->null_value &&
(null_value || sortcmp(&value,result,collation.collation) < 0))
{
value.copy(*result);
null_value=0;
}
}
break;
case INT_RESULT:
{
longlong nr=args[0]->val_int();
if (!args[0]->null_value && (null_value ||
(unsigned_flag &&
(ulonglong) nr > (ulonglong) sum_int) ||
(!unsigned_flag && nr > sum_int)))
{
sum_int=nr;
null_value=0;
}
}
break;
case DECIMAL_RESULT:
{
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
if (!args[0]->null_value &&
(null_value || (my_decimal_cmp(val, &sum_dec) > 0)))
{
my_decimal2decimal(val, &sum_dec);
null_value= 0;
}
}
break;
case REAL_RESULT:
{
double nr= args[0]->val_real();
if (!args[0]->null_value && (null_value || nr > sum))
{
sum=nr;
null_value=0;
}
}
break;
case ROW_RESULT:
default:
// This case should never be choosen
DBUG_ASSERT(0);
break;
value->store(args[0]);
value->cache_value();
null_value= 0;
}
return 0;
}
@ -2226,14 +2053,15 @@ void Item_sum_hybrid::update_field()
void
Item_sum_hybrid::min_max_update_str_field()
{
String *res_str=args[0]->val_str(&value);
DBUG_ASSERT(cmp);
String *res_str=args[0]->val_str(&cmp->value1);
if (!args[0]->null_value)
{
result_field->val_str(&tmp_value);
result_field->val_str(&cmp->value2);
if (result_field->is_null() ||
(cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
(cmp_sign * sortcmp(res_str,&cmp->value2,collation.collation)) < 0)
result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
result_field->set_notnull();
}

View file

@ -323,22 +323,6 @@ public:
virtual void update_field()=0;
virtual bool keep_field_type(void) const { return 0; }
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
/*
This method is used for debug purposes to print the name of an
item to the debug log. The second use of this method is as
a helper function of print(), where it is applicable.
To suit both goals it should return a meaningful,
distinguishable and sintactically correct string. This method
should not be used for runtime type identification, use enum
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
instead.
NOTE: for Items inherited from Item_sum, func_name() return part of
function name till first argument (including '(') to make difference in
names for functions with 'distinct' clause and without 'distinct' and
also to make printing of items inherited from Item_sum uniform.
*/
virtual const char *func_name() const= 0;
virtual Item *result_item(Field *field)
{ return new Item_field(field); }
table_map used_tables() const { return used_tables_cache; }
@ -664,6 +648,7 @@ public:
}
void fix_length_and_dec() {}
enum Item_result result_type () const { return hybrid_type; }
const char *func_name() const { DBUG_ASSERT(0); return "avg_field"; }
};
@ -732,6 +717,7 @@ public:
}
void fix_length_and_dec() {}
enum Item_result result_type () const { return hybrid_type; }
const char *func_name() const { DBUG_ASSERT(0); return "variance_field"; }
};
@ -807,6 +793,7 @@ public:
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
const char *func_name() const { DBUG_ASSERT(0); return "std_field"; }
};
/*
@ -832,14 +819,13 @@ class Item_sum_std :public Item_sum_variance
};
// This class is a string or number function depending on num_func
class Arg_comparator;
class Item_cache;
class Item_sum_hybrid :public Item_sum
{
protected:
String value,tmp_value;
double sum;
longlong sum_int;
my_decimal sum_dec;
Item_cache *value;
Arg_comparator *cmp;
Item_result hybrid_type;
enum_field_types hybrid_field_type;
int cmp_sign;
@ -847,12 +833,17 @@ protected:
public:
Item_sum_hybrid(Item *item_par,int sign)
:Item_sum(item_par), sum(0.0), sum_int(0),
:Item_sum(item_par), value(0), cmp(0),
hybrid_type(INT_RESULT), hybrid_field_type(MYSQL_TYPE_LONGLONG),
cmp_sign(sign), was_values(TRUE)
{ collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item);
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
:Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
was_values(item->was_values)
{ }
bool fix_fields(THD *, Item **);
void setup(Item *item, Item *value_arg);
void clear();
double val_real();
longlong val_int();

View file

@ -386,7 +386,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
if (tmp - val > 6)
tmp= (char*) val + 6;
l_time->second_part= (int) my_strtoll10(val, &tmp, &error);
frac_part= 6 - (uint) (tmp - val);
frac_part= 6 - (int) (tmp - val);
if (frac_part > 0)
l_time->second_part*= (ulong) log_10_int[frac_part];
val= tmp;
@ -876,9 +876,9 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
value= value*LL(10) + (longlong) (*str - '0');
if (transform_msec && i == count - 1) // microseconds always last
{
long msec_length= 6 - (uint) (str - start);
int msec_length= 6 - (int)(str - start);
if (msec_length > 0)
value*= (long) log_10_int[msec_length];
value*= (long)log_10_int[msec_length];
}
values[i]= value;
while (str != end && !my_isdigit(cs,*str))

View file

@ -5650,9 +5650,8 @@ int TC_LOG_BINLOG::recover(IO_CACHE *log, Format_description_log_event *fdle)
Xid_log_event *xev=(Xid_log_event *)ev;
uchar *x= (uchar *) memdup_root(&mem_root, (uchar*) &xev->xid,
sizeof(xev->xid));
if (! x)
if (!x || my_hash_insert(&xids, x))
goto err2;
my_hash_insert(&xids, x);
}
delete ev;
}

View file

@ -8450,13 +8450,17 @@ Rows_log_event::write_row(const Relay_log_info *const rli,
auto_afree_ptr<char> key(NULL);
/* fill table->record[0] with default values */
bool abort_on_warnings= (rli->sql_thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
if ((error= prepare_record(table, m_width,
TRUE /* check if columns have def. values */)))
table->file->ht->db_type != DB_TYPE_NDBCLUSTER,
abort_on_warnings, m_curr_row == m_rows_buf)))
DBUG_RETURN(error);
/* unpack row into table->record[0] */
error= unpack_current_row(rli); // TODO: how to handle errors?
if ((error= unpack_current_row(rli, abort_on_warnings)))
DBUG_RETURN(error);
if (m_curr_row == m_rows_buf)
{
/* this is the first row to be inserted, we estimate the rows with
@ -9253,8 +9257,12 @@ Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
store_record(m_table,record[1]);
bool abort_on_warnings= (rli->sql_thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
m_curr_row= m_curr_row_end;
error= unpack_current_row(rli); // this also updates m_curr_row_end
/* this also updates m_curr_row_end */
if ((error= unpack_current_row(rli, abort_on_warnings)))
return error;
/*
Now we have the right row to update. The old row (the one we're

View file

@ -3541,12 +3541,16 @@ protected:
int write_row(const Relay_log_info *const, const bool);
// Unpack the current row into m_table->record[0]
int unpack_current_row(const Relay_log_info *const rli)
int unpack_current_row(const Relay_log_info *const rli,
const bool abort_on_warning= TRUE)
{
DBUG_ASSERT(m_table);
bool first_row= (m_curr_row == m_rows_buf);
ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
&m_curr_row_end, &m_master_reclength);
&m_curr_row_end, &m_master_reclength,
abort_on_warning, first_row);
if (m_curr_row_end > m_rows_end)
my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);

View file

@ -5224,12 +5224,16 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
pthread_handler_t handle_connections_namedpipes(void *arg)
{
HANDLE hConnectedPipe;
OVERLAPPED connectOverlapped = {0};
OVERLAPPED connectOverlapped= {0};
THD *thd;
my_thread_init();
DBUG_ENTER("handle_connections_namedpipes");
connectOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
connectOverlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
if (!connectOverlapped.hEvent)
{
sql_print_error("Can't create event, last error=%u", GetLastError());
unireg_abort(1);
}
DBUG_PRINT("general",("Waiting for named pipe connections."));
while (!abort_loop)
{
@ -5252,7 +5256,8 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
{
CloseHandle(hPipe);
if ((hPipe= CreateNamedPipe(pipe_name,
PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_ACCESS_DUPLEX |
FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
@ -5272,7 +5277,8 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
hConnectedPipe = hPipe;
/* create new pipe for new connection */
if ((hPipe = CreateNamedPipe(pipe_name,
PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_ACCESS_DUPLEX |
FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,

View file

@ -6671,6 +6671,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
{ // Found tmp.max < key2.min
SEL_ARG *next=tmp->next;
/* key1 on the left of key2 non-overlapping */
if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
{
// Join near ranges like tmp.max < 0 and key2.min >= 0
@ -6699,6 +6700,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
int tmp_cmp;
if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
{
/* tmp is on the right of key2 non-overlapping */
if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
{ // ranges are connected
tmp->copy_min_to_min(key2);
@ -6733,25 +6735,52 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
}
}
// tmp.max >= key2.min && tmp.min <= key.max (overlapping ranges)
/*
tmp.min >= key2.min && tmp.min <= key.max (overlapping ranges)
key2.min <= tmp.min <= key2.max
*/
if (eq_tree(tmp->next_key_part,key2->next_key_part))
{
if (tmp->is_same(key2))
{
/*
Found exact match of key2 inside key1.
Use the relevant range in key1.
*/
tmp->merge_flags(key2); // Copy maybe flags
key2->increment_use_count(-1); // Free not used tree
}
else
{
SEL_ARG *last=tmp;
SEL_ARG *first=tmp;
/*
Find the last range in tmp that overlaps key2 and has the same
condition on the rest of the keyparts.
*/
while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
eq_tree(last->next->next_key_part,key2->next_key_part))
{
/*
We've found the last overlapping key1 range in last.
This means that the ranges between (and including) the
first overlapping range (tmp) and the last overlapping range
(last) are fully nested into the current range of key2
and can safely be discarded. We just need the minimum endpoint
of the first overlapping range (tmp) so we can compare it with
the minimum endpoint of the enclosing key2 range.
*/
SEL_ARG *save=last;
last=last->next;
key1=key1->tree_delete(save);
}
last->copy_min(tmp);
/*
The tmp range (the first overlapping range) could have been discarded
by the previous loop. We should re-direct tmp to the new united range
that's taking its place.
*/
tmp= last;
last->copy_min(first);
bool full_range= last->copy_min(key2);
if (!full_range)
{
@ -9822,7 +9851,11 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
}
else if (cur_arg->const_item())
{
DBUG_RETURN(TRUE);
/*
For predicates of the form "const OP expr" we also have to check 'expr'
to make a decision.
*/
continue;
}
else
DBUG_RETURN(FALSE);

View file

@ -559,7 +559,12 @@ HOSTS";
goto err;
}
si->server_id = log_server_id;
my_hash_insert(&slave_list, (uchar*)si);
if (my_hash_insert(&slave_list, (uchar*)si))
{
error= "the slave is out of memory";
pthread_mutex_unlock(&LOCK_slave_list);
goto err;
}
}
strmake(si->host, row[1], sizeof(si->host)-1);
si->port = atoi(row[port_ind]);

View file

@ -180,7 +180,8 @@ int
unpack_row(Relay_log_info const *rli,
TABLE *table, uint const colcnt,
uchar const *const row_data, MY_BITMAP const *cols,
uchar const **const row_end, ulong *const master_reclength)
uchar const **const row_end, ulong *const master_reclength,
const bool abort_on_warning, const bool first_row)
{
DBUG_ENTER("unpack_row");
DBUG_ASSERT(row_data);
@ -224,8 +225,35 @@ unpack_row(Relay_log_info const *rli,
/* Field...::unpack() cannot return 0 */
DBUG_ASSERT(pack_ptr != NULL);
if ((null_bits & null_mask) && f->maybe_null())
f->set_null();
if (null_bits & null_mask)
{
if (f->maybe_null())
{
DBUG_PRINT("debug", ("Was NULL; null mask: 0x%x; null bits: 0x%x",
null_mask, null_bits));
f->set_null();
}
else
{
MYSQL_ERROR::enum_warning_level error_type=
MYSQL_ERROR::WARN_LEVEL_NOTE;
if (abort_on_warning && (table->file->has_transactions() ||
first_row))
{
error = HA_ERR_ROWS_EVENT_APPLY;
error_type= MYSQL_ERROR::WARN_LEVEL_ERROR;
}
else
{
f->set_default();
error_type= MYSQL_ERROR::WARN_LEVEL_WARN;
}
push_warning_printf(current_thd, error_type,
ER_BAD_NULL_ERROR,
ER(ER_BAD_NULL_ERROR),
f->field_name);
}
}
else
{
f->set_notnull();
@ -305,13 +333,17 @@ unpack_row(Relay_log_info const *rli,
@param table Table whose record[0] buffer is prepared.
@param skip Number of columns for which default/nullable check
should be skipped.
@param check Indicates if errors should be raised when checking
default/nullable field properties.
@param check Specifies if lack of default error needs checking.
@param abort_on_warning
Controls how to react on lack of a field's default.
The parameter mimics the master side one for
@c check_that_all_fields_are_given_values.
@returns 0 on success or a handler level error code
*/
int prepare_record(TABLE *const table,
const uint skip, const bool check)
const uint skip, const bool check,
const bool abort_on_warning, const bool first_row)
{
DBUG_ENTER("prepare_record");
@ -326,17 +358,37 @@ int prepare_record(TABLE *const table,
if (skip >= table->s->fields || !check)
DBUG_RETURN(0);
/* Checking if exists default/nullable fields in the default values. */
for (Field **field_ptr= table->field+skip ; *field_ptr ; ++field_ptr)
/*
For fields the extra fields on the slave, we check if they have a default.
The check follows the same rules as the INSERT query without specifying an
explicit value for a field not having the explicit default
(@c check_that_all_fields_are_given_values()).
*/
for (Field **field_ptr= table->field+skip; *field_ptr; ++field_ptr)
{
uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
Field *const f= *field_ptr;
if (((f->flags & mask) == mask))
if ((f->flags & NO_DEFAULT_VALUE_FLAG) &&
(f->real_type() != MYSQL_TYPE_ENUM))
{
my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name);
error = HA_ERR_ROWS_EVENT_APPLY;
MYSQL_ERROR::enum_warning_level error_type=
MYSQL_ERROR::WARN_LEVEL_NOTE;
if (abort_on_warning && (table->file->has_transactions() ||
first_row))
{
error= HA_ERR_ROWS_EVENT_APPLY;
error_type= MYSQL_ERROR::WARN_LEVEL_ERROR;
}
else
{
f->set_default();
error_type= MYSQL_ERROR::WARN_LEVEL_WARN;
}
push_warning_printf(current_thd, error_type,
ER_NO_DEFAULT_FOR_FIELD,
ER(ER_NO_DEFAULT_FOR_FIELD),
f->field_name);
}
}

View file

@ -27,10 +27,13 @@ size_t pack_row(TABLE* table, MY_BITMAP const* cols,
int unpack_row(Relay_log_info const *rli,
TABLE *table, uint const colcnt,
uchar const *const row_data, MY_BITMAP const *cols,
uchar const **const row_end, ulong *const master_reclength);
uchar const **const row_end, ulong *const master_reclength,
const bool abort_on_warning= TRUE, const bool first_row= TRUE);
// Fill table's record[0] with default values.
int prepare_record(TABLE *const, const uint =0, const bool =FALSE);
int prepare_record(TABLE *const table, const uint skip, const bool check,
const bool abort_on_warning= TRUE,
const bool first_row= TRUE);
#endif
#endif

View file

@ -119,7 +119,13 @@ int table_mapping::set_table(ulong table_id, TABLE* table)
}
e->table_id= table_id;
e->table= table;
my_hash_insert(&m_table_ids,(uchar *)e);
if (my_hash_insert(&m_table_ids,(uchar *)e))
{
/* we add this entry to the chain of free (free for use) entries */
e->next= m_free;
m_free= e;
DBUG_RETURN(ERR_MEMORY_ALLOCATION);
}
DBUG_PRINT("info", ("tid %lu -> table 0x%lx (%s)",
table_id, (long) e->table,

209
sql/sp.cc
View file

@ -70,6 +70,122 @@ enum
MYSQL_PROC_FIELD_COUNT
};
static const
TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] =
{
{
{ C_STRING_WITH_LEN("db") },
{ C_STRING_WITH_LEN("char(64)") },
{ C_STRING_WITH_LEN("utf8") }
},
{
{ C_STRING_WITH_LEN("name") },
{ C_STRING_WITH_LEN("char(64)") },
{ C_STRING_WITH_LEN("utf8") }
},
{
{ C_STRING_WITH_LEN("type") },
{ C_STRING_WITH_LEN("enum('FUNCTION','PROCEDURE')") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("specific_name") },
{ C_STRING_WITH_LEN("char(64)") },
{ C_STRING_WITH_LEN("utf8") }
},
{
{ C_STRING_WITH_LEN("language") },
{ C_STRING_WITH_LEN("enum('SQL')") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("sql_data_access") },
{ C_STRING_WITH_LEN("enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("is_deterministic") },
{ C_STRING_WITH_LEN("enum('YES','NO')") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("security_type") },
{ C_STRING_WITH_LEN("enum('INVOKER','DEFINER')") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("param_list") },
{ C_STRING_WITH_LEN("blob") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("returns") },
{ C_STRING_WITH_LEN("longblob") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("body") },
{ C_STRING_WITH_LEN("longblob") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("definer") },
{ C_STRING_WITH_LEN("char(77)") },
{ C_STRING_WITH_LEN("utf8") }
},
{
{ C_STRING_WITH_LEN("created") },
{ C_STRING_WITH_LEN("timestamp") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("modified") },
{ C_STRING_WITH_LEN("timestamp") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("sql_mode") },
{ C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
"'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
"'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
"'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES',"
"'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER',"
"'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')") },
{ NULL, 0 }
},
{
{ C_STRING_WITH_LEN("comment") },
{ C_STRING_WITH_LEN("char(64)") },
{ C_STRING_WITH_LEN("utf8") }
},
{
{ C_STRING_WITH_LEN("character_set_client") },
{ C_STRING_WITH_LEN("char(32)") },
{ C_STRING_WITH_LEN("utf8") }
},
{
{ C_STRING_WITH_LEN("collation_connection") },
{ C_STRING_WITH_LEN("char(32)") },
{ C_STRING_WITH_LEN("utf8") }
},
{
{ C_STRING_WITH_LEN("db_collation") },
{ C_STRING_WITH_LEN("char(32)") },
{ C_STRING_WITH_LEN("utf8") }
},
{
{ C_STRING_WITH_LEN("body_utf8") },
{ C_STRING_WITH_LEN("longblob") },
{ NULL, 0 }
}
};
static const TABLE_FIELD_DEF
proc_table_def= {MYSQL_PROC_FIELD_COUNT, proc_table_fields};
/*************************************************************************/
/**
@ -247,6 +363,50 @@ Stored_routine_creation_ctx::load_from_db(THD *thd,
/*************************************************************************/
class Proc_table_intact : public Table_check_intact
{
private:
bool m_print_once;
public:
Proc_table_intact() : m_print_once(TRUE) {}
protected:
void report_error(uint code, const char *fmt, ...);
};
/**
Report failure to validate the mysql.proc table definition.
Print a message to the error log only once.
*/
void Proc_table_intact::report_error(uint code, const char *fmt, ...)
{
va_list args;
char buf[512];
va_start(args, fmt);
my_vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
if (code)
my_message(code, buf, MYF(0));
else
my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "proc");
if (m_print_once)
{
m_print_once= FALSE;
sql_print_error("%s", buf);
}
};
/** Single instance used to control printing to the error log. */
static Proc_table_intact proc_table_intact;
/**
Open the mysql.proc table for read.
@ -266,15 +426,17 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
DBUG_ENTER("open_proc_table_for_read");
TABLE_LIST table;
bzero((char*) &table, sizeof(table));
table.db= (char*) "mysql";
table.table_name= table.alias= (char*)"proc";
table.lock_type= TL_READ;
table.init_one_table("mysql", "proc", TL_READ);
if (!open_system_tables_for_read(thd, &table, backup))
if (open_system_tables_for_read(thd, &table, backup))
DBUG_RETURN(NULL);
if (!proc_table_intact.check(table.table, &proc_table_def))
DBUG_RETURN(table.table);
else
DBUG_RETURN(0);
close_system_tables(thd, backup);
DBUG_RETURN(NULL);
}
@ -296,13 +458,19 @@ static TABLE *open_proc_table_for_update(THD *thd)
{
DBUG_ENTER("open_proc_table_for_update");
TABLE_LIST table;
bzero((char*) &table, sizeof(table));
table.db= (char*) "mysql";
table.table_name= table.alias= (char*)"proc";
table.lock_type= TL_WRITE;
TABLE *table;
TABLE_LIST table_list;
table_list.init_one_table("mysql", "proc", TL_WRITE);
DBUG_RETURN(open_system_table_for_update(thd, &table));
if (!(table= open_system_table_for_update(thd, &table_list)))
DBUG_RETURN(NULL);
if (!proc_table_intact.check(table, &proc_table_def))
DBUG_RETURN(table);
close_thread_tables(thd);
DBUG_RETURN(NULL);
}
@ -1506,7 +1674,8 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
rn->key.length= key->length;
rn->key.str= (char *)rn + sizeof(Sroutine_hash_entry);
memcpy(rn->key.str, key->str, key->length + 1);
my_hash_insert(&lex->sroutines, (uchar *)rn);
if (my_hash_insert(&lex->sroutines, (uchar *)rn))
return FALSE;
lex->sroutines_list.link_in_list((uchar *)rn, (uchar **)&rn->next);
rn->belong_to_view= belong_to_view;
return TRUE;
@ -1584,16 +1753,24 @@ void sp_remove_not_own_routines(LEX *lex)
dependant on time of life of elements from source hash. It also
won't touch lists linking elements in source and destination
hashes.
@returns
@return TRUE Failure
@return FALSE Success
*/
void sp_update_sp_used_routines(HASH *dst, HASH *src)
bool sp_update_sp_used_routines(HASH *dst, HASH *src)
{
for (uint i=0 ; i < src->records ; i++)
{
Sroutine_hash_entry *rt= (Sroutine_hash_entry *)hash_element(src, i);
if (!hash_search(dst, (uchar *)rt->key.str, rt->key.length))
my_hash_insert(dst, (uchar *)rt);
{
if (my_hash_insert(dst, (uchar *)rt))
return TRUE;
}
}
return FALSE;
}

View file

@ -69,7 +69,7 @@ void sp_get_prelocking_info(THD *thd, bool *need_prelocking,
void sp_add_used_routine(LEX *lex, Query_arena *arena,
sp_name *rt, char rt_type);
void sp_remove_not_own_routines(LEX *lex);
void sp_update_sp_used_routines(HASH *dst, HASH *src);
bool sp_update_sp_used_routines(HASH *dst, HASH *src);
int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
bool first_no_prelock);
int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,

View file

@ -36,10 +36,16 @@ public:
sp_cache();
~sp_cache();
inline void insert(sp_head *sp)
/**
Inserts a sp_head object into a hash table.
@returns Success status
@return TRUE Failure
@return FALSE Success
*/
inline bool insert(sp_head *sp)
{
/* TODO: why don't we check return value? */
my_hash_insert(&m_hashtable, (const uchar *)sp);
return my_hash_insert(&m_hashtable, (const uchar *)sp);
}
inline sp_head *lookup(char *name, uint namelen)

View file

@ -2090,8 +2090,18 @@ sp_head::reset_lex(THD *thd)
DBUG_RETURN(FALSE);
}
/// Restore lex during parsing, after we have parsed a sub statement.
void
/**
Restore lex during parsing, after we have parsed a sub statement.
@param thd Thread handle
@return
@retval TRUE failure
@retval FALSE success
*/
bool
sp_head::restore_lex(THD *thd)
{
DBUG_ENTER("sp_head::restore_lex");
@ -2102,7 +2112,7 @@ sp_head::restore_lex(THD *thd)
oldlex= (LEX *)m_lex.pop();
if (! oldlex)
return; // Nothing to restore
DBUG_RETURN(FALSE); // Nothing to restore
oldlex->trg_table_fields.push_back(&sublex->trg_table_fields);
@ -2118,7 +2128,8 @@ sp_head::restore_lex(THD *thd)
Add routines which are used by statement to respective set for
this routine.
*/
sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines);
if (sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines))
DBUG_RETURN(TRUE);
/*
Merge tables used by this statement (but not by its functions or
procedures) to multiset of tables used by this routine.
@ -2130,7 +2141,7 @@ sp_head::restore_lex(THD *thd)
delete sublex;
}
thd->lex= oldlex;
DBUG_VOID_RETURN;
DBUG_RETURN(FALSE);
}
/**
@ -3868,7 +3879,8 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
tab->lock_type= table->lock_type;
tab->lock_count= tab->query_lock_count= 1;
tab->trg_event_map= table->trg_event_map;
my_hash_insert(&m_sptabs, (uchar *)tab);
if (my_hash_insert(&m_sptabs, (uchar *)tab))
return FALSE;
}
}
return TRUE;

View file

@ -340,7 +340,7 @@ public:
@todo Conflicting comment in sp_head.cc
*/
void
bool
restore_lex(THD *thd);
/// Put the instruction on the backpatch list, associated with the label.

View file

@ -31,9 +31,8 @@
#include "sp_head.h"
#include "sp.h"
time_t mysql_db_table_last_check= 0L;
TABLE_FIELD_W_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = {
static const
TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = {
{
{ C_STRING_WITH_LEN("Host") },
{ C_STRING_WITH_LEN("char(60)") },
@ -146,6 +145,8 @@ TABLE_FIELD_W_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = {
}
};
const TABLE_FIELD_DEF
mysql_db_table_def= {MYSQL_DB_FIELD_COUNT, mysql_db_table_fields};
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@ -2404,7 +2405,12 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
privs = cols = 0; /* purecov: deadcode */
return; /* purecov: deadcode */
}
my_hash_insert(&hash_columns, (uchar *) mem_check);
if (my_hash_insert(&hash_columns, (uchar *) mem_check))
{
/* Invalidate this entry */
privs= cols= 0;
return;
}
} while (!col_privs->file->index_next(col_privs->record[0]) &&
!key_cmp_if_same(col_privs,key,0,key_prefix_len));
col_privs->file->ha_index_end();
@ -2609,7 +2615,11 @@ static int replace_column_table(GRANT_TABLE *g_t,
goto end; /* purecov: inspected */
}
grant_column= new GRANT_COLUMN(column->column,privileges);
my_hash_insert(&g_t->hash_columns,(uchar*) grant_column);
if (my_hash_insert(&g_t->hash_columns,(uchar*) grant_column))
{
result= -1;
goto end;
}
}
}
@ -3134,12 +3144,12 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
Str->user.str, table_name,
rights,
column_priv);
if (!grant_table) // end of memory
if (!grant_table ||
my_hash_insert(&column_priv_hash,(uchar*) grant_table))
{
result= TRUE; /* purecov: deadcode */
continue; /* purecov: deadcode */
}
my_hash_insert(&column_priv_hash,(uchar*) grant_table);
}
/* If revoke_grant, calculate the new column privilege for tables_priv */
@ -3343,12 +3353,13 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
grant_name= new GRANT_NAME(Str->host.str, db_name,
Str->user.str, table_name,
rights, TRUE);
if (!grant_name)
if (!grant_name ||
my_hash_insert(is_proc ?
&proc_priv_hash : &func_priv_hash,(uchar*) grant_name))
{
result= TRUE;
continue;
}
my_hash_insert(is_proc ? &proc_priv_hash : &func_priv_hash,(uchar*) grant_name);
}
if (replace_routine_table(thd, grant_name, tables[1].table, *Str,
@ -3451,6 +3462,13 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
result= TRUE;
continue;
}
/*
No User, but a password?
They did GRANT ... TO CURRENT_USER() IDENTIFIED BY ... !
Get the current user, and shallow-copy the new password to them!
*/
if (!tmp_Str->user.str && tmp_Str->password.str)
Str->password= tmp_Str->password;
if (replace_user_table(thd, tables[0].table, *Str,
(!db ? rights : 0), revoke_grant, create_new_users,
test(thd->variables.sql_mode &

View file

@ -159,8 +159,7 @@ enum mysql_db_table_field
MYSQL_DB_FIELD_COUNT
};
extern TABLE_FIELD_W_TYPE mysql_db_table_fields[];
extern time_t mysql_db_table_last_check;
extern const TABLE_FIELD_DEF mysql_db_table_def;
/* Classes */

View file

@ -2935,7 +2935,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
DBUG_PRINT("info", ("inserting table '%s'.'%s' 0x%lx into the cache",
table->s->db.str, table->s->table_name.str,
(long) table));
VOID(my_hash_insert(&open_cache,(uchar*) table));
if (my_hash_insert(&open_cache,(uchar*) table))
{
my_free(table, MYF(0));
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(NULL);
}
}
check_unused(); // Debugging call

View file

@ -421,12 +421,16 @@ TYPELIB query_cache_type_typelib=
effect by another thread. This enables a quick path in execution to skip waits
when the outcome is known.
@param use_timeout TRUE if the lock can abort because of a timeout.
@note use_timeout is optional and default value is FALSE.
@return
@retval FALSE An exclusive lock was taken
@retval TRUE The locking attempt failed
*/
bool Query_cache::try_lock(void)
bool Query_cache::try_lock(bool use_timeout)
{
bool interrupt= FALSE;
DBUG_ENTER("Query_cache::try_lock");
@ -456,7 +460,26 @@ bool Query_cache::try_lock(void)
else
{
DBUG_ASSERT(m_cache_lock_status == Query_cache::LOCKED);
pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
/*
To prevent send_result_to_client() and query_cache_insert() from
blocking execution for too long a timeout is put on the lock.
*/
if (use_timeout)
{
struct timespec waittime;
set_timespec_nsec(waittime,(ulong)(50000000L)); /* Wait for 50 msec */
int res= pthread_cond_timedwait(&COND_cache_status_changed,
&structure_guard_mutex,&waittime);
if (res == ETIMEDOUT)
{
interrupt= TRUE;
break;
}
}
else
{
pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
}
}
}
pthread_mutex_unlock(&structure_guard_mutex);
@ -1190,8 +1213,14 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
A table- or a full flush operation can potentially take a long time to
finish. We choose not to wait for them and skip caching statements
instead.
In case the wait time can't be determined there is an upper limit which
causes try_lock() to abort with a time out.
The 'TRUE' parameter indicate that the lock is allowed to timeout
*/
if (try_lock())
if (try_lock(TRUE))
DBUG_VOID_RETURN;
if (query_cache_size == 0)
{
@ -1385,8 +1414,10 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Try to obtain an exclusive lock on the query cache. If the cache is
disabled or if a full cache flush is in progress, the attempt to
get the lock is aborted.
The 'TRUE' parameter indicate that the lock is allowed to timeout
*/
if (try_lock())
if (try_lock(TRUE))
goto err;
if (query_cache_size == 0)

View file

@ -485,7 +485,7 @@ protected:
const char *name);
my_bool in_blocks(Query_cache_block * point);
bool try_lock(void);
bool try_lock(bool use_timeout= FALSE);
void lock(void);
void lock_and_suspend(void);
void unlock(void);

View file

@ -426,7 +426,8 @@ cleanup:
}
DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
free_underlaid_joins(thd, select_lex);
if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
if (error < 0 ||
(thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error))
{
/*
If a TRUNCATE TABLE was issued, the number of rows should be reported as
@ -1089,6 +1090,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
TABLE *table;
bool error;
uint path_length;
bool is_temporary_table= false;
DBUG_ENTER("mysql_truncate");
bzero((char*) &create_info,sizeof(create_info));
@ -1099,6 +1101,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
/* If it is a temporary table, close and regenerate it */
if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
{
is_temporary_table= true;
handlerton *table_type= table->s->db_type();
TABLE_SHARE *share= table->s;
if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
@ -1162,11 +1165,9 @@ end:
{
if (!error)
{
/*
TRUNCATE must always be statement-based binlogged (not row-based) so
we don't test current_stmt_binlog_row_based.
*/
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
/* In RBR, the statement is not binlogged if the table is temporary. */
if (!is_temporary_table || !thd->current_stmt_binlog_row_based)
write_bin_log(thd, TRUE, thd->query(), thd->query_length());
my_ok(thd); // This should return record count
}
VOID(pthread_mutex_lock(&LOCK_open));

View file

@ -500,6 +500,22 @@ bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list)
DBUG_ENTER("open_and_lock_for_insert_delayed");
#ifndef EMBEDDED_LIBRARY
if (thd->locked_tables && thd->global_read_lock)
{
/*
If this connection has the global read lock, the handler thread
will not be able to lock the table. It will wait for the global
read lock to go away, but this will never happen since the
connection thread will be stuck waiting for the handler thread
to open and lock the table.
If we are not in locked tables mode, INSERT will seek protection
against the global read lock (and fail), thus we will only get
to this point in locked tables mode.
*/
my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0));
DBUG_RETURN(TRUE);
}
if (delayed_get_table(thd, table_list))
DBUG_RETURN(TRUE);

Some files were not shown because too many files have changed in this diff Show more