diff --git a/libmariadb/ma_context.c b/libmariadb/ma_context.c index 224783b2..a80a7867 100644 --- a/libmariadb/ma_context.c +++ b/libmariadb/ma_context.c @@ -107,8 +107,21 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d) c->active= 1; u.a[1]= 0; /* Otherwise can give uninitialized warnings on 32-bit. */ u.p= c; + /* + makecontext function expects function pointer to receive multiple + ints as an arguments, however is declared in ucontext.h header with + a void (empty) argument list. Ignore clang cast-function-type-strict + warning for this function call. + */ +# ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wcast-function-type-strict" +# endif makecontext(&c->spawned_context, (uc_func_t)my_context_spawn_internal, 2, u.a[0], u.a[1]); +# ifdef __clang__ +# pragma clang diagnostic pop +# endif return my_context_continue(c); } @@ -725,7 +738,11 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d) [stack] "+r" (stack) : [save] "r" (save) : "x3", "x4", "x5", "x6", "x7", - "x9", "x10", "x11", "x14", "x15", "x18", "x30", + "x9", "x10", "x11", "x14", "x15", +#if defined(__linux__) && !defined(__ANDROID__) + "x18", +#endif + "x30", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", @@ -828,7 +845,11 @@ my_context_continue(struct my_context *c) : [ret] "=r" (ret) : [save] "r" (save) : "x1", "x2", "x3", "x4", "x5", "x6", "x7", - "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x18", "x30", + "x9", "x10", "x11", "x12", "x13", "x14", "x15", +#if defined(__linux__) && !defined(__ANDROID__) + "x18", +#endif + "x30", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", @@ -905,7 +926,11 @@ my_context_yield(struct my_context *c) : : [save] "r" (save) : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", - "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x18", "x30", + "x9", "x10", "x11", "x12", "x13", "x14", "x15", +#if defined(__linux__) && !defined(__ANDROID__) + "x18", +#endif + "x30", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", diff --git a/libmariadb/mariadb_stmt.c b/libmariadb/mariadb_stmt.c index 221e44b6..5920acf6 100644 --- a/libmariadb/mariadb_stmt.c +++ b/libmariadb/mariadb_stmt.c @@ -448,6 +448,9 @@ int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row) stmt->bind[i].is_null= &stmt->bind[i].is_null_value; *stmt->bind[i].is_null= 1; stmt->bind[i].u.row_ptr= NULL; + if (!stmt->bind[i].length) + stmt->bind[i].length= &stmt->bind[i].length_value; + *stmt->bind[i].length= stmt->bind[i].length_value= 0; } } else { @@ -460,6 +463,9 @@ int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row) if (stmt->result_callback) stmt->result_callback(stmt->user_data, i, &row); else { + if (!stmt->bind[i].is_null) + stmt->bind[i].is_null= &stmt->bind[i].is_null_value; + *stmt->bind[i].is_null= 0; if (mysql_ps_fetch_functions[stmt->fields[i].type].pack_len >= 0) length= mysql_ps_fetch_functions[stmt->fields[i].type].pack_len; else diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index 41c6312d..513ddebd 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -5983,11 +5983,52 @@ static int test_conc176(MYSQL *mysql) return OK; } +static int test_conc762(MYSQL *mysql) +{ + int rc; + MYSQL_STMT *stmt= mysql_stmt_init(mysql); + MYSQL_BIND bind[2]; + my_bool is_null[2]= {1,1}; + unsigned long length[2]= {1,1}; + + rc= mysql_stmt_prepare(stmt, SL("SELECT NULL, 'foo'")); + check_stmt_rc(rc, stmt); + + memset(&bind, 0, sizeof(MYSQL_BIND) * 2); + + bind[0].buffer_type = MYSQL_TYPE_STRING; + bind[1].buffer_type = MYSQL_TYPE_STRING; + bind[0].is_null= &is_null[0]; + bind[1].is_null= &is_null[1]; + bind[0].buffer_length= bind[1].buffer_length= 0; + bind[0].length= &length[0]; + bind[1].length= &length[1]; + + rc= mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_bind_result(stmt, bind); + + mysql_stmt_fetch(stmt); + FAIL_IF(is_null[0]==0, "Expected NULL value"); + FAIL_IF(is_null[1]==1, "Expected non NULL value"); + FAIL_IF(length[0]!=0, "Expected length=0"); + FAIL_IF(length[1]!=3, "Expected length=3"); + +// FAIL_IF(length[0] != 0, "Expected length=0"); + +//FAIL_IF(length[1] != 3, "Expected length=3)"; + + mysql_stmt_close(stmt); + return OK; +} + struct my_tests_st my_tests[] = { {"test_conc683", test_conc683, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc667", test_conc667, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc702", test_conc702, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, + {"test_conc762", test_conc762, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc176", test_conc176, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc739", test_conc739, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc633", test_conc633, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},