From 225e1d6cfc83fc315f6876b8dae907d3c0f225e3 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Tue, 12 Nov 2024 13:15:53 -0500 Subject: [PATCH 1/8] bump the VERSION --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a189201..7bdf600b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ SET(CC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) SET(CPACK_PACKAGE_VERSION_MAJOR 3) SET(CPACK_PACKAGE_VERSION_MINOR 1) -SET(CPACK_PACKAGE_VERSION_PATCH 26) +SET(CPACK_PACKAGE_VERSION_PATCH 27) SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") MATH(EXPR MARIADB_PACKAGE_VERSION_ID "${CPACK_PACKAGE_VERSION_MAJOR} * 10000 + ${CPACK_PACKAGE_VERSION_MINOR} * 100 + From 581855782ff8c4c1fa2946169ded09f449b69398 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Tue, 12 Nov 2024 13:18:19 -0500 Subject: [PATCH 2/8] bump the VERSION --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cd1f737..7e8f8b2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,7 @@ SET(CC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) SET(CPACK_PACKAGE_VERSION_MAJOR 3) SET(CPACK_PACKAGE_VERSION_MINOR 3) -SET(CPACK_PACKAGE_VERSION_PATCH 13) +SET(CPACK_PACKAGE_VERSION_PATCH 14) SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") MATH(EXPR MARIADB_PACKAGE_VERSION_ID "${CPACK_PACKAGE_VERSION_MAJOR} * 10000 + ${CPACK_PACKAGE_VERSION_MINOR} * 100 + From 55e3b63c343207371283a749508e0df4dfadd249 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 15 Nov 2024 17:41:23 +0100 Subject: [PATCH 3/8] CONPY-739: prepared statement support AUTO_SEC_PART_DIGITS FROM_UNIXTIME() function always returns AUTO_SEC_PART_DIGITS (value=39). In case the microsecond value was set in MYSQL_TIME, the decimal part should be SEC_PART_DIGITS (=6). --- libmariadb/ma_stmt_codec.c | 33 +++++++++++------------ unittest/libmariadb/ps_bugs.c | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/libmariadb/ma_stmt_codec.c b/libmariadb/ma_stmt_codec.c index afb46b25..ab3ec1ed 100644 --- a/libmariadb/ma_stmt_codec.c +++ b/libmariadb/ma_stmt_codec.c @@ -50,6 +50,7 @@ #include "mysql.h" #include /* ceil() */ #include +#include #ifdef WIN32 #include @@ -1145,29 +1146,25 @@ void ps_fetch_datetime(MYSQL_BIND *r_param, const MYSQL_FIELD * field, length= sprintf(dtbuffer, "%04u-%02u-%02u", tm.year, tm.month, tm.day); break; case MYSQL_TYPE_TIME: - length= sprintf(dtbuffer, "%s%02u:%02u:%02u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second); - if (field->decimals && field->decimals <= 6) + if (field->decimals && (field->decimals <= SEC_PART_DIGITS || + (field->decimals == AUTO_SEC_PART_DIGITS && tm.second_part))) { - char ms[8]; - sprintf(ms, ".%06lu", tm.second_part); - if (field->decimals < 6) - ms[field->decimals + 1]= 0; - length+= strlen(ms); - strcat(dtbuffer, ms); - } + uint8_t decimals= (field->decimals == AUTO_SEC_PART_DIGITS) ? SEC_PART_DIGITS : field->decimals; + length= sprintf(dtbuffer, "%s%02u:%02u:%02u.%0*u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second, + decimals, (uint32_t)(tm.second_part / pow(10, 6 - decimals))); + } else + length= sprintf(dtbuffer, "%s%02u:%02u:%02u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second); break; case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: - length= sprintf(dtbuffer, "%04u-%02u-%02u %02u:%02u:%02u", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second); - if (field->decimals && field->decimals <= 6) + if (field->decimals && (field->decimals <= SEC_PART_DIGITS || + (field->decimals == AUTO_SEC_PART_DIGITS && tm.second_part))) { - char ms[8]; - sprintf(ms, ".%06lu", tm.second_part); - if (field->decimals < 6) - ms[field->decimals + 1]= 0; - length+= strlen(ms); - strcat(dtbuffer, ms); - } + uint8_t decimals= (field->decimals == AUTO_SEC_PART_DIGITS) ? SEC_PART_DIGITS : field->decimals; + length= sprintf(dtbuffer, "%04u-%02u-%02u %02u:%02u:%02u.%0*u", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, + decimals, (uint32_t)(tm.second_part / pow(10, 6 - decimals))); + } else + length= sprintf(dtbuffer, "%04u-%02u-%02u %02u:%02u:%02u", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second); break; default: dtbuffer[0]= 0; diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index 91de2ee3..f193e3af 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -5572,7 +5572,56 @@ end: return ret; } +static int test_conc739(MYSQL *mysql) +{ + MYSQL_STMT *stmt; + int rc; + MYSQL_BIND bind[2]; + char buffer[2][100]; + MYSQL_ROW row; + MYSQL_RES *result; + uint8 i; + + rc= mysql_query(mysql, "SELECT FROM_UNIXTIME('1922.1'), FROM_UNIXTIME('1922.0')"); + check_mysql_rc(rc, mysql); + result= mysql_store_result(mysql); + row= mysql_fetch_row(result); + + stmt= mysql_stmt_init(mysql); + + rc= mysql_stmt_prepare(stmt, SL("SELECT FROM_UNIXTIME('1922.1'), FROM_UNIXTIME('1922.0')")); + check_stmt_rc(rc, stmt); + + memset(bind, 0, 2 * sizeof(MYSQL_BIND)); + for (i=0; i < 2; i++) + { + bind[i].buffer_type= MYSQL_TYPE_STRING; + bind[i].buffer= &buffer[i]; + bind[i].buffer_length= 100; + } + + rc= mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_bind_result(stmt, bind); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_fetch(stmt); + check_stmt_rc(rc, stmt); + + for (i=0; i < 2; i++) + { + diag("text: %s binary: %s", row[i], buffer[i]); + FAIL_IF(strcmp(buffer[i], row[i]), "Different results (text/binary protocol)"); + } + + mysql_stmt_close(stmt); + mysql_free_result(result); + return OK; +} + struct my_tests_st my_tests[] = { + {"test_conc739", test_conc739, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc633", test_conc633, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc627", test_conc627, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_mdev19838", test_mdev19838, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, From 662a966056a66ea5667217ddb1aa673e95707590 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Mon, 18 Nov 2024 07:15:42 +0100 Subject: [PATCH 4/8] CONC-702: Fix statement status If a resultset in binary protpcpl doesn't contain data (fields equal zero) and there are no more pending result sets we need to change the statement status to FETCH_DONE, otherwise it will be impossible to execute other commands until the statement was closed. --- libmariadb/mariadb_stmt.c | 2 ++ unittest/libmariadb/ps_bugs.c | 67 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/libmariadb/mariadb_stmt.c b/libmariadb/mariadb_stmt.c index 5bcecfde..bb559a09 100644 --- a/libmariadb/mariadb_stmt.c +++ b/libmariadb/mariadb_stmt.c @@ -2499,6 +2499,8 @@ int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt) stmt->upsert_status.server_status= stmt->mysql->server_status; ma_status_callback(stmt->mysql, last_status); stmt->upsert_status.warning_count= stmt->mysql->warning_count; + if (!mysql_stmt_more_results(stmt)) + stmt->state= MYSQL_STMT_FETCH_DONE; } stmt->field_count= stmt->mysql->field_count; diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index 72af30b4..23d260a1 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -5741,7 +5741,74 @@ end: return ret; } +static int test_conc702(MYSQL *ma) +{ + MYSQL_STMT *stmt, *stmt2; + + diag("Server info %s\nClient info: %s", + mysql_get_server_info(ma), mysql_get_client_info()); + + mysql_query(ma, "DROP PROCEDURE IF EXISTS p1"); + + mysql_query(ma, "CREATE PROCEDURE p1() BEGIN" + " SELECT 1 FROM DUAL; " + "END"); + + stmt= mysql_stmt_init(ma); + + FAIL_IF(!stmt, "Could not allocate stmt"); + + mysql_stmt_prepare(stmt, "CALL p1()", -1); + mysql_stmt_execute(stmt); + + + mysql_stmt_store_result(stmt); + + // We've done everything w/ result and skip everything else + + while (mysql_stmt_more_results(stmt)) { + + mysql_stmt_next_result(stmt); + // state at this moment is MYSQL_STMT_WAITING_USE_OR_STORE. But there is no result, + // we can't store it. And there is no way to change it + + } + // Now we are not closing it, for later use. For example it's been put to the cache + // Using connection freely - we haven't done anything wrong, "nothing is out of sync" + + mysql_query(ma, "DROP PROCEDURE p1"); + mysql_query(ma, "DROP PROCEDURE IF EXISTS p2"); + mysql_query(ma, "CREATE PROCEDURE p2() " + "BEGIN " + " SELECT 'Marten' FROM DUAL; " + " SELECT 'Zack' FROM DUAL; " + "END"); + + stmt2= mysql_stmt_init(ma); + + mysql_stmt_prepare(stmt2, "CALL p2()", -1); + + mysql_stmt_execute(stmt2); + + mysql_stmt_store_result(stmt2); + + // I was initially wrong, this goes thru + check_stmt_rc(mysql_stmt_next_result(stmt2), stmt2); + + // But we get error"Out of sync" set, if check + // check_stmt_rc(mysql_stmt_next_result(stmt2), stmt2); + + check_stmt_rc(mysql_stmt_store_result(stmt2), stmt2); + + mysql_stmt_close(stmt2); + + mysql_stmt_close(stmt); + + return OK; +} + struct my_tests_st my_tests[] = { + {"test_conc702", test_conc702, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc633", test_conc633, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc623", test_conc623, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc627", test_conc627, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, From 1a2ed3f67af698b394b2faed069b49d4f409a155 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 20 Nov 2024 14:42:04 +0100 Subject: [PATCH 5/8] CONC-710: Remove UDF declarations Removed UDF declarations from mariadb_com.h --- include/mariadb_com.h | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/include/mariadb_com.h b/include/mariadb_com.h index 340568d6..57e48925 100644 --- a/include/mariadb_com.h +++ b/include/mariadb_com.h @@ -404,30 +404,6 @@ struct rand_struct { double max_value_dbl; }; - /* The following is for user defined functions */ - -enum Item_result {STRING_RESULT,REAL_RESULT,INT_RESULT,ROW_RESULT,DECIMAL_RESULT}; - -typedef struct st_udf_args -{ - unsigned int arg_count; /* Number of arguments */ - enum Item_result *arg_type; /* Pointer to item_results */ - char **args; /* Pointer to argument */ - unsigned long *lengths; /* Length of string arguments */ - char *maybe_null; /* Set to 1 for all maybe_null args */ -} UDF_ARGS; - - /* This holds information about the result */ - -typedef struct st_udf_init -{ - my_bool maybe_null; /* 1 if function can return NULL */ - unsigned int decimals; /* for real functions */ - unsigned int max_length; /* For string functions */ - char *ptr; /* free pointer for function data */ - my_bool const_item; /* 0 if result is independent of arguments */ -} UDF_INIT; - /* Connection types */ #define MARIADB_CONNECTION_UNIXSOCKET 0 #define MARIADB_CONNECTION_TCP 1 From bdc66d6b8f83256ac116a4a18a25df18f3027399 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 27 Nov 2024 07:48:27 +0100 Subject: [PATCH 6/8] Fix for CONC-703: If connect failed and no error was set (apparently this happens sometimes on Mac) we now set error to CR_SERVER_LOST. --- libmariadb/mariadb_lib.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 7d5f6241..da754b3d 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -2040,6 +2040,12 @@ error: if (!(client_flag & CLIENT_REMEMBER_OPTIONS) && !(IS_MYSQL_ASYNC(mysql))) mysql_close_options(mysql); + + /* CONC-703: If no error was set, we set CR_SERVER_LOST by default */ + if (!mysql_errno(mysql)) + my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN, + "Can't connect to server (%d).", + errno); return(0); } From a13f65c4c6225902f62b8a88461e42b661a25dbc Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 27 Nov 2024 07:52:29 +0100 Subject: [PATCH 7/8] Fix CMake deprecation warning Minimum required CMake version is now 3.5.1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bdf600b..ba7e6509 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # This is the LGPL libmariadb project. -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1 FATAL_ERROR) INCLUDE(CheckFunctionExists) INCLUDE(FeatureSummary) IF(COMMAND CMAKE_POLICY) From 78e56a7fd3c1af3de659a736a90702e76ad5675b Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 27 Nov 2024 16:03:45 +0100 Subject: [PATCH 8/8] Fixed replication build With fix for CONC-710 (Remove UDF declarations) in 3.1 branch, we also removed the variable types, which are also used by the binary log api. The enumeration for variable types were now added back in mariadb_rpl.h --- include/mariadb_rpl.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/mariadb_rpl.h b/include/mariadb_rpl.h index ea0ca4db..255a9a56 100644 --- a/include/mariadb_rpl.h +++ b/include/mariadb_rpl.h @@ -73,6 +73,8 @@ extern "C" { #define SEMI_SYNC_INDICATOR 0xEF #define SEMI_SYNC_ACK_REQ 0x01 +enum Item_result {STRING_RESULT,REAL_RESULT,INT_RESULT,ROW_RESULT,DECIMAL_RESULT}; + /* Options */ enum mariadb_rpl_option { MARIADB_RPL_FILENAME, /* Filename and length */