mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 13:02:28 +01:00
Merge svojtovich@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/svoj/devel/mysql/yassl-mysql-5.0
This commit is contained in:
commit
8209f84d49
11 changed files with 148 additions and 61 deletions
|
@ -672,3 +672,17 @@ select default(t30.s1) from t30;
|
|||
end|
|
||||
drop procedure bug10969|
|
||||
drop table t1|
|
||||
prepare stmt from "select 1";
|
||||
create procedure p() deallocate prepare stmt;
|
||||
ERROR 0A000: DEALLOCATE is not allowed in stored procedures
|
||||
create function f() returns int begin deallocate prepare stmt;
|
||||
ERROR 0A000: DEALLOCATE is not allowed in stored procedures
|
||||
create procedure p() prepare stmt from "select 1";
|
||||
ERROR 0A000: PREPARE is not allowed in stored procedures
|
||||
create function f() returns int begin prepare stmt from "select 1";
|
||||
ERROR 0A000: PREPARE is not allowed in stored procedures
|
||||
create procedure p() execute stmt;
|
||||
ERROR 0A000: EXECUTE is not allowed in stored procedures
|
||||
create function f() returns int begin execute stmt;
|
||||
ERROR 0A000: EXECUTE is not allowed in stored procedures
|
||||
deallocate prepare stmt;
|
||||
|
|
|
@ -40,3 +40,18 @@ Id User Host db Command Time State Info
|
|||
unlock tables;
|
||||
drop procedure bug9486;
|
||||
drop table t1, t2;
|
||||
drop procedure if exists bug11158;
|
||||
create procedure bug11158() delete t1 from t1, t2 where t1.id = t2.id;
|
||||
create table t1 (id int, j int);
|
||||
insert into t1 values (1, 1), (2, 2);
|
||||
create table t2 (id int);
|
||||
insert into t2 values (1);
|
||||
call bug11158();
|
||||
select * from t1;
|
||||
id j
|
||||
2 2
|
||||
lock tables t2 read;
|
||||
call bug11158();
|
||||
unlock tables;
|
||||
drop procedure bug11158;
|
||||
drop table t1, t2;
|
||||
|
|
|
@ -965,3 +965,24 @@ drop procedure bug10969|
|
|||
drop table t1|
|
||||
|
||||
delimiter ;|
|
||||
|
||||
#
|
||||
# Bug#10975, #10605, #7115: Dynamic SQL by means of
|
||||
# PREPARE/EXECUTE/DEALLOCATE is not supported yet.
|
||||
# Check that an error message is returned.
|
||||
#
|
||||
prepare stmt from "select 1";
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create procedure p() deallocate prepare stmt;
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create function f() returns int begin deallocate prepare stmt;
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create procedure p() prepare stmt from "select 1";
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create function f() returns int begin prepare stmt from "select 1";
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create procedure p() execute stmt;
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create function f() returns int begin execute stmt;
|
||||
deallocate prepare stmt;
|
||||
|
||||
|
|
|
@ -84,6 +84,32 @@ reap;
|
|||
drop procedure bug9486;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# BUG#11158: Can't perform multi-delete in stored procedure
|
||||
#
|
||||
--disable_warnings
|
||||
drop procedure if exists bug11158;
|
||||
--enable_warnings
|
||||
create procedure bug11158() delete t1 from t1, t2 where t1.id = t2.id;
|
||||
create table t1 (id int, j int);
|
||||
insert into t1 values (1, 1), (2, 2);
|
||||
create table t2 (id int);
|
||||
insert into t2 values (1);
|
||||
# Procedure should work and cause proper effect (delete only first row)
|
||||
call bug11158();
|
||||
select * from t1;
|
||||
# Also let us test that we obtain only read (and thus non exclusive) lock
|
||||
# for table from which we are not going to delete rows.
|
||||
connection con2root;
|
||||
lock tables t2 read;
|
||||
connection con1root;
|
||||
call bug11158();
|
||||
connection con2root;
|
||||
unlock tables;
|
||||
connection con1root;
|
||||
# Clean-up
|
||||
drop procedure bug11158;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
|
|
|
@ -247,10 +247,10 @@ Ndbfs::readWriteRequest(int action, Signal * signal)
|
|||
AsyncFile* openFile = theOpenFiles.find(filePointer);
|
||||
|
||||
const NewVARIABLE *myBaseAddrRef = &getBat(blockNumber)[fsRWReq->varIndex];
|
||||
unsigned int tPageSize;
|
||||
unsigned int tClusterSize;
|
||||
unsigned int tNRR;
|
||||
unsigned int tPageOffset;
|
||||
UintPtr tPageSize;
|
||||
UintPtr tClusterSize;
|
||||
UintPtr tNRR;
|
||||
UintPtr tPageOffset;
|
||||
char* tWA;
|
||||
FsRef::NdbfsErrorCodeType errorCode;
|
||||
|
||||
|
@ -294,8 +294,8 @@ Ndbfs::readWriteRequest(int action, Signal * signal)
|
|||
jam();
|
||||
for (unsigned int i = 0; i < fsRWReq->numberOfPages; i++) {
|
||||
jam();
|
||||
const Uint32 varIndex = fsRWReq->data.listOfPair[i].varIndex;
|
||||
const Uint32 fileOffset = fsRWReq->data.listOfPair[i].fileOffset;
|
||||
const UintPtr varIndex = fsRWReq->data.listOfPair[i].varIndex;
|
||||
const UintPtr fileOffset = fsRWReq->data.listOfPair[i].fileOffset;
|
||||
if (varIndex >= tNRR) {
|
||||
jam();
|
||||
errorCode = FsRef::fsErrInvalidParameters;
|
||||
|
@ -316,8 +316,8 @@ Ndbfs::readWriteRequest(int action, Signal * signal)
|
|||
errorCode = FsRef::fsErrInvalidParameters;
|
||||
goto error;
|
||||
}//if
|
||||
const Uint32 varIndex = fsRWReq->data.arrayOfPages.varIndex;
|
||||
const Uint32 fileOffset = fsRWReq->data.arrayOfPages.fileOffset;
|
||||
const UintPtr varIndex = fsRWReq->data.arrayOfPages.varIndex;
|
||||
const UintPtr fileOffset = fsRWReq->data.arrayOfPages.fileOffset;
|
||||
|
||||
request->par.readWrite.pages[0].offset = fileOffset * tPageSize;
|
||||
request->par.readWrite.pages[0].size = tPageSize * fsRWReq->numberOfPages;
|
||||
|
@ -334,7 +334,7 @@ Ndbfs::readWriteRequest(int action, Signal * signal)
|
|||
|
||||
for (unsigned int i = 0; i < fsRWReq->numberOfPages; i++) {
|
||||
jam();
|
||||
Uint32 varIndex = fsRWReq->data.listOfMemPages.varIndex[i];
|
||||
UintPtr varIndex = fsRWReq->data.listOfMemPages.varIndex[i];
|
||||
|
||||
if (varIndex >= tNRR) {
|
||||
jam();
|
||||
|
|
|
@ -482,7 +482,7 @@ bool check_merge_table_access(THD *thd, char *db,
|
|||
TABLE_LIST *table_list);
|
||||
bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc);
|
||||
bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
|
||||
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count);
|
||||
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables);
|
||||
bool mysql_multi_update_prepare(THD *thd);
|
||||
bool mysql_multi_delete_prepare(THD *thd);
|
||||
bool mysql_insert_select_prepare(THD *thd);
|
||||
|
@ -577,6 +577,7 @@ void mysql_init_query(THD *thd, uchar *buf, uint length);
|
|||
bool mysql_new_select(LEX *lex, bool move_down);
|
||||
void create_select_for_variable(const char *var_name);
|
||||
void mysql_init_multi_delete(LEX *lex);
|
||||
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
|
||||
void init_max_user_conn(void);
|
||||
void init_update_queries(void);
|
||||
void free_max_user_conn(void);
|
||||
|
|
|
@ -42,7 +42,6 @@ static my_bool open_new_frm(const char *path, const char *alias,
|
|||
uint db_stat, uint prgflag,
|
||||
uint ha_open_flags, TABLE *outparam,
|
||||
TABLE_LIST *table_desc, MEM_ROOT *mem_root);
|
||||
static void relink_tables_for_multidelete(THD *thd);
|
||||
|
||||
extern "C" byte *table_cache_key(const byte *record,uint *length,
|
||||
my_bool not_used __attribute__((unused)))
|
||||
|
@ -2089,7 +2088,6 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
|
|||
(thd->fill_derived_tables() &&
|
||||
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
relink_tables_for_multidelete(thd);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -2119,36 +2117,10 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables)
|
|||
if (open_tables(thd, &tables, &counter) ||
|
||||
mysql_handle_derived(thd->lex, &mysql_derived_prepare))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
relink_tables_for_multidelete(thd); // Not really needed, but
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Let us propagate pointers to open tables from global table list
|
||||
to table lists for multi-delete
|
||||
*/
|
||||
|
||||
static void relink_tables_for_multidelete(THD *thd)
|
||||
{
|
||||
if (thd->lex->all_selects_list->next_select_in_list())
|
||||
{
|
||||
for (SELECT_LEX *sl= thd->lex->all_selects_list;
|
||||
sl;
|
||||
sl= sl->next_select_in_list())
|
||||
{
|
||||
for (TABLE_LIST *cursor= (TABLE_LIST *) sl->table_list.first;
|
||||
cursor;
|
||||
cursor=cursor->next_local)
|
||||
{
|
||||
if (cursor->correspondent_table)
|
||||
cursor->table= cursor->correspondent_table->table;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Mark all real tables in the list as free for reuse.
|
||||
|
||||
|
|
|
@ -751,7 +751,12 @@ typedef struct st_lex
|
|||
uint grant, grant_tot_col, which_columns;
|
||||
uint fk_delete_opt, fk_update_opt, fk_match_option;
|
||||
uint slave_thd_opt, start_transaction_opt;
|
||||
uint table_count; /* used when usual update transformed in multiupdate */
|
||||
/*
|
||||
In LEX representing update which were transformed to multi-update
|
||||
stores total number of tables. For LEX representing multi-delete
|
||||
holds number of tables from which we will delete records.
|
||||
*/
|
||||
uint table_count;
|
||||
uint8 describe;
|
||||
uint8 derived_tables;
|
||||
uint8 create_view_algorithm;
|
||||
|
|
|
@ -3291,10 +3291,9 @@ end_with_restore_list:
|
|||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
TABLE_LIST *aux_tables=
|
||||
(TABLE_LIST *)thd->lex->auxilliary_table_list.first;
|
||||
uint table_count;
|
||||
multi_delete *result;
|
||||
|
||||
if ((res= multi_delete_precheck(thd, all_tables, &table_count)))
|
||||
if ((res= multi_delete_precheck(thd, all_tables)))
|
||||
break;
|
||||
|
||||
/* condition will be TRUE on SP re-excuting */
|
||||
|
@ -3311,7 +3310,7 @@ end_with_restore_list:
|
|||
goto error;
|
||||
|
||||
if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables,
|
||||
table_count)))
|
||||
lex->table_count)))
|
||||
{
|
||||
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
||||
select_lex->get_table_list(),
|
||||
|
@ -6801,23 +6800,19 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
|
|||
multi_delete_precheck()
|
||||
thd Thread handler
|
||||
tables Global/local table list
|
||||
table_count Pointer to table counter
|
||||
|
||||
RETURN VALUE
|
||||
FALSE OK
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
|
||||
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||
TABLE_LIST *aux_tables=
|
||||
(TABLE_LIST *)thd->lex->auxilliary_table_list.first;
|
||||
TABLE_LIST *target_tbl;
|
||||
DBUG_ENTER("multi_delete_precheck");
|
||||
|
||||
*table_count= 0;
|
||||
|
||||
/* sql_yacc guarantees that tables and aux_tables are not zero */
|
||||
DBUG_ASSERT(aux_tables != 0);
|
||||
if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) ||
|
||||
|
@ -6830,9 +6825,35 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
|
|||
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
for (target_tbl= aux_tables; target_tbl; target_tbl= target_tbl->next_local)
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Link tables in auxilary table list of multi-delete with corresponding
|
||||
elements in main table list, and set proper locks for them.
|
||||
|
||||
SYNOPSIS
|
||||
multi_delete_set_locks_and_link_aux_tables()
|
||||
lex - pointer to LEX representing multi-delete
|
||||
|
||||
RETURN VALUE
|
||||
FALSE - success
|
||||
TRUE - error
|
||||
*/
|
||||
|
||||
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
|
||||
{
|
||||
TABLE_LIST *tables= (TABLE_LIST*)lex->select_lex.table_list.first;
|
||||
TABLE_LIST *target_tbl;
|
||||
DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
|
||||
|
||||
lex->table_count= 0;
|
||||
|
||||
for (target_tbl= (TABLE_LIST *)lex->auxilliary_table_list.first;
|
||||
target_tbl; target_tbl= target_tbl->next_local)
|
||||
{
|
||||
(*table_count)++;
|
||||
lex->table_count++;
|
||||
/* All tables in aux_tables must be found in FROM PART */
|
||||
TABLE_LIST *walk;
|
||||
for (walk= tables; walk; walk= walk->next_local)
|
||||
|
@ -6850,14 +6871,6 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
|
|||
}
|
||||
walk->lock_type= target_tbl->lock_type;
|
||||
target_tbl->correspondent_table= walk; // Remember corresponding table
|
||||
|
||||
/* in case of subselects, we need to set lock_type in
|
||||
* corresponding table in list of all tables */
|
||||
if (walk->correspondent_table)
|
||||
{
|
||||
target_tbl->correspondent_table= walk->correspondent_table;
|
||||
walk->correspondent_table->lock_type= walk->lock_type;
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
|
|
@ -1402,8 +1402,6 @@ static bool mysql_test_multiupdate(Prepared_statement *stmt,
|
|||
static bool mysql_test_multidelete(Prepared_statement *stmt,
|
||||
TABLE_LIST *tables)
|
||||
{
|
||||
uint fake_counter;
|
||||
|
||||
stmt->thd->lex->current_select= &stmt->thd->lex->select_lex;
|
||||
if (add_item_to_list(stmt->thd, new Item_null()))
|
||||
{
|
||||
|
@ -1411,7 +1409,7 @@ static bool mysql_test_multidelete(Prepared_statement *stmt,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (multi_delete_precheck(stmt->thd, tables, &fake_counter) ||
|
||||
if (multi_delete_precheck(stmt->thd, tables) ||
|
||||
select_like_stmt_test_with_open_n_lock(stmt, tables,
|
||||
&mysql_multi_delete_prepare,
|
||||
OPTION_SETUP_TABLES_DONE))
|
||||
|
|
|
@ -919,6 +919,11 @@ deallocate:
|
|||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
}
|
||||
if (lex->sphead)
|
||||
{
|
||||
my_error(ER_SP_BADSTATEMENT, MYF(0), "DEALLOCATE");
|
||||
YYABORT;
|
||||
}
|
||||
lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
|
||||
lex->prepared_stmt_name= $3;
|
||||
};
|
||||
|
@ -939,6 +944,11 @@ prepare:
|
|||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
}
|
||||
if (lex->sphead)
|
||||
{
|
||||
my_error(ER_SP_BADSTATEMENT, MYF(0), "PREPARE");
|
||||
YYABORT;
|
||||
}
|
||||
lex->sql_command= SQLCOM_PREPARE;
|
||||
lex->prepared_stmt_name= $2;
|
||||
};
|
||||
|
@ -969,6 +979,11 @@ execute:
|
|||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
}
|
||||
if (lex->sphead)
|
||||
{
|
||||
my_error(ER_SP_BADSTATEMENT, MYF(0), "EXECUTE");
|
||||
YYABORT;
|
||||
}
|
||||
lex->sql_command= SQLCOM_EXECUTE;
|
||||
lex->prepared_stmt_name= $2;
|
||||
}
|
||||
|
@ -6132,10 +6147,17 @@ single_multi:
|
|||
| table_wild_list
|
||||
{ mysql_init_multi_delete(Lex); }
|
||||
FROM join_table_list where_clause
|
||||
{
|
||||
if (multi_delete_set_locks_and_link_aux_tables(Lex))
|
||||
YYABORT;
|
||||
}
|
||||
| FROM table_wild_list
|
||||
{ mysql_init_multi_delete(Lex); }
|
||||
USING join_table_list where_clause
|
||||
{}
|
||||
{
|
||||
if (multi_delete_set_locks_and_link_aux_tables(Lex))
|
||||
YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
table_wild_list:
|
||||
|
|
Loading…
Reference in a new issue