1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

Fix for CONC-282: mysql_stmt_fetch_column doesn't work with prior call to mysql_stmt_store_result

- If no bind variables were bound or the function mysql_stmt_store_result was not called before, the internal bind variables (stmt->bind) was not filled (lengths and null values)
This commit is contained in:
Georg Richter
2017-09-25 13:51:01 +02:00
parent b06a8d1d1d
commit 240204eaeb
3 changed files with 60 additions and 6 deletions

View File

@@ -167,7 +167,7 @@ IF(MAJOR_VERSION)
ELSE() ELSE()
SET(MARIADB_CLIENT_VERSION_MAJOR "10") SET(MARIADB_CLIENT_VERSION_MAJOR "10")
SET(MARIADB_CLIENT_VERSION_MINOR "2") SET(MARIADB_CLIENT_VERSION_MINOR "2")
SET(MARIADB_CLIENT_VERSION_PATCH "6") SET(MARIADB_CLIENT_VERSION_PATCH "9")
ENDIF() ENDIF()
SET(MARIADB_CLIENT_VERSION "${MARIADB_CLIENT_VERSION_MAJOR}.${MARIADB_CLIENT_VERSION_MINOR}.${MARIADB_CLIENT_VERSION_PATCH}") SET(MARIADB_CLIENT_VERSION "${MARIADB_CLIENT_VERSION_MAJOR}.${MARIADB_CLIENT_VERSION_MINOR}.${MARIADB_CLIENT_VERSION_PATCH}")
SET(MARIADB_BASE_VERSION "mariadb-${MARIADB_CLIENT_VERSION_MAJOR}.${MARIADB_CLIENT_VERSION_MINOR}") SET(MARIADB_BASE_VERSION "mariadb-${MARIADB_CLIENT_VERSION_MAJOR}.${MARIADB_CLIENT_VERSION_MINOR}")

View File

@@ -347,10 +347,6 @@ int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row)
uint i; uint i;
size_t truncations= 0; size_t truncations= 0;
unsigned char *null_ptr, bit_offset= 4; unsigned char *null_ptr, bit_offset= 4;
if (!stmt->bind_result_done) /* nothing to do */
return(0);
row++; /* skip status byte */ row++; /* skip status byte */
null_ptr= row; null_ptr= row;
row+= (stmt->field_count + 9) / 8; row+= (stmt->field_count + 9) / 8;
@@ -360,12 +356,15 @@ int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row)
/* save row position for fetching values in pieces */ /* save row position for fetching values in pieces */
if (*null_ptr & bit_offset) if (*null_ptr & bit_offset)
{ {
if (!stmt->bind[i].is_null)
stmt->bind[i].is_null= &stmt->bind[i].is_null_value;
*stmt->bind[i].is_null= 1; *stmt->bind[i].is_null= 1;
stmt->bind[i].u.row_ptr= NULL; stmt->bind[i].u.row_ptr= NULL;
} else } else
{ {
stmt->bind[i].u.row_ptr= row; stmt->bind[i].u.row_ptr= row;
if (stmt->bind[i].flags & MADB_BIND_DUMMY) if (!stmt->bind_result_done ||
stmt->bind[i].flags & MADB_BIND_DUMMY)
{ {
unsigned long length; unsigned long length;
@@ -374,6 +373,9 @@ int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row)
else else
length= net_field_length(&row); length= net_field_length(&row);
row+= length; row+= length;
if (!stmt->bind[i].length)
stmt->bind[i].length= &stmt->bind[i].length_value;
*stmt->bind[i].length= stmt->bind[i].length_value= length;
} }
else else
{ {
@@ -1622,6 +1624,7 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned lon
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
goto fail; goto fail;
} }
memset(stmt->bind, 0, sizeof(MYSQL_BIND) * stmt->field_count);
} }
stmt->state = MYSQL_STMT_PREPARED; stmt->state = MYSQL_STMT_PREPARED;
return(0); return(0);
@@ -1815,6 +1818,7 @@ int stmt_read_execute_response(MYSQL_STMT *stmt)
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return(1); return(1);
} }
memset(stmt->bind, 0, sizeof(MYSQL_BIND) * mysql->field_count);
stmt->field_count= mysql->field_count; stmt->field_count= mysql->field_count;
for (i=0; i < stmt->field_count; i++) for (i=0; i < stmt->field_count; i++)
@@ -2380,6 +2384,7 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt,
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
goto fail; goto fail;
} }
memset(stmt->bind, 0, sizeof(MYSQL_BIND) * stmt->field_count);
} }
stmt->state = MYSQL_STMT_PREPARED; stmt->state = MYSQL_STMT_PREPARED;

View File

@@ -924,7 +924,56 @@ static int test_fetch_double(MYSQL *mysql)
return rc; return rc;
} }
static int test_conc282(MYSQL *mysql)
{
int rc;
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
MYSQL_BIND bind[2];
unsigned long length= 0;
char buffer[2048];
rc= mysql_query(mysql, "DROP TABLE IF EXISTS conc282");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "CREATE TABLE conc282 (a blob, b varchar(1000), c int)");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "INSERT INTO conc282 VALUES (REPEAT('A',2000), REPEAT('B', 999),3)");
check_mysql_rc(rc, mysql);
rc= mysql_stmt_prepare(stmt, "SELECT a, b FROM conc282", -1);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc, stmt);
memset(bind, 0, sizeof(MYSQL_BIND) * 2);
bind[0].buffer_type= MYSQL_TYPE_BLOB;
bind[0].buffer= buffer;
bind[0].buffer_length= 2048;
bind[0].length= &length;
rc= mysql_stmt_fetch_column(stmt, &bind[0], 0, 0);
check_stmt_rc(rc, stmt);
FAIL_IF(length != 2000, "Expected length= 2000");
FAIL_IF(buffer[0] != 'A' || buffer[1999] != 'A', "Wrong result");
mysql_stmt_close(stmt);
rc= mysql_query(mysql, "DROP TABLE conc282");
check_mysql_rc(rc, mysql);
return OK;
}
struct my_tests_st my_tests[] = { struct my_tests_st my_tests[] = {
{"test_conc282", test_conc282, 1, 0, NULL, NULL},
{"test_fetch_seek", test_fetch_seek, 1, 0, NULL , NULL}, {"test_fetch_seek", test_fetch_seek, 1, 0, NULL , NULL},
{"test_fetch_offset", test_fetch_offset, 1, 0, NULL , NULL}, {"test_fetch_offset", test_fetch_offset, 1, 0, NULL , NULL},
{"test_fetch_column", test_fetch_column, 1, 0, NULL , NULL}, {"test_fetch_column", test_fetch_column, 1, 0, NULL , NULL},