patch ob-connector-c 2.2.3
This commit is contained in:
commit
6a6074a2a9
@ -34,9 +34,26 @@ ENDFOREACH()
|
||||
SET(CC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
SET(CC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR 20)
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR 1)
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH 13)
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR 0)
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR 0)
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH 0)
|
||||
|
||||
#get rpm version for Win pack and mariadb_version.h.in
|
||||
SET(CPACK_PACKAGE_VERSION_RPM "1.0.0")
|
||||
file(STRINGS ./rpm/libobclient-VER.txt STRLIST LIMIT_COUNT 1)
|
||||
foreach(STR IN LISTS STRLIST)
|
||||
SET(CPACK_PACKAGE_VERSION_RPM ${STR})
|
||||
endforeach(STR)
|
||||
|
||||
string(REPLACE "." ";" VERSION_LIST ${CPACK_PACKAGE_VERSION_RPM})
|
||||
list(GET VERSION_LIST 0 CPACK_PACKAGE_VERSION_MAJOR)
|
||||
list(GET VERSION_LIST 1 CPACK_PACKAGE_VERSION_MINOR)
|
||||
list(GET VERSION_LIST 2 CPACK_PACKAGE_VERSION_PATCH)
|
||||
list(LENGTH VERSION_LIST len)
|
||||
IF(len EQUAL 4)
|
||||
list(GET VERSION_LIST 3 CPACK_PACKAGE_VERSION_EXTRA)
|
||||
ENDIF()
|
||||
|
||||
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 +
|
||||
@ -127,6 +144,13 @@ SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDBUG_OFF")
|
||||
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DDBUG_OFF")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDBUG_OFF")
|
||||
|
||||
IF(UNIX)
|
||||
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -z noexecstack -z now -pie -fPIC -fstack-protector-all")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -z noexecstack -z now -pie -fPIC -fstack-protector-all")
|
||||
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -z noexecstack -z now -pie -fPIC -fstack-protector-all")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -z noexecstack -z now -pie -fPIC -fstack-protector-all")
|
||||
ENDIF()
|
||||
|
||||
IF(CMAKE_COMPILER_IS_GNUCC)
|
||||
INCLUDE(CheckCCompilerFlag)
|
||||
SET(GCC_FLAGS -Wunused -Wlogical-op -Wno-uninitialized -Wall -Wextra -Wformat-security -Wno-init-self -Wwrite-strings -Wshift-count-overflow -Wdeclaration-after-statement -Wno-undef -Wno-unknown-pragmas)
|
||||
@ -446,12 +470,6 @@ ELSE()
|
||||
|
||||
string(TIMESTAMP COMPILE_TIME %Y%m%d%H%M%S)
|
||||
MESSAGE(STATUS ${COMPILE_TIME})
|
||||
|
||||
SET(CPACK_PACKAGE_VERSION_RPM ${CPACK_PACKAGE_VERSION})
|
||||
file(STRINGS ./rpm/libobclient-VER.txt STRLIST LIMIT_COUNT 1)
|
||||
foreach(STR IN LISTS STRLIST)
|
||||
SET(CPACK_PACKAGE_VERSION_RPM ${STR})
|
||||
endforeach(STR)
|
||||
|
||||
IF(NOT PACKAGE_STATUS_SUFFIX)
|
||||
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "ob-connector-c-${CPACK_PACKAGE_VERSION_RPM}-src")
|
||||
|
@ -378,30 +378,37 @@ enum ObCapabilityFlagShift
|
||||
OBCLIENT_CAP_PROXY_REROUTE_SHIFT,
|
||||
OBCLIENT_CAP_PROXY_SESSION_SYNC_SHIFT,
|
||||
OBCLIENT_CAP_FULL_LINK_TRACE_SHIFT,
|
||||
OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO_SHIFT
|
||||
OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO_SHIFT,
|
||||
OBCLIENT_CAP_PROXY_SESSION_VAR_SYNC_SHIFT,
|
||||
OBCLIENT_CAP_PROXY_WEAK_STALE_FEEDBACK_SHIFT,
|
||||
OBCLIENT_CAP_PROXY_FULL_LINK_TRACE_SHOW_TRACE_SHIFT
|
||||
};
|
||||
|
||||
#define OB_TEST_CAPABILITY(cap, tg_cap) (((cap) & (tg_cap)) == (tg_cap))
|
||||
#define OBCLIENT_TEST_CAPABILITY(cap, tg_cap) (((cap) & (tg_cap)) == (tg_cap))
|
||||
#define OBCLIENT_CAP_GET_TYPE(i) (1LL << i)
|
||||
#define OBCLIENT_CAP_PARTITION_TABLE OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PARTITION_TABLE_SHIFT)
|
||||
#define OBCLIENT_CAP_CHANGE_USER OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_CHANGE_USER_SHIFT)
|
||||
#define OBCLIENT_CAP_READ_WEAK OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_READ_WEAK_SHIFT)
|
||||
#define OBCLIENT_CAP_CHECKSUM OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_CHECKSUM_SHIFT)
|
||||
#define OBCLIENT_CAP_SAFE_WEAK_READ OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_SAFE_WEAK_READ_SHIFT)
|
||||
#define OBCLIENT_CAP_PRIORITY_HIT OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PRIORITY_HIT_SHIFT)
|
||||
#define OBCLIENT_CAP_CHECKSUM_SWITCH OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_CHECKSUM_SWITCH_SHIFT)
|
||||
#define OBCLIENT_CAP_OB_PROTOCOL_V2 OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_OB_PROTOCOL_V2_SHIFT)
|
||||
#define OBCLIENT_CAP_PARTITION_TABLE OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PARTITION_TABLE_SHIFT)
|
||||
#define OBCLIENT_CAP_CHANGE_USER OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_CHANGE_USER_SHIFT)
|
||||
#define OBCLIENT_CAP_READ_WEAK OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_READ_WEAK_SHIFT)
|
||||
#define OBCLIENT_CAP_CHECKSUM OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_CHECKSUM_SHIFT)
|
||||
#define OBCLIENT_CAP_SAFE_WEAK_READ OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_SAFE_WEAK_READ_SHIFT)
|
||||
#define OBCLIENT_CAP_PRIORITY_HIT OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PRIORITY_HIT_SHIFT)
|
||||
#define OBCLIENT_CAP_CHECKSUM_SWITCH OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_CHECKSUM_SWITCH_SHIFT)
|
||||
#define OBCLIENT_CAP_OB_PROTOCOL_V2 OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_OB_PROTOCOL_V2_SHIFT)
|
||||
#define OBCLIENT_CAP_EXTRA_OK_PACKET_FOR_STATISTICS OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_EXTRA_OK_PACKET_FOR_STATISTICS_SHIFT)
|
||||
#define OBCLIENT_CAP_PL_ROUTE OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PL_ROUTE_SHIFT)
|
||||
#define OBCLIENT_CAP_PROXY_REROUTE OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PROXY_REROUTE_SHIFT)
|
||||
#define OBCLIENT_CAP_PROXY_SESSION_SYNC OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PROXY_SESSION_SYNC_SHIFT)
|
||||
#define OBCLIENT_CAP_FULL_LINK_TRACE OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_FULL_LINK_TRACE_SHIFT)
|
||||
#define OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO_SHIFT)
|
||||
#define OBCLIENT_CAP_PL_ROUTE OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PL_ROUTE_SHIFT)
|
||||
#define OBCLIENT_CAP_PROXY_REROUTE OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PROXY_REROUTE_SHIFT)
|
||||
#define OBCLIENT_CAP_PROXY_SESSION_SYNC OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PROXY_SESSION_SYNC_SHIFT)
|
||||
#define OBCLIENT_CAP_FULL_LINK_TRACE OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_FULL_LINK_TRACE_SHIFT)
|
||||
#define OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO_SHIFT)
|
||||
#define OBCLIENT_CAP_PROXY_SESSION_VAR_SYNC OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PROXY_SESSION_VAR_SYNC_SHIFT)
|
||||
#define OBCLIENT_CAP_PROXY_WEAK_STALE_FEEDBACK OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PROXY_WEAK_STALE_FEEDBACK_SHIFT)
|
||||
#define OBCLIENT_CAP_PROXY_FULL_LINK_TRACE_SHOW_TRACE OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_PROXY_FULL_LINK_TRACE_SHOW_TRACE_SHIFT)
|
||||
|
||||
static const unsigned long OBPROXY_DEFAULT_CAPABILITY_FLAG =
|
||||
(OBCLIENT_CAP_OB_PROTOCOL_V2
|
||||
| OBCLIENT_CAP_FULL_LINK_TRACE
|
||||
| OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO);
|
||||
| OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO
|
||||
| OBCLIENT_CAP_PROXY_FULL_LINK_TRACE_SHOW_TRACE);
|
||||
|
||||
static const long OB_MAX_UINT32_BUF_LEN = 11; // string length of max uint32_t(2**32 - 1)
|
||||
static const long OB_MAX_UINT64_BUF_LEN = 22; // string length of max uint64_t(2**64 - 1)
|
||||
@ -415,6 +422,22 @@ static const char *const OB_MYSQL_CONNECTION_ID = "__connection_id";
|
||||
static const char *const OB_MYSQL_PROXY_CONNECTION_ID = "__proxy_connection_id";
|
||||
static const char *const OB_MYSQL_GLOBAL_VARS_VERSION = "__global_vars_version";
|
||||
|
||||
|
||||
enum ObClientLobLocatorVersion
|
||||
{
|
||||
OBCLIENT_LOB_LOCATORV1 = 1,
|
||||
OBCLIENT_LOB_LOCATORV2 = 2,
|
||||
OBCLIENT_LOB_LOCATOR_ERROR
|
||||
};
|
||||
enum ObCapabilityFlagLob
|
||||
{
|
||||
OBCLIENT_CAP_OB_LOB_LOCATOR_V2 = 0
|
||||
};
|
||||
#define OBCLIENT_CAP_OB_LOB_LOCATOR_V2 OBCLIENT_CAP_GET_TYPE(OBCLIENT_CAP_OB_LOB_LOCATOR_V2)
|
||||
static const unsigned long OBCLIENT_CAP_OB_LOB_LOCATOR_V2_FLAG = OBCLIENT_CAP_OB_LOB_LOCATOR_V2;
|
||||
static const char *const OB_MYSQL_LOB_LOCATOR_V2 = "__ob_client_attribute_capability_flag";
|
||||
|
||||
|
||||
typedef enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
|
||||
MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
|
||||
MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
|
||||
|
@ -219,6 +219,65 @@ typedef struct ObLobLocator
|
||||
char data_[1]; // rowid + varchar
|
||||
} OB_LOB_LOCATOR;
|
||||
|
||||
|
||||
typedef struct st_ObClientMemLobCommon
|
||||
{
|
||||
uint32_t magic_; // Keep the old version consistent
|
||||
uint32_t version_ : 8;
|
||||
uint32_t type_ : 4; // Persistent/TmpFull/TmpDelta
|
||||
uint32_t read_only_ : 1; // Whether to write
|
||||
uint32_t is_inrow_ : 1;
|
||||
uint32_t is_open_ : 1; // only persist lob could be open
|
||||
uint32_t is_simple : 1;
|
||||
uint32_t has_extern : 1;
|
||||
uint32_t reserved_ : 15;
|
||||
}ObClientMemLobCommon;
|
||||
typedef struct st_ObClientMemLobExternHeader
|
||||
{
|
||||
int64_t snapshot_ver_;
|
||||
uint64_t table_id_;
|
||||
uint32_t column_idx_;
|
||||
uint16_t has_tx_info : 1;
|
||||
uint16_t has_cid_hash : 1;
|
||||
uint16_t has_view_info : 1;
|
||||
uint16_t extern_flags_ : 13;
|
||||
uint16_t rowkey_size_;
|
||||
uint32_t payload_offset_;
|
||||
uint32_t payload_size_;
|
||||
}ObClientMemLobExternHeader;
|
||||
typedef struct st_ObClientLobCommon
|
||||
{
|
||||
uint32_t version_ : 8;
|
||||
uint32_t is_init_ : 1;
|
||||
uint32_t is_empty_ : 1;
|
||||
uint32_t in_row_ : 1;
|
||||
uint32_t opt_encrypt_ : 1;
|
||||
uint32_t opt_compress_ : 1;
|
||||
uint32_t opt_deduplicate_ : 1;
|
||||
uint32_t has_content_type_ : 1;
|
||||
uint32_t use_big_endian_ : 1;
|
||||
uint32_t is_mem_loc_ : 1;
|
||||
uint32_t reserve_ : 15;
|
||||
}ObClientLobCommon;
|
||||
typedef struct st_ObClientLobData
|
||||
{
|
||||
uint64_t tablet_id_;
|
||||
uint64_t lob_id_;
|
||||
uint64_t byte_size_;
|
||||
}ObClientLobData;
|
||||
typedef struct ObLobLocatorV2
|
||||
{
|
||||
ObClientMemLobCommon common;
|
||||
ObClientMemLobExternHeader extern_header;
|
||||
char data_[1];
|
||||
}OB_LOB_LOCATOR_V2;
|
||||
uint8_t get_ob_lob_locator_version(void *lob);
|
||||
int64_t get_ob_lob_payload_data_len(void *lob);
|
||||
int stmt_get_data_from_lobv2(MYSQL *mysql, void * lob, enum_field_types dty,
|
||||
int64_t char_offset, int64_t byte_offset, int64_t char_len, int64_t byte_len, char *buf, const int64_t buf_len, int64_t *data_len, int64_t *act_len);
|
||||
|
||||
|
||||
|
||||
typedef struct st_mysqlnd_upsert_result
|
||||
{
|
||||
unsigned int warning_count;
|
||||
@ -374,7 +433,7 @@ enum enum_ob20_protocol
|
||||
PROTOCOL_OB20_FORCE_CLOSE = 0,
|
||||
PROTOCOL_OB20_AUTO_OPEN,
|
||||
PROTOCOL_OB20_FORCE_OPEN,
|
||||
PROTOCOL_OB20_FLAY_MAX
|
||||
PROTOCOL_OB20_FLAG_MAX
|
||||
};
|
||||
my_bool determine_protocol_ob20(MYSQL *mysql);
|
||||
my_bool get_use_protocol_ob20(MYSQL *mysql);
|
||||
@ -384,15 +443,37 @@ enum enum_full_link_trace
|
||||
PROTOCOL_FLT_FORCE_CLOSE = 0,
|
||||
PROTOCOL_FLT_AUTO_OPEN,
|
||||
PROTOCOL_FLT_FORCE_OPEN,
|
||||
PROTOCOL_FLT_FLAY_MAX
|
||||
PROTOCOL_FLT_FLAG_MAX
|
||||
};
|
||||
my_bool determine_full_link_trace(MYSQL *mysql);
|
||||
my_bool get_use_full_link_trace(MYSQL *mysql);
|
||||
|
||||
enum enum_flt_show_trace
|
||||
{
|
||||
FLT_SHOW_TRACE_FORCE_CLOSE = 0,
|
||||
FLT_SHOW_TRACE_AUTO_OPEN,
|
||||
FLT_SHOW_TRACE_FORCE_OPEN,
|
||||
FLT_SHOW_TRACE_FLAG_MAX
|
||||
};
|
||||
my_bool determine_flt_show_trace(MYSQL *mysql);
|
||||
my_bool get_use_flt_show_trace(MYSQL *mysql);
|
||||
|
||||
uint32_t ob_crc32(uint64_t crc, const char *buf, int64_t len);
|
||||
uint64_t ob_crc64(uint64_t crc, const char *buf, int64_t len);
|
||||
/*end for support protocol ob20*/
|
||||
|
||||
enum enum_ob_client_lob_locatorv2
|
||||
{
|
||||
OB_CLIENT_LOB_LOCATORV2_FORCE_CLOSE = 0,
|
||||
OB_CLIENT_LOB_LOCATORV2_AUTO_OPEN,
|
||||
OB_CLIENT_LOB_LOCATORV2_FORCE_OPEN,
|
||||
OB_CLIENT_LOB_LOCATORV2_FLAY_MAX
|
||||
};
|
||||
my_bool determine_ob_client_lob_locatorv2(MYSQL *mysql);
|
||||
my_bool get_use_ob_client_lob_locatorv2(MYSQL *mysql);
|
||||
|
||||
my_bool set_nls_format(MYSQL *mysql);
|
||||
|
||||
/* add for support bindbyname for plarray */
|
||||
struct prepare_extend_args_t
|
||||
{
|
||||
|
@ -45,4 +45,20 @@
|
||||
/* Source information */
|
||||
#define CC_SOURCE_REVISION "@CC_SOURCE_REVISION@"
|
||||
|
||||
#ifndef LIBOBCLIENT_VERSION_MAJOR
|
||||
#define LIBOBCLIENT_VERSION_MAJOR @CPACK_PACKAGE_VERSION_MAJOR@
|
||||
#endif
|
||||
|
||||
#ifndef LIBOBCLIENT_VERSION_MINOR
|
||||
#define LIBOBCLIENT_VERSION_MINOR @CPACK_PACKAGE_VERSION_MINOR@
|
||||
#endif
|
||||
|
||||
#ifndef LIBOBCLIENT_VERSION_PATCH
|
||||
#define LIBOBCLIENT_VERSION_PATCH @CPACK_PACKAGE_VERSION_PATCH@
|
||||
#endif
|
||||
|
||||
#ifndef LIBOBCLIENT_VERSION
|
||||
#define LIBOBCLIENT_VERSION "@CPACK_PACKAGE_VERSION_RPM@"
|
||||
#endif
|
||||
|
||||
#endif /* _mariadb_version_h_ */
|
||||
|
@ -408,10 +408,13 @@ struct st_mysql_options {
|
||||
my_bool can_plarray_bindbyname;
|
||||
my_bool can_use_protocol_ob20;
|
||||
my_bool can_use_full_link_trace;
|
||||
my_bool can_use_ob_client_lob_locatorv2;
|
||||
my_bool can_use_flt_show_trace;
|
||||
unsigned long ob_server_version;
|
||||
unsigned long ob_proxy_version;
|
||||
unsigned long capability; // system varaiable
|
||||
} MYSQL;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* For mysql_use_result, an additional buffer is needed to store rows.
|
||||
@ -424,7 +427,7 @@ struct st_mysql_options {
|
||||
typedef struct st_ob_result_extension {
|
||||
ulong pkt_len;
|
||||
char *pkt_buffer;
|
||||
MYSQL_FIELD *mysql_fields;
|
||||
MYSQL_FIELD *mysql_fields; // ±£´æfieldÐÅÏ¢
|
||||
} OB_RES_EXT;
|
||||
|
||||
struct st_mysql_trace_info;
|
||||
@ -522,6 +525,33 @@ typedef struct st_oracle_time
|
||||
int offset_hour, offset_minute;
|
||||
char *tz_name, *tz_abbr;
|
||||
} ORACLE_TIME;
|
||||
|
||||
typedef struct st_ym_object
|
||||
{
|
||||
int ym_year;
|
||||
int ym_month;
|
||||
int ym_scale;
|
||||
}YM_OBJECT;
|
||||
typedef struct st_ds_object
|
||||
{
|
||||
int ds_day;
|
||||
int ds_hour;
|
||||
int ds_minute;
|
||||
int ds_second;
|
||||
int ds_frac_second;
|
||||
int ds_day_scale;
|
||||
int ds_frac_second_scale;
|
||||
}DS_OBJECT;
|
||||
typedef struct st_oracle_interval
|
||||
{
|
||||
unsigned short mysql_type;
|
||||
char data_symbol; //1:+, -1:- 0, default
|
||||
union {
|
||||
struct st_ym_object ym_object;
|
||||
struct st_ds_object ds_object;
|
||||
} data_object;
|
||||
}ORACLE_INTERVAL;
|
||||
|
||||
#define AUTO_SEC_PART_DIGITS 39
|
||||
#endif
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define _ob_full_link_trace_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ob_object.h"
|
||||
#include "mysql.h"
|
||||
#include "ma_list.h"
|
||||
#include "ob_thread_key.h"
|
||||
|
||||
@ -44,11 +44,12 @@
|
||||
if (get_use_full_link_trace(mysql) && OB_NOT_NULL(ob20protocol)) { \
|
||||
flt = ob20protocol->flt; \
|
||||
if (OB_NOT_NULL(flt)) { \
|
||||
if (mysql->server_status & SERVER_STATUS_IN_TRANS) { \
|
||||
if ((TRUE == flt->control_info_.flt_show_trace_enable_) \
|
||||
|| !(mysql->server_status & SERVER_STATUS_IN_TRANS)) { \
|
||||
BEGIN_TRACE(flt); \
|
||||
} else { \
|
||||
/* A reset is required before each begin in the current transaction to prevent insufficient span*/ \
|
||||
reset_span(flt->trace_); \
|
||||
} else { \
|
||||
BEGIN_TRACE(flt); \
|
||||
} \
|
||||
span = BEGIN_SPAN(flt, span_level); \
|
||||
SET_TAG(flt, tag_level, tag_str); \
|
||||
@ -78,10 +79,8 @@
|
||||
trace->slow_query_print_ = FALSE; /* Slow query is set to FALSE for each request */ \
|
||||
flush_first_span(trace); \
|
||||
} \
|
||||
if (mysql->server_status & SERVER_STATUS_IN_TRANS) { \
|
||||
/* do nothing */ \
|
||||
} else { \
|
||||
/* 不在事务中需要结束trace */ \
|
||||
if ((TRUE == flt->control_info_.flt_show_trace_enable_) \
|
||||
|| !(mysql->server_status & SERVER_STATUS_IN_TRANS)) { \
|
||||
END_TRACE(flt); \
|
||||
} \
|
||||
} \
|
||||
@ -104,15 +103,20 @@
|
||||
#define DEFINE_TO_STRING_FUNC_FOR(type) \
|
||||
int tostring_##type(char *buf, const int64_t buf_len, int64_t *pos, type *src)
|
||||
|
||||
// Currently maintains a size of 4k for each trace, which is the size of all space allocated during the entire trace
|
||||
#define OBTRACE_DEFAULT_BUFFER_SIZE (1L << 12)
|
||||
// Currently maintains a size of 5k for each trace, which is the size of all space allocated during the entire trace
|
||||
#define OBTRACE_DEFAULT_BUFFER_SIZE (5 * (1L << 10))
|
||||
// The current driver free span is 4
|
||||
#define SPAN_CACHE_COUNT (1L << 2)
|
||||
// The current driver free span is 4
|
||||
#define TAG_CACHE_COUNT (1L << 4)
|
||||
// Since there is currently at most one SPAN, the largest LOG buffer is 1k
|
||||
#define MAX_TRACE_LOG_SIZE (1L << 10)
|
||||
// The current maximum size of the full link after serialization is 2k
|
||||
#define MAX_FLT_SERIALIZE_SIZE (1L << 11)
|
||||
#define INIT_OFFSET (MAX_TRACE_LOG_SIZE + MAX_FLT_SERIALIZE_SIZE + SPAN_CACHE_COUNT * (sizeof(LIST) + sizeof(ObSpanCtx)))
|
||||
// span cache begin buffer
|
||||
#define TAG_BUFFER_BEGIN ((2 * MAX_TRACE_LOG_SIZE) + MAX_FLT_SERIALIZE_SIZE)
|
||||
#define SPAN_BUFFER_BEGIN ((2 * MAX_TRACE_LOG_SIZE) + MAX_FLT_SERIALIZE_SIZE + TAG_CACHE_COUNT * (sizeof(ObTagCtx)))
|
||||
#define INIT_OFFSET (SPAN_BUFFER_BEGIN + SPAN_CACHE_COUNT * (sizeof(LIST) + sizeof(ObSpanCtx)))
|
||||
|
||||
#define OBTRACE(flt) get_trace_instance(flt)
|
||||
#define BEGIN_TRACE(flt) (begin_trace(OBTRACE(flt)))
|
||||
@ -171,14 +175,17 @@ typedef enum enum_fulllinktraceextrainfoid
|
||||
FLT_SAMPLE_PERCENTAGE,
|
||||
FLT_RECORD_POLICY,
|
||||
FLT_PRINT_SAMPLE_PCT,
|
||||
FLT_SHOW_TRACE_ENABLE,
|
||||
FLT_SLOW_QUERY_THRES,
|
||||
FLT_SHOW_TRACE_ENABLE,
|
||||
// SPAN_INFO
|
||||
FLT_TRACE_ENABLE = 2030,
|
||||
FLT_FORCE_PRINT,
|
||||
FLT_TRACE_ID,
|
||||
FLT_REF_TYPE,
|
||||
FLT_SPAN_ID,
|
||||
// FLT_SHOW_TRACE
|
||||
FLT_DRV_SHOW_TRACE_SPAN = 2050,
|
||||
FLT_PROXY_SHOW_TRACE_SPAN,
|
||||
FLT_EXTRA_INFO_ID_END
|
||||
} FullLinkTraceExtraInfoId;
|
||||
|
||||
@ -196,6 +203,8 @@ typedef enum enum_fulllinktraceextrainfotype
|
||||
FLT_QUERY_INFO,
|
||||
FLT_CONTROL_INFO,
|
||||
FLT_SPAN_INFO,
|
||||
FLT_TYPE_SHOW_TRACE_SPAN,
|
||||
|
||||
FLT_EXTRA_INFO_TYPE_END
|
||||
} FullLinkTraceExtraInfoType;
|
||||
|
||||
@ -219,6 +228,8 @@ typedef struct st_fltcontrolinfo
|
||||
RecordPolicy rp_;
|
||||
double print_sample_pct_;
|
||||
int64_t slow_query_threshold_;
|
||||
|
||||
int8_t flt_show_trace_enable_; // enable show trace or not
|
||||
} FLTControlInfo;
|
||||
|
||||
typedef struct st_fltappinfo
|
||||
@ -253,6 +264,12 @@ typedef struct st_fltdriverspaninfo
|
||||
const char *client_span_;
|
||||
} FLTDriverSpanInfo;
|
||||
|
||||
typedef struct st_showtracespan
|
||||
{
|
||||
FullLinkTraceExtraInfoType type_;
|
||||
const char *client_span_json_;
|
||||
} FLTShowTraceSpan;
|
||||
|
||||
typedef struct st_fltvaluedata
|
||||
{
|
||||
void *value_data_;
|
||||
@ -261,6 +278,7 @@ typedef struct st_fltvaluedata
|
||||
|
||||
typedef struct st_fltinfo
|
||||
{
|
||||
FLTShowTraceSpan show_trace_span_;
|
||||
FLTDriverSpanInfo client_span_;
|
||||
FLTControlInfo control_info_;
|
||||
FLTAppInfo app_info_;
|
||||
@ -340,6 +358,7 @@ struct st_obtrace
|
||||
uint64_t seq_;
|
||||
my_bool in_trans_;
|
||||
my_bool trace_enable_;
|
||||
my_bool show_trace_enable_;
|
||||
my_bool force_print_;
|
||||
my_bool slow_query_print_;
|
||||
FLTInfo *flt; // point to flt struct
|
||||
@ -349,6 +368,7 @@ struct st_obtrace
|
||||
LIST *current_span_list_;
|
||||
LIST *free_span_list_;
|
||||
ObSpanCtx *last_active_span_;
|
||||
ObTagCtx free_tag_list_;
|
||||
union {
|
||||
uint8_t policy_;
|
||||
struct {
|
||||
@ -358,6 +378,8 @@ struct st_obtrace
|
||||
};
|
||||
uint64_t log_buf_offset_;
|
||||
char *log_buf_; // size is MAX_TRACE_LOG_SIZE
|
||||
uint64_t show_trace_buf_offset_;
|
||||
char *show_trace_buf_; // size is MAX_TRACE_LOG_SIZE
|
||||
char *flt_serialize_buf_; // size is MAX_FLT_SERIALIZE_SIZE
|
||||
char data_[0]; // Multi-allocated space to store free span and facilitate subsequent tagging
|
||||
};
|
||||
@ -370,6 +392,7 @@ ObSpanCtx* begin_span(ObTrace *trace, uint32_t span_type, uint8_t level, my_bool
|
||||
void end_span(ObTrace *trace, ObSpanCtx *span);
|
||||
void reset_span(ObTrace *trace);
|
||||
void append_tag(ObTrace *trace, ObSpanCtx *span, uint16_t tag_type, const char *str);
|
||||
void reset_tag(ObTrace *trace, ObSpanCtx *span, ObTagCtx *tag);
|
||||
ObTrace *get_trace_instance(FLTInfo *flt);
|
||||
void flush_first_span(ObTrace *trace);
|
||||
void flush_trace(ObTrace *trace);
|
||||
@ -379,6 +402,7 @@ DEFINE_FLT_SERIALIZE_FUNC(queryinfo); // FLT_QUERY_INFO
|
||||
DEFINE_FLT_SERIALIZE_FUNC(controlinfo); // FLT_CONTROL_INFO
|
||||
DEFINE_FLT_SERIALIZE_FUNC(spaninfo); // FLT_SPAN_INFO
|
||||
DEFINE_FLT_SERIALIZE_FUNC(driverspaninfo); // FLT_DRIVER_SPAN_INFO
|
||||
DEFINE_FLT_SERIALIZE_FUNC(showtracespan); // FLT_TYPE_SHOW_TRACE_SPAN
|
||||
DEFINE_FLT_SERIALIZE_FUNC(nosupport); // FLT_EXTRA_INFO_TYPE_END
|
||||
|
||||
my_bool flt_is_vaild(FLTInfo *flt);
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <mariadb_dyncol.h>
|
||||
#include <stdint.h>
|
||||
#include <ma_list.h>
|
||||
#include <ob_object.h>
|
||||
#include <ob_full_link_trace.h>
|
||||
|
||||
|
||||
|
@ -128,9 +128,9 @@ int encode_vstr_with_len(char *buf, const int64_t buf_len, int64_t *ppos, const
|
||||
|
||||
int encode_vstr(char *buf, const int64_t buf_len, int64_t *ppos, const char *s);
|
||||
|
||||
inline const char *decode_vstr_nocopy(const char *buf, const int64_t data_len, int64_t *ppos, int64_t *lenp);
|
||||
const char *decode_vstr_nocopy(const char *buf, const int64_t data_len, int64_t *ppos, int64_t *lenp);
|
||||
|
||||
inline const char *decode_vstr(const char *buf, const int64_t data_len, int64_t *ppos,
|
||||
const char *decode_vstr(const char *buf, const int64_t data_len, int64_t *ppos,
|
||||
char *dest, int64_t buf_len, int64_t *lenp);
|
||||
|
||||
#define OB_UNIS_ENCODE(obj, type) \
|
||||
|
@ -337,6 +337,10 @@ SET(MARIADB_NONBLOCK_SYMBOLS
|
||||
ob_delete_thread_key
|
||||
ob_get_thread_key
|
||||
ob_set_thread_key
|
||||
#for lobv2
|
||||
get_ob_lob_locator_version
|
||||
get_ob_lob_payload_data_len
|
||||
stmt_get_data_from_lobv2
|
||||
)
|
||||
|
||||
# handle static plugins
|
||||
@ -383,7 +387,7 @@ ob_strtoll10.c
|
||||
ob_oracle_format_models.c
|
||||
ob_thread.c
|
||||
ob_serialize.c
|
||||
#ob_object.c
|
||||
ob_object.c
|
||||
ob_full_link_trace.c
|
||||
ob_rwlock.c
|
||||
ob_cond.c
|
||||
@ -540,10 +544,27 @@ IF(WITH_MYSQLCOMPAT)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(UNIX)
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE)
|
||||
SET(OS_SHARED_LIB_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}")
|
||||
ELSE()
|
||||
if(${SHARED_LIB_EXTRA_VERSION})
|
||||
SET(OS_SHARED_LIB_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}.${CPACK_PACKAGE_VERSION_EXTRA}")
|
||||
ELSE()
|
||||
SET(OS_SHARED_LIB_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
SET_TARGET_PROPERTIES(libobclnt PROPERTIES
|
||||
OUTPUT_NAME libobclnt
|
||||
VERSION "${OS_SHARED_LIB_VERSION}"
|
||||
SOVERSION "${CPACK_PACKAGE_VERSION_MAJOR}")
|
||||
ENDIF()
|
||||
|
||||
SET_TARGET_PROPERTIES(libobclnt PROPERTIES VERSION
|
||||
${CPACK_PACKAGE_VERSION_MAJOR}
|
||||
SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
|
||||
IF(WIN32)
|
||||
SET_TARGET_PROPERTIES(libobclnt PROPERTIES VERSION
|
||||
${CPACK_PACKAGE_VERSION_MAJOR}
|
||||
SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
|
||||
ENDIF()
|
||||
|
||||
IF(NOT WIN32)
|
||||
SET_TARGET_PROPERTIES(obclnt PROPERTIES OUTPUT_NAME "${LIBMARIADB_STATIC_NAME}")
|
||||
|
@ -201,13 +201,14 @@ int ma_net_flush(NET *net)
|
||||
int ma_net_write(NET *net, const uchar *packet, size_t len)
|
||||
{
|
||||
uchar buff[NET_HEADER_SIZE];
|
||||
unsigned long max_packet_length = MAX_PACKET_LENGTH;
|
||||
// update ob20 request id
|
||||
if (net->use_ob20protocol && OB_NOT_NULL(net->ob20protocol)) {
|
||||
update_request_id(&net->ob20protocol->header.request_id);
|
||||
}
|
||||
while (len >= MAX_PACKET_LENGTH)
|
||||
while (len >= max_packet_length)
|
||||
{
|
||||
const ulong max_len= MAX_PACKET_LENGTH;
|
||||
const ulong max_len= max_packet_length;
|
||||
int3store(buff,max_len);
|
||||
buff[3]= (uchar)net->pkt_nr++;
|
||||
if (ma_net_write_buff(net,(char*) buff,NET_HEADER_SIZE) ||
|
||||
@ -233,6 +234,7 @@ int ma_net_write_command(NET *net, uchar command,
|
||||
size_t buff_size= NET_HEADER_SIZE + 1;
|
||||
size_t length= 1 + len; /* 1 extra byte for command */
|
||||
int rc;
|
||||
unsigned long max_packet_length = MAX_PACKET_LENGTH;
|
||||
|
||||
buff[NET_HEADER_SIZE]= 0;
|
||||
buff[4]=command;
|
||||
@ -242,26 +244,34 @@ int ma_net_write_command(NET *net, uchar command,
|
||||
update_request_id(&net->ob20protocol->header.request_id);
|
||||
}
|
||||
|
||||
if (length >= MAX_PACKET_LENGTH)
|
||||
if (length >= max_packet_length)
|
||||
{
|
||||
len= MAX_PACKET_LENGTH - 1;
|
||||
len= max_packet_length - 1;
|
||||
do
|
||||
{
|
||||
int3store(buff, MAX_PACKET_LENGTH);
|
||||
buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
|
||||
int3store(buff, max_packet_length);
|
||||
if (net->use_ob20protocol) {
|
||||
buff[3]= (uchar) (net->pkt_nr++);
|
||||
} else {
|
||||
buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
|
||||
}
|
||||
|
||||
if (ma_net_write_buff(net, (char *)buff, buff_size) ||
|
||||
ma_net_write_buff(net, packet, len))
|
||||
return(1);
|
||||
packet+= len;
|
||||
length-= MAX_PACKET_LENGTH;
|
||||
len= MAX_PACKET_LENGTH;
|
||||
length-= max_packet_length;
|
||||
len= max_packet_length;
|
||||
buff_size= NET_HEADER_SIZE; /* don't send command for further packets */
|
||||
} while (length >= MAX_PACKET_LENGTH);
|
||||
} while (length >= max_packet_length);
|
||||
len= length;
|
||||
}
|
||||
int3store(buff,length);
|
||||
buff[3]= (net->compress) ? 0 :(uchar) (net->pkt_nr++);
|
||||
if (net->use_ob20protocol) {
|
||||
buff[3]= (uchar) (net->pkt_nr++);
|
||||
} else {
|
||||
buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
|
||||
}
|
||||
rc= test (ma_net_write_buff(net,(char *)buff, buff_size) ||
|
||||
ma_net_write_buff(net,packet,len));
|
||||
if (!rc && !disable_flush)
|
||||
@ -292,42 +302,36 @@ static int ma_net_write_buff(NET *net,const char *packet, size_t len)
|
||||
if (ma_net_real_write(net,(char*) net->buff, 0)) { // buffer为0,只写20头和extra info
|
||||
return 1; // error
|
||||
}
|
||||
} else if (extra_info_length + (size_t)(net->write_pos - net->buff) + len > MAX_PACKET_LENGTH_WITH_OB20) {
|
||||
// 将当前的buffer和extra info写入到网络包中
|
||||
if (ma_net_real_write(net,(char*) net->buff, (size_t)(net->write_pos - net->buff))) {
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
left_length=(size_t) (net->buff_end - net->write_pos);
|
||||
|
||||
if (net->use_ob20protocol && len > left_length && net->max_packet <= MAX_PACKET_LENGTH_WITH_OB20) {
|
||||
size_t write_len = net->write_pos - net->buff;
|
||||
size_t resize_len = len + write_len;
|
||||
|
||||
if (resize_len >= MAX_PACKET_LENGTH_WITH_OB20) {
|
||||
resize_len = MAX_PACKET_LENGTH_WITH_OB20;
|
||||
}
|
||||
if (net_realloc(net, resize_len))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
net->write_pos= net->buff;
|
||||
} else {
|
||||
// 当前所有都能放入一个包中, 这个分支会走到最后memcpy,然后结束
|
||||
net->write_pos += write_len;
|
||||
left_length=(size_t) (net->buff_end - net->write_pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (net->max_packet > MAX_PACKET_LENGTH && net->compress) {
|
||||
if (net->use_ob20protocol) {
|
||||
left_length= (size_t)(MAX_PACKET_LENGTH_WITH_OB20 - (net->write_pos - net->buff));
|
||||
} else {
|
||||
left_length= (size_t)(MAX_PACKET_LENGTH - (net->write_pos - net->buff));
|
||||
}
|
||||
if (net->max_packet > MAX_PACKET_LENGTH_WITH_OB20 && net->compress && net->use_ob20protocol) {
|
||||
left_length= (size_t)(MAX_PACKET_LENGTH_WITH_OB20 - (net->write_pos - net->buff));
|
||||
} else if (net->max_packet > MAX_PACKET_LENGTH && net->compress) {
|
||||
left_length= (size_t)(MAX_PACKET_LENGTH - (net->write_pos - net->buff));
|
||||
} else {
|
||||
left_length=(size_t) (net->buff_end - net->write_pos);
|
||||
}
|
||||
|
||||
if (net->use_ob20protocol && len > left_length && net->buf_length < net->max_packet_size - 1) {
|
||||
size_t write_len = net->write_pos - net->buff;
|
||||
size_t resize_len = len + write_len;
|
||||
|
||||
if (resize_len >= net->max_packet_size) {
|
||||
resize_len = net->max_packet_size - 1;
|
||||
}
|
||||
if (net_realloc(net, resize_len))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
net->write_pos += write_len;
|
||||
left_length=(size_t) (net->buff_end - net->write_pos);
|
||||
}
|
||||
|
||||
if (len > left_length)
|
||||
{
|
||||
if (net->write_pos != net->buff)
|
||||
@ -342,11 +346,11 @@ static int ma_net_write_buff(NET *net,const char *packet, size_t len)
|
||||
}
|
||||
if (net->compress)
|
||||
{
|
||||
/* uncompressed length is stored in 3 bytes,so
|
||||
packet can't be > 0xFFFFFF */
|
||||
if (net->use_ob20protocol) {
|
||||
left_length= MAX_PACKET_LENGTH_WITH_OB20;
|
||||
} else {
|
||||
/* uncompressed length is stored in 3 bytes,so
|
||||
packet can't be > 0xFFFFFF */
|
||||
left_length= MAX_PACKET_LENGTH;
|
||||
}
|
||||
while (len > left_length)
|
||||
@ -805,6 +809,7 @@ ulong ma_net_read(NET *net)
|
||||
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
|
||||
}
|
||||
#endif
|
||||
|
||||
return (ulong)len;
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,11 @@ my_bool mysql_ps_subsystem_initialized= 0;
|
||||
((((val) > (max_range)) || ((val) < (min_range)) ? 1 : 0))
|
||||
|
||||
|
||||
extern ulong calculate_interval_length(uchar *cp, enum_field_types type);
|
||||
extern int rewrite_interval(uchar *cp, char *to, const uint to_size, ulong *convert_len, enum_field_types type);
|
||||
extern ulong calculate_new_time_length_with_nls(MYSQL *mysql, uchar *cp, ulong len, enum_field_types type);
|
||||
extern ulong rewrite_new_time_with_nls(MYSQL *mysql, uchar *cp, ulong len, char *to, int64_t buf_len, enum_field_types type);
|
||||
|
||||
void ma_bmove_upp(register char *dst, register const char *src, register size_t len)
|
||||
{
|
||||
while (len-- != 0) *--dst = *--src;
|
||||
@ -881,13 +886,26 @@ static void convert_from_float(MYSQL_BIND *r_param, const MYSQL_FIELD *field, fl
|
||||
|
||||
length= MIN(MAX_DOUBLE_STRING_REP_LENGTH - 1, r_param->buffer_length);
|
||||
|
||||
if (field->decimals >= NOT_FIXED_DEC)
|
||||
{
|
||||
length= ma_gcvt(val, MY_GCVT_ARG_FLOAT, (int)length, buff, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
length= ma_fcvt(val, field->decimals, buff, NULL);
|
||||
if (isnan(val)) {
|
||||
snprintf(buff, length, "%s", "Nan");
|
||||
length = 3;
|
||||
} else if (isinf(val)) {
|
||||
if (val > 0) {
|
||||
snprintf(buff, length, "%s", "Inf");
|
||||
length = 3;
|
||||
} else {
|
||||
snprintf(buff, length, "%s", "-Inf");
|
||||
length = 4;
|
||||
}
|
||||
} else {
|
||||
if (field->decimals >= NOT_FIXED_DEC)
|
||||
{
|
||||
length = ma_gcvt(val, MY_GCVT_ARG_FLOAT, (int)length, buff, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
length = ma_fcvt(val, field->decimals, buff, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* check if ZEROFILL flag is active */
|
||||
@ -982,13 +1000,26 @@ static void convert_from_double(MYSQL_BIND *r_param, const MYSQL_FIELD *field, d
|
||||
|
||||
length= MIN(MAX_DOUBLE_STRING_REP_LENGTH - 1, r_param->buffer_length);
|
||||
|
||||
if (field->decimals >= NOT_FIXED_DEC)
|
||||
{
|
||||
length= ma_gcvt(val, MY_GCVT_ARG_DOUBLE, (int)length, buff, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
length= ma_fcvt(val, field->decimals, buff, NULL);
|
||||
if (isnan(val)) {
|
||||
snprintf(buff, length, "%s", "Nan");
|
||||
length = 3;
|
||||
} else if (isinf(val)) {
|
||||
if (val > 0) {
|
||||
snprintf(buff, length, "%s", "Inf");
|
||||
length = 3;
|
||||
} else {
|
||||
snprintf(buff, length, "%s", "-Inf");
|
||||
length = 4;
|
||||
}
|
||||
} else {
|
||||
if (field->decimals >= NOT_FIXED_DEC)
|
||||
{
|
||||
length = ma_gcvt(val, MY_GCVT_ARG_DOUBLE, (int)length, buff, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
length = ma_fcvt(val, field->decimals, buff, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* check if ZEROFILL flag is active */
|
||||
@ -1122,68 +1153,192 @@ void ps_fetch_oracle_timestamp(MYSQL_BIND *param,
|
||||
uint buffer_length = 0;
|
||||
uint length = net_field_length(row);
|
||||
|
||||
switch (param->buffer_type) {
|
||||
case MYSQL_TYPE_OB_TIMESTAMP_NANO:
|
||||
case MYSQL_TYPE_OB_TIMESTAMP_WITH_LOCAL_TIME_ZONE:
|
||||
case MYSQL_TYPE_OB_TIMESTAMP_WITH_TIME_ZONE: {
|
||||
if (length > 16) {
|
||||
buffer_length = length - 16 + sizeof(ORACLE_TIME) + 2;
|
||||
} else {
|
||||
buffer_length = sizeof(ORACLE_TIME);
|
||||
}
|
||||
|
||||
if (param->buffer_length < buffer_length) {
|
||||
*param->length = buffer_length;
|
||||
*param->error = 1;
|
||||
*row += length;
|
||||
} else {
|
||||
ORACLE_TIME *tm = (ORACLE_TIME *)param->buffer;
|
||||
uint tz_length = 0;
|
||||
uint buffer_offset = 0;
|
||||
uchar *to = *row;
|
||||
|
||||
memset(tm, 0, sizeof(ORACLE_TIME));
|
||||
tm->century = (int)(*(char*)to++);
|
||||
tm->year = (int)(*(char*)to++);
|
||||
tm->month = (uint)(*to++);
|
||||
tm->day = (uint)(*to++);
|
||||
tm->hour = (uint)(*to++);
|
||||
tm->minute = (uint)(*to++);
|
||||
tm->second = (uint)(*to++);
|
||||
|
||||
tm->second_part = (ulong)sint4korr(to);
|
||||
to += 4;
|
||||
tm->scale = (uint)(*to++);
|
||||
|
||||
buffer_length = buffer_offset = sizeof(ORACLE_TIME);
|
||||
if (length > 12) {
|
||||
tm->offset_hour = (int)(*(char*)to++);
|
||||
tm->offset_minute = (int)(*(char*)to++);
|
||||
|
||||
tz_length = (uint)(*to++);
|
||||
buffer_length += (tz_length + 1);
|
||||
if (tz_length > 0 && buffer_offset + tz_length + 1 < param->buffer_length) {
|
||||
memcpy((char*)param->buffer + buffer_offset, to, tz_length);
|
||||
tm->tz_name = (char*)param->buffer + buffer_offset;
|
||||
buffer_offset += tz_length;
|
||||
*((char*)param->buffer + buffer_offset) = '\0';
|
||||
buffer_offset++;
|
||||
}
|
||||
to += tz_length;
|
||||
|
||||
tz_length = (uint)(*to++);
|
||||
buffer_length += (tz_length + 1);
|
||||
if (tz_length > 0 && buffer_offset + tz_length + 1 < param->buffer_length) {
|
||||
memcpy((char*)param->buffer + buffer_offset, to, tz_length);
|
||||
tm->tz_abbr = (char*)param->buffer + buffer_offset;
|
||||
buffer_offset += tz_length;
|
||||
*((char*)param->buffer + buffer_offset) = '\0';
|
||||
buffer_offset++;
|
||||
}
|
||||
to += tz_length;
|
||||
}
|
||||
*param->length = buffer_length;
|
||||
*param->error = param->buffer_length < buffer_length;
|
||||
*row = to;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING:{
|
||||
uchar *buffer = *row;
|
||||
ulong convert_len = calculate_new_time_length_with_nls(param->mysql, buffer, length, field->type);
|
||||
*param->length = convert_len;
|
||||
if (param->buffer_length < convert_len) {
|
||||
*param->error = 1;
|
||||
} else {
|
||||
convert_len = rewrite_new_time_with_nls(param->mysql, buffer, length, param->buffer, (uint)(param->buffer_length), field->type);
|
||||
*param->length = convert_len;
|
||||
}
|
||||
*row += length;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
convert_froma_string(param, (char *)*row, length);
|
||||
*row += length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void ps_fetch_oracle_interval(MYSQL_BIND *param, const MYSQL_FIELD *field, uchar **row)
|
||||
{
|
||||
uint length = net_field_length(row);
|
||||
uchar * buffer = *row;
|
||||
|
||||
switch (param->buffer_type)
|
||||
{
|
||||
case MYSQL_TYPE_OB_INTERVAL_DS: {
|
||||
*param->length = sizeof(ORACLE_INTERVAL);
|
||||
if (length != 14) {
|
||||
*param->error = 1;
|
||||
} else {
|
||||
ORACLE_INTERVAL * interval = (ORACLE_INTERVAL*)param->buffer;
|
||||
interval->mysql_type = MYSQL_TYPE_OB_INTERVAL_DS;
|
||||
interval->data_symbol = (buffer[0] > 0 ? -1 : 1);
|
||||
interval->data_object.ds_object.ds_day = sint4korr(buffer + 1);
|
||||
interval->data_object.ds_object.ds_hour = buffer[5];
|
||||
interval->data_object.ds_object.ds_minute = buffer[6];
|
||||
interval->data_object.ds_object.ds_second = buffer[7];
|
||||
interval->data_object.ds_object.ds_frac_second = sint4korr(buffer + 8);
|
||||
interval->data_object.ds_object.ds_day_scale = buffer[12];
|
||||
interval->data_object.ds_object.ds_frac_second_scale = buffer[13];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MYSQL_TYPE_OB_INTERVAL_YM: {
|
||||
*param->length = sizeof(ORACLE_INTERVAL);
|
||||
if (length != 7) {
|
||||
*param->error = 1;
|
||||
} else {
|
||||
ORACLE_INTERVAL * interval = (ORACLE_INTERVAL*)param->buffer;
|
||||
interval->mysql_type = MYSQL_TYPE_OB_INTERVAL_YM;
|
||||
interval->data_symbol = (buffer[0] > 0 ? -1 : 1);
|
||||
interval->data_object.ym_object.ym_year = sint4korr(buffer + 1);
|
||||
interval->data_object.ym_object.ym_month = buffer[5];
|
||||
interval->data_object.ym_object.ym_scale = buffer[6];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING: {
|
||||
ulong convert_len = calculate_interval_length(buffer, field->type);
|
||||
*param->length = convert_len;
|
||||
if ((length != 7 && length != 14) || param->buffer_length < convert_len) {
|
||||
*param->error = 1;
|
||||
} else {
|
||||
if (!rewrite_interval(buffer, param->buffer, (uint)(param->buffer_length), &convert_len, field->type)) {
|
||||
*param->error = 1;
|
||||
}
|
||||
*param->length = convert_len;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
convert_froma_string(param, (char *)*row, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*row += length;
|
||||
}
|
||||
|
||||
static
|
||||
void ps_fetch_oracle_raw(MYSQL_BIND *param, const MYSQL_FIELD *field, uchar **row)
|
||||
{
|
||||
ulong length = net_field_length(row);
|
||||
uchar * buffer = *row;
|
||||
UNUSED(field);
|
||||
|
||||
if (length > 16) {
|
||||
buffer_length = length - 16 + sizeof(ORACLE_TIME) + 2;
|
||||
} else {
|
||||
buffer_length = sizeof(ORACLE_TIME);
|
||||
switch (param->buffer_type)
|
||||
{
|
||||
case MYSQL_TYPE_OB_RAW: {
|
||||
convert_froma_string(param, (char *)*row, length);
|
||||
break;
|
||||
}
|
||||
|
||||
if (param->buffer_length < buffer_length) {
|
||||
*param->length= buffer_length;
|
||||
*param->error= 1;
|
||||
*row += length;
|
||||
} else {
|
||||
ORACLE_TIME *tm= (ORACLE_TIME *)param->buffer;
|
||||
uint tz_length = 0;
|
||||
uint buffer_offset = 0;
|
||||
uchar *to= *row;
|
||||
|
||||
memset(tm, 0, sizeof(ORACLE_TIME));
|
||||
tm->century= (int) (*(char*)to++);
|
||||
tm->year= (int) (*(char*)to++);
|
||||
tm->month= (uint) (*to++);
|
||||
tm->day= (uint) (*to++);
|
||||
tm->hour= (uint) (*to++);
|
||||
tm->minute= (uint) (*to++);
|
||||
tm->second= (uint) (*to++);
|
||||
|
||||
tm->second_part= (ulong) sint4korr(to);
|
||||
to += 4;
|
||||
tm->scale = (uint) (*to++);
|
||||
|
||||
buffer_length = buffer_offset = sizeof(ORACLE_TIME);
|
||||
if (length > 12) {
|
||||
tm->offset_hour = (int) (*(char*)to++);
|
||||
tm->offset_minute = (int) (*(char*)to++);
|
||||
|
||||
tz_length = (uint) (*to++);
|
||||
buffer_length += (tz_length + 1);
|
||||
if (tz_length > 0 && buffer_offset + tz_length + 1 < param->buffer_length) {
|
||||
memcpy((char*)param->buffer + buffer_offset, to, tz_length);
|
||||
tm->tz_name = (char*)param->buffer + buffer_offset;
|
||||
buffer_offset += tz_length;
|
||||
*((char*)param->buffer + buffer_offset) = '\0';
|
||||
buffer_offset++;
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING:{
|
||||
uchar *to = param->buffer;
|
||||
uchar *cp = buffer;
|
||||
uchar *end = buffer + length;
|
||||
if (param->buffer_length < length * 2) {
|
||||
*param->error = 1;
|
||||
} else {
|
||||
for (; cp < end; cp++, to += 2) {
|
||||
sprintf((char *)to, "%02X", *((uchar*)cp));
|
||||
}
|
||||
to += tz_length;
|
||||
|
||||
tz_length = (uint) (*to++);
|
||||
buffer_length += (tz_length + 1);
|
||||
if (tz_length > 0 && buffer_offset + tz_length + 1 < param->buffer_length) {
|
||||
memcpy((char*)param->buffer + buffer_offset, to, tz_length);
|
||||
tm->tz_abbr = (char*)param->buffer + buffer_offset;
|
||||
buffer_offset += tz_length;
|
||||
*((char*)param->buffer + buffer_offset) = '\0';
|
||||
buffer_offset++;
|
||||
}
|
||||
to += tz_length;
|
||||
(*to++) = 0;
|
||||
}
|
||||
*param->length= buffer_length;
|
||||
*param->error= param->buffer_length < buffer_length;
|
||||
*row = to;
|
||||
*param->length = length * 2;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
convert_froma_string(param, (char *)*row, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*row += length;
|
||||
}
|
||||
|
||||
|
||||
@ -1277,22 +1432,92 @@ static void fill_ob_lob_locator(OB_LOB_LOCATOR *ob_lob_locator, uchar *row)
|
||||
ob_lob_locator->payload_size_ = uint4korr(row + 36);
|
||||
}
|
||||
|
||||
|
||||
static void fill_ob_client_mem_lob_common(ObClientMemLobCommon* common, uchar *row)
|
||||
{
|
||||
#define BIT1 0x01
|
||||
#define BIT4 0x0F
|
||||
#define BIT8 0xFF
|
||||
#define BIT15 0x7FFF
|
||||
uint32_t tmps = 0;
|
||||
common->magic_ = uint4korr(row);
|
||||
tmps = uint4korr(row + 4);
|
||||
common->version_ = tmps & BIT8;
|
||||
tmps >>= 8;
|
||||
common->type_ = tmps & BIT4;
|
||||
tmps >>= 4;
|
||||
common->read_only_ = tmps & BIT1;
|
||||
tmps >>= 1;
|
||||
common->is_inrow_ = tmps & BIT1;
|
||||
tmps >>= 1;
|
||||
common->is_open_ = tmps & BIT1;
|
||||
tmps >>= 1;
|
||||
common->is_simple = tmps & BIT1;
|
||||
tmps >>= 1;
|
||||
common->has_extern = tmps & BIT1;
|
||||
tmps >>= 1;
|
||||
common->reserved_ = tmps & BIT15;
|
||||
}
|
||||
static void fill_ob_client_mem_lob_extern_header(ObClientMemLobExternHeader* header, uchar *row)
|
||||
{
|
||||
#define BIT1 0x01
|
||||
#define BIT13 0x1FFF
|
||||
uint16_t tmps = 0;
|
||||
header->snapshot_ver_ = sint8korr(row);
|
||||
header->table_id_ = uint8korr(row+8);
|
||||
header->column_idx_ = uint4korr(row+16);
|
||||
|
||||
tmps = uint2korr(row + 20);
|
||||
header->has_tx_info = tmps & BIT1;
|
||||
tmps >>= 1;
|
||||
header->has_cid_hash = tmps & BIT1;
|
||||
tmps >>= 1;
|
||||
header->has_view_info = tmps & BIT1;
|
||||
tmps >>= 1;
|
||||
header->extern_flags_ = tmps & BIT13;
|
||||
|
||||
header->rowkey_size_ = uint2korr(row + 22);
|
||||
header->payload_offset_ = uint4korr(row + 24);
|
||||
header->payload_size_ = uint4korr(row + 28);
|
||||
}
|
||||
static void fill_ob_lob_locator_v2(OB_LOB_LOCATOR_V2 *ob_lob_locator, uchar *row)
|
||||
{
|
||||
fill_ob_client_mem_lob_common(&ob_lob_locator->common, row);
|
||||
if (ob_lob_locator->common.has_extern){
|
||||
fill_ob_client_mem_lob_extern_header(&ob_lob_locator->extern_header, row+sizeof(ObClientMemLobCommon));
|
||||
}
|
||||
}
|
||||
|
||||
static void fetch_result_ob_lob(MYSQL_BIND *param,
|
||||
const MYSQL_FIELD *field __attribute__((unused)),
|
||||
uchar **row)
|
||||
{
|
||||
ulong length= net_field_length(row);
|
||||
ulong copy_length = 0;
|
||||
|
||||
if (param->buffer_length <= 0
|
||||
|| param->buffer_length < MAX_OB_LOB_LOCATOR_HEADER_LENGTH
|
||||
|| length < MAX_OB_LOB_LOCATOR_HEADER_LENGTH) {
|
||||
*param->error= 1;
|
||||
} else {
|
||||
OB_LOB_LOCATOR *ob_lob_locator = (OB_LOB_LOCATOR *)param->buffer;
|
||||
ulong copy_length = MIN(param->buffer_length - MAX_OB_LOB_LOCATOR_HEADER_LENGTH, length - MAX_OB_LOB_LOCATOR_HEADER_LENGTH);
|
||||
fill_ob_lob_locator(ob_lob_locator, *row);
|
||||
memcpy(ob_lob_locator->data_, (*row) + MAX_OB_LOB_LOCATOR_HEADER_LENGTH, copy_length);
|
||||
*param->error= copy_length + MAX_OB_LOB_LOCATOR_HEADER_LENGTH < length;
|
||||
ObClientMemLobCommon common;
|
||||
fill_ob_client_mem_lob_common(&common, *row);
|
||||
if (common.version_ == OBCLIENT_LOB_LOCATORV1) {
|
||||
OB_LOB_LOCATOR *ob_lob_locator = (OB_LOB_LOCATOR *)param->buffer;
|
||||
fill_ob_lob_locator(ob_lob_locator, *row);
|
||||
|
||||
copy_length = MIN(param->buffer_length - MAX_OB_LOB_LOCATOR_HEADER_LENGTH, length - MAX_OB_LOB_LOCATOR_HEADER_LENGTH);
|
||||
memcpy(ob_lob_locator->data_, (*row) + MAX_OB_LOB_LOCATOR_HEADER_LENGTH, copy_length);
|
||||
*param->error= copy_length + MAX_OB_LOB_LOCATOR_HEADER_LENGTH < length;
|
||||
} else if (common.version_ == OBCLIENT_LOB_LOCATORV2) {
|
||||
OB_LOB_LOCATOR_V2 *ob_lob_locatorv2 = (OB_LOB_LOCATOR_V2 *)param->buffer;
|
||||
//for oracle mode, common.has_extern = 1
|
||||
fill_ob_lob_locator_v2(ob_lob_locatorv2, *row);
|
||||
|
||||
copy_length = MIN(param->buffer_length - MAX_OB_LOB_LOCATOR_HEADER_LENGTH, length - MAX_OB_LOB_LOCATOR_HEADER_LENGTH);
|
||||
memcpy(ob_lob_locatorv2->data_, (*row) + MAX_OB_LOB_LOCATOR_HEADER_LENGTH, copy_length);
|
||||
*param->error = copy_length + MAX_OB_LOB_LOCATOR_HEADER_LENGTH < length;
|
||||
}
|
||||
}
|
||||
|
||||
*param->length= length;
|
||||
@ -2006,6 +2231,32 @@ void ps_fetch_bin(MYSQL_BIND *r_param,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static
|
||||
void ps_fetch_mysql_lob(MYSQL_BIND *r_param, const MYSQL_FIELD *field, unsigned char **row)
|
||||
{
|
||||
ulong length = net_field_length(row);
|
||||
if (field->charsetnr == 63)
|
||||
{
|
||||
ulong field_length = *r_param->length = length;
|
||||
uchar *current_pos = (*row) + r_param->offset, *end = (*row) + field_length;
|
||||
size_t copylen = 0;
|
||||
if (current_pos < end)
|
||||
{
|
||||
copylen = end - current_pos;
|
||||
if (r_param->buffer_length)
|
||||
memcpy(r_param->buffer, current_pos, MIN(copylen, r_param->buffer_length));
|
||||
}
|
||||
if (copylen < r_param->buffer_length &&
|
||||
(r_param->buffer_type == MYSQL_TYPE_STRING ||
|
||||
r_param->buffer_type == MYSQL_TYPE_JSON))
|
||||
((char *)r_param->buffer)[copylen] = 0;
|
||||
*r_param->error = copylen > r_param->buffer_length;
|
||||
} else {
|
||||
convert_froma_string(r_param, (char *)*row, length);
|
||||
}
|
||||
(*row) += length;
|
||||
}
|
||||
|
||||
/* {{{ ps_fetch_result_skip_direct */
|
||||
static
|
||||
void ps_fetch_result_skip_direct(MYSQL_BIND *r_param,
|
||||
@ -2083,6 +2334,13 @@ void mysql_init_ps_subsystem(void)
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_TIMESTAMP_WITH_TIME_ZONE].pack_len = MYSQL_PS_SKIP_RESULT_W_LEN;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_TIMESTAMP_WITH_TIME_ZONE].max_len = -1;
|
||||
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_INTERVAL_YM].func = ps_fetch_oracle_interval;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_INTERVAL_YM].pack_len = MYSQL_PS_SKIP_RESULT_W_LEN;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_INTERVAL_YM].max_len = -1;
|
||||
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_INTERVAL_DS].func = ps_fetch_oracle_interval;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_INTERVAL_DS].pack_len = MYSQL_PS_SKIP_RESULT_W_LEN;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_INTERVAL_DS].max_len = -1;
|
||||
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_NEWDATE].func = ps_fetch_string;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_NEWDATE].pack_len = MYSQL_PS_SKIP_RESULT_W_LEN;
|
||||
@ -2096,19 +2354,19 @@ void mysql_init_ps_subsystem(void)
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].pack_len= MYSQL_PS_SKIP_RESULT_W_LEN;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].max_len = 30;
|
||||
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].func = ps_fetch_bin;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].func = ps_fetch_mysql_lob;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].pack_len= MYSQL_PS_SKIP_RESULT_STR;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].max_len = -1;
|
||||
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_BLOB].func = ps_fetch_bin;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_BLOB].func = ps_fetch_mysql_lob;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_BLOB].pack_len = MYSQL_PS_SKIP_RESULT_STR;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_BLOB].max_len = -1;
|
||||
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].func = ps_fetch_bin;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].func = ps_fetch_mysql_lob;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].pack_len= MYSQL_PS_SKIP_RESULT_STR;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].max_len = -1;
|
||||
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].func = ps_fetch_bin;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].func = ps_fetch_mysql_lob;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].pack_len = MYSQL_PS_SKIP_RESULT_STR;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].max_len = -1;
|
||||
|
||||
@ -2173,8 +2431,8 @@ void mysql_init_ps_subsystem(void)
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_ORA_CLOB].pack_len = MYSQL_PS_SKIP_RESULT_STR;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_ORA_CLOB].max_len = -1;
|
||||
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_RAW].func = ps_fetch_string;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_RAW].pack_len = MYSQL_PS_SKIP_RESULT_STR;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_RAW].func = ps_fetch_oracle_raw;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_RAW].pack_len = MYSQL_PS_SKIP_RESULT_W_LEN;
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OB_RAW].max_len = -1;
|
||||
|
||||
mysql_ps_fetch_functions[MYSQL_TYPE_OBJECT].func = ps_fetch_result_type;
|
||||
|
@ -181,7 +181,7 @@ my_bool get_local_ip_port(my_socket fd, char *ip, int iplen, int *port)
|
||||
static void mysql_close_memory(MYSQL *mysql);
|
||||
void read_user_name(char *name);
|
||||
my_bool STDCALL mariadb_reconnect(MYSQL *mysql);
|
||||
static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length);
|
||||
// static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length);
|
||||
|
||||
extern int mysql_client_plugin_init();
|
||||
extern void mysql_client_plugin_deinit();
|
||||
@ -288,7 +288,7 @@ ma_net_safe_read(MYSQL *mysql)
|
||||
NET *net= &mysql->net;
|
||||
ulong len=0;
|
||||
|
||||
restart:
|
||||
// restart:
|
||||
if (net->pvio != 0)
|
||||
len=ma_net_read(net);
|
||||
|
||||
@ -310,18 +310,18 @@ restart:
|
||||
pos+=2;
|
||||
len-=2;
|
||||
|
||||
if (last_errno== 65535 &&
|
||||
((mariadb_connection(mysql) && (mysql->server_capabilities & CLIENT_PROGRESS)) ||
|
||||
(!(mysql->extension->mariadb_server_capabilities & MARIADB_CLIENT_PROGRESS << 32))))
|
||||
{
|
||||
if (cli_report_progress(mysql, (uchar *)pos, (uint) (len-1)))
|
||||
{
|
||||
/* Wrong packet */
|
||||
my_set_error(mysql, CR_MALFORMED_PACKET, SQLSTATE_UNKNOWN, 0);
|
||||
return (packet_error);
|
||||
}
|
||||
goto restart;
|
||||
}
|
||||
// if (last_errno== 65535 &&
|
||||
// ((mariadb_connection(mysql) && (mysql->server_capabilities & CLIENT_PROGRESS)) ||
|
||||
// (!(mysql->extension->mariadb_server_capabilities & MARIADB_CLIENT_PROGRESS << 32))))
|
||||
// {
|
||||
// if (cli_report_progress(mysql, (uchar *)pos, (uint) (len-1)))
|
||||
// {
|
||||
// /* Wrong packet */
|
||||
// my_set_error(mysql, CR_MALFORMED_PACKET, SQLSTATE_UNKNOWN, 0);
|
||||
// return (packet_error);
|
||||
// }
|
||||
// goto restart;
|
||||
// }
|
||||
net->last_errno= last_errno;
|
||||
if (pos[0]== '#')
|
||||
{
|
||||
@ -354,31 +354,31 @@ restart:
|
||||
0 ok
|
||||
1 error
|
||||
*/
|
||||
static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length)
|
||||
{
|
||||
uint stage, max_stage, proc_length;
|
||||
double progress;
|
||||
uchar *start= packet;
|
||||
// static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length)
|
||||
// {
|
||||
// uint stage, max_stage, proc_length;
|
||||
// double progress;
|
||||
// uchar *start= packet;
|
||||
|
||||
if (length < 5)
|
||||
return 1; /* Wrong packet */
|
||||
// if (length < 5)
|
||||
// return 1; /* Wrong packet */
|
||||
|
||||
if (!(mysql->options.extension && mysql->options.extension->report_progress))
|
||||
return 0; /* No callback, ignore packet */
|
||||
// if (!(mysql->options.extension && mysql->options.extension->report_progress))
|
||||
// return 0; /* No callback, ignore packet */
|
||||
|
||||
packet++; /* Ignore number of strings */
|
||||
stage= (uint) *packet++;
|
||||
max_stage= (uint) *packet++;
|
||||
progress= uint3korr(packet)/1000.0;
|
||||
packet+= 3;
|
||||
proc_length= net_field_length(&packet);
|
||||
if (packet + proc_length > start + length)
|
||||
return 1; /* Wrong packet */
|
||||
(*mysql->options.extension->report_progress)(mysql, stage, max_stage,
|
||||
progress, (char*) packet,
|
||||
proc_length);
|
||||
return 0;
|
||||
}
|
||||
// packet++; /* Ignore number of strings */
|
||||
// stage= (uint) *packet++;
|
||||
// max_stage= (uint) *packet++;
|
||||
// progress= uint3korr(packet)/1000.0;
|
||||
// packet+= 3;
|
||||
// proc_length= net_field_length(&packet);
|
||||
// if (packet + proc_length > start + length)
|
||||
// return 1; /* Wrong packet */
|
||||
// (*mysql->options.extension->report_progress)(mysql, stage, max_stage,
|
||||
// progress, (char*) packet,
|
||||
// proc_length);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
/* Get the length of next field. Change parameter to point at fieldstart */
|
||||
ulong
|
||||
@ -1022,7 +1022,8 @@ unpack_fields(const MYSQL *mysql,
|
||||
if (0 == len) {
|
||||
field->owner_name = NULL;
|
||||
} else {
|
||||
field->owner_name = (unsigned char *)ma_memdup_root(alloc, (char*)complex_type, len);
|
||||
field->owner_name = (unsigned char *)ma_memdup_root(alloc, (char*)complex_type, len+1);
|
||||
field->owner_name[len] = 0;
|
||||
complex_type += len;
|
||||
}
|
||||
|
||||
@ -1031,7 +1032,8 @@ unpack_fields(const MYSQL *mysql,
|
||||
if (0 == len) {
|
||||
field->type_name = NULL;
|
||||
} else {
|
||||
field->type_name = (unsigned char *)ma_memdup_root(alloc, (char*)complex_type, len);
|
||||
field->type_name = (unsigned char *)ma_memdup_root(alloc, (char*)complex_type, len+1);
|
||||
field->type_name[len] = 0;
|
||||
complex_type += len;
|
||||
}
|
||||
|
||||
@ -1834,7 +1836,7 @@ int mthd_my_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
|
||||
if (NULL == mysql_fields) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
for (field=0 ; field < fields ; field++) {
|
||||
if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH) {
|
||||
continue;
|
||||
@ -1947,7 +1949,7 @@ int mthd_my_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
|
||||
if (mysql_fields[field].max_length < len)
|
||||
mysql_fields[field].max_length=len;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (field=0 ; field < fields ; field++)
|
||||
{
|
||||
@ -2114,15 +2116,23 @@ char *ma_send_connect_attr(MYSQL *mysql, unsigned char *buffer)
|
||||
static my_bool
|
||||
ma_set_ob_connect_attrs(MYSQL *mysql)
|
||||
{
|
||||
#define OB_MAX_UINT64_BUF_LEN 128
|
||||
int rc = 0;
|
||||
uint64_t cap = OBPROXY_DEFAULT_CAPABILITY_FLAG;
|
||||
char cap_buf[OB_MAX_UINT64_BUF_LEN];
|
||||
char cap_buf[OB_MAX_UINT64_BUF_LEN] = {0};
|
||||
uint64_t caplob = 0;
|
||||
char caplob_buf[OB_MAX_UINT64_BUF_LEN] = {0};
|
||||
|
||||
if (mysql->can_use_protocol_ob20) {
|
||||
cap |= OBCLIENT_CAP_OB_PROTOCOL_V2;
|
||||
cap |= OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO;
|
||||
if (mysql->can_use_full_link_trace) {
|
||||
cap |= OBCLIENT_CAP_FULL_LINK_TRACE;
|
||||
if (mysql->can_use_flt_show_trace) {
|
||||
cap |= OBCLIENT_CAP_PROXY_FULL_LINK_TRACE_SHOW_TRACE;
|
||||
} else {
|
||||
cap &= ~OBCLIENT_CAP_PROXY_FULL_LINK_TRACE_SHOW_TRACE;
|
||||
}
|
||||
} else {
|
||||
cap &= ~OBCLIENT_CAP_FULL_LINK_TRACE;
|
||||
}
|
||||
@ -2130,6 +2140,7 @@ ma_set_ob_connect_attrs(MYSQL *mysql)
|
||||
cap &= ~OBCLIENT_CAP_OB_PROTOCOL_V2;
|
||||
cap &= ~OBCLIENT_CAP_FULL_LINK_TRACE;
|
||||
cap &= ~OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO;
|
||||
cap &= ~OBCLIENT_CAP_PROXY_FULL_LINK_TRACE_SHOW_TRACE;
|
||||
}
|
||||
|
||||
snprintf(cap_buf, OB_MAX_UINT64_BUF_LEN, "%lu", cap);
|
||||
@ -2137,6 +2148,11 @@ ma_set_ob_connect_attrs(MYSQL *mysql)
|
||||
rc += mysql_optionsv(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, OB_MYSQL_CAPABILITY_FLAG, cap_buf);
|
||||
rc += mysql_optionsv(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, OB_MYSQL_CLIENT_MODE, "__ob_libobclient");
|
||||
|
||||
if (mysql->can_use_ob_client_lob_locatorv2) {
|
||||
caplob |= OBCLIENT_CAP_OB_LOB_LOCATOR_V2;
|
||||
snprintf(caplob_buf, OB_MAX_UINT64_BUF_LEN, "%lu", caplob);
|
||||
rc += mysql_optionsv(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, OB_MYSQL_LOB_LOCATOR_V2, caplob_buf);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -2670,6 +2686,8 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
||||
// check env variable to determine if use ob20
|
||||
determine_protocol_ob20(mysql);
|
||||
determine_full_link_trace(mysql);
|
||||
determine_ob_client_lob_locatorv2(mysql);
|
||||
determine_flt_show_trace(mysql);
|
||||
|
||||
if (run_plugin_auth(mysql, scramble_data, scramble_len,
|
||||
scramble_plugin, db))
|
||||
@ -2706,8 +2724,14 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
||||
}
|
||||
if (get_ob_server_version(mysql)) {
|
||||
// select version errro
|
||||
goto error;
|
||||
// goto error;
|
||||
}
|
||||
|
||||
if (!set_nls_format(mysql)) {
|
||||
// goto error;
|
||||
// do nothing
|
||||
}
|
||||
|
||||
determine_use_prepare_execute(mysql);
|
||||
determine_send_plarray_maxrarr_len(mysql);
|
||||
determine_plarray_bindbyname(mysql);
|
||||
|
@ -771,7 +771,7 @@ int STDCALL mysql_stmt_fetch_oracle_buffered_result(MYSQL_STMT *stmt)
|
||||
return(1);
|
||||
}
|
||||
/* just read the buffered result for some situation, not to fetch the result from ObServer any more */
|
||||
if (rc = stmt_buffered_fetch(stmt, &row))
|
||||
if ((rc = stmt_buffered_fetch(stmt, &row)))
|
||||
{
|
||||
stmt->state= MYSQL_STMT_FETCH_DONE;
|
||||
stmt->mysql->status= MYSQL_STATUS_READY;
|
||||
@ -1286,28 +1286,107 @@ static void store_param_str(MYSQL_STMT *stmt, int column, unsigned char **pos, u
|
||||
store_param_str_complex(pos, &header);
|
||||
}
|
||||
|
||||
static void ob_client_mem_lob_common_to_buff(unsigned char** pos, uint32_t *len, ObClientMemLobCommon* common)
|
||||
{
|
||||
uint32_t tmps = 0;
|
||||
int4store(*pos, common->magic_);
|
||||
*pos += 4; *len -= 4;
|
||||
tmps <<= 15;
|
||||
tmps |= common->reserved_;
|
||||
tmps <<= 1;
|
||||
tmps |= common->has_extern;
|
||||
tmps <<= 1;
|
||||
tmps |= common->is_simple;
|
||||
tmps <<= 1;
|
||||
tmps |= common->is_open_;
|
||||
tmps <<= 1;
|
||||
tmps |= common->is_inrow_;
|
||||
tmps <<= 1;
|
||||
tmps |= common->read_only_;
|
||||
tmps <<= 4;
|
||||
tmps |= common->type_;
|
||||
tmps <<= 8;
|
||||
tmps |= common->version_;
|
||||
int4store(*pos, tmps);
|
||||
*pos += 4; *len -= 4;
|
||||
}
|
||||
static void ob_client_mem_lob_extern_header_to_buff(unsigned char** pos, uint32_t *len, ObClientMemLobExternHeader *header)
|
||||
{
|
||||
uint16_t tmps = 0;
|
||||
int8store(*pos, header->snapshot_ver_);
|
||||
*pos += 8; *len -= 8;
|
||||
int8store(*pos, header->table_id_);
|
||||
*pos += 8; *len -= 8;
|
||||
int4store(*pos, header->column_idx_);
|
||||
*pos += 4; *len -= 4;
|
||||
|
||||
tmps <<= 13;
|
||||
tmps |= header->extern_flags_;
|
||||
tmps <<= 1;
|
||||
tmps |= header->has_view_info;
|
||||
tmps <<= 1;
|
||||
tmps |= header->has_cid_hash;
|
||||
tmps <<= 1;
|
||||
tmps |= header->has_tx_info;
|
||||
int2store(*pos, tmps);
|
||||
*pos += 2; *len -= 2;
|
||||
|
||||
int2store(*pos, header->rowkey_size_);
|
||||
*pos += 2; *len -= 2;
|
||||
int4store(*pos, header->payload_offset_);
|
||||
*pos += 4; *len -= 4;
|
||||
int4store(*pos, header->payload_size_);
|
||||
*pos += 4; *len -= 4;
|
||||
}
|
||||
static void store_ob_lob_locator_v2(unsigned char** pos, uint32_t* len, OB_LOB_LOCATOR_V2* ob_lob_locator) {
|
||||
ob_client_mem_lob_common_to_buff(pos, len, &ob_lob_locator->common);
|
||||
if (ob_lob_locator->common.has_extern) {
|
||||
ob_client_mem_lob_extern_header_to_buff(pos, len, &ob_lob_locator->extern_header);
|
||||
}
|
||||
}
|
||||
static void store_ob_lob_locator_v1(unsigned char** pos, uint32_t *len, OB_LOB_LOCATOR* lob_locator){
|
||||
int4store(*pos, lob_locator->magic_code_);
|
||||
*pos += 4; *len -= 4;
|
||||
int4store(*pos, lob_locator->version_);
|
||||
*pos += 4; *len -= 4;
|
||||
int8store(*pos, lob_locator->snapshot_version_);
|
||||
*pos += 8; *len -= 8;
|
||||
int8store(*pos, lob_locator->table_id_);
|
||||
*pos += 8; *len -= 8;
|
||||
int4store(*pos, lob_locator->column_id_);
|
||||
*pos += 4; *len -= 4;
|
||||
int2store(*pos, lob_locator->mode_);
|
||||
*pos += 2; *len -= 2;
|
||||
int2store(*pos, lob_locator->option_);
|
||||
*pos += 2; *len -= 2;
|
||||
int4store(*pos, lob_locator->payload_offset_);
|
||||
*pos += 4; *len -= 4;
|
||||
int4store(*pos, lob_locator->payload_size_);
|
||||
*pos += 4; *len -= 4;
|
||||
}
|
||||
|
||||
static void store_param_ob_lob_complex(unsigned char **pos, MYSQL_COMPLEX_BIND_HEADER *param)
|
||||
{
|
||||
OB_LOB_LOCATOR *lob_locator = (OB_LOB_LOCATOR *) param->buffer;
|
||||
uchar buff[MAX_OB_LOB_LOCATOR_HEADER_LENGTH];
|
||||
uint8_t version = get_ob_lob_locator_version(lob_locator);
|
||||
if (version == OBCLIENT_LOB_LOCATORV1) {
|
||||
uint32_t len = MAX_OB_LOB_LOCATOR_HEADER_LENGTH;
|
||||
*pos = mysql_net_store_length(*pos, MAX_OB_LOB_LOCATOR_HEADER_LENGTH + lob_locator->payload_size_ + lob_locator->payload_offset_);
|
||||
|
||||
*pos = mysql_net_store_length(*pos, MAX_OB_LOB_LOCATOR_HEADER_LENGTH + lob_locator->payload_size_ + lob_locator->payload_offset_);
|
||||
store_ob_lob_locator_v1(pos, &len, lob_locator);
|
||||
|
||||
int4store(buff, lob_locator->magic_code_);
|
||||
int4store(buff + 4, lob_locator->version_);
|
||||
int8store(buff + 8, lob_locator->snapshot_version_);
|
||||
int8store(buff + 16, lob_locator->table_id_);
|
||||
int4store(buff + 24, lob_locator->column_id_);
|
||||
int2store(buff + 28, lob_locator->mode_);
|
||||
int2store(buff + 30, lob_locator->option_);
|
||||
int4store(buff + 32, lob_locator->payload_offset_);
|
||||
int4store(buff + 36, lob_locator->payload_size_);
|
||||
memcpy((char *)*pos, lob_locator->data_, lob_locator->payload_size_ + lob_locator->payload_offset_);
|
||||
*pos += lob_locator->payload_size_ + lob_locator->payload_offset_;
|
||||
} else if (version == OBCLIENT_LOB_LOCATORV2) {
|
||||
uint32_t len = MAX_OB_LOB_LOCATOR_HEADER_LENGTH;
|
||||
OB_LOB_LOCATOR_V2 *lob_locatorv2 = (OB_LOB_LOCATOR_V2 *)param->buffer;
|
||||
*pos = mysql_net_store_length(*pos, MAX_OB_LOB_LOCATOR_HEADER_LENGTH + lob_locatorv2->extern_header.payload_size_ + lob_locatorv2->extern_header.payload_offset_);
|
||||
|
||||
store_ob_lob_locator_v2(pos, &len, lob_locatorv2);
|
||||
|
||||
memcpy((char *)*pos, buff, MAX_OB_LOB_LOCATOR_HEADER_LENGTH);
|
||||
*pos += MAX_OB_LOB_LOCATOR_HEADER_LENGTH;
|
||||
|
||||
memcpy((char *)*pos, lob_locator->data_, lob_locator->payload_size_ + lob_locator->payload_offset_);
|
||||
*pos += lob_locator->payload_size_ + lob_locator->payload_offset_;
|
||||
memcpy((char *)*pos, lob_locatorv2->data_, lob_locatorv2->extern_header.payload_size_ + lob_locatorv2->extern_header.payload_offset_);
|
||||
*pos += lob_locatorv2->extern_header.payload_size_ + lob_locatorv2->extern_header.payload_offset_;
|
||||
}
|
||||
}
|
||||
|
||||
static void store_param_ob_lob(MYSQL_STMT *stmt, int column, unsigned char **pos, unsigned long row_nr)
|
||||
@ -1941,8 +2020,14 @@ static ulong calculate_param_ob_lob_len(MYSQL_BIND *param)
|
||||
|
||||
if (NULL != param->buffer) {
|
||||
OB_LOB_LOCATOR *ob_lob_locator= (OB_LOB_LOCATOR *) param->buffer;
|
||||
len = MAX_OB_LOB_LOCATOR_HEADER_LENGTH + ob_lob_locator->payload_offset_ + ob_lob_locator->payload_size_;
|
||||
len += mysql_store_length_size(len);
|
||||
if (OBCLIENT_LOB_LOCATORV1 == get_ob_lob_locator_version(ob_lob_locator)) {
|
||||
len = MAX_OB_LOB_LOCATOR_HEADER_LENGTH + ob_lob_locator->payload_offset_ + ob_lob_locator->payload_size_;
|
||||
len += mysql_store_length_size(len);
|
||||
} else if (OBCLIENT_LOB_LOCATORV2 == get_ob_lob_locator_version(ob_lob_locator)) {
|
||||
OB_LOB_LOCATOR_V2 *ob_lob_locatorv2 = (OB_LOB_LOCATOR_V2*)param->buffer;
|
||||
len = MAX_OB_LOB_LOCATOR_HEADER_LENGTH + ob_lob_locatorv2->extern_header.payload_offset_ + ob_lob_locatorv2->extern_header.payload_size_;
|
||||
len += mysql_store_length_size(len);
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@ -2924,6 +3009,7 @@ int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind, unsigned
|
||||
bind[0].error= &bind[0].error_value;
|
||||
*bind[0].error= 0;
|
||||
bind[0].offset= offset;
|
||||
bind[0].mysql = stmt->mysql;
|
||||
save_ptr= stmt->bind[column].u.row_ptr;
|
||||
if (bind->piece_data_used)
|
||||
fetch_result_with_piece(&bind[0], &stmt->fields[column], &stmt->bind[column].u.row_ptr);
|
||||
@ -3050,6 +3136,7 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned lon
|
||||
{
|
||||
MYSQL *mysql= stmt->mysql;
|
||||
int rc= 1;
|
||||
int ret = 0;
|
||||
my_bool is_multi= 0;
|
||||
FLT_DECLARE;
|
||||
|
||||
@ -3099,8 +3186,13 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned lon
|
||||
|
||||
FLT_BEFORE_COMMAND(0, FLT_TAG_COMMAND_NAME, "\"mysql_stmt_prepare\"");
|
||||
|
||||
if (mysql->methods->db_command(mysql, COM_STMT_PREPARE, query, length, 1, stmt))
|
||||
ret = mysql->methods->db_command(mysql, COM_STMT_PREPARE, query, length, 1, stmt);
|
||||
// end trace
|
||||
FLT_AFTER_COMMAND;
|
||||
|
||||
if (ret) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!is_multi && mysql->net.extension->multi_status == COM_MULTI_ENABLED && FALSE == get_use_protocol_ob20(mysql))
|
||||
ma_multi_command(mysql, COM_MULTI_END);
|
||||
@ -3157,10 +3249,7 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned lon
|
||||
}
|
||||
stmt->state = MYSQL_STMT_PREPARED;
|
||||
|
||||
// end trace
|
||||
FLT_AFTER_COMMAND;
|
||||
|
||||
return(0);
|
||||
return(0);
|
||||
|
||||
fail:
|
||||
stmt->state= MYSQL_STMT_INITTED;
|
||||
@ -4538,35 +4627,24 @@ my_bool determine_send_plarray_maxrarr_len(MYSQL *mysql)
|
||||
char* env = getenv("ENABLE_PLARRAY_MAXRARRLEN");
|
||||
if (env) {
|
||||
tmp_val = atoi(env);
|
||||
if (tmp_val >= 0 && tmp_val < SEND_PLARRAY_MAXRARRLEN_FLAG_MAX)
|
||||
{
|
||||
if (tmp_val >= 0 && tmp_val < SEND_PLARRAY_MAXRARRLEN_FLAG_MAX) {
|
||||
ival = tmp_val;
|
||||
}
|
||||
}
|
||||
if (ival == SEND_PLARRAY_MAXRARRLEN_FORCE_OPEN)
|
||||
{
|
||||
if (ival == SEND_PLARRAY_MAXRARRLEN_FORCE_OPEN) {
|
||||
bret = TRUE;
|
||||
}
|
||||
else if (ival == SEND_PLARRAY_MAXRARRLEN_FORCE_CLOSE)
|
||||
{
|
||||
} else if (ival == SEND_PLARRAY_MAXRARRLEN_FORCE_CLOSE) {
|
||||
bret = FALSE;
|
||||
}
|
||||
else if (NULL != mysql)
|
||||
{
|
||||
if (!mysql->oracle_mode)
|
||||
{
|
||||
} else if (NULL != mysql) {
|
||||
if (!mysql->oracle_mode) {
|
||||
// only oracle mode use new protocol
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mysql->ob_server_version >= SUPPORT_SEND_PLARRAY_MAXRARR_LEN)
|
||||
{
|
||||
} else {
|
||||
if (mysql->ob_server_version >= SUPPORT_SEND_PLARRAY_MAXRARR_LEN) {
|
||||
bret = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mysql)
|
||||
{
|
||||
if (mysql) {
|
||||
mysql->can_send_plarray_maxrarr_len = bret;
|
||||
}
|
||||
DBUG_RETURN(bret);
|
||||
@ -4574,8 +4652,7 @@ my_bool determine_send_plarray_maxrarr_len(MYSQL *mysql)
|
||||
|
||||
my_bool get_support_send_plarray_maxrarr_len(MYSQL *mysql)
|
||||
{
|
||||
if (mysql)
|
||||
{
|
||||
if (mysql) {
|
||||
return mysql->can_send_plarray_maxrarr_len;
|
||||
}
|
||||
return FALSE;
|
||||
@ -4592,35 +4669,24 @@ my_bool determine_plarray_bindbyname(MYSQL *mysql)
|
||||
char* env = getenv("ENABLE_PLARRAY_BINDBYNAME");
|
||||
if (env) {
|
||||
tmp_val = atoi(env);
|
||||
if (tmp_val >= 0 && tmp_val < PLARRAY_BINDBYNAME_FLAG_MAX)
|
||||
{
|
||||
if (tmp_val >= 0 && tmp_val < PLARRAY_BINDBYNAME_FLAG_MAX) {
|
||||
ival = tmp_val;
|
||||
}
|
||||
}
|
||||
if (ival == PLARRAY_BINDBYNAME_FORCE_OPEN)
|
||||
{
|
||||
if (ival == PLARRAY_BINDBYNAME_FORCE_OPEN) {
|
||||
bret = TRUE;
|
||||
}
|
||||
else if (ival == PLARRAY_BINDBYNAME_FORCE_CLOSE)
|
||||
{
|
||||
} else if (ival == PLARRAY_BINDBYNAME_FORCE_CLOSE) {
|
||||
bret = FALSE;
|
||||
}
|
||||
else if (NULL != mysql)
|
||||
{
|
||||
if (!mysql->oracle_mode)
|
||||
{
|
||||
} else if (NULL != mysql) {
|
||||
if (!mysql->oracle_mode) {
|
||||
// only oracle mode use new protocol
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mysql->ob_server_version >= SUPPORT_PLARRAY_BINDBYNAME)
|
||||
{
|
||||
} else {
|
||||
if (mysql->ob_server_version >= SUPPORT_PLARRAY_BINDBYNAME) {
|
||||
bret = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mysql)
|
||||
{
|
||||
if (mysql) {
|
||||
mysql->can_plarray_bindbyname = bret;
|
||||
}
|
||||
DBUG_RETURN(bret);
|
||||
@ -4628,8 +4694,7 @@ my_bool determine_plarray_bindbyname(MYSQL *mysql)
|
||||
|
||||
my_bool get_support_plarray_bindbyname(MYSQL *mysql)
|
||||
{
|
||||
if (mysql)
|
||||
{
|
||||
if (mysql) {
|
||||
return mysql->can_plarray_bindbyname;
|
||||
}
|
||||
return FALSE;
|
||||
@ -4647,21 +4712,16 @@ my_bool determine_protocol_ob20(MYSQL *mysql)
|
||||
char* env = getenv("ENABLE_PROTOCOL_OB20");
|
||||
if (env) {
|
||||
tmp_val = atoi(env);
|
||||
if (tmp_val >= 0 && tmp_val < PROTOCOL_OB20_FLAY_MAX)
|
||||
{
|
||||
if (tmp_val >= 0 && tmp_val < PROTOCOL_OB20_FLAG_MAX) {
|
||||
ival = tmp_val;
|
||||
}
|
||||
}
|
||||
if (ival == PROTOCOL_OB20_FORCE_OPEN)
|
||||
{
|
||||
if (ival == PROTOCOL_OB20_FORCE_OPEN) {
|
||||
bret = TRUE;
|
||||
}
|
||||
else if (ival == PROTOCOL_OB20_FORCE_CLOSE)
|
||||
{
|
||||
} else if (ival == PROTOCOL_OB20_FORCE_CLOSE) {
|
||||
bret = FALSE;
|
||||
}
|
||||
if (mysql)
|
||||
{
|
||||
if (mysql) {
|
||||
mysql->can_use_protocol_ob20 = bret;
|
||||
}
|
||||
DBUG_RETURN(bret);
|
||||
@ -4684,21 +4744,16 @@ my_bool determine_full_link_trace(MYSQL *mysql)
|
||||
char* env = getenv("ENABLE_FLT");
|
||||
if (env) {
|
||||
tmp_val = atoi(env);
|
||||
if (tmp_val >= 0 && tmp_val < PROTOCOL_FLT_FLAY_MAX)
|
||||
{
|
||||
if (tmp_val >= 0 && tmp_val < PROTOCOL_FLT_FLAG_MAX) {
|
||||
ival = tmp_val;
|
||||
}
|
||||
}
|
||||
if (ival == PROTOCOL_FLT_FORCE_OPEN)
|
||||
{
|
||||
if (ival == PROTOCOL_FLT_FORCE_OPEN) {
|
||||
bret = TRUE;
|
||||
}
|
||||
else if (ival == PROTOCOL_FLT_FORCE_CLOSE)
|
||||
{
|
||||
} else if (ival == PROTOCOL_FLT_FORCE_CLOSE) {
|
||||
bret = FALSE;
|
||||
}
|
||||
if (mysql)
|
||||
{
|
||||
if (mysql) {
|
||||
mysql->can_use_full_link_trace = bret;
|
||||
}
|
||||
DBUG_RETURN(bret);
|
||||
@ -4717,6 +4772,287 @@ my_bool get_use_full_link_trace(MYSQL *mysql)
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
my_bool determine_flt_show_trace(MYSQL *mysql)
|
||||
{
|
||||
my_bool bret = TRUE;
|
||||
int ival = FLT_SHOW_TRACE_AUTO_OPEN; //default is AUTO
|
||||
int tmp_val = 0;
|
||||
char* env = getenv("ENABLE_FLT_SHOW_TRACE");
|
||||
if (env) {
|
||||
tmp_val = atoi(env);
|
||||
if (tmp_val >= 0 && tmp_val < FLT_SHOW_TRACE_FLAG_MAX) {
|
||||
ival = tmp_val;
|
||||
}
|
||||
}
|
||||
if (ival == FLT_SHOW_TRACE_FORCE_OPEN) {
|
||||
bret = TRUE;
|
||||
} else if (ival == FLT_SHOW_TRACE_FORCE_CLOSE) {
|
||||
bret = FALSE;
|
||||
}
|
||||
if (mysql) {
|
||||
mysql->can_use_flt_show_trace = bret;
|
||||
}
|
||||
DBUG_RETURN(bret);
|
||||
}
|
||||
|
||||
my_bool get_use_flt_show_trace(MYSQL *mysql)
|
||||
{
|
||||
my_bool bret = FALSE;
|
||||
if (mysql && (mysql->capability & OBCLIENT_CAP_FULL_LINK_TRACE)
|
||||
&& (mysql->capability & OBCLIENT_CAP_PROXY_NEW_EXTRA_INFO)) {
|
||||
bret = TRUE;
|
||||
if (mysql->capability & OBCLIENT_CAP_PROXY_FULL_LINK_TRACE_SHOW_TRACE) {
|
||||
// do nothing, bret = TRUE;
|
||||
} else {
|
||||
bret = FALSE;
|
||||
}
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
my_bool determine_ob_client_lob_locatorv2(MYSQL *mysql)
|
||||
{
|
||||
my_bool bret = TRUE;
|
||||
int ival = OB_CLIENT_LOB_LOCATORV2_AUTO_OPEN; //default is AUTO
|
||||
int tmp_val = 0;
|
||||
char* env = getenv("ENABLE_OB_CLIENT_LOB_LOCATORV2");
|
||||
if (env) {
|
||||
tmp_val = atoi(env);
|
||||
if (tmp_val >= 0 && tmp_val < OB_CLIENT_LOB_LOCATORV2_FLAY_MAX) {
|
||||
ival = tmp_val;
|
||||
}
|
||||
}
|
||||
if (ival == OB_CLIENT_LOB_LOCATORV2_FORCE_OPEN) {
|
||||
bret = TRUE;
|
||||
} else if (ival == OB_CLIENT_LOB_LOCATORV2_FORCE_CLOSE) {
|
||||
bret = FALSE;
|
||||
}
|
||||
if (mysql) {
|
||||
mysql->can_use_ob_client_lob_locatorv2 = bret;
|
||||
}
|
||||
DBUG_RETURN(bret);
|
||||
}
|
||||
my_bool get_use_ob_client_lob_locatorv2(MYSQL *mysql)
|
||||
{
|
||||
if (mysql) {
|
||||
return mysql->can_use_ob_client_lob_locatorv2;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
uint8_t get_ob_lob_locator_version(void *lob)
|
||||
{
|
||||
uint8_t ver = 0;
|
||||
if (NULL == lob) {
|
||||
ver = 0;
|
||||
} else {
|
||||
ObClientMemLobCommon *plob = (ObClientMemLobCommon*)lob;
|
||||
ver = plob->version_;
|
||||
}
|
||||
return ver;
|
||||
}
|
||||
int64_t get_ob_lob_payload_data_len(void *lob)
|
||||
{
|
||||
int64_t len = -1;
|
||||
if (NULL == lob) {
|
||||
len = -1;
|
||||
} else {
|
||||
ObClientMemLobCommon *plob = (ObClientMemLobCommon*)lob;
|
||||
if (plob->version_ == OBCLIENT_LOB_LOCATORV1) {
|
||||
OB_LOB_LOCATOR *tmp = (OB_LOB_LOCATOR*)lob;
|
||||
len = tmp->payload_size_;
|
||||
} else if (plob->version_ == OBCLIENT_LOB_LOCATORV2) {
|
||||
OB_LOB_LOCATOR_V2 *tmp = (OB_LOB_LOCATOR_V2*)lob;
|
||||
if (0 == tmp->common.has_extern)
|
||||
len = -1;
|
||||
|
||||
if (tmp->common.is_inrow_) {
|
||||
len = tmp->extern_header.payload_size_;
|
||||
} else {
|
||||
//这种情况下的数据大小是位置在
|
||||
//sizeof(ObMemLobCommon ) + sizeof(ObMemLobExternHeader) + sizeof(uint16)+ ex_size + rowkey_size + sizeof(ObLobCommon)+sizeof(ObLobData)
|
||||
int tmp_len = tmp->extern_header.payload_offset_+ tmp->extern_header.payload_size_;
|
||||
char *tmp_buf = tmp->data_;
|
||||
uint16_t ex_size = uint2korr(tmp_buf);
|
||||
int offset = MAX_OB_LOB_LOCATOR_HEADER_LENGTH + sizeof(uint16) + ex_size + tmp->extern_header.rowkey_size_ + sizeof(ObClientLobCommon) + sizeof(ObClientLobData);
|
||||
if (tmp_len > offset) {
|
||||
len = uint8korr(tmp_buf + offset - 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int prepare_execute_v2(MYSQL *mysql, MYSQL_STMT* stmt, const char* query, MYSQL_BIND* params) {
|
||||
int ret = 0;
|
||||
int length = strlen(query);
|
||||
if (get_use_prepare_execute(mysql)) {
|
||||
void* extend_arg = NULL;
|
||||
if (mysql_stmt_prepare_v2(stmt, query, length, extend_arg)) {
|
||||
ret = -1;
|
||||
} else if (params && mysql_stmt_bind_param(stmt, params)) {
|
||||
ret = -1;
|
||||
} else if (mysql_stmt_execute_v2(stmt, query, length, 1, 0, extend_arg)) {
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
if (mysql_stmt_prepare(stmt, query, length)) {
|
||||
ret = -1;
|
||||
} else if (params && mysql_stmt_bind_param(stmt, params)) {
|
||||
ret = -1;
|
||||
} else if (mysql_stmt_execute(stmt)) {
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int stmt_get_data_from_lobv2( MYSQL *mysql, void * lob, enum_field_types type,
|
||||
int64_t char_offset, int64_t byte_offset, int64_t char_len, int64_t byte_len, char *buf, const int64_t buf_len, int64_t *data_len, int64_t *act_len)
|
||||
{
|
||||
int ret = -1;
|
||||
const char *read_sql = "call DBMS_LOB.read(?, ?, ?, ?)";
|
||||
MYSQL_BIND param_bind[4];
|
||||
MYSQL_BIND param_res[2];
|
||||
MYSQL_STMT* stmt = NULL;
|
||||
int64_t length = 0;
|
||||
OB_LOB_LOCATOR_V2 *loblocator = (OB_LOB_LOCATOR_V2*)lob;
|
||||
|
||||
char_offset = char_offset;
|
||||
char_len = char_len;
|
||||
|
||||
if (!mysql) {
|
||||
SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (NULL == lob) {
|
||||
SET_CLIENT_STMT_ERROR(stmt, CR_UNKNOWN_ERROR, unknown_sqlstate, NULL);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (OBCLIENT_LOB_LOCATORV2 != get_ob_lob_locator_version(lob)) {
|
||||
SET_CLIENT_STMT_ERROR(stmt, CR_UNKNOWN_ERROR, unknown_sqlstate, NULL);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (type != MYSQL_TYPE_ORA_CLOB && type != MYSQL_TYPE_ORA_BLOB) {
|
||||
SET_CLIENT_STMT_ERROR(stmt, CR_UNKNOWN_ERROR, unknown_sqlstate, NULL);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (1 != loblocator->common.has_extern) {
|
||||
SET_CLIENT_STMT_ERROR(stmt, CR_UNKNOWN_ERROR, unknown_sqlstate, NULL);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
if (1 == loblocator->common.is_inrow_) {
|
||||
length = byte_len > buf_len ? buf_len : byte_len;
|
||||
length = length > loblocator->extern_header.payload_size_ ? loblocator->extern_header.payload_size_ : length;
|
||||
memcpy(buf, loblocator->data_ + loblocator->extern_header.payload_offset_, length);
|
||||
if (data_len)
|
||||
*data_len = length;
|
||||
if (act_len)
|
||||
*act_len = loblocator->extern_header.payload_size_;
|
||||
ret = 0;
|
||||
} else {
|
||||
int64_t tmp_len = byte_len + 1;
|
||||
char *tmp_buf = calloc(1, byte_len);
|
||||
if (NULL != tmp_buf) {
|
||||
//params
|
||||
memset(param_bind, 0, sizeof(param_bind));
|
||||
param_bind[0].buffer = lob;
|
||||
param_bind[0].buffer_length = loblocator->extern_header.payload_size_ + loblocator->extern_header.payload_offset_ + MAX_OB_LOB_LOCATOR_HEADER_LENGTH;
|
||||
param_bind[0].buffer_type = type;
|
||||
param_bind[1].buffer = (char *)&tmp_len;
|
||||
param_bind[1].buffer_type = MYSQL_TYPE_LONGLONG;
|
||||
param_bind[2].buffer = (char *)&byte_offset;
|
||||
param_bind[2].buffer_type = MYSQL_TYPE_LONGLONG;
|
||||
param_bind[3].is_null = ¶m_bind[3].is_null_value;
|
||||
*param_bind[3].is_null = 1;
|
||||
if (MYSQL_TYPE_ORA_CLOB == type) {
|
||||
param_bind[3].buffer_type = MYSQL_TYPE_VAR_STRING;
|
||||
} else {
|
||||
param_bind[3].buffer_type = MYSQL_TYPE_OB_RAW;
|
||||
}
|
||||
|
||||
//result
|
||||
memset(param_res, 0, sizeof(param_res));
|
||||
param_res[0].error = ¶m_res[0].error_value;
|
||||
param_res[0].is_null = ¶m_res[0].is_null_value;
|
||||
param_res[0].buffer = &length;
|
||||
param_res[0].buffer_type = MYSQL_TYPE_LONGLONG;
|
||||
param_res[1].error = ¶m_res[1].error_value;
|
||||
param_res[1].is_null = ¶m_res[1].is_null_value;
|
||||
param_res[1].length = ¶m_res[1].length_value;
|
||||
param_res[1].buffer = tmp_buf;
|
||||
param_res[1].buffer_length = tmp_len;
|
||||
if (MYSQL_TYPE_ORA_CLOB == type) {
|
||||
param_res[1].buffer_type = MYSQL_TYPE_VAR_STRING;
|
||||
} else {
|
||||
param_res[1].buffer_type = MYSQL_TYPE_OB_RAW;
|
||||
}
|
||||
|
||||
if (NULL == (stmt = mysql_stmt_init(mysql))) {
|
||||
ret = -1;
|
||||
} else if (prepare_execute_v2(mysql, stmt, read_sql, param_bind)) {
|
||||
ret = -1;
|
||||
} else if (mysql_stmt_bind_result(stmt, param_res)) {
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = mysql_stmt_fetch(stmt);
|
||||
if (0 == ret) {
|
||||
*data_len = param_res[1].length_value;
|
||||
*act_len = *data_len;
|
||||
if (*data_len > byte_len) {
|
||||
*data_len = byte_len > buf_len ? buf_len : byte_len;
|
||||
} else {
|
||||
*data_len = *data_len > buf_len ? buf_len : *data_len;
|
||||
}
|
||||
memcpy(buf, tmp_buf, *data_len);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != stmt) {
|
||||
mysql_stmt_close(stmt);
|
||||
}
|
||||
|
||||
free(tmp_buf);
|
||||
tmp_buf = NULL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
my_bool set_nls_format(MYSQL *mysql)
|
||||
{
|
||||
my_bool bret = TRUE;
|
||||
if (mysql->oracle_mode) {
|
||||
char *nls_date_format = getenv("NLS_DATE_FORMAT");
|
||||
char *nls_timestamp_format = getenv("NLS_TIMESTAMP_FORMAT");
|
||||
char *nls_timestamp_tz_format = getenv("NLS_TIMESTAMP_TZ_FORMAT");
|
||||
|
||||
if (NULL != nls_date_format) {
|
||||
char change_date_format_sql[100];
|
||||
snprintf(change_date_format_sql, 100, "ALTER SESSION SET NLS_DATE_FORMAT='%s';", nls_date_format);
|
||||
if (mysql_query(mysql, change_date_format_sql)) {
|
||||
bret = FALSE;
|
||||
}
|
||||
}
|
||||
if (bret && NULL != nls_timestamp_format) {
|
||||
char change_timestamp_format_sql[100];
|
||||
snprintf(change_timestamp_format_sql, 100, "ALTER SESSION SET NLS_TIMESTAMP_FORMAT='%s';", nls_timestamp_format);
|
||||
if (mysql_query(mysql, change_timestamp_format_sql)) {
|
||||
bret = FALSE;
|
||||
}
|
||||
}
|
||||
if (bret && NULL != nls_timestamp_tz_format) {
|
||||
char change_timestamp_tz_format_sql[100];
|
||||
snprintf(change_timestamp_tz_format_sql, 100, "ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='%s';", nls_timestamp_tz_format);
|
||||
if (mysql_query(mysql, change_timestamp_tz_format_sql)) {
|
||||
bret = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
/*
|
||||
* judge where can use prepare_execute protocol
|
||||
* use version to judge
|
||||
@ -5334,10 +5670,12 @@ static int madb_update_stmt_fields(MYSQL_STMT *stmt) // same as update_stmt_fiel
|
||||
if (MYSQL_TYPE_OBJECT == field->type && NULL == stmt_field->owner_name && NULL != field->owner_name) {
|
||||
stmt_field->owner_name= (unsigned char *)ma_memdup_root(fields_ma_alloc_root,
|
||||
(char*)field->owner_name,
|
||||
field->owner_name_length);
|
||||
field->owner_name_length+1);
|
||||
stmt_field->owner_name[field->owner_name_length] = 0;
|
||||
stmt_field->type_name= (unsigned char *)ma_memdup_root(fields_ma_alloc_root,
|
||||
(char*)field->type_name,
|
||||
field->type_name_length);
|
||||
field->type_name_length+1);
|
||||
stmt_field->type_name[field->type_name_length] = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -60,6 +60,9 @@ if (OB_NOT_NULL(span) && 0 == span->span_id_.high_) { \
|
||||
FLT_EXTRA_INFO_DEF(FLT_TRACE_ID, MYSQL_TYPE_VAR_STRING); \
|
||||
FLT_EXTRA_INFO_DEF(FLT_REF_TYPE, MYSQL_TYPE_TINY); \
|
||||
FLT_EXTRA_INFO_DEF(FLT_SPAN_ID, MYSQL_TYPE_VAR_STRING); \
|
||||
/* SHOW_TRACE_SPAN */ \
|
||||
FLT_EXTRA_INFO_DEF(FLT_DRV_SHOW_TRACE_SPAN, MYSQL_TYPE_VAR_STRING); \
|
||||
FLT_EXTRA_INFO_DEF(FLT_PROXY_SHOW_TRACE_SPAN, MYSQL_TYPE_VAR_STRING); \
|
||||
FLT_EXTRA_INFO_DEF(FLT_EXTRA_INFO_ID_END, MAX_NO_FIELD_TYPES); \
|
||||
} while (0);
|
||||
#define FLT_SERIALIZE_FUNC_SET(id, funcname) (flt_funcs[id] = (FLTFunc)FLT_SERIALIZE_FUNC(funcname))
|
||||
@ -76,6 +79,8 @@ if (OB_NOT_NULL(span) && 0 == span->span_id_.high_) { \
|
||||
FLT_SERIALIZE_FUNC_SET(FLT_CONTROL_INFO, controlinfo); \
|
||||
/* SPAN_INFO */ \
|
||||
FLT_SERIALIZE_FUNC_SET(FLT_SPAN_INFO, spaninfo); \
|
||||
/* SHOW_TRACE_SPAN */ \
|
||||
FLT_SERIALIZE_FUNC_SET(FLT_TYPE_SHOW_TRACE_SPAN, showtracespan); \
|
||||
} while (0);
|
||||
|
||||
const char *tag_str[FLT_TAG_MAX_TYPE] =
|
||||
@ -132,6 +137,7 @@ int flt_init(FLTInfo *flt)
|
||||
|
||||
memset(flt, 0, sizeof(*flt));
|
||||
|
||||
flt->show_trace_span_.type_ = FLT_TYPE_SHOW_TRACE_SPAN;
|
||||
flt->client_span_.type_ = FLT_DRIVER_SPAN_INFO;
|
||||
flt->app_info_.type_ = FLT_APP_INFO;
|
||||
flt->query_info_.type_ = FLT_QUERY_INFO;
|
||||
@ -145,6 +151,7 @@ int flt_init(FLTInfo *flt)
|
||||
flt->control_info_.rp_ = MAX_RECORD_POLICY;
|
||||
flt->control_info_.print_sample_pct_ = -1;
|
||||
flt->control_info_.slow_query_threshold_ = -1;
|
||||
flt->control_info_.flt_show_trace_enable_ = 0;
|
||||
|
||||
if (OB_FAIL(trace_init(flt))) {
|
||||
// trace init error;
|
||||
@ -188,6 +195,7 @@ int flt_build_request(MYSQL *mysql, FLTInfo *flt)
|
||||
int32_t span_info_serialize_size = 0;
|
||||
int32_t client_log_serialize_size = 0;
|
||||
int32_t app_info_serialize_size = 0;
|
||||
int32_t show_trace_serialize_size = 0;
|
||||
int64_t tmp_trace_id_pos = 0;
|
||||
int64_t tmp_span_id_pos = 0;
|
||||
|
||||
@ -221,21 +229,36 @@ int flt_build_request(MYSQL *mysql, FLTInfo *flt)
|
||||
flt->client_span_.client_span_ = NULL;
|
||||
}
|
||||
|
||||
if (1 < trace->show_trace_buf_offset_ && trace->show_trace_enable_) {
|
||||
flt->show_trace_span_.client_span_json_ = trace->show_trace_buf_;
|
||||
// Change the final comma to a parenthesis
|
||||
trace->show_trace_buf_[trace->show_trace_buf_offset_ - 1] = ']';
|
||||
} else {
|
||||
flt->show_trace_span_.client_span_json_ = NULL;
|
||||
}
|
||||
|
||||
if (OB_FAIL(flt_get_serialize_size_extra_info(&app_info_serialize_size, &flt->app_info_))) {
|
||||
// error
|
||||
} else if (OB_FAIL(flt_get_serialize_size_extra_info(&client_log_serialize_size, &flt->client_span_))) {
|
||||
// error
|
||||
} else if (OB_FAIL(flt_get_serialize_size_extra_info(&span_info_serialize_size, &flt->span_info_))) {
|
||||
// error
|
||||
} else if (OB_FAIL(flt_get_serialize_size_extra_info(&show_trace_serialize_size, &flt->show_trace_span_))) {
|
||||
// error
|
||||
} else {
|
||||
serialize_size += app_info_serialize_size;
|
||||
serialize_size += client_log_serialize_size;
|
||||
serialize_size += span_info_serialize_size;
|
||||
serialize_size += show_trace_serialize_size;
|
||||
#ifdef DEBUG_OB20
|
||||
printf("spaninfo ssize is %d, log ssize is %d, appinfo ssize %d\n", span_info_serialize_size, client_log_serialize_size, app_info_serialize_size);
|
||||
printf("spaninfo ssize:%d, log ssize:%d, appinfo ssize:%d, show trace ssize:%d\n", span_info_serialize_size,
|
||||
client_log_serialize_size, app_info_serialize_size, show_trace_serialize_size);
|
||||
if (0 != client_log_serialize_size) {
|
||||
printf("log:%s\n", flt->client_span_.client_span_);
|
||||
}
|
||||
if (0 != show_trace_serialize_size) {
|
||||
printf("log:%s\n", flt->show_trace_span_.client_span_json_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -256,6 +279,10 @@ int flt_build_request(MYSQL *mysql, FLTInfo *flt)
|
||||
// error
|
||||
} else if (pos != span_info_serialize_size + client_log_serialize_size) {
|
||||
ret = OB_ERROR;
|
||||
} else if (0 != show_trace_serialize_size && OB_FAIL(flt_serialize_extra_info(flt->flt_value_data_.value_data_, serialize_size, &pos, &flt->show_trace_span_))) {
|
||||
// error
|
||||
} else if (pos != span_info_serialize_size + client_log_serialize_size + show_trace_serialize_size) {
|
||||
ret = OB_ERROR;
|
||||
} else if (0 != app_info_serialize_size && OB_FAIL(flt_serialize_extra_info(flt->flt_value_data_.value_data_, serialize_size, &pos, &flt->app_info_))) {
|
||||
// error
|
||||
} else if (pos != serialize_size) {
|
||||
@ -269,6 +296,10 @@ int flt_build_request(MYSQL *mysql, FLTInfo *flt)
|
||||
// reset the log buf offset
|
||||
trace->log_buf_offset_ = 0;
|
||||
flt->client_span_.client_span_ = NULL;
|
||||
// reset show trace log buffer
|
||||
trace->show_trace_buf_[0] = '[';
|
||||
trace->show_trace_buf_offset_ = 1;
|
||||
flt->show_trace_span_.client_span_json_ = NULL;
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(ob20_set_extra_info(mysql, FULL_TRC, &flt->flt_value_data_))) {
|
||||
@ -328,11 +359,12 @@ int flt_get_serialize_size_controlinfo(int32_t *size, void *flt_info)
|
||||
UNUSED(flt_info);
|
||||
|
||||
local_size += TYPE_LENGTH + LEN_LENGTH;
|
||||
local_size += flt_get_store_int1_size();
|
||||
local_size += flt_get_store_double_size();
|
||||
local_size += flt_get_store_int1_size();
|
||||
local_size += flt_get_store_double_size();
|
||||
local_size += flt_get_store_int8_size();
|
||||
local_size += flt_get_store_int1_size(); // type_
|
||||
local_size += flt_get_store_double_size(); // sample_pct_
|
||||
local_size += flt_get_store_int1_size(); // rp_
|
||||
local_size += flt_get_store_double_size(); // print_sample_pct_
|
||||
local_size += flt_get_store_int8_size(); // slow_query_threshold_
|
||||
local_size += flt_get_store_int8_size(); // flt_show_trace_enable_
|
||||
|
||||
*size = local_size;
|
||||
return ret;
|
||||
@ -361,6 +393,8 @@ int flt_serialize_controlinfo(char *buf, const int64_t len, int64_t *pos, void *
|
||||
ret = OB_ERROR;
|
||||
} else if (OB_FAIL(flt_store_int8(buf, len, pos, control_info->slow_query_threshold_, FLT_SLOW_QUERY_THRES))) {
|
||||
ret = OB_ERROR;
|
||||
} else if (OB_FAIL(flt_store_int8(buf, len, pos, control_info->flt_show_trace_enable_, FLT_SHOW_TRACE_ENABLE))) {
|
||||
ret = OB_ERROR;
|
||||
} else {
|
||||
// fill type and len in the head
|
||||
int32_t total_len = *pos - org_pos - 6;
|
||||
@ -431,6 +465,16 @@ int flt_deserialize_field_controlinfo(FullLinkTraceExtraInfoId extra_id, const i
|
||||
// do nothing
|
||||
#ifdef DEBUG_OB20
|
||||
printf("slow_query_threshold is %ld\n", flt_control_info->slow_query_threshold_);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FLT_SHOW_TRACE_ENABLE: {
|
||||
if (OB_FAIL(flt_get_int1(buf, len, pos, v_len, &flt_control_info->flt_show_trace_enable_))) {
|
||||
ret = OB_ERROR;
|
||||
} else {
|
||||
#ifdef DEBUG_OB20
|
||||
printf("show_trace_enable is %hhd\n", flt_control_info->flt_show_trace_enable_);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@ -544,7 +588,7 @@ int flt_deserialize_field_appinfo(FullLinkTraceExtraInfoId extra_id, const int64
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// get an unrecognized key here, skip it directly
|
||||
// get an unrecognized key here, skip it directly
|
||||
*pos += *pos + v_len;
|
||||
break;
|
||||
}
|
||||
@ -619,7 +663,7 @@ int flt_deserialize_field_queryinfo(FullLinkTraceExtraInfoId extra_id, const int
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// get an unrecognized key here, skip it directly
|
||||
// get an unrecognized key here, skip it directly
|
||||
*pos += *pos + v_len;
|
||||
break;
|
||||
}
|
||||
@ -811,6 +855,72 @@ int flt_deserialize_field_driverspaninfo(FullLinkTraceExtraInfoId extra_id, cons
|
||||
}
|
||||
// for driverspaninfo info
|
||||
|
||||
// for show trace span
|
||||
int flt_get_serialize_size_showtracespan(int32_t *size, void *flt_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int32_t local_size = 0;
|
||||
FLTShowTraceSpan *show_trace_span = (FLTShowTraceSpan *)flt_info;
|
||||
|
||||
if (NULL != show_trace_span->client_span_json_) {
|
||||
local_size += TYPE_LENGTH + LEN_LENGTH;
|
||||
local_size += flt_get_store_str_size(strlen(show_trace_span->client_span_json_) + 1);
|
||||
}
|
||||
|
||||
*size = local_size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int flt_serialize_showtracespan(char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t org_pos = *pos;
|
||||
FLTShowTraceSpan *show_trace_span = (FLTShowTraceSpan *)flt_info;
|
||||
// resrver for type and len
|
||||
if (*pos + 6 > len) {
|
||||
ret = OB_SIZE_OVERFLOW;
|
||||
} else {
|
||||
*pos += 6;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(flt_store_str(buf, len, pos, show_trace_span->client_span_json_, strlen(show_trace_span->client_span_json_) + 1, FLT_DRV_SHOW_TRACE_SPAN))) {
|
||||
ret = OB_ERROR;
|
||||
} else {
|
||||
// fill type and len in the head
|
||||
int32_t total_len = *pos - org_pos - 6;
|
||||
if (OB_FAIL(flt_store_type_and_len(buf, len, &org_pos, show_trace_span->type_, total_len))) {
|
||||
ret = OB_ERROR;
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int flt_deserialize_field_showtracespan(FullLinkTraceExtraInfoId extra_id, const int64_t v_len,
|
||||
const char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
FLTShowTraceSpan *show_trace_span = (FLTShowTraceSpan *)flt_info;
|
||||
switch(extra_id) {
|
||||
case FLT_CLIENT_IDENTIFIER: {
|
||||
if (OB_FAIL(flt_get_str(buf, len, pos, v_len, (char **)&show_trace_span->client_span_json_))) {
|
||||
ret = OB_ERROR;
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*pos += *pos + v_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// for driverspaninfo info
|
||||
|
||||
// for no support
|
||||
int flt_deserialize_field_nosupport(FullLinkTraceExtraInfoId extra_id, const int64_t v_len,
|
||||
const char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
||||
@ -1281,18 +1391,31 @@ int trace_init(FLTInfo *flt)
|
||||
memset(trace, 0, sizeof(*trace));
|
||||
trace->buffer_size_ = OBTRACE_DEFAULT_BUFFER_SIZE - sizeof(*trace);
|
||||
trace->log_buf_ = trace->data_; // size is MAX_TRACE_LOG_SIZE
|
||||
trace->flt_serialize_buf_ = trace->data_ + MAX_TRACE_LOG_SIZE; // size is MAX_FLT_SERIALIZE_SIZE
|
||||
trace->show_trace_buf_ = trace->data_ + MAX_TRACE_LOG_SIZE; // size is MAX_TRACE_LOG_SIZE
|
||||
trace->flt_serialize_buf_ = trace->data_ + (2 * MAX_TRACE_LOG_SIZE); // size is MAX_FLT_SERIALIZE_SIZE
|
||||
trace->offset_ = INIT_OFFSET;
|
||||
trace->auto_flush_ = 1;
|
||||
trace->trace_enable_ = FALSE;
|
||||
trace->show_trace_enable_ = FALSE;
|
||||
trace->force_print_ = FALSE;
|
||||
trace->slow_query_print_ = FALSE;
|
||||
trace->root_span_id_.low_ = 0;
|
||||
trace->root_span_id_.high_ = 0;
|
||||
trace->flt = flt;
|
||||
flt->trace_ = trace;
|
||||
// set the starting parentheses
|
||||
trace->show_trace_buf_[0] = '[';
|
||||
trace->show_trace_buf_offset_ = 1;
|
||||
trace->free_tag_list_.data_ = NULL;
|
||||
trace->free_tag_list_.next_ = NULL;
|
||||
trace->free_tag_list_.tag_type_ = 0;
|
||||
for (index = 0; index < TAG_CACHE_COUNT; ++index) {
|
||||
ObTagCtx *tag = (ObTagCtx *)(trace->data_ + TAG_BUFFER_BEGIN + (index * sizeof(ObTagCtx)));
|
||||
tag->next_ = trace->free_tag_list_.next_;
|
||||
trace->free_tag_list_.next_ = tag;
|
||||
}
|
||||
for (index = 0; index < SPAN_CACHE_COUNT; ++index) {
|
||||
char *begin_addr = trace->data_ + MAX_TRACE_LOG_SIZE + MAX_FLT_SERIALIZE_SIZE + (index * (sizeof(LIST) + sizeof(ObSpanCtx)));
|
||||
char *begin_addr = trace->data_ + SPAN_BUFFER_BEGIN + (index * (sizeof(LIST) + sizeof(ObSpanCtx)));
|
||||
LIST *list = (LIST *)begin_addr;
|
||||
list->data = (ObSpanCtx *)(begin_addr + sizeof(LIST));
|
||||
trace->free_span_list_ = list_add(trace->free_span_list_, list);
|
||||
@ -1322,11 +1445,18 @@ void begin_trace(ObTrace *trace)
|
||||
if (OB_ISNULL(flt)) {
|
||||
// error, do not entable trace
|
||||
trace->trace_enable_ = FALSE;
|
||||
trace->show_trace_enable_ = FALSE;
|
||||
} else if (FALSE == flt_is_vaild(flt)) {
|
||||
// error, invalid trace
|
||||
trace->trace_enable_ = FALSE;
|
||||
trace->show_trace_enable_ = FALSE;
|
||||
} else if (TRUE == flt->control_info_.flt_show_trace_enable_) {
|
||||
// for show trace , always true
|
||||
trace->trace_enable_ = TRUE;
|
||||
trace->show_trace_enable_ = TRUE;
|
||||
} else {
|
||||
double trace_pct = flt_get_pct(trace->uuid_random_seed);
|
||||
trace->show_trace_enable_ = FALSE;
|
||||
|
||||
if (trace_pct <= flt->control_info_.sample_pct_) {
|
||||
// trace enable
|
||||
@ -1337,10 +1467,15 @@ void begin_trace(ObTrace *trace)
|
||||
}
|
||||
|
||||
if (TRUE == trace->trace_enable_) {
|
||||
// todo : add interface to set trace id
|
||||
trace->trace_id_ = uuid4_generate(trace->uuid_random_seed);
|
||||
trace->level_ = flt->control_info_.level_;
|
||||
// If the trace hits, the subsequent calculation and printing strategy
|
||||
if (RP_ALL == flt->control_info_.rp_) {
|
||||
|
||||
if (TRUE == flt->control_info_.flt_show_trace_enable_) {
|
||||
// for show trace , always true
|
||||
trace->force_print_ = TRUE;
|
||||
} else if (RP_ALL == flt->control_info_.rp_) {
|
||||
trace->force_print_ = TRUE;
|
||||
} else if (RP_SAMPLE_AND_SLOW_QUERY == flt->control_info_.rp_) {
|
||||
// Hit print samples need to print
|
||||
@ -1380,8 +1515,8 @@ void end_trace(ObTrace *trace)
|
||||
if (0 == span->end_ts_) {
|
||||
span->end_ts_ = get_current_time_us();
|
||||
}
|
||||
trace->current_span_list_ = trace->current_span_list_->next;
|
||||
// add all elem to free span list
|
||||
trace->current_span_list_ = list_delete(trace->current_span_list_, span_elem);
|
||||
trace->free_span_list_ = list_add(trace->free_span_list_, span_elem);
|
||||
}
|
||||
trace->offset_ = INIT_OFFSET;
|
||||
@ -1454,29 +1589,37 @@ void flush_first_span(ObTrace *trace)
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && 0 != span->end_ts_) {
|
||||
// clear span and reset tag
|
||||
ObTagCtx *tag = span->tags_;
|
||||
while(OB_NOT_NULL(tag)) {
|
||||
ObTagCtx *free_tag = tag;
|
||||
tag = tag->next_;
|
||||
reset_tag(trace, span, free_tag);
|
||||
}
|
||||
span->tags_ = NULL;
|
||||
trace->current_span_list_ = list_delete(trace->current_span_list_, span_list);
|
||||
trace->free_span_list_ = list_add(trace->free_span_list_, span_list);
|
||||
}
|
||||
span->tags_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void flush_trace(ObTrace *trace)
|
||||
{
|
||||
LIST *next;
|
||||
LIST *span_list;
|
||||
LIST *span_elem;
|
||||
ObSpanCtx *span;
|
||||
int64_t pos = 0;
|
||||
int ret = OB_SUCCESS;
|
||||
int log_buf_len = 0;
|
||||
int show_trace_buf_len = 0;
|
||||
|
||||
if (OB_ISNULL(trace) || (0 == trace->trace_id_.low_ && 0 == trace->trace_id_.high_)) {
|
||||
// do nothing
|
||||
} else if (OB_ISNULL(span_list = trace->current_span_list_)) {
|
||||
} else if (OB_ISNULL(trace->current_span_list_)) {
|
||||
// do nothing
|
||||
} else {
|
||||
while (OB_NOT_NULL(span_list)) {
|
||||
span = (ObSpanCtx *)span_list->data;
|
||||
next = span_list->next;
|
||||
while (OB_NOT_NULL(trace->current_span_list_) && OB_SUCC(ret)) {
|
||||
span_elem = trace->current_span_list_;
|
||||
span = (ObSpanCtx *)span_elem->data;
|
||||
if (OB_NOT_NULL(span)) {
|
||||
ObTagCtx *tag = span->tags_;
|
||||
my_bool first = TRUE;
|
||||
@ -1508,31 +1651,50 @@ void flush_trace(ObTrace *trace)
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
INIT_SPAN(trace, span->source_span_);
|
||||
ret = snprintf(trace->log_buf_ + trace->log_buf_offset_,
|
||||
MAX_TRACE_LOG_SIZE - trace->log_buf_offset_,
|
||||
TRACE_PATTERN "%s}",
|
||||
UUID_TOSTRING(trace->trace_id_),
|
||||
"obclient",
|
||||
UUID_TOSTRING(span->span_id_),
|
||||
span->start_ts_,
|
||||
span->end_ts_,
|
||||
UUID_TOSTRING(OB_ISNULL(span->source_span_) ? trace->root_span_id_ : span->source_span_->span_id_),
|
||||
span->is_follow_ ? "true" : "false",
|
||||
buf);
|
||||
if (ret < 0 || trace->log_buf_offset_ + ret >= MAX_TRACE_LOG_SIZE) {
|
||||
log_buf_len = snprintf(trace->log_buf_ + trace->log_buf_offset_,
|
||||
MAX_TRACE_LOG_SIZE - trace->log_buf_offset_,
|
||||
TRACE_PATTERN "%s}",
|
||||
UUID_TOSTRING(trace->trace_id_),
|
||||
"obclient",
|
||||
UUID_TOSTRING(span->span_id_),
|
||||
span->start_ts_,
|
||||
span->end_ts_,
|
||||
UUID_TOSTRING(OB_ISNULL(span->source_span_) ? trace->root_span_id_ : span->source_span_->span_id_),
|
||||
span->is_follow_ ? "true" : "false",
|
||||
buf);
|
||||
if (log_buf_len < 0 || trace->log_buf_offset_ + log_buf_len >= MAX_TRACE_LOG_SIZE) {
|
||||
ret = OB_ERROR;
|
||||
} else {
|
||||
trace->log_buf_offset_ += ret;
|
||||
ret = OB_SUCCESS;
|
||||
trace->log_buf_offset_ += log_buf_len;
|
||||
if (0 != span->end_ts_) {
|
||||
// The span that has ended needs to be put into the show trace buffer and sent to the backend next time
|
||||
show_trace_buf_len = snprintf(trace->show_trace_buf_ + trace->show_trace_buf_offset_,
|
||||
MAX_TRACE_LOG_SIZE - trace->show_trace_buf_offset_,
|
||||
"%.*s,",
|
||||
log_buf_len,
|
||||
trace->log_buf_ + trace->log_buf_offset_ - log_buf_len);
|
||||
if (show_trace_buf_len < 0 || trace->show_trace_buf_offset_ + show_trace_buf_len >= MAX_TRACE_LOG_SIZE) {
|
||||
ret = OB_ERROR;
|
||||
} else {
|
||||
trace->show_trace_buf_offset_ += show_trace_buf_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && 0 != span->end_ts_) {
|
||||
trace->current_span_list_ = list_delete(trace->current_span_list_, span_list);
|
||||
trace->free_span_list_ = list_add(trace->free_span_list_, span_list);
|
||||
|
||||
// clear span and reset tag
|
||||
ObTagCtx *tag = span->tags_;
|
||||
while(OB_NOT_NULL(tag)) {
|
||||
ObTagCtx *free_tag = tag;
|
||||
tag = tag->next_;
|
||||
reset_tag(trace, span, free_tag);
|
||||
}
|
||||
span->tags_ = 0;
|
||||
trace->current_span_list_ = list_delete(trace->current_span_list_, span_elem);
|
||||
trace->free_span_list_ = list_add(trace->free_span_list_, span_elem);
|
||||
}
|
||||
span->tags_ = 0;
|
||||
}
|
||||
span_list = next;
|
||||
}
|
||||
trace->offset_ = INIT_OFFSET;
|
||||
}
|
||||
@ -1556,7 +1718,6 @@ ObSpanCtx* begin_span(ObTrace *trace, uint32_t span_type, uint8_t level, my_bool
|
||||
}
|
||||
if (OB_NOT_NULL(trace->free_span_list_)) {
|
||||
LIST *span_elem = trace->free_span_list_;
|
||||
trace->free_span_list_ = trace->free_span_list_->next;
|
||||
if (OB_NOT_NULL(span_elem)) {
|
||||
new_span = (ObSpanCtx *)span_elem->data;
|
||||
new_span->span_type_ = span_type;
|
||||
@ -1568,6 +1729,7 @@ ObSpanCtx* begin_span(ObTrace *trace, uint32_t span_type, uint8_t level, my_bool
|
||||
new_span->end_ts_ = 0;
|
||||
new_span->tags_ = NULL;
|
||||
trace->last_active_span_ = new_span;
|
||||
trace->free_span_list_ = list_delete(trace->free_span_list_, span_elem);
|
||||
trace->current_span_list_ = list_add(trace->current_span_list_, span_elem);
|
||||
}
|
||||
}
|
||||
@ -1619,17 +1781,14 @@ void reset_span(ObTrace *trace)
|
||||
// trace is not inited
|
||||
} else {
|
||||
ObSpanCtx *span;
|
||||
LIST *next;
|
||||
LIST *span_elem = trace->current_span_list_;
|
||||
while(OB_NOT_NULL(span_elem)) {
|
||||
LIST *span_elem;
|
||||
while(OB_NOT_NULL(trace->current_span_list_)) {
|
||||
span_elem = trace->current_span_list_;
|
||||
span = (ObSpanCtx *)span_elem->data;
|
||||
next = span_elem->next;
|
||||
if (0 != span->end_ts_) {
|
||||
trace->current_span_list_ = list_delete(trace->current_span_list_, span_elem);
|
||||
trace->free_span_list_ = list_add(trace->free_span_list_, span_elem);
|
||||
}
|
||||
// All spans are recycled after a statement in the transaction ends
|
||||
trace->current_span_list_ = list_delete(trace->current_span_list_, span_elem);
|
||||
trace->free_span_list_ = list_add(trace->free_span_list_, span_elem);
|
||||
span->tags_ = NULL;
|
||||
span_elem = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1640,15 +1799,30 @@ void append_tag(ObTrace *trace, ObSpanCtx *span, uint16_t tag_type, const char *
|
||||
// do nothing
|
||||
} else if (OB_ISNULL(str)) {
|
||||
// do nothing
|
||||
} else if (trace->offset_ + sizeof(ObTagCtx) > trace->buffer_size_) {
|
||||
} else if (OB_ISNULL(trace->free_tag_list_.next_)) {
|
||||
// do nothing
|
||||
} else {
|
||||
ObTagCtx *tag = (ObTagCtx *)(trace->data_ + trace->offset_);
|
||||
// get tag from free tag list
|
||||
ObTagCtx *tag = (ObTagCtx *)(trace->free_tag_list_.next_);
|
||||
trace->free_tag_list_.next_ = tag->next_;
|
||||
// append tag into span
|
||||
tag->next_ = span->tags_;
|
||||
span->tags_ = tag;
|
||||
tag->tag_type_ = tag_type;
|
||||
tag->data_ = str;
|
||||
trace->offset_ += sizeof(ObTagCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void reset_tag(ObTrace *trace, ObSpanCtx *span, ObTagCtx *tag)
|
||||
{
|
||||
UNUSED(span);
|
||||
if (OB_ISNULL(trace)) {
|
||||
// do nothing
|
||||
} else if (OB_ISNULL(tag)) {
|
||||
// do nothing
|
||||
} else {
|
||||
tag->next_ = trace->free_tag_list_.next_;
|
||||
trace->free_tag_list_.next_ = tag;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -389,8 +389,6 @@ uchar *fill_protocol20_header(Ob20Protocol *ob20protocol, size_t len, size_t pkt
|
||||
{
|
||||
size_t pos = 0;
|
||||
|
||||
// printf("write request %u\n", ob20protocol->header.request_id);
|
||||
|
||||
int3store(&buffer[NET_HEADER_SIZE], complen);
|
||||
int3store(&buffer[pos], len);
|
||||
buffer[3]=(uchar) (pkt_nr);
|
||||
@ -417,6 +415,22 @@ uchar *fill_protocol20_header(Ob20Protocol *ob20protocol, size_t len, size_t pkt
|
||||
int2store(&buffer[pos], ob20protocol->header.header_checksum);
|
||||
pos += 2;
|
||||
|
||||
#ifdef DEBUG_OB20
|
||||
printf("////////////////begin ob20 pkt write[%u]//////////////////////////\n", pkt_nr);
|
||||
printf("mysql pkt_len is %u\n", len);
|
||||
printf("mysql pkt_nr is %u\n", pkt_nr);
|
||||
printf("complen is %u\n", complen);
|
||||
printf("magic_num is %u\n", ob20protocol->header.magic_num);
|
||||
printf("version is %u\n", ob20protocol->header.version);
|
||||
printf("connection_id is %u\n", ob20protocol->header.connection_id);
|
||||
printf("request_id is %u\n", ob20protocol->header.request_id);
|
||||
printf("ob20 pkt_seq is %u\n", ob20protocol->header.pkt_seq);
|
||||
printf("ob20 payload_len is %u\n", ob20protocol->header.payload_len);
|
||||
printf("flag is %u\n", ob20protocol->header.flag.flags);
|
||||
printf("header checksum is %u\n", ob20protocol->header.header_checksum);
|
||||
printf("////////////////end ob20 pkt write[%u]//////////////////////////\n", pkt_nr);
|
||||
#endif
|
||||
|
||||
return buffer + pos;
|
||||
}
|
||||
|
||||
@ -468,22 +482,6 @@ int decode_protocol20_header(Ob20Protocol *ob20protocol, uchar *buffer, uint32_t
|
||||
crc16 = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_OB20
|
||||
printf("////////////////begin ob20 pkt [%u]//////////////////////////\n", pkt_nr);
|
||||
printf("mysql pkt_len is %u\n", pkt_len);
|
||||
printf("mysql pkt_nr is %u\n", pkt_nr);
|
||||
printf("complen is %u\n", complen);
|
||||
printf("magic_num is %u\n", magic_num);
|
||||
printf("version is %u\n", version);
|
||||
printf("connection_id is %u\n", connection_id);
|
||||
printf("request_id is %u\n", request_id);
|
||||
printf("ob20 pkt_seq is %u\n", pkt_seq);
|
||||
printf("ob20 payload_len is %u\n", payload_len);
|
||||
printf("flag is %u\n", flag.flags);
|
||||
printf("header checksum is %u\n", header_checksum);
|
||||
printf("////////////////end ob20 pkt [%u]//////////////////////////\n", pkt_nr);
|
||||
#endif
|
||||
|
||||
if (crc16 != header_checksum) {
|
||||
ret = 1; // error
|
||||
} else if (magic_num != ob20protocol->header.magic_num) {
|
||||
@ -495,10 +493,8 @@ int decode_protocol20_header(Ob20Protocol *ob20protocol, uchar *buffer, uint32_t
|
||||
} else if (request_id != ob20protocol->header.request_id) {
|
||||
ret = 1; // error
|
||||
} else {
|
||||
//check request id and pkt_seq
|
||||
ob20protocol->header.pkt_seq++;
|
||||
if (pkt_seq != ob20protocol->header.pkt_seq) {
|
||||
// printf("pkt_seq check error, local is %u, header is %u\n", ob20protocol->header.pkt_seq, pkt_seq);
|
||||
ret = 1; // error
|
||||
} else {
|
||||
ob20protocol->header.flag = flag;
|
||||
@ -509,6 +505,26 @@ int decode_protocol20_header(Ob20Protocol *ob20protocol, uchar *buffer, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_OB20
|
||||
printf("////////////////begin ob20 pkt read[%u]//////////////////////////\n", pkt_nr);
|
||||
printf("mysql pkt_len is %u\n", pkt_len);
|
||||
printf("mysql pkt_nr is %u\n", pkt_nr);
|
||||
printf("complen is %u\n", complen);
|
||||
printf("magic_num is %u\n", magic_num);
|
||||
printf("version is %u\n", version);
|
||||
printf("connection_id is %u\n", connection_id);
|
||||
printf("request_id is %u\n", request_id);
|
||||
printf("ob20 pkt_seq is %u\n", pkt_seq);
|
||||
printf("ob20 payload_len is %u\n", payload_len);
|
||||
printf("flag is %u\n", flag.flags);
|
||||
printf("header checksum is %u\n", header_checksum);
|
||||
|
||||
if (0 != ret) {
|
||||
printf("decode header error\n");
|
||||
}
|
||||
printf("////////////////end ob20 pkt read[%u]//////////////////////////\n", pkt_nr);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -517,7 +533,6 @@ int extrainfo_serialize_flt(char *buf, const int64_t len, int64_t *ppos, void *d
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t pos = *ppos;
|
||||
FLTValueData *flt_data = (FLTValueData *)data;
|
||||
// data是flt_build_request中生成,函数中需要保证生成string类型
|
||||
int64_t v_len = flt_data->length;
|
||||
|
||||
if (OB_ISNULL(buf)) {
|
||||
@ -579,13 +594,13 @@ int extrainfo_deserialize_flt(const char *buf, const int64_t len, int64_t *ppos,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 对于不识别的key,需要跳过
|
||||
// For unrecognized keys, need to skip
|
||||
pos += tmp_v_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
*ppos = pos; // 最后设置好pos
|
||||
*ppos = pos;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -616,7 +631,7 @@ uchar *fill_protocol20_extra_info(Ob20Protocol *ob20protocol, uchar *buffer, siz
|
||||
while (NULL != ob20protocol->extra_info_list.current) {
|
||||
extra_info_item = ob20protocol->extra_info_list.current->data;
|
||||
if (OB_ISNULL(extra_serialize_funcs[extra_info_item->key].serialize_func)) {
|
||||
// 函数指针没有设置, do nothing, 跳到下一个key
|
||||
// do nothing
|
||||
} if (OB_FAIL(extra_serialize_funcs[extra_info_item->key].serialize_func(packet + pos, buffer_len, &pos, extra_info_item->value))) {
|
||||
return buffer;
|
||||
}
|
||||
@ -669,7 +684,7 @@ int decode_protocol20_extra_info(Ob20Protocol *ob20protocol, uchar *buffer)
|
||||
|
||||
check_pos = pos;
|
||||
if (OB_ISNULL(extra_serialize_funcs[key_type].deserialize_func)) {
|
||||
// 如果函数指针没有设置,直接跳过value不解析
|
||||
// If the function pointer is not set, skip the value directly without parsing
|
||||
pos += value_len;
|
||||
} else if (OB_FAIL(extra_serialize_funcs[key_type].deserialize_func(row, extra_info_len, &pos, ob20protocol, sizeof(*ob20protocol)))) {
|
||||
// error
|
||||
|
@ -189,7 +189,7 @@ inline int decode_i8(const char *buf, const int64_t data_len, int64_t *ppos, int
|
||||
return ret;
|
||||
}
|
||||
|
||||
int encode_i64(char *buf, const int64_t buf_len, int64_t *ppos, int64_t val)
|
||||
inline int encode_i64(char *buf, const int64_t buf_len, int64_t *ppos, int64_t val)
|
||||
{
|
||||
int pos = *ppos;
|
||||
int ret = ((NULL != buf) &&
|
||||
@ -209,7 +209,7 @@ int encode_i64(char *buf, const int64_t buf_len, int64_t *ppos, int64_t val)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int decode_i64(const char *buf, const int64_t data_len, int64_t *ppos, int64_t *val)
|
||||
inline int decode_i64(const char *buf, const int64_t data_len, int64_t *ppos, int64_t *val)
|
||||
{
|
||||
int pos = *ppos;
|
||||
int ret = (NULL != buf && data_len - pos >= 8) ? OB_SUCCESS : OB_ERROR;
|
||||
|
@ -32,7 +32,22 @@
|
||||
longlong strtoll10(const char *nptr, char **endptr, int *error)
|
||||
{
|
||||
longlong ret = 0;
|
||||
char *tmp_endptr = NULL;
|
||||
char tmp_endptr_value;
|
||||
if (NULL != endptr && NULL != *endptr) {
|
||||
tmp_endptr = *endptr;
|
||||
tmp_endptr_value = **endptr;
|
||||
*tmp_endptr = '\0';
|
||||
}
|
||||
/*
|
||||
* Obclient 2.2.2 changes, obclient 1.x uses my_strtoll10, 2.x uses lib c to provide strtoll after rectification,
|
||||
* the two perform differently on endptr, my_strtoll10 will detect endptr and not convert the bit result,
|
||||
* so set 0 here, Compatible with obclient 1.x
|
||||
*/
|
||||
ret = strtoll(nptr, endptr, 10);
|
||||
*error = errno;
|
||||
if (NULL != tmp_endptr) {
|
||||
*tmp_endptr = tmp_endptr_value;
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -1 +1 @@
|
||||
2.2.2
|
||||
2.2.3
|
||||
|
@ -1,7 +1,7 @@
|
||||
CFLAGS= -I../../include
|
||||
CCFLAGS= -I../../include
|
||||
LDFLAGS= -g -L ../../libmariadb/ -lobclnt -lz -lpthread -lgtest
|
||||
BIN=ob20_appinfo_test ob20_trans_test ob20_clientinfo_test ob20_slowquery_test ob20_bigpacket_response_test ob20_bigpacket_request_test
|
||||
BIN=ob20_appinfo_test ob20_trans_test ob20_clientinfo_test ob20_slowquery_test ob20_bigpacket_response_test ob20_bigpacket_request_test ob20_show_trace_test
|
||||
EXEC=env LD_LIBRARY_PATH=../../libmariadb/:${LD_LIBRARY_PATH}
|
||||
all:${BIN}
|
||||
.PHONY:clean
|
||||
@ -11,6 +11,7 @@ ob20_clientinfo_test:ob20_clientinfo_test.c
|
||||
ob20_slowquery_test:ob20_slowquery_test.c
|
||||
ob20_bigpacket_response_test:ob20_bigpacket_response_test.c
|
||||
ob20_bigpacket_request_test:ob20_bigpacket_request_test.c
|
||||
ob20_show_trace_test:ob20_show_trace_test.c
|
||||
# run:
|
||||
# $(EXEC) ./ob_oracle_array_binding_test
|
||||
clean:
|
||||
|
79
unittest/ob20_test/ob20_show_trace_test.c
Normal file
79
unittest/ob20_test/ob20_show_trace_test.c
Normal file
@ -0,0 +1,79 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "mysql.h"
|
||||
#include "test_util.h"
|
||||
#include "ob_object.h"
|
||||
#include "ob_protocol20.h"
|
||||
#include "ob_full_link_trace.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
mysql_library_init(0, NULL, NULL);
|
||||
MYSQL *mysql = mysql_init(NULL);
|
||||
MYSQL_RES *RES;
|
||||
unsigned int timeout = 3000;
|
||||
const char *enable_show_trace = "set ob_enable_show_trace = true;";
|
||||
const char *disable_show_trace = "set ob_enable_show_trace = false;";
|
||||
if (6 == argc) {
|
||||
DBHOST = argv[1];
|
||||
DBUSER = argv[2];
|
||||
DBPASS = argv[3];
|
||||
DBNAME = argv[4];
|
||||
DBPORT = atoi(argv[5]);
|
||||
|
||||
printf("host is %s, user is %s, pass is %s, name is %s, port is %u\n", DBHOST, DBUSER, DBPASS, DBNAME, DBPORT);
|
||||
}
|
||||
|
||||
if (mysql_real_connect(mysql, DBHOST, DBUSER, DBPASS, DBNAME, DBPORT, DBSOCK, DBPCNT) == NULL)
|
||||
{
|
||||
my_log("connect failed: %s, host:%s, port:%d, user:%s, pass:%s, dbname:%s",
|
||||
mysql_error(mysql),DBHOST, DBPORT, DBUSER, DBPASS, DBNAME);
|
||||
mysql_close(mysql);
|
||||
mysql_library_end();
|
||||
return 0;
|
||||
} else {
|
||||
my_log("connect %s:%d using %s succ", DBHOST, DBPORT, DBUSER);
|
||||
}
|
||||
if (mysql_query(mysql, enable_show_trace)) {
|
||||
printf("query error:%s\n", mysql_error(mysql));
|
||||
return 0;
|
||||
} else {
|
||||
RES = mysql_store_result(mysql);
|
||||
}
|
||||
|
||||
if (mysql_query(mysql, "drop table if exists test_trace;")) {
|
||||
printf("query error:%s\n", mysql_error(mysql));
|
||||
return 0;
|
||||
} else {
|
||||
RES = mysql_store_result(mysql);
|
||||
}
|
||||
|
||||
if (mysql_query(mysql, "create table test_trace(c1 number);")) {
|
||||
printf("query error:%s\n", mysql_error(mysql));
|
||||
return 0;
|
||||
} else {
|
||||
RES = mysql_store_result(mysql);
|
||||
}
|
||||
if (mysql_query(mysql, "insert into test_trace values (1);")) {
|
||||
printf("query error:%s\n", mysql_error(mysql));
|
||||
return 0;
|
||||
} else {
|
||||
RES = mysql_store_result(mysql);
|
||||
}
|
||||
if (mysql_query(mysql, "commit")) {
|
||||
printf("query error:%s\n", mysql_error(mysql));
|
||||
return 0;
|
||||
} else {
|
||||
RES = mysql_store_result(mysql);
|
||||
}
|
||||
if (mysql_query(mysql, disable_show_trace)) {
|
||||
printf("query error:%s\n", mysql_error(mysql));
|
||||
return 0;
|
||||
} else {
|
||||
RES = mysql_store_result(mysql);
|
||||
}
|
||||
|
||||
|
||||
mysql_close(mysql);
|
||||
mysql_library_end();
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user