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

Merge branch '3.3' into 3.4

This commit is contained in:
Georg Richter
2025-02-11 11:45:53 +01:00
8 changed files with 113 additions and 13 deletions

View File

@@ -116,10 +116,11 @@ extern const char *mariadb_client_errors[]; /* Error messages */
#define CR_BINLOG_SEMI_SYNC_ERROR 5023 #define CR_BINLOG_SEMI_SYNC_ERROR 5023
#define CR_INVALID_CLIENT_FLAG 5024 #define CR_INVALID_CLIENT_FLAG 5024
#define CR_STMT_NO_RESULT 5025 #define CR_STMT_NO_RESULT 5025
#define CR_ERR_MISSING_ERROR_INFO 5026
/* Always last, if you add new error codes please update the /* Always last, if you add new error codes please update the
value for CR_MARIADB_LAST_ERROR */ value for CR_MARIADB_LAST_ERROR */
#define CR_MARIADB_LAST_ERROR CR_STMT_NO_RESULT #define CR_MARIADB_LAST_ERROR CR_ERR_MISSING_ERROR_INFO
#endif #endif
@@ -128,6 +129,6 @@ extern const char *mariadb_client_errors[]; /* Error messages */
#define ER(code) IS_MYSQL_ERROR((code)) ? client_errors[(code) - CR_MIN_ERROR] : \ #define ER(code) IS_MYSQL_ERROR((code)) ? client_errors[(code) - CR_MIN_ERROR] : \
IS_MARIADB_ERROR((code)) ? mariadb_client_errors[(code) - CER_MIN_ERROR] : \ IS_MARIADB_ERROR((code)) ? mariadb_client_errors[(code) - CER_MIN_ERROR] : \
"Unknown or undefined error code" "Unknown or undefined error code"
#define CER(code) ER((code)) #define CER(code) ER((code))

View File

@@ -26,8 +26,33 @@
(This particular implementation uses Posix ucontext swapcontext().) (This particular implementation uses Posix ucontext swapcontext().)
*/ */
/*
When running with address sanitizer, the stack switching can cause confusion
unless the __sanitizer_{start,finish}_switch_fiber() functions are used
(CONC-618).
In this case prefer the use of boost::context or ucontext, which should have
this instrumentation, over our custom assembler variants.
*/
#ifdef __has_feature
/* Clang */
# if __has_feature(address_sanitizer)
# define ASAN_PREFER_NON_ASM 1
# endif
#else
/* GCC */
# ifdef __SANITIZE_ADDRESS__
# define ASAN_PREFER_NON_ASM 1
# endif
#endif
#ifdef _WIN32 #ifdef _WIN32
#define MY_CONTEXT_USE_WIN32_FIBERS 1 #define MY_CONTEXT_USE_WIN32_FIBERS 1
#elif defined(ASAN_PREFER_NON_ASM) && defined(HAVE_BOOST_CONTEXT_H)
#define MY_CONTEXT_USE_BOOST_CONTEXT
#elif defined(ASAN_PREFER_NON_ASM) && defined(HAVE_UCONTEXT_H)
#define MY_CONTEXT_USE_UCONTEXT
#elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__x86_64__) && !defined(__ILP32__) #elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__x86_64__) && !defined(__ILP32__)
#define MY_CONTEXT_USE_X86_64_GCC_ASM #define MY_CONTEXT_USE_X86_64_GCC_ASM
#elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__) #elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__)

View File

@@ -168,12 +168,6 @@ SET(MYSQL_LIB_SYMBOLS
mysql_use_result mysql_use_result
mysql_warning_count) mysql_warning_count)
# some gcc versions fail to compile asm parts of my_context.c,
# if build type is "Release" (see CONC-133), so we need to add -g flag
IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_BUILD_TYPE MATCHES "Release")
SET_SOURCE_FILES_PROPERTIES(my_context.c PROPERTIES COMPILE_FLAGS -g)
ENDIF()
IF(ZLIB_FOUND AND WITH_EXTERNAL_ZLIB) IF(ZLIB_FOUND AND WITH_EXTERNAL_ZLIB)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
ELSE() ELSE()

