mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
Automerge.
This commit is contained in:
commit
40767bf54a
110 changed files with 3524 additions and 1047 deletions
|
@ -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 : "";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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])])
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -50,7 +50,6 @@ EXPORTS
|
|||
mysql_next_result
|
||||
mysql_num_fields
|
||||
mysql_num_rows
|
||||
mysql_odbc_escape_string
|
||||
mysql_options
|
||||
mysql_ping
|
||||
mysql_query
|
||||
|
|
|
@ -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;
|
||||
|
|
364
mysql-test/extra/rpl_tests/rpl_not_null.test
Normal file
364
mysql-test/extra/rpl_tests/rpl_not_null.test
Normal 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;
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
26
mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result
Normal file
26
mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result
Normal 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;
|
202
mysql-test/suite/rpl/r/rpl_not_null_innodb.result
Normal file
202
mysql-test/suite/rpl/r/rpl_not_null_innodb.result
Normal 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;
|
202
mysql-test/suite/rpl/r/rpl_not_null_myisam.result
Normal file
202
mysql-test/suite/rpl/r/rpl_not_null_myisam.result
Normal 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;
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
29
mysql-test/suite/rpl/r/rpl_row_trunc_temp.result
Normal file
29
mysql-test/suite/rpl/r/rpl_row_trunc_temp.result
Normal 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;
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
53
mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test
Normal file
53
mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test
Normal 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;
|
19
mysql-test/suite/rpl/t/rpl_not_null_innodb.test
Normal file
19
mysql-test/suite/rpl/t/rpl_not_null_innodb.test
Normal 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
|
18
mysql-test/suite/rpl/t/rpl_not_null_myisam.test
Normal file
18
mysql-test/suite/rpl/t/rpl_not_null_myisam.test
Normal 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
|
35
mysql-test/suite/rpl/t/rpl_row_trunc_temp.test
Normal file
35
mysql-test/suite/rpl/t/rpl_row_trunc_temp.test
Normal 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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
44
sql/field.cc
44
sql/field.cc
|
@ -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);
|
||||
|
|
|
@ -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 *);
|
||||
};
|
||||
|
||||
|
||||
|
|
110
sql/item.cc
110
sql/item.cc
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
29
sql/item.h
29
sql/item.h
|
@ -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();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
290
sql/item_sum.cc
290
sql/item_sum.cc
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
209
sql/sp.cc
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
2
sql/sp.h
2
sql/sp.h
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 &
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue