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
2024-11-27 16:17:12 +01:00
7 changed files with 141 additions and 43 deletions

View File

@@ -2,7 +2,7 @@
# This is the LGPL libmariadb project. # 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(CheckFunctionExists)
IF(COMMAND CMAKE_POLICY) IF(COMMAND CMAKE_POLICY)
SET(NEW_POLICIES CMP0003 CMP0022 CMP0023 CMP0057 CMP0077 CMP0069 CMP0075) SET(NEW_POLICIES CMP0003 CMP0022 CMP0023 CMP0057 CMP0077 CMP0069 CMP0075)

View File

@@ -427,30 +427,6 @@ struct rand_struct {
double max_value_dbl; 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 */ /* Connection types */
#define MARIADB_CONNECTION_UNIXSOCKET 0 #define MARIADB_CONNECTION_UNIXSOCKET 0
#define MARIADB_CONNECTION_TCP 1 #define MARIADB_CONNECTION_TCP 1

View File

@@ -73,6 +73,8 @@ extern "C" {
#define SEMI_SYNC_INDICATOR 0xEF #define SEMI_SYNC_INDICATOR 0xEF
#define SEMI_SYNC_ACK_REQ 0x01 #define SEMI_SYNC_ACK_REQ 0x01
enum Item_result {STRING_RESULT,REAL_RESULT,INT_RESULT,ROW_RESULT,DECIMAL_RESULT};
/* Options */ /* Options */
enum mariadb_rpl_option { enum mariadb_rpl_option {
MARIADB_RPL_FILENAME, /* Filename and length */ MARIADB_RPL_FILENAME, /* Filename and length */

View File

@@ -50,6 +50,7 @@
#include "mysql.h" #include "mysql.h"
#include <math.h> /* ceil() */ #include <math.h> /* ceil() */
#include <limits.h> #include <limits.h>
#include <stdint.h>
#ifdef WIN32 #ifdef WIN32
#include <malloc.h> #include <malloc.h>
@@ -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); length= sprintf(dtbuffer, "%04u-%02u-%02u", tm.year, tm.month, tm.day);
break; break;
case MYSQL_TYPE_TIME: case MYSQL_TYPE_TIME:
length= sprintf(dtbuffer, "%s%02u:%02u:%02u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second); if (field->decimals && (field->decimals <= SEC_PART_DIGITS ||
if (field->decimals && field->decimals <= 6) (field->decimals == AUTO_SEC_PART_DIGITS && tm.second_part)))
{ {
char ms[8]; uint8_t decimals= (field->decimals == AUTO_SEC_PART_DIGITS) ? SEC_PART_DIGITS : field->decimals;
sprintf(ms, ".%06lu", tm.second_part); length= sprintf(dtbuffer, "%s%02u:%02u:%02u.%0*u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second,
if (field->decimals < 6) decimals, (uint32_t)(tm.second_part / pow(10, 6 - decimals)));
ms[field->decimals + 1]= 0; } else
length+= strlen(ms); length= sprintf(dtbuffer, "%s%02u:%02u:%02u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second);
strcat(dtbuffer, ms);
}
break; break;
case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_TIMESTAMP: 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 <= SEC_PART_DIGITS ||
if (field->decimals && field->decimals <= 6) (field->decimals == AUTO_SEC_PART_DIGITS && tm.second_part)))
{ {
char ms[8]; uint8_t decimals= (field->decimals == AUTO_SEC_PART_DIGITS) ? SEC_PART_DIGITS : field->decimals;
sprintf(ms, ".%06lu", tm.second_part); length= sprintf(dtbuffer, "%04u-%02u-%02u %02u:%02u:%02u.%0*u", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second,
if (field->decimals < 6) decimals, (uint32_t)(tm.second_part / pow(10, 6 - decimals)));
ms[field->decimals + 1]= 0; } else
length+= strlen(ms); length= sprintf(dtbuffer, "%04u-%02u-%02u %02u:%02u:%02u", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
strcat(dtbuffer, ms);
}
break; break;
default: default:
dtbuffer[0]= 0; dtbuffer[0]= 0;

View File

@@ -2054,6 +2054,12 @@ error:
if (!(client_flag & CLIENT_REMEMBER_OPTIONS) && if (!(client_flag & CLIENT_REMEMBER_OPTIONS) &&
!(IS_MYSQL_ASYNC(mysql))) !(IS_MYSQL_ASYNC(mysql)))
mysql_close_options(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); return(0);
} }

View File

@@ -2543,6 +2543,8 @@ int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt)
stmt->upsert_status.server_status= stmt->mysql->server_status; stmt->upsert_status.server_status= stmt->mysql->server_status;
ma_status_callback(stmt->mysql, last_status); ma_status_callback(stmt->mysql, last_status);
stmt->upsert_status.warning_count= stmt->mysql->warning_count; 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; stmt->field_count= stmt->mysql->field_count;

View File

@@ -5809,9 +5809,124 @@ static int test_conc683(MYSQL *mysql)
return OK; return OK;
} }
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;
}
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[] = { struct my_tests_st my_tests[] = {
{"test_conc683", test_conc683, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc683", test_conc683, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc667", test_conc667, 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_conc739", test_conc739, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc633", test_conc633, 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_conc623", test_conc623, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc627", test_conc627, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc627", test_conc627, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},