View File

@@ -105,6 +105,7 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
c->user_func= f; c->user_func= f;
c->user_data= d; c->user_data= d;
c->active= 1; c->active= 1;
u.a[1]= 0; /* Otherwise can give uninitialized warnings on 32-bit. */
u.p= c; u.p= c;
makecontext(&c->spawned_context, (uc_func_t)my_context_spawn_internal, 2, makecontext(&c->spawned_context, (uc_func_t)my_context_spawn_internal, 2,
u.a[0], u.a[1]); u.a[0], u.a[1]);
@@ -204,7 +205,7 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
( (
"movq %%rsp, (%[save])\n\t" "movq %%rsp, (%[save])\n\t"
"movq %[stack], %%rsp\n\t" "movq %[stack], %%rsp\n\t"
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __clang__) && !defined(__INTEL_COMPILER) #if defined(__GCC_HAVE_DWARF2_CFI_ASM) || (defined(__clang__) && __clang_major__ < 13)
/* /*
This emits a DWARF DW_CFA_undefined directive to make the return address This emits a DWARF DW_CFA_undefined directive to make the return address
undefined. This indicates that this is the top of the stack frame, and undefined. This indicates that this is the top of the stack frame, and
@@ -440,7 +441,7 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
( (
"movl %%esp, (%[save])\n\t" "movl %%esp, (%[save])\n\t"
"movl %[stack], %%esp\n\t" "movl %[stack], %%esp\n\t"
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __clang__) && !defined(__INTEL_COMPILER) #if defined(__GCC_HAVE_DWARF2_CFI_ASM) || (defined(__clang__) && __clang_major__ < 13)
/* /*
This emits a DWARF DW_CFA_undefined directive to make the return address This emits a DWARF DW_CFA_undefined directive to make the return address
undefined. This indicates that this is the top of the stack frame, and undefined. This indicates that this is the top of the stack frame, and
@@ -675,7 +676,7 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d)
( (
"mov x10, sp\n\t" "mov x10, sp\n\t"
"mov sp, %[stack]\n\t" "mov sp, %[stack]\n\t"
#if !defined(__INTEL_COMPILER) #if defined(__GCC_HAVE_DWARF2_CFI_ASM) || (defined(__clang__) && __clang_major__ < 13)
/* /*
This emits a DWARF DW_CFA_undefined directive to make the return address This emits a DWARF DW_CFA_undefined directive to make the return address
(UNW_AARCH64_X30) undefined. This indicates that this is the top of the (UNW_AARCH64_X30) undefined. This indicates that this is the top of the

View File

@@ -120,6 +120,7 @@ const char *mariadb_client_errors[] =
/* 5023 */ "Semi sync request error: %s", /* 5023 */ "Semi sync request error: %s",
/* 5024 */ "Invalid client flags (%lu) specified. Supported flags: %lu", /* 5024 */ "Invalid client flags (%lu) specified. Supported flags: %lu",
/* 5025 */ "Statement has no result set", /* 5025 */ "Statement has no result set",
/* 5026 */ "Server returned an error packet without further information",
"" ""
}; };

View File

