Commit 8b90390e authored by tomas@poseidon.ndb.mysql.com's avatar tomas@poseidon.ndb.mysql.com

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

into poseidon.ndb.mysql.com:/home/tomas/mysql-5.1
parents 911d878c d6e2fae0
...@@ -1774,6 +1774,7 @@ static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row); ...@@ -1774,6 +1774,7 @@ static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row);
static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row); static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row);
static int stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row); static int stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row);
static int stmt_read_row_no_data(MYSQL_STMT *stmt, unsigned char **row); static int stmt_read_row_no_data(MYSQL_STMT *stmt, unsigned char **row);
static int stmt_read_row_no_result_set(MYSQL_STMT *stmt, unsigned char **row);
/* /*
This function is used in mysql_stmt_store_result if This function is used in mysql_stmt_store_result if
...@@ -2036,7 +2037,7 @@ mysql_stmt_init(MYSQL *mysql) ...@@ -2036,7 +2037,7 @@ mysql_stmt_init(MYSQL *mysql)
stmt->list.data= stmt; stmt->list.data= stmt;
stmt->state= MYSQL_STMT_INIT_DONE; stmt->state= MYSQL_STMT_INIT_DONE;
stmt->mysql= mysql; stmt->mysql= mysql;
stmt->read_row_func= stmt_read_row_no_data; stmt->read_row_func= stmt_read_row_no_result_set;
stmt->prefetch_rows= DEFAULT_PREFETCH_ROWS; stmt->prefetch_rows= DEFAULT_PREFETCH_ROWS;
/* The rest of statement members was bzeroed inside malloc */ /* The rest of statement members was bzeroed inside malloc */
...@@ -2778,6 +2779,13 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row) ...@@ -2778,6 +2779,13 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row)
static int static int
stmt_read_row_no_data(MYSQL_STMT *stmt __attribute__((unused)), stmt_read_row_no_data(MYSQL_STMT *stmt __attribute__((unused)),
unsigned char **row __attribute__((unused))) unsigned char **row __attribute__((unused)))
{
return MYSQL_NO_DATA;
}
static int
stmt_read_row_no_result_set(MYSQL_STMT *stmt __attribute__((unused)),
unsigned char **row __attribute__((unused)))
{ {
set_stmt_error(stmt, CR_NO_RESULT_SET, unknown_sqlstate); set_stmt_error(stmt, CR_NO_RESULT_SET, unknown_sqlstate);
return 1; return 1;
...@@ -4600,7 +4608,8 @@ int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt) ...@@ -4600,7 +4608,8 @@ int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt)
((rc= stmt_fetch_row(stmt, row)) && rc != MYSQL_DATA_TRUNCATED)) ((rc= stmt_fetch_row(stmt, row)) && rc != MYSQL_DATA_TRUNCATED))
{ {
stmt->state= MYSQL_STMT_PREPARE_DONE; /* XXX: this is buggy */ stmt->state= MYSQL_STMT_PREPARE_DONE; /* XXX: this is buggy */
stmt->read_row_func= stmt_read_row_no_data; stmt->read_row_func= (rc == MYSQL_NO_DATA) ?
stmt_read_row_no_data : stmt_read_row_no_result_set;
} }
else else
{ {
...@@ -4937,7 +4946,7 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags) ...@@ -4937,7 +4946,7 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
for (; param < param_end; param++) for (; param < param_end; param++)
param->long_data_used= 0; param->long_data_used= 0;
} }
stmt->read_row_func= stmt_read_row_no_data; stmt->read_row_func= stmt_read_row_no_result_set;
if (mysql) if (mysql)
{ {
if ((int) stmt->state > (int) MYSQL_STMT_PREPARE_DONE) if ((int) stmt->state > (int) MYSQL_STMT_PREPARE_DONE)
......
...@@ -657,3 +657,22 @@ a b ...@@ -657,3 +657,22 @@ a b
1.1 1.100 1.1 1.100
2.1 2.100 2.1 2.100
DROP TABLE t1; DROP TABLE t1;
create table t1 (utext varchar(20) character set ucs2);
insert into t1 values ("lily");
insert into t1 values ("river");
prepare stmt from 'select utext from t1 where utext like ?';
set @param1='%%';
execute stmt using @param1;
utext
lily
river
execute stmt using @param1;
utext
lily
river
select utext from t1 where utext like '%%';
utext
lily
river
drop table t1;
deallocate prepare stmt;
...@@ -759,25 +759,6 @@ execute stmt using @a, @b; ...@@ -759,25 +759,6 @@ execute stmt using @a, @b;
?=? ?=?
1 1
deallocate prepare stmt; deallocate prepare stmt;
create table t1 (utext varchar(20) character set ucs2);
insert into t1 values ("lily");
insert into t1 values ("river");
prepare stmt from 'select utext from t1 where utext like ?';
set @param1='%%';
execute stmt using @param1;
utext
lily
river
execute stmt using @param1;
utext
lily
river
select utext from t1 where utext like '%%';
utext
lily
river
drop table t1;
deallocate prepare stmt;
create table t1 (a int); create table t1 (a int);
prepare stmt from "select ??"; prepare stmt from "select ??";
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
......
...@@ -3062,4 +3062,21 @@ l ...@@ -3062,4 +3062,21 @@ l
drop procedure bug6063| drop procedure bug6063|
drop procedure bug7088_1| drop procedure bug7088_1|
drop procedure bug7088_2| drop procedure bug7088_2|
drop procedure if exists bug9565_sub|
drop procedure if exists bug9565|
create procedure bug9565_sub()
begin
select * from t1;
end|
create procedure bug9565()
begin
insert into t1 values ("one", 1);
call bug9565_sub();
end|
call bug9565()|
id data
one 1
delete from t1|
drop procedure bug9565_sub|
drop procedure bug9565|
drop table t1,t2; drop table t1,t2;
...@@ -1235,3 +1235,13 @@ create table t1(a varchar(65537)); ...@@ -1235,3 +1235,13 @@ create table t1(a varchar(65537));
ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
create table t1(a varbinary(65537)); create table t1(a varbinary(65537));
ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
set @@sql_mode='traditional';
create table t1(a int, b date not null);
alter table t1 modify a bigint unsigned not null;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(20) unsigned NOT NULL,
`b` date NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
...@@ -1977,3 +1977,17 @@ A ...@@ -1977,3 +1977,17 @@ A
B B
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 ( bug_table_seq INTEGER NOT NULL);
CREATE OR REPLACE VIEW v1 AS SELECT * from t1;
DROP PROCEDURE IF EXISTS p1;
Warnings:
Note 1305 PROCEDURE p1 does not exist
CREATE PROCEDURE p1 ( )
BEGIN
DO (SELECT @next := IFNULL(max(bug_table_seq),0) + 1 FROM v1);
INSERT INTO t1 VALUES (1);
END //
CALL p1();
DROP PROCEDURE p1;
DROP VIEW v1;
DROP TABLE t1;
...@@ -427,3 +427,17 @@ INSERT INTO t1 VALUES ("1.1", 0), ("2.1", 0); ...@@ -427,3 +427,17 @@ INSERT INTO t1 VALUES ("1.1", 0), ("2.1", 0);
update t1 set b=a; update t1 set b=a;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#9442 Set parameter make query fail if column character set is UCS2
#
create table t1 (utext varchar(20) character set ucs2);
insert into t1 values ("lily");
insert into t1 values ("river");
prepare stmt from 'select utext from t1 where utext like ?';
set @param1='%%';
execute stmt using @param1;
execute stmt using @param1;
select utext from t1 where utext like '%%';
drop table t1;
deallocate prepare stmt;
...@@ -789,19 +789,6 @@ set @b='CHRISTINE'; ...@@ -789,19 +789,6 @@ set @b='CHRISTINE';
execute stmt using @a, @b; execute stmt using @a, @b;
deallocate prepare stmt; deallocate prepare stmt;
# #
# Bug#9442 Set parameter make query fail if column character set is UCS2
#
create table t1 (utext varchar(20) character set ucs2);
insert into t1 values ("lily");
insert into t1 values ("river");
prepare stmt from 'select utext from t1 where utext like ?';
set @param1='%%';
execute stmt using @param1;
execute stmt using @param1;
select utext from t1 where utext like '%%';
drop table t1;
deallocate prepare stmt;
#
# Bug#11299 "prepared statement makes wrong SQL syntax in binlog which stops # Bug#11299 "prepared statement makes wrong SQL syntax in binlog which stops
# replication": check that errouneous queries with placeholders are not # replication": check that errouneous queries with placeholders are not
# allowed # allowed
......
...@@ -3832,6 +3832,28 @@ drop procedure bug6063| ...@@ -3832,6 +3832,28 @@ drop procedure bug6063|
drop procedure bug7088_1| drop procedure bug7088_1|
drop procedure bug7088_2| drop procedure bug7088_2|
#
# BUG#9565: "Wrong locking in stored procedure if a sub-sequent procedure
# is called".
#
--disable_warnings
drop procedure if exists bug9565_sub|
drop procedure if exists bug9565|
--enable_warnings
create procedure bug9565_sub()
begin
select * from t1;
end|
create procedure bug9565()
begin
insert into t1 values ("one", 1);
call bug9565_sub();
end|
call bug9565()|
delete from t1|
drop procedure bug9565_sub|
drop procedure bug9565|
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
......
...@@ -1093,3 +1093,13 @@ set @@sql_mode='traditional'; ...@@ -1093,3 +1093,13 @@ set @@sql_mode='traditional';
create table t1(a varchar(65537)); create table t1(a varchar(65537));
--error 1074 --error 1074
create table t1(a varbinary(65537)); create table t1(a varbinary(65537));
#
# Bug #9881: problem with altering table
#
set @@sql_mode='traditional';
create table t1(a int, b date not null);
alter table t1 modify a bigint unsigned not null;
show create table t1;
drop table t1;
...@@ -1804,7 +1804,6 @@ drop table t1; ...@@ -1804,7 +1804,6 @@ drop table t1;
# #
# Test for bug #11771: wrong query_id in SELECT * FROM <view> # Test for bug #11771: wrong query_id in SELECT * FROM <view>
# #
CREATE TABLE t1 (f1 char) ENGINE = innodb; CREATE TABLE t1 (f1 char) ENGINE = innodb;
INSERT INTO t1 VALUES ('A'); INSERT INTO t1 VALUES ('A');
CREATE VIEW v1 AS SELECT * FROM t1; CREATE VIEW v1 AS SELECT * FROM t1;
...@@ -1815,3 +1814,21 @@ SELECT * FROM t1; ...@@ -1815,3 +1814,21 @@ SELECT * FROM t1;
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
#
# opening table in correct locking mode (BUG#9597)
#
CREATE TABLE t1 ( bug_table_seq INTEGER NOT NULL);
CREATE OR REPLACE VIEW v1 AS SELECT * from t1;
DROP PROCEDURE IF EXISTS p1;
delimiter //;
CREATE PROCEDURE p1 ( )
BEGIN
DO (SELECT @next := IFNULL(max(bug_table_seq),0) + 1 FROM v1);
INSERT INTO t1 VALUES (1);
END //
delimiter ;//
CALL p1();
DROP PROCEDURE p1;
DROP VIEW v1;
DROP TABLE t1;
...@@ -8488,7 +8488,8 @@ create_field::create_field(Field *old_field,Field *orig_field) ...@@ -8488,7 +8488,8 @@ create_field::create_field(Field *old_field,Field *orig_field)
else else
interval=0; interval=0;
def=0; def=0;
if (!old_field->is_real_null() && ! (flags & BLOB_FLAG) && if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) &&
!old_field->is_real_null() &&
old_field->ptr && orig_field) old_field->ptr && orig_field)
{ {
char buff[MAX_FIELD_WIDTH],*pos; char buff[MAX_FIELD_WIDTH],*pos;
......
...@@ -1041,6 +1041,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -1041,6 +1041,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
if (thd->locked_tables || thd->prelocked_mode) if (thd->locked_tables || thd->prelocked_mode)
{ // Using table locks { // Using table locks
TABLE *best_table= 0;
int best_distance= INT_MIN, distance;
for (table=thd->open_tables; table ; table=table->next) for (table=thd->open_tables; table ; table=table->next)
{ {
if (table->s->key_length == key_length && if (table->s->key_length == key_length &&
...@@ -1049,11 +1051,37 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -1049,11 +1051,37 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->query_id != thd->query_id && /* skip tables already used by this query */ table->query_id != thd->query_id && /* skip tables already used by this query */
!(thd->prelocked_mode && table->query_id)) !(thd->prelocked_mode && table->query_id))
{ {
table->query_id= thd->query_id; distance= ((int) table->reginfo.lock_type -
DBUG_PRINT("info",("Using locked table")); (int) table_list->lock_type);
goto reset; /*
Find a table that either has the exact lock type requested,
or has the best suitable lock. In case there is no locked
table that has an equal or higher lock than requested,
we still maitain the best_table to produce an error message
about wrong lock mode on the table. The best_table is changed
if bd < 0 <= d or bd < d < 0 or 0 <= d < bd.
distance < 0 - we have not enough high lock mode
distance > 0 - we have lock mode higher then we require
distance == 0 - we have lock mode exactly which we need
*/
if (best_distance < 0 && distance > best_distance ||
distance >= 0 && distance < best_distance)
{
best_distance= distance;
best_table= table;
if (best_distance == 0)
break;
}
} }
} }
if (best_table)
{
table= best_table;
table->query_id= thd->query_id;
DBUG_PRINT("info",("Using locked table"));
goto reset;
}
/* /*
is it view? is it view?
(it is work around to allow to open view with locked tables, (it is work around to allow to open view with locked tables,
......
...@@ -1170,12 +1170,22 @@ public: ...@@ -1170,12 +1170,22 @@ public:
This is to track items changed during execution of a prepared This is to track items changed during execution of a prepared
statement/stored procedure. It's created by statement/stored procedure. It's created by
register_item_tree_change() in memory root of THD, and freed in register_item_tree_change() in memory root of THD, and freed in
rollback_item_tree_changes(). For conventional execution it's always 0. rollback_item_tree_changes(). For conventional execution it's always
empty.
*/ */
Item_change_list change_list; Item_change_list change_list;
/* /*
Current prepared Query_arena if there one, or 0 A permanent memory area of the statement. For conventional
execution, the parsed tree and execution runtime reside in the same
memory root. In this case current_arena points to THD. In case of
a prepared statement or a stored procedure statement, thd->mem_root
conventionally points to runtime memory, and thd->current_arena
points to the memory of the PS/SP, where the parsed tree of the
statement resides. Whenever you need to perform a permanent
transformation of a parsed tree, you should allocate new memory in
current_arena, to allow correct re-execution of PS/SP.
Note: in the parser, current_arena == thd, even for PS/SP.
*/ */
Query_arena *current_arena; Query_arena *current_arena;
/* /*
......
...@@ -13315,7 +13315,7 @@ static void test_bug9992() ...@@ -13315,7 +13315,7 @@ static void test_bug9992()
DIE_UNLESS(rc == 1); /* Got errors, as expected */ DIE_UNLESS(rc == 1); /* Got errors, as expected */
if (!opt_silent) if (!opt_silent)
fprintf(stdout, "Got error, sa expected:\n [%d] %s\n", fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
mysql_errno(mysql1), mysql_error(mysql1)); mysql_errno(mysql1), mysql_error(mysql1));
mysql_close(mysql1); mysql_close(mysql1);
...@@ -13705,6 +13705,51 @@ static void test_bug11183() ...@@ -13705,6 +13705,51 @@ static void test_bug11183()
myquery(rc); myquery(rc);
} }
static void test_bug11037()
{
MYSQL_STMT *stmt;
int rc;
const char *stmt_text;
myheader("test_bug11037");
mysql_query(mysql, "drop table if exists t1");
rc= mysql_query(mysql, "create table t1 (id int not null)");
myquery(rc);
rc= mysql_query(mysql, "insert into t1 values (1)");
myquery(rc);
stmt_text= "select id FROM t1";
stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
/* expected error */
rc = mysql_stmt_fetch(stmt);
DIE_UNLESS(rc==1);
if (!opt_silent)
fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
rc = mysql_stmt_execute(stmt);
check_execute(stmt, rc);
rc = mysql_stmt_fetch(stmt);
DIE_UNLESS(rc==0);
rc = mysql_stmt_fetch(stmt);
DIE_UNLESS(rc==MYSQL_NO_DATA);
rc = mysql_stmt_fetch(stmt);
DIE_UNLESS(rc==MYSQL_NO_DATA);
mysql_stmt_close(stmt);
rc= mysql_query(mysql, "drop table t1");
myquery(rc);
}
/* /*
Read and parse arguments and MySQL options from my.cnf Read and parse arguments and MySQL options from my.cnf
*/ */
...@@ -13948,6 +13993,7 @@ static struct my_tests_st my_tests[]= { ...@@ -13948,6 +13993,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug10214", test_bug10214 }, { "test_bug10214", test_bug10214 },
{ "test_bug9735", test_bug9735 }, { "test_bug9735", test_bug9735 },
{ "test_bug11183", test_bug11183 }, { "test_bug11183", test_bug11183 },
{ "test_bug11037", test_bug11037 },
{ 0, 0 } { 0, 0 }
}; };
......
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