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:
unknown 2006-06-15 15:54:50 +02:00
commit 2fc416fe22
73 changed files with 2395 additions and 936 deletions

File diff suppressed because it is too large Load diff

View file

@ -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);

View file

@ -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);

View file

@ -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);
}
/*************************************************************************

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -189,4 +189,5 @@ HEX(f)
select HEX(f) from t4;
HEX(f)
835C
flush logs;
drop table t1, t2, t03, t04, t3, t4;

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View 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;

View file

@ -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;

View file

@ -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;

View file

@ -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|

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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.

View file

@ -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;

View file

@ -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').

View file

@ -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);

View file

@ -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;

View file

@ -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.

View file

@ -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). #
# #
#######################################################################

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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

View 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;

View file

@ -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

View file

@ -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

View file

@ -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
#

View file

@ -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

View file

@ -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;

View file

@ -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.

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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__

View file

@ -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;

View file

@ -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)) &&

View file

@ -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));
}

View file

@ -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.

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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;
}
};

View file

@ -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)
{

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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"

View file

@ -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. */

View file

@ -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_ */

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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, &not_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)
{

View file

@ -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)

View file

@ -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, &not_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
****************************************************************************/

View file

@ -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,