Merge branch 'feature_patch_228' into 'master'

patch228

See merge request oceanbase-ce-publish/obconnector-c!2
This commit is contained in:
致云 2025-01-02 10:58:26 +08:00
commit 6b1835d31e
17 changed files with 669 additions and 332 deletions

View File

@ -144,11 +144,11 @@ 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")
IF(UNIX AND NOT APPLE)
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -z noexecstack -z relro -z now -pie -fPIC -fstack-protector")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -z noexecstack -z relro -z now -pie -fPIC -fstack-protector")
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -z noexecstack -z relro -z now -pie -fPIC -fstack-protector")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -z noexecstack -z relro -z now -pie -fPIC -fstack-protector")
ENDIF()
IF(CMAKE_COMPILER_IS_GNUCC)

View File

@ -1,228 +0,0 @@
resources:
containers:
- container: ubuntu-1804
image: ubuntu:18.04
options: "--name ubuntu-1804 --add-host=mariadb.example.com:127.0.0.1 -v /usr/bin/docker:/tmp/docker:ro"
jobs:
- job: SSLFiles
displayName: 'Creating SSL Files'
pool:
vmImage: 'ubuntu-16.04'
container: $[ variables['containerImage'] ]
steps:
- script: |
java --version
mkdir tmp
chmod 777 .travis/gen-ssl.sh
.travis/gen-ssl.sh mariadb.example.com tmp
cp -R tmp $BUILD_ARTIFACTSTAGINGDIRECTORY
displayName: 'create SSL certificates'
- task: PublishPipelineArtifact@0
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
artifactName: ssl_certs
- job: windowsTest
displayName: 'test windows'
pool:
vmImage: 'windows-2019'
dependsOn:
- SSLFiles
steps:
- task: DownloadPipelineArtifact@2
displayName: 'Download SSL files'
inputs:
artifactName: ssl_certs
targetPath: $(System.DefaultWorkingDirectory)
- task: DownloadPipelineArtifact@2
displayName: 'Download 10.4 server'
inputs:
source: 'specific'
project: '550599d3-6165-4abd-8c86-e3f7e53a1847'
artifact: 'Windows'
pipeline: 3
runVersion: 'latestFromBranch'
runBranch: 'refs/heads/10.4-enterprise'
downloadPath: $(System.DefaultWorkingDirectory)
- script: |
for /f %%a in ('dir /B $(System.DefaultWorkingDirectory)\win_build\mariadb-enterprise-10.*-winx64.msi') do set servername=$(System.DefaultWorkingDirectory)\win_build\%%a
echo %servername%
msiexec /i %servername% INSTALLDIR=c:\projects\server SERVICENAME=mariadb ALLOWREMOTEROOTACCESS=true /qn
c:\projects\server\bin\mysql.exe -e "create database testc" --user=root
displayName: 'install server'
- script: |
echo 127.0.0.1 mariadb.example.com >> %WINDIR%\System32\Drivers\Etc\Hosts
displayName: 'set hostname'
- script: |
cmake -G "Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build . --config RelWithDebInfo
displayName: 'build connector'
- script: |
cd $(System.DefaultWorkingDirectory)\unittest\libmariadb
set MARIADB_PLUGIN_DIR=$(System.DefaultWorkingDirectory)\plugins\lib\RelWithDebInfo
ctest -V
if %ERRORLEVEL% EQU 0 (
echo Success
) else (
echo exit code is %errorlevel%
exit /b %errorlevel%
)
displayName: 'run tests'
env:
MYSQL_TEST_HOST: "mariadb.example.com"
MYSQL_TEST_USER: 'someUser'
MYSQL_TEST_DB: 'testc'
MYSQL_TEST_PORT: 3306
TEST_SSL_CA_FILE: "$(System.DefaultWorkingDirectory)/tmp/server.crt"
TEST_SSL_CLIENT_KEY_FILE: "$(System.DefaultWorkingDirectory)/tmp/client.key"
TEST_SSL_CLIENT_CERT_FILE: "$(System.DefaultWorkingDirectory)/tmp/client.crt"
TEST_SSL_CLIENT_KEYSTORE_FILE: "$(System.DefaultWorkingDirectory)/tmp/client-keystore.p12"
- job: RunInContainer
pool:
vmImage: 'ubuntu-16.04'
displayName: 'test ubuntu bionic'
dependsOn:
- SSLFiles
strategy:
matrix:
ubuntu-1804:
containerImage: ubuntu-1804
containerName: bionic
container: $[variables['containerImage']]
steps:
- task: DownloadPipelineArtifact@2
inputs:
artifactName: ssl_certs
targetPath: $(System.DefaultWorkingDirectory)
- script: /tmp/docker exec -t -u 0 $(containerImage) sh -c "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" -y install sudo"
displayName: Set up sudo
- task: DownloadPipelineArtifact@2
displayName: 'Download 10.4 enterprise server artifact files'
inputs:
source: 'specific'
project: '550599d3-6165-4abd-8c86-e3f7e53a1847'
artifact: '$(containerImage)'
pipeline: 3
runVersion: 'latestFromBranch'
runBranch: 'refs/heads/10.4-enterprise'
downloadPath: $(System.DefaultWorkingDirectory)
- task: DownloadPipelineArtifact@2
displayName: 'Download galera server artifact files'
inputs:
source: 'specific'
project: '550599d3-6165-4abd-8c86-e3f7e53a1847'
artifact: $(containerImage)
runVersion: 'latestFromBranch'
pipeline: 2
runBranch: 'refs/heads/es-mariadb-4.x'
downloadPath: $(System.DefaultWorkingDirectory)
- script: |
tar xf mariadb-enterprise*
sudo ln -fs /usr/share/zoneinfo/UTC /etc/localtime
sudo apt-get update && sudo apt-get install -y --no-install-recommends apt-transport-https ca-certificates tzdata pwgen
export DEBIAN_FRONTEND="noninteractive"
sudo debconf-set-selections <<< "mariadb-server-10.4 mysql-server/root_password password P4ssw@rd"
sudo debconf-set-selections <<< "mariadb-server-10.4 mysql-server/root_password_again password P4ssw@rd"
sudo apt-get update -y
sudo apt-get install --allow-unauthenticated -f -y libssl-dev libaio1 libaio-dev libxml2 libcurl4 curl libc-dev linux-libc-dev libc-dev-bin libdbi-perl rsync socat libnuma1 zlib1g-dev libreadline5 libjemalloc1 libsnappy1v5 libcrack2 gawk lsof psmisc perl libreadline5
cd mariadb-enterprise*/
sudo groupadd mysql
sudo useradd -g mysql mysql
export PROJ_PATH=`pwd`
echo $PROJ_PATH
cat <<EOT >> my.cnf
[mysqld]
port=3306
max_allowed_packet=16M
datadir=$PROJ_PATH/data
socket=/tmp/mysql.sock
user=mysql
ssl-ca=$(System.DefaultWorkingDirectory)/tmp/ca.crt
ssl-cert=$(System.DefaultWorkingDirectory)/tmp/server.crt
ssl-key=$(System.DefaultWorkingDirectory)/tmp/server.key
EOT
sudo chown mysql $PROJ_PATH/my.cnf
sudo tail -n 5000 $PROJ_PATH/my.cnf
sudo chmod 777 $PROJ_PATH
sudo ln -s $PROJ_PATH /usr/local/mysql
sudo ./scripts/mysql_install_db --defaults-file=$PROJ_PATH/my.cnf --user=mysql
sudo chown -R root .
sudo chown -R mysql data
export PATH=$PATH:$PROJ_PATH/bin/
env:
WORKING_DIR: $(System.DefaultWorkingDirectory)
displayName: 'install server'
- script: |
sudo apt-get install -f -y make cmake
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWITH_SSL=OPENSSL -DCERT_PATH=$(System.DefaultWorkingDirectory)/tmp
make
displayName: 'Build'
- script: |
cd mariadb-enterprise*/
sudo ./bin/mysqld --defaults-file=./my.cnf &
for i in {30..0}; do
if sudo ./bin/mysql -e "SELECT 1" &> /dev/null; then
echo 'MySQL connected...'
break
fi
echo 'MySQL init process in progress...'
sleep 1
done
if [ "$i" = 0 ]; then
echo >&2 'MySQL init process failed.'
sudo ./bin/mysql -e "SELECT 1"
exit 1
fi
sudo ./bin/mysql -e "CREATE DATABASE testc;"
echo "Running tests"
cd ../unittest/libmariadb
ctest -V
if [ $? -ne 0 ]; then
exit 1
fi
cd $(System.DefaultWorkingDirectory)/mariadb-enterprise*/
sudo ./bin/mysqladmin shutdown
env:
MYSQL_TEST_HOST: mariadb.example.com
MYSQL_TEST_DB: testc
MYSQL_TEST_USER: 'someUser'
MYSQL_TEST_PORT: 3306
MYSQL_TEST_TRAVIS: 1
TEST_SSL_CA_FILE: "$(System.DefaultWorkingDirectory)/tmp/server.crt"
TEST_SSL_CLIENT_KEY_FILE: "$(System.DefaultWorkingDirectory)/tmp/client.key"
TEST_SSL_CLIENT_CERT_FILE: "$(System.DefaultWorkingDirectory)/tmp/client.crt"
TEST_SSL_CLIENT_KEYSTORE_FILE: "$(System.DefaultWorkingDirectory)/tmp/client-keystore.p12"
displayName: 'run tests'

