mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge branch '10.6' into 10.11
This commit is contained in:
@@ -22062,6 +22062,452 @@ static void test_mdev_30159()
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/**
|
||||
Test case for bulk UPDATE against a table with an active AFTER UPDATE
|
||||
trigger.
|
||||
*/
|
||||
|
||||
static void test_mdev_34718_au()
|
||||
{
|
||||
int rc;
|
||||
MYSQL_STMT *stmt_update;
|
||||
MYSQL_BIND bind[2];
|
||||
unsigned int vals[]= { 1, 2, 3};
|
||||
unsigned int new_vals[]= { 5, 6, 7};
|
||||
unsigned int vals_array_len= 3;
|
||||
my_ulonglong row_count;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
const char *update_stmt= "UPDATE t1 SET a = ? WHERE a = ?";
|
||||
const char *update_stmt_state_info;
|
||||
|
||||
myheader("test_mdev_34718_au");
|
||||
|
||||
/* Set up test's environment */
|
||||
rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE t2 (a INT)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2), (3)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TRIGGER t1_au AFTER UPDATE ON t1 "
|
||||
"FOR EACH ROW BEGIN INSERT INTO t2 (a) VALUES (NEW.a); END;");
|
||||
|
||||
stmt_update= mysql_stmt_init(mysql);
|
||||
check_stmt(stmt_update);
|
||||
|
||||
rc= mysql_stmt_prepare(stmt_update, update_stmt, strlen(update_stmt));
|
||||
check_execute(stmt_update, rc);
|
||||
|
||||
memset(&bind[0], 0, sizeof(MYSQL_BIND));
|
||||
memset(&bind[1], 0, sizeof(MYSQL_BIND));
|
||||
|
||||
bind[0].buffer_type= MYSQL_TYPE_LONG;
|
||||
bind[0].buffer= new_vals;
|
||||
|
||||
bind[1].buffer_type= MYSQL_TYPE_LONG;
|
||||
bind[1].buffer= vals;
|
||||
|
||||
/*
|
||||
Every input positional parameter is bound with array of 3 elements
|
||||
containing actual values for positional parameters
|
||||
*/
|
||||
rc= mysql_stmt_attr_set(stmt_update, STMT_ATTR_ARRAY_SIZE, &vals_array_len);
|
||||
check_execute(stmt_update, rc);
|
||||
|
||||
rc= mysql_stmt_bind_param(stmt_update, bind);
|
||||
check_execute(stmt_update, rc);
|
||||
|
||||
/*
|
||||
Execution of this prepared statement replaces the table rows (1), (2), (3)
|
||||
with values (5), (6), (7)
|
||||
*/
|
||||
rc= mysql_stmt_execute(stmt_update);
|
||||
check_execute(stmt_update, rc);
|
||||
|
||||
/*
|
||||
Check that the BULK UPDATE statement affects exactly 3 rows
|
||||
*/
|
||||
row_count = mysql_stmt_affected_rows(stmt_update);
|
||||
DIE_UNLESS(row_count == 3);
|
||||
|
||||
update_stmt_state_info= mysql_info(mysql);
|
||||
|
||||
/*
|
||||
Check that information about executed operation is matched with
|
||||
the expected result
|
||||
*/
|
||||
DIE_UNLESS(!strcmp("Rows matched: 3 Changed: 3 Warnings: 0",
|
||||
update_stmt_state_info));
|
||||
|
||||
/*
|
||||
* Check that the AFTER UPDATE trigger of the table t1 does work correctly
|
||||
* and inserts the rows (5), (6), (7) into the table t2.
|
||||
*/
|
||||
rc= mysql_query(mysql, "SELECT 't1' tname, a FROM t1 "
|
||||
"UNION SELECT 't2' tname, a FROM t2 ORDER BY tname, a");
|
||||
myquery(rc);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
|
||||
row = mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 5);
|
||||
|
||||
row = mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 6);
|
||||
|
||||
row = mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 7);
|
||||
|
||||
row = mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 5);
|
||||
|
||||
row = mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 6);
|
||||
|
||||
row = mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 7);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(row == NULL);
|
||||
|
||||
mysql_free_result(result);
|
||||
|
||||
mysql_stmt_close(stmt_update);
|
||||
|
||||
/* Clean up */
|
||||
rc= mysql_query(mysql, "DROP TABLE t1, t2");
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test case for bulk UPDATE against a table with an active BEFORE UPDATE
|
||||
trigger.
|
||||
*/
|
||||
|
||||
static void test_mdev_34718_bu()
|
||||
{
|
||||
int rc;
|
||||
MYSQL_STMT *stmt_update;
|
||||
MYSQL_BIND bind[2];
|
||||
unsigned int vals[]= { 1, 2, 3};
|
||||
unsigned int new_vals[]= { 5, 6, 7};
|
||||
unsigned int vals_array_len= 3;
|
||||
my_ulonglong row_count;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
const char *update_stmt= "UPDATE t1 SET a = ? WHERE a = ?";
|
||||
const char *update_stmt_state_info;
|
||||
|
||||
myheader("test_mdev_34718_bu");
|
||||
|
||||
/* Set up test's environment */
|
||||
rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE t2 (a INT)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2), (3)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TRIGGER t1_au BEFORE UPDATE ON t1 "
|
||||
"FOR EACH ROW BEGIN INSERT INTO t2 (a) VALUES (NEW.a); END;");
|
||||
|
||||
/* Initialize the prepared statement and set it up for bulk operations */
|
||||
stmt_update= mysql_stmt_init(mysql);
|
||||
check_stmt(stmt_update);
|
||||
|
||||
rc= mysql_stmt_prepare(stmt_update, update_stmt, strlen(update_stmt));
|
||||
check_execute(stmt_update, rc);
|
||||
|
||||
memset(&bind[0], 0, sizeof(MYSQL_BIND));
|
||||
memset(&bind[1], 0, sizeof(MYSQL_BIND));
|
||||
|
||||
bind[0].buffer_type= MYSQL_TYPE_LONG;
|
||||
bind[0].buffer= new_vals;
|
||||
|
||||
bind[1].buffer_type= MYSQL_TYPE_LONG;
|
||||
bind[1].buffer= vals;
|
||||
|
||||
/*
|
||||
Every input positional parameter is bound with array of 3 elements
|
||||
containing actual values for positional parameters
|
||||
*/
|
||||
rc= mysql_stmt_attr_set(stmt_update, STMT_ATTR_ARRAY_SIZE, &vals_array_len);
|
||||
check_execute(stmt_update, rc);
|
||||
|
||||
rc= mysql_stmt_bind_param(stmt_update, bind);
|
||||
check_execute(stmt_update, rc);
|
||||
|
||||
/*
|
||||
Execution of this prepared statement replaces the table rows (1), (2), (3)
|
||||
with values (5), (6), (7)
|
||||
*/
|
||||
rc= mysql_stmt_execute(stmt_update);
|
||||
check_execute(stmt_update, rc);
|
||||
|
||||
/*
|
||||
Check that the BULK UPDATE statement affects exactly 3 rows
|
||||
*/
|
||||
row_count= mysql_stmt_affected_rows(stmt_update);
|
||||
DIE_UNLESS(row_count == 3);
|
||||
|
||||
update_stmt_state_info= mysql_info(mysql);
|
||||
|
||||
/*
|
||||
Check that information about executed operation is matched with
|
||||
the expected result
|
||||
*/
|
||||
DIE_UNLESS(!strcmp("Rows matched: 3 Changed: 3 Warnings: 0",
|
||||
update_stmt_state_info));
|
||||
|
||||
/*
|
||||
* Check that the BEFORE UPDATE trigger of the table t1 does work correctly
|
||||
* and inserts the rows (5), (6), (7) into the table t2.
|
||||
*/
|
||||
rc= mysql_query(mysql, "SELECT 't1' tname, a FROM t1 "
|
||||
"UNION SELECT 't2' tname, a FROM t2 ORDER BY tname, a");
|
||||
myquery(rc);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 5);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 6);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 7);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 5);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 6);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 7);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(row == NULL);
|
||||
|
||||
mysql_free_result(result);
|
||||
|
||||
mysql_stmt_close(stmt_update);
|
||||
|
||||
/* Clean up */
|
||||
rc= mysql_query(mysql, "DROP TABLE t1, t2");
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test case for bulk DELETE against a table with an active BEFORE DELETE
|
||||
trigger.
|
||||
*/
|
||||
|
||||
static void test_mdev_34718_bd()
|
||||
{
|
||||
int rc;
|
||||
MYSQL_STMT *stmt_delete;
|
||||
MYSQL_BIND bind[1];
|
||||
unsigned int vals[]= { 1, 2, 3};
|
||||
unsigned int vals_array_len= 3;
|
||||
my_ulonglong row_count;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
const char *delete_stmt= "DELETE FROM t1 WHERE a = ?";
|
||||
|
||||
myheader("test_mdev_34718_bd");
|
||||
|
||||
/* Set up test's environment */
|
||||
rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE t2 (a INT)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2), (3)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TRIGGER t1_bd BEFORE DELETE ON t1 "
|
||||
"FOR EACH ROW BEGIN INSERT INTO t2 (a) VALUES (OLD.a); END;");
|
||||
|
||||
/* Initialize the prepared statement and set it up for bulk operations */
|
||||
stmt_delete= mysql_stmt_init(mysql);
|
||||
check_stmt(stmt_delete);
|
||||
|
||||
rc= mysql_stmt_prepare(stmt_delete, delete_stmt, strlen(delete_stmt));
|
||||
check_execute(stmt_delete, rc);
|
||||
|
||||
memset(&bind[0], 0, sizeof(MYSQL_BIND));
|
||||
|
||||
bind[0].buffer_type= MYSQL_TYPE_LONG;
|
||||
bind[0].buffer= vals;
|
||||
|
||||
/*
|
||||
Input positional parameter is bound with array of 3 elements
|
||||
containing actual values for the positional parameter
|
||||
*/
|
||||
rc= mysql_stmt_attr_set(stmt_delete, STMT_ATTR_ARRAY_SIZE, &vals_array_len);
|
||||
check_execute(stmt_delete, rc);
|
||||
|
||||
rc= mysql_stmt_bind_param(stmt_delete, bind);
|
||||
check_execute(stmt_delete, rc);
|
||||
|
||||
/*
|
||||
Execution of this prepared statement deletes the rows (1), (2), (3)
|
||||
from the table t1 and inserts the rows (1), (2), (3) into the table t2
|
||||
in result of firing the BEFORE DELETE trigger
|
||||
*/
|
||||
rc= mysql_stmt_execute(stmt_delete);
|
||||
check_execute(stmt_delete, rc);
|
||||
|
||||
/*
|
||||
Check that the BULK DELETE statement affects exactly 3 rows
|
||||
*/
|
||||
row_count= mysql_stmt_affected_rows(stmt_delete);
|
||||
DIE_UNLESS(row_count == 3);
|
||||
|
||||
/*
|
||||
* Check that the BEFORE DELETE trigger of the table t1 does work correctly
|
||||
* and inserts the rows (1), (2), (3) into the table t2.
|
||||
*/
|
||||
rc= mysql_query(mysql, "SELECT 't1' tname, a FROM t1 "
|
||||
"UNION SELECT 't2' tname, a FROM t2 ORDER BY tname, a");
|
||||
myquery(rc);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 1);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 2);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 3);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(row == NULL);
|
||||
|
||||
mysql_free_result(result);
|
||||
|
||||
mysql_stmt_close(stmt_delete);
|
||||
|
||||
/* Clean up */
|
||||
rc= mysql_query(mysql, "DROP TABLE t1, t2");
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test case for bulk DELETE against a table with an active AFTER DELETE
|
||||
trigger.
|
||||
*/
|
||||
static void test_mdev_34718_ad()
|
||||
{
|
||||
int rc;
|
||||
MYSQL_STMT *stmt_delete;
|
||||
MYSQL_BIND bind[1];
|
||||
unsigned int vals[]= { 1, 2, 3};
|
||||
unsigned int vals_array_len= 3;
|
||||
my_ulonglong row_count;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
const char *delete_stmt= "DELETE FROM t1 WHERE a = ?";
|
||||
|
||||
myheader("test_mdev_34718_bd");
|
||||
|
||||
/* Set up test's environment */
|
||||
rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TABLE t2 (a INT)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2), (3)");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "CREATE TRIGGER t1_bd AFTER DELETE ON t1 "
|
||||
"FOR EACH ROW BEGIN INSERT INTO t2 (a) VALUES (OLD.a); END;");
|
||||
|
||||
/* Initialize the prepared statement and set it up for bulk operations */
|
||||
stmt_delete= mysql_stmt_init(mysql);
|
||||
check_stmt(stmt_delete);
|
||||
|
||||
rc= mysql_stmt_prepare(stmt_delete, delete_stmt, strlen(delete_stmt));
|
||||
check_execute(stmt_delete, rc);
|
||||
|
||||
memset(&bind[0], 0, sizeof(MYSQL_BIND));
|
||||
|
||||
bind[0].buffer_type= MYSQL_TYPE_LONG;
|
||||
bind[0].buffer= vals;
|
||||
|
||||
/*
|
||||
Input positional parameter is bound with array of 3 elements
|
||||
containing actual values for the positional parameter
|
||||
*/
|
||||
rc= mysql_stmt_attr_set(stmt_delete, STMT_ATTR_ARRAY_SIZE, &vals_array_len);
|
||||
check_execute(stmt_delete, rc);
|
||||
|
||||
rc= mysql_stmt_bind_param(stmt_delete, bind);
|
||||
check_execute(stmt_delete, rc);
|
||||
|
||||
/*
|
||||
Execution of this prepared statement deletes the rows (1), (2), (3)
|
||||
from the table t1 and inserts the rows (1), (2), (3) into the table t2
|
||||
in result of firing the BEFORE DELETE trigger
|
||||
*/
|
||||
rc= mysql_stmt_execute(stmt_delete);
|
||||
check_execute(stmt_delete, rc);
|
||||
|
||||
/*
|
||||
Check that the BULK DELETE statement affects exactly 3 rows
|
||||
*/
|
||||
row_count= mysql_stmt_affected_rows(stmt_delete);
|
||||
DIE_UNLESS(row_count == 3);
|
||||
|
||||
/*
|
||||
* Check that the AFTER DELETE trigger of the table t1 does work correctly
|
||||
* and inserts the rows (1), (2), (3) into the table t2.
|
||||
*/
|
||||
rc= mysql_query(mysql, "SELECT 't1' tname, a FROM t1 "
|
||||
"UNION SELECT 't2' tname, a FROM t2 ORDER BY tname, a");
|
||||
myquery(rc);
|
||||
|
||||
result= mysql_store_result(mysql);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 1);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 2);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 3);
|
||||
|
||||
row= mysql_fetch_row(result);
|
||||
DIE_UNLESS(row == NULL);
|
||||
|
||||
mysql_free_result(result);
|
||||
|
||||
mysql_stmt_close(stmt_delete);
|
||||
|
||||
/* Clean up */
|
||||
rc= mysql_query(mysql, "DROP TABLE t1, t2");
|
||||
myquery(rc);
|
||||
}
|
||||
#endif // EMBEDDED_LIBRARY
|
||||
|
||||
/*
|
||||
Check that server_status returned after connecting to server
|
||||
is consistent with the value of autocommit variable.
|
||||
@@ -22630,6 +23076,10 @@ static struct my_tests_st my_tests[]= {
|
||||
{ "test_cache_metadata", test_cache_metadata},
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
{ "test_mdev_24411", test_mdev_24411},
|
||||
{ "test_mdev_34718_bu", test_mdev_34718_bu },
|
||||
{ "test_mdev_34718_au", test_mdev_34718_au },
|
||||
{ "test_mdev_34718_bd", test_mdev_34718_bd },
|
||||
{ "test_mdev_34718_ad", test_mdev_34718_ad },
|
||||
#endif
|
||||
{ "test_mdev_10075", test_mdev_10075},
|
||||
{ 0, 0 }
|
||||
|
Reference in New Issue
Block a user