@@ -80,7 +80,7 @@
#define strncasecmp _strnicmp #define strncasecmp _strnicmp
#endif #endif
#define ASYNC_CONTEXT_DEFAULT_STACK_SIZE (4096*15) #define ASYNC_CONTEXT_DEFAULT_STACK_SIZE (256*1024)
#define MA_RPL_VERSION_HACK "5.5.5-" #define MA_RPL_VERSION_HACK "5.5.5-"
#define CHARSET_NAME_LEN 64 #define CHARSET_NAME_LEN 64
@@ -273,6 +273,11 @@ restart:
ma_strmake(net->last_error,(char*) pos, ma_strmake(net->last_error,(char*) pos,
min(len,sizeof(net->last_error)-1)); min(len,sizeof(net->last_error)-1));
} }
/* MDEV-35935: if server sends error packet without error, we have to
set error manually */
if (!net->last_errno) {
my_set_error(mysql, CR_ERR_MISSING_ERROR_INFO, SQLSTATE_UNKNOWN, 0);
}
} }
else else
{ {

View File

@@ -272,8 +272,77 @@ static int test_parse_error_and_bad_length(MYSQL *mysql)
return OK; return OK;
} }
#define TEST_ARRAY_SIZE 1024
static int test_mdev35935(MYSQL *mysql)
{
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
const char *stmt_str= "INSERT INTO bulk1 (a,b) VALUES (?,?)";
unsigned int array_size= TEST_ARRAY_SIZE;
int rc;
unsigned int i;
char **buffer;
unsigned long *lengths;
unsigned int *vals;
MYSQL_BIND bind[2];
const char *data= "test";
SKIP_MYSQL(mysql);
rc= mysql_select_db(mysql, schema);
rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk1");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "CREATE TABLE bulk1 (a int , b VARCHAR(255))");
check_mysql_rc(rc, mysql);
rc= mysql_stmt_prepare(stmt, SL(stmt_str));
check_stmt_rc(rc, stmt);
rc= mysql_query(mysql, "ALTER TABLE bulk1 ADD c int");
check_mysql_rc(rc, mysql);
/* allocate memory */
buffer= calloc(TEST_ARRAY_SIZE, sizeof(char *));
lengths= calloc(TEST_ARRAY_SIZE, sizeof *lengths);
vals= calloc(TEST_ARRAY_SIZE, sizeof *vals);
for (i=0; i < TEST_ARRAY_SIZE; i++)
{
buffer[i]= (void *)data;
lengths[i]= -1;
vals[i]= i;
}
memset(bind, 0, sizeof(MYSQL_BIND) * 2);
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= vals;
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer= (void *)buffer;
bind[1].length= (unsigned long *)lengths;
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_bind_param(stmt, bind);
check_stmt_rc(rc, stmt);
if ((rc= mysql_stmt_execute(stmt)))
{
FAIL_IF((!mysql_stmt_errno(stmt) || !mysql_errno(mysql)), "Error number > 0 expected");
}
mysql_stmt_close(stmt);
rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk1");
check_mysql_rc(rc, mysql);
return OK;
}
struct my_tests_st my_tests[] = { struct my_tests_st my_tests[] = {
{"test_mdev35935", test_mdev35935, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_client_warnings", test_client_warnings, TEST_CONNECTION_DEFAULT, 0, NULL , NULL}, {"test_client_warnings", test_client_warnings, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_ps_client_warnings", test_ps_client_warnings, TEST_CONNECTION_DEFAULT, 0, NULL , NULL}, {"test_ps_client_warnings", test_ps_client_warnings, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_server_warnings", test_server_warnings, TEST_CONNECTION_DEFAULT, 0, NULL , NULL}, {"test_server_warnings", test_server_warnings, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},

View File

@@ -5027,11 +5027,14 @@ static int test_conc_fraction(MYSQL *mysql)
diag("second_part: %ld", tm.second_part); diag("second_part: %ld", tm.second_part);
expected= i > 6 ? 123456 : frac * (unsigned int)powl(10, (6 - i)); expected= frac * 100000;
while (expected >= 1000000)
expected /= 10;
if (tm.second_part != expected) if (tm.second_part != expected)
{ {
diag("Error: tm.second_part=%ld expected=%ld", tm.second_part, expected); diag("Error: tm.second_part=%ld expected=%ld", tm.second_part, expected);
mysql_stmt_close(stmt);
return FAIL; return FAIL;
} }
} }
@@ -5618,6 +5621,7 @@ static int test_conc623(MYSQL *mysql)
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CB_PARAM, conc623_param_callback); rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CB_PARAM, conc623_param_callback);
check_stmt_rc(rc, stmt); check_stmt_rc(rc, stmt);
memset(&bind, 0, sizeof(MYSQL_BIND));
bind.buffer_type= MYSQL_TYPE_LONG; bind.buffer_type= MYSQL_TYPE_LONG;
rc= mysql_stmt_bind_param(stmt, &bind); rc= mysql_stmt_bind_param(stmt, &bind);
check_stmt_rc(rc, stmt); check_stmt_rc(rc, stmt);