Commit 2a138695 authored by unknown's avatar unknown

Merge jbruehe@bk-internal.mysql.com:/home/bk/mysql-5.0

into mysql.com:/M50/mysql-5.0

parents a994f984 3e1ff238
......@@ -1249,15 +1249,13 @@ dict_table_remove_from_cache(
/* Remove table from LRU list of tables */
UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
mutex_free(&(table->autoinc_mutex));
size = mem_heap_get_size(table->heap);
ut_ad(dict_sys->size >= size);
dict_sys->size -= size;
mem_heap_free(table->heap);
dict_mem_table_free(table);
}
/**************************************************************************
......@@ -1378,6 +1376,38 @@ dict_col_reposition_in_cache(
HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
}
/********************************************************************
If the given column name is reserved for InnoDB system columns, return
TRUE. */
ibool
dict_col_name_is_reserved(
/*======================*/
/* out: TRUE if name is reserved */
const char* name) /* in: column name */
{
/* This check reminds that if a new system column is added to
the program, it should be dealt with here. */
#if DATA_N_SYS_COLS != 4
#error "DATA_N_SYS_COLS != 4"
#endif
static const char* reserved_names[] = {
"DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID"
};
ulint i;
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
if (strcmp(name, reserved_names[i]) == 0) {
return(TRUE);
}
}
return(FALSE);
}
/**************************************************************************
Adds an index to the dictionary cache. */
......@@ -1551,7 +1581,7 @@ dict_index_remove_from_cache(
dict_sys->size -= size;
mem_heap_free(index->heap);
dict_mem_index_free(index);
}
/***********************************************************************
......
......@@ -767,7 +767,7 @@ dict_load_table(
if (!btr_pcur_is_on_user_rec(&pcur, &mtr)
|| rec_get_deleted_flag(rec, sys_tables->comp)) {
/* Not found */
err_exit:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
mem_heap_free(heap);
......@@ -779,11 +779,8 @@ dict_load_table(
/* Check if the table name in record is the searched one */
if (len != ut_strlen(name) || ut_memcmp(name, field, len) != 0) {
btr_pcur_close(&pcur);
mtr_commit(&mtr);
mem_heap_free(heap);
return(NULL);
goto err_exit;
}
ut_a(0 == ut_strcmp("SPACE",
......@@ -844,6 +841,14 @@ dict_load_table(
field = rec_get_nth_field_old(rec, 5, &len);
table->type = mach_read_from_4(field);
if (UNIV_UNLIKELY(table->type != DICT_TABLE_ORDINARY)) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: table %s: unknown table type %lu\n",
name, (ulong) table->type);
goto err_exit;
}
if (table->type == DICT_TABLE_CLUSTER_MEMBER) {
ut_error;
#if 0 /* clustered tables have not been implemented yet */
......
......@@ -97,6 +97,21 @@ dict_mem_table_create(
return(table);
}
/********************************************************************
Free a table memory object. */
void
dict_mem_table_free(
/*================*/
dict_table_t* table) /* in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
mutex_free(&(table->autoinc_mutex));
mem_heap_free(table->heap);
}
/**************************************************************************
Creates a cluster memory object. */
......@@ -290,5 +305,8 @@ dict_mem_index_free(
/*================*/
dict_index_t* index) /* in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
mem_heap_free(index->heap);
}
......@@ -1160,9 +1160,9 @@ ibuf_dummy_index_free(
dict_index_t* index) /* in: dummy index */
{
dict_table_t* table = index->table;
mem_heap_free(index->heap);
mutex_free(&(table->autoinc_mutex));
mem_heap_free(table->heap);
dict_mem_index_free(index);
dict_mem_table_free(table);
}
/*************************************************************************
......
......@@ -98,6 +98,15 @@ ulint
dict_col_get_clust_pos(
/*===================*/
dict_col_t* col);
/********************************************************************
If the given column name is reserved for InnoDB system columns, return
TRUE. */
ibool
dict_col_name_is_reserved(
/*======================*/
/* out: TRUE if name is reserved */
const char* name); /* in: column name */
/************************************************************************
Initializes the autoinc counter. It is not an error to initialize an already
initialized counter. */
......
......@@ -56,6 +56,13 @@ dict_mem_table_create(
a member of a cluster */
ulint n_cols, /* in: number of columns */
ibool comp); /* in: TRUE=compact page format */
/********************************************************************
Free a table memory object. */
void
dict_mem_table_free(
/*================*/
dict_table_t* table); /* in: table */
/**************************************************************************
Creates a cluster memory object. */
......
......@@ -261,6 +261,9 @@ it is read or written. */
/* Tell the compiler that cond is unlikely to hold */
#define UNIV_UNLIKELY(cond) UNIV_EXPECT(cond, FALSE)
/* Compile-time constant of the given array's size. */
#define UT_ARR_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#include <stdio.h>
#include "ut0dbg.h"
#include "ut0ut.h"
......
......@@ -890,9 +890,9 @@ recv_parse_or_apply_log_rec_body(
ut_ad(!page || ptr);
if (index) {
dict_table_t* table = index->table;
mem_heap_free(index->heap);
mutex_free(&(table->autoinc_mutex));
mem_heap_free(table->heap);
dict_mem_index_free(index);
dict_mem_table_free(table);
}
return(ptr);
......
......@@ -1673,7 +1673,9 @@ row_mysql_recover_tmp_table(
if (!ptr) {
/* table name does not begin with "/rsql" */
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
return(DB_ERROR);
}
else {
......@@ -1785,6 +1787,7 @@ row_create_table_for_mysql(
const char* table_name;
ulint table_name_len;
ulint err;
ulint i;
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
#ifdef UNIV_SYNC_DEBUG
......@@ -1802,6 +1805,7 @@ row_create_table_for_mysql(
"InnoDB: with raw, and innodb_force_... is removed.\n",
stderr);
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
return(DB_ERROR);
......@@ -1816,11 +1820,25 @@ row_create_table_for_mysql(
"InnoDB: MySQL system tables must be of the MyISAM type!\n",
table->name);
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
return(DB_ERROR);
}
/* Check that no reserved column names are used. */
for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
dict_col_t* col = dict_table_get_nth_col(table, i);
if (dict_col_name_is_reserved(col->name)) {
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
return(DB_ERROR);
}
}
trx_start_if_not_started(trx);
if (row_mysql_is_recovered_tmp_table(table->name)) {
......
......@@ -34,20 +34,20 @@ static uint lengths[256];
static struct my_option my_long_options[] =
{
{"dump", 'd', "Dump index (incl. data offsets and word weights).",
{"help", 'h', "Display help and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"stats", 's', "Report global stats.",
{"help", '?', "Synonym for -h.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Be verbose.",
(gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"count", 'c', "Calculate per-word stats (counts and global weights).",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"length", 'l', "Report length distribution.",
{"dump", 'd', "Dump index (incl. data offsets and word weights).",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"help", 'h', "Display help and exit.",
{"length", 'l', "Report length distribution.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"help", '?', "Synonym for -h.",
{"stats", 's', "Report global stats.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Be verbose.",
(gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
......
......@@ -72,3 +72,10 @@ set @@max_allowed_packet=1048576*100;
select compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null;
compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null
0
create table t1(a blob);
insert into t1 values(NULL), (compress('a'));
select uncompress(a), uncompressed_length(a) from t1;
uncompress(a) uncompressed_length(a)
NULL NULL
a 1
drop table t1;
......@@ -3241,6 +3241,8 @@ where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
a a
2005-10-01 2005-10-01
drop table t1, t2;
CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
ERROR HY000: Can't create table './test/t1.frm' (errno: -1)
CREATE TABLE t1 (
a BIGINT(20) NOT NULL,
PRIMARY KEY (a)
......
......@@ -74,3 +74,61 @@ SET FOREIGN_KEY_CHECKS=0;
INSERT INTO t1 VALUES (1),(1);
ERROR 23000: Duplicate entry '1' for key 1
drop table t1;
drop function if exists bug15728;
drop function if exists bug15728_insert;
drop table if exists t1, t2;
create table t1 (
id int not null auto_increment,
last_id int,
primary key (id)
);
create function bug15728() returns int(11)
return last_insert_id();
insert into t1 (last_id) values (0);
insert into t1 (last_id) values (last_insert_id());
insert into t1 (last_id) values (bug15728());
create table t2 (
id int not null auto_increment,
last_id int,
primary key (id)
);
create function bug15728_insert() returns int(11) modifies sql data
begin
insert into t2 (last_id) values (bug15728());
return bug15728();
end|
create trigger t1_bi before insert on t1 for each row
begin
declare res int;
select bug15728_insert() into res;
set NEW.last_id = res;
end|
insert into t1 (last_id) values (0);
drop trigger t1_bi;
select last_insert_id();
last_insert_id()
4
select bug15728_insert();
bug15728_insert()
2
select last_insert_id();
last_insert_id()
4
insert into t1 (last_id) values (bug15728());
select last_insert_id();
last_insert_id()
5
select * from t1;
id last_id
1 0
2 1
3 2
4 1
5 4
select * from t2;
id last_id
1 3
2 4
drop function bug15728;
drop function bug15728_insert;
drop table t1, t2;
......@@ -103,3 +103,17 @@ f
1
drop temporary table t4;
drop table t5;
set @session.pseudo_thread_id=100;
create temporary table t101 (id int);
create temporary table t102 (id int);
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);
set @con1_id=connection_id();
kill @con1_id;
create table t1(f int);
insert into t1 values (1);
select * from t1 /* must be 1 */;
f
1
drop table t1;
drop table if exists t1;
create table t1 (
id char(16) not null default '',
data int not null
);
drop procedure if exists goto1//
create procedure goto1()
begin
declare y int;
label a;
select * from t1;
select count(*) into y from t1;
if y > 2 then
goto b;
end if;
insert into t1 values ("j", y);
goto a;
label b;
end//
call goto1()//
id data
id data
j 0
id data
j 0
j 1
id data
j 0
j 1
j 2
drop procedure goto1//
drop procedure if exists goto2//
create procedure goto2(a int)
begin
declare x int default 0;
declare continue handler for sqlstate '42S98' set x = 1;
label a;
select * from t1;
b:
while x < 2 do
begin
declare continue handler for sqlstate '42S99' set x = 2;
if a = 0 then
set x = x + 1;
iterate b;
elseif a = 1 then
leave b;
elseif a = 2 then
set a = 1;
goto a;
end if;
end;
end while b;
select * from t1;
end//
call goto2(0)//
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
call goto2(1)//
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
call goto2(2)//
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
drop procedure goto2//
delete from t1//
drop procedure if exists goto3//
create procedure goto3()
begin
label L1;
begin
end;
goto L1;
end//
drop procedure goto3//
drop procedure if exists goto4//
create procedure goto4()
begin
begin
label lab1;
begin
goto lab1;
end;
end;
end//
drop procedure goto4//
drop procedure if exists goto5//
create procedure goto5()
begin
begin
begin
goto lab1;
end;
label lab1;
end;
end//
drop procedure goto5//
drop procedure if exists goto6//
create procedure goto6()
begin
label L1;
goto L5;
begin
label L2;
goto L1;
goto L5;
begin
label L3;
goto L1;
goto L2;
goto L3;
goto L4;
goto L5;
end;
goto L2;
goto L4;
label L4;
end;
label L5;
goto L1;
end//
drop procedure goto6//
create procedure foo()
begin
goto foo;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
begin
label foo;
end;
goto foo;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
goto foo;
begin
label foo;
end;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
begin
goto foo;
end;
begin
label foo;
end;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
begin
label foo;
end;
begin
goto foo;
end;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure p()
begin
declare continue handler for sqlexception
begin
goto L1;
end;
select field from t1;
label L1;
end//
ERROR HY000: GOTO is not allowed in a stored procedure handler
drop procedure if exists bug6898//
create procedure bug6898()
begin
goto label1;
label label1;
begin end;
goto label1;
end//
drop procedure bug6898//
drop table t1;
......@@ -4848,4 +4848,60 @@ c 2
b 3
a 1
delete from t1|
drop function if exists bug15728|
drop table if exists t3|
create table t3 (
id int not null auto_increment,
primary key (id)
)|
create function bug15728() returns int(11)
return last_insert_id()|
insert into t3 values (0)|
select last_insert_id()|
last_insert_id()
1
select bug15728()|
bug15728()
1
drop function bug15728|
drop table t3|
drop procedure if exists bug18787|
create procedure bug18787()
begin
declare continue handler for sqlexception begin end;
select no_such_function();
end|
call bug18787()|
no_such_function()
NULL
drop procedure bug18787|
create database bug18344_012345678901|
use bug18344_012345678901|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|
create database bug18344_0123456789012|
use bug18344_0123456789012|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|
use test|
select schema_name from information_schema.schemata where
schema_name like 'bug18344%'|
schema_name
bug18344_012345678901
bug18344_0123456789012
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
routine_name routine_schema
bug18344 bug18344_012345678901
bug18344_2 bug18344_012345678901
bug18344 bug18344_0123456789012
bug18344_2 bug18344_0123456789012
drop database bug18344_012345678901|
drop database bug18344_0123456789012|
select schema_name from information_schema.schemata where
schema_name like 'bug18344%'|
schema_name
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
routine_name routine_schema
drop table t1,t2;
drop tables if exists t1, t2;
drop view if exists v1;
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\_%';
......@@ -59,3 +61,18 @@ delete from mysql.db where user like 'mysqltest\_%';
delete from mysql.tables_priv where user like 'mysqltest\_%';
flush privileges;
drop table t1, t2;
create table t1 (a int, b datetime);
insert into t1 values (1, 20010101000000), (2, 20020101000000);
grant all privileges on test.* to mysqltest_1@localhost;
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1;
select * from v1;
a lb
1 2001-01-01 03:00:00
2 2002-01-01 03:00:00
select * from v1, mysql.time_zone;
ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone'
drop view v1;
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1, mysql.time_zone;
ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for table 'time_zone'
drop table t1;
drop user mysqltest_1@localhost;
......@@ -949,9 +949,42 @@ insert into t1 values
create function f2() returns int return (select max(b) from t2);
insert into t2 select a, f2() from t1;
load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
drop table t1;
drop tables t1, t2;
drop function f1;
drop function f2;
create table t1(i int not null, j int not null, n numeric(15,2), primary key(i,j));
create table t2(i int not null, n numeric(15,2), primary key(i));
create trigger t1_ai after insert on t1 for each row
begin
declare sn numeric(15,2);
select sum(n) into sn from t1 where i=new.i;
replace into t2 values(new.i, sn);
end|
insert into t1 values
(1,1,10.00),(1,2,10.00),(1,3,10.00),(1,4,10.00),(1,5,10.00),
(1,6,10.00),(1,7,10.00),(1,8,10.00),(1,9,10.00),(1,10,10.00),
(1,11,10.00),(1,12,10.00),(1,13,10.00),(1,14,10.00),(1,15,10.00);
select * from t1;
i j n
1 1 10.00
1 2 10.00
1 3 10.00
1 4 10.00
1 5 10.00
1 6 10.00
1 7 10.00
1 8 10.00
1 9 10.00
1 10 10.00
1 11 10.00
1 12 10.00
1 13 10.00
1 14 10.00
1 15 10.00
select * from t2;
i n
1 150.00
drop tables t1, t2;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
conn_id INT,
......
......@@ -2623,3 +2623,29 @@ select * from v1;
ERROR HY000: Recursive stored functions and triggers are not allowed.
drop function f1;
drop view t1, v1;
create table t1 (dt datetime);
insert into t1 values (20040101000000), (20050101000000), (20060101000000);
create view v1 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from t1;
select * from v1;
ldt
2004-01-01 03:00:00
2005-01-01 03:00:00
2006-01-01 03:00:00
drop view v1;
create view v1 as select * from t1 where convert_tz(dt, 'UTC', 'Europe/Moscow') >= 20050101000000;
select * from v1;
dt
2005-01-01 00:00:00
2006-01-01 00:00:00
create view v2 as select * from v1 where dt < 20060101000000;
select * from v2;
dt
2005-01-01 00:00:00
drop view v2;
create view v2 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from v1;
select * from v2;
ldt
2005-01-01 03:00:00
2006-01-01 03:00:00
drop view v1, v2;
drop table t1;
......@@ -10,6 +10,5 @@
#
##############################################################################
sp-goto : GOTO is currently is disabled - will be fixed in the future
ndb_load : Bug#17233
udf : Bug#18564 (Permission by Brian)
......@@ -47,4 +47,13 @@ set @@max_allowed_packet=1048576*100;
--replace_result "''" XXX "'1'" XXX
eval select compress(repeat('aaaaaaaaaa', IF('$LOW_MEMORY', 10, 10000000))) is null;
#
# Bug #18643: problem with null values
#
create table t1(a blob);
insert into t1 values(NULL), (compress('a'));
select uncompress(a), uncompressed_length(a) from t1;
drop table t1;
# End of 4.1 tests
......@@ -2133,13 +2133,17 @@ disconnect b;
#
create table t1(a date) engine=innodb;
create table t2(a date, key(a)) engine=innodb;
create table t2(a date, key(a)) engine=innodb;
insert into t1 values('2005-10-01');
insert into t2 values('2005-10-01');
select * from t1, t2
where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
drop table t1, t2;
# bug 18934, "InnoDB crashes when table uses column names like DB_ROW_ID"
--error 1005
CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
#
# Bug #17152: Wrong result with BINARY comparison on aliased column
#
......
......@@ -78,3 +78,73 @@ connection master;
drop table t1;
sync_slave_with_master;
# End of 4.1 tests
#
# BUG#15728: LAST_INSERT_ID function inside a stored function returns 0
#
# The solution is not to reset last_insert_id on enter to sub-statement.
#
connection master;
--disable_warnings
drop function if exists bug15728;
drop function if exists bug15728_insert;
drop table if exists t1, t2;
--enable_warnings
create table t1 (
id int not null auto_increment,
last_id int,
primary key (id)
);
create function bug15728() returns int(11)
return last_insert_id();
insert into t1 (last_id) values (0);
insert into t1 (last_id) values (last_insert_id());
insert into t1 (last_id) values (bug15728());
# Check that nested call replicates too.
create table t2 (
id int not null auto_increment,
last_id int,
primary key (id)
);
delimiter |;
create function bug15728_insert() returns int(11) modifies sql data
begin
insert into t2 (last_id) values (bug15728());
return bug15728();
end|
create trigger t1_bi before insert on t1 for each row
begin
declare res int;
select bug15728_insert() into res;
set NEW.last_id = res;
end|
delimiter ;|
insert into t1 (last_id) values (0);
drop trigger t1_bi;
# Check that nested call doesn't affect outer context.
select last_insert_id();
select bug15728_insert();
select last_insert_id();
insert into t1 (last_id) values (bug15728());
# This should be exactly one greater than in the previous call.
select last_insert_id();
save_master_pos;
connection slave;
sync_with_master;
select * from t1;
select * from t2;
connection master;
drop function bug15728;
drop function bug15728_insert;
drop table t1, t2;
# End of 5.0 tests
......@@ -129,6 +129,8 @@ drop table t1,t2;
create temporary table t3 (f int);
sync_with_master;
# The server will now close done
#
# Bug#17284 erroneous temp table cleanup on slave
#
......@@ -154,6 +156,32 @@ connection master;
drop temporary table t4;
drop table t5;
# The server will now close done
#
# BUG#17263 incorrect generation DROP temp tables
# Temporary tables of connection are dropped in batches
# where a batch correspond to pseudo_thread_id
# value was set up at the moment of temp table creation
#
connection con1;
set @session.pseudo_thread_id=100;
create temporary table t101 (id int);
create temporary table t102 (id int);
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);
set @con1_id=connection_id();
kill @con1_id;
#now do something to show that slave is ok after DROP temp tables
connection master;
create table t1(f int);
insert into t1 values (1);
sync_slave_with_master;
#connection slave;
select * from t1 /* must be 1 */;
connection master;
drop table t1;
# End of 5.0 tests
#
# The non-standard GOTO, for compatibility
#
# QQQ The "label" syntax is temporary, it will (hopefully)
# change to the more common "L:" syntax soon.
# For the time being, this feature is disabled, until
# the syntax (and some other known bugs) can be fixed.
#
# Test cases for bugs are added at the end. See template there.
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (
id char(16) not null default '',
data int not null
);
delimiter //;
--disable_warnings
drop procedure if exists goto1//
--enable_warnings
create procedure goto1()
begin
declare y int;
label a;
select * from t1;
select count(*) into y from t1;
if y > 2 then
goto b;
end if;
insert into t1 values ("j", y);
goto a;
label b;
end//
call goto1()//
drop procedure goto1//
# With dummy handlers, just to test restore of contexts with jumps
--disable_warnings
drop procedure if exists goto2//
--enable_warnings
create procedure goto2(a int)
begin
declare x int default 0;
declare continue handler for sqlstate '42S98' set x = 1;
label a;
select * from t1;
b:
while x < 2 do
begin
declare continue handler for sqlstate '42S99' set x = 2;
if a = 0 then
set x = x + 1;
iterate b;
elseif a = 1 then
leave b;
elseif a = 2 then
set a = 1;
goto a;
end if;
end;
end while b;
select * from t1;
end//
call goto2(0)//
call goto2(1)//
call goto2(2)//
drop procedure goto2//
delete from t1//
# Check label visibility for some more cases. We don't call these.
--disable_warnings
drop procedure if exists goto3//
--enable_warnings
create procedure goto3()
begin
label L1;
begin
end;
goto L1;
end//
drop procedure goto3//
--disable_warnings
drop procedure if exists goto4//
--enable_warnings
create procedure goto4()
begin
begin
label lab1;
begin
goto lab1;
end;
end;
end//
drop procedure goto4//
--disable_warnings
drop procedure if exists goto5//
--enable_warnings
create procedure goto5()
begin
begin
begin
goto lab1;
end;
label lab1;
end;
end//
drop procedure goto5//
--disable_warnings
drop procedure if exists goto6//
--enable_warnings
create procedure goto6()
begin
label L1;
goto L5;
begin
label L2;
goto L1;
goto L5;
begin
label L3;
goto L1;
goto L2;
goto L3;
goto L4;
goto L5;
end;
goto L2;
goto L4;
label L4;
end;
label L5;
goto L1;
end//
drop procedure goto6//
# Mismatching labels
--error 1308
create procedure foo()
begin
goto foo;
end//
--error 1308
create procedure foo()
begin
begin
label foo;
end;
goto foo;
end//
--error 1308
create procedure foo()
begin
goto foo;
begin
label foo;
end;
end//
--error 1308
create procedure foo()
begin
begin
goto foo;
end;
begin
label foo;
end;
end//
--error 1308
create procedure foo()
begin
begin
label foo;
end;
begin
goto foo;
end;
end//
# No goto in a handler
--error 1358
create procedure p()
begin
declare continue handler for sqlexception
begin
goto L1;
end;
select field from t1;
label L1;
end//
#
# Test cases for old bugs
#
#
# BUG#6898: Stored procedure crash if GOTO statements exist
#
--disable_warnings
drop procedure if exists bug6898//
--enable_warnings
create procedure bug6898()
begin
goto label1;
label label1;
begin end;
goto label1;
end//
drop procedure bug6898//
#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
#drop procedure if exists bugNNNN//
#--enable_warnings
#create procedure bugNNNN...
# Add bugs above this line. Use existing tables t1 and t2 when
# practical, or create table t3, t4 etc temporarily (and drop them).
delimiter ;//
drop table t1;
......@@ -5698,6 +5698,81 @@ select * from t1 order by @x|
delete from t1|
#
# BUG#15728: LAST_INSERT_ID function inside a stored function returns 0
#
# The solution is not to reset last_insert_id on enter to sub-statement.
#
--disable_warnings
drop function if exists bug15728|
drop table if exists t3|
--enable_warnings
create table t3 (
id int not null auto_increment,
primary key (id)
)|
create function bug15728() returns int(11)
return last_insert_id()|
insert into t3 values (0)|
select last_insert_id()|
select bug15728()|
drop function bug15728|
drop table t3|
#
# BUG#18787: Server crashed when calling a stored procedure containing
# a misnamed function
#
--disable_warnings
drop procedure if exists bug18787|
--enable_warnings
create procedure bug18787()
begin
declare continue handler for sqlexception begin end;
select no_such_function();
end|
call bug18787()|
drop procedure bug18787|
#
# BUG#18344: DROP DATABASE does not drop associated routines
# (... if the database name is longer than 21 characters)
#
# 1234567890123456789012
create database bug18344_012345678901|
use bug18344_012345678901|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|
create database bug18344_0123456789012|
use bug18344_0123456789012|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|
use test|
select schema_name from information_schema.schemata where
schema_name like 'bug18344%'|
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
drop database bug18344_012345678901|
drop database bug18344_0123456789012|
# Should be nothing left.
select schema_name from information_schema.schemata where
schema_name like 'bug18344%'|
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
#
# BUG#NNNN: New bug synopsis
#
......
# Embedded server testing does not support grants
-- source include/not_embedded.inc
--disable_warnings
drop tables if exists t1, t2;
drop view if exists v1;
--enable_warnings
#
# Test for bug #6116 "SET time_zone := ... requires access to mysql.time_zone
# tables". We should allow implicit access to time zone description tables
......@@ -82,3 +87,29 @@ flush privileges;
drop table t1, t2;
# End of 4.1 tests
#
# Additional test for bug #15153: CONVERT_TZ() is not allowed in all
# places in views.
#
# Let us check that usage of CONVERT_TZ() function in view does not
# require additional privileges.
# Let us rely on that previous tests done proper cleanups
create table t1 (a int, b datetime);
insert into t1 values (1, 20010101000000), (2, 20020101000000);
grant all privileges on test.* to mysqltest_1@localhost;
connect (tzuser3, localhost, mysqltest_1,,);
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1;
select * from v1;
# Of course we should not be able select from mysql.time_zone tables
--error ER_TABLEACCESS_DENIED_ERROR
select * from v1, mysql.time_zone;
drop view v1;
--error ER_TABLEACCESS_DENIED_ERROR
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1, mysql.time_zone;
connection default;
drop table t1;
drop user mysqltest_1@localhost;
# End of 5.0 tests
......@@ -1111,10 +1111,34 @@ insert into t1 values
create function f2() returns int return (select max(b) from t2);
insert into t2 select a, f2() from t1;
load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
drop table t1;
drop tables t1, t2;
drop function f1;
drop function f2;
#
# Test for bug #16021 "Wrong index given to function in trigger" which
# was caused by the same bulk insert optimization as bug #17764 but had
# slightly different symptoms (instead of reporting table as crashed
# storage engine reported error number 124)
#
create table t1(i int not null, j int not null, n numeric(15,2), primary key(i,j));
create table t2(i int not null, n numeric(15,2), primary key(i));
delimiter |;
create trigger t1_ai after insert on t1 for each row
begin
declare sn numeric(15,2);
select sum(n) into sn from t1 where i=new.i;
replace into t2 values(new.i, sn);
end|
delimiter ;|
insert into t1 values
(1,1,10.00),(1,2,10.00),(1,3,10.00),(1,4,10.00),(1,5,10.00),
(1,6,10.00),(1,7,10.00),(1,8,10.00),(1,9,10.00),(1,10,10.00),
(1,11,10.00),(1,12,10.00),(1,13,10.00),(1,14,10.00),(1,15,10.00);
select * from t1;
select * from t2;
drop tables t1, t2;
#
# Test for Bug #16461 connection_id() does not work properly inside trigger
#
......
......@@ -2485,3 +2485,30 @@ rename table v2 to t1;
select * from v1;
drop function f1;
drop view t1, v1;
#
# Bug #15153: CONVERT_TZ() is not allowed in all places in VIEWs
#
# Error was reported when one tried to use CONVERT_TZ() function
# select list of view which was processed using MERGE algorithm.
# (Also see additional test in timezone_grant.test)
create table t1 (dt datetime);
insert into t1 values (20040101000000), (20050101000000), (20060101000000);
# Let us test that convert_tz() can be used in view's select list
create view v1 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from t1;
select * from v1;
drop view v1;
# And in its where part
create view v1 as select * from t1 where convert_tz(dt, 'UTC', 'Europe/Moscow') >= 20050101000000;
select * from v1;
# Other interesting case - a view which uses convert_tz() function
# through other view.
create view v2 as select * from v1 where dt < 20060101000000;
select * from v2;
drop view v2;
# And even more interesting case when view uses convert_tz() both
# directly and indirectly
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;
......@@ -4744,7 +4744,9 @@ Item_func_sp::sp_result_field(void) const
share->table_cache_key = empty_name;
share->table_name = empty_name;
}
field= m_sp->create_result_field(max_length, name, dummy_table);
if (!(field= m_sp->create_result_field(max_length, name, dummy_table)))
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
DBUG_RETURN(field);
}
......@@ -4772,8 +4774,9 @@ Item_func_sp::execute(Field **flp)
{
if (!(*flp= f= sp_result_field()))
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
return 0;
/* Error set by sp_result_field() */
null_value= 1;
return TRUE;
}
f->move_field((f->pack_length() > sizeof(result_buf)) ?
......@@ -4928,16 +4931,19 @@ longlong Item_func_found_rows::val_int()
Field *
Item_func_sp::tmp_table_field(TABLE *t_arg)
{
Field *res= 0;
Field *field= 0;
DBUG_ENTER("Item_func_sp::tmp_table_field");
if (m_sp)
res= m_sp->create_result_field(max_length, (const char*) name, t_arg);
field= m_sp->create_result_field(max_length, (const char*) name, t_arg);
if (!res)
res= Item_func::tmp_table_field(t_arg);
if (!field)
field= Item_func::tmp_table_field(t_arg);
DBUG_RETURN(res);
if (!field)
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
DBUG_RETURN(field);
}
......
......@@ -2941,6 +2941,7 @@ String *Item_func_uncompress::val_str(String *str)
if (!res)
goto err;
null_value= 0;
if (res->is_empty())
return res;
......
......@@ -215,9 +215,6 @@ static SYMBOL symbols[] = {
{ "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)},
{ "GET_FORMAT", SYM(GET_FORMAT)},
{ "GLOBAL", SYM(GLOBAL_SYM)},
#ifdef SP_GOTO
{ "GOTO", SYM(GOTO_SYM)},
#endif
{ "GRANT", SYM(GRANT)},
{ "GRANTS", SYM(GRANTS)},
{ "GROUP", SYM(GROUP)},
......@@ -265,10 +262,6 @@ static SYMBOL symbols[] = {
{ "KEY", SYM(KEY_SYM)},
{ "KEYS", SYM(KEYS)},
{ "KILL", SYM(KILL_SYM)},
#ifdef SP_GOTO
/* QQ This will go away when the GOTO label syntax is fixed */
{ "LABEL", SYM(LABEL_SYM)},
#endif
{ "LANGUAGE", SYM(LANGUAGE_SYM)},
{ "LAST", SYM(LAST_SYM)},
{ "LEADING", SYM(LEADING)},
......
......@@ -886,28 +886,23 @@ int
sp_drop_db_routines(THD *thd, char *db)
{
TABLE *table;
byte key[64]; // db
uint keylen;
int ret;
uint key_len;
DBUG_ENTER("sp_drop_db_routines");
DBUG_PRINT("enter", ("db: %s", db));
// Put the key used to read the row together
keylen= strlen(db);
if (keylen > 64)
keylen= 64;
memcpy(key, db, keylen);
memset(key+keylen, (int)' ', 64-keylen); // Pad with space
keylen= sizeof(key);
ret= SP_OPEN_TABLE_FAILED;
if (!(table= open_proc_table_for_update(thd)))
goto err;
table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info);
key_len= table->key_info->key_part[0].store_length;
ret= SP_OK;
table->file->ha_index_init(0);
if (! table->file->index_read(table->record[0],
key, keylen, HA_READ_KEY_EXACT))
(byte *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
key_len, HA_READ_KEY_EXACT))
{
int nxtres;
bool deleted= FALSE;
......@@ -923,7 +918,8 @@ sp_drop_db_routines(THD *thd, char *db)
break;
}
} while (! (nxtres= table->file->index_next_same(table->record[0],
key, keylen)));
(byte *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
key_len)));
if (nxtres != HA_ERR_END_OF_FILE)
ret= SP_KEY_NOT_FOUND;
if (deleted)
......
......@@ -1670,44 +1670,11 @@ sp_head::backpatch(sp_label_t *lab)
while ((bp= li++))
{
if (bp->lab == lab ||
(bp->lab->type == SP_LAB_REF &&
my_strcasecmp(system_charset_info, bp->lab->name, lab->name) == 0))
{
if (bp->lab->type != SP_LAB_REF)
bp->instr->backpatch(dest, lab->ctx);
else
{
sp_label_t *dstlab= bp->lab->ctx->find_label(lab->name);
if (dstlab)
{
bp->lab= lab;
bp->instr->backpatch(dest, dstlab->ctx);
}
}
}
}
}
int
sp_head::check_backpatch(THD *thd)
{
bp_t *bp;
List_iterator_fast<bp_t> li(m_backpatch);
while ((bp= li++))
{
if (bp->lab->type == SP_LAB_REF)
{
my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "GOTO", bp->lab->name);
return -1;
}
if (bp->lab == lab)
bp->instr->backpatch(dest, lab->ctx);
}
return 0;
}
/*
Prepare an instance of create_field for field creation (fill all necessary
attributes).
......
......@@ -263,13 +263,6 @@ public:
void
backpatch(struct sp_label *);
// Check that no unresolved references exist.
// If none found, 0 is returned, otherwise errors have been issued
// and -1 is returned.
// This is called by the parser at the end of a create procedure/function.
int
check_backpatch(THD *thd);
// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr.
void
new_cont_backpatch(sp_instr_opt_meta *i);
......
......@@ -241,7 +241,7 @@ sp_pcontext::push_label(char *name, uint ip)
{
lab->name= name;
lab->ip= ip;
lab->type= SP_LAB_GOTO;
lab->type= SP_LAB_IMPL;
lab->ctx= this;
m_label.push_front(lab);
}
......
......@@ -48,10 +48,9 @@ typedef struct sp_variable
} sp_variable_t;
#define SP_LAB_REF 0 // Unresolved reference (for goto)
#define SP_LAB_GOTO 1 // Free goto label
#define SP_LAB_BEGIN 2 // Label at BEGIN
#define SP_LAB_ITER 3 // Label at iteration control
#define SP_LAB_IMPL 0 // Implicit label generated by parser
#define SP_LAB_BEGIN 1 // Label at BEGIN
#define SP_LAB_ITER 2 // Label at iteration control
/*
An SQL/PSM label. Can refer to the identifier used with the
......
......@@ -607,13 +607,22 @@ void close_temporary(TABLE *table,bool delete_table)
DBUG_VOID_RETURN;
}
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
static inline uint tmpkeyval(THD *thd, TABLE *table)
{
return uint4korr(table->s->table_cache_key + table->s->key_length - 4);
}
/* Creates one DROP TEMPORARY TABLE binlog event for each pseudo-thread */
void close_temporary_tables(THD *thd)
{
TABLE *table,*next;
char *query, *end;
uint query_buf_size;
bool found_user_tables = 0;
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;
if (!thd->temporary_tables)
return;
......@@ -621,47 +630,122 @@ void close_temporary_tables(THD *thd)
LINT_INIT(end);
query_buf_size= 50; // Enough for DROP ... TABLE IF EXISTS
for (table=thd->temporary_tables ; table ; table=table->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] != '#');
table;
prev_table= table, table= table->next)
{
TABLE *prev_sorted /* same as for prev_table */,
*sorted;
/*
We are going to add 4 ` around the db/table names, so 1 does 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.
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 `#'
*/
query_buf_size+= table->s->key_length+1;
if ((query = alloc_root(thd->mem_root, query_buf_size)))
// Better add "if exists", in case a RESET MASTER has been done
end=strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
for (table=thd->temporary_tables ; table ; table=next)
if (table->s->table_name[0] == '#')
continue;
else
{
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))
{
/* 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;
}
}
}
/*
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)
{
if (query) // we might be out of memory, but this is not fatal
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)
{
// skip temporary tables not created directly by the user
if (table->s->table_name[0] != '#')
found_user_tables = 1;
end = strxmov(end,"`",table->s->db,"`.`",
table->s->table_name,"`,", NullS);
/*
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;
}
next=table->next;
close_temporary(table, 1);
if (tmp_names_len > max_names_len) max_names_len= tmp_names_len;
}
if (query && found_user_tables && mysql_bin_log.is_open())
/* 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 ");
/* scan sorted tmps to generate sequence of DROP */
for (table=thd->temporary_tables; table; table= next)
{
/* The -1 is to remove last ',' */
thd->clear_error();
Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0, FALSE);
/*
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
"killed", because it's not really a statement updating data, and there
are 99.99% chances it will succeed on slave.
If a real update (one updating a persistent table) was killed on the
master, then this real update will be logged with error_code=killed,
rightfully causing the slave to stop.
*/
qinfo.error_code= 0;
mysql_bin_log.write(&qinfo);
if (query // we might be out of memory, but this is not fatal
&& table->s->table_name[0] != '#')
{
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] != '#' &&
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
table= next)
{
end_cur= strxmov(end_cur, "`", table->s->db, "`.`",
table->s->table_name, "`,", NullS);
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);
/*
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
"killed", because it's not really a statement updating data, and there
are 99.99% chances it will succeed on slave.
If a real update (one updating a persistent table) was killed on the
master, then this real update will be logged with error_code=killed,
rightfully causing the slave to stop.
*/
qinfo.error_code= 0;
mysql_bin_log.write(&qinfo);
}
else
{
next= table->next;
close_temporary(table, 1);
}
}
thd->temporary_tables=0;
}
......
......@@ -2025,7 +2025,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
The following things is done
- Disable binary logging for the duration of the statement
- Disable multi-result-sets for the duration of the statement
- Value of last_insert_id() is reset and restored
- Value of last_insert_id() is saved and restored
- Value set by 'SET INSERT_ID=#' is reset and restored
- Value for found_rows() is reset and restored
- examined_row_count is added to the total
......@@ -2037,6 +2037,8 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
We reset examined_row_count and cuted_fields and add these to the
result to ensure that if we have a bug that would reset these within
a function, we are not loosing any rows from the main statement.
We do not reset value of last_insert_id().
****************************************************************************/
void THD::reset_sub_statement_state(Sub_statement_state *backup,
......@@ -2062,7 +2064,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
/* Disable result sets */
client_capabilities &= ~CLIENT_MULTI_RESULTS;
in_sub_stmt|= new_state;
last_insert_id= 0;
next_insert_id= 0;
insert_id_used= 0;
examined_row_count= 0;
......
......@@ -1057,15 +1057,23 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
!old_lex->can_not_use_merged())
{
List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
/*
Currently 'view_main_select_tables' differs from 'view_tables'
only then view has CONVERT_TZ() function in its select list.
This may change in future, for example if we enable merging
of views with subqueries in select list.
*/
TABLE_LIST *view_main_select_tables=
(TABLE_LIST*)lex->select_lex.table_list.first;
/* lex should contain at least one table */
DBUG_ASSERT(view_tables != 0);
DBUG_ASSERT(view_main_select_tables != 0);
table->effective_algorithm= VIEW_ALGORITHM_MERGE;
DBUG_PRINT("info", ("algorithm: MERGE"));
table->updatable= (table->updatable_view != 0);
table->effective_with_check=
old_lex->get_effective_with_check(table);
table->merge_underlying_list= view_tables;
table->merge_underlying_list= view_main_select_tables;
/*
Let us set proper lock type for tables of the view's main select
since we may want to perform update or insert on view. This won't
......@@ -1081,7 +1089,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
}
/* prepare view context */
lex->select_lex.context.resolve_in_table_list_only(view_tables);
lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
lex->select_lex.context.outer_context= 0;
lex->select_lex.context.select_lex= table->select_lex;
lex->select_lex.select_n_having_items+=
......@@ -1097,7 +1105,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
tbl->select_lex= table->select_lex;
{
if (view_tables->next_local)
if (view_main_select_tables->next_local)
{
table->multitable_view= TRUE;
if (table->belong_to_view)
......
......@@ -301,7 +301,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token GEOMFROMWKB
%token GET_FORMAT
%token GLOBAL_SYM
%token GOTO_SYM
%token GRANT
%token GRANTS
%token GREATEST_SYM
......@@ -1332,8 +1331,6 @@ create_function_tail:
if (sp->is_not_allowed_in_function("function"))
YYABORT;
if (sp->check_backpatch(YYTHD))
YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->init_strings(YYTHD, lex, lex->spname);
if (!(sp->m_flags & sp_head::HAS_RETURN))
......@@ -2054,91 +2051,6 @@ sp_proc_stmt:
sp->add_instr(i);
}
}
| LABEL_SYM IDENT
{
#ifdef SP_GOTO
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
sp_label_t *lab= ctx->find_label($2.str);
if (lab)
{
my_error(ER_SP_LABEL_REDEFINE, MYF(0), $2.str);
YYABORT;
}
else
{
lab= ctx->push_label($2.str, sp->instructions());
lab->type= SP_LAB_GOTO;
lab->ctx= ctx;
sp->backpatch(lab);
}
#else
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
#endif
}
| GOTO_SYM IDENT
{
#ifdef SP_GOTO
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
uint ip= lex->sphead->instructions();
sp_label_t *lab;
sp_instr_jump *i;
sp_instr_hpop *ih;
sp_instr_cpop *ic;
if (sp->m_in_handler)
{
my_message(ER_SP_GOTO_IN_HNDLR, ER(ER_SP_GOTO_IN_HNDLR), MYF(0));
YYABORT;
}
lab= ctx->find_label($2.str);
if (! lab)
{
lab= (sp_label_t *)YYTHD->alloc(sizeof(sp_label_t));
lab->name= $2.str;
lab->ip= 0;
lab->type= SP_LAB_REF;
lab->ctx= ctx;
ih= new sp_instr_hpop(ip++, ctx, 0);
sp->push_backpatch(ih, lab);
sp->add_instr(ih);
ic= new sp_instr_cpop(ip++, ctx, 0);
sp->add_instr(ic);
sp->push_backpatch(ic, lab);
i= new sp_instr_jump(ip, ctx);
sp->push_backpatch(i, lab); /* Jumping forward */
sp->add_instr(i);
}
else
{
uint n;
n= ctx->diff_handlers(lab->ctx);
if (n)
{
ih= new sp_instr_hpop(ip++, ctx, n);
sp->add_instr(ih);
}
n= ctx->diff_cursors(lab->ctx);
if (n)
{
ic= new sp_instr_cpop(ip++, ctx, n);
sp->add_instr(ic);
}
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
sp->add_instr(i);
}
#else
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
#endif
}
| OPEN_SYM ident
{
LEX *lex= Lex;
......@@ -9246,8 +9158,6 @@ sp_tail:
LEX *lex= Lex;
sp_head *sp= lex->sphead;
if (sp->check_backpatch(YYTHD))
YYABORT;
sp->init_strings(YYTHD, lex, $3);
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
/* Restore flag if it was cleared above */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment