diff --git a/CMakeLists.txt b/CMakeLists.txt index bc7dc7d0..45b5e6f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,7 @@ IF(MAJOR_VERSION) ELSE() SET(MARIADB_CLIENT_VERSION_MAJOR "10") SET(MARIADB_CLIENT_VERSION_MINOR "2") - SET(MARIADB_CLIENT_VERSION_PATCH "6") + SET(MARIADB_CLIENT_VERSION_PATCH "9") ENDIF() 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}") diff --git a/libmariadb/mariadb_stmt.c b/libmariadb/mariadb_stmt.c index 792e9423..e0dc1b24 100644 --- a/libmariadb/mariadb_stmt.c +++ b/libmariadb/mariadb_stmt.c @@ -347,10 +347,6 @@ int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row) uint i; size_t truncations= 0; unsigned char *null_ptr, bit_offset= 4; - - if (!stmt->bind_result_done) /* nothing to do */ - return(0); - row++; /* skip status byte */ null_ptr= row; 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 */ 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].u.row_ptr= NULL; } else { 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; @@ -374,6 +373,9 @@ int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row) else length= net_field_length(&row); 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 { @@ -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); goto fail; } + memset(stmt->bind, 0, sizeof(MYSQL_BIND) * stmt->field_count); } stmt->state = MYSQL_STMT_PREPARED; 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); return(1); } + memset(stmt->bind, 0, sizeof(MYSQL_BIND) * mysql->field_count); stmt->field_count= mysql->field_count; 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); goto fail; } + memset(stmt->bind, 0, sizeof(MYSQL_BIND) * stmt->field_count); } stmt->state = MYSQL_STMT_PREPARED; diff --git a/unittest/libmariadb/fetch.c b/unittest/libmariadb/fetch.c index 3c11a4dd..df3a6e30 100644 --- a/unittest/libmariadb/fetch.c +++ b/unittest/libmariadb/fetch.c @@ -924,7 +924,56 @@ static int test_fetch_double(MYSQL *mysql) 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[] = { + {"test_conc282", test_conc282, 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_column", test_fetch_column, 1, 0, NULL , NULL},