diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e2279e2..5f827644 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,7 +103,7 @@ ENDIF() IF(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/unittest) ADD_SUBDIRECTORY(unittest/mytap) - ADD_SUBDIRECTORY(unittest/libmysql) + ADD_SUBDIRECTORY(unittest/libmariadb) ENDIF() IF(BUILD_DOCS) diff --git a/README b/README index afb0c71b..8f840f98 100644 --- a/README +++ b/README @@ -6,8 +6,10 @@ and PHP's mysqlnd extension. The following are the main known limitations: - - float to string conversion for prepared statements - doesn't work correctly +- double to string conversion for prepared statements + doesn't work correctly +- support for dynamic columns is not integrated yet +- Asynchronus interface is not integrated yet If you want to be part of this development effort, you can discuss this at maria-developers@lists.launchpad.org. diff --git a/include/mysql.h b/include/mysql.h index c02a4939..d457d5e7 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -370,7 +370,7 @@ int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname); MYSQL * STDCALL mysql_init(MYSQL *mysql); int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert, const char *ca, - const char *capath); + const char *capath, const char *cipher); const char * STDCALL mysql_get_ssl_cipher(MYSQL *mysql); int STDCALL mysql_ssl_clear(MYSQL *mysql); MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host, diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 02541bf9..7d080766 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1310,12 +1310,13 @@ mysql_init(MYSQL *mysql) int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert, - const char *ca, const char *capath) + const char *ca, const char *capath, const char *cipher) { mysql->options.ssl_key = key==0 ? 0 : my_strdup(key,MYF(0)); mysql->options.ssl_cert = cert==0 ? 0 : my_strdup(cert,MYF(0)); mysql->options.ssl_ca = ca==0 ? 0 : my_strdup(ca,MYF(0)); mysql->options.ssl_capath = capath==0 ? 0 : my_strdup(capath,MYF(0)); + mysql->options.ssl_cipher = cipher==0 ? 0 : my_strdup(cipher,MYF(0)); mysql->options.use_ssl = 1; //mysql->connector_fd = new_VioSSLConnectorFd(key, cert, ca, capath); return 0; @@ -1940,6 +1941,7 @@ static void mysql_close_options(MYSQL *mysql) my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); #endif /* HAVE_OPENSSL */ } diff --git a/libmysql/my_stmt.c b/libmysql/my_stmt.c index 66ea1fb1..3d131034 100644 --- a/libmysql/my_stmt.c +++ b/libmysql/my_stmt.c @@ -950,6 +950,7 @@ int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt) if (stmt->state <= MYSQL_STMT_EXECUTED) { + SET_CLIENT_STMT_ERROR(stmt, CR_COMMANDS_OUT_OF_SYNC, SQLSTATE_UNKNOWN, 0); DBUG_RETURN(1); } @@ -1593,10 +1594,6 @@ int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt) DBUG_RETURN(1); } - /* test_pure_coverage requires checking of error_no */ - if (stmt->last_errno) - DBUG_RETURN(1); - if (stmt->state < MYSQL_STMT_EXECUTED) { SET_CLIENT_ERROR(stmt->mysql, CR_COMMANDS_OUT_OF_SYNC, SQLSTATE_UNKNOWN, 0); @@ -1616,5 +1613,13 @@ int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt) stmt->mysql->net.last_error); DBUG_RETURN(1); } + + if (stmt->field_count != stmt->mysql->field_count) + { + if (stmt->bind) + stmt->bind= NULL; + stmt->field_count= stmt->mysql->field_count; + } + DBUG_RETURN(0); } diff --git a/unittest/libmysql/CMakeLists.txt b/unittest/libmariadb/CMakeLists.txt similarity index 95% rename from unittest/libmysql/CMakeLists.txt rename to unittest/libmariadb/CMakeLists.txt index 4acb695c..c99ba88b 100644 --- a/unittest/libmysql/CMakeLists.txt +++ b/unittest/libmariadb/CMakeLists.txt @@ -21,7 +21,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/unittest/mytap) SET(API_TESTS "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view" "ps" "ps_bugs" - "sp" "result" "connection" "misc" "ssl") + "sp" "result" "connection" "misc" "ssl" "ps_new") FOREACH(API_TEST ${API_TESTS}) ADD_EXECUTABLE(${API_TEST} ${API_TEST}.c) diff --git a/unittest/libmysql/basic-t.c b/unittest/libmariadb/basic-t.c similarity index 99% rename from unittest/libmysql/basic-t.c rename to unittest/libmariadb/basic-t.c index 2370d3f6..0ab37e79 100644 --- a/unittest/libmysql/basic-t.c +++ b/unittest/libmariadb/basic-t.c @@ -439,10 +439,10 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -/* + if (argc > 1) - get_options(&argc, &argv); -*/ + get_options(argc, argv); + get_envvars(); run_tests(my_tests); diff --git a/unittest/libmysql/ca.pem b/unittest/libmariadb/ca.pem similarity index 100% rename from unittest/libmysql/ca.pem rename to unittest/libmariadb/ca.pem diff --git a/unittest/libmysql/charset.c b/unittest/libmariadb/charset.c similarity index 99% rename from unittest/libmysql/charset.c rename to unittest/libmariadb/charset.c index 3b61aff7..ee8cdb30 100644 --- a/unittest/libmysql/charset.c +++ b/unittest/libmariadb/charset.c @@ -672,8 +672,8 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -// if (argc > 1) - // get_options(&argc, &argv); + if (argc > 1) + get_options(argc, argv); get_envvars(); diff --git a/unittest/libmysql/connection.c b/unittest/libmariadb/connection.c similarity index 99% rename from unittest/libmysql/connection.c rename to unittest/libmariadb/connection.c index f773a2e9..a7f3f02e 100644 --- a/unittest/libmysql/connection.c +++ b/unittest/libmariadb/connection.c @@ -501,8 +501,8 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -// if (argc > 1) -// get_options(&argc, &argv); + if (argc > 1) + get_options(argc, argv); get_envvars(); diff --git a/unittest/libmysql/cursor.c b/unittest/libmariadb/cursor.c similarity index 99% rename from unittest/libmysql/cursor.c rename to unittest/libmariadb/cursor.c index e663ed78..9b9c5db9 100644 --- a/unittest/libmysql/cursor.c +++ b/unittest/libmariadb/cursor.c @@ -1645,7 +1645,11 @@ static int test_bug9478(MYSQL *mysql) rc= mysql_stmt_reset(stmt); check_stmt_rc(rc, stmt); rc= mysql_stmt_fetch(stmt); + + /* mariadb client supports GEOMETRY, so no error will + be returned FAIL_UNLESS(rc && mysql_stmt_errno(stmt), "Error expected"); + */ } rc= mysql_stmt_close(stmt); check_stmt_rc(rc, stmt); @@ -1831,8 +1835,8 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -// if (argc > 1) -// get_options(&argc, &argv); + if (argc > 1) + get_options(argc, argv); get_envvars(); diff --git a/unittest/libmysql/data.csv b/unittest/libmariadb/data.csv similarity index 100% rename from unittest/libmysql/data.csv rename to unittest/libmariadb/data.csv diff --git a/unittest/libmysql/errors.c b/unittest/libmariadb/errors.c similarity index 99% rename from unittest/libmysql/errors.c rename to unittest/libmariadb/errors.c index 2601ce2e..cefe1856 100644 --- a/unittest/libmysql/errors.c +++ b/unittest/libmariadb/errors.c @@ -271,8 +271,8 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -// if (argc > 1) -// get_options(&argc, &argv); + if (argc > 1) + get_options(argc, argv); get_envvars(); diff --git a/unittest/libmysql/fetch.c b/unittest/libmariadb/fetch.c similarity index 99% rename from unittest/libmysql/fetch.c rename to unittest/libmariadb/fetch.c index f27991be..fe531fab 100644 --- a/unittest/libmysql/fetch.c +++ b/unittest/libmariadb/fetch.c @@ -893,8 +893,8 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -// if (argc > 1) -// get_options(&argc, &argv); + if (argc > 1) + get_options(argc, argv); get_envvars(); diff --git a/unittest/libmysql/logs.c b/unittest/libmariadb/logs.c similarity index 99% rename from unittest/libmysql/logs.c rename to unittest/libmariadb/logs.c index 6cb1040f..7d60f644 100644 --- a/unittest/libmysql/logs.c +++ b/unittest/libmariadb/logs.c @@ -202,8 +202,8 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -// if (argc > 1) -// get_options(&argc, &argv); + if (argc > 1) + get_options(argc, argv); get_envvars(); diff --git a/unittest/libmysql/misc.c b/unittest/libmariadb/misc.c similarity index 99% rename from unittest/libmysql/misc.c rename to unittest/libmariadb/misc.c index 6fe9ba1a..e6f18bd0 100644 --- a/unittest/libmysql/misc.c +++ b/unittest/libmariadb/misc.c @@ -828,8 +828,8 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -// if (argc > 1) -// get_options(&argc, &argv); + if (argc > 1) + get_options(argc, argv); get_envvars(); diff --git a/unittest/libmysql/my_test.h b/unittest/libmariadb/my_test.h similarity index 100% rename from unittest/libmysql/my_test.h rename to unittest/libmariadb/my_test.h diff --git a/unittest/libmysql/ps.c b/unittest/libmariadb/ps.c similarity index 99% rename from unittest/libmysql/ps.c rename to unittest/libmariadb/ps.c index c423935f..38096aad 100644 --- a/unittest/libmysql/ps.c +++ b/unittest/libmariadb/ps.c @@ -4608,8 +4608,8 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -// if (argc > 1) -// get_options(&argc, &argv); + if (argc > 1) + get_options(argc, argv); get_envvars(); diff --git a/unittest/libmysql/ps_bugs.c b/unittest/libmariadb/ps_bugs.c similarity index 100% rename from unittest/libmysql/ps_bugs.c rename to unittest/libmariadb/ps_bugs.c diff --git a/unittest/libmariadb/ps_new.c b/unittest/libmariadb/ps_new.c new file mode 100644 index 00000000..525fadc1 --- /dev/null +++ b/unittest/libmariadb/ps_new.c @@ -0,0 +1,147 @@ +/************************************************************************************ + Copyright (C) 2012 Monty Program AB + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not see + or write to the Free Software Foundation, Inc., + 51 Franklin St., Fifth Floor, Boston, MA 02110, USA + *************************************************************************************/ + +#include "my_test.h" + +/* Utility function to verify the field members */ + + +static int test_multi_result(MYSQL *mysql) +{ + MYSQL_STMT *stmt; + MYSQL_BIND ps_params[3]; /* input parameter buffers */ + MYSQL_BIND rs_bind[3]; + int int_data[3]; /* input/output values */ + my_bool is_null[3]; /* output value nullability */ + int rc, i; + + /* set up stored procedure */ + rc = mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1"); + check_mysql_rc(rc, mysql); + + rc = mysql_query(mysql, + "CREATE PROCEDURE p1(" + " IN p_in INT, " + " OUT p_out INT, " + " INOUT p_inout INT) " + "BEGIN " + " SELECT p_in, p_out, p_inout; " + " SET p_in = 100, p_out = 200, p_inout = 300; " + " SELECT p_in, p_out, p_inout; " + "END"); + check_mysql_rc(rc, mysql); + + /* initialize and prepare CALL statement with parameter placeholders */ + stmt = mysql_stmt_init(mysql); + if (!stmt) + { + printf("Could not initialize statement\n"); + exit(1); + } + rc = mysql_stmt_prepare(stmt, "CALL p1(?, ?, ?)", 16); + check_stmt_rc(rc, stmt); + + /* initialize parameters: p_in, p_out, p_inout (all INT) */ + memset(ps_params, 0, sizeof (ps_params)); + + ps_params[0].buffer_type = MYSQL_TYPE_LONG; + ps_params[0].buffer = (char *) &int_data[0]; + ps_params[0].length = 0; + ps_params[0].is_null = 0; + + ps_params[1].buffer_type = MYSQL_TYPE_LONG; + ps_params[1].buffer = (char *) &int_data[1]; + ps_params[1].length = 0; + ps_params[1].is_null = 0; + + ps_params[2].buffer_type = MYSQL_TYPE_LONG; + ps_params[2].buffer = (char *) &int_data[2]; + ps_params[2].length = 0; + ps_params[2].is_null = 0; + + /* bind parameters */ + rc = mysql_stmt_bind_param(stmt, ps_params); + check_stmt_rc(rc, stmt); + + /* assign values to parameters and execute statement */ + int_data[0]= 10; /* p_in */ + int_data[1]= 20; /* p_out */ + int_data[2]= 30; /* p_inout */ + + rc = mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + + FAIL_IF(mysql_stmt_field_count(stmt) != 3, "expected 3 fields"); + + memset(rs_bind, 0, sizeof (MYSQL_BIND) * 3); + for (i=0; i < 3; i++) + { + rs_bind[i].buffer = (char *) &(int_data[i]); + rs_bind[i].buffer_length = sizeof (int_data); + rs_bind[i].buffer_type = MYSQL_TYPE_LONG; + rs_bind[i].is_null = &is_null[i]; + } + rc= mysql_stmt_bind_result(stmt, rs_bind); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_fetch(stmt); + check_stmt_rc(rc, stmt); + + FAIL_IF(int_data[0] != 10 || int_data[1] != 20 || int_data[2] != 30, + "expected 10 20 30"); + + FAIL_IF(mysql_stmt_next_result(stmt) != 0, "expected more results"); + rc= mysql_stmt_bind_result(stmt, rs_bind); + + rc= mysql_stmt_fetch(stmt); + FAIL_IF(mysql_stmt_field_count(stmt) != 3, "expected 3 fields"); + FAIL_IF(int_data[0] != 100 || int_data[1] != 200 || int_data[2] != 300, + "expected 100 200 300"); + + FAIL_IF(mysql_stmt_next_result(stmt) != 0, "expected more results"); + rc= mysql_stmt_bind_result(stmt, rs_bind); + + rc= mysql_stmt_fetch(stmt); + FAIL_IF(mysql_stmt_field_count(stmt) != 2, "expected 2 fields"); + FAIL_IF(int_data[0] != 200 || int_data[1] != 300, + "expected 100 200 300"); + + FAIL_IF(mysql_stmt_next_result(stmt) != 0, "expected more results"); + FAIL_IF(mysql_stmt_field_count(stmt) != 0, "expected 0 fields"); + + rc= mysql_stmt_close(stmt); + check_stmt_rc(rc, stmt); +} + +struct my_tests_st my_tests[] = { + {"test_multi_result", test_multi_result, TEST_CONNECTION_NEW, CLIENT_MULTI_STATEMENTS, NULL , NULL}, + {NULL, NULL, 0, 0, NULL, NULL} +}; + +int main(int argc, char **argv) +{ + if (argc > 1) + get_options(argc, argv); + + get_envvars(); + + run_tests(my_tests); + + return(exit_status()); +} diff --git a/unittest/libmysql/result.c b/unittest/libmariadb/result.c similarity index 99% rename from unittest/libmysql/result.c rename to unittest/libmariadb/result.c index 35a95d51..885b70bc 100644 --- a/unittest/libmysql/result.c +++ b/unittest/libmariadb/result.c @@ -1053,8 +1053,8 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -// if (argc > 1) -// get_options(&argc, &argv); + if (argc > 1) + get_options(argc, argv); get_envvars(); diff --git a/unittest/libmysql/sp.c b/unittest/libmariadb/sp.c similarity index 98% rename from unittest/libmysql/sp.c rename to unittest/libmariadb/sp.c index 8d27650c..04239e9b 100644 --- a/unittest/libmysql/sp.c +++ b/unittest/libmariadb/sp.c @@ -80,8 +80,8 @@ struct my_tests_st my_tests[] = { int main(int argc, char **argv) { -// if (argc > 1) -// get_options(&argc, &argv); + if (argc > 1) + get_options(argc, argv); get_envvars(); diff --git a/unittest/libmysql/ssl.c b/unittest/libmariadb/ssl.c similarity index 97% rename from unittest/libmysql/ssl.c rename to unittest/libmariadb/ssl.c index 99cdc92a..ad2ffc0e 100644 --- a/unittest/libmysql/ssl.c +++ b/unittest/libmariadb/ssl.c @@ -74,7 +74,7 @@ static int test_ssl_cipher(MYSQL *unused) my= mysql_init(NULL); FAIL_IF(!my, "mysql_init() failed"); - mysql_ssl_set(my,0, 0, "./ca.pem", 0); + mysql_ssl_set(my,0, 0, "./ca.pem", 0, 0); FAIL_IF(!mysql_real_connect(my, hostname, username, password, schema, port, socketname, 0), mysql_error(my)); @@ -115,7 +115,7 @@ static int test_multi_ssl_connections(MYSQL *unused) mysql[i]= mysql_init(NULL); FAIL_IF(!mysql[i],"mysql_init() failed"); - mysql_ssl_set(mysql[i], 0, 0, "./ca.pem", 0); + mysql_ssl_set(mysql[i], 0, 0, "./ca.pem", 0, 0); FAIL_IF(!mysql_real_connect(mysql[i], hostname, username, password, schema, port, socketname, 0), mysql_error(mysql[i])); @@ -154,7 +154,7 @@ static void ssl_thread(void) mysql_thread_end(); pthread_exit(-1); } - mysql_ssl_set(mysql, 0, 0, "./ca.pem", 0); + mysql_ssl_set(mysql, 0, 0, "./ca.pem", 0, 0); if(!mysql_real_connect(mysql, hostname, username, password, schema, port, socketname, 0)) diff --git a/unittest/libmysql/view.c b/unittest/libmariadb/view.c similarity index 100% rename from unittest/libmysql/view.c rename to unittest/libmariadb/view.c