mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge quad.opbmk:/mnt/raid/alik/MySQL/devel/5.0
into quad.opbmk:/mnt/raid/alik/MySQL/devel/5.0-rt-merged
This commit is contained in:
commit
50c37672a7
8 changed files with 94 additions and 100 deletions
|
@ -2456,7 +2456,7 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
|
|||
int4store(buff+5, 1); /* iteration count */
|
||||
|
||||
res= test(cli_advanced_command(mysql, COM_STMT_EXECUTE, buff, sizeof(buff),
|
||||
packet, length, 1, NULL) ||
|
||||
packet, length, 1, stmt) ||
|
||||
(*mysql->methods->read_query_result)(mysql));
|
||||
stmt->affected_rows= mysql->affected_rows;
|
||||
stmt->server_status= mysql->server_status;
|
||||
|
@ -2673,7 +2673,7 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row)
|
|||
int4store(buff + 4, stmt->prefetch_rows); /* number of rows to fetch */
|
||||
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
|
||||
buff, sizeof(buff), NullS, 0,
|
||||
1, NULL))
|
||||
1, stmt))
|
||||
{
|
||||
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
|
||||
return 1;
|
||||
|
@ -3340,7 +3340,7 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
|
|||
*/
|
||||
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_SEND_LONG_DATA,
|
||||
buff, sizeof(buff), data,
|
||||
length, 1, NULL))
|
||||
length, 1, stmt))
|
||||
{
|
||||
set_stmt_errmsg(stmt, mysql->net.last_error,
|
||||
mysql->net.last_errno, mysql->net.sqlstate);
|
||||
|
@ -4737,6 +4737,13 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
|
|||
MYSQL_DATA *result= &stmt->result;
|
||||
DBUG_ENTER("mysql_stmt_store_result");
|
||||
|
||||
if (!mysql)
|
||||
{
|
||||
/* mysql can be reset in mysql_close called from mysql_reconnect */
|
||||
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
mysql= mysql->last_used_con;
|
||||
|
||||
if (!stmt->field_count)
|
||||
|
@ -4762,7 +4769,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
|
|||
int4store(buff, stmt->stmt_id);
|
||||
int4store(buff + 4, (int)~0); /* number of rows to fetch */
|
||||
if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff),
|
||||
NullS, 0, 1, NULL))
|
||||
NullS, 0, 1, stmt))
|
||||
{
|
||||
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
|
||||
DBUG_RETURN(1);
|
||||
|
@ -4949,7 +4956,7 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
|
|||
char buff[MYSQL_STMT_HEADER]; /* packet header: 4 bytes for stmt id */
|
||||
int4store(buff, stmt->stmt_id);
|
||||
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_RESET, buff,
|
||||
sizeof(buff), 0, 0, 0, NULL))
|
||||
sizeof(buff), 0, 0, 0, stmt))
|
||||
{
|
||||
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
|
||||
mysql->net.sqlstate);
|
||||
|
|
|
@ -140,4 +140,23 @@ select * from t3;
|
|||
c
|
||||
1
|
||||
drop table t1, t2, t3;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=innodb;
|
||||
CREATE TABLE t2(b INT, FOREIGN KEY(b) REFERENCES t1(a)) ENGINE=innodb;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
CREATE TRIGGER t1_bd BEFORE DELETE ON t1 FOR EACH ROW SET @a = 1;
|
||||
CREATE TRIGGER t1_ad AFTER DELETE ON t1 FOR EACH ROW SET @b = 1;
|
||||
SET @a = 0;
|
||||
SET @b = 0;
|
||||
TRUNCATE t1;
|
||||
SELECT @a, @b;
|
||||
@a @b
|
||||
0 0
|
||||
INSERT INTO t1 VALUES (1);
|
||||
DELETE FROM t1;
|
||||
SELECT @a, @b;
|
||||
@a @b
|
||||
1 1
|
||||
DROP TABLE t2, t1;
|
||||
End of 5.0 tests
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
# server or run mysql-test-run --debug mysql_client_test and check
|
||||
# var/log/mysql_client_test.trace
|
||||
|
||||
--exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1
|
||||
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1
|
||||
--exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1
|
||||
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1
|
||||
|
||||
# End of 4.1 tests
|
||||
echo ok;
|
||||
|
|
|
@ -128,5 +128,37 @@ drop table t1, t2, t3;
|
|||
disconnect connection_update;
|
||||
disconnect connection_aux;
|
||||
|
||||
#
|
||||
# Bug#34643: TRUNCATE crash if trigger and foreign key.
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=innodb;
|
||||
CREATE TABLE t2(b INT, FOREIGN KEY(b) REFERENCES t1(a)) ENGINE=innodb;
|
||||
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
||||
CREATE TRIGGER t1_bd BEFORE DELETE ON t1 FOR EACH ROW SET @a = 1;
|
||||
CREATE TRIGGER t1_ad AFTER DELETE ON t1 FOR EACH ROW SET @b = 1;
|
||||
|
||||
SET @a = 0;
|
||||
SET @b = 0;
|
||||
|
||||
TRUNCATE t1;
|
||||
|
||||
SELECT @a, @b;
|
||||
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
SELECT @a, @b;
|
||||
|
||||
DROP TABLE t2, t1;
|
||||
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
|
|
@ -669,11 +669,12 @@ my_bool
|
|||
cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
||||
const char *header, ulong header_length,
|
||||
const char *arg, ulong arg_length, my_bool skip_check,
|
||||
MYSQL_STMT *stmt __attribute__((unused)))
|
||||
MYSQL_STMT *stmt)
|
||||
{
|
||||
NET *net= &mysql->net;
|
||||
my_bool result= 1;
|
||||
init_sigpipe_variables
|
||||
my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE;
|
||||
DBUG_ENTER("cli_advanced_command");
|
||||
|
||||
/* Don't give sigpipe errors if the client doesn't want them */
|
||||
|
@ -681,7 +682,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
|||
|
||||
if (mysql->net.vio == 0)
|
||||
{ /* Do reconnect if possible */
|
||||
if (mysql_reconnect(mysql))
|
||||
if (mysql_reconnect(mysql) || stmt_skip)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (mysql->status != MYSQL_STATUS_READY ||
|
||||
|
@ -712,7 +713,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
|||
goto end;
|
||||
}
|
||||
end_server(mysql);
|
||||
if (mysql_reconnect(mysql))
|
||||
if (mysql_reconnect(mysql) || stmt_skip)
|
||||
goto end;
|
||||
if (net_write_command(net,(uchar) command, header, header_length,
|
||||
arg, arg_length))
|
||||
|
@ -2518,6 +2519,9 @@ my_bool mysql_reconnect(MYSQL *mysql)
|
|||
if (stmt->state != MYSQL_STMT_INIT_DONE)
|
||||
{
|
||||
stmt->mysql= 0;
|
||||
stmt->last_errno= CR_SERVER_LOST;
|
||||
strmov(stmt->last_error, ER(CR_SERVER_LOST));
|
||||
strmov(stmt->sqlstate, unknown_sqlstate);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||
READ_RECORD info;
|
||||
bool using_limit=limit != HA_POS_ERROR;
|
||||
bool transactional_table, safe_update, const_cond;
|
||||
bool triggers_applicable;
|
||||
ha_rows deleted;
|
||||
uint usable_index= MAX_KEY;
|
||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||
|
@ -93,6 +94,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||
|
||||
select_lex->no_error= thd->lex->ignore;
|
||||
|
||||
/* NOTE: TRUNCATE must not invoke triggers. */
|
||||
|
||||
triggers_applicable= table->triggers &&
|
||||
thd->lex->sql_command != SQLCOM_TRUNCATE;
|
||||
|
||||
/*
|
||||
Test if the user wants to delete all rows and deletion doesn't have
|
||||
any side-effects (because of triggers), so we can use optimized
|
||||
|
@ -102,8 +108,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||
*/
|
||||
if (!using_limit && const_cond && (!conds || conds->val_int()) &&
|
||||
!(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
|
||||
(thd->lex->sql_command == SQLCOM_TRUNCATE ||
|
||||
!(table->triggers && table->triggers->has_delete_triggers()))
|
||||
!(triggers_applicable && table->triggers->has_delete_triggers())
|
||||
)
|
||||
{
|
||||
deleted= table->file->records;
|
||||
|
@ -217,7 +222,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||
init_ftfuncs(thd, select_lex, 1);
|
||||
thd->proc_info="updating";
|
||||
|
||||
if (table->triggers)
|
||||
if (triggers_applicable)
|
||||
{
|
||||
table->triggers->mark_fields_used(thd, TRG_EVENT_DELETE);
|
||||
if (table->triggers->has_triggers(TRG_EVENT_DELETE,
|
||||
|
@ -239,7 +244,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||
if (!(select && select->skip_record())&& !thd->net.report_error )
|
||||
{
|
||||
|
||||
if (table->triggers &&
|
||||
if (triggers_applicable &&
|
||||
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
|
||||
TRG_ACTION_BEFORE, FALSE))
|
||||
{
|
||||
|
@ -250,7 +255,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||
if (!(error=table->file->delete_row(table->record[0])))
|
||||
{
|
||||
deleted++;
|
||||
if (table->triggers &&
|
||||
if (triggers_applicable &&
|
||||
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
|
||||
TRG_ACTION_AFTER, FALSE))
|
||||
{
|
||||
|
|
|
@ -2516,7 +2516,7 @@ void mysql_stmt_close(THD *thd, char *packet)
|
|||
DBUG_ENTER("mysql_stmt_close");
|
||||
|
||||
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close")))
|
||||
DBUG_VOID_RETURN;
|
||||
goto out;
|
||||
|
||||
/*
|
||||
The only way currently a statement can be deallocated when it's
|
||||
|
@ -2525,6 +2525,9 @@ void mysql_stmt_close(THD *thd, char *packet)
|
|||
DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE));
|
||||
(void) stmt->deallocate();
|
||||
|
||||
out:
|
||||
/* clear errors, response packet is not expected */
|
||||
thd->clear_error();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -2591,10 +2594,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
|
|||
#ifndef EMBEDDED_LIBRARY
|
||||
/* Minimal size of long data packet is 6 bytes */
|
||||
if (packet_length <= MYSQL_LONG_DATA_HEADER)
|
||||
{
|
||||
my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_send_long_data");
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
stmt_id= uint4korr(packet);
|
||||
|
@ -2602,7 +2602,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
|
|||
|
||||
if (!(stmt=find_prepared_statement(thd, stmt_id,
|
||||
"mysql_stmt_send_long_data")))
|
||||
DBUG_VOID_RETURN;
|
||||
goto out;
|
||||
|
||||
param_number= uint2korr(packet);
|
||||
packet+= 2;
|
||||
|
@ -2614,7 +2614,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
|
|||
stmt->last_errno= ER_WRONG_ARGUMENTS;
|
||||
sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS),
|
||||
"mysql_stmt_send_long_data");
|
||||
DBUG_VOID_RETURN;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2630,6 +2630,10 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
|
|||
stmt->last_errno= ER_OUTOFMEMORY;
|
||||
sprintf(stmt->last_error, ER(ER_OUTOFMEMORY), 0);
|
||||
}
|
||||
|
||||
out:
|
||||
/* clear errors, response packet is not expected */
|
||||
thd->clear_error();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
|
@ -11746,6 +11746,7 @@ static void test_bug5194()
|
|||
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_execute(stmt, rc);
|
||||
mysql_stmt_reset(stmt);
|
||||
}
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
@ -15952,83 +15953,6 @@ static void test_bug27592()
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static void test_bug29948()
|
||||
{
|
||||
MYSQL *dbc=NULL;
|
||||
MYSQL_STMT *stmt=NULL;
|
||||
MYSQL_BIND bind;
|
||||
|
||||
int res=0;
|
||||
my_bool auto_reconnect=1, error=0, is_null=0;
|
||||
char kill_buf[20];
|
||||
const char *query;
|
||||
int buf;
|
||||
unsigned long length, cursor_type;
|
||||
|
||||
dbc = mysql_init(NULL);
|
||||
DIE_UNLESS(dbc);
|
||||
|
||||
mysql_options(dbc, MYSQL_OPT_RECONNECT, (char*)&auto_reconnect);
|
||||
if (!mysql_real_connect(dbc, opt_host, opt_user,
|
||||
opt_password, current_db, opt_port,
|
||||
opt_unix_socket,
|
||||
(CLIENT_FOUND_ROWS | CLIENT_MULTI_STATEMENTS |
|
||||
CLIENT_MULTI_RESULTS)))
|
||||
{
|
||||
printf("connection failed: %s (%d)", mysql_error(dbc),
|
||||
mysql_errno(dbc));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bzero(&bind, sizeof(bind));
|
||||
bind.buffer_type= MYSQL_TYPE_LONG;
|
||||
bind.buffer= (char *)&buf;
|
||||
bind.is_null= &is_null;
|
||||
bind.error= &error;
|
||||
bind.length= &length;
|
||||
|
||||
res= mysql_query(dbc, "DROP TABLE IF EXISTS t1");
|
||||
myquery(res);
|
||||
res= mysql_query(dbc, "CREATE TABLE t1 (a INT)");
|
||||
myquery(res);
|
||||
res= mysql_query(dbc, "INSERT INTO t1 VALUES(1)");
|
||||
myquery(res);
|
||||
|
||||
stmt= mysql_stmt_init(dbc);
|
||||
check_stmt(stmt);
|
||||
|
||||
cursor_type= CURSOR_TYPE_READ_ONLY;
|
||||
res= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void *)&cursor_type);
|
||||
myquery(res);
|
||||
|
||||
query= "SELECT * from t1 where a=?";
|
||||
res= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||
myquery(res);
|
||||
|
||||
res= mysql_stmt_bind_param(stmt, &bind);
|
||||
myquery(res);
|
||||
|
||||
res= mysql_stmt_execute(stmt);
|
||||
check_execute(stmt, res);
|
||||
|
||||
res= mysql_stmt_bind_result(stmt,&bind);
|
||||
check_execute(stmt, res);
|
||||
|
||||
sprintf(kill_buf, "kill %ld", dbc->thread_id);
|
||||
mysql_query(dbc, kill_buf);
|
||||
|
||||
res= mysql_stmt_store_result(stmt);
|
||||
DIE_UNLESS(res);
|
||||
|
||||
mysql_stmt_free_result(stmt);
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_query(dbc, "DROP TABLE t1");
|
||||
mysql_close(dbc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
|
||||
|
@ -16556,7 +16480,6 @@ static struct my_tests_st my_tests[]= {
|
|||
{ "test_bug28505", test_bug28505 },
|
||||
{ "test_bug28934", test_bug28934 },
|
||||
{ "test_bug27592", test_bug27592 },
|
||||
/* { "test_bug29948", test_bug29948 }, Bug#35103 */
|
||||
{ "test_bug29306", test_bug29306 },
|
||||
{ "test_bug31669", test_bug31669 },
|
||||
{ "test_bug32265", test_bug32265 },
|
||||
|
|
Loading…
Reference in a new issue