mirror of
https://github.com/MariaDB/server.git
synced 2026-05-01 20:55:32 +02:00
Merge mysql.com:/users/lthalmann/bkroot/mysql-5.0-rpl
into mysql.com:/users/lthalmann/bk/MERGE/mysql-5.0-merge
This commit is contained in:
commit
2fc416fe22
73 changed files with 2395 additions and 936 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -3699,6 +3699,37 @@ os_aio_posix_handle(
|
|||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
Do a 'last millisecond' check that the page end is sensible;
|
||||
reported page checksum errors from Linux seem to wipe over the page end. */
|
||||
static
|
||||
void
|
||||
os_file_check_page_trailers(
|
||||
/*========================*/
|
||||
byte* combined_buf, /* in: combined write buffer */
|
||||
ulint total_len) /* in: size of combined_buf, in bytes
|
||||
(a multiple of UNIV_PAGE_SIZE) */
|
||||
{
|
||||
ulint len;
|
||||
|
||||
for (len = 0; len + UNIV_PAGE_SIZE <= total_len;
|
||||
len += UNIV_PAGE_SIZE) {
|
||||
byte* buf = combined_buf + len;
|
||||
|
||||
if (memcmp(buf + (FIL_PAGE_LSN + 4), buf + (UNIV_PAGE_SIZE
|
||||
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4), 4)) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: ERROR: The page to be written seems corrupt!\n"
|
||||
"InnoDB: Writing a block of %lu bytes, currently at offset %lu\n",
|
||||
(ulong)total_len, (ulong)len);
|
||||
buf_page_print(buf);
|
||||
fprintf(stderr,
|
||||
"InnoDB: ERROR: The page to be written seems corrupt!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Does simulated aio. This function should be called by an i/o-handler
|
||||
thread. */
|
||||
|
|
@ -3736,7 +3767,6 @@ os_aio_simulated_handle(
|
|||
ibool ret;
|
||||
ulint n;
|
||||
ulint i;
|
||||
ulint len2;
|
||||
|
||||
segment = os_aio_get_array_and_local_segment(&array, global_segment);
|
||||
|
||||
|
|
@ -3943,33 +3973,16 @@ consecutive_loop:
|
|||
(ulong) total_len);
|
||||
ut_error;
|
||||
}
|
||||
|
||||
/* Do a 'last millisecond' check that the page end
|
||||
is sensible; reported page checksum errors from
|
||||
Linux seem to wipe over the page end */
|
||||
|
||||
for (len2 = 0; len2 + UNIV_PAGE_SIZE <= total_len;
|
||||
len2 += UNIV_PAGE_SIZE) {
|
||||
if (mach_read_from_4(combined_buf + len2
|
||||
+ FIL_PAGE_LSN + 4)
|
||||
!= mach_read_from_4(combined_buf + len2
|
||||
+ UNIV_PAGE_SIZE
|
||||
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: ERROR: The page to be written seems corrupt!\n");
|
||||
fprintf(stderr,
|
||||
"InnoDB: Writing a block of %lu bytes, currently writing at offset %lu\n",
|
||||
(ulong)total_len, (ulong)len2);
|
||||
buf_page_print(combined_buf + len2);
|
||||
fprintf(stderr,
|
||||
"InnoDB: ERROR: The page to be written seems corrupt!\n");
|
||||
}
|
||||
}
|
||||
os_file_check_page_trailers(combined_buf, total_len);
|
||||
}
|
||||
|
||||
|
||||
ret = os_file_write(slot->name, slot->file, combined_buf,
|
||||
slot->offset, slot->offset_high, total_len);
|
||||
|
||||
if (array == os_aio_write_array) {
|
||||
os_file_check_page_trailers(combined_buf, total_len);
|
||||
}
|
||||
} else {
|
||||
ret = os_file_read(slot->file, combined_buf,
|
||||
slot->offset, slot->offset_high, total_len);
|
||||
|
|
|
|||
|
|
@ -2570,14 +2570,14 @@ do not allow the discard. We also reserve the data dictionary latch. */
|
|||
}
|
||||
}
|
||||
funct_exit:
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
if (graph) {
|
||||
que_graph_free(graph);
|
||||
}
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
trx->op_info = "";
|
||||
|
||||
return((int) err);
|
||||
|
|
@ -2707,10 +2707,10 @@ row_import_tablespace_for_mysql(
|
|||
}
|
||||
|
||||
funct_exit:
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx->op_info = "";
|
||||
|
||||
return((int) err);
|
||||
|
|
@ -3398,6 +3398,8 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
|||
}
|
||||
funct_exit:
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
if (locked_dictionary) {
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
}
|
||||
|
|
@ -3408,8 +3410,6 @@ funct_exit:
|
|||
|
||||
que_graph_free(graph);
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
trx->op_info = "";
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
|
|
@ -3488,10 +3488,10 @@ loop:
|
|||
}
|
||||
}
|
||||
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx->op_info = "";
|
||||
|
||||
return(err);
|
||||
|
|
@ -3905,6 +3905,8 @@ row_rename_table_for_mysql(
|
|||
}
|
||||
}
|
||||
funct_exit:
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
if (!recovering_temp_table) {
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
}
|
||||
|
|
@ -3917,8 +3919,6 @@ funct_exit:
|
|||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
trx->op_info = "";
|
||||
|
||||
return((int) err);
|
||||
|
|
|
|||
|
|
@ -1064,11 +1064,12 @@ row_sel_try_search_shortcut(
|
|||
ut_ad(plan->pcur.latch_mode == node->latch_mode);
|
||||
|
||||
plan->n_rows_fetched++;
|
||||
ret = SEL_FOUND;
|
||||
func_exit:
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(SEL_FOUND);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ sub mtr_record_dead_children ();
|
|||
sub mtr_exit ($);
|
||||
sub sleep_until_file_created ($$$);
|
||||
sub mtr_kill_processes ($);
|
||||
sub mtr_kill_process ($$$$);
|
||||
|
||||
# static in C
|
||||
sub spawn_impl ($$$$$$$$);
|
||||
|
|
@ -885,6 +886,25 @@ sub mtr_kill_processes ($) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
sub mtr_kill_process ($$$$) {
|
||||
my $pid= shift;
|
||||
my $signal= shift;
|
||||
my $retries= shift;
|
||||
my $timeout= shift;
|
||||
|
||||
while (1)
|
||||
{
|
||||
kill($signal, $pid);
|
||||
|
||||
last unless kill (0, $pid) and $retries--;
|
||||
|
||||
mtr_debug("Sleep $timeout second waiting for processes to die");
|
||||
|
||||
sleep($timeout);
|
||||
}
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# When we exit, we kill off all children
|
||||
|
|
|
|||
|
|
@ -918,6 +918,7 @@ sub command_line_setup () {
|
|||
path_err => "$opt_vardir/log/im.err",
|
||||
path_log => "$opt_vardir/log/im.log",
|
||||
path_pid => "$opt_vardir/run/im.pid",
|
||||
path_angel_pid => "$opt_vardir/run/im.angel.pid",
|
||||
path_sock => "$sockdir/im.sock",
|
||||
port => $im_port,
|
||||
start_timeout => $master->[0]->{'start_timeout'},
|
||||
|
|
@ -1188,6 +1189,7 @@ sub environment_setup () {
|
|||
$ENV{'NDB_STATUS_OK'}= "YES";
|
||||
|
||||
$ENV{'IM_PATH_PID'}= $instance_manager->{path_pid};
|
||||
$ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid};
|
||||
$ENV{'IM_PORT'}= $instance_manager->{port};
|
||||
|
||||
$ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock};
|
||||
|
|
@ -1813,6 +1815,7 @@ sub im_create_defaults_file($) {
|
|||
|
||||
[manager]
|
||||
pid-file = $instance_manager->{path_pid}
|
||||
angel-pid-file = $instance_manager->{path_angel_pid}
|
||||
socket = $instance_manager->{path_sock}
|
||||
port = $instance_manager->{port}
|
||||
password-file = $instance_manager->{password_file}
|
||||
|
|
@ -1837,7 +1840,7 @@ log-slow-queries = $instance->{path_datadir}/mysqld$server_id.slow.log
|
|||
language = $path_language
|
||||
character-sets-dir = $path_charsetsdir
|
||||
basedir = $path_my_basedir
|
||||
server_id =$server_id
|
||||
server_id = $server_id
|
||||
skip-stack-trace
|
||||
skip-innodb
|
||||
skip-bdb
|
||||
|
|
@ -2805,6 +2808,18 @@ sub im_start($$) {
|
|||
sub im_stop($) {
|
||||
my $instance_manager = shift;
|
||||
|
||||
# Obtain mysqld-process pids before we start stopping IM (it can delete pid
|
||||
# files).
|
||||
|
||||
my @mysqld_pids = ();
|
||||
my $instances = $instance_manager->{'instances'};
|
||||
|
||||
push(@mysqld_pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'}))
|
||||
if -r $instances->[0]->{'path_pid'};
|
||||
|
||||
push(@mysqld_pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'}))
|
||||
if -r $instances->[1]->{'path_pid'};
|
||||
|
||||
# Re-read pid from the file, since during tests Instance Manager could have
|
||||
# been restarted, so its pid could have been changed.
|
||||
|
||||
|
|
@ -2812,34 +2827,79 @@ sub im_stop($) {
|
|||
mtr_get_pid_from_file($instance_manager->{'path_pid'})
|
||||
if -f $instance_manager->{'path_pid'};
|
||||
|
||||
if (-f $instance_manager->{'path_angel_pid'})
|
||||
{
|
||||
$instance_manager->{'angel_pid'} =
|
||||
mtr_get_pid_from_file($instance_manager->{'path_angel_pid'})
|
||||
}
|
||||
else
|
||||
{
|
||||
$instance_manager->{'angel_pid'} = undef;
|
||||
}
|
||||
|
||||
# Inspired from mtr_stop_mysqld_servers().
|
||||
|
||||
start_reap_all();
|
||||
|
||||
# Create list of pids. We should stop Instance Manager and all started
|
||||
# mysqld-instances. Some of them may be nonguarded, so IM will not stop them
|
||||
# on shutdown.
|
||||
# Try graceful shutdown.
|
||||
|
||||
my @pids = ( $instance_manager->{'pid'} );
|
||||
my $instances = $instance_manager->{'instances'};
|
||||
mtr_kill_process($instance_manager->{'pid'}, 'TERM', 10, 1);
|
||||
|
||||
if ( -r $instances->[0]->{'path_pid'} )
|
||||
# Check that all processes died.
|
||||
|
||||
my $clean_shutdown= 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
push(@pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'}));
|
||||
last if kill (0, $instance_manager->{'pid'});
|
||||
|
||||
last if (defined $instance_manager->{'angel_pid'}) &&
|
||||
kill (0, $instance_manager->{'angel_pid'});
|
||||
|
||||
foreach my $pid (@mysqld_pids)
|
||||
{
|
||||
last if kill (0, $pid);
|
||||
}
|
||||
|
||||
$clean_shutdown= 1;
|
||||
last;
|
||||
}
|
||||
|
||||
if ( -r $instances->[1]->{'path_pid'} )
|
||||
# Kill leftovers (the order is important).
|
||||
|
||||
unless ($clean_shutdown)
|
||||
{
|
||||
push(@pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'}));
|
||||
mtr_kill_process($instance_manager->{'angel_pid'}, 'KILL', 10, 1)
|
||||
if defined $instance_manager->{'angel_pid'};
|
||||
|
||||
mtr_kill_process($instance_manager->{'pid'}, 'KILL', 10, 1);
|
||||
|
||||
# Shutdown managed mysqld-processes. Some of them may be nonguarded, so IM
|
||||
# will not stop them on shutdown. So, we should firstly try to end them
|
||||
# legally.
|
||||
|
||||
mtr_kill_processes(\@mysqld_pids);
|
||||
|
||||
# Complain in error log so that a warning will be shown.
|
||||
|
||||
my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
|
||||
|
||||
open (ERRLOG, ">>$errlog") ||
|
||||
mtr_error("Can not open error log ($errlog)");
|
||||
|
||||
my $ts= localtime();
|
||||
print ERRLOG
|
||||
"Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
|
||||
|
||||
close ERRLOG;
|
||||
}
|
||||
|
||||
# Kill processes.
|
||||
|
||||
mtr_kill_processes(\@pids);
|
||||
# That's all.
|
||||
|
||||
stop_reap_all();
|
||||
|
||||
$instance_manager->{'pid'} = undef;
|
||||
$instance_manager->{'angel_pid'} = undef;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ t1 CREATE TABLE `t1` (
|
|||
`c2` varchar(1) character set latin1 collate latin1_danish_ci NOT NULL default '',
|
||||
`c3` varbinary(1) NOT NULL default '',
|
||||
`c4` varbinary(1) NOT NULL default '',
|
||||
`c5` varbinary(3) NOT NULL default '',
|
||||
`c6` varbinary(3) NOT NULL default '',
|
||||
`c5` varbinary(4) NOT NULL default '',
|
||||
`c6` varbinary(4) NOT NULL default '',
|
||||
`c7` decimal(2,1) NOT NULL default '0.0',
|
||||
`c8` decimal(2,1) NOT NULL default '0.0',
|
||||
`c9` decimal(2,1) default NULL,
|
||||
|
|
@ -152,11 +152,11 @@ SHOW CREATE TABLE t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`COALESCE(1)` int(1) NOT NULL default '0',
|
||||
`COALESCE(1.0)` decimal(2,1) unsigned NOT NULL default '0.0',
|
||||
`COALESCE(1.0)` decimal(2,1) NOT NULL default '0.0',
|
||||
`COALESCE('a')` varchar(1) NOT NULL default '',
|
||||
`COALESCE(1,1.0)` decimal(2,1) NOT NULL default '0.0',
|
||||
`COALESCE(1,'1')` varbinary(1) NOT NULL default '',
|
||||
`COALESCE(1.1,'1')` varbinary(3) NOT NULL default '',
|
||||
`COALESCE(1.1,'1')` varbinary(4) NOT NULL default '',
|
||||
`COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default ''
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -53,3 +53,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE ÔÁÂ ref ÉÎÄ0,ÉÎÄ01 ÉÎÄ0 5 const 1 Using where; Using index
|
||||
drop table ÔÁÂ;
|
||||
set names latin1;
|
||||
select 3 into @v1;
|
||||
explain select 3 into @v1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
server_id =1
|
||||
server_id =2
|
||||
server_id = 1
|
||||
server_id = 2
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
SET mysqld1.server_id = 11;
|
||||
server_id =11
|
||||
server_id =2
|
||||
server_id = 2
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
server_id =1
|
||||
server_id =2
|
||||
server_id = 1
|
||||
server_id = 2
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
UNSET mysqld1.server_id;
|
||||
server_id =2
|
||||
server_id = 2
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
|
|
|
|||
|
|
@ -1154,3 +1154,25 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index
|
||||
1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index
|
||||
DROP TABLE t1,t2;
|
||||
DROP VIEW IF EXISTS v1,v2;
|
||||
DROP TABLE IF EXISTS t1,t2;
|
||||
CREATE TABLE t1 (a int);
|
||||
CREATE table t2 (b int);
|
||||
INSERT INTO t1 VALUES (1), (2), (3), (4), (1), (1), (3);
|
||||
INSERT INTO t2 VALUES (2), (3);
|
||||
CREATE VIEW v1 AS SELECT a FROM t1 JOIN t2 ON t1.a=t2.b;
|
||||
CREATE VIEW v2 AS SELECT b FROM t2 JOIN t1 ON t2.b=t1.a;
|
||||
SELECT v1.a, v2. b
|
||||
FROM v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3)
|
||||
GROUP BY v1.a;
|
||||
a b
|
||||
2 NULL
|
||||
3 3
|
||||
SELECT v1.a, v2. b
|
||||
FROM { OJ v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3) }
|
||||
GROUP BY v1.a;
|
||||
a b
|
||||
2 NULL
|
||||
3 3
|
||||
DROP VIEW v1,v2;
|
||||
DROP TABLE t1,t2;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ drop table if exists t1,t2;
|
|||
select 1, 1.0, -1, "hello", NULL;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def 1 8 1 1 N 32897 0 63
|
||||
def 1.0 246 3 3 N 161 1 63
|
||||
def 1.0 246 4 3 N 129 1 63
|
||||
def -1 8 2 2 N 32897 0 63
|
||||
def hello 253 5 5 N 1 31 8
|
||||
def NULL 6 0 0 Y 32896 0 63
|
||||
|
|
|
|||
|
|
@ -189,4 +189,5 @@ HEX(f)
|
|||
select HEX(f) from t4;
|
||||
HEX(f)
|
||||
835C
|
||||
flush logs;
|
||||
drop table t1, t2, t03, t04, t3, t4;
|
||||
|
|
|
|||
|
|
@ -1458,7 +1458,6 @@ UNLOCK TABLES;
|
|||
/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
|
||||
DROP TABLE IF EXISTS `v2`;
|
||||
/*!50001 DROP VIEW IF EXISTS `v2`*/;
|
||||
/*!50001 DROP TABLE IF EXISTS `v2`*/;
|
||||
/*!50001 CREATE TABLE `v2` (
|
||||
`a` varchar(30)
|
||||
) */;
|
||||
|
|
@ -1763,7 +1762,6 @@ UNLOCK TABLES;
|
|||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
DROP TABLE IF EXISTS `v1`;
|
||||
/*!50001 DROP VIEW IF EXISTS `v1`*/;
|
||||
/*!50001 DROP TABLE IF EXISTS `v1`*/;
|
||||
/*!50001 CREATE TABLE `v1` (
|
||||
`a` int(11)
|
||||
) */;
|
||||
|
|
@ -1821,7 +1819,6 @@ UNLOCK TABLES;
|
|||
/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
|
||||
DROP TABLE IF EXISTS `v2`;
|
||||
/*!50001 DROP VIEW IF EXISTS `v2`*/;
|
||||
/*!50001 DROP TABLE IF EXISTS `v2`*/;
|
||||
/*!50001 CREATE TABLE `v2` (
|
||||
`a` varchar(30)
|
||||
) */;
|
||||
|
|
@ -1914,7 +1911,6 @@ UNLOCK TABLES;
|
|||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
DROP TABLE IF EXISTS `v1`;
|
||||
/*!50001 DROP VIEW IF EXISTS `v1`*/;
|
||||
/*!50001 DROP TABLE IF EXISTS `v1`*/;
|
||||
/*!50001 CREATE TABLE `v1` (
|
||||
`a` int(11),
|
||||
`b` int(11),
|
||||
|
|
@ -1922,13 +1918,11 @@ DROP TABLE IF EXISTS `v1`;
|
|||
) */;
|
||||
DROP TABLE IF EXISTS `v2`;
|
||||
/*!50001 DROP VIEW IF EXISTS `v2`*/;
|
||||
/*!50001 DROP TABLE IF EXISTS `v2`*/;
|
||||
/*!50001 CREATE TABLE `v2` (
|
||||
`a` int(11)
|
||||
) */;
|
||||
DROP TABLE IF EXISTS `v3`;
|
||||
/*!50001 DROP VIEW IF EXISTS `v3`*/;
|
||||
/*!50001 DROP TABLE IF EXISTS `v3`*/;
|
||||
/*!50001 CREATE TABLE `v3` (
|
||||
`a` int(11),
|
||||
`b` int(11),
|
||||
|
|
@ -2489,7 +2483,6 @@ UNLOCK TABLES;
|
|||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
DROP TABLE IF EXISTS `v0`;
|
||||
/*!50001 DROP VIEW IF EXISTS `v0`*/;
|
||||
/*!50001 DROP TABLE IF EXISTS `v0`*/;
|
||||
/*!50001 CREATE TABLE `v0` (
|
||||
`a` int(11),
|
||||
`b` varchar(32),
|
||||
|
|
@ -2497,7 +2490,6 @@ DROP TABLE IF EXISTS `v0`;
|
|||
) */;
|
||||
DROP TABLE IF EXISTS `v1`;
|
||||
/*!50001 DROP VIEW IF EXISTS `v1`*/;
|
||||
/*!50001 DROP TABLE IF EXISTS `v1`*/;
|
||||
/*!50001 CREATE TABLE `v1` (
|
||||
`a` int(11),
|
||||
`b` varchar(32),
|
||||
|
|
@ -2505,16 +2497,11 @@ DROP TABLE IF EXISTS `v1`;
|
|||
) */;
|
||||
DROP TABLE IF EXISTS `v2`;
|
||||
/*!50001 DROP VIEW IF EXISTS `v2`*/;
|
||||
/*!50001 DROP TABLE IF EXISTS `v2`*/;
|
||||
/*!50001 CREATE TABLE `v2` (
|
||||
`a` int(11),
|
||||
`b` varchar(32),
|
||||
`c` varchar(32)
|
||||
) */;
|
||||
|
||||
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 */;
|
||||
|
||||
USE `test`;
|
||||
/*!50001 DROP TABLE IF EXISTS `v0`*/;
|
||||
/*!50001 DROP VIEW IF EXISTS `v0`*/;
|
||||
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||
|
|
@ -2731,3 +2718,61 @@ p CREATE DEFINER=`root`@`localhost` PROCEDURE `p`()
|
|||
select 42
|
||||
drop function f;
|
||||
drop procedure p;
|
||||
drop database if exists test;
|
||||
create database test;
|
||||
use test;
|
||||
create table t1 (id int);
|
||||
create view v1 as select * from t1;
|
||||
insert into t1 values (1232131);
|
||||
insert into t1 values (4711);
|
||||
insert into t1 values (3231);
|
||||
insert into t1 values (0815);
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
/*!40000 DROP DATABASE IF EXISTS `test`*/;
|
||||
|
||||
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 */;
|
||||
|
||||
USE `test`;
|
||||
DROP TABLE IF EXISTS `t1`;
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
|
||||
|
||||
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
|
||||
LOCK TABLES `t1` WRITE;
|
||||
INSERT INTO `t1` VALUES (1232131),(4711),(3231),(815);
|
||||
UNLOCK TABLES;
|
||||
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||
DROP TABLE IF EXISTS `v1`;
|
||||
/*!50001 DROP VIEW IF EXISTS `v1`*/;
|
||||
/*!50001 CREATE TABLE `v1` (
|
||||
`id` int(11)
|
||||
) */;
|
||||
/*!50001 DROP TABLE IF EXISTS `v1`*/;
|
||||
/*!50001 DROP VIEW IF EXISTS `v1`*/;
|
||||
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
|
||||
/*!50001 VIEW `v1` AS select `t1`.`id` AS `id` from `t1` */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
drop view v1;
|
||||
|
|
|
|||
|
|
@ -1777,7 +1777,7 @@ Table Create Table
|
|||
t5 CREATE TABLE `t5` (
|
||||
`const01` bigint(1) NOT NULL default '0',
|
||||
`param01` bigint(20) default NULL,
|
||||
`const02` decimal(2,1) unsigned NOT NULL default '0.0',
|
||||
`const02` decimal(2,1) NOT NULL default '0.0',
|
||||
`param02` decimal(65,30) default NULL,
|
||||
`const03` double NOT NULL default '0',
|
||||
`param03` double default NULL,
|
||||
|
|
@ -1807,7 +1807,7 @@ select * from t5 ;
|
|||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
|
||||
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
|
||||
def test t5 t5 const02 const02 246 3 3 N 33 1 63
|
||||
def test t5 t5 const02 const02 246 4 3 N 1 1 63
|
||||
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
|
||||
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
|
||||
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
|
||||
|
|
|
|||
|
|
@ -1760,7 +1760,7 @@ Table Create Table
|
|||
t5 CREATE TABLE `t5` (
|
||||
`const01` bigint(1) NOT NULL default '0',
|
||||
`param01` bigint(20) default NULL,
|
||||
`const02` decimal(2,1) unsigned NOT NULL default '0.0',
|
||||
`const02` decimal(2,1) NOT NULL default '0.0',
|
||||
`param02` decimal(65,30) default NULL,
|
||||
`const03` double NOT NULL default '0',
|
||||
`param03` double default NULL,
|
||||
|
|
@ -1790,7 +1790,7 @@ select * from t5 ;
|
|||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
|
||||
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
|
||||
def test t5 t5 const02 const02 246 3 3 N 33 1 63
|
||||
def test t5 t5 const02 const02 246 4 3 N 1 1 63
|
||||
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
|
||||
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
|
||||
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
|
||||
|
|
|
|||
|
|
@ -1761,7 +1761,7 @@ Table Create Table
|
|||
t5 CREATE TABLE `t5` (
|
||||
`const01` bigint(1) NOT NULL default '0',
|
||||
`param01` bigint(20) default NULL,
|
||||
`const02` decimal(2,1) unsigned NOT NULL default '0.0',
|
||||
`const02` decimal(2,1) NOT NULL default '0.0',
|
||||
`param02` decimal(65,30) default NULL,
|
||||
`const03` double NOT NULL default '0',
|
||||
`param03` double default NULL,
|
||||
|
|
@ -1791,7 +1791,7 @@ select * from t5 ;
|
|||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
|
||||
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
|
||||
def test t5 t5 const02 const02 246 3 3 N 33 1 63
|
||||
def test t5 t5 const02 const02 246 4 3 N 1 1 63
|
||||
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
|
||||
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
|
||||
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
|
||||
|
|
|
|||
|
|
@ -1697,7 +1697,7 @@ Table Create Table
|
|||
t5 CREATE TABLE `t5` (
|
||||
`const01` bigint(1) NOT NULL default '0',
|
||||
`param01` bigint(20) default NULL,
|
||||
`const02` decimal(2,1) unsigned NOT NULL default '0.0',
|
||||
`const02` decimal(2,1) NOT NULL default '0.0',
|
||||
`param02` decimal(65,30) default NULL,
|
||||
`const03` double NOT NULL default '0',
|
||||
`param03` double default NULL,
|
||||
|
|
@ -1727,7 +1727,7 @@ select * from t5 ;
|
|||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
|
||||
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
|
||||
def test t5 t5 const02 const02 246 3 3 N 33 1 63
|
||||
def test t5 t5 const02 const02 246 4 3 N 1 1 63
|
||||
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
|
||||
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
|
||||
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
|
||||
|
|
@ -4711,7 +4711,7 @@ Table Create Table
|
|||
t5 CREATE TABLE `t5` (
|
||||
`const01` bigint(1) NOT NULL default '0',
|
||||
`param01` bigint(20) default NULL,
|
||||
`const02` decimal(2,1) unsigned NOT NULL default '0.0',
|
||||
`const02` decimal(2,1) NOT NULL default '0.0',
|
||||
`param02` decimal(65,30) default NULL,
|
||||
`const03` double NOT NULL default '0',
|
||||
`param03` double default NULL,
|
||||
|
|
@ -4741,7 +4741,7 @@ select * from t5 ;
|
|||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
|
||||
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
|
||||
def test t5 t5 const02 const02 246 3 3 N 33 1 63
|
||||
def test t5 t5 const02 const02 246 4 3 N 1 1 63
|
||||
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
|
||||
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
|
||||
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
|
||||
|
|
|
|||
|
|
@ -1760,7 +1760,7 @@ Table Create Table
|
|||
t5 CREATE TABLE `t5` (
|
||||
`const01` bigint(1) NOT NULL default '0',
|
||||
`param01` bigint(20) default NULL,
|
||||
`const02` decimal(2,1) unsigned NOT NULL default '0.0',
|
||||
`const02` decimal(2,1) NOT NULL default '0.0',
|
||||
`param02` decimal(65,30) default NULL,
|
||||
`const03` double NOT NULL default '0',
|
||||
`param03` double default NULL,
|
||||
|
|
@ -1790,7 +1790,7 @@ select * from t5 ;
|
|||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
|
||||
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
|
||||
def test t5 t5 const02 const02 246 3 3 N 33 1 63
|
||||
def test t5 t5 const02 const02 246 4 3 N 1 1 63
|
||||
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
|
||||
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
|
||||
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
|
||||
|
|
|
|||
|
|
@ -1760,7 +1760,7 @@ Table Create Table
|
|||
t5 CREATE TABLE `t5` (
|
||||
`const01` bigint(1) NOT NULL default '0',
|
||||
`param01` bigint(20) default NULL,
|
||||
`const02` decimal(2,1) unsigned NOT NULL default '0.0',
|
||||
`const02` decimal(2,1) NOT NULL default '0.0',
|
||||
`param02` decimal(65,30) default NULL,
|
||||
`const03` double NOT NULL default '0',
|
||||
`param03` double default NULL,
|
||||
|
|
@ -1790,7 +1790,7 @@ select * from t5 ;
|
|||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
|
||||
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
|
||||
def test t5 t5 const02 const02 246 3 3 N 33 1 63
|
||||
def test t5 t5 const02 const02 246 4 3 N 1 1 63
|
||||
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
|
||||
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
|
||||
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
|
||||
|
|
|
|||
47
mysql-test/r/rpl_auto_increment_11932.result
Normal file
47
mysql-test/r/rpl_auto_increment_11932.result
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
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;
|
||||
drop database if exists test1;
|
||||
create database test1;
|
||||
use test1;
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`fname` varchar(100) default NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
|
||||
INSERT INTO `t1` VALUES (1, 'blablabla');
|
||||
CREATE TABLE `t2` (
|
||||
`id` int(10) NOT NULL auto_increment,
|
||||
`comment` varchar(255) NOT NULL default '',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=3 ;
|
||||
INSERT INTO `t2` VALUES (1, 'testtest 1');
|
||||
INSERT INTO `t2` VALUES (2, 'test 2');
|
||||
CREATE PROCEDURE simpleproc3 ()
|
||||
NOT DETERMINISTIC
|
||||
BEGIN
|
||||
INSERT INTO t1 (fname) (SELECT t2.comment FROM t2 WHERE t2.id = '1');
|
||||
INSERT INTO t1 (fname) VALUES('test');
|
||||
END
|
||||
$
|
||||
CALL simpleproc3();
|
||||
select * from t2;
|
||||
id comment
|
||||
1 testtest 1
|
||||
2 test 2
|
||||
TRUNCATE TABLE `t1`;
|
||||
CALL simpleproc3();
|
||||
select * from t1;
|
||||
id fname
|
||||
1 testtest 1
|
||||
2 test
|
||||
use test1;
|
||||
select * from t1;
|
||||
id fname
|
||||
1 testtest 1
|
||||
2 test
|
||||
drop database test1;
|
||||
drop database test1;
|
||||
|
|
@ -103,15 +103,24 @@ f
|
|||
1
|
||||
drop temporary table t4;
|
||||
drop table t5;
|
||||
set @session.pseudo_thread_id=100;
|
||||
set @@session.pseudo_thread_id=100;
|
||||
create temporary table t101 (id int);
|
||||
create temporary table t102 (id int);
|
||||
set @session.pseudo_thread_id=200;
|
||||
set @@session.pseudo_thread_id=200;
|
||||
create temporary table t201 (id int);
|
||||
create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int);
|
||||
create temporary table `t``201` (id int);
|
||||
create temporary table `#sql_not_user_table202` (id int);
|
||||
set @@session.pseudo_thread_id=300;
|
||||
create temporary table t301 (id int);
|
||||
create temporary table t302 (id int);
|
||||
create temporary table `#sql_not_user_table303` (id int);
|
||||
create table t1(f int);
|
||||
insert into t1 values (1);
|
||||
select * from t1 /* must be 1 */;
|
||||
f
|
||||
1
|
||||
drop table t1;
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
drop table t1;
|
||||
|
|
|
|||
|
|
@ -29,9 +29,40 @@ n
|
|||
2
|
||||
3
|
||||
4
|
||||
show slave status;
|
||||
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
|
||||
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 319 # Master master-bin.000001 319 No #
|
||||
SHOW SLAVE STATUS;
|
||||
Slave_IO_State #
|
||||
Master_Host 127.0.0.1
|
||||
Master_User root
|
||||
Master_Port MASTER_MYPORT
|
||||
Connect_Retry 1
|
||||
Master_Log_File master-bin.000001
|
||||
Read_Master_Log_Pos 776
|
||||
Relay_Log_File slave-relay-bin.000004
|
||||
Relay_Log_Pos #
|
||||
Relay_Master_Log_File master-bin.000001
|
||||
Slave_IO_Running #
|
||||
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 0
|
||||
Last_Error
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos 319
|
||||
Relay_Log_Space #
|
||||
Until_Condition Master
|
||||
Until_Log_File master-bin.000001
|
||||
Until_Log_Pos 319
|
||||
Master_SSL_Allowed No
|
||||
Master_SSL_CA_File
|
||||
Master_SSL_CA_Path
|
||||
Master_SSL_Cert
|
||||
Master_SSL_Cipher
|
||||
Master_SSL_Key
|
||||
Seconds_Behind_Master #
|
||||
start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
|
||||
select * from t1;
|
||||
n
|
||||
|
|
@ -39,23 +70,116 @@ n
|
|||
2
|
||||
3
|
||||
4
|
||||
show slave status;
|
||||
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
|
||||
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 319 # Master master-no-such-bin.000001 291 No #
|
||||
SHOW SLAVE STATUS;
|
||||
Slave_IO_State #
|
||||
Master_Host 127.0.0.1
|
||||
Master_User root
|
||||
Master_Port MASTER_MYPORT
|
||||
Connect_Retry 1
|
||||
Master_Log_File master-bin.000001
|
||||
Read_Master_Log_Pos 776
|
||||
Relay_Log_File slave-relay-bin.000004
|
||||
Relay_Log_Pos #
|
||||
Relay_Master_Log_File master-bin.000001
|
||||
Slave_IO_Running #
|
||||
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 0
|
||||
Last_Error
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos 319
|
||||
Relay_Log_Space #
|
||||
Until_Condition Master
|
||||
Until_Log_File master-no-such-bin.000001
|
||||
Until_Log_Pos 291
|
||||
Master_SSL_Allowed No
|
||||
Master_SSL_CA_File
|
||||
Master_SSL_CA_Path
|
||||
Master_SSL_Cert
|
||||
Master_SSL_Cipher
|
||||
Master_SSL_Key
|
||||
Seconds_Behind_Master #
|
||||
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=746;
|
||||
select * from t2;
|
||||
n
|
||||
1
|
||||
2
|
||||
show slave status;
|
||||
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
|
||||
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 608 # Relay slave-relay-bin.000004 746 No #
|
||||
SHOW SLAVE STATUS;
|
||||
Slave_IO_State #
|
||||
Master_Host 127.0.0.1
|
||||
Master_User root
|
||||
Master_Port MASTER_MYPORT
|
||||
Connect_Retry 1
|
||||
Master_Log_File master-bin.000001
|
||||
Read_Master_Log_Pos 776
|
||||
Relay_Log_File slave-relay-bin.000004
|
||||
Relay_Log_Pos #
|
||||
Relay_Master_Log_File master-bin.000001
|
||||
Slave_IO_Running #
|
||||
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 0
|
||||
Last_Error
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos 608
|
||||
Relay_Log_Space #
|
||||
Until_Condition Relay
|
||||
Until_Log_File slave-relay-bin.000004
|
||||
Until_Log_Pos 746
|
||||
Master_SSL_Allowed No
|
||||
Master_SSL_CA_File
|
||||
Master_SSL_CA_Path
|
||||
Master_SSL_Cert
|
||||
Master_SSL_Cipher
|
||||
Master_SSL_Key
|
||||
Seconds_Behind_Master #
|
||||
start slave;
|
||||
stop slave;
|
||||
start slave until master_log_file='master-bin.000001', master_log_pos=776;
|
||||
show slave status;
|
||||
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
|
||||
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 776 # Master master-bin.000001 776 No #
|
||||
SHOW SLAVE STATUS;
|
||||
Slave_IO_State #
|
||||
Master_Host 127.0.0.1
|
||||
Master_User root
|
||||
Master_Port MASTER_MYPORT
|
||||
Connect_Retry 1
|
||||
Master_Log_File master-bin.000001
|
||||
Read_Master_Log_Pos 776
|
||||
Relay_Log_File slave-relay-bin.000004
|
||||
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 0
|
||||
Last_Error
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos 776
|
||||
Relay_Log_Space #
|
||||
Until_Condition Master
|
||||
Until_Log_File master-bin.000001
|
||||
Until_Log_Pos 776
|
||||
Master_SSL_Allowed No
|
||||
Master_SSL_CA_File
|
||||
Master_SSL_CA_Path
|
||||
Master_SSL_Cert
|
||||
Master_SSL_Cipher
|
||||
Master_SSL_Key
|
||||
Seconds_Behind_Master #
|
||||
start slave until master_log_file='master-bin', master_log_pos=561;
|
||||
ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
|
||||
start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12;
|
||||
|
|
|
|||
|
|
@ -282,9 +282,9 @@ select @tmp_x, @tmp_y, @tmp_z|
|
|||
@tmp_x @tmp_y @tmp_z
|
||||
42 45 87
|
||||
call p(42, 43, @tmp_z)|
|
||||
ERROR 42000: OUT or INOUT argument 2 for routine test.p is not a variable
|
||||
ERROR 42000: OUT or INOUT argument 2 for routine test.p is not a variable or NEW pseudo-variable in BEFORE trigger
|
||||
call p(42, @tmp_y, 43)|
|
||||
ERROR 42000: OUT or INOUT argument 3 for routine test.p is not a variable
|
||||
ERROR 42000: OUT or INOUT argument 3 for routine test.p is not a variable or NEW pseudo-variable in BEFORE trigger
|
||||
drop procedure p|
|
||||
create procedure p() begin end|
|
||||
lock table t1 read|
|
||||
|
|
|
|||
|
|
@ -4904,4 +4904,60 @@ schema_name
|
|||
select routine_name,routine_schema from information_schema.routines where
|
||||
routine_schema like 'bug18344%'|
|
||||
routine_name routine_schema
|
||||
drop function if exists bug12472|
|
||||
create function bug12472() returns int return (select count(*) from t1)|
|
||||
create table t3 as select bug12472() as i|
|
||||
show create table t3|
|
||||
Table Create Table
|
||||
t3 CREATE TABLE `t3` (
|
||||
`i` int(11) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
select * from t3|
|
||||
i
|
||||
0
|
||||
drop table t3|
|
||||
create view v1 as select bug12472() as j|
|
||||
create table t3 as select * from v1|
|
||||
show create table t3|
|
||||
Table Create Table
|
||||
t3 CREATE TABLE `t3` (
|
||||
`j` bigint(11) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
select * from t3|
|
||||
j
|
||||
0
|
||||
drop table t3|
|
||||
drop view v1|
|
||||
drop function bug12472|
|
||||
DROP FUNCTION IF EXISTS bug18589_f1|
|
||||
DROP PROCEDURE IF EXISTS bug18589_p1|
|
||||
DROP PROCEDURE IF EXISTS bug18589_p2|
|
||||
CREATE FUNCTION bug18589_f1(arg TEXT) RETURNS TEXT
|
||||
BEGIN
|
||||
RETURN CONCAT(arg, "");
|
||||
END|
|
||||
CREATE PROCEDURE bug18589_p1(arg TEXT, OUT ret TEXT)
|
||||
BEGIN
|
||||
SET ret = CONCAT(arg, "");
|
||||
END|
|
||||
CREATE PROCEDURE bug18589_p2(arg TEXT)
|
||||
BEGIN
|
||||
DECLARE v TEXT;
|
||||
CALL bug18589_p1(arg, v);
|
||||
SELECT v;
|
||||
END|
|
||||
SELECT bug18589_f1(REPEAT("a", 767))|
|
||||
bug18589_f1(REPEAT("a", 767))
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
SET @bug18589_v1 = ""|
|
||||
CALL bug18589_p1(REPEAT("a", 767), @bug18589_v1)|
|
||||
SELECT @bug18589_v1|
|
||||
@bug18589_v1
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
CALL bug18589_p2(REPEAT("a", 767))|
|
||||
v
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
DROP FUNCTION bug18589_f1|
|
||||
DROP PROCEDURE bug18589_p1|
|
||||
DROP PROCEDURE bug18589_p2|
|
||||
drop table t1,t2;
|
||||
|
|
|
|||
|
|
@ -485,6 +485,10 @@ set sql_mode=2097152;
|
|||
select @@sql_mode;
|
||||
@@sql_mode
|
||||
STRICT_TRANS_TABLES
|
||||
set sql_mode=4194304;
|
||||
select @@sql_mode;
|
||||
@@sql_mode
|
||||
STRICT_ALL_TABLES
|
||||
set sql_mode=16384+(65536*4);
|
||||
select @@sql_mode;
|
||||
@@sql_mode
|
||||
|
|
|
|||
|
|
@ -3169,3 +3169,11 @@ create table t2 (a int, b int);
|
|||
insert into t2 values (2, 1), (1, 0);
|
||||
delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
|
||||
drop table t1, t2;
|
||||
CREATE TABLE t1 (a INT);
|
||||
CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
|
||||
ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
|
||||
CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
|
||||
ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
|
||||
SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
|
||||
ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -310,3 +310,87 @@ SELECT @mysqltest_var;
|
|||
Hello, world!
|
||||
DROP USER mysqltest_u1@localhost;
|
||||
DROP DATABASE mysqltest_db1;
|
||||
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
|
||||
FLUSH PRIVILEGES;
|
||||
DROP DATABASE IF EXISTS mysqltest_db1;
|
||||
CREATE DATABASE mysqltest_db1;
|
||||
USE mysqltest_db1;
|
||||
CREATE TABLE t1 (i1 INT);
|
||||
CREATE TABLE t2 (i1 INT);
|
||||
CREATE USER mysqltest_dfn@localhost;
|
||||
CREATE USER mysqltest_inv@localhost;
|
||||
GRANT EXECUTE, CREATE ROUTINE, SUPER ON *.* TO mysqltest_dfn@localhost;
|
||||
GRANT INSERT ON mysqltest_db1.* TO mysqltest_inv@localhost;
|
||||
CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 3;
|
||||
CREATE PROCEDURE p2(INOUT i INT) DETERMINISTIC NO SQL SET i = i * 5;
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
|
||||
CALL p2(NEW.i1);
|
||||
INSERT INTO t1 VALUES (7);
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
|
||||
INSERT INTO t2 VALUES (11);
|
||||
ERROR 42000: SELECT,UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
|
||||
DROP TRIGGER t2_bi;
|
||||
DROP TRIGGER t1_bi;
|
||||
GRANT SELECT ON mysqltest_db1.* TO mysqltest_dfn@localhost;
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
|
||||
CALL p2(NEW.i1);
|
||||
INSERT INTO t1 VALUES (13);
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
|
||||
INSERT INTO t2 VALUES (17);
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
|
||||
REVOKE SELECT ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
|
||||
DROP TRIGGER t2_bi;
|
||||
DROP TRIGGER t1_bi;
|
||||
GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
|
||||
CALL p2(NEW.i1);
|
||||
INSERT INTO t1 VALUES (19);
|
||||
INSERT INTO t2 VALUES (23);
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
|
||||
REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
|
||||
DROP TRIGGER t2_bi;
|
||||
DROP TRIGGER t1_bi;
|
||||
GRANT SELECT, UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
|
||||
CALL p2(NEW.i1);
|
||||
INSERT INTO t1 VALUES (29);
|
||||
INSERT INTO t2 VALUES (31);
|
||||
REVOKE SELECT, UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
|
||||
DROP TRIGGER t2_bi;
|
||||
DROP TRIGGER t1_bi;
|
||||
DROP PROCEDURE p2;
|
||||
DROP PROCEDURE p1;
|
||||
GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
|
||||
CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 37;
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
INSERT INTO t1 VALUES (41);
|
||||
DROP PROCEDURE p1;
|
||||
CREATE PROCEDURE p1(IN i INT) DETERMINISTIC NO SQL SET @v1 = i + 43;
|
||||
INSERT INTO t1 VALUES (47);
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
|
||||
DROP PROCEDURE p1;
|
||||
CREATE PROCEDURE p1(INOUT i INT) DETERMINISTIC NO SQL SET i = i + 51;
|
||||
INSERT INTO t1 VALUES (53);
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
|
||||
DROP PROCEDURE p1;
|
||||
REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
|
||||
DROP TRIGGER t1_bi;
|
||||
DROP USER mysqltest_inv@localhost;
|
||||
DROP USER mysqltest_dfn@localhost;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
DROP DATABASE mysqltest_db1;
|
||||
USE test;
|
||||
End of 5.0 tests.
|
||||
|
|
|
|||
|
|
@ -998,3 +998,95 @@ SELECT * FROM t1 WHERE conn_id != trigger_conn_id;
|
|||
conn_id trigger_conn_id
|
||||
DROP TRIGGER t1_bi;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (i1 INT);
|
||||
SET @save_sql_mode=@@sql_mode;
|
||||
SET SQL_MODE='';
|
||||
CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
|
||||
SET @x = 5/0;
|
||||
SET SQL_MODE='traditional';
|
||||
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
|
||||
SET @x = 5/0;
|
||||
SET @x=1;
|
||||
INSERT INTO t1 VALUES (@x);
|
||||
SELECT @x;
|
||||
@x
|
||||
NULL
|
||||
SET @x=2;
|
||||
UPDATE t1 SET i1 = @x;
|
||||
ERROR 22012: Division by 0
|
||||
SELECT @x;
|
||||
@x
|
||||
2
|
||||
SET SQL_MODE='';
|
||||
SET @x=3;
|
||||
INSERT INTO t1 VALUES (@x);
|
||||
SELECT @x;
|
||||
@x
|
||||
NULL
|
||||
SET @x=4;
|
||||
UPDATE t1 SET i1 = @x;
|
||||
ERROR 22012: Division by 0
|
||||
SELECT @x;
|
||||
@x
|
||||
4
|
||||
SET @@sql_mode=@save_sql_mode;
|
||||
DROP TRIGGER t1_ai;
|
||||
DROP TRIGGER t1_au;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
DROP PROCEDURE IF EXISTS p2;
|
||||
CREATE TABLE t1 (i1 INT);
|
||||
INSERT INTO t1 VALUES (3);
|
||||
CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET i1 = 5;
|
||||
CREATE PROCEDURE p2(INOUT i1 INT) DETERMINISTIC NO SQL SET i1 = i1 * 7;
|
||||
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
|
||||
BEGIN
|
||||
CALL p1(NEW.i1);
|
||||
CALL p2(NEW.i1);
|
||||
END//
|
||||
UPDATE t1 SET i1 = 11 WHERE i1 = 3;
|
||||
DROP TRIGGER t1_bu;
|
||||
DROP PROCEDURE p2;
|
||||
DROP PROCEDURE p1;
|
||||
INSERT INTO t1 VALUES (13);
|
||||
CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 17;
|
||||
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
|
||||
CALL p1(OLD.i1);
|
||||
UPDATE t1 SET i1 = 19 WHERE i1 = 13;
|
||||
ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
|
||||
DROP TRIGGER t1_bu;
|
||||
DROP PROCEDURE p1;
|
||||
INSERT INTO t1 VALUES (23);
|
||||
CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 29;
|
||||
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
|
||||
CALL p1(OLD.i1);
|
||||
UPDATE t1 SET i1 = 31 WHERE i1 = 23;
|
||||
ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
|
||||
DROP TRIGGER t1_bu;
|
||||
DROP PROCEDURE p1;
|
||||
INSERT INTO t1 VALUES (37);
|
||||
CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 41;
|
||||
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
UPDATE t1 SET i1 = 43 WHERE i1 = 37;
|
||||
ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
|
||||
DROP TRIGGER t1_au;
|
||||
DROP PROCEDURE p1;
|
||||
INSERT INTO t1 VALUES (47);
|
||||
CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 49;
|
||||
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
UPDATE t1 SET i1 = 51 WHERE i1 = 47;
|
||||
ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
|
||||
DROP TRIGGER t1_au;
|
||||
DROP PROCEDURE p1;
|
||||
SELECT * FROM t1;
|
||||
i1
|
||||
35
|
||||
13
|
||||
23
|
||||
43
|
||||
51
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -245,22 +245,22 @@ show warnings;
|
|||
Level Code Message
|
||||
desc t1;
|
||||
Field Type Null Key Default Extra
|
||||
x decimal(21,2) unsigned NO 0.00
|
||||
x decimal(21,2) NO 0.00
|
||||
drop table t1;
|
||||
create table t1 select 0.0 x;
|
||||
desc t1;
|
||||
Field Type Null Key Default Extra
|
||||
x decimal(2,1) unsigned NO 0.0
|
||||
x decimal(2,1) NO 0.0
|
||||
create table t2 select 105213674794682365.00 y;
|
||||
desc t2;
|
||||
Field Type Null Key Default Extra
|
||||
y decimal(20,2) unsigned NO 0.00
|
||||
y decimal(20,2) NO 0.00
|
||||
create table t3 select x+y a from t1,t2;
|
||||
show warnings;
|
||||
Level Code Message
|
||||
desc t3;
|
||||
Field Type Null Key Default Extra
|
||||
a decimal(21,2) unsigned NO 0.00
|
||||
a decimal(21,2) NO 0.00
|
||||
drop table t1,t2,t3;
|
||||
create table t1 (s1 float(0,2));
|
||||
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').
|
||||
|
|
|
|||
|
|
@ -68,10 +68,10 @@ NULL 1.1 NULL NULL NULL 1
|
|||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`nullif(1.1, 1.1)` decimal(2,1) unsigned default NULL,
|
||||
`nullif(1.1, 1.2)` decimal(2,1) unsigned default NULL,
|
||||
`nullif(1.1, 0.11e1)` decimal(2,1) unsigned default NULL,
|
||||
`nullif(1.0, 1)` decimal(2,1) unsigned default NULL,
|
||||
`nullif(1.1, 1.1)` decimal(2,1) default NULL,
|
||||
`nullif(1.1, 1.2)` decimal(2,1) default NULL,
|
||||
`nullif(1.1, 0.11e1)` decimal(2,1) default NULL,
|
||||
`nullif(1.0, 1)` decimal(2,1) default NULL,
|
||||
`nullif(1, 1.0)` int(1) default NULL,
|
||||
`nullif(1, 1.1)` int(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
|
|
@ -174,9 +174,9 @@ create table t1 select round(15.4,-1), truncate(-5678.123451,-3), abs(-1.1), -(-
|
|||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`round(15.4,-1)` decimal(3,0) unsigned NOT NULL default '0',
|
||||
`round(15.4,-1)` decimal(3,0) NOT NULL default '0',
|
||||
`truncate(-5678.123451,-3)` decimal(4,0) NOT NULL default '0',
|
||||
`abs(-1.1)` decimal(2,1) NOT NULL default '0.0',
|
||||
`abs(-1.1)` decimal(3,1) NOT NULL default '0.0',
|
||||
`-(-1.1)` decimal(2,1) NOT NULL default '0.0'
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
|
|
@ -771,7 +771,7 @@ create table t1 as select 0.5;
|
|||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`0.5` decimal(2,1) unsigned NOT NULL default '0.0'
|
||||
`0.5` decimal(2,1) NOT NULL default '0.0'
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
select round(1.5),round(2.5);
|
||||
|
|
|
|||
|
|
@ -706,7 +706,7 @@ create view v1 as select a from t1;
|
|||
create view v2 as select a from t2 where a in (select a from v1);
|
||||
show create view v2;
|
||||
View Create View
|
||||
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where `a` in (select `v1`.`a` AS `a` from `v1`)
|
||||
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where `t2`.`a` in (select `v1`.`a` AS `a` from `v1`)
|
||||
drop view v2, v1;
|
||||
drop table t1, t2;
|
||||
CREATE VIEW `v 1` AS select 5 AS `5`;
|
||||
|
|
@ -2649,3 +2649,14 @@ ldt
|
|||
2006-01-01 03:00:00
|
||||
drop view v1, v2;
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, d datetime);
|
||||
CREATE VIEW v1 AS
|
||||
SELECT id, date(d) + INTERVAL TIME_TO_SEC(d) SECOND AS t, COUNT(*)
|
||||
FROM t1 GROUP BY id, t;
|
||||
SHOW CREATE VIEW v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`id` AS `id`,(cast(`t1`.`d` as date) + interval time_to_sec(`t1`.`d`) second) AS `t`,count(0) AS `COUNT(*)` from `t1` group by `t1`.`id`,(cast(`t1`.`d` as date) + interval time_to_sec(`t1`.`d`) second)
|
||||
SELECT * FROM v1;
|
||||
id t COUNT(*)
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -43,3 +43,12 @@ drop table
|
|||
set names latin1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
|
||||
#
|
||||
# Bug#15463: EXPLAIN SELECT..INTO hangs the client (QB, command line)
|
||||
#
|
||||
select 3 into @v1;
|
||||
explain select 3 into @v1;
|
||||
|
||||
# End of 5.0 tests.
|
||||
|
|
|
|||
|
|
@ -2196,3 +2196,16 @@ drop table t2, t1;
|
|||
#
|
||||
--error ER_TABLE_CANT_HANDLE_SPKEYS
|
||||
create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
|
||||
|
||||
#######################################################################
|
||||
# #
|
||||
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
|
||||
# These files are to be modified ONLY BY INNOBASE guys. #
|
||||
# #
|
||||
# Use innodb_mysql.[test|result] files instead. #
|
||||
# #
|
||||
# If nevertheless you need to make some changes here, please, forward #
|
||||
# your commit message To: dev@innodb.com Cc: dev-innodb@mysql.com #
|
||||
# (otherwise your changes may be erased). #
|
||||
# #
|
||||
#######################################################################
|
||||
|
|
|
|||
|
|
@ -779,3 +779,29 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
|
|||
WHERE t1.name LIKE 'A%' OR FALSE;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug 19396: LEFT OUTER JOIN over views in curly braces
|
||||
#
|
||||
--disable_warnings
|
||||
DROP VIEW IF EXISTS v1,v2;
|
||||
DROP TABLE IF EXISTS t1,t2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (a int);
|
||||
CREATE table t2 (b int);
|
||||
INSERT INTO t1 VALUES (1), (2), (3), (4), (1), (1), (3);
|
||||
INSERT INTO t2 VALUES (2), (3);
|
||||
|
||||
CREATE VIEW v1 AS SELECT a FROM t1 JOIN t2 ON t1.a=t2.b;
|
||||
CREATE VIEW v2 AS SELECT b FROM t2 JOIN t1 ON t2.b=t1.a;
|
||||
|
||||
SELECT v1.a, v2. b
|
||||
FROM v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3)
|
||||
GROUP BY v1.a;
|
||||
SELECT v1.a, v2. b
|
||||
FROM { OJ v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3) }
|
||||
GROUP BY v1.a;
|
||||
|
||||
DROP VIEW v1,v2;
|
||||
DROP TABLE t1,t2;
|
||||
|
|
|
|||
|
|
@ -122,9 +122,22 @@ select HEX(f) from t3;
|
|||
select HEX(f) from t04;
|
||||
select HEX(f) from t4;
|
||||
|
||||
#
|
||||
# BUG#14157: utf8 encoding in binlog without set character_set_client
|
||||
#
|
||||
# BUG:
|
||||
# This test only works on the MySQL-internal rpl machines.
|
||||
# Needs to be fixed. Problem is that koi8r is not installed
|
||||
# on many machines.
|
||||
#
|
||||
flush logs;
|
||||
# --exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=koi8r test -e 'create table if not exists t5 (a int); set names koi8r; create temporary table `ÑÝÉË` (a int); insert into `ÑÝÉË` values (1); insert into t5 select * from `ÑÝÉË`'
|
||||
|
||||
# resulted log is client charset insensitive (latin1 not koi8r) as it must be
|
||||
# --exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000006 | $MYSQL --default-character-set=latin1
|
||||
#select * from t5 /* must be (1),(1) */;
|
||||
|
||||
# clean up
|
||||
drop table t1, t2, t03, t04, t3, t4;
|
||||
|
||||
# End of 4.1 tests
|
||||
# End of 5.0 tests
|
||||
|
|
|
|||
|
|
@ -1143,3 +1143,19 @@ show create procedure p;
|
|||
drop function f;
|
||||
drop procedure p;
|
||||
|
||||
#
|
||||
# BUG#17201 Spurious 'DROP DATABASE' in output,
|
||||
# also confusion between tables and views.
|
||||
# Example code from Markus Popp
|
||||
|
||||
drop database if exists test;
|
||||
create database test;
|
||||
use test;
|
||||
create table t1 (id int);
|
||||
create view v1 as select * from t1;
|
||||
insert into t1 values (1232131);
|
||||
insert into t1 values (4711);
|
||||
insert into t1 values (3231);
|
||||
insert into t1 values (0815);
|
||||
--exec $MYSQL_DUMP --skip-comments --add-drop-database --databases test
|
||||
drop view v1;
|
||||
|
|
|
|||
|
|
@ -61,9 +61,15 @@ connection con2;
|
|||
sleep 1;
|
||||
show tables;
|
||||
UNLOCK TABLES;
|
||||
sleep 1;
|
||||
connection con1;
|
||||
reap;
|
||||
connection con2;
|
||||
show tables;
|
||||
|
||||
drop table t2, t4;
|
||||
|
||||
disconnect con2;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
|
|
|||
63
mysql-test/t/rpl_auto_increment_11932.test
Normal file
63
mysql-test/t/rpl_auto_increment_11932.test
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#
|
||||
# Test of auto_increment
|
||||
# BUG#11932
|
||||
#
|
||||
# Bug reported that master and slave get out of sync after TRUNCATE
|
||||
# TABLE.
|
||||
#
|
||||
# Test supplied by Are Casilla
|
||||
|
||||
source include/master-slave.inc;
|
||||
--disable_warnings
|
||||
connection master;
|
||||
drop database if exists test1;
|
||||
--enable_warnings
|
||||
create database test1;
|
||||
use test1;
|
||||
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`fname` varchar(100) default NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
|
||||
|
||||
INSERT INTO `t1` VALUES (1, 'blablabla');
|
||||
|
||||
CREATE TABLE `t2` (
|
||||
`id` int(10) NOT NULL auto_increment,
|
||||
`comment` varchar(255) NOT NULL default '',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=3 ;
|
||||
|
||||
INSERT INTO `t2` VALUES (1, 'testtest 1');
|
||||
INSERT INTO `t2` VALUES (2, 'test 2');
|
||||
|
||||
DELIMITER $;
|
||||
CREATE PROCEDURE simpleproc3 ()
|
||||
NOT DETERMINISTIC
|
||||
BEGIN
|
||||
INSERT INTO t1 (fname) (SELECT t2.comment FROM t2 WHERE t2.id = '1');
|
||||
INSERT INTO t1 (fname) VALUES('test');
|
||||
END
|
||||
$
|
||||
DELIMITER ;$
|
||||
|
||||
CALL simpleproc3();
|
||||
|
||||
select * from t2;
|
||||
|
||||
TRUNCATE TABLE `t1`;
|
||||
CALL simpleproc3();
|
||||
|
||||
select * from t1;
|
||||
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
|
||||
use test1;
|
||||
select * from t1;
|
||||
|
||||
drop database test1;
|
||||
connection master;
|
||||
drop database test1;
|
||||
|
|
@ -163,24 +163,19 @@ drop table t5;
|
|||
# value was set up at the moment of temp table creation
|
||||
#
|
||||
connection con1;
|
||||
set @session.pseudo_thread_id=100;
|
||||
set @@session.pseudo_thread_id=100;
|
||||
create temporary table t101 (id int);
|
||||
create temporary table t102 (id int);
|
||||
set @session.pseudo_thread_id=200;
|
||||
set @@session.pseudo_thread_id=200;
|
||||
create temporary table t201 (id int);
|
||||
create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int);
|
||||
|
||||
#
|
||||
# Don't kill our own connection to the server as
|
||||
# the result code differs depending on platform.
|
||||
#
|
||||
# Select the id to kill into a variable of mysqltest
|
||||
let $con1_id= `select connection_id()`;
|
||||
# Switch connection to avoid killing our own connection
|
||||
connection master;
|
||||
--disable_query_log
|
||||
eval kill $con1_id;
|
||||
--enable_query_log
|
||||
create temporary table `t``201` (id int);
|
||||
# emulate internal temp table not to come to binlog
|
||||
create temporary table `#sql_not_user_table202` (id int);
|
||||
set @@session.pseudo_thread_id=300;
|
||||
create temporary table t301 (id int);
|
||||
create temporary table t302 (id int);
|
||||
create temporary table `#sql_not_user_table303` (id int);
|
||||
disconnect con1;
|
||||
|
||||
#now do something to show that slave is ok after DROP temp tables
|
||||
connection master;
|
||||
|
|
@ -194,4 +189,16 @@ select * from t1 /* must be 1 */;
|
|||
connection master;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
#14157: utf8 encoding in binlog without set character_set_client
|
||||
#
|
||||
--exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=koi8r test -e 'create table t1 (a int); set names koi8r; create temporary table `ÑÝÉË` (a int); insert into `ÑÝÉË` values (1); insert into t1 select * from `ÑÝÉË`'
|
||||
|
||||
sync_slave_with_master;
|
||||
#connection slave;
|
||||
select * from t1;
|
||||
|
||||
connection master;
|
||||
drop table t1;
|
||||
|
||||
# End of 5.0 tests
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ wait_for_slave_to_stop;
|
|||
select * from t1;
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||
--replace_column 1 # 9 # 11 # 23 # 33 #
|
||||
show slave status;
|
||||
--query_vertical SHOW SLAVE STATUS
|
||||
|
||||
# this should fail right after start
|
||||
start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
|
||||
|
|
@ -41,7 +41,7 @@ sleep 2;
|
|||
wait_for_slave_to_stop;
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||
--replace_column 1 # 9 # 11 # 23 # 33 #
|
||||
show slave status;
|
||||
--query_vertical SHOW SLAVE STATUS
|
||||
|
||||
# try replicate all until second insert to t2;
|
||||
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=746;
|
||||
|
|
@ -50,7 +50,7 @@ wait_for_slave_to_stop;
|
|||
select * from t2;
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||
--replace_column 1 # 9 # 11 # 23 # 33 #
|
||||
show slave status;
|
||||
--query_vertical SHOW SLAVE STATUS
|
||||
|
||||
# clean up
|
||||
start slave;
|
||||
|
|
@ -67,7 +67,7 @@ wait_for_slave_to_stop;
|
|||
# here the sql slave thread should be stopped
|
||||
--replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004
|
||||
--replace_column 1 # 9 # 23 # 33 #
|
||||
show slave status;
|
||||
--query_vertical SHOW SLAVE STATUS
|
||||
|
||||
#testing various error conditions
|
||||
--error 1277
|
||||
|
|
|
|||
|
|
@ -5773,6 +5773,76 @@ select routine_name,routine_schema from information_schema.routines where
|
|||
routine_schema like 'bug18344%'|
|
||||
|
||||
|
||||
#
|
||||
# BUG#12472/BUG#15137 'CREATE TABLE ... SELECT ... which explicitly or
|
||||
# implicitly uses stored function gives "Table not locked" error'.
|
||||
#
|
||||
--disable_warnings
|
||||
drop function if exists bug12472|
|
||||
--enable_warnings
|
||||
create function bug12472() returns int return (select count(*) from t1)|
|
||||
# Check case when function is used directly
|
||||
create table t3 as select bug12472() as i|
|
||||
show create table t3|
|
||||
select * from t3|
|
||||
drop table t3|
|
||||
# Check case when function is used indirectly through view
|
||||
create view v1 as select bug12472() as j|
|
||||
create table t3 as select * from v1|
|
||||
show create table t3|
|
||||
select * from t3|
|
||||
drop table t3|
|
||||
drop view v1|
|
||||
drop function bug12472|
|
||||
|
||||
|
||||
#
|
||||
# BUG#18587: Function that accepts and returns TEXT garbles data if longer than
|
||||
# 766 chars
|
||||
#
|
||||
|
||||
# Prepare.
|
||||
|
||||
--disable_warnings
|
||||
DROP FUNCTION IF EXISTS bug18589_f1|
|
||||
DROP PROCEDURE IF EXISTS bug18589_p1|
|
||||
DROP PROCEDURE IF EXISTS bug18589_p2|
|
||||
--enable_warnings
|
||||
|
||||
CREATE FUNCTION bug18589_f1(arg TEXT) RETURNS TEXT
|
||||
BEGIN
|
||||
RETURN CONCAT(arg, "");
|
||||
END|
|
||||
|
||||
CREATE PROCEDURE bug18589_p1(arg TEXT, OUT ret TEXT)
|
||||
BEGIN
|
||||
SET ret = CONCAT(arg, "");
|
||||
END|
|
||||
|
||||
CREATE PROCEDURE bug18589_p2(arg TEXT)
|
||||
BEGIN
|
||||
DECLARE v TEXT;
|
||||
CALL bug18589_p1(arg, v);
|
||||
SELECT v;
|
||||
END|
|
||||
|
||||
# Test case.
|
||||
|
||||
SELECT bug18589_f1(REPEAT("a", 767))|
|
||||
|
||||
SET @bug18589_v1 = ""|
|
||||
CALL bug18589_p1(REPEAT("a", 767), @bug18589_v1)|
|
||||
SELECT @bug18589_v1|
|
||||
|
||||
CALL bug18589_p2(REPEAT("a", 767))|
|
||||
|
||||
# Cleanup.
|
||||
|
||||
DROP FUNCTION bug18589_f1|
|
||||
DROP PROCEDURE bug18589_p1|
|
||||
DROP PROCEDURE bug18589_p2|
|
||||
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
|
|
|||
|
|
@ -258,6 +258,9 @@ drop table t1, t2;
|
|||
select @@sql_mode;
|
||||
set sql_mode=2097152;
|
||||
select @@sql_mode;
|
||||
# BUG#14675
|
||||
set sql_mode=4194304;
|
||||
select @@sql_mode;
|
||||
set sql_mode=16384+(65536*4);
|
||||
select @@sql_mode;
|
||||
--error 1231
|
||||
|
|
|
|||
|
|
@ -2085,3 +2085,18 @@ create table t2 (a int, b int);
|
|||
insert into t2 values (2, 1), (1, 0);
|
||||
delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# Bug #7549: Missing error message for invalid view selection with subquery
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
|
||||
--error 1054
|
||||
CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
|
||||
--error 1054
|
||||
CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
|
||||
--error 1054
|
||||
SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
|
||||
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -564,3 +564,176 @@ SELECT @mysqltest_var;
|
|||
DROP USER mysqltest_u1@localhost;
|
||||
|
||||
DROP DATABASE mysqltest_db1;
|
||||
|
||||
|
||||
#
|
||||
# Test for bug #14635 Accept NEW.x as INOUT parameters to stored
|
||||
# procedures from within triggers
|
||||
#
|
||||
# We require UPDATE privilege when NEW.x passed as OUT parameter, and
|
||||
# SELECT and UPDATE when NEW.x passed as INOUT parameter.
|
||||
#
|
||||
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS mysqltest_db1;
|
||||
--enable_warnings
|
||||
|
||||
CREATE DATABASE mysqltest_db1;
|
||||
USE mysqltest_db1;
|
||||
|
||||
CREATE TABLE t1 (i1 INT);
|
||||
CREATE TABLE t2 (i1 INT);
|
||||
|
||||
CREATE USER mysqltest_dfn@localhost;
|
||||
CREATE USER mysqltest_inv@localhost;
|
||||
|
||||
GRANT EXECUTE, CREATE ROUTINE, SUPER ON *.* TO mysqltest_dfn@localhost;
|
||||
GRANT INSERT ON mysqltest_db1.* TO mysqltest_inv@localhost;
|
||||
|
||||
connect (definer,localhost,mysqltest_dfn,,mysqltest_db1);
|
||||
connect (invoker,localhost,mysqltest_inv,,mysqltest_db1);
|
||||
|
||||
connection definer;
|
||||
CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 3;
|
||||
CREATE PROCEDURE p2(INOUT i INT) DETERMINISTIC NO SQL SET i = i * 5;
|
||||
|
||||
# Check that having no privilege won't work.
|
||||
connection definer;
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
|
||||
CALL p2(NEW.i1);
|
||||
|
||||
connection invoker;
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES (7);
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t2 VALUES (11);
|
||||
|
||||
connection definer;
|
||||
DROP TRIGGER t2_bi;
|
||||
DROP TRIGGER t1_bi;
|
||||
|
||||
# Check that having only SELECT privilege is not enough.
|
||||
connection default;
|
||||
GRANT SELECT ON mysqltest_db1.* TO mysqltest_dfn@localhost;
|
||||
|
||||
connection definer;
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
|
||||
CALL p2(NEW.i1);
|
||||
|
||||
connection invoker;
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES (13);
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t2 VALUES (17);
|
||||
|
||||
connection default;
|
||||
REVOKE SELECT ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
|
||||
|
||||
connection definer;
|
||||
DROP TRIGGER t2_bi;
|
||||
DROP TRIGGER t1_bi;
|
||||
|
||||
# Check that having only UPDATE privilege is enough for OUT parameter,
|
||||
# but not for INOUT parameter.
|
||||
connection default;
|
||||
GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
|
||||
|
||||
connection definer;
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
|
||||
CALL p2(NEW.i1);
|
||||
|
||||
connection invoker;
|
||||
INSERT INTO t1 VALUES (19);
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t2 VALUES (23);
|
||||
|
||||
connection default;
|
||||
REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
|
||||
|
||||
connection definer;
|
||||
DROP TRIGGER t2_bi;
|
||||
DROP TRIGGER t1_bi;
|
||||
|
||||
# Check that having SELECT and UPDATE privileges is enough.
|
||||
connection default;
|
||||
GRANT SELECT, UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
|
||||
|
||||
connection definer;
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
|
||||
CALL p2(NEW.i1);
|
||||
|
||||
connection invoker;
|
||||
INSERT INTO t1 VALUES (29);
|
||||
INSERT INTO t2 VALUES (31);
|
||||
|
||||
connection default;
|
||||
REVOKE SELECT, UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
|
||||
|
||||
connection definer;
|
||||
DROP TRIGGER t2_bi;
|
||||
DROP TRIGGER t1_bi;
|
||||
|
||||
connection default;
|
||||
DROP PROCEDURE p2;
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
# Check that late procedure redefining won't open a security hole.
|
||||
connection default;
|
||||
GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
|
||||
|
||||
connection definer;
|
||||
CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 37;
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
|
||||
connection invoker;
|
||||
INSERT INTO t1 VALUES (41);
|
||||
|
||||
connection definer;
|
||||
DROP PROCEDURE p1;
|
||||
CREATE PROCEDURE p1(IN i INT) DETERMINISTIC NO SQL SET @v1 = i + 43;
|
||||
|
||||
connection invoker;
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES (47);
|
||||
|
||||
connection definer;
|
||||
DROP PROCEDURE p1;
|
||||
CREATE PROCEDURE p1(INOUT i INT) DETERMINISTIC NO SQL SET i = i + 51;
|
||||
|
||||
connection invoker;
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES (53);
|
||||
|
||||
connection default;
|
||||
DROP PROCEDURE p1;
|
||||
REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
|
||||
|
||||
connection definer;
|
||||
DROP TRIGGER t1_bi;
|
||||
|
||||
# Cleanup.
|
||||
disconnect definer;
|
||||
disconnect invoker;
|
||||
connection default;
|
||||
DROP USER mysqltest_inv@localhost;
|
||||
DROP USER mysqltest_dfn@localhost;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
DROP DATABASE mysqltest_db1;
|
||||
USE test;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
|
|
|||
|
|
@ -1165,4 +1165,126 @@ SELECT * FROM t1 WHERE conn_id != trigger_conn_id;
|
|||
DROP TRIGGER t1_bi;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
#
|
||||
# Bug#6951: Triggers/Traditional: SET @ result wrong
|
||||
#
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (i1 INT);
|
||||
|
||||
SET @save_sql_mode=@@sql_mode;
|
||||
|
||||
SET SQL_MODE='';
|
||||
|
||||
CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
|
||||
SET @x = 5/0;
|
||||
|
||||
SET SQL_MODE='traditional';
|
||||
|
||||
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
|
||||
SET @x = 5/0;
|
||||
|
||||
SET @x=1;
|
||||
INSERT INTO t1 VALUES (@x);
|
||||
SELECT @x;
|
||||
|
||||
SET @x=2;
|
||||
--error 1365
|
||||
UPDATE t1 SET i1 = @x;
|
||||
SELECT @x;
|
||||
|
||||
SET SQL_MODE='';
|
||||
|
||||
SET @x=3;
|
||||
INSERT INTO t1 VALUES (@x);
|
||||
SELECT @x;
|
||||
|
||||
SET @x=4;
|
||||
--error 1365
|
||||
UPDATE t1 SET i1 = @x;
|
||||
SELECT @x;
|
||||
|
||||
SET @@sql_mode=@save_sql_mode;
|
||||
|
||||
DROP TRIGGER t1_ai;
|
||||
DROP TRIGGER t1_au;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
#
|
||||
# Test for bug #14635 Accept NEW.x as INOUT parameters to stored
|
||||
# procedures from within triggers
|
||||
#
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
DROP PROCEDURE IF EXISTS p2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (i1 INT);
|
||||
|
||||
# Check that NEW.x pseudo variable is accepted as INOUT and OUT
|
||||
# parameter to stored routine.
|
||||
INSERT INTO t1 VALUES (3);
|
||||
CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET i1 = 5;
|
||||
CREATE PROCEDURE p2(INOUT i1 INT) DETERMINISTIC NO SQL SET i1 = i1 * 7;
|
||||
delimiter //;
|
||||
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
|
||||
BEGIN
|
||||
CALL p1(NEW.i1);
|
||||
CALL p2(NEW.i1);
|
||||
END//
|
||||
delimiter ;//
|
||||
UPDATE t1 SET i1 = 11 WHERE i1 = 3;
|
||||
DROP TRIGGER t1_bu;
|
||||
DROP PROCEDURE p2;
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
# Check that OLD.x pseudo variable is not accepted as INOUT and OUT
|
||||
# parameter to stored routine.
|
||||
INSERT INTO t1 VALUES (13);
|
||||
CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 17;
|
||||
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
|
||||
CALL p1(OLD.i1);
|
||||
--error ER_SP_NOT_VAR_ARG
|
||||
UPDATE t1 SET i1 = 19 WHERE i1 = 13;
|
||||
DROP TRIGGER t1_bu;
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
INSERT INTO t1 VALUES (23);
|
||||
CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 29;
|
||||
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
|
||||
CALL p1(OLD.i1);
|
||||
--error ER_SP_NOT_VAR_ARG
|
||||
UPDATE t1 SET i1 = 31 WHERE i1 = 23;
|
||||
DROP TRIGGER t1_bu;
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
# Check that NEW.x pseudo variable is read-only in the AFTER TRIGGER.
|
||||
INSERT INTO t1 VALUES (37);
|
||||
CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 41;
|
||||
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
--error ER_SP_NOT_VAR_ARG
|
||||
UPDATE t1 SET i1 = 43 WHERE i1 = 37;
|
||||
DROP TRIGGER t1_au;
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
INSERT INTO t1 VALUES (47);
|
||||
CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 49;
|
||||
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
|
||||
CALL p1(NEW.i1);
|
||||
--error ER_SP_NOT_VAR_ARG
|
||||
UPDATE t1 SET i1 = 51 WHERE i1 = 47;
|
||||
DROP TRIGGER t1_au;
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
# Post requisite.
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
# End of 5.0 tests
|
||||
|
|
|
|||
|
|
@ -2512,3 +2512,19 @@ create view v2 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from v1;
|
|||
select * from v2;
|
||||
drop view v1, v2;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #19490: usage of view specified by a query with GROUP BY
|
||||
# an expression containing non-constant interval
|
||||
|
||||
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, d datetime);
|
||||
|
||||
CREATE VIEW v1 AS
|
||||
SELECT id, date(d) + INTERVAL TIME_TO_SEC(d) SECOND AS t, COUNT(*)
|
||||
FROM t1 GROUP BY id, t;
|
||||
|
||||
SHOW CREATE VIEW v1;
|
||||
SELECT * FROM v1;
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -35,12 +35,12 @@
|
|||
#endif
|
||||
|
||||
|
||||
static int create_pid_file(const char *pid_file_name)
|
||||
int create_pid_file(const char *pid_file_name, int pid)
|
||||
{
|
||||
if (FILE *pid_file= my_fopen(pid_file_name,
|
||||
O_WRONLY | O_CREAT | O_BINARY, MYF(0)))
|
||||
{
|
||||
fprintf(pid_file, "%d\n", (int) getpid());
|
||||
fprintf(pid_file, "%d\n", (int) pid);
|
||||
my_fclose(pid_file, MYF(0));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -138,8 +138,13 @@ void manager(const Options &options)
|
|||
if (user_map.load(options.password_file_name))
|
||||
return;
|
||||
|
||||
/* write pid file */
|
||||
if (create_pid_file(options.pid_file_name))
|
||||
/* write Instance Manager pid file */
|
||||
|
||||
log_info("IM pid file: '%s'; PID: %d.",
|
||||
(const char *) options.pid_file_name,
|
||||
(int) manager_pid);
|
||||
|
||||
if (create_pid_file(options.pid_file_name, manager_pid))
|
||||
return;
|
||||
|
||||
sigset_t mask;
|
||||
|
|
|
|||
|
|
@ -20,4 +20,6 @@ struct Options;
|
|||
|
||||
void manager(const Options &options);
|
||||
|
||||
int create_pid_file(const char *pid_file_name, int pid);
|
||||
|
||||
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MANAGER_H
|
||||
|
|
|
|||
|
|
@ -338,6 +338,14 @@ spawn:
|
|||
/* Here we return to main, and fall into manager */
|
||||
break;
|
||||
default: // parent, success
|
||||
pid= getpid(); /* Get our pid. */
|
||||
|
||||
log_info("Angel pid file: '%s'; PID: %d.",
|
||||
(const char *) options.angel_pid_file_name,
|
||||
(int) pid);
|
||||
|
||||
create_pid_file(Options::angel_pid_file_name, pid);
|
||||
|
||||
while (child_status == CHILD_OK && is_terminated == 0)
|
||||
sigsuspend(&zeromask);
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ const char *Options::user= 0; /* No default value */
|
|||
const char *default_password_file_name= QUOTE(DEFAULT_PASSWORD_FILE_NAME);
|
||||
const char *default_log_file_name= QUOTE(DEFAULT_LOG_FILE_NAME);
|
||||
const char *Options::config_file= QUOTE(DEFAULT_CONFIG_FILE);
|
||||
const char *Options::angel_pid_file_name= NULL;
|
||||
#endif
|
||||
const char *Options::log_file_name= default_log_file_name;
|
||||
const char *Options::pid_file_name= QUOTE(DEFAULT_PID_FILE_NAME);
|
||||
|
|
@ -58,6 +59,9 @@ char **Options::saved_argv= NULL;
|
|||
/* Remember if the config file was forced */
|
||||
bool Options::is_forced_default_file= 0;
|
||||
|
||||
static const char * const ANGEL_PID_FILE_SUFFIX= ".angel.pid";
|
||||
static const int ANGEL_PID_FILE_SUFFIX_LEN= strlen(ANGEL_PID_FILE_SUFFIX);
|
||||
|
||||
/*
|
||||
List of options, accepted by the instance manager.
|
||||
List must be closed with empty option.
|
||||
|
|
@ -72,6 +76,7 @@ enum options {
|
|||
#ifndef __WIN__
|
||||
OPT_RUN_AS_SERVICE,
|
||||
OPT_USER,
|
||||
OPT_ANGEL_PID_FILE,
|
||||
#else
|
||||
OPT_INSTALL_SERVICE,
|
||||
OPT_REMOVE_SERVICE,
|
||||
|
|
@ -94,7 +99,14 @@ static struct my_option my_long_options[] =
|
|||
|
||||
{ "pid-file", OPT_PID_FILE, "Pid file to use.",
|
||||
(gptr *) &Options::pid_file_name, (gptr *) &Options::pid_file_name,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
|
||||
#ifndef __WIN__
|
||||
{ "angel-pid-file", OPT_ANGEL_PID_FILE, "Pid file for angel process.",
|
||||
(gptr *) &Options::angel_pid_file_name,
|
||||
(gptr *) &Options::angel_pid_file_name,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
#endif
|
||||
|
||||
{ "socket", OPT_SOCKET, "Socket file to use for connection.",
|
||||
(gptr *) &Options::socket_file_name, (gptr *) &Options::socket_file_name,
|
||||
|
|
@ -290,6 +302,46 @@ int Options::load(int argc, char **argv)
|
|||
get_one_option)) != 0)
|
||||
goto err;
|
||||
|
||||
#ifndef __WIN__
|
||||
if (Options::run_as_service)
|
||||
{
|
||||
if (Options::angel_pid_file_name == NULL)
|
||||
{
|
||||
/*
|
||||
Calculate angel pid file on the IM pid file basis: replace the
|
||||
extension (everything after the last dot) of the pid file basename to
|
||||
'.angel.pid'.
|
||||
*/
|
||||
|
||||
char *angel_pid_file_name;
|
||||
char *base_name_ptr;
|
||||
char *ext_ptr;
|
||||
|
||||
angel_pid_file_name= (char *) malloc(strlen(Options::pid_file_name) +
|
||||
ANGEL_PID_FILE_SUFFIX_LEN);
|
||||
|
||||
strcpy(angel_pid_file_name, Options::pid_file_name);
|
||||
|
||||
base_name_ptr= strrchr(angel_pid_file_name, '/');
|
||||
|
||||
if (!base_name_ptr)
|
||||
base_name_ptr= angel_pid_file_name + 1;
|
||||
|
||||
ext_ptr= strrchr(base_name_ptr, '.');
|
||||
if (ext_ptr)
|
||||
*ext_ptr= 0;
|
||||
|
||||
strcat(angel_pid_file_name, ANGEL_PID_FILE_SUFFIX);
|
||||
|
||||
Options::angel_pid_file_name= angel_pid_file_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
Options::angel_pid_file_name= strdup(Options::angel_pid_file_name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
|
@ -301,6 +353,11 @@ void Options::cleanup()
|
|||
/* free_defaults returns nothing */
|
||||
if (Options::saved_argv != NULL)
|
||||
free_defaults(Options::saved_argv);
|
||||
|
||||
#ifndef __WIN__
|
||||
if (Options::run_as_service)
|
||||
free((void *) Options::angel_pid_file_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __WIN__
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ struct Options
|
|||
#else
|
||||
static char run_as_service; /* handle_options doesn't support bool */
|
||||
static const char *user;
|
||||
static const char *angel_pid_file_name;
|
||||
#endif
|
||||
static bool is_forced_default_file;
|
||||
static const char *log_file_name;
|
||||
|
|
|
|||
|
|
@ -642,7 +642,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
|
|||
|
||||
void field_conv(Field *to,Field *from)
|
||||
{
|
||||
if (to->real_type() == from->real_type())
|
||||
if (to->real_type() == from->real_type() &&
|
||||
!(to->type() == FIELD_TYPE_BLOB && to->table->copy_blobs))
|
||||
{
|
||||
if (to->pack_length() == from->pack_length() &&
|
||||
!(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) &&
|
||||
|
|
|
|||
|
|
@ -4048,6 +4048,9 @@ ha_innobase::index_prev(
|
|||
mysql_byte* buf) /* in/out: buffer for previous row in MySQL
|
||||
format */
|
||||
{
|
||||
statistic_increment(current_thd->status_var.ha_read_prev_count,
|
||||
&LOCK_status);
|
||||
|
||||
return(general_fetch(buf, ROW_SEL_PREV, 0));
|
||||
}
|
||||
|
||||
|
|
|
|||
35
sql/item.cc
35
sql/item.cc
|
|
@ -958,6 +958,12 @@ void Item_splocal::print(String *str)
|
|||
}
|
||||
|
||||
|
||||
bool Item_splocal::set_value(THD *thd, sp_rcontext *ctx, Item **it)
|
||||
{
|
||||
return ctx->set_variable(thd, get_var_idx(), it);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
Item_case_expr methods
|
||||
*****************************************************************************/
|
||||
|
|
@ -1883,7 +1889,6 @@ Item_decimal::Item_decimal(const char *str_arg, uint length,
|
|||
name= (char*) str_arg;
|
||||
decimals= (uint8) decimal_value.frac;
|
||||
fixed= 1;
|
||||
unsigned_flag= !decimal_value.sign();
|
||||
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
|
||||
decimals, unsigned_flag);
|
||||
}
|
||||
|
|
@ -1893,7 +1898,6 @@ Item_decimal::Item_decimal(longlong val, bool unsig)
|
|||
int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value);
|
||||
decimals= (uint8) decimal_value.frac;
|
||||
fixed= 1;
|
||||
unsigned_flag= !decimal_value.sign();
|
||||
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
|
||||
decimals, unsigned_flag);
|
||||
}
|
||||
|
|
@ -1904,7 +1908,6 @@ Item_decimal::Item_decimal(double val, int precision, int scale)
|
|||
double2my_decimal(E_DEC_FATAL_ERROR, val, &decimal_value);
|
||||
decimals= (uint8) decimal_value.frac;
|
||||
fixed= 1;
|
||||
unsigned_flag= !decimal_value.sign();
|
||||
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
|
||||
decimals, unsigned_flag);
|
||||
}
|
||||
|
|
@ -1917,7 +1920,6 @@ Item_decimal::Item_decimal(const char *str, const my_decimal *val_arg,
|
|||
name= (char*) str;
|
||||
decimals= (uint8) decimal_par;
|
||||
max_length= length;
|
||||
unsigned_flag= !decimal_value.sign();
|
||||
fixed= 1;
|
||||
}
|
||||
|
||||
|
|
@ -1927,7 +1929,6 @@ Item_decimal::Item_decimal(my_decimal *value_par)
|
|||
my_decimal2decimal(value_par, &decimal_value);
|
||||
decimals= (uint8) decimal_value.frac;
|
||||
fixed= 1;
|
||||
unsigned_flag= !decimal_value.sign();
|
||||
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
|
||||
decimals, unsigned_flag);
|
||||
}
|
||||
|
|
@ -1939,7 +1940,6 @@ Item_decimal::Item_decimal(const char *bin, int precision, int scale)
|
|||
&decimal_value, precision, scale);
|
||||
decimals= (uint8) decimal_value.frac;
|
||||
fixed= 1;
|
||||
unsigned_flag= !decimal_value.sign();
|
||||
max_length= my_decimal_precision_to_length(precision, decimals,
|
||||
unsigned_flag);
|
||||
}
|
||||
|
|
@ -5365,6 +5365,25 @@ bool Item_trigger_field::eq(const Item *item, bool binary_cmp) const
|
|||
}
|
||||
|
||||
|
||||
void Item_trigger_field::set_required_privilege(const bool rw)
|
||||
{
|
||||
/*
|
||||
Require SELECT and UPDATE privilege if this field will be read and
|
||||
set, and only UPDATE privilege for setting the field.
|
||||
*/
|
||||
want_privilege= (rw ? SELECT_ACL | UPDATE_ACL : UPDATE_ACL);
|
||||
}
|
||||
|
||||
|
||||
bool Item_trigger_field::set_value(THD *thd, sp_rcontext */*ctx*/, Item **it)
|
||||
{
|
||||
Item *item= sp_prepare_func_item(thd, it);
|
||||
|
||||
return (!item || (!fixed && fix_fields(thd, 0)) ||
|
||||
(item->save_in_field(field, 0) < 0));
|
||||
}
|
||||
|
||||
|
||||
bool Item_trigger_field::fix_fields(THD *thd, Item **items)
|
||||
{
|
||||
/*
|
||||
|
|
@ -5387,8 +5406,7 @@ bool Item_trigger_field::fix_fields(THD *thd, Item **items)
|
|||
|
||||
if (table_grants)
|
||||
{
|
||||
table_grants->want_privilege=
|
||||
access_type == AT_READ ? SELECT_ACL : UPDATE_ACL;
|
||||
table_grants->want_privilege= want_privilege;
|
||||
|
||||
if (check_grant_column(thd, table_grants, triggers->table->s->db,
|
||||
triggers->table->s->table_name, field_name,
|
||||
|
|
@ -5420,6 +5438,7 @@ void Item_trigger_field::print(String *str)
|
|||
|
||||
void Item_trigger_field::cleanup()
|
||||
{
|
||||
want_privilege= original_privilege;
|
||||
/*
|
||||
Since special nature of Item_trigger_field we should not do most of
|
||||
things from Item_field::cleanup() or Item_ident::cleanup() here.
|
||||
|
|
|
|||
101
sql/item.h
101
sql/item.h
|
|
@ -372,6 +372,42 @@ public:
|
|||
|
||||
/*************************************************************************/
|
||||
|
||||
class sp_rcontext;
|
||||
|
||||
|
||||
class Settable_routine_parameter
|
||||
{
|
||||
public:
|
||||
/*
|
||||
Set required privileges for accessing the parameter.
|
||||
|
||||
SYNOPSIS
|
||||
set_required_privilege()
|
||||
rw if 'rw' is true then we are going to read and set the
|
||||
parameter, so SELECT and UPDATE privileges might be
|
||||
required, otherwise we only reading it and SELECT
|
||||
privilege might be required.
|
||||
*/
|
||||
virtual void set_required_privilege(bool rw) {};
|
||||
|
||||
/*
|
||||
Set parameter value.
|
||||
|
||||
SYNOPSIS
|
||||
set_value()
|
||||
thd thread handle
|
||||
ctx context to which parameter belongs (if it is local
|
||||
variable).
|
||||
it item which represents new value
|
||||
|
||||
RETURN
|
||||
FALSE if parameter value has been set,
|
||||
TRUE if error has occured.
|
||||
*/
|
||||
virtual bool set_value(THD *thd, sp_rcontext *ctx, Item **it)= 0;
|
||||
};
|
||||
|
||||
|
||||
typedef bool (Item::*Item_processor)(byte *arg);
|
||||
typedef Item* (Item::*Item_transformer) (byte *arg);
|
||||
typedef void (*Cond_traverser) (const Item *item, void *arg);
|
||||
|
|
@ -744,6 +780,15 @@ public:
|
|||
}
|
||||
|
||||
virtual bool is_splocal() { return 0; } /* Needed for error checking */
|
||||
|
||||
/*
|
||||
Return Settable_routine_parameter interface of the Item. Return 0
|
||||
if this Item is not Settable_routine_parameter.
|
||||
*/
|
||||
virtual Settable_routine_parameter *get_settable_routine_parameter()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -842,7 +887,8 @@ inline bool Item_sp_variable::send(Protocol *protocol, String *str)
|
|||
runtime.
|
||||
*****************************************************************************/
|
||||
|
||||
class Item_splocal :public Item_sp_variable
|
||||
class Item_splocal :public Item_sp_variable,
|
||||
private Settable_routine_parameter
|
||||
{
|
||||
uint m_var_idx;
|
||||
|
||||
|
|
@ -880,6 +926,15 @@ public:
|
|||
|
||||
inline enum Type type() const;
|
||||
inline Item_result result_type() const;
|
||||
|
||||
private:
|
||||
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
||||
|
||||
public:
|
||||
Settable_routine_parameter *get_settable_routine_parameter()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
@ -2100,14 +2155,13 @@ class Table_triggers_list;
|
|||
two Field instances representing either OLD or NEW version of this
|
||||
field.
|
||||
*/
|
||||
class Item_trigger_field : public Item_field
|
||||
class Item_trigger_field : public Item_field,
|
||||
private Settable_routine_parameter
|
||||
{
|
||||
public:
|
||||
/* Is this item represents row from NEW or OLD row ? */
|
||||
enum row_version_type {OLD_ROW, NEW_ROW};
|
||||
row_version_type row_version;
|
||||
/* Is this item used for reading or updating the value? */
|
||||
enum access_types { AT_READ = 0x1, AT_UPDATE = 0x2 };
|
||||
/* Next in list of all Item_trigger_field's in trigger */
|
||||
Item_trigger_field *next_trg_field;
|
||||
/* Index of the field in the TABLE::field array */
|
||||
|
|
@ -2118,11 +2172,11 @@ public:
|
|||
Item_trigger_field(Name_resolution_context *context_arg,
|
||||
row_version_type row_ver_arg,
|
||||
const char *field_name_arg,
|
||||
access_types access_type_arg)
|
||||
ulong priv, const bool ro)
|
||||
:Item_field(context_arg,
|
||||
(const char *)NULL, (const char *)NULL, field_name_arg),
|
||||
row_version(row_ver_arg), field_idx((uint)-1),
|
||||
access_type(access_type_arg), table_grants(NULL)
|
||||
row_version(row_ver_arg), field_idx((uint)-1), original_privilege(priv),
|
||||
want_privilege(priv), table_grants(NULL), read_only (ro)
|
||||
{}
|
||||
void setup_field(THD *thd, TABLE *table, GRANT_INFO *table_grant_info);
|
||||
enum Type type() const { return TRIGGER_FIELD_ITEM; }
|
||||
|
|
@ -2133,8 +2187,39 @@ public:
|
|||
void cleanup();
|
||||
|
||||
private:
|
||||
access_types access_type;
|
||||
void set_required_privilege(const bool rw);
|
||||
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
||||
|
||||
public:
|
||||
Settable_routine_parameter *get_settable_routine_parameter()
|
||||
{
|
||||
return (read_only ? 0 : this);
|
||||
}
|
||||
|
||||
bool set_value(THD *thd, Item **it)
|
||||
{
|
||||
return set_value(thd, NULL, it);
|
||||
}
|
||||
|
||||
private:
|
||||
/*
|
||||
'want_privilege' holds privileges required to perform operation on
|
||||
this trigger field (SELECT_ACL if we are going to read it and
|
||||
UPDATE_ACL if we are going to update it). It is initialized at
|
||||
parse time but can be updated later if this trigger field is used
|
||||
as OUT or INOUT parameter of stored routine (in this case
|
||||
set_required_privilege() is called to appropriately update
|
||||
want_privilege and cleanup() is responsible for restoring of
|
||||
original want_privilege once parameter's value is updated).
|
||||
*/
|
||||
ulong original_privilege;
|
||||
ulong want_privilege;
|
||||
GRANT_INFO *table_grants;
|
||||
/*
|
||||
Trigger field is read-only unless it belongs to the NEW row in a
|
||||
BEFORE INSERT of BEFORE UPDATE trigger.
|
||||
*/
|
||||
bool read_only;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4120,6 +4120,18 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
|
|||
}
|
||||
|
||||
|
||||
bool Item_func_get_user_var::set_value(THD *thd,
|
||||
sp_rcontext */*ctx*/, Item **it)
|
||||
{
|
||||
Item_func_set_user_var *suv= new Item_func_set_user_var(get_name(), *it);
|
||||
/*
|
||||
Item_func_set_user_var is not fixed after construction, call
|
||||
fix_fields().
|
||||
*/
|
||||
return (!suv || suv->fix_fields(thd, it) || suv->check() || suv->update());
|
||||
}
|
||||
|
||||
|
||||
bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
|
|
@ -4752,6 +4764,7 @@ Item_func_sp::sp_result_field(void) const
|
|||
dummy_table->alias = empty_name;
|
||||
dummy_table->maybe_null = maybe_null;
|
||||
dummy_table->in_use= current_thd;
|
||||
dummy_table->copy_blobs= TRUE;
|
||||
share->table_cache_key = empty_name;
|
||||
share->table_name = empty_name;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1179,7 +1179,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class Item_func_get_user_var :public Item_func
|
||||
class Item_func_get_user_var :public Item_func,
|
||||
private Settable_routine_parameter
|
||||
{
|
||||
user_var_entry *var_entry;
|
||||
|
||||
|
|
@ -1206,6 +1207,15 @@ public:
|
|||
table_map used_tables() const
|
||||
{ return const_item() ? 0 : RAND_TABLE_BIT; }
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
|
||||
private:
|
||||
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
||||
|
||||
public:
|
||||
Settable_routine_parameter *get_settable_routine_parameter()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1351,6 +1351,17 @@ void Item_in_subselect::print(String *str)
|
|||
}
|
||||
|
||||
|
||||
bool Item_in_subselect::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
bool result = 0;
|
||||
|
||||
if(thd->lex->view_prepare_mode && left_expr && !left_expr->fixed)
|
||||
result = left_expr->fix_fields(thd, &left_expr);
|
||||
|
||||
return result || Item_subselect::fix_fields(thd, ref);
|
||||
}
|
||||
|
||||
|
||||
Item_subselect::trans_res
|
||||
Item_allany_subselect::select_transformer(JOIN *join)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -258,6 +258,7 @@ public:
|
|||
void top_level_item() { abort_on_null=1; }
|
||||
bool test_limit(st_select_lex_unit *unit);
|
||||
void print(String *str);
|
||||
bool fix_fields(THD *thd, Item **ref);
|
||||
|
||||
friend class Item_ref_null_helper;
|
||||
friend class Item_is_not_null_test;
|
||||
|
|
|
|||
|
|
@ -2144,8 +2144,13 @@ bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
|
|||
Item_date_add_interval *other= (Item_date_add_interval*) item;
|
||||
|
||||
if ((int_type != other->int_type) ||
|
||||
(!args[0]->eq(other->args[0], binary_cmp)) ||
|
||||
(get_interval_value(args[1], int_type, &val, &interval)))
|
||||
(!args[0]->eq(other->args[0], binary_cmp)))
|
||||
return FALSE;
|
||||
|
||||
if (!args[1]->const_item() || !other->args[1]->const_item())
|
||||
return (args[1]->eq(other->args[1], binary_cmp));
|
||||
|
||||
if (get_interval_value(args[1], int_type, &val, &interval))
|
||||
return FALSE;
|
||||
|
||||
val= other->value;
|
||||
|
|
|
|||
|
|
@ -718,12 +718,6 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||
List<create_field> &fields, List<Key> &keys,
|
||||
bool tmp_table, uint select_field_count);
|
||||
|
||||
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
||||
TABLE_LIST *create_table,
|
||||
List<create_field> *extra_fields,
|
||||
List<Key> *keys,
|
||||
List<Item> *items,
|
||||
MYSQL_LOCK **lock);
|
||||
bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
|
||||
HA_CREATE_INFO *create_info,
|
||||
TABLE_LIST *table_list,
|
||||
|
|
@ -1315,10 +1309,11 @@ extern struct st_VioSSLFd * ssl_acceptor_fd;
|
|||
|
||||
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
|
||||
uint flags, bool *need_reopen);
|
||||
/* mysql_lock_tables() flags bits */
|
||||
/* mysql_lock_tables() and open_table() flags bits */
|
||||
#define MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK 0x0001
|
||||
#define MYSQL_LOCK_IGNORE_FLUSH 0x0002
|
||||
#define MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN 0x0004
|
||||
#define MYSQL_OPEN_IGNORE_LOCKED_TABLES 0x0008
|
||||
|
||||
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
|
||||
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
|
||||
|
|
@ -1582,6 +1577,16 @@ inline int hexchar_to_int(char c)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
is_user_table()
|
||||
return true if the table was created explicitly
|
||||
*/
|
||||
|
||||
inline bool is_user_table(TABLE * table)
|
||||
{
|
||||
const char *name= table->s->table_name;
|
||||
return strncmp(name, tmp_file_prefix, tmp_file_prefix_length);
|
||||
}
|
||||
|
||||
/*
|
||||
Some functions that are different in the embedded library and the normal
|
||||
|
|
|
|||
|
|
@ -5475,7 +5475,7 @@ ER_SP_DUP_HANDLER 42000
|
|||
eng "Duplicate handler declared in the same block"
|
||||
ger "Doppelter Handler im selben Block deklariert"
|
||||
ER_SP_NOT_VAR_ARG 42000
|
||||
eng "OUT or INOUT argument %d for routine %s is not a variable"
|
||||
eng "OUT or INOUT argument %d for routine %s is not a variable or NEW pseudo-variable in BEFORE trigger"
|
||||
ger "OUT- oder INOUT-Argument %d für Routine %s ist keine Variable"
|
||||
ER_SP_NO_RETSET 0A000
|
||||
eng "Not allowed to return a result set from a %s"
|
||||
|
|
|
|||
243
sql/sp_head.cc
243
sql/sp_head.cc
|
|
@ -310,11 +310,13 @@ sp_prepare_func_item(THD* thd, Item **it_addr)
|
|||
*/
|
||||
|
||||
bool
|
||||
sp_eval_expr(THD *thd, Field *result_field, Item *expr_item)
|
||||
sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
|
||||
{
|
||||
Item *expr_item;
|
||||
|
||||
DBUG_ENTER("sp_eval_expr");
|
||||
|
||||
if (!(expr_item= sp_prepare_func_item(thd, &expr_item)))
|
||||
if (!(expr_item= sp_prepare_func_item(thd, expr_item_ptr)))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
bool err_status= FALSE;
|
||||
|
|
@ -936,6 +938,7 @@ sp_head::execute(THD *thd)
|
|||
bool err_status= FALSE;
|
||||
uint ip= 0;
|
||||
ulong save_sql_mode;
|
||||
bool save_abort_on_warning;
|
||||
Query_arena *old_arena;
|
||||
/* per-instruction arena */
|
||||
MEM_ROOT execute_mem_root;
|
||||
|
|
@ -996,6 +999,10 @@ sp_head::execute(THD *thd)
|
|||
thd->derived_tables= 0;
|
||||
save_sql_mode= thd->variables.sql_mode;
|
||||
thd->variables.sql_mode= m_sql_mode;
|
||||
save_abort_on_warning= thd->abort_on_warning;
|
||||
thd->abort_on_warning=
|
||||
(m_sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
|
||||
|
||||
/*
|
||||
It is also more efficient to save/restore current thd->lex once when
|
||||
do it in each instruction
|
||||
|
|
@ -1128,6 +1135,7 @@ sp_head::execute(THD *thd)
|
|||
DBUG_ASSERT(!thd->derived_tables);
|
||||
thd->derived_tables= old_derived_tables;
|
||||
thd->variables.sql_mode= save_sql_mode;
|
||||
thd->abort_on_warning= save_abort_on_warning;
|
||||
|
||||
thd->stmt_arena= old_arena;
|
||||
state= EXECUTED;
|
||||
|
|
@ -1204,130 +1212,144 @@ bool
|
|||
sp_head::execute_function(THD *thd, Item **argp, uint argcount,
|
||||
Field *return_value_fld)
|
||||
{
|
||||
Item_cache **param_values;
|
||||
ulonglong binlog_save_options;
|
||||
bool need_binlog_call;
|
||||
uint params;
|
||||
uint arg_no;
|
||||
sp_rcontext *octx = thd->spcont;
|
||||
sp_rcontext *nctx = NULL;
|
||||
char buf[STRING_BUFFER_USUAL_SIZE];
|
||||
String binlog_buf(buf, sizeof(buf), &my_charset_bin);
|
||||
bool err_status= FALSE;
|
||||
MEM_ROOT call_mem_root;
|
||||
Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP);
|
||||
Query_arena backup_arena;
|
||||
|
||||
DBUG_ENTER("sp_head::execute_function");
|
||||
DBUG_PRINT("info", ("function %s", m_name.str));
|
||||
|
||||
params = m_pcont->context_var_count();
|
||||
|
||||
/*
|
||||
Check that the function is called with all specified arguments.
|
||||
|
||||
If it is not, use my_error() to report an error, or it will not terminate
|
||||
the invoking query properly.
|
||||
*/
|
||||
|
||||
if (argcount != params)
|
||||
if (argcount != m_pcont->context_var_count())
|
||||
{
|
||||
/*
|
||||
Need to use my_error here, or it will not terminate the
|
||||
invoking query properly.
|
||||
*/
|
||||
my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0),
|
||||
"FUNCTION", m_qname.str, params, argcount);
|
||||
"FUNCTION", m_qname.str, m_pcont->context_var_count(), argcount);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/* Allocate param_values to be used for dumping the call into binlog. */
|
||||
|
||||
if (!(param_values= (Item_cache**)thd->alloc(sizeof(Item_cache*)*argcount)))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
// QQ Should have some error checking here? (types, etc...)
|
||||
/*
|
||||
Prepare arena and memroot for objects which lifetime is whole
|
||||
duration of function call (sp_rcontext, it's tables and items,
|
||||
sp_cursor and Item_cache holders for case expressions).
|
||||
We can't use caller's arena/memroot for those objects because
|
||||
in this case some fixed amount of memory will be consumed for
|
||||
each function/trigger invocation and so statements which involve
|
||||
lot of them will hog memory.
|
||||
TODO: we should create sp_rcontext once per command and reuse
|
||||
it on subsequent executions of a function/trigger.
|
||||
*/
|
||||
init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
|
||||
thd->set_n_backup_active_arena(&call_arena, &backup_arena);
|
||||
|
||||
if (!(nctx= new sp_rcontext(m_pcont, return_value_fld, octx)) ||
|
||||
nctx->init(thd))
|
||||
{
|
||||
delete nctx; /* Delete nctx if it was init() that failed. */
|
||||
DBUG_RETURN(TRUE);
|
||||
thd->restore_active_arena(&call_arena, &backup_arena);
|
||||
err_status= TRUE;
|
||||
goto err_with_cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
We have to switch temporarily back to callers arena/memroot.
|
||||
Function arguments belong to the caller and so the may reference
|
||||
memory which they will allocate during calculation long after
|
||||
this function call will be finished (e.g. in Item::cleanup()).
|
||||
*/
|
||||
thd->restore_active_arena(&call_arena, &backup_arena);
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
nctx->sp= this;
|
||||
#endif
|
||||
|
||||
/* Pass arguments. */
|
||||
|
||||
for (arg_no= 0; arg_no < argcount; arg_no++)
|
||||
{
|
||||
uint i;
|
||||
|
||||
for (i= 0 ; i < argcount ; i++)
|
||||
/* Arguments must be fixed in Item_func_sp::fix_fields */
|
||||
DBUG_ASSERT(argp[arg_no]->fixed);
|
||||
|
||||
if ((err_status= nctx->set_variable(thd, arg_no, &(argp[arg_no]))))
|
||||
goto err_with_cleanup;
|
||||
}
|
||||
|
||||
need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
|
||||
|
||||
/*
|
||||
Remember the original arguments for unrolled replication of functions
|
||||
before they are changed by execution.
|
||||
*/
|
||||
if (need_binlog_call)
|
||||
{
|
||||
binlog_buf.length(0);
|
||||
binlog_buf.append(STRING_WITH_LEN("SELECT "));
|
||||
append_identifier(thd, &binlog_buf, m_name.str, m_name.length);
|
||||
binlog_buf.append('(');
|
||||
for (arg_no= 0; arg_no < argcount; arg_no++)
|
||||
{
|
||||
if (!argp[i]->fixed && argp[i]->fix_fields(thd, &argp[i]))
|
||||
{
|
||||
err_status= TRUE;
|
||||
break;
|
||||
}
|
||||
String str_value_holder;
|
||||
String *str_value;
|
||||
|
||||
param_values[i]= Item_cache::get_cache(argp[i]->result_type());
|
||||
param_values[i]->store(argp[i]);
|
||||
if (arg_no)
|
||||
binlog_buf.append(',');
|
||||
|
||||
if (nctx->set_variable(thd, i, param_values[i]))
|
||||
{
|
||||
err_status= TRUE;
|
||||
break;
|
||||
}
|
||||
str_value= sp_get_item_value(nctx->get_item(arg_no),
|
||||
&str_value_holder);
|
||||
|
||||
if (str_value)
|
||||
binlog_buf.append(*str_value);
|
||||
else
|
||||
binlog_buf.append(STRING_WITH_LEN("NULL"));
|
||||
}
|
||||
binlog_buf.append(')');
|
||||
}
|
||||
|
||||
if (err_status)
|
||||
{
|
||||
delete nctx;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
thd->spcont= nctx;
|
||||
|
||||
binlog_save_options= thd->options;
|
||||
need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
|
||||
if (need_binlog_call)
|
||||
{
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
mysql_bin_log.start_union_events(thd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Switch to call arena/mem_root so objects like sp_cursor or
|
||||
Item_cache holders for case expressions can be allocated on it.
|
||||
|
||||
TODO: In future we should associate call arena/mem_root with
|
||||
sp_rcontext and allocate all these objects (and sp_rcontext
|
||||
itself) on it directly rather than juggle with arenas.
|
||||
*/
|
||||
thd->set_n_backup_active_arena(&call_arena, &backup_arena);
|
||||
|
||||
thd->options&= ~OPTION_BIN_LOG;
|
||||
err_status= execute(thd);
|
||||
thd->options= binlog_save_options;
|
||||
|
||||
|
||||
thd->restore_active_arena(&call_arena, &backup_arena);
|
||||
|
||||
if (need_binlog_call)
|
||||
mysql_bin_log.stop_union_events(thd);
|
||||
|
||||
if (need_binlog_call && thd->binlog_evt_union.unioned_events)
|
||||
{
|
||||
char buf[256];
|
||||
String bufstr(buf, sizeof(buf), &my_charset_bin);
|
||||
bufstr.length(0);
|
||||
bufstr.append(STRING_WITH_LEN("SELECT "));
|
||||
append_identifier(thd, &bufstr, m_name.str, m_name.length);
|
||||
bufstr.append('(');
|
||||
for (uint i=0; i < argcount; i++)
|
||||
{
|
||||
String str_value_holder;
|
||||
String *str_value;
|
||||
|
||||
if (i)
|
||||
bufstr.append(',');
|
||||
|
||||
str_value= sp_get_item_value(param_values[i], &str_value_holder);
|
||||
|
||||
if (str_value)
|
||||
bufstr.append(*str_value);
|
||||
else
|
||||
bufstr.append(STRING_WITH_LEN("NULL"));
|
||||
}
|
||||
bufstr.append(')');
|
||||
|
||||
Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
|
||||
Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(),
|
||||
thd->binlog_evt_union.unioned_events_trans, FALSE);
|
||||
if (mysql_bin_log.write(&qinfo) &&
|
||||
if (mysql_bin_log.write(&qinfo) &&
|
||||
thd->binlog_evt_union.unioned_events_trans)
|
||||
{
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
|
||||
|
|
@ -1348,27 +1370,19 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
nctx->pop_all_cursors(); // To avoid memory leaks after an error
|
||||
|
||||
err_with_cleanup:
|
||||
delete nctx;
|
||||
call_arena.free_items();
|
||||
free_root(&call_mem_root, MYF(0));
|
||||
thd->spcont= octx;
|
||||
|
||||
DBUG_RETURN(err_status);
|
||||
}
|
||||
|
||||
|
||||
static Item_func_get_user_var *item_is_user_var(Item *it)
|
||||
{
|
||||
if (it->type() == Item::FUNC_ITEM)
|
||||
{
|
||||
Item_func *fi= static_cast<Item_func*>(it);
|
||||
|
||||
if (fi->functype() == Item_func::GUSERVAR_FUNC)
|
||||
return static_cast<Item_func_get_user_var*>(fi);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Execute a procedure.
|
||||
SYNOPSIS
|
||||
|
|
@ -1444,22 +1458,28 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||
for (uint i= 0 ; i < params ; i++)
|
||||
{
|
||||
Item *arg_item= it_args++;
|
||||
sp_variable_t *spvar= m_pcont->find_variable(i);
|
||||
|
||||
if (!arg_item)
|
||||
break;
|
||||
|
||||
sp_variable_t *spvar= m_pcont->find_variable(i);
|
||||
|
||||
if (!spvar)
|
||||
continue;
|
||||
|
||||
if (spvar->mode != sp_param_in)
|
||||
{
|
||||
if (!arg_item->is_splocal() && !item_is_user_var(arg_item))
|
||||
Settable_routine_parameter *srp=
|
||||
arg_item->get_settable_routine_parameter();
|
||||
|
||||
if (!srp)
|
||||
{
|
||||
my_error(ER_SP_NOT_VAR_ARG, MYF(0), i+1, m_qname.str);
|
||||
err_status= TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
srp->set_required_privilege(spvar->mode == sp_param_inout);
|
||||
}
|
||||
|
||||
if (spvar->mode == sp_param_out)
|
||||
|
|
@ -1467,7 +1487,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||
Item_null *null_item= new Item_null();
|
||||
|
||||
if (!null_item ||
|
||||
nctx->set_variable(thd, i, null_item))
|
||||
nctx->set_variable(thd, i, (struct Item **)&null_item))
|
||||
{
|
||||
err_status= TRUE;
|
||||
break;
|
||||
|
|
@ -1475,7 +1495,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (nctx->set_variable(thd, i, *it_args.ref()))
|
||||
if (nctx->set_variable(thd, i, it_args.ref()))
|
||||
{
|
||||
err_status= TRUE;
|
||||
break;
|
||||
|
|
@ -1527,36 +1547,16 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||
if (spvar->mode == sp_param_in)
|
||||
continue;
|
||||
|
||||
if (arg_item->is_splocal())
|
||||
Settable_routine_parameter *srp=
|
||||
arg_item->get_settable_routine_parameter();
|
||||
|
||||
DBUG_ASSERT(srp);
|
||||
|
||||
if (srp->set_value(thd, octx, nctx->get_item_addr(i)))
|
||||
{
|
||||
if (octx->set_variable(thd,
|
||||
((Item_splocal*) arg_item)->get_var_idx(),
|
||||
nctx->get_item(i)))
|
||||
{
|
||||
err_status= TRUE;
|
||||
break;
|
||||
}
|
||||
err_status= TRUE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Item_func_get_user_var *guv= item_is_user_var(arg_item);
|
||||
|
||||
if (guv)
|
||||
{
|
||||
Item *item= nctx->get_item(i);
|
||||
Item_func_set_user_var *suv;
|
||||
|
||||
suv= new Item_func_set_user_var(guv->get_name(), item);
|
||||
/*
|
||||
Item_func_set_user_var is not fixed after construction,
|
||||
call fix_fields().
|
||||
*/
|
||||
if ((err_status= test(!suv || suv->fix_fields(thd, &item) ||
|
||||
suv->check() || suv->update())))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2328,7 +2328,7 @@ sp_instr_set::execute(THD *thd, uint *nextp)
|
|||
int
|
||||
sp_instr_set::exec_core(THD *thd, uint *nextp)
|
||||
{
|
||||
int res= thd->spcont->set_variable(thd, m_offset, m_value);
|
||||
int res= thd->spcont->set_variable(thd, m_offset, &m_value);
|
||||
|
||||
if (res && thd->spcont->found_handler_here())
|
||||
{
|
||||
|
|
@ -2393,12 +2393,7 @@ sp_instr_set_trigger_field::execute(THD *thd, uint *nextp)
|
|||
int
|
||||
sp_instr_set_trigger_field::exec_core(THD *thd, uint *nextp)
|
||||
{
|
||||
int res= 0;
|
||||
Item *it= sp_prepare_func_item(thd, &value);
|
||||
if (!it ||
|
||||
!trigger_field->fixed && trigger_field->fix_fields(thd, 0) ||
|
||||
(it->save_in_field(trigger_field->field, 0) < 0))
|
||||
res= -1;
|
||||
const int res= (trigger_field->set_value(thd, &value) ? -1 : 0);
|
||||
*nextp = m_ip+1;
|
||||
return res;
|
||||
}
|
||||
|
|
@ -2603,7 +2598,7 @@ sp_instr_freturn::exec_core(THD *thd, uint *nextp)
|
|||
do it in scope of execution the current context/block.
|
||||
*/
|
||||
|
||||
return thd->spcont->set_return_value(thd, m_value);
|
||||
return thd->spcont->set_return_value(thd, &m_value);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3047,7 +3042,7 @@ sp_instr_set_case_expr::execute(THD *thd, uint *nextp)
|
|||
int
|
||||
sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
|
||||
{
|
||||
int res= thd->spcont->set_case_expr(thd, m_case_expr_id, m_case_expr);
|
||||
int res= thd->spcont->set_case_expr(thd, m_case_expr_id, &m_case_expr);
|
||||
|
||||
if (res &&
|
||||
!thd->spcont->get_case_expr(m_case_expr_id) &&
|
||||
|
|
@ -3061,7 +3056,7 @@ sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
|
|||
Item *null_item= new Item_null();
|
||||
|
||||
if (!null_item ||
|
||||
thd->spcont->set_case_expr(thd, m_case_expr_id, null_item))
|
||||
thd->spcont->set_case_expr(thd, m_case_expr_id, &null_item))
|
||||
{
|
||||
/* If this also failed, we have to abort. */
|
||||
|
||||
|
|
|
|||
|
|
@ -1169,6 +1169,6 @@ Item *
|
|||
sp_prepare_func_item(THD* thd, Item **it_addr);
|
||||
|
||||
bool
|
||||
sp_eval_expr(THD *thd, Field *result_field, Item *expr_item);
|
||||
sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr);
|
||||
|
||||
#endif /* _SP_HEAD_H_ */
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ sp_rcontext::init_var_items()
|
|||
|
||||
|
||||
bool
|
||||
sp_rcontext::set_return_value(THD *thd, Item *return_value_item)
|
||||
sp_rcontext::set_return_value(THD *thd, Item **return_value_item)
|
||||
{
|
||||
DBUG_ASSERT(m_return_value_fld);
|
||||
|
||||
|
|
@ -279,14 +279,14 @@ sp_rcontext::pop_cursors(uint count)
|
|||
|
||||
|
||||
int
|
||||
sp_rcontext::set_variable(THD *thd, uint var_idx, Item *value)
|
||||
sp_rcontext::set_variable(THD *thd, uint var_idx, Item **value)
|
||||
{
|
||||
return set_variable(thd, m_var_table->field[var_idx], value);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sp_rcontext::set_variable(THD *thd, Field *field, Item *value)
|
||||
sp_rcontext::set_variable(THD *thd, Field *field, Item **value)
|
||||
{
|
||||
if (!value)
|
||||
{
|
||||
|
|
@ -478,9 +478,10 @@ sp_rcontext::create_case_expr_holder(THD *thd, Item_result result_type)
|
|||
*/
|
||||
|
||||
int
|
||||
sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item *case_expr_item)
|
||||
sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr)
|
||||
{
|
||||
if (!(case_expr_item= sp_prepare_func_item(thd, &case_expr_item)))
|
||||
Item *case_expr_item= sp_prepare_func_item(thd, case_expr_item_ptr);
|
||||
if (!case_expr_item)
|
||||
return TRUE;
|
||||
|
||||
if (!m_case_expr_holders[case_expr_id] ||
|
||||
|
|
@ -542,7 +543,7 @@ bool Select_fetch_into_spvars::send_data(List<Item> &items)
|
|||
*/
|
||||
for (; spvar= spvar_iter++, item= item_iter++; )
|
||||
{
|
||||
if (thd->spcont->set_variable(thd, spvar->offset, item))
|
||||
if (thd->spcont->set_variable(thd, spvar->offset, &item))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class sp_rcontext : public Sql_alloc
|
|||
~sp_rcontext();
|
||||
|
||||
int
|
||||
set_variable(THD *thd, uint var_idx, Item *value);
|
||||
set_variable(THD *thd, uint var_idx, Item **value);
|
||||
|
||||
Item *
|
||||
get_item(uint var_idx);
|
||||
|
|
@ -100,7 +100,7 @@ class sp_rcontext : public Sql_alloc
|
|||
get_item_addr(uint var_idx);
|
||||
|
||||
bool
|
||||
set_return_value(THD *thd, Item *return_value_item);
|
||||
set_return_value(THD *thd, Item **return_value_item);
|
||||
|
||||
inline bool
|
||||
is_return_value_set() const
|
||||
|
|
@ -200,7 +200,7 @@ class sp_rcontext : public Sql_alloc
|
|||
*/
|
||||
|
||||
int
|
||||
set_case_expr(THD *thd, int case_expr_id, Item *case_expr_item);
|
||||
set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr);
|
||||
|
||||
Item *
|
||||
get_case_expr(int case_expr_id);
|
||||
|
|
@ -254,7 +254,7 @@ private:
|
|||
|
||||
Item_cache *create_case_expr_holder(THD *thd, Item_result result_type);
|
||||
|
||||
int set_variable(THD *thd, Field *field, Item *value);
|
||||
int set_variable(THD *thd, Field *field, Item **value);
|
||||
}; // class sp_rcontext : public Sql_alloc
|
||||
|
||||
|
||||
|
|
|
|||
165
sql/sql_base.cc
165
sql/sql_base.cc
|
|
@ -617,118 +617,110 @@ static inline uint tmpkeyval(THD *thd, TABLE *table)
|
|||
|
||||
void close_temporary_tables(THD *thd)
|
||||
{
|
||||
TABLE *next,
|
||||
*prev_table /* prev link is not maintained in TABLE's double-linked list */,
|
||||
*table;
|
||||
char *query= (gptr) 0, *end;
|
||||
uint query_buf_size, max_names_len;
|
||||
bool found_user_tables;
|
||||
|
||||
TABLE *table;
|
||||
if (!thd->temporary_tables)
|
||||
return;
|
||||
|
||||
LINT_INIT(end);
|
||||
query_buf_size= 50; // Enough for DROP ... TABLE IF EXISTS
|
||||
|
||||
/*
|
||||
insertion sort of temp tables by pseudo_thread_id to build ordered list
|
||||
if (!mysql_bin_log.is_open())
|
||||
{
|
||||
for (table= thd->temporary_tables; table; table= table->next)
|
||||
{
|
||||
close_temporary(table, 1);
|
||||
}
|
||||
thd->temporary_tables= 0;
|
||||
return;
|
||||
}
|
||||
|
||||
TABLE *next,
|
||||
*prev_table /* prev link is not maintained in TABLE's double-linked list */;
|
||||
bool was_quote_show= true; /* to assume thd->options has OPTION_QUOTE_SHOW_CREATE */
|
||||
// Better add "if exists", in case a RESET MASTER has been done
|
||||
const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
|
||||
uint stub_len= sizeof(stub) - 1;
|
||||
char buf[256];
|
||||
memcpy(buf, stub, stub_len);
|
||||
String s_query= String(buf, sizeof(buf), system_charset_info);
|
||||
bool found_user_tables= false;
|
||||
LINT_INIT(next);
|
||||
|
||||
/*
|
||||
insertion sort of temp tables by pseudo_thread_id to build ordered list
|
||||
of sublists of equal pseudo_thread_id
|
||||
*/
|
||||
for (prev_table= thd->temporary_tables,
|
||||
table= prev_table->next,
|
||||
found_user_tables= (prev_table->s->table_name[0] != '#');
|
||||
|
||||
for (prev_table= thd->temporary_tables, table= prev_table->next;
|
||||
table;
|
||||
prev_table= table, table= table->next)
|
||||
{
|
||||
TABLE *prev_sorted /* same as for prev_table */,
|
||||
*sorted;
|
||||
/*
|
||||
table not created directly by the user is moved to the tail.
|
||||
Fixme/todo: nothing (I checked the manual) prevents user to create temp
|
||||
with `#'
|
||||
*/
|
||||
if (table->s->table_name[0] == '#')
|
||||
continue;
|
||||
else
|
||||
TABLE *prev_sorted /* same as for prev_table */, *sorted;
|
||||
if (is_user_table(table))
|
||||
{
|
||||
found_user_tables = 1;
|
||||
}
|
||||
for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
|
||||
prev_sorted= sorted, sorted= sorted->next)
|
||||
{
|
||||
if (sorted->s->table_name[0] == '#' || tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
|
||||
if (!found_user_tables)
|
||||
found_user_tables= true;
|
||||
for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
|
||||
prev_sorted= sorted, sorted= sorted->next)
|
||||
{
|
||||
/* move into the sorted part of the list from the unsorted */
|
||||
prev_table->next= table->next;
|
||||
table->next= sorted;
|
||||
if (prev_sorted)
|
||||
if (!is_user_table(sorted) ||
|
||||
tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
|
||||
{
|
||||
prev_sorted->next= table;
|
||||
/* move into the sorted part of the list from the unsorted */
|
||||
prev_table->next= table->next;
|
||||
table->next= sorted;
|
||||
if (prev_sorted)
|
||||
{
|
||||
prev_sorted->next= table;
|
||||
}
|
||||
else
|
||||
{
|
||||
thd->temporary_tables= table;
|
||||
}
|
||||
table= prev_table;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
thd->temporary_tables= table;
|
||||
}
|
||||
table= prev_table;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
calc query_buf_size as max per sublists, one sublist per pseudo thread id.
|
||||
Also stop at first occurence of `#'-named table that starts
|
||||
all implicitly created temp tables
|
||||
*/
|
||||
for (max_names_len= 0, table=thd->temporary_tables;
|
||||
table && table->s->table_name[0] != '#';
|
||||
table=table->next)
|
||||
{
|
||||
uint tmp_names_len;
|
||||
for (tmp_names_len= table->s->key_length + 1;
|
||||
table->next && table->s->table_name[0] != '#' &&
|
||||
tmpkeyval(thd, table) == tmpkeyval(thd, table->next);
|
||||
table=table->next)
|
||||
{
|
||||
/*
|
||||
We are going to add 4 ` around the db/table names, so 1 might not look
|
||||
enough; indeed it is enough, because table->key_length is greater (by 8,
|
||||
because of server_id and thread_id) than db||table.
|
||||
*/
|
||||
tmp_names_len += table->next->s->key_length + 1;
|
||||
}
|
||||
if (tmp_names_len > max_names_len) max_names_len= tmp_names_len;
|
||||
}
|
||||
|
||||
/* allocate */
|
||||
if (found_user_tables && mysql_bin_log.is_open() &&
|
||||
(query = alloc_root(thd->mem_root, query_buf_size+= max_names_len)))
|
||||
// Better add "if exists", in case a RESET MASTER has been done
|
||||
end= strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
|
||||
|
||||
/* We always quote db,table names though it is slight overkill */
|
||||
if (found_user_tables &&
|
||||
!(was_quote_show= (thd->options & OPTION_QUOTE_SHOW_CREATE)))
|
||||
{
|
||||
thd->options |= OPTION_QUOTE_SHOW_CREATE;
|
||||
}
|
||||
|
||||
/* scan sorted tmps to generate sequence of DROP */
|
||||
for (table=thd->temporary_tables; table; table= next)
|
||||
for (table= thd->temporary_tables; table; table= next)
|
||||
{
|
||||
if (query // we might be out of memory, but this is not fatal
|
||||
&& table->s->table_name[0] != '#')
|
||||
if (is_user_table(table))
|
||||
{
|
||||
char *end_cur;
|
||||
/* Set pseudo_thread_id to be that of the processed table */
|
||||
thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
|
||||
/* Loop forward through all tables within the sublist of
|
||||
common pseudo_thread_id to create single DROP query */
|
||||
for (end_cur= end;
|
||||
table && table->s->table_name[0] != '#' &&
|
||||
for (s_query.length(stub_len);
|
||||
table && is_user_table(table) &&
|
||||
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
|
||||
table= next)
|
||||
{
|
||||
end_cur= strxmov(end_cur, "`", table->s->db, "`.`",
|
||||
table->s->table_name, "`,", NullS);
|
||||
/*
|
||||
We are going to add 4 ` around the db/table names and possible more
|
||||
due to special characters in the names
|
||||
*/
|
||||
append_identifier(thd, &s_query, table->s->db, strlen(table->s->db));
|
||||
s_query.q_append('.');
|
||||
append_identifier(thd, &s_query, table->s->table_name,
|
||||
strlen(table->s->table_name));
|
||||
s_query.q_append(',');
|
||||
next= table->next;
|
||||
close_temporary(table, 1);
|
||||
}
|
||||
thd->clear_error();
|
||||
/* The -1 is to remove last ',' */
|
||||
Query_log_event qinfo(thd, query, (ulong)(end_cur - query) - 1, 0, FALSE);
|
||||
CHARSET_INFO *cs_save= thd->variables.character_set_client;
|
||||
thd->variables.character_set_client= system_charset_info;
|
||||
Query_log_event qinfo(thd, s_query.ptr(),
|
||||
s_query.length() - 1 /* to remove trailing ',' */,
|
||||
0, FALSE);
|
||||
thd->variables.character_set_client= cs_save;
|
||||
/*
|
||||
Imagine the thread had created a temp table, then was doing a SELECT, and
|
||||
the SELECT was killed. Then it's not clever to mark the statement above as
|
||||
|
|
@ -741,12 +733,14 @@ void close_temporary_tables(THD *thd)
|
|||
qinfo.error_code= 0;
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
next= table->next;
|
||||
close_temporary(table, 1);
|
||||
}
|
||||
}
|
||||
if (!was_quote_show)
|
||||
thd->options &= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
|
||||
thd->temporary_tables=0;
|
||||
}
|
||||
|
||||
|
|
@ -1160,6 +1154,8 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
|
|||
MYSQL_LOCK_IGNORE_FLUSH - Open table even if
|
||||
someone has done a flush or namelock on it.
|
||||
No version number checking is done.
|
||||
MYSQL_OPEN_IGNORE_LOCKED_TABLES - Open table
|
||||
ignoring set of locked tables and prelocked mode.
|
||||
|
||||
IMPLEMENTATION
|
||||
Uses a cache of open tables to find a table not in use.
|
||||
|
|
@ -1219,7 +1215,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
}
|
||||
}
|
||||
|
||||
if (thd->locked_tables || thd->prelocked_mode)
|
||||
if (!(flags & MYSQL_OPEN_IGNORE_LOCKED_TABLES) &&
|
||||
(thd->locked_tables || thd->prelocked_mode))
|
||||
{ // Using table locks
|
||||
TABLE *best_table= 0;
|
||||
int best_distance= INT_MIN;
|
||||
|
|
|
|||
|
|
@ -1877,7 +1877,7 @@ bool select_dumpvar::send_data(List<Item> &items)
|
|||
if ((yy=var_li++))
|
||||
{
|
||||
if (thd->spcont->set_variable(current_thd, yy->get_var_idx(),
|
||||
*it.ref()))
|
||||
it.ref()))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2437,6 +2437,153 @@ bool select_insert::send_eof()
|
|||
CREATE TABLE (SELECT) ...
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
Create table from lists of fields and items (or open existing table
|
||||
with same name).
|
||||
|
||||
SYNOPSIS
|
||||
create_table_from_items()
|
||||
thd in Thread object
|
||||
create_info in Create information (like MAX_ROWS, ENGINE or
|
||||
temporary table flag)
|
||||
create_table in Pointer to TABLE_LIST object providing database
|
||||
and name for table to be created or to be open
|
||||
extra_fields in/out Initial list of fields for table to be created
|
||||
keys in List of keys for table to be created
|
||||
items in List of items which should be used to produce rest
|
||||
of fields for the table (corresponding fields will
|
||||
be added to the end of 'extra_fields' list)
|
||||
lock out Pointer to the MYSQL_LOCK object for table created
|
||||
(open) will be returned in this parameter. Since
|
||||
this table is not included in THD::lock caller is
|
||||
responsible for explicitly unlocking this table.
|
||||
|
||||
NOTES
|
||||
If 'create_info->options' bitmask has HA_LEX_CREATE_IF_NOT_EXISTS
|
||||
flag and table with name provided already exists then this function will
|
||||
simply open existing table.
|
||||
Also note that create, open and lock sequence in this function is not
|
||||
atomic and thus contains gap for deadlock and can cause other troubles.
|
||||
Since this function contains some logic specific to CREATE TABLE ... SELECT
|
||||
it should be changed before it can be used in other contexts.
|
||||
|
||||
RETURN VALUES
|
||||
non-zero Pointer to TABLE object for table created or opened
|
||||
0 Error
|
||||
*/
|
||||
|
||||
static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
||||
TABLE_LIST *create_table,
|
||||
List<create_field> *extra_fields,
|
||||
List<Key> *keys, List<Item> *items,
|
||||
MYSQL_LOCK **lock)
|
||||
{
|
||||
TABLE tmp_table; // Used during 'create_field()'
|
||||
TABLE *table= 0;
|
||||
uint select_field_count= items->elements;
|
||||
/* Add selected items to field list */
|
||||
List_iterator_fast<Item> it(*items);
|
||||
Item *item;
|
||||
Field *tmp_field;
|
||||
bool not_used;
|
||||
DBUG_ENTER("create_table_from_items");
|
||||
|
||||
tmp_table.alias= 0;
|
||||
tmp_table.timestamp_field= 0;
|
||||
tmp_table.s= &tmp_table.share_not_to_be_used;
|
||||
tmp_table.s->db_create_options=0;
|
||||
tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
|
||||
tmp_table.s->db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM ||
|
||||
create_info->db_type == DB_TYPE_HEAP);
|
||||
tmp_table.null_row=tmp_table.maybe_null=0;
|
||||
|
||||
while ((item=it++))
|
||||
{
|
||||
create_field *cr_field;
|
||||
Field *field;
|
||||
if (item->type() == Item::FUNC_ITEM)
|
||||
field=item->tmp_table_field(&tmp_table);
|
||||
else
|
||||
field=create_tmp_field(thd, &tmp_table, item, item->type(),
|
||||
(Item ***) 0, &tmp_field, 0, 0, 0, 0, 0);
|
||||
if (!field ||
|
||||
!(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
|
||||
((Item_field *)item)->field :
|
||||
(Field*) 0))))
|
||||
DBUG_RETURN(0);
|
||||
if (item->maybe_null)
|
||||
cr_field->flags &= ~NOT_NULL_FLAG;
|
||||
extra_fields->push_back(cr_field);
|
||||
}
|
||||
/*
|
||||
create and lock table
|
||||
|
||||
We don't log the statement, it will be logged later.
|
||||
|
||||
If this is a HEAP table, the automatic DELETE FROM which is written to the
|
||||
binlog when a HEAP table is opened for the first time since startup, must
|
||||
not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
|
||||
don't want to delete from it) 2) it would be written before the CREATE
|
||||
TABLE, which is a wrong order. So we keep binary logging disabled when we
|
||||
open_table().
|
||||
NOTE: By locking table which we just have created (or for which we just have
|
||||
have found that it already exists) separately from other tables used by the
|
||||
statement we create potential window for deadlock.
|
||||
TODO: create and open should be done atomic !
|
||||
*/
|
||||
{
|
||||
tmp_disable_binlog(thd);
|
||||
if (!mysql_create_table(thd, create_table->db, create_table->table_name,
|
||||
create_info, *extra_fields, *keys, 0,
|
||||
select_field_count))
|
||||
{
|
||||
/*
|
||||
If we are here in prelocked mode we either create temporary table
|
||||
or prelocked mode is caused by the SELECT part of this statement.
|
||||
*/
|
||||
DBUG_ASSERT(!thd->prelocked_mode ||
|
||||
create_info->options & HA_LEX_CREATE_TMP_TABLE ||
|
||||
thd->lex->requires_prelocking());
|
||||
|
||||
/*
|
||||
NOTE: We don't want to ignore set of locked tables here if we are
|
||||
under explicit LOCK TABLES since it will open gap for deadlock
|
||||
too wide (and also is not backward compatible).
|
||||
*/
|
||||
if (! (table= open_table(thd, create_table, thd->mem_root, (bool*) 0,
|
||||
(MYSQL_LOCK_IGNORE_FLUSH |
|
||||
((thd->prelocked_mode == PRELOCKED) ?
|
||||
MYSQL_OPEN_IGNORE_LOCKED_TABLES:0)))))
|
||||
quick_rm_table(create_info->db_type, create_table->db,
|
||||
table_case_name(create_info, create_table->table_name));
|
||||
}
|
||||
reenable_binlog(thd);
|
||||
if (!table) // open failed
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
FIXME: What happens if trigger manages to be created while we are
|
||||
obtaining this lock ? May be it is sensible just to disable
|
||||
trigger execution in this case ? Or will MYSQL_LOCK_IGNORE_FLUSH
|
||||
save us from that ?
|
||||
*/
|
||||
table->reginfo.lock_type=TL_WRITE;
|
||||
if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
|
||||
MYSQL_LOCK_IGNORE_FLUSH, ¬_used)))
|
||||
{
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
hash_delete(&open_cache,(byte*) table);
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
quick_rm_table(create_info->db_type, create_table->db,
|
||||
table_case_name(create_info, create_table->table_name));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
table->file->extra(HA_EXTRA_WRITE_CACHE);
|
||||
DBUG_RETURN(table);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5709,6 +5709,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
|
|||
}
|
||||
else
|
||||
{
|
||||
DBUG_ASSERT(thd->net.report_error);
|
||||
DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
|
||||
thd->is_fatal_error));
|
||||
query_cache_abort(&thd->net);
|
||||
|
|
@ -7226,7 +7227,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
|
|||
lex->create_info.merge_list.first))
|
||||
goto err;
|
||||
if (grant_option && want_priv != CREATE_TMP_ACL &&
|
||||
check_grant(thd, want_priv, create_table, 0, UINT_MAX, 0))
|
||||
check_grant(thd, want_priv, create_table, 0, 1, 0))
|
||||
goto err;
|
||||
|
||||
if (select_lex->item_list.elements)
|
||||
|
|
|
|||
|
|
@ -1795,105 +1795,6 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
|
|||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Create table from a list of fields and items
|
||||
****************************************************************************/
|
||||
|
||||
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
||||
TABLE_LIST *create_table,
|
||||
List<create_field> *extra_fields,
|
||||
List<Key> *keys,
|
||||
List<Item> *items,
|
||||
MYSQL_LOCK **lock)
|
||||
{
|
||||
TABLE tmp_table; // Used during 'create_field()'
|
||||
TABLE *table= 0;
|
||||
uint select_field_count= items->elements;
|
||||
/* Add selected items to field list */
|
||||
List_iterator_fast<Item> it(*items);
|
||||
Item *item;
|
||||
Field *tmp_field;
|
||||
bool not_used;
|
||||
DBUG_ENTER("create_table_from_items");
|
||||
|
||||
tmp_table.alias= 0;
|
||||
tmp_table.timestamp_field= 0;
|
||||
tmp_table.s= &tmp_table.share_not_to_be_used;
|
||||
tmp_table.s->db_create_options=0;
|
||||
tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
|
||||
tmp_table.s->db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM ||
|
||||
create_info->db_type == DB_TYPE_HEAP);
|
||||
tmp_table.null_row=tmp_table.maybe_null=0;
|
||||
|
||||
while ((item=it++))
|
||||
{
|
||||
create_field *cr_field;
|
||||
Field *field;
|
||||
if (item->type() == Item::FUNC_ITEM)
|
||||
field=item->tmp_table_field(&tmp_table);
|
||||
else
|
||||
field=create_tmp_field(thd, &tmp_table, item, item->type(),
|
||||
(Item ***) 0, &tmp_field, 0, 0, 0, 0, 0);
|
||||
if (!field ||
|
||||
!(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
|
||||
((Item_field *)item)->field :
|
||||
(Field*) 0))))
|
||||
DBUG_RETURN(0);
|
||||
if (item->maybe_null)
|
||||
cr_field->flags &= ~NOT_NULL_FLAG;
|
||||
extra_fields->push_back(cr_field);
|
||||
}
|
||||
/*
|
||||
create and lock table
|
||||
|
||||
We don't log the statement, it will be logged later.
|
||||
|
||||
If this is a HEAP table, the automatic DELETE FROM which is written to the
|
||||
binlog when a HEAP table is opened for the first time since startup, must
|
||||
not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
|
||||
don't want to delete from it) 2) it would be written before the CREATE
|
||||
TABLE, which is a wrong order. So we keep binary logging disabled when we
|
||||
open_table().
|
||||
TODO: create and open should be done atomic !
|
||||
*/
|
||||
{
|
||||
tmp_disable_binlog(thd);
|
||||
if (!mysql_create_table(thd, create_table->db, create_table->table_name,
|
||||
create_info, *extra_fields, *keys, 0,
|
||||
select_field_count))
|
||||
{
|
||||
if (! (table= open_table(thd, create_table, thd->mem_root, (bool*) 0,
|
||||
MYSQL_LOCK_IGNORE_FLUSH)))
|
||||
quick_rm_table(create_info->db_type, create_table->db,
|
||||
table_case_name(create_info, create_table->table_name));
|
||||
}
|
||||
reenable_binlog(thd);
|
||||
if (!table) // open failed
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
FIXME: What happens if trigger manages to be created while we are
|
||||
obtaining this lock ? May be it is sensible just to disable
|
||||
trigger execution in this case ? Or will MYSQL_LOCK_IGNORE_FLUSH
|
||||
save us from that ?
|
||||
*/
|
||||
table->reginfo.lock_type=TL_WRITE;
|
||||
if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
|
||||
MYSQL_LOCK_IGNORE_FLUSH, ¬_used)))
|
||||
{
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
hash_delete(&open_cache,(byte*) table);
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
quick_rm_table(create_info->db_type, create_table->db,
|
||||
table_case_name(create_info, create_table->table_name));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
table->file->extra(HA_EXTRA_WRITE_CACHE);
|
||||
DBUG_RETURN(table);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Alter a table definition
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -448,6 +448,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token NUMERIC_SYM
|
||||
%token NVARCHAR_SYM
|
||||
%token OFFSET_SYM
|
||||
%token OJ_SYM
|
||||
%token OLD_PASSWORD
|
||||
%token ON
|
||||
%token ONE_SHOT_SYM
|
||||
|
|
@ -5246,11 +5247,14 @@ table_factor:
|
|||
}
|
||||
expr '}'
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
YYERROR_UNLESS($3 && $7);
|
||||
add_join_on($7,$10);
|
||||
Lex->pop_context();
|
||||
$7->outer_join|=JOIN_TYPE_LEFT;
|
||||
$$=$7;
|
||||
if (!($$= lex->current_select->nest_last_join(lex->thd)))
|
||||
YYABORT;
|
||||
}
|
||||
| select_derived_init get_select_lex select_derived2
|
||||
{
|
||||
|
|
@ -5795,7 +5799,11 @@ select_var_ident:
|
|||
if (lex->result)
|
||||
((select_dumpvar *)lex->result)->var_list.push_back( new my_var($2,0,0,(enum_field_types)0));
|
||||
else
|
||||
YYABORT;
|
||||
/*
|
||||
The parser won't create select_result instance only
|
||||
if it's an EXPLAIN.
|
||||
*/
|
||||
DBUG_ASSERT(lex->describe);
|
||||
}
|
||||
| ident_or_text
|
||||
{
|
||||
|
|
@ -5807,10 +5815,8 @@ select_var_ident:
|
|||
my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str);
|
||||
YYABORT;
|
||||
}
|
||||
if (! lex->result)
|
||||
YYABORT;
|
||||
else
|
||||
{
|
||||
if (lex->result)
|
||||
{
|
||||
my_var *var;
|
||||
((select_dumpvar *)lex->result)->
|
||||
var_list.push_back(var= new my_var($1,1,t->offset,t->type));
|
||||
|
|
@ -5818,6 +5824,14 @@ select_var_ident:
|
|||
if (var)
|
||||
var->sp= lex->sphead;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
The parser won't create select_result instance only
|
||||
if it's an EXPLAIN.
|
||||
*/
|
||||
DBUG_ASSERT(lex->describe);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
@ -7206,12 +7220,18 @@ simple_ident_q:
|
|||
YYABORT;
|
||||
}
|
||||
|
||||
DBUG_ASSERT(!new_row ||
|
||||
(lex->trg_chistics.event == TRG_EVENT_INSERT ||
|
||||
lex->trg_chistics.event == TRG_EVENT_UPDATE));
|
||||
const bool read_only=
|
||||
!(new_row && lex->trg_chistics.action_time == TRG_ACTION_BEFORE);
|
||||
if (!(trg_fld= new Item_trigger_field(Lex->current_context(),
|
||||
new_row ?
|
||||
Item_trigger_field::NEW_ROW:
|
||||
Item_trigger_field::OLD_ROW,
|
||||
$3.str,
|
||||
Item_trigger_field::AT_READ)))
|
||||
SELECT_ACL,
|
||||
read_only)))
|
||||
YYABORT;
|
||||
|
||||
/*
|
||||
|
|
@ -7847,11 +7867,13 @@ sys_option_value:
|
|||
it= new Item_null();
|
||||
}
|
||||
|
||||
DBUG_ASSERT(lex->trg_chistics.action_time == TRG_ACTION_BEFORE &&
|
||||
(lex->trg_chistics.event == TRG_EVENT_INSERT ||
|
||||
lex->trg_chistics.event == TRG_EVENT_UPDATE));
|
||||
if (!(trg_fld= new Item_trigger_field(Lex->current_context(),
|
||||
Item_trigger_field::NEW_ROW,
|
||||
$2.base_name.str,
|
||||
Item_trigger_field::AT_UPDATE)
|
||||
) ||
|
||||
UPDATE_ACL, FALSE)) ||
|
||||
!(sp_fld= new sp_instr_set_trigger_field(lex->sphead->
|
||||
instructions(),
|
||||
lex->spcont,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue