You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-08 14:02:17 +03:00
Fix for CONC-623:
If callback function returns a non zero return code, execute will now abort with error CR_ERR_STMT_PARAM_CALLBACK.
This commit is contained in:
@@ -106,10 +106,11 @@ extern const char *mariadb_client_errors[]; /* Error messages */
|
|||||||
#define CR_ERR_NET_READ 5013
|
#define CR_ERR_NET_READ 5013
|
||||||
#define CR_ERR_NET_WRITE 5014
|
#define CR_ERR_NET_WRITE 5014
|
||||||
#define CR_ERR_NET_UNCOMPRESS 5015
|
#define CR_ERR_NET_UNCOMPRESS 5015
|
||||||
|
#define CR_ERR_STMT_PARAM_CALLBACK 5016
|
||||||
|
|
||||||
/* Always last, if you add new error codes please update the
|
/* Always last, if you add new error codes please update the
|
||||||
value for CR_MARIADB_LAST_ERROR */
|
value for CR_MARIADB_LAST_ERROR */
|
||||||
#define CR_MARIADB_LAST_ERROR CR_ERR_NET_UNCOMPRESS
|
#define CR_MARIADB_LAST_ERROR CR_ERR_STMT_PARAM_CALLBACK
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -110,6 +110,7 @@ const char *mariadb_client_errors[] =
|
|||||||
/* 5013 */ "Read error: %s (%d)",
|
/* 5013 */ "Read error: %s (%d)",
|
||||||
/* 5014 */ "Write error: %s (%d)",
|
/* 5014 */ "Write error: %s (%d)",
|
||||||
/* 5015 */ "Error while uncompressing packet",
|
/* 5015 */ "Error while uncompressing packet",
|
||||||
|
/* 5016 */ "Error while retrieving parameter from callback function",
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -941,7 +941,10 @@ unsigned char* ma_stmt_execute_generate_bulk_request(MYSQL_STMT *stmt, size_t *r
|
|||||||
|
|
||||||
/* preallocate length bytes */
|
/* preallocate length bytes */
|
||||||
if (!(start= p= (uchar *)malloc(length)))
|
if (!(start= p= (uchar *)malloc(length)))
|
||||||
goto mem_error;
|
{
|
||||||
|
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
int4store(p, stmt->stmt_id);
|
int4store(p, stmt->stmt_id);
|
||||||
p += STMT_ID_LENGTH;
|
p += STMT_ID_LENGTH;
|
||||||
@@ -973,7 +976,10 @@ unsigned char* ma_stmt_execute_generate_bulk_request(MYSQL_STMT *stmt, size_t *r
|
|||||||
size_t offset= p - start;
|
size_t offset= p - start;
|
||||||
length= offset + stmt->param_count * 2 + 20;
|
length= offset + stmt->param_count * 2 + 20;
|
||||||
if (!(start= (uchar *)realloc(start, length)))
|
if (!(start= (uchar *)realloc(start, length)))
|
||||||
goto mem_error;
|
{
|
||||||
|
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
p= start + offset;
|
p= start + offset;
|
||||||
}
|
}
|
||||||
for (i = 0; i < stmt->param_count; i++)
|
for (i = 0; i < stmt->param_count; i++)
|
||||||
@@ -991,7 +997,13 @@ unsigned char* ma_stmt_execute_generate_bulk_request(MYSQL_STMT *stmt, size_t *r
|
|||||||
/* If callback for parameters was specified, we need to
|
/* If callback for parameters was specified, we need to
|
||||||
update bind information for new row */
|
update bind information for new row */
|
||||||
if (stmt->param_callback)
|
if (stmt->param_callback)
|
||||||
stmt->param_callback(stmt->user_data, stmt->params, j);
|
{
|
||||||
|
if (stmt->param_callback(stmt->user_data, stmt->params, j))
|
||||||
|
{
|
||||||
|
SET_CLIENT_STMT_ERROR(stmt, CR_ERR_STMT_PARAM_CALLBACK, SQLSTATE_UNKNOWN, 0);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mysql_stmt_skip_paramset(stmt, j))
|
if (mysql_stmt_skip_paramset(stmt, j))
|
||||||
continue;
|
continue;
|
||||||
@@ -1059,7 +1071,10 @@ unsigned char* ma_stmt_execute_generate_bulk_request(MYSQL_STMT *stmt, size_t *r
|
|||||||
size_t offset= p - start;
|
size_t offset= p - start;
|
||||||
length= MAX(2 * length, offset + size + 20);
|
length= MAX(2 * length, offset + size + 20);
|
||||||
if (!(start= (uchar *)realloc(start, length)))
|
if (!(start= (uchar *)realloc(start, length)))
|
||||||
goto mem_error;
|
{
|
||||||
|
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
p= start + offset;
|
p= start + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1075,8 +1090,7 @@ unsigned char* ma_stmt_execute_generate_bulk_request(MYSQL_STMT *stmt, size_t *r
|
|||||||
stmt->send_types_to_server= 0;
|
stmt->send_types_to_server= 0;
|
||||||
*request_len = (size_t)(p - start);
|
*request_len = (size_t)(p - start);
|
||||||
return start;
|
return start;
|
||||||
mem_error:
|
error:
|
||||||
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
|
||||||
free(start);
|
free(start);
|
||||||
*request_len= 0;
|
*request_len= 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -5587,7 +5587,58 @@ static int test_mdev19838(MYSQL *mysql)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_bool conc623_param_callback(void *data __attribute((unused)),
|
||||||
|
MYSQL_BIND *bind __attribute((unused)),
|
||||||
|
unsigned int row_nr __attribute((unused)))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_conc623(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
unsigned int paramcount= 1;
|
||||||
|
unsigned int array_size= 2;
|
||||||
|
MYSQL_BIND bind;
|
||||||
|
|
||||||
|
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "CREATE OR REPLACE TEMPORARY TABLE t1 (a int)");
|
||||||
|
|
||||||
|
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CB_USER_DATA, mysql);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, ¶mcount);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CB_PARAM, conc623_param_callback);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
bind.buffer_type= MYSQL_TYPE_LONG;
|
||||||
|
rc= mysql_stmt_bind_param(stmt, &bind);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
rc= mysql_stmt_prepare(stmt, SL("INSERT INTO t1 VALUES (?)"));
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
diag("Error expected from callback function");
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
diag("Error (expected) %s", mysql_stmt_error(stmt));
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
|
{"test_conc623", test_conc623, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_mdev19838", test_mdev19838, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_mdev19838", test_mdev19838, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_conc525", test_conc525, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_conc525", test_conc525, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_conc566", test_conc566, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_conc566", test_conc566, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
|
Reference in New Issue
Block a user