Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Cannot Reproduce
-
10.3.4
-
None
Description
If we have auto_increment field in the table, and we insert there a few rows using parameter array, and we have indicator array set for the auto_increment field, and for some row indicator value is set to STMT_INDICATOR_NULL or STMT_INDICATOR_IGNORE, for all subsequent rows server insert values like if same indicator value was set for them, too. i.e. it auto-incremented values instead of values specified in bound array.
I don't think C/C can be here to blame - I traced execution, and things look sane. Besides same error is not exposed with 10.2 server.
I am not sure if that is "major" issue, as this does not look like very probable scenario, but on other hand c/odbc testcases have it. Besides I don't think it's very hard to fix.
Below is short program to repeat it
#include <stdio.h>
|
#include <stdarg.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <mysql.h>
|
|
#ifndef OK
|
# define OK 0
|
#endif
|
#ifndef FAIL
|
# define FAIL 1
|
#endif
|
#ifndef SKIP
|
# define SKIP -1
|
#endif
|
#ifndef FALSE
|
# define FALSE 0
|
#endif
|
#ifndef TRUE
|
# define TRUE 1
|
#endif
|
|
void
|
diag(char const *fmt, ...) |
{
|
va_list ap; |
va_start(ap, fmt); |
fprintf(stdout, "# "); |
vfprintf(stdout, fmt, ap); |
fprintf(stdout, "\n"); |
va_end(ap); |
}
|
|
#define check_stmt_rc(_rc, _stmt) \
|
if (_rc)\ |
{\
|
diag("Error: [%s] %s(%d) (%s: %d)", mysql_stmt_sqlstate(_stmt), mysql_stmt_error(_stmt), mysql_stmt_errno(_stmt), __FILE__, __LINE__);\ |
return(FAIL);\ |
}
|
|
#define check_mysql_rc(rc, mysql) \
|
if (rc)\ |
{\
|
diag("Error (%d): %s (%d) in %s line %d", rc, mysql_error(mysql), \ |
mysql_errno(mysql), __FILE__, __LINE__);\
|
return(FAIL);\ |
}
|
|
#define FAIL_IF(expr, reason)\
|
if (expr)\ |
{\
|
diag("Error: %s (%s: %d)", (reason) ? reason : "", __FILE__, __LINE__);\ |
return FAIL;\ |
}
|
|
|
int main(int argc, char *argv) |
{
|
MYSQL *ma;
|
MYSQL_STMT *stmt;
|
MYSQL_BIND bind[1];
|
MYSQL_RES *res;
|
MYSQL_ROW row;
|
char indicator[]= {0, STMT_INDICATOR_NULL, 0/*STMT_INDICATOR_IGNORE*/}; |
my_bool error[1];
|
int i, id[]= {2, 3, 777}, param_count= 1, count= sizeof(id)/sizeof(id[0]); |
my_bool UpdateMaxLength= 1;
|
|
ma = mysql_init(NULL);
|
if (!mysql_real_connect(ma, "localhost", "root", "", "test", 3306, NULL, 0)) |
{
|
printf("Could not connect: %s\n", mysql_error(ma)); |
exit(1); |
}
|
else |
{
|
printf("Server info %s\nClient info: %s\n", |
mysql_get_server_info(ma), mysql_get_client_info());
|
}
|
|
stmt = mysql_stmt_init(ma);
|
|
if (!stmt) |
{
|
diag("Could not init stmt handler(s)"); |
return FAIL; |
}
|
|
check_mysql_rc(mysql_query(ma, "DROP TABLE IF EXISTS ai_field_value"), ma); |
check_mysql_rc(mysql_query(ma, "CREATE TABLE ai_field_value (id int not null primary key auto_increment)"), ma); |
check_stmt_rc(mysql_stmt_prepare(stmt, "INSERT INTO ai_field_value(id) values(?)", -1), stmt); |
|
memset(bind, 0, sizeof(bind)); |
bind[0].buffer_type = MYSQL_TYPE_LONG;
|
bind[0].buffer = (void *)id; |
bind[0].buffer_length = 0;
|
bind[0].is_null = NULL;
|
bind[0].length = NULL;
|
bind[0].error = error;
|
bind[0].u.indicator= indicator;
|
|
mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count); |
check_stmt_rc(mysql_stmt_bind_param(stmt, bind), stmt);
|
|
check_stmt_rc(mysql_stmt_execute(stmt), stmt);
|
|
mysql_stmt_close(stmt);
|
|
check_mysql_rc(mysql_query(ma, "SELECT id FROM ai_field_value"), ma); |
|
res= mysql_store_result(ma);
|
|
i= 0;
|
while (row= mysql_fetch_row(res)) |
{
|
diag("id= %s", row[0]); |
FAIL_IF(atoi(row[0]) != id[i++], "Values is differented form the expected"); |
}
|
check_mysql_rc(mysql_query(ma, "DROP TABLE ai_field_value"), ma); |
|
mysql_close(ma);
|
|
exit(0); |
}
|
Attachments
Issue Links
- causes
-
ODBC-132 Few Testcases fail against 10.3 server
-
- Closed
-
Activity
Field | Original Value | New Value |
---|---|---|
Fix Version/s | 10.3 [ 22126 ] |
Description |
If we have auto_increment field in the table, and we insert there a few rows using parameter array, and we have indicator array set for the auto_increment field, and for some row indicator value is set to STMT_INDICATOR_NULL or STMT_INDICATOR_IGNORE, for all subsequent rows server insert values like if same indicator value was set for them, too. i.e. it auto-incremented values instead of values specified in bound array.
I don't think C/C can be here to blame - I traced execution, and things look sane. Besides same error is not exposed with 10.2 server. I am not sure if that is "major" issue, as this does not look like very probable scenario, but on other hand c/odbc testcases have it. Besides I don't think it's very hard to fix. Below is short program to repeat it #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> #include <mysql.h> #ifndef OK # define OK 0 #endif #ifndef FAIL # define FAIL 1 #endif #ifndef SKIP # define SKIP -1 #endif #ifndef FALSE # define FALSE 0 #endif #ifndef TRUE # define TRUE 1 #endif void diag(char const *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stdout, "# "); vfprintf(stdout, fmt, ap); fprintf(stdout, "\n"); va_end(ap); } #define check_stmt_rc(_rc, _stmt) \ if (_rc)\ {\ diag("Error: [%s] %s(%d) (%s: %d)", mysql_stmt_sqlstate(_stmt), mysql_stmt_error(_stmt), mysql_stmt_errno(_stmt), __FILE__, __LINE__);\ return(FAIL);\ } #define check_mysql_rc(rc, mysql) \ if (rc)\ {\ diag("Error (%d): %s (%d) in %s line %d", rc, mysql_error(mysql), \ mysql_errno(mysql), __FILE__, __LINE__);\ return(FAIL);\ } #define FAIL_IF(expr, reason)\ if (expr)\ {\ diag("Error: %s (%s: %d)", (reason) ? reason : "", __FILE__, __LINE__);\ return FAIL;\ } int main(int argc, char *argv) { MYSQL *ma; MYSQL_STMT *stmt; MYSQL_BIND bind[1]; MYSQL_RES *res; MYSQL_ROW row; char indicator[]= {0, STMT_INDICATOR_NULL, 0/*STMT_INDICATOR_IGNORE*/}; my_bool error[1]; int i, id[]= {2, 3, 777}, param_count= 1, count= sizeof(id)/sizeof(id[0]); my_bool UpdateMaxLength= 1; ma = mysql_init(NULL); if (!mysql_real_connect(ma, "localhost", "root", "", "test", 3306, NULL, 0)) { printf("Could not connect: %s\n", mysql_error(ma)); exit(1); } else { printf("Server info %s\nClient info: %s\n", mysql_get_server_info(ma), mysql_get_client_info()); } stmt = mysql_stmt_init(ma); if (!stmt) { diag("Could not init stmt handler(s)"); return FAIL; } check_mysql_rc(mysql_query(ma, "DROP TABLE IF EXISTS ai_field_value"), ma); check_mysql_rc(mysql_query(ma, "CREATE TABLE ai_field_value (id int not null primary key auto_increment)"), ma); check_stmt_rc(mysql_stmt_prepare(stmt, "INSERT INTO ai_field_value(id) values(?)", -1), stmt); memset(bind, 0, sizeof(bind)); bind[0].buffer_type = MYSQL_TYPE_LONG; bind[0].buffer = (void *)id; bind[0].buffer_length = 0; bind[0].is_null = NULL; bind[0].length = NULL; bind[0].error = error; bind[0].u.indicator= indicator; mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count); check_stmt_rc(mysql_stmt_bind_param(stmt, bind), stmt); check_stmt_rc(mysql_stmt_execute(stmt), stmt); mysql_stmt_close(stmt); check_mysql_rc(mysql_query(ma, "SELECT id FROM ai_field_value"), ma); res= mysql_store_result(ma); i= 0; while (row= mysql_fetch_row(res)) { diag("id= %s", row[0]); FAIL_IF(atoi(row[0]) != id[i++], "Values is differented form the expected"); } check_mysql_rc(mysql_query(ma, "DROP TABLE ai_field_value"), ma); mysql_close(ma); exit(0); } |
If we have auto_increment field in the table, and we insert there a few rows using parameter array, and we have indicator array set for the auto_increment field, and for some row indicator value is set to STMT_INDICATOR_NULL or STMT_INDICATOR_IGNORE, for all subsequent rows server insert values like if same indicator value was set for them, too. i.e. it auto-incremented values instead of values specified in bound array.
I don't think C/C can be here to blame - I traced execution, and things look sane. Besides same error is not exposed with 10.2 server. I am not sure if that is "major" issue, as this does not look like very probable scenario, but on other hand c/odbc testcases have it. Besides I don't think it's very hard to fix. Below is short program to repeat it {code:c} #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> #include <mysql.h> #ifndef OK # define OK 0 #endif #ifndef FAIL # define FAIL 1 #endif #ifndef SKIP # define SKIP -1 #endif #ifndef FALSE # define FALSE 0 #endif #ifndef TRUE # define TRUE 1 #endif void diag(char const *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stdout, "# "); vfprintf(stdout, fmt, ap); fprintf(stdout, "\n"); va_end(ap); } #define check_stmt_rc(_rc, _stmt) \ if (_rc)\ {\ diag("Error: [%s] %s(%d) (%s: %d)", mysql_stmt_sqlstate(_stmt), mysql_stmt_error(_stmt), mysql_stmt_errno(_stmt), __FILE__, __LINE__);\ return(FAIL);\ } #define check_mysql_rc(rc, mysql) \ if (rc)\ {\ diag("Error (%d): %s (%d) in %s line %d", rc, mysql_error(mysql), \ mysql_errno(mysql), __FILE__, __LINE__);\ return(FAIL);\ } #define FAIL_IF(expr, reason)\ if (expr)\ {\ diag("Error: %s (%s: %d)", (reason) ? reason : "", __FILE__, __LINE__);\ return FAIL;\ } int main(int argc, char *argv) { MYSQL *ma; MYSQL_STMT *stmt; MYSQL_BIND bind[1]; MYSQL_RES *res; MYSQL_ROW row; char indicator[]= {0, STMT_INDICATOR_NULL, 0/*STMT_INDICATOR_IGNORE*/}; my_bool error[1]; int i, id[]= {2, 3, 777}, param_count= 1, count= sizeof(id)/sizeof(id[0]); my_bool UpdateMaxLength= 1; ma = mysql_init(NULL); if (!mysql_real_connect(ma, "localhost", "root", "", "test", 3306, NULL, 0)) { printf("Could not connect: %s\n", mysql_error(ma)); exit(1); } else { printf("Server info %s\nClient info: %s\n", mysql_get_server_info(ma), mysql_get_client_info()); } stmt = mysql_stmt_init(ma); if (!stmt) { diag("Could not init stmt handler(s)"); return FAIL; } check_mysql_rc(mysql_query(ma, "DROP TABLE IF EXISTS ai_field_value"), ma); check_mysql_rc(mysql_query(ma, "CREATE TABLE ai_field_value (id int not null primary key auto_increment)"), ma); check_stmt_rc(mysql_stmt_prepare(stmt, "INSERT INTO ai_field_value(id) values(?)", -1), stmt); memset(bind, 0, sizeof(bind)); bind[0].buffer_type = MYSQL_TYPE_LONG; bind[0].buffer = (void *)id; bind[0].buffer_length = 0; bind[0].is_null = NULL; bind[0].length = NULL; bind[0].error = error; bind[0].u.indicator= indicator; mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count); check_stmt_rc(mysql_stmt_bind_param(stmt, bind), stmt); check_stmt_rc(mysql_stmt_execute(stmt), stmt); mysql_stmt_close(stmt); check_mysql_rc(mysql_query(ma, "SELECT id FROM ai_field_value"), ma); res= mysql_store_result(ma); i= 0; while (row= mysql_fetch_row(res)) { diag("id= %s", row[0]); FAIL_IF(atoi(row[0]) != id[i++], "Values is differented form the expected"); } check_mysql_rc(mysql_query(ma, "DROP TABLE ai_field_value"), ma); mysql_close(ma); exit(0); } {code} |
Assignee | Oleksandr Byelkin [ sanja ] |
Sprint | 10.2.13 [ 228 ] |
Sprint | 10.2.13 [ 228 ] |
Affects Version/s | 10.2 [ 14601 ] |
Fix Version/s | 10.2 [ 14601 ] |
Affects Version/s | 10.2 [ 14601 ] |
Fix Version/s | 10.2 [ 14601 ] |
Status | Open [ 1 ] | In Progress [ 3 ] |
Status | In Progress [ 3 ] | Stalled [ 10000 ] |
Fix Version/s | 10.3.7 [ 23005 ] | |
Fix Version/s | 10.3 [ 22126 ] | |
Resolution | Cannot Reproduce [ 5 ] | |
Status | Stalled [ 10000 ] | Closed [ 6 ] |
Workflow | MariaDB v3 [ 85149 ] | MariaDB v4 [ 153654 ] |
I guess this bug has been fixed, since corresponding ODBC tests do not fail any more against 10.3