220 lines
6.2 KiB
C++
220 lines
6.2 KiB
C++
/**
|
|
* MXS-1121: MariaDB 10.2 Bulk Insert test
|
|
*
|
|
* This test is a copy of one of the examples for bulk inserts:
|
|
* https://mariadb.com/kb/en/mariadb/bulk-insert-column-wise-binding/
|
|
*/
|
|
|
|
#include "testconnections.h"
|
|
|
|
static int show_mysql_error(MYSQL *mysql)
|
|
{
|
|
printf("Error(%d) [%s] \"%s\"\n", mysql_errno(mysql),
|
|
mysql_sqlstate(mysql),
|
|
mysql_error(mysql));
|
|
return 1;
|
|
}
|
|
|
|
static int show_stmt_error(MYSQL_STMT *stmt)
|
|
{
|
|
printf("Error(%d) [%s] \"%s\"\n", mysql_stmt_errno(stmt),
|
|
mysql_stmt_sqlstate(stmt),
|
|
mysql_stmt_error(stmt));
|
|
return 1;
|
|
}
|
|
|
|
int bind_by_column(MYSQL *mysql)
|
|
{
|
|
MYSQL_STMT *stmt;
|
|
MYSQL_BIND bind[3];
|
|
|
|
/* Data for insert */
|
|
const char *surnames[] = {"Widenius", "Axmark", "N.N."};
|
|
unsigned long surnames_length[] = {8, 6, 4};
|
|
const char *forenames[] = {"Monty", "David", "will be replaced by default value"};
|
|
char forename_ind[] = {STMT_INDICATOR_NTS, STMT_INDICATOR_NTS, STMT_INDICATOR_DEFAULT};
|
|
char id_ind[] = {STMT_INDICATOR_NULL, STMT_INDICATOR_NULL, STMT_INDICATOR_NULL};
|
|
unsigned int array_size = 3;
|
|
|
|
if (mysql_query(mysql, "DROP TABLE IF EXISTS test.bulk_example1"))
|
|
{
|
|
return show_mysql_error(mysql);
|
|
}
|
|
|
|
if (mysql_query(mysql, "CREATE TABLE test.bulk_example1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY," \
|
|
"forename CHAR(30) NOT NULL DEFAULT 'unknown', surname CHAR(30))"))
|
|
{
|
|
return show_mysql_error(mysql);
|
|
}
|
|
|
|
stmt = mysql_stmt_init(mysql);
|
|
if (mysql_stmt_prepare(stmt, "INSERT INTO test.bulk_example1 VALUES (?,?,?)", -1))
|
|
{
|
|
return show_stmt_error(stmt);
|
|
}
|
|
|
|
memset(bind, 0, sizeof(MYSQL_BIND) * 3);
|
|
|
|
/* We autogenerate id's, so all indicators are STMT_INDICATOR_NULL */
|
|
bind[0].u.indicator = id_ind;
|
|
bind[0].buffer_type = MYSQL_TYPE_LONG;
|
|
|
|
bind[1].buffer = forenames;
|
|
bind[1].buffer_type = MYSQL_TYPE_STRING;
|
|
bind[1].u.indicator = forename_ind;
|
|
|
|
bind[2].buffer_type = MYSQL_TYPE_STRING;
|
|
bind[2].buffer = surnames;
|
|
bind[2].length = surnames_length;
|
|
|
|
/* set array size */
|
|
mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
|
|
|
|
/* bind parameter */
|
|
mysql_stmt_bind_param(stmt, bind);
|
|
|
|
/* execute */
|
|
if (mysql_stmt_execute(stmt))
|
|
{
|
|
return show_stmt_error(stmt);
|
|
}
|
|
|
|
mysql_stmt_close(stmt);
|
|
|
|
/* Check that the rows were inserted */
|
|
if (mysql_query(mysql, "SELECT * FROM test.bulk_example1"))
|
|
{
|
|
return show_mysql_error(mysql);
|
|
}
|
|
|
|
MYSQL_RES *res = mysql_store_result(mysql);
|
|
|
|
if (res == NULL || mysql_num_rows(res) != 3)
|
|
{
|
|
printf("Expected 3 rows but got %d (%s)\n", res ? (int)mysql_num_rows(res) : 0, mysql_error(mysql));
|
|
return 1;
|
|
}
|
|
|
|
if (mysql_query(mysql, "DROP TABLE test.bulk_example1"))
|
|
{
|
|
return show_mysql_error(mysql);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bind_by_row(MYSQL *mysql)
|
|
{
|
|
MYSQL_STMT *stmt;
|
|
MYSQL_BIND bind[3];
|
|
|
|
struct st_data
|
|
{
|
|
unsigned long id;
|
|
char id_ind;
|
|
char forename[30];
|
|
char forename_ind;
|
|
char surname[30];
|
|
char surname_ind;
|
|
};
|
|
|
|
struct st_data data[] =
|
|
{
|
|
{0, STMT_INDICATOR_NULL, "Monty", STMT_INDICATOR_NTS, "Widenius", STMT_INDICATOR_NTS},
|
|
{0, STMT_INDICATOR_NULL, "David", STMT_INDICATOR_NTS, "Axmark", STMT_INDICATOR_NTS},
|
|
{0, STMT_INDICATOR_NULL, "default", STMT_INDICATOR_DEFAULT, "N.N.", STMT_INDICATOR_NTS},
|
|
};
|
|
|
|
unsigned int array_size = 3;
|
|
size_t row_size = sizeof(struct st_data);
|
|
|
|
if (mysql_query(mysql, "DROP TABLE IF EXISTS bulk_example2"))
|
|
{
|
|
show_mysql_error(mysql);
|
|
}
|
|
|
|
if (mysql_query(mysql, "CREATE TABLE bulk_example2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,"\
|
|
"forename CHAR(30) NOT NULL DEFAULT 'unknown', surname CHAR(30))"))
|
|
{
|
|
show_mysql_error(mysql);
|
|
}
|
|
|
|
stmt = mysql_stmt_init(mysql);
|
|
if (mysql_stmt_prepare(stmt, "INSERT INTO bulk_example2 VALUES (?,?,?)", -1))
|
|
{
|
|
show_stmt_error(stmt);
|
|
}
|
|
|
|
memset(bind, 0, sizeof(MYSQL_BIND) * 3);
|
|
|
|
/* We autogenerate id's, so all indicators are STMT_INDICATOR_NULL */
|
|
bind[0].u.indicator = &data[0].id_ind;
|
|
bind[0].buffer_type = MYSQL_TYPE_LONG;
|
|
|
|
bind[1].buffer = &data[0].forename;
|
|
bind[1].buffer_type = MYSQL_TYPE_STRING;
|
|
bind[1].u.indicator = &data[0].forename_ind;
|
|
|
|
bind[2].buffer_type = MYSQL_TYPE_STRING;
|
|
bind[2].buffer = &data[0].surname;
|
|
bind[2].u.indicator = &data[0].surname_ind;
|
|
|
|
/* set array size */
|
|
mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
|
|
|
|
/* set row size */
|
|
mysql_stmt_attr_set(stmt, STMT_ATTR_ROW_SIZE, &row_size);
|
|
|
|
/* bind parameter */
|
|
mysql_stmt_bind_param(stmt, bind);
|
|
|
|
/* execute */
|
|
if (mysql_stmt_execute(stmt))
|
|
{
|
|
show_stmt_error(stmt);
|
|
}
|
|
|
|
mysql_stmt_close(stmt);
|
|
|
|
|
|
/* Check that the rows were inserted */
|
|
if (mysql_query(mysql, "SELECT * FROM test.bulk_example2"))
|
|
{
|
|
return show_mysql_error(mysql);
|
|
}
|
|
|
|
MYSQL_RES *res = mysql_store_result(mysql);
|
|
|
|
if (res == NULL || mysql_num_rows(res) != 3)
|
|
{
|
|
printf("Expected 3 rows but got %d (%s)\n", res ? (int)mysql_num_rows(res) : 0, mysql_error(mysql));
|
|
return 1;
|
|
}
|
|
|
|
if (mysql_query(mysql, "DROP TABLE test.bulk_example2"))
|
|
{
|
|
return show_mysql_error(mysql);
|
|
}
|
|
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
TestConnections::require_repl_version("10.2");
|
|
TestConnections test(argc, argv);
|
|
test.connect_maxscale();
|
|
|
|
test.tprintf("Testing column-wise binding with readwritesplit");
|
|
test.add_result(bind_by_column(test.conn_rwsplit), "Bulk inserts with readwritesplit should work");
|
|
test.tprintf("Testing column-wise binding with readconnroute");
|
|
test.add_result(bind_by_column(test.conn_master), "Bulk inserts with readconnroute should work");
|
|
|
|
test.tprintf("Testing row-wise binding with readwritesplit");
|
|
test.add_result(bind_by_row(test.conn_rwsplit), "Bulk inserts with readwritesplit should work");
|
|
test.tprintf("Testing row-wise binding with readconnroute");
|
|
test.add_result(bind_by_row(test.conn_master), "Bulk inserts with readconnroute should work");
|
|
|
|
test.close_maxscale_connections();
|
|
return test.global_result;
|
|
}
|