View File

@ -39,7 +39,7 @@ static inline uint ma_extended_type_info_rows(const MYSQL *mysql)
static inline uint ma_result_set_rows(const MYSQL *mysql)
{
return ma_has_extended_type_info(mysql) ? 9 : 8;
return ma_has_extended_type_info(mysql) ? 8 : 7;
}
MA_FIELD_EXTENSION *ma_field_extension_deep_dup(MA_MEM_ROOT *memroot,

View File

@ -200,6 +200,7 @@ extern const char *SQLSTATE_UNKNOWN;
typedef struct st_mysql_rows {
struct st_mysql_rows *next; /* list of rows */
MYSQL_ROW data;
unsigned long* data_length;
unsigned long length;
} MYSQL_ROWS;

View File

@ -47,6 +47,13 @@ typedef enum enum_types {
TYPE_SHORT,
TYPE_FLOAT,
TYPE_DOUBLE,
TYPE_NVARCHAR2,
TYPE_OB_NUMBER_FLOAT,
TYPE_OB_TIMESTAMP_NANO,
TYPE_OB_TIMESTAMP_WITH_TIME_ZONE,
TYPE_OB_TIMESTAMP_WITH_LOCAL_TIME_ZONE,
TYPE_OB_INTERVAL_YM,
TYPE_OB_INTERVAL_DS,
TYPE_UNKNOW,
TYPE_MAX
} enum_types;

View File

@ -17,12 +17,13 @@ typedef struct _st_obclient_lb_AddressList {
}ObClientLbAddressList;
typedef struct _st_obclient_lb_config{
int retry_all_downs; //总的次数
int black_remove_strategy; //2001
int black_remove_timeout; //移出黑名单时间
int black_append_strategy; //3002 NORMAL, 3001 RETRYDURATION
int black_append_retrytimes; //单个address次数
int black_append_duration; //时间duration内,执行>= retrytimes次加黑
unsigned int retry_all_downs; //总的次数
unsigned int retry_timeout; // LB 阶段总的超时时间(ms)
unsigned int black_remove_strategy; //2001
unsigned int black_remove_timeout; //移出黑名单时间(ms)
unsigned int black_append_strategy; //3002 NORMAL, 3001 RETRYDURATION
unsigned int black_append_retrytimes; //单个address次数
unsigned int black_append_duration; //时间duration内(ms),执行>= retrytimes次加黑
unsigned int mysql_connect_timeout;
unsigned int mysql_read_timeout;
@ -42,6 +43,7 @@ typedef struct _st_obclient_lb_config{
my_bool mysql_opt_interactive;
my_bool mysql_report_data_truncation;
my_bool mysql_opt_reconnect;
char* mysql_read_default_file;
my_bool mysql_opt_use_ssl;
my_bool mysql_opt_ssl_verify_server_cert;
@ -59,6 +61,10 @@ typedef struct _st_obclient_lb_config{
MYSQL* ob_mysql_real_connect(MYSQL* mysql, const char* tns_name, ObClientLbAddressList *addr_list, ObClientLbConfig *config,
const char *user, const char *passwd, const char *db, const char *unix_socket, unsigned long client_flag, ObClientLbAddress* success);
//addr_list [fe80::42:acff:fe11:2%eth0]:38884,[xxx.xxx.xxx.xxx]:2222,xxx.xxx.xxx.xxx:38884
MYSQL* ob_mysql_real_connect2(MYSQL* mysql, const char* tns_name, const char *addr_list, ObClientLbConfig *config,
const char *user, const char *passwd, const char *db, const char *unix_socket, unsigned long client_flag, char* success, int len_success);
#ifdef __cplusplus
}
#endif

View File

@ -342,6 +342,7 @@ SET(MARIADB_NONBLOCK_SYMBOLS
get_ob_lob_payload_data_len
stmt_get_data_from_lobv2
ob_mysql_real_connect
ob_mysql_real_connect2
ob_get_libobclient_version
ob_set_socket5_proxy
)

View File

@ -1535,6 +1535,7 @@ static ulong get_complex_header_length(enum_types type) {
return sizeof(MYSQL_COMPLEX_BIND_OBJECT);
case TYPE_COLLECTION:
return sizeof(MYSQL_COMPLEX_BIND_ARRAY);
case TYPE_NVARCHAR2:
case TYPE_VARCHAR2:
case TYPE_CHAR:
case TYPE_RAW:
@ -1548,6 +1549,14 @@ static ulong get_complex_header_length(enum_types type) {
case TYPE_FLOAT:
case TYPE_DOUBLE:
return sizeof(MYSQL_COMPLEX_BIND_BASIC);
case TYPE_OB_NUMBER_FLOAT:
return sizeof(MYSQL_COMPLEX_BIND_STRING);
case TYPE_OB_INTERVAL_YM:
case TYPE_OB_INTERVAL_DS:
case TYPE_OB_TIMESTAMP_NANO:
case TYPE_OB_TIMESTAMP_WITH_LOCAL_TIME_ZONE:
case TYPE_OB_TIMESTAMP_WITH_TIME_ZONE:
return sizeof(MYSQL_COMPLEX_BIND_BASIC);
default:
return sizeof(MYSQL_COMPLEX_BIND_BASIC);
}
@ -1671,6 +1680,122 @@ static void fetch_result_double_complex(MYSQL_COMPLEX_BIND_BASIC *header,
return;
}
static void read_binary_interval(int type, ORACLE_INTERVAL *tm, uchar **pos)
{
uint length = net_field_length(pos);
uchar *to = *pos;
ORACLE_INTERVAL *interval = tm;
switch (type)
{
case MYSQL_TYPE_OB_INTERVAL_DS: {
if (length == 14) {
interval->mysql_type = MYSQL_TYPE_OB_INTERVAL_DS;
interval->data_symbol = (to[0] > 0 ? -1 : 1);
interval->data_object.ds_object.ds_day = sint4korr(to + 1);
interval->data_object.ds_object.ds_hour = to[5];
interval->data_object.ds_object.ds_minute = to[6];
interval->data_object.ds_object.ds_second = to[7];
interval->data_object.ds_object.ds_frac_second = sint4korr(to + 8);
interval->data_object.ds_object.ds_day_scale = to[12];
interval->data_object.ds_object.ds_frac_second_scale = to[13];
}
break;
}
case MYSQL_TYPE_OB_INTERVAL_YM: {
if (length == 7) {
interval->mysql_type = MYSQL_TYPE_OB_INTERVAL_YM;
interval->data_symbol = (to[0] > 0 ? -1 : 1);
interval->data_object.ym_object.ym_year = sint4korr(to + 1);
interval->data_object.ym_object.ym_month = to[5];
interval->data_object.ym_object.ym_scale = to[6];
}
break;
}
}
*pos += length;
}
static void fetch_result_ob_interval_complex(MYSQL_COMPLEX_BIND_BASIC *header,
MYSQL_BIND *param,
uchar **row)
{
ORACLE_INTERVAL *tm = NULL;
tm = fetch_result_complex_alloc_space(header, param, sizeof(ORACLE_INTERVAL));
if (NULL == tm) {
return;
}
read_binary_interval(header->buffer_type, tm, row);
return;
}
static void fetch_result_ob_timestamp_complex(MYSQL_COMPLEX_BIND_BASIC *header,
MYSQL_BIND *param,
uchar **row)
{
void *buffer = NULL;
ulong bufferlen = 0;
ulong length = 0;
ulong tz_length = 0;
ulong buffer_offset = 0;
ulong buffer_length = 0;
ORACLE_TIME *tm = NULL;
uchar *to = NULL;
length = net_field_length(row);
bufferlen = sizeof(ORACLE_TIME) + length; //+length 包括TZ信息
buffer = fetch_result_complex_alloc_space((MYSQL_COMPLEX_BIND_HEADER *)header, param, bufferlen);
if (NULL == buffer || length < 12) {
return;
}
to = *row;
tm = (ORACLE_TIME*)buffer;
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 < bufferlen) {
memcpy((char*)buffer + buffer_offset, to, tz_length);
tm->tz_name = (char*)buffer + buffer_offset;
buffer_offset += tz_length;
*((char*)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 < bufferlen) {
memcpy((char*)buffer + buffer_offset, to, tz_length);
tm->tz_abbr = (char*)buffer + buffer_offset;
buffer_offset += tz_length;
*((char*)buffer + buffer_offset) = '\0';
buffer_offset++;
}
to += tz_length;
}
*row = to;
return;
}
static void fetch_result_object_complex(MYSQL_COMPLEX_BIND_OBJECT *header,
MYSQL_BIND *param,
@ -1725,6 +1850,7 @@ static void fetch_result_object_complex(MYSQL_COMPLEX_BIND_OBJECT *header,
header->length = (char*)buffer - (char*)header->buffer;
return;
}
static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
{
uint length= net_field_length(pos);
@ -1850,11 +1976,13 @@ static void fetch_result_complex(MYSQL_BIND *param, void *buffer,
CHILD_TYPE *child, uchar **row)
{
switch (child->type) {
case TYPE_OB_NUMBER_FLOAT:
case TYPE_NUMBER:
{
fetch_result_str_complex((MYSQL_COMPLEX_BIND_STRING *)buffer, param, row);
break;
}
case TYPE_NVARCHAR2:
case TYPE_VARCHAR2:
case TYPE_CHAR:
{
@ -1911,6 +2039,19 @@ static void fetch_result_complex(MYSQL_BIND *param, void *buffer,
fetch_result_double_complex((MYSQL_COMPLEX_BIND_BASIC *)buffer, param, row);
break;
}
case TYPE_OB_INTERVAL_DS:
case TYPE_OB_INTERVAL_YM:
{
fetch_result_ob_interval_complex((MYSQL_COMPLEX_BIND_BASIC *)buffer, param, row);
break;
}
case TYPE_OB_TIMESTAMP_NANO:
case TYPE_OB_TIMESTAMP_WITH_TIME_ZONE:
case TYPE_OB_TIMESTAMP_WITH_LOCAL_TIME_ZONE:
{
fetch_result_ob_timestamp_complex((MYSQL_COMPLEX_BIND_BASIC *)buffer, param, row);
break;
}
default:
*param->error= 1;
break;
@ -1987,6 +2128,11 @@ static uint mysql_type_to_object_type(uint mysql_type)
object_type = TYPE_VARCHAR2;
break;
}
case MYSQL_TYPE_OB_NVARCHAR2:
{
object_type = TYPE_NVARCHAR2;
break;
}
case MYSQL_TYPE_OB_RAW:
{
object_type = TYPE_RAW;
@ -2007,6 +2153,36 @@ static uint mysql_type_to_object_type(uint mysql_type)
object_type = TYPE_COLLECTION;
break;
}
case MYSQL_TYPE_OB_NUMBER_FLOAT:
{
object_type = TYPE_OB_NUMBER_FLOAT;
break;
}
case MYSQL_TYPE_OB_INTERVAL_DS:
{
object_type = TYPE_OB_INTERVAL_DS;
break;
}
case MYSQL_TYPE_OB_INTERVAL_YM:
{
object_type = TYPE_OB_INTERVAL_YM;
break;
}
case MYSQL_TYPE_OB_TIMESTAMP_NANO:
{
object_type = TYPE_OB_TIMESTAMP_NANO;
break;
}
case MYSQL_TYPE_OB_TIMESTAMP_WITH_TIME_ZONE:
{
object_type = TYPE_OB_TIMESTAMP_WITH_TIME_ZONE;
break;
}
case MYSQL_TYPE_OB_TIMESTAMP_WITH_LOCAL_TIME_ZONE:
{
object_type = TYPE_OB_TIMESTAMP_WITH_LOCAL_TIME_ZONE;
break;
}
default:
object_type = TYPE_UNKNOW;
break;
@ -2031,6 +2207,12 @@ static void fill_complex_type(MYSQL_BIND *param, void *buffer,
header->buffer_type = MYSQL_TYPE_VARCHAR;
break;
}
case TYPE_NVARCHAR2:
{
MYSQL_COMPLEX_BIND_STRING *header = (MYSQL_COMPLEX_BIND_STRING *)buffer;
header->buffer_type = MYSQL_TYPE_OB_NVARCHAR2;
break;
}
case TYPE_RAW:
{
MYSQL_COMPLEX_BIND_STRING *header = (MYSQL_COMPLEX_BIND_STRING *)buffer;
@ -2079,6 +2261,42 @@ static void fill_complex_type(MYSQL_BIND *param, void *buffer,
header->buffer_type = MYSQL_TYPE_DOUBLE;
break;
}
case TYPE_OB_NUMBER_FLOAT:
{
MYSQL_COMPLEX_BIND_STRING *header = (MYSQL_COMPLEX_BIND_STRING *)buffer;
header->buffer_type = MYSQL_TYPE_OB_NUMBER_FLOAT;
break;
}
case TYPE_OB_INTERVAL_DS:
{
MYSQL_COMPLEX_BIND_BASIC *header = (MYSQL_COMPLEX_BIND_BASIC *)buffer;
header->buffer_type = MYSQL_TYPE_OB_INTERVAL_DS;
break;
}
case TYPE_OB_INTERVAL_YM:
{
MYSQL_COMPLEX_BIND_BASIC *header = (MYSQL_COMPLEX_BIND_BASIC *)buffer;
header->buffer_type = MYSQL_TYPE_OB_INTERVAL_YM;
break;
}
case TYPE_OB_TIMESTAMP_NANO:
{
MYSQL_COMPLEX_BIND_BASIC *header = (MYSQL_COMPLEX_BIND_BASIC *)buffer;
header->buffer_type = MYSQL_TYPE_OB_TIMESTAMP_NANO;
break;
}
case TYPE_OB_TIMESTAMP_WITH_TIME_ZONE:
{
MYSQL_COMPLEX_BIND_BASIC *header = (MYSQL_COMPLEX_BIND_BASIC *)buffer;
header->buffer_type = MYSQL_TYPE_OB_TIMESTAMP_WITH_TIME_ZONE;
break;
}
case TYPE_OB_TIMESTAMP_WITH_LOCAL_TIME_ZONE:
{
MYSQL_COMPLEX_BIND_BASIC *header = (MYSQL_COMPLEX_BIND_BASIC *)buffer;
header->buffer_type = MYSQL_TYPE_OB_TIMESTAMP_WITH_LOCAL_TIME_ZONE;
break;
}
case TYPE_OBJECT:
{
MYSQL_COMPLEX_BIND_OBJECT *header = (MYSQL_COMPLEX_BIND_OBJECT *)buffer;

View File

@ -946,15 +946,18 @@ static size_t rset_field_offsets[]= {
MYSQL_FIELD *
unpack_fields(const MYSQL *mysql,
MYSQL_DATA *data, MA_MEM_ROOT *alloc, uint fields,
my_bool default_value)
MYSQL_DATA *data, MA_MEM_ROOT *alloc, uint fields, my_bool default_value)
{
#define CHECK_PKT_LENGTH(len1, len2) {if ((len1) > (len2)) goto error;}
#define CHECK_PKT_LENGTH_END(len1, len2) {if ((len1) >= (len2)) goto error;}
MYSQL_ROWS *row;
MYSQL_FIELD *field,*result;
uchar *p; /* use unsigned char for data to avoid convert error for char to uint. */
unsigned int i, field_count= sizeof(rset_field_offsets)/sizeof(size_t)/2;
uchar *complex_type;
ulong len;
uchar *complex_type = NULL;
ulong len = 0;
ulong pkt_len = 0;
field=result=(MYSQL_FIELD*) ma_alloc_root(alloc,sizeof(MYSQL_FIELD)*fields);
if (!result)
@ -1016,27 +1019,32 @@ unpack_fields(const MYSQL *mysql,
if (MYSQL_TYPE_OBJECT == field->type) {
complex_type = (uchar*)row->data[i];
pkt_len = row->data_length[i];
len=(ulong) net_field_length(&complex_type);
field->owner_name_length = len;
if (0 == len) {
field->owner_name = NULL;
} else {
field->owner_name = (unsigned char *)ma_memdup_root(alloc, (char*)complex_type, len+1);
CHECK_PKT_LENGTH(len, (pkt_len - ((char*)complex_type - row->data[i])));
field->owner_name = (unsigned char *)ma_memdup_root(alloc, (char*)complex_type, len + 1);
field->owner_name[len] = 0;
complex_type += len;
}
CHECK_PKT_LENGTH_END((char*)complex_type - row->data[i], (long)pkt_len);
len=(ulong) net_field_length(&complex_type);
field->type_name_length = len;
if (0 == len) {
field->type_name = NULL;
} else {
CHECK_PKT_LENGTH(len, (pkt_len - ((char*)complex_type - row->data[i])));
field->type_name = (unsigned char *)ma_memdup_root(alloc, (char*)complex_type, len+1);
field->type_name[len] = 0;
complex_type += len;
}
CHECK_PKT_LENGTH_END((char*)complex_type - row->data[i], (long)pkt_len);
field->version = (ulong) net_field_length(&complex_type);
if (0 == len) {
@ -1044,6 +1052,7 @@ unpack_fields(const MYSQL *mysql,
complex_type++;
if (MYSQL_TYPE_OBJECT == field->elem_type) {
CHECK_PKT_LENGTH_END((char*)complex_type - row->data[i], (long)pkt_len);
len=(ulong) net_field_length(&complex_type);
field->elem_owner_name_length = len;
if (0 == len) {
@ -1051,35 +1060,53 @@ unpack_fields(const MYSQL *mysql,
}
else
{
field->elem_owner_name = (unsigned char *)ma_memdup_root(alloc, (char *)complex_type, len);
CHECK_PKT_LENGTH(len, (pkt_len - ((char*)complex_type - row->data[i])));
field->elem_owner_name = (unsigned char *)ma_memdup_root(alloc, (char *)complex_type, len + 1);
field->elem_owner_name[len] = 0;
complex_type += len;
}
CHECK_PKT_LENGTH_END((char*)complex_type - row->data[i], (long)pkt_len);
len=(ulong) net_field_length(&complex_type);
field->elem_type_name_length = len;
if (0 == len) {
field->elem_type_name = NULL;
} else {
field->elem_type_name = (unsigned char *)ma_memdup_root(alloc, (char*)complex_type, len);
CHECK_PKT_LENGTH(len, (pkt_len - ((char*)complex_type - row->data[i])));
field->elem_type_name = (unsigned char *)ma_memdup_root(alloc, (char*)complex_type, len+1);
field->elem_type_name[len] = 0;
complex_type += len;
}
CHECK_PKT_LENGTH_END((char*)complex_type - row->data[i], (long)pkt_len);
field->elem_version = (ulong) net_field_length(&complex_type);
}
}
len = (ulong) net_field_length(&complex_type);
if (default_value && len > 0) {
field->def=ma_memdup_root(alloc, (char*)complex_type, len);
} else {
field->def=0;
//object 检查下长度,这里后面应该是没有数据了,防止core
if ((char*)complex_type - row->data[i] > (long)pkt_len)
{
//CHECK_PKT_LENGTH_END((char*)complex_type - row->data[i], pkt_len);
len = (ulong)net_field_length(&complex_type);
if (default_value && len > 0 && len != NULL_LENGTH) {
field->def = ma_memdup_root(alloc, (char*)complex_type, len);
} else {
field->def = 0;
}
}
} else {
if (default_value && row->data[i]) {
field->def=ma_strdup_root(alloc,(char*) row->data[i]);
/*
mthd_my_read_query_result ma_result_set_rows 9:8->8:7, row->data[i]length
PS协议/object处理,row->data[i]lengthlength
*/
if (default_value && row->data[i] && row->data_length[i] > 0) {
len = (ulong)net_field_length(&(row->data[i]));
if (default_value && len > 0 && len != NULL_LENGTH) {
field->def = ma_strdup_root(alloc, (char*)row->data[i]);
} else {
field->def = 0;
}
} else {
field->def=0;
field->def = 0;
}
}
field->def_length= 0;
@ -1580,7 +1607,7 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
uint field;
ulong pkt_len;
ulong len;
uchar *cp;
uchar *cp, *end_cp;
char *to, *end_to;
MYSQL_DATA *result;
MYSQL_ROWS **prev_ptr,*cur;
@ -1603,6 +1630,7 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
while (*(cp=net->read_pos) != 254 || pkt_len >= 8)
{
end_cp = cp + pkt_len;
if (mysql_fields) {
for (field=0 ; field < fields ; field++) {
if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH) {
@ -1632,17 +1660,21 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
}
}
cp = net->read_pos;
end_cp = cp + pkt_len;
result->rows++;
if (!(cur= (MYSQL_ROWS*) ma_alloc_root(&result->alloc,
sizeof(MYSQL_ROWS))) ||
if (!(cur= (MYSQL_ROWS*) ma_alloc_root(&result->alloc, sizeof(MYSQL_ROWS))) ||
!(cur->data= ((MYSQL_ROW)
ma_alloc_root(&result->alloc,
(fields+1)*sizeof(char *)+fields+pkt_len))))
ma_alloc_root(&result->alloc, (fields+1)*sizeof(char *)+fields+pkt_len))) ||
!(cur->data_length= (unsigned long*)
ma_alloc_root(&result->alloc, (fields + 1) * sizeof(unsigned long)))
)
{
free_rows(result);
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return(0);
}
memset(cur->data, 0, (fields + 1) * sizeof(char *) + fields + pkt_len);
memset(cur->data_length, 0, (fields + 1) * sizeof(unsigned long));
*prev_ptr=cur;
prev_ptr= &cur->next;
to= (char*) (cur->data+fields+1);
@ -1652,6 +1684,7 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH)
{ /* null field */
cur->data[field] = 0;
cur->data_length[field] = 0;
}
else
{
@ -1682,6 +1715,7 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
to+=convert_len+1;
cp+=len;
len = convert_len;
cur->data_length[field] = len;
is_done = 1;
} else if (mysql_fields[field].type == MYSQL_TYPE_OB_RAW) {
uchar *end = cp + len;
@ -1691,6 +1725,7 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
(*to++)=0;
len *= 2;
cur->data_length[field] = len;
is_done = 1;
} else if (mysql_fields[field].type == MYSQL_TYPE_OB_INTERVAL_YM
|| mysql_fields[field].type == MYSQL_TYPE_OB_INTERVAL_DS) {
@ -1702,6 +1737,7 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
to+=convert_len+1;
cp+=len;
len = convert_len;
cur->data_length[field] = len;
is_done = 1;
}
}
@ -1709,6 +1745,7 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
memcpy(to,(char*) cp,len); to[len]=0;
to+=len+1;
cp+=len;
cur->data_length[field] = len;
is_done = 1;
}
@ -1719,8 +1756,12 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
}
}
}
memcpy(to, (char *)cp, (ulong)(end_to - to));
convert_len = (ulong)(end_cp - cp >= 0 ? (end_cp - cp) : 0);
memcpy(to, (char *)cp, convert_len);
//convert_len = (ulong)(end_to - to >= 0 ? (end_to - to) : 0);
//memcpy(to, (char *)cp, (ulong)(end_to - to));
cur->data[field]=to; /* End of last field */
cur->data_length[field] = convert_len; //convert_len
if ((pkt_len=ma_net_safe_read(mysql)) == packet_error)
{
free_rows(result);
@ -2147,7 +2188,7 @@ ma_set_ob_connect_attrs(MYSQL *mysql)
cap |= OBCLIENT_CAP_PROXY_LOCAL_INFILES;
}
snprintf(cap_buf, OB_MAX_UINT64_BUF_LEN, "%lu", cap);
snprintf(cap_buf, OB_MAX_UINT64_BUF_LEN, "%llu", cap);
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");
@ -2156,7 +2197,7 @@ ma_set_ob_connect_attrs(MYSQL *mysql)
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);
snprintf(caplob_buf, OB_MAX_UINT64_BUF_LEN, "%llu", caplob);
rc += mysql_optionsv(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, OB_MYSQL_LOB_LOCATOR_V2, caplob_buf);
}
if (mysql->proxy_user && mysql->proxy_user[0]) {

View File

@ -1275,6 +1275,35 @@ static void store_param_oracle_timestamp_tz_complex(unsigned char **pos, MYSQL_C
*(*pos - length - 1) = length;
}
static void store_param_oracle_interval_complex(unsigned char **pos, MYSQL_COMPLEX_BIND_HEADER *param)
{
ORACLE_INTERVAL *interval = (ORACLE_INTERVAL *)param->buffer;
uchar buff[20] = {0};
int len = 0;
if (param->buffer_type == MYSQL_TYPE_OB_INTERVAL_YM) {
len = 8;
buff[0] = 7;
buff[1] = interval->data_symbol > 0 ? 0 : 1; //正 0, 负 1
int4store(buff + 2, interval->data_object.ym_object.ym_year);
buff[6] = (uchar)(interval->data_object.ym_object.ym_month);
buff[7] = (uchar)(interval->data_object.ym_object.ym_scale);
} else if (param->buffer_type == MYSQL_TYPE_OB_INTERVAL_DS) {
len = 15;
buff[0] = 14;
buff[1] = interval->data_symbol > 0 ? 0 : 1; //正 0, 负 1
int4store(buff + 2, interval->data_object.ds_object.ds_day);
buff[6] = (uchar)(interval->data_object.ds_object.ds_hour);
buff[7] = (uchar)(interval->data_object.ds_object.ds_minute);
buff[8] = (uchar)(interval->data_object.ds_object.ds_second);
int4store(buff + 9, interval->data_object.ds_object.ds_frac_second);
buff[13] = (uchar)(interval->data_object.ds_object.ds_day_scale);
buff[14] = (uchar)(interval->data_object.ds_object.ds_frac_second_scale);
}
memcpy((char *)*pos, buff, len);
(*pos) += len;
}
static void store_param_str_complex(unsigned char **pos, MYSQL_COMPLEX_BIND_STRING *param)
{
/* param->length is always set in mysql_stmt_bind_param */
@ -1453,6 +1482,10 @@ static void store_param_all_complex(unsigned char **pos, MYSQL_COMPLEX_BIND_HEAD
case MYSQL_TYPE_OB_TIMESTAMP_WITH_TIME_ZONE:
store_param_oracle_timestamp_tz_complex(pos, header);
break;
case MYSQL_TYPE_OB_INTERVAL_YM:
case MYSQL_TYPE_OB_INTERVAL_DS:
store_param_oracle_interval_complex(pos, header);
break;
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
@ -1807,6 +1840,8 @@ int convert_type_to_complex(enum enum_field_types type)
case MYSQL_TYPE_CURSOR:
case MYSQL_TYPE_ORA_BLOB:
case MYSQL_TYPE_ORA_CLOB:
case MYSQL_TYPE_OB_INTERVAL_DS:
case MYSQL_TYPE_OB_INTERVAL_YM:
case MYSQL_TYPE_OB_TIMESTAMP_NANO:
case MYSQL_TYPE_OB_TIMESTAMP_WITH_TIME_ZONE:
case MYSQL_TYPE_OB_TIMESTAMP_WITH_LOCAL_TIME_ZONE:
@ -3160,6 +3195,8 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned lon
if (length == (unsigned long) -1)
length= (unsigned long)strlen(query);
free_old_query(mysql); //new query clean old feilds
/* clear flags */
CLEAR_CLIENT_STMT_ERROR(stmt);
CLEAR_CLIENT_ERROR(stmt->mysql);
@ -3370,6 +3407,12 @@ static int madb_alloc_stmt_fields(MYSQL_STMT *stmt)
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return(1);
}
if (!stmt->mysql->fields) {
if (stmt->mysql->net.last_errno == 0)
SET_CLIENT_STMT_ERROR(stmt, CR_NEW_STMT_METADATA, SQLSTATE_UNKNOWN, 0);
return(1);
}
memset(stmt->fields, 0, sizeof(MYSQL_FIELD) * stmt->mysql->field_count);
stmt->field_count= stmt->mysql->field_count;
@ -3558,8 +3601,8 @@ int stmt_read_execute_response(MYSQL_STMT *stmt)
/* Only cursor read */
stmt->default_rset_handler = _mysql_stmt_use_result;
} else if (stmt->flags & CURSOR_TYPE_READ_ONLY)
stmt->state = MYSQL_STMT_WAITING_USE_OR_STORE;
} else if ((stmt->flags & CURSOR_TYPE_READ_ONLY) && !(stmt->upsert_status.server_status & SERVER_MORE_RESULTS_EXIST))
{
/*
We have asked for CURSOR but got no cursor, because the condition
@ -3571,6 +3614,8 @@ int stmt_read_execute_response(MYSQL_STMT *stmt)
precached on client and server's resources are freed.
*/
if (stmt->mysql->status == MYSQL_STATUS_GET_RESULT)
stmt->mysql->status = MYSQL_STATUS_STMT_RESULT;
/* preferred is buffered read */
if (mysql_stmt_store_result(stmt))
return 1;
@ -3590,8 +3635,9 @@ int stmt_read_execute_response(MYSQL_STMT *stmt)
} else {
stmt->mysql->status= MYSQL_STATUS_STMT_RESULT;
}
stmt->state = MYSQL_STMT_WAITING_USE_OR_STORE;
}
stmt->state= MYSQL_STMT_WAITING_USE_OR_STORE;
//stmt->state= MYSQL_STMT_WAITING_USE_OR_STORE;
/* in certain cases parameter types can change: For example see bug
4026 (SELECT ?), so we need to update field information */
// if (mysql->field_count == stmt->field_count)
@ -4523,7 +4569,7 @@ uint32 ob_crc32(uint64_t crc, const char *buf, int64_t len)
return crc64 & 0xffffffff;
}
uint64 ob_crc64(uint64_t crc, const char *buf, int64_t len)
uint64_t ob_crc64(uint64_t crc, const char *buf, int64_t len)
{
uint64_t crc64 = crc64_sse42_dispatch(crc, buf, len);
return crc64;
@ -5248,6 +5294,8 @@ mysql_stmt_prepare_v2(MYSQL_STMT *stmt, const char *query,
if (length == (unsigned long) -1)
length= (unsigned long)strlen(query);
free_old_query(mysql); //new query clean old feilds
/* clear flags */
CLEAR_CLIENT_STMT_ERROR(stmt);
CLEAR_CLIENT_ERROR(stmt->mysql);
@ -6139,7 +6187,7 @@ mysql_stmt_read_piece_data(MYSQL_STMT *stmt, unsigned int param_number,
*param->error = 1;
} else {
ulong copy_length = MIN(*ret_data_len, param->buffer_length);
memcpy(param->buffer, (char *)*row, copy_length);
memcpy(param->buffer, (char *)row, copy_length);
*param->error = copy_length < *ret_data_len;
}
*param->length = *ret_data_len;

View File

@ -207,6 +207,26 @@ static enum_types convert_type(const char *type) {
return TYPE_DATE;
} else if (!strcmp(type, "RAW")) {
return TYPE_RAW;
} else if (!strcmp(type, "NVARCHAR2")) {
return TYPE_NVARCHAR2;
} else if (!strcmp(type, "FLOAT")) {
return TYPE_OB_NUMBER_FLOAT;
} else if (!strncmp(type, "INTERVAL YEAR", 13)) {
return TYPE_OB_INTERVAL_YM;
} else if (!strncmp(type, "INTERVAL DAY", 12)) {
return TYPE_OB_INTERVAL_DS;
} else if (!strncmp(type, "TIMESTAMP", 9)) {
if (strstr(type, "WITH TIME ZONE")) {
return TYPE_OB_TIMESTAMP_WITH_TIME_ZONE;
} else if (strstr(type, "WITH LOCAL TIME ZONE")) {
return TYPE_OB_TIMESTAMP_WITH_LOCAL_TIME_ZONE;
} else {
return TYPE_OB_TIMESTAMP_NANO;
}
} else if (!strcmp(type, "BINARY_FLOAT")) {
return TYPE_FLOAT;
} else if (!strcmp(type, "BINARY_DOUBLE")) {
return TYPE_DOUBLE;
} else {
return TYPE_MAX;
}

View File

@ -44,8 +44,8 @@ typedef struct _st_ob_lb_address_list {
}ObLbAddressList;
typedef struct _st_connect_info {
int connect_cnt;
int connect_max;
unsigned int connect_cnt;
unsigned int connect_max;
int64_t *connect_list;
}ConnectInfo;
@ -137,8 +137,8 @@ static ObLbAddress* get_ob_address_by_address_list(ObLbAddressList *addr_list)
break;
}
case OBCLIENT_LB_OPTION_SERVERAFFINITY: {
int rand_number = (int)rand() % weight + 1;
int index = 0;
int rand_number = (int)rand() % weight + 1;
for (index = 0; index < valid_cnt; ++index) {
rand_number -= addr_list->add_arr[idxarr[index]].weight;
if (index == valid_cnt - 1 || rand_number <= 0) {
@ -192,7 +192,7 @@ static void check_ob_address_black(ObLbAddress * address, ObClientLbConfig *conf
int len = info->connect_cnt;
int64_t *list = info->connect_list;
int64_t curtime = get_current_time_us();
int64_t duration = config->black_append_duration * 1000;// ��λmsתΪus
int64_t duration = config->black_append_duration * 1000;// µ¥Î»msתΪus
for (idx = 0; idx < len; idx++) {
if (curtime - list[idx] <= duration) {
break;
@ -236,16 +236,74 @@ static void check_ob_address_white(ObLbAddressList * addr_list, ObClientLbConfig
}
}
static int init_oblb_addresslist(ObLbAddressList* list, ObClientLbAddressList* addrlist) {
static int init_oblb_addresslist_str(ObLbAddressList* list, char* str, ObClientLBOption oblb_strategy) {
int ret = 0;
if (NULL == list || NULL == str) {
ret = -1;
} else {
char *p = str, *s = NULL, *e = NULL;
int count = 1;
while (p && *p) {
if (*p++ == ',')
count++;
}
if (OB_ISNULL(list->add_arr = (ObLbAddress*)calloc(1, count * sizeof(ObLbAddress)))) {
ret = -1;
} else {
unsigned int i = 0;
my_bool valid = 0;
my_bool instring = 0;
int idx = 0;
int port = 0;
p = str;
while (p && *p) {
if (instring == 0 && *p == '[') {
instring = 1;
s = p + 1;
valid = 0;
} else if (instring == 1 && *p == ']') {
instring = 0;
e = p;
valid = 1;
} else if (instring == 0 && *p == ',') {
s = p + 1;
e = NULL;
valid = 0;
} else if (instring == 0 && *p == ':') {
if (valid == 0) {
e = p;
}
if (s && e) {
memcpy(list->add_arr[idx].host, s, e - s);
list->add_arr[idx].port = atoi(p + 1);
list->add_arr[i].weight = 1;
list->add_arr[i].state = OBCLIENT_LB_WHITE;
idx++;
s = NULL;
e = NULL;
valid = 0;
}
}
p++;
}
list->count = idx;
list->rotation_flag = 0;
list->option = oblb_strategy;
}
}
return ret;
}
static int init_oblb_addresslist(ObLbAddressList* list, ObClientLbAddressList* addrlist, ObClientLBOption oblb_strategy) {
int ret = 0;
if (!list || !addrlist || !addrlist->address_list || addrlist->address_list_count <= 0) {
ret = -1;
} else if (OB_ISNULL(list->add_arr = (ObLbAddress*)malloc(addrlist->address_list_count * sizeof(ObLbAddress)))) {
} else if (OB_ISNULL(list->add_arr = (ObLbAddress*)calloc(1, addrlist->address_list_count * sizeof(ObLbAddress)))) {
ret = -1;
} else {
unsigned int i = 0;
memset(list->add_arr, 0, addrlist->address_list_count * sizeof(ObLbAddress));
for (i = 0; i < addrlist->address_list_count; i++) {
memcpy(list->add_arr[i].host, addrlist->address_list[i].host, strlen(addrlist->address_list[i].host));
list->add_arr[i].port = addrlist->address_list[i].port;
@ -254,19 +312,18 @@ static int init_oblb_addresslist(ObLbAddressList* list, ObClientLbAddressList* a
}
list->count = addrlist->address_list_count;
list->rotation_flag = 0;
list->option = OBCLIENT_LB_OPTION_ROTATION;
list->option = oblb_strategy;
}
return ret;
}
static int init_oblb_addresslist_tns(ObLbAddressList* list, ObClientAddressList* addrlist) {
static int init_oblb_addresslist_tns(ObLbAddressList* list, ObClientAddressList* addrlist, ObClientLBOption oblb_strategy) {
int ret = 0;
if (!list || !addrlist || !addrlist->address || addrlist->address_count <= 0) {
ret = -1;
} else if (OB_ISNULL(list->add_arr = (ObLbAddress*)malloc(addrlist->address_count * sizeof(ObLbAddress)))){
} else if (OB_ISNULL(list->add_arr = (ObLbAddress*)calloc(1, addrlist->address_count * sizeof(ObLbAddress)))){
ret = -1;
} else {
unsigned int i = 0;
memset(list->add_arr, 0, addrlist->address_count * sizeof(ObLbAddress));
for (i = 0; i < addrlist->address_count; i++) {
memcpy(list->add_arr[i].host, addrlist->address[i].host, addrlist->address[i].host_len);
list->add_arr[i].port = addrlist->address[i].port;
@ -275,18 +332,57 @@ static int init_oblb_addresslist_tns(ObLbAddressList* list, ObClientAddressList*
}
list->count = addrlist->address_count;
list->rotation_flag = 0;
list->option = addrlist->oblb_strategy;
if (addrlist->oblb_strategy != OBCLIENT_LB_OPTION_RANDOM &&
addrlist->oblb_strategy != OBCLIENT_LB_OPTION_SERVERAFFINITY &&
addrlist->oblb_strategy != OBCLIENT_LB_OPTION_ROTATION) {
list->option = oblb_strategy;
} else {
list->option = addrlist->oblb_strategy;
}
}
return ret;
}
static void release_oblb_addresslist(ObLbAddressList* list) {
if (list && list->add_arr) {
free(list->add_arr);
list->add_arr = NULL;
list->count = 0;
}
}
static int post_session_variable(MYSQL *mysql, char *session_variable, int session_variable_len)
{
int ret = 0;
if (NULL == mysql) {
ret = -1;
} else if (0 == session_variable_len) {
;
} else {
char post_sql[1024] = { 0 };
int post_sql_len = snprintf(post_sql, 1024, "set %.*s", session_variable_len, session_variable);
if (post_sql_len < 0) {
ret = -1;
} else if (mysql_real_query(mysql, post_sql, post_sql_len)) {
ret = -1;
}
}
return ret;
}
static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, ObClientLbConfig *config,
static MYSQL* connect_by_addresslist(MYSQL* mysql, int64_t lb_starttime, ObLbAddressList *addr_list, ObClientLbConfig *config,
const char *user, const char *passwd, const char *db, const char *unix_socket, unsigned long client_flag, ObClientLbAddress* success)
{
ObLbAddress *address = NULL;
MYSQL* tmp = NULL;
unsigned int i = 0;
int err = 0;
char buf[128] = { 0 };
int64_t lb_endtime = 0;
my_bool default_report_data_truncation = 1;
unsigned int default_local_infile = 2;
unsigned int default_connect_timeout = 6;//s
unsigned int mysql_connect_timeout = 0;
unsigned int mysql_read_timeout = 0;
@ -307,6 +403,7 @@ static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, O
my_bool mysql_opt_interactive = 0;
my_bool mysql_report_data_truncation = 0;
my_bool mysql_opt_reconnect = 0;
char* mysql_read_default_file = NULL;
my_bool mysql_opt_use_ssl = 0;
my_bool mysql_opt_ssl_verify_server_cert = 0;
@ -318,8 +415,9 @@ static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, O
char *mysql_opt_ssl_crl = NULL;
char *mysql_opt_ssl_crlpath = NULL;
char *mysql_opt_tls_version = NULL;
if (mysql == NULL || addr_list == NULL || config == NULL || addr_list->add_arr == NULL || addr_list->count <= 0) {
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, "invalid handle or address list is zero.");
return NULL;
}
@ -328,13 +426,6 @@ static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, O
addr_list->option != OBCLIENT_LB_OPTION_SERVERAFFINITY) {
addr_list->option = OBCLIENT_LB_OPTION_ROTATION;
}
if (config->black_append_strategy != OBCLIENT_LB_OPTION_NORMAL &&
config->black_append_strategy != OBCLIENT_LB_OPTION_RETRY_DERUATION) {
config->black_append_strategy = OBCLIENT_LB_OPTION_NORMAL;
}
if (config->retry_all_downs <= 0) config->retry_all_downs = addr_list->count;
if (config->black_append_duration <= 0) config->black_append_duration = 60 * 1000;
if (config->black_append_retrytimes <= 0) config->black_append_retrytimes = 1;
for (i = 0; i < addr_list->count; i++) {
addr_list->add_arr[i].state = OBCLIENT_LB_WHITE;
@ -344,6 +435,8 @@ static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, O
}
init_connect_info(&(addr_list->add_arr[i]));
}
lb_endtime = lb_starttime + config->retry_timeout * 1000;
srand(time(NULL));
//init mysql options
mysql_connect_timeout = config->mysql_connect_timeout;
@ -364,6 +457,7 @@ static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, O
mysql_opt_interactive = config->mysql_opt_interactive;
mysql_report_data_truncation = config->mysql_report_data_truncation;
mysql_opt_reconnect = config->mysql_opt_reconnect;
mysql_read_default_file = config->mysql_read_default_file;
mysql_opt_use_ssl = config->mysql_opt_use_ssl;
mysql_opt_ssl_verify_server_cert = config->mysql_opt_ssl_verify_server_cert;
@ -382,6 +476,7 @@ static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, O
//get address
if (NULL == (address = get_ob_address_by_address_list(addr_list))) {
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, "address list is empty(all in black).");
break;
}
@ -392,6 +487,10 @@ static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, O
#ifdef DEBUG_LOAD_BALANCE
printf("host:%s,port:%d,state:%d\n", address->host, address->port, address->state);
#endif
//set default options
mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char *)&default_report_data_truncation);
mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, (char*)&default_local_infile);
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, &default_connect_timeout);
//mysql options
if (mysql_connect_timeout > 0)
@ -430,6 +529,8 @@ static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, O
mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char *)&mysql_report_data_truncation);
if (mysql_opt_reconnect)
mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&mysql_opt_reconnect);
if (mysql_read_default_file && *mysql_read_default_file)
mysql_options(mysql, MYSQL_READ_DEFAULT_FILE, (char*)mysql_read_default_file);
if (mysql_opt_use_ssl) {
mysql_ssl_set(mysql, mysql_opt_ssl_key, mysql_opt_ssl_cert, mysql_opt_ssl_ca, mysql_opt_ssl_capath, mysql_opt_ssl_cipher);
@ -459,8 +560,18 @@ static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, O
//check black
check_ob_address_black(address, config);
if (config->retry_timeout > 0 && get_current_time_us() > lb_endtime) {
snprintf(buf, sizeof(buf), "retry_timeout(%d)(%lld-%lld).", config->retry_timeout, lb_starttime, get_current_time_us());
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, buf);
break;
}
config->retry_all_downs--;
} while (address && config->retry_all_downs > 0);
if (config->retry_all_downs <= 0) {
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, "retry_all_downs is zero.");
break;
}
} while (address);
//release connect
for (i = 0; i < addr_list->count; i++) {
@ -470,23 +581,28 @@ static MYSQL* connect_by_addresslist(MYSQL* mysql, ObLbAddressList *addr_list, O
return tmp;
}
static MYSQL* connect_by_tnsname(MYSQL* mysql, const char* tns_name, ObClientLbConfig * config,
static MYSQL* connect_by_tnsname(MYSQL* mysql, int64_t lb_starttime, const char* tns_name, ObClientLbConfig * config,
const char *user, const char* passwd, const char *db, const char* unix_socket, unsigned long client_flag, ObClientLbAddress *success)
{
int ret = 0;
MYSQL *tmp = NULL;
char buf[128] = { 0 };
my_bool find = 0;
ObClientTns tns;
const char *sid = db;
char session_variable[1024] = { 0 };
char new_user_name[256] = { 0 };
int user_len = strlen((const char *)user ? user : "");
int64_t lb_endtime = 0;
if (OB_FAIL(ObClientTnsInit(&tns))) {
tmp = NULL;
if (NULL == tns_name || NULL == config) {
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, "invalid tns_name or config.");
} else if (OB_FAIL(ObClientTnsInit(&tns))) {
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, "tns init fail.");
} else if (OB_FAIL(ObClientTnsBuild(&tns, tns_name, strlen(tns_name), &find))) {
tmp = NULL;
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, "ob client tns build fail.");
} else if (1 != find || !tns.tns_service || !tns.tns_service->description || tns.tns_service->description_count == 0) {
tmp = NULL;
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, "tns description is null.");
} else {
unsigned int i = 0;
ObClientDescription *des = tns.tns_service->description;
@ -507,28 +623,40 @@ static MYSQL* connect_by_tnsname(MYSQL* mysql, const char* tns_name, ObClientLbC
//tns config
config->retry_all_downs = des->retry_all_downs;
config->retry_timeout = des->retry_timeout;
config->black_remove_strategy = des->black_list_conf.remove_strategy;
config->black_remove_timeout = des->black_list_conf.remove_timeout;
config->black_append_strategy = des->black_list_conf.append_strategy;
config->black_append_duration = des->black_list_conf.duration;
config->black_append_retrytimes = des->black_list_conf.retry_times;
if (des->connect_timout > 0) config->mysql_connect_timeout = des->connect_timout;
if (des->read_timout > 0) config->mysql_read_timeout = des->read_timout;
if (des->write_timout > 0) config->mysql_write_timeout = des->write_timout;
lb_endtime = lb_starttime + config->retry_timeout * 1000;
for (i = 0; i < des->address_list_count; i++) {
ObLbAddressList list;
memset(&list, 0, sizeof(list));
#ifdef DEBUG_LOAD_BALANCE
printf("------------------------------------------\n");
#endif
if (OB_SUCC(init_oblb_addresslist_tns(&list, &(des->address_list[i])))) {
tmp = connect_by_addresslist(mysql, &list, config, new_user_name, passwd, sid, unix_socket, client_flag, success);
}
if (list.add_arr) {
free(list.add_arr);
list.add_arr = NULL;
list.count = 0;
ObLbAddressList list;
memset(&list, 0, sizeof(list));
if (OB_SUCC(init_oblb_addresslist_tns(&list, &(des->address_list[i]), des->oblb_strategy))) {
tmp = connect_by_addresslist(mysql, lb_starttime, &list, config, new_user_name, passwd, sid, unix_socket, client_flag, success);
}
release_oblb_addresslist(&list);
//connect success
if (tmp) {
if (des && des->connect_data && des->connect_data->session_variable_len > 0) {
post_session_variable(tmp, des->connect_data->session_variable, des->connect_data->session_variable_len);
}
break;
}
if (config->retry_timeout > 0 && get_current_time_us() > lb_endtime) {
snprintf(buf, sizeof(buf), "retry_timeout(%d)(%lld-%lld).", config->retry_timeout, lb_starttime, get_current_time_us());
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, buf);
break;
}
}
@ -542,20 +670,84 @@ MYSQL* ob_mysql_real_connect(MYSQL* mysql, const char* tns_name, ObClientLbAddre
{
int ret = 0;
MYSQL *tmp = NULL;
ObClientLbConfig default_config = {0};
int64_t lb_starttime = get_current_time_us();
if (NULL == config) {
memset(&default_config, 0, sizeof(ObClientLbConfig));
config = &default_config;
}
if (tns_name && *tns_name) {
tmp = connect_by_tnsname(mysql, tns_name, config, user, passwd, db, unix_socket, client_flag, success);
} else {
tmp = connect_by_tnsname(mysql, lb_starttime, tns_name, config, user, passwd, db, unix_socket, client_flag, success);
} else if (addr_list) {
ObLbAddressList list;
memset(&list, 0, sizeof(list));
if (OB_SUCC(init_oblb_addresslist(&list, addr_list))) {
tmp = connect_by_addresslist(mysql, &list, config, user, passwd, db, unix_socket, client_flag, success);
}
if (list.add_arr) {
free(list.add_arr);
list.add_arr = NULL;
list.count = 0;
if (OB_SUCC(init_oblb_addresslist(&list, addr_list, OBCLIENT_LB_OPTION_ROTATION))) {
if (config->retry_all_downs <= 0) config->retry_all_downs = addr_list->address_list_count;
if (config->retry_timeout <= 0) config->retry_timeout = 0; //list µØÖ·Ä£Ê½Ä¬ÈÏÂÖѵ£¬Õâ¸ö²ÎÊý²»ÉúЧ
if (config->black_append_strategy != OBCLIENT_LB_OPTION_NORMAL &&
config->black_append_strategy != OBCLIENT_LB_OPTION_RETRY_DERUATION) {
config->black_append_strategy = OBCLIENT_LB_OPTION_NORMAL;
}
if (config->black_append_duration <= 0) config->black_append_duration = 10 * 1000;
if (config->black_append_retrytimes <= 0) config->black_append_retrytimes = 1;
if (config->black_remove_strategy != OBCLIENT_LB_OPTION_TIMEOUT) {
config->black_remove_strategy = OBCLIENT_LB_OPTION_TIMEOUT;
}
//if (config->black_remove_timeout <= 0) config->black_remove_timeout = 50 * 1000;
tmp = connect_by_addresslist(mysql, lb_starttime, &list, config, user, passwd, db, unix_socket, client_flag, success);
}
release_oblb_addresslist(&list);
} else {
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, "tns_name/addr_list is null.");
}
return tmp;
}
MYSQL* ob_mysql_real_connect2(MYSQL* mysql, const char* tns_name, const char *addr_list, ObClientLbConfig *config,
const char *user, const char *passwd, const char *db, const char *unix_socket, unsigned long client_flag, char* success, int len_success)
{
int ret = 0;
MYSQL *tmp = NULL;
ObClientLbConfig default_config = { 0 };
ObClientLbAddress success_addr;
int64_t lb_starttime = get_current_time_us();
memset(&success_addr, 0, sizeof(success_addr));
if (NULL == config) {
memset(&default_config, 0, sizeof(ObClientLbConfig));
config = &default_config;
}
if (tns_name && *tns_name) {
tmp = connect_by_tnsname(mysql, lb_starttime, tns_name, config, user, passwd, db, unix_socket, client_flag, &success_addr);
} else if (addr_list) {
ObLbAddressList list;
memset(&list, 0, sizeof(list));
if (OB_SUCC(init_oblb_addresslist_str(&list, (char*)addr_list, OBCLIENT_LB_OPTION_ROTATION))) {
if (config->retry_all_downs <= 0) config->retry_all_downs = list.count;
if (config->retry_timeout <= 0) config->retry_timeout = 0; //list µØÖ·Ä£Ê½Ä¬ÈÏÂÖѵ£¬Õâ¸ö²ÎÊý²»ÉúЧ
if (config->black_append_strategy != OBCLIENT_LB_OPTION_NORMAL &&
config->black_append_strategy != OBCLIENT_LB_OPTION_RETRY_DERUATION) {
config->black_append_strategy = OBCLIENT_LB_OPTION_NORMAL;
}
if (config->black_append_duration <= 0) config->black_append_duration = 10 * 1000;
if (config->black_append_retrytimes <= 0) config->black_append_retrytimes = 1;
if (config->black_remove_strategy != OBCLIENT_LB_OPTION_TIMEOUT) {
config->black_remove_strategy = OBCLIENT_LB_OPTION_TIMEOUT;
}
//if (config->black_remove_timeout <= 0) config->black_remove_timeout = 50 * 1000;
tmp = connect_by_addresslist(mysql, lb_starttime, &list, config, user, passwd, db, unix_socket, client_flag, &success_addr);
}
release_oblb_addresslist(&list);
} else {
SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, "tns_name/addr_list is null.");
}
if (tmp && success && len_success > 0) {
snprintf(success, len_success, "[%s]:%d", success_addr.host, success_addr.port);
}
return tmp;

View File

@ -5,7 +5,6 @@
#include "mysql.h"
#include "ma_global.h"
#include "ob_object.h"
#include "ob_full_link_trace.h"
#include "ob_rwlock.h"

View File

@ -101,7 +101,7 @@ static ObClientLBKeyType tns_keytype_15[] = { OBCLIENT_LB_REMOVE_STRATEGY, OBCLI
static ObClientLBKeyType tns_keytype_16[] = { OBCLIENT_LB_SESSION_VARIABLE};
static ObClientLBKeyType tns_keytype_17[] = { OBCLIENT_LB_READ_TIMEOUT};
static ObClientLBKeyType tns_keytype_18[] = { OBCLIENT_LB_EXTRA_INFO, OBCLIENT_LB_OBLB_RETRY_TIMEOUT, OBCLIENT_LB_WRITE_TIMEOUT};
static ObClientLBKeyType tns_keytype_19[] = { OBCLIENT_LB_OBLB_GROUP_STRATEGY };
static ObClientLBKeyType tns_keytype_19[] = { OBCLIENT_LB_OBLB_GROUP_STRATEGY};
static ObClientLBKeyType tns_keytype_20[] = { OBCLIENT_LB_OBLB_RETRY_ALL_DOWNS, OBCLIENT_LB_CONNECT_TIMEOUT};
static const void *tns_key_array[] = {
@ -568,7 +568,7 @@ int ObClientTnsServiceSkip(ObClientTnsParseParams *parse_params)
return ret;
}
int ObClientTnsServiceExtraInfoGet(ObClientTnsService *tns_service, char *extra_info, int *extra_info_len, int *ob_mode)
int ObClientTnsServiceExtraInfoGet(ObClientTnsService *tns_service, char *extra_info, int *extra_info_len, int *ob_mode, char* session_variable, int *session_variable_len)
{
int ret = 0;
ObClientDescription *des;
@ -580,10 +580,16 @@ int ObClientTnsServiceExtraInfoGet(ObClientTnsService *tns_service, char *extra_
ret = -1;
} else if (OB_ISNULL(con_data = des->connect_data)) {
ret = -1;
} else if (0 != con_data->user_extra_info_len) {
*extra_info_len = con_data->user_extra_info_len;
strncpy(extra_info, con_data->user_extra_info, *extra_info_len);
*ob_mode = con_data->ob_mode;
} else {
if (0 != con_data->user_extra_info_len) {
*extra_info_len = con_data->user_extra_info_len;
strncpy(extra_info, con_data->user_extra_info, *extra_info_len);
*ob_mode = con_data->ob_mode;
}
if (0 != con_data->session_variable_len) {
*session_variable_len = con_data->session_variable_len;
strncpy(session_variable, con_data->session_variable, *session_variable_len);
}
}
return ret;
@ -791,6 +797,17 @@ int ObClientDescriptionBuild(ObClientTnsService *tns_service, ObClientTnsParsePa
TNS_PARSE_INTRGER_VALUE(parse_params, des->read_timout);
} else if (OBCLIENT_LB_WRITE_TIMEOUT == parse_params->key_type) {
TNS_PARSE_INTRGER_VALUE(parse_params, des->write_timout);
} else if (OBCLIENT_LB_OBLB_STRATEGY == parse_params->key_type) {
TNS_PARSE(parse_params, TNS_KEY);
if (0 == strncasecmp(parse_params->tns_key, "RANDOM", parse_params->tns_key_len)) {
des->oblb_strategy = OBCLIENT_LB_OPTION_RANDOM;
} else if (0 == strncasecmp(parse_params->tns_key, "SERVERAFFINITY", parse_params->tns_key_len)) {
des->oblb_strategy = OBCLIENT_LB_OPTION_SERVERAFFINITY;
} else if (0 == strncasecmp(parse_params->tns_key, "ROTATION", parse_params->tns_key_len)) {
des->oblb_strategy = OBCLIENT_LB_OPTION_ROTATION;
} else {
ret = -1;
}
} else if (OBCLIENT_LB_OBLB_GROUP_STRATEGY == parse_params->key_type) {
TNS_PARSE(parse_params, TNS_KEY);
if (0 == strncasecmp(parse_params->tns_key, "ROTATION", parse_params->tns_key_len)) {
@ -1244,6 +1261,9 @@ int ObClientConnectDataDisplay(ObClientConnectData *con_data, FILE *display_file
fprintf(display_file, "----------obmode:%ld\n", con_data->ob_mode);
fprintf(display_file, "----------use_default_sid:%ld\n", con_data->use_default_sid);
}
if (0 != con_data->session_variable_len) {
fprintf(display_file, "----------session_variable:%.*s\n", con_data->session_variable_len, con_data->session_variable);
}
}
return ret;
@ -1283,6 +1303,8 @@ int ObClientConnectDataBuild(ObClientDescription *des, ObClientTnsParseParams *p
TNS_PARSE_INTRGER_VALUE(parse_params, connect_data->ob_mode);
} else if (OBCLIENT_LB_USE_DEFAULT_SID == parse_params->key_type) {
TNS_PARSE_INTRGER_VALUE(parse_params, connect_data->use_default_sid);
} else if (OBCLIENT_LB_SESSION_VARIABLE == parse_params->key_type) {
TNS_PARSE_STRING_VALUE(parse_params, connect_data->session_variable, connect_data->session_variable_len, OBCLIENT_TNS_KEY_SIZE);
} else {
ret = -1;
}
@ -1467,19 +1489,25 @@ int ObClientTnsParseBlank(ObClientTnsParseParams *parse_params)
}
} else {
while (parse_params->buffer_pos < parse_params->buffer_len) {
ch = parse_params->tns_buffer[parse_params->buffer_pos];
if ('\t' == ch || '\n' == ch || ' ' == ch) {
parse_params->buffer_pos++;
} else if ('#' == ch) { // ignore comments
if (!parse_params->is_comment) {
ch = parse_params->tns_buffer[parse_params->buffer_pos];
if (('\t' == ch || '\n' == ch || ' ' == ch || '\r' == ch)) {
parse_params->buffer_pos++;
} else if ('#' == ch) { // ignore comments
parse_params->is_comment = 1;
} else {
break;
}
} else {
unsigned int tmp = parse_params->buffer_pos;
for (; tmp < parse_params->buffer_len; tmp++) {
char tmpch = parse_params->tns_buffer[tmp];
if ('\n' == tmpch || '\0' == tmpch)
if ('\n' == tmpch || '\0' == tmpch) {
parse_params->is_comment = 0;
break;
}
}
parse_params->buffer_pos = tmp;
} else {
break;
}
}
if (parse_params->buffer_pos < parse_params->buffer_len) {

View File

@ -149,6 +149,7 @@ struct obclient_description
unsigned long read_timout; // 单次读的超时时间
unsigned long write_timout; // 单次写的超时时间
unsigned long retry_timeout; // 整个LB阶段的超时时间
ObClientLBOption oblb_strategy;
ObClientLBOption oblb_group_strategy;
ObClientBlacklistConf black_list_conf;
};
@ -178,6 +179,8 @@ struct obclient_connect_data
unsigned int service_name_len;
char user_extra_info[OBCLIENT_TNS_KEY_SIZE];
unsigned int user_extra_info_len;
char session_variable[OBCLIENT_TNS_KEY_SIZE];
unsigned int session_variable_len;
unsigned long ob_mode;
unsigned long use_default_sid;
};
@ -196,6 +199,7 @@ struct obclient_tns_parse_params
char *description;
int description_len;
int description_offset;
int is_comment;
ObClientTnsTokenType tns_token_type;
ObClientLBKeyType key_type;
};
@ -214,7 +218,7 @@ int ObClientTnsServiceDisplay(ObClientTnsService *tns_service, FILE *display_fil
int ObClientTnsServiceBuild(ObClientTns *tns, ObClientTnsParseParams *parse_params);
int ObClientTnsServiceSkip(ObClientTnsParseParams *parse_params);
// 非负载均衡模式下获取extra info
int ObClientTnsServiceExtraInfoGet(ObClientTnsService *tns_service, char *extra_info, int *extra_info_len, int *ob_mode);
int ObClientTnsServiceExtraInfoGet(ObClientTnsService *tns_service, char *extra_info, int *extra_info_len, int *ob_mode, char* session_variable, int *session_variable_len);
// 非负载均衡模式下获取dblink, 直接获取第一个address,拼接dblink
int ObClientTnsServiceDblinkGet(ObClientTnsService *tns_service, char *dblink, int *dblink_len);

View File

@ -32,5 +32,5 @@ int64_t get_current_time_us()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000000 + tv.tv_usec;
return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}

View File

@ -1 +1 @@
2.2.7
2.2.8