...
 
Commits (6)
    https://gitcode.net/oceanbase/obproxy/-/commit/f302921b7db2e9ec6c6b15969f6b41413b460810 Feature 2021-10-22T10:38:48+08:00 Wesley Wang wgs13579@gmail.com 1. Optimize the use of epoll_wait, fully event-driven 2. New replication table supports evenly distributed routing 3. Support weak read requests sent to backup copies 4. Supports random selection of the partition route when the partition cannot be calculated 5. Supports routing that contains Chinese full-width punctuation(commas, brackets, spaces) 6. Support COM_CHANGE_USER command Bugfix 1. Fix the problem of client connection failure when enable_proxy_scramble is configured as true 2. Fix that after starting through rslist, the server list is not rebuilt after the server is offline, and the server still accesses the offline server, which causes the access to continue to fail 3. Fix the problem that the 127.0.0.1 rslist cannot be matched with the server in all_server and cannot be accessed at startup 4. Fix the problem that ODP cannot be accessed normally from the local configuration file after OCP hangs 5. Fix the problem of ODP tenant name being injected 6. Fix the problem that thread variables cannot be synchronized when switching sessions in ODP 3.x 7. Fix the problem that hint contains special symbols, which causes insertion and parsing to fail 8. Fix the disconnection problem when the cursor does not exist 9. Fix the problem that the connection to the main library without cluster id can be successfully executed after several queries and the link is broken 11.Fix the problem of continuous access failure if rslist is returned to rslist after rslist is started https://gitcode.net/oceanbase/obproxy/-/commit/54e7e450744e6fd919a013bf21cdb1fc1347f9c3 BugFixs: 2021-10-22T10:38:48+08:00 Wesley Wang wgs13579@gmail.com 1. Use the new prometheus package to fix the core problem Other: 1. update version to 3.2.0 2. Open source opens the 2.0 protocol by default https://gitcode.net/oceanbase/obproxy/-/commit/b91a4006ba52e107d1a3edb03a50f3d14ef63cd8 Modify the default value of skip_proxy_sys_private_check to true 2021-10-27T16:03:49+08:00 guangshu.wgs guangshu.wgs@antfin.com https://gitcode.net/oceanbase/obproxy/-/commit/ae1122bc41c5ae432e50e1ac86bfd20a604784a2 Shorten the file name 2021-12-16T21:50:37+08:00 Wesley Wang wgs13579@gmail.com https://gitcode.net/oceanbase/obproxy/-/commit/2b275341013859224c319d86589994c75146508e Modify the package name to obproxy-ce 2021-12-16T21:50:54+08:00 Wesley Wang wgs13579@gmail.com https://gitcode.net/oceanbase/obproxy/-/commit/178a779f11e38ad79e4d6435d7dee99cb80d5162 * Shorten the file name 2021-12-17T10:17:14+08:00 Wesley Wang wgs13579@gmail.com * Modify the package name to obproxy-ce
......@@ -90,8 +90,8 @@ function do_rpm()
{
set -x
sw
PACKAGE=obproxy
VERSION=3.1.0
PACKAGE=obproxy-ce
VERSION=3.2.0
RELEASE=1
PREFIX=/home/admin/obproxy
SPEC_FILE=obproxy.spec
......@@ -106,7 +106,7 @@ function do_rpm()
mkdir -p ${TMP_DIR}/RPMS
mkdir -p ${TMP_DIR}/SOURCES
mkdir -p ${TMP_DIR}/SRPMS
cp obproxy-${VERSION}.tar.gz ${TMP_DIR}/SOURCES
cp ${PACKAGE}-${VERSION}.tar.gz ${TMP_DIR}/SOURCES
cd ${TMP_DIR}/BUILD
echo "[BUILD] make rpms..._prefix=${PREFIX} spec_file=${SPEC_FILE}"
......
AC_INIT([OceanBase],
[3.1.0],
[huating.zmq@alipay.com],
[obproxy],
[3.2.0],
[wgs13579@gmail.com],
[obproxy-ce],
[http://oceanbase.taobao.org/])
obapi_version="3.1.0"
obapi_version="3.2.0"
AC_SUBST(obapi_version)
AC_DISABLE_STATIC
......
......@@ -6,7 +6,7 @@ repo=https://mirrors.aliyun.com/oceanbase/development-kit/el/7/x86_64/
devdeps-openssl-static-1.0.1e-3.el7.x86_64.rpm
devdeps-libcurl-static-7.29.0-3.el7.x86_64.rpm
devdeps-mariadb-connector-c-3.1.12-3.el7.x86_64.rpm
devdeps-prometheus-cpp-0.8.0-3.el7.x86_64.rpm
devdeps-prometheus-cpp-0.8.0-4.el7.x86_64.rpm
devdeps-gtest-1.8.0-3.el7.x86_64.rpm
devdeps-grpc-1.20.1-3.el7.x86_64.rpm
......
......@@ -6,7 +6,7 @@ repo=https://mirrors.aliyun.com/oceanbase/development-kit/el/8/x86_64/
devdeps-openssl-static-1.0.1e-3.el8.x86_64.rpm
devdeps-libcurl-static-7.29.0-3.el8.x86_64.rpm
devdeps-mariadb-connector-c-3.1.12-3.el8.x86_64.rpm
devdeps-prometheus-cpp-0.8.0-3.el8.x86_64.rpm
devdeps-prometheus-cpp-0.8.0-4.el8.x86_64.rpm
devdeps-gtest-1.8.0-3.el8.x86_64.rpm
devdeps-grpc-1.20.1-3.el8.x86_64.rpm
......
......@@ -2613,9 +2613,43 @@ static int string_string(const ObObjType expect_type, ObObjCastParams &params,
} else {
ObString str;
in.get_string(str);
ret = copy_string(params, expect_type, str, out);
if (CS_TYPE_INVALID != in.get_collation_type()) {
out.set_collation_type(in.get_collation_type());
if (0 != str.length()
&& CS_TYPE_BINARY != in.get_collation_type()
&& CS_TYPE_BINARY != params.dest_collation_
&& (ObCharset::charset_type_by_coll(in.get_collation_type())
!= ObCharset::charset_type_by_coll(params.dest_collation_))) {
char *buf = NULL;
// buf_len is related to the encoding length, gbk uses 2 bytes to encode a character, utf8mb4 uses 1 to 4 bytes
// CharConvertFactorNum is a multiple of the requested memory size
const int32_t CharConvertFactorNum = 2;
int32_t buf_len = str.length() * CharConvertFactorNum;
uint32_t result_len = 0;
if (OB_UNLIKELY(NULL == (buf = static_cast<char*>(params.alloc(buf_len))))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc memory failed", K(ret));
} else if (OB_FAIL(ObCharset::charset_convert(in.get_collation_type(),
str.ptr(),
str.length(),
params.dest_collation_,
buf,
buf_len,
result_len))) {
LOG_WARN("charset convert failed", K(ret), K(in.get_collation_type()), K(params.dest_collation_));
}
LOG_DEBUG("convert result", K(str), "result", ObHexEscapeSqlStr(ObString(result_len, buf)));
if (OB_SUCC(ret)) {
out.set_string(expect_type, buf, static_cast<int32_t>(result_len));
if (CS_TYPE_INVALID != in.get_collation_type()) {
out.set_collation_type(params.dest_collation_);
}
}
} else {
ret = copy_string(params, expect_type, str, out);
if (CS_TYPE_INVALID != in.get_collation_type()) {
out.set_collation_type(in.get_collation_type());
}
}
}
if (OB_SUCC(ret)) {
......@@ -3230,6 +3264,7 @@ int ObObjCasterV2::to_type(const ObObjType expect_type, const ObCollationType ex
const ObObjTypeClass in_tc = in_obj.get_type_class();
const ObObjTypeClass out_tc = ob_obj_type_class(expect_type);
cast_ctx.warning_ = OB_SUCCESS;
cast_ctx.dest_collation_ = expect_cs_type;
if (OB_UNLIKELY(ob_is_invalid_obj_tc(in_tc) || ob_is_invalid_obj_tc(out_tc))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected type", K(ret), K(in_obj), K(expect_type));
......
......@@ -121,6 +121,7 @@ struct ObObjCastParams
const ObZerofillInfo *zf_info_;
ObCollationType connection_collation_;
ObAccuracy *res_accuracy_;
ObCollationType dest_collation_;
};
/**
* cast functions to do the real work
......
......@@ -39,6 +39,20 @@ private:
DISALLOW_COPY_AND_ASSIGN(ObMutex);
};
static inline int mutex_acquire(ObMutex *m)
{
return m->lock();
}
static inline bool mutex_try_acquire(ObMutex *m)
{
return common::OB_SUCCESS == m->trylock();
}
static inline int mutex_release(ObMutex *m)
{
return m->unlock();
}
typedef ObLockGuard<ObMutex> ObMutexGuard;
} // end of namespace lib
......
......@@ -63,6 +63,11 @@ public:
memset(&ip_, 0, sizeof (ip_));
}
inline bool is_ip_loopback() const
{
return (IPV4 == version_ && INADDR_LOOPBACK == ip_.v4_)
|| (IPV6 == version_ && IN6_IS_ADDR_LOOPBACK(ip_.v6_));
}
static uint32_t convert_ipv4_addr(const char *ip);
int64_t to_string(char *buffer, const int64_t size) const;
......@@ -101,7 +106,7 @@ private:
VER version_;
union
{
uint32_t v4_;
uint32_t v4_; //host byte order
uint32_t v6_[4];
} ip_;
int32_t port_;
......
......@@ -69,7 +69,8 @@ int ObAlterConfigSetHandler::handle_set_config(int event, void *data)
ObString value_string(value_str_);
if ((0 == key_string.case_compare("observer_sys_password")
|| 0 == key_string.case_compare("obproxy_sys_password"))
|| 0 == key_string.case_compare("obproxy_sys_password")
|| 0 == key_string.case_compare("observer_sys_password1"))
&& !value_string.empty()) {
char passwd_staged1_buf[ENC_STRING_BUF_LEN];
ObString passwd_string(ENC_STRING_BUF_LEN, passwd_staged1_buf);
......
......@@ -309,7 +309,8 @@ int ObDdsConfigHandler::handle_select_sql_variables()
}
if (OB_FAIL(ret)) {
//do nothing
} else if (OB_FAIL(handle_parse_where_fields(&allocator, expr_result))) {
} else if (OB_FAIL(handle_parse_where_fields(&allocator, expr_result,
static_cast<ObCollationType>(sm_->get_client_session()->get_session_info().get_collation_connection())))) {
WARN_ICMD("fail to parse where fileds", K(ret));
} else {
ObString app_block = table_name;
......@@ -335,7 +336,8 @@ int ObDdsConfigHandler::handle_select_sql_variables()
return event_ret;
}
int ObDdsConfigHandler::handle_parse_where_fields(ObArenaAllocator* allocator, ObExprParseResult& expr_result)
int ObDdsConfigHandler::handle_parse_where_fields(ObArenaAllocator* allocator, ObExprParseResult& expr_result,
ObCollationType connection_collation)
{
int ret = OB_SUCCESS;
bool need_parse_fields = true;
......@@ -360,7 +362,9 @@ int ObDdsConfigHandler::handle_parse_where_fields(ObArenaAllocator* allocator, O
} else {
ObExprParser expr_parser(*allocator, parse_mode);
expr_result.part_key_info_.key_num_ = 0;
if (OB_FAIL(expr_parser.parse_reqsql(sql, sql_parse_result.get_parsed_length(), expr_result, sql_parse_result.get_stmt_type()))) {
if (OB_FAIL(expr_parser.parse_reqsql(sql, sql_parse_result.get_parsed_length(),
expr_result, sql_parse_result.get_stmt_type(),
connection_collation))) {
WARN_ICMD("fail to do expr parse_reqsql", K(sql), K(ret));
} else {
DEBUG_ICMD("parse success:", K(sql), K(expr_result.all_relation_info_.relation_num_));
......@@ -445,7 +449,8 @@ int ObDdsConfigHandler::handle_update_variables()
ObString table_name = client_request.get_parse_result().get_table_name();
ObArenaAllocator allocator;
ObExprParseResult expr_result;
if (OB_FAIL(handle_parse_where_fields(&allocator, expr_result))) {
if (OB_FAIL(handle_parse_where_fields(&allocator, expr_result,
static_cast<ObCollationType>(sm_->get_client_session()->get_session_info().get_collation_connection())))) {
WARN_ICMD("fail to parse where fileds", K(ret));
} else {
ObString app_block = table_name;
......
......@@ -56,7 +56,8 @@ private:
common::ObString& config_val);
int handle_parse_where_fields(common::ObArenaAllocator* allocator,
ObExprParseResult& expr_result);
ObExprParseResult& expr_result,
common::ObCollationType connection_collation);
int update_dds_config_to_processor(const common::ObString& app_name,
const common::ObString& app_version,
const common::ObString& app_block,
......
......@@ -103,7 +103,7 @@ int ObProxyParallelResp::next(ObObj *&rows)
} else {
ObCastCtx cast_ctx(allocator_, NULL, CM_NULL_ON_WARN, cs_type);
// use src_obj as buf_obj
if (OB_FAIL(ObObjCasterV2::to_type(ob_type, cast_ctx, rows[i], rows[i]))) {
if (OB_FAIL(ObObjCasterV2::to_type(ob_type, cs_type, cast_ctx, rows[i], rows[i]))) {
COMMON_LOG(WARN, "failed to cast obj", "idx", i, "row", rows[i], K(ob_type), K(cs_type), K(ret));
}
}
......
......@@ -348,7 +348,7 @@ void ObEThread::execute()
Que(ObEvent, link_) negative_queue;
ObEvent *e = NULL;
ObHRTime next_time = 0;
ObHRTime sleep_time = 0;
sleep_time_ = 0;
bool done_one = false;
//NOTE:: the precision of schedule in ObEThread is [-5ms, 60ms)
......@@ -389,6 +389,21 @@ void ObEThread::execute()
}
//3.1 execute all the available external events that have already been dequeued
dequeue_local_event(negative_queue);
if (ethreads_to_be_signalled_count_ > 0) {
flush_signals(this);
}
if (event_queue_external_.get_local_queue_size() > 0 || event_queue_external_.get_atomic_list_size() > 0) {
sleep_time_ = 0;
} else {
cur_time_ = get_hrtime_internal();
sleep_time_ = event_queue_.earliest_timeout() - cur_time_;
if (sleep_time_ <= 0) {
sleep_time_ = 0;
} else if (sleep_time_ > THREAD_MAX_HEARTBEAT_MSECONDS * HRTIME_MSECOND) {
sleep_time_ = THREAD_MAX_HEARTBEAT_MSECONDS * HRTIME_MSECOND;
}
}
// execute poll events
while (NULL != (e = negative_queue.dequeue())) {
......@@ -403,9 +418,9 @@ void ObEThread::execute()
//4. wait for the appropriate event
} else {
next_time = event_queue_.earliest_timeout();
sleep_time = next_time - cur_time_;
sleep_time_ = next_time - cur_time_;
if (sleep_time > THREAD_MAX_HEARTBEAT_MSECONDS * HRTIME_MSECOND) {
if (sleep_time_ > THREAD_MAX_HEARTBEAT_MSECONDS * HRTIME_MSECOND) {
next_time = cur_time_ + THREAD_MAX_HEARTBEAT_MSECONDS * HRTIME_MSECOND;
}
// dequeue all the external events and put them in a local queue.
......
......@@ -335,6 +335,8 @@ public:
ObProtectedQueue event_queue_external_;
ObPriorityEventQueue event_queue_;
ObHRTime sleep_time_;
ObEThread **ethreads_to_be_signalled_;
int64_t ethreads_to_be_signalled_count_;
......
......@@ -198,21 +198,14 @@ public:
#endif //OB_HAS_EVENT_DEBUG
}
virtual ~ObProxyMutex() { common::mutex_destroy(&the_mutex_); }
virtual ~ObProxyMutex() {}
/**
* Initializes the underlying mutex object.
* After constructing your ObProxyMutex object, use this function
* to initialize the underlying mutex object with an optional name.
*/
int init()
{
int ret = common::OB_SUCCESS;
if (OB_FAIL(common::mutex_init(&the_mutex_))) {
PROXY_EVENT_LOG(ERROR, "fail to init mutex", K(ret));
}
return ret;
}
int init() { return common::OB_SUCCESS; }
void free()
{
......@@ -221,10 +214,6 @@ public:
print_lock_stats(1);
#endif //OB_HAS_LOCK_CONTENTION_PROFILING
#endif //OB_HAS_EVENT_DEBUG
int ret = common::OB_SUCCESS;
if (OB_FAIL(common::mutex_destroy(&the_mutex_))) {
PROXY_EVENT_LOG(ERROR, "fail to destroy mutex", K(ret));
}
op_reclaim_free(this);
}
......@@ -241,7 +230,7 @@ public:
* The platform independent mutex for the ObProxyMutex class. You
* must not modify or set it directly.
*/
ObMutex the_mutex_;
lib::ObMutex the_mutex_;
/**
* Backpointer to owning thread.
......@@ -286,7 +275,7 @@ inline bool mutex_trylock(
PROXY_EVENT_LOG(WARN, "argument is error", K(t), K(m));
} else {
if (m->thread_holding_ != t) {
if (OB_UNLIKELY(!common::mutex_try_acquire(&m->the_mutex_))) {
if (OB_UNLIKELY(!lib::mutex_try_acquire(&m->the_mutex_))) {
#ifdef OB_HAS_EVENT_DEBUG
lock_waiting(m->srcloc_, m->handler_);
#ifdef OB_HAS_LOCK_CONTENTION_PROFILING
......@@ -339,7 +328,7 @@ inline bool mutex_trylock_spin(
} else {
if (m->thread_holding_ != t) {
do {
bret = common::mutex_try_acquire(&m->the_mutex_);
bret = lib::mutex_try_acquire(&m->the_mutex_);
} while (--spincnt && OB_UNLIKELY(!bret));
if (OB_UNLIKELY(!bret)) {
......@@ -393,7 +382,7 @@ inline bool mutex_lock(
PROXY_EVENT_LOG(WARN, "argument is error", K(t), K(m));
} else {
if (m->thread_holding_ != t) {
if (OB_UNLIKELY(common::OB_SUCCESS != common::mutex_acquire(&m->the_mutex_))) {
if (OB_UNLIKELY(common::OB_SUCCESS != lib::mutex_acquire(&m->the_mutex_))) {
bret = false;
PROXY_EVENT_LOG(ERROR, "fail to acquire mutex");
} else {
......@@ -444,7 +433,7 @@ inline void mutex_unlock(ObProxyMutex *m, ObEThread *t)
m->handler_ = NULL;
#endif //OB_HAS_EVENT_DEBUG
m->thread_holding_ = NULL;
if (OB_UNLIKELY(common::OB_SUCCESS != common::mutex_release(&m->the_mutex_))) {
if (OB_UNLIKELY(common::OB_SUCCESS != lib::mutex_release(&m->the_mutex_))) {
PROXY_EVENT_LOG(ERROR, "fail to release mutex");
}
}
......
......@@ -32,6 +32,7 @@
#define USING_LOG_PREFIX PROXY_EVENT
#include "iocore/eventsystem/ob_event_system.h"
#include "iocore/net/ob_unix_net.h"
using namespace oceanbase::common;
......@@ -71,6 +72,9 @@ void ObProtectedQueue::enqueue(ObEvent *e, const bool fast_signal)
if (OB_FAIL(signal())) {
LOG_WARN("fail to do signal, it should not happened", K(ret));
}
if (NULL != e_ethread->net_poll_) {
e_ethread->get_net_poll().timerfd_settime();
}
if (fast_signal) {
if (NULL != e_ethread->signal_hook_) {
e_ethread->signal_hook_(*e_ethread);
......@@ -81,7 +85,13 @@ void ObProtectedQueue::enqueue(ObEvent *e, const bool fast_signal)
#ifdef EAGER_SIGNALLING
// Try to signal now and avoid deferred posting.
if (OB_SUCC(e_ethread->event_queue_external_.try_signal())) {
need_break = true;
if (NULL != e_ethread->net_poll_) {
if (OB_SUCC(e_ethread->get_net_poll().timerfd_settime())) {
need_break = true;
}
} else {
need_break = true;
}
}
#endif
if (!need_break) {
......@@ -146,7 +156,13 @@ void flush_signals(ObEThread *thr)
// Try to signal as many threads as possible without blocking.
if (NULL != thr->ethreads_to_be_signalled_[i]) {
if (thr->ethreads_to_be_signalled_[i]->event_queue_external_.try_signal()) {
thr->ethreads_to_be_signalled_[i] = 0;
if (NULL != thr->ethreads_to_be_signalled_[i]->net_poll_) {
if (OB_SUCC(thr->ethreads_to_be_signalled_[i]->get_net_poll().timerfd_settime())) {
thr->ethreads_to_be_signalled_[i] = 0;
}
} else {
thr->ethreads_to_be_signalled_[i] = 0;
}
}
}
}
......@@ -156,6 +172,9 @@ void flush_signals(ObEThread *thr)
if (OB_FAIL(thr->ethreads_to_be_signalled_[i]->event_queue_external_.signal())) {
LOG_WARN("failed to do signal, it should not happened", K(ret));
}
if (NULL != thr->ethreads_to_be_signalled_[i]->net_poll_) {
thr->ethreads_to_be_signalled_[i]->get_net_poll().timerfd_settime();
}
if (NULL != thr->ethreads_to_be_signalled_[i]->signal_hook_) {
thr->ethreads_to_be_signalled_[i]->signal_hook_(*(thr->ethreads_to_be_signalled_[i]));
}
......
......@@ -5,6 +5,7 @@ obproxy/iocore/net/ob_connection.cpp\
obproxy/iocore/net/ob_inet.h\
obproxy/iocore/net/ob_inet.cpp\
obproxy/iocore/net/ob_socket_manager.h\
obproxy/iocore/net/ob_timerfd_manager.h\
obproxy/iocore/net/ob_net_vconnection.h\
obproxy/iocore/net/ob_unix_net.h\
obproxy/iocore/net/ob_unix_net.cpp\
......
......@@ -53,6 +53,7 @@ namespace net
#define EVENTIO_NETACCEPT 1
#define EVENTIO_READWRITE_VC 2
#define EVENTIO_ASYNC_SIGNAL 3
#define EVENTIO_TIMER 4
#ifdef USE_EDGE_TRIGGER_EPOLL
#define USE_EDGE_TRIGGER 1
......
......@@ -45,8 +45,6 @@ namespace net
}
// This will get set via either command line or ObProxyConfig.
// epoll timeout
int net_config_poll_timeout = -1;
int init_net(ObModuleVersion version, const ObNetOptions &net_options)
{
......@@ -69,7 +67,6 @@ int init_net(ObModuleVersion version, const ObNetOptions &net_options)
int update_net_options(const ObNetOptions &net_options)
{
int ret = OB_SUCCESS;
net_config_poll_timeout = static_cast<int32_t>(net_options.poll_timeout_);
if (OB_FAIL(update_cop_config(net_options.default_inactivity_timeout_, net_options.max_client_connections_))) {
PROXY_NET_LOG(WARN, "fail to update_cop_config",
K(net_options.default_inactivity_timeout_),
......
......@@ -79,7 +79,6 @@ namespace net
struct ObNetOptions
{
int64_t poll_timeout_;
int64_t max_connections_;
int64_t default_inactivity_timeout_;
int64_t max_client_connections_;
......
......@@ -44,8 +44,6 @@ namespace obproxy
namespace net
{
extern int net_config_poll_timeout;
class ObSocketManager
{
ObSocketManager() { };
......
/**
* Copyright (c) 2021 OceanBase
* OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OBPROXY_TIMERFD_MANAGER_H
#define OBPROXY_TIMERFD_MANAGER_H
#include <sys/timerfd.h>
namespace oceanbase
{
namespace obproxy
{
namespace net
{
class ObTimerFdManager
{
ObTimerFdManager() { };
~ObTimerFdManager() { };
public:
static int timerfd_create(int clockid, int flags, int &timerfd);
static int timerfd_settime(int timerfd, int flags, int64_t new_value_sec, int64_t new_value_nsec);
static void timerfd_close(int timerfd);
private:
DISALLOW_COPY_AND_ASSIGN(ObTimerFdManager);
};
inline int ObTimerFdManager::timerfd_create(int clockid, int flags, int &timerfd)
{
int ret = common::OB_SUCCESS;
timerfd = ::timerfd_create(clockid, flags);
if (OB_UNLIKELY(timerfd < 0)) {
ret = ob_get_sys_errno();
}
return ret;
}
inline int ObTimerFdManager::timerfd_settime(int timerfd, int flags, int64_t new_value_sec, int64_t new_value_nsec)
{
int ret = common::OB_SUCCESS;
struct itimerspec new_value;
new_value.it_value.tv_sec = new_value_sec; //Turn off the timer during initialization
new_value.it_value.tv_nsec = new_value_nsec;
new_value.it_interval.tv_sec = 0;
new_value.it_interval.tv_nsec = 0;
// Set the timer
ret = ::timerfd_settime(timerfd, flags, &new_value, NULL);
if (OB_UNLIKELY(ret < 0)) {
ret = ob_get_sys_errno();
}
return ret;
}
inline void ObTimerFdManager::timerfd_close(int timerfd)
{
if (timerfd >= 0) {
::close(timerfd);
}
}
} // end of namespace net
} // end of namespace obproxy
} // end of namespace oceanbase
#endif // OBPROXY_TIMERFD_MANAGER_H
......@@ -33,6 +33,7 @@
#include "iocore/net/ob_net.h"
#include "iocore/net/ob_unix_net.h"
#include "iocore/net/ob_event_io.h"
#include "iocore/net/ob_timerfd_manager.h"
using namespace oceanbase::common;
using namespace oceanbase::obproxy::event;
......@@ -205,7 +206,8 @@ int initialize_thread_for_net(ObEThread *thread)
ObNetPoll::ObNetPoll(ObNetHandler &nh)
: poll_descriptor_(NULL),
nh_(nh),
poll_timeout_(-1)
timer_fd_(OB_INVALID_INDEX),
ep_(NULL)
{
}
......@@ -213,6 +215,13 @@ ObNetPoll::~ObNetPoll()
{
delete poll_descriptor_;
poll_descriptor_ = NULL;
if (NULL != ep_) {
op_reclaim_free(ep_);
ep_ = NULL;
}
ObTimerFdManager::timerfd_close(timer_fd_);
}
int ObNetPoll::init()
......@@ -230,11 +239,36 @@ int ObNetPoll::init()
PROXY_NET_LOG(WARN, "fail to init poll_descriptor");
delete poll_descriptor_;
poll_descriptor_ = NULL;
} else if (OB_FAIL(ObTimerFdManager::timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK, timer_fd_))) {
PROXY_NET_LOG(WARN, "fail to create timerfd", K(timer_fd_), KERRMSGS, K(ret));
} else if (OB_FAIL(ObTimerFdManager::timerfd_settime(timer_fd_, 0, 0, 0))) {
PROXY_NET_LOG(WARN, "fail to set timerfd time", K(timer_fd_), KERRMSGS, K(ret));
} else if (OB_ISNULL(ep_ = op_reclaim_alloc(ObEventIO))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
PROXY_NET_LOG(ERROR, "fail to new ObEventIO", K(ret));
} else {
struct epoll_event ev;
memset(&ev, 0, sizeof(ev));
ev.events = EVENTIO_READ;
ev.data.ptr = ep_;
ep_->type_ = EVENTIO_TIMER;
if (OB_FAIL(ObSocketManager::epoll_ctl(poll_descriptor_->epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev))) {
PROXY_NET_LOG(WARN, "fail to epoll_ctl, op is EPOLL_CTL_ADD", K(poll_descriptor_->epoll_fd_), K_(timer_fd), K(ret));
}
}
}
return ret;
}
int ObNetPoll::timerfd_settime()
{
int ret = OB_SUCCESS;
if (timer_fd_ > 0 && OB_FAIL(ObTimerFdManager::timerfd_settime(timer_fd_, 0, 0, 1))) {
PROXY_NET_LOG(WARN, "fail to set timer time, it should not happened", K(timer_fd_), K(ret));
}
return ret;
}
ObInactivityCop::ObInactivityCop(ObProxyMutex *m)
: ObContinuation(m), default_inactivity_timeout_(1800),
total_connections_in_(0), max_connections_in_(0), connections_per_thread_in_(0)
......@@ -503,17 +537,18 @@ int ObNetHandler::main_net_event(int event, ObEvent *e)
ObEventIO *epd = NULL;
NET_INCREMENT_DYN_STAT(NET_HANDLER_RUN);
if (OB_LIKELY(!read_ready_list_.empty() || !write_ready_list_.empty()
|| !read_enable_list_.empty() || !write_enable_list_.empty())) {
poll_timeout = 0; // poll immediately returns -- we have triggered stuff to process right now
} else {
poll_timeout = net_config_poll_timeout;
}
if(OB_ISNULL(ethread = trigger_event_->ethread_)) {
ret = OB_ERR_UNEXPECTED;
PROXY_NET_LOG(WARN, "fail to get trigger_event_'s ethread", K(trigger_event_), K(ret));
} else {
if (OB_LIKELY(!read_ready_list_.empty() || !write_ready_list_.empty()
|| !read_enable_list_.empty() || !write_enable_list_.empty())) {
poll_timeout = 0; // poll immediately returns -- we have triggered stuff to process right now
} else {
poll_timeout = (int32_t)(hrtime_to_msec(ethread->sleep_time_));
}
ObPollDescriptor &pd = ethread->get_net_poll().get_poll_descriptor();
if (OB_FAIL(ObSocketManager::epoll_wait(pd.epoll_fd_,
pd.epoll_triggered_events_,
......@@ -562,6 +597,9 @@ int ObNetHandler::main_net_event(int event, ObEvent *e)
}
} else if (EVENTIO_ASYNC_SIGNAL == epd->type_) {
net_signal_hook_callback(*ethread);
} else if (EVENTIO_TIMER == epd->type_) {
uint64_t exp;
read(ethread->get_net_poll().get_timer_fd(), &exp, sizeof(uint64_t)); //Need to read uint64_t size, otherwise an error will occur
}
}
}
......
......@@ -60,13 +60,16 @@ public:
~ObNetPoll();
int init();
ObPollDescriptor &get_poll_descriptor() { return *poll_descriptor_; }
int timerfd_settime();
int get_timer_fd() { return timer_fd_; }
public:
ObPollDescriptor *poll_descriptor_;
private:
ObNetHandler &nh_;
int poll_timeout_;
int timer_fd_;
ObEventIO *ep_;
DISALLOW_COPY_AND_ASSIGN(ObNetPoll);
};
......
......@@ -309,6 +309,9 @@ inline bool ObUnixNetVConnection::handle_read_from_net_error(ObEThread &thread,
read_.triggered_ = false;
nh_->read_ready_list_.remove(this);
} else if (0 == total_read || OB_SYS_ECONNRESET == error) {
if (OB_SYS_ETIMEDOUT == error) {
PROXY_NET_LOG(INFO, "recv OB_SYS_ETIMEDOUT error when read, maybe KeepAlive fail");
}
read_.triggered_ = false;
nh_->read_ready_list_.remove(this);
if (EVENT_DONE == read_signal_done(VC_EVENT_EOS)) {
......@@ -354,6 +357,9 @@ inline bool ObUnixNetVConnection::handle_write_to_net_error(ObEThread &thread,
nh_->write_ready_list_.remove(this);
write_reschedule();
} else if (0 == total_write || OB_SYS_ECONNRESET == error) {
if (OB_SYS_ETIMEDOUT == error) {
PROXY_NET_LOG(INFO, "recv OB_SYS_ETIMEDOUT erroru when write, maybe KeepAlive fail");
}
write_.triggered_ = false;
if (EVENT_DONE == write_signal_done(VC_EVENT_EOS)) {
is_done = true;
......
......@@ -195,7 +195,6 @@ int ObProxy::init(ObProxyOptions &opts, ObAppVersionInfo &proxy_version)
regression_cont_.set_regression_test(opts.regression_test_);
#endif
ObNetOptions net_options;
net_options.poll_timeout_ = usec_to_msec(config_->net_config_poll_timeout);
net_options.default_inactivity_timeout_ = usec_to_sec(config_->default_inactivity_timeout);
net_options.max_client_connections_ = config_->client_max_connections;
......@@ -273,6 +272,32 @@ int ObProxy::start()
}
if (OB_SUCC(ret)) {
char *password1 = NULL;
char *password2 = NULL;
password1 = getenv("observer_sys_password");
password2 = getenv("observer_sys_password1");
if (NULL != password1) {
ObString key_string("observer_sys_password");
ObString value_string(password1);
if (OB_FAIL(get_global_proxy_config().update_config_item(key_string, value_string))) {
LOG_WARN("fail to update config", K(key_string));
}
}
if (OB_SUCC(ret) && NULL != password2) {
ObString key_string("observer_sys_password1");
ObString value_string(password2);
if (OB_FAIL(get_global_proxy_config().update_config_item(key_string, value_string))) {
LOG_WARN("fail to update config", K(key_string));
}
}
if (OB_SUCC(ret) && OB_FAIL(get_global_proxy_config().dump_config_to_local())) {
LOG_WARN("fail to dump config to local", K(ret));
}
}
if (OB_SUCC(ret) && config_->is_metadb_used()) {
if (is_force_remote_start_ && meta_client_proxy_.is_inited()) {
if (OB_FAIL(meta_client_proxy_.clear_raw_execute())) {
......@@ -874,7 +899,6 @@ int ObProxy::do_reload_config(obutils::ObProxyConfig &config)
if (OB_SUCC(ret)) {
// net related
ObNetOptions net_options;
net_options.poll_timeout_ = usec_to_msec(config_->net_config_poll_timeout);
net_options.default_inactivity_timeout_ = usec_to_sec(config.default_inactivity_timeout);
net_options.max_client_connections_ = config.client_max_connections;
update_net_options(net_options);
......@@ -901,6 +925,7 @@ int ObProxy::get_meta_table_server(ObIArray<ObProxyReplicaLocation> &replicas, O
const ObString user_name(ObProxyTableInfo::READ_ONLY_USERNAME);
const ObString database(ObProxyTableInfo::READ_ONLY_DATABASE);
ObString password(config_->observer_sys_password.str());
ObString password1(config_->observer_sys_password1.str());
ObSEArray<ObAddr, 5> rs_list;
// first get from local
......@@ -921,7 +946,7 @@ int ObProxy::get_meta_table_server(ObIArray<ObProxyReplicaLocation> &replicas, O
if (rs_list.count() <= 0) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("rs_list count must > 0", K(ret));
} else if (OB_FAIL(raw_client.init(user_name, password, database))) {
} else if (OB_FAIL(raw_client.init(user_name, password, database, password1))) {
LOG_WARN("fail to init raw mysql client", K(ret));
} else if (OB_FAIL(raw_client.set_server_addr(rs_list))) {
LOG_WARN("fail to set server addr", K(ret));
......
......@@ -43,6 +43,7 @@ static const ObString type_names[CACHED_VAR_MAX + 1] = {
ObString(OB_SV_LOWER_CASE_TABLE_NAMES),
ObString(OB_SV_TX_READ_ONLY),
ObString(OB_SV_READ_CONSISTENCY),
ObString(OB_SV_COLLATION_CONNECTION),
ObString("CACHED_VAR_MAX"),
};
......@@ -108,6 +109,11 @@ int ObCachedVariables::update_var(const ObCachedVariableType &type, const ObObj
break;
}
case CACHED_INT_VAR_COLLATION_CONNECTION: {
cached_vars_[index] = obj;
break;
}
case CACHED_VAR_MAX:
// not a cached variables, do nothing
break;
......
......@@ -34,6 +34,7 @@ enum ObCachedVariableType
CACHED_INT_VAR_LOWER_CASE_TABLE_NAMES,
CACHED_INT_VAR_TX_READ_ONLY,
CACHED_INT_VAR_READ_CONSISTENCY,
CACHED_INT_VAR_COLLATION_CONNECTION,
CACHED_VAR_MAX,
};
......@@ -50,6 +51,7 @@ public:
int update_var(const ObCachedVariableType &type, const common::ObObj &obj);
int64_t get_query_timeout() const { return get_int_var(CACHED_INT_VAR_QUERY_TIMEOUT); }
int64_t get_collation_connection() const { return get_int_var(CACHED_INT_VAR_COLLATION_CONNECTION); }
int64_t get_trx_timeout() const { return get_int_var(CACHED_INT_VAR_TRX_TIMEOUT); }
int64_t get_wait_timeout() const { return get_int_var(CACHED_INT_VAR_WAIT_TIMEOUT); }
int64_t get_net_read_timeout() const { return get_int_var(CACHED_INT_VAR_NET_READ_TIMEOUT); }
......@@ -60,6 +62,7 @@ public:
int64_t get_read_consistency() const { return get_int_var(CACHED_INT_VAR_READ_CONSISTENCY); }
const common::ObObj &get_query_timeout_obj() const { return get_obj_var(CACHED_INT_VAR_QUERY_TIMEOUT); }
const common::ObObj &get_collation_connection_obj() const { return get_obj_var(CACHED_INT_VAR_COLLATION_CONNECTION); }
const common::ObObj &get_trx_timeout_obj() const { return get_obj_var(CACHED_INT_VAR_TRX_TIMEOUT); }
const common::ObObj &get_wait_timeout_obj() const { return get_obj_var(CACHED_INT_VAR_WAIT_TIMEOUT); }
const common::ObObj &get_net_read_timeout_obj() const { return get_obj_var(CACHED_INT_VAR_NET_READ_TIMEOUT); }
......
......@@ -820,7 +820,10 @@ int ObConfigServerProcessor::swap_with_rslist(ObProxyJsonConfigInfo *new_json_in
&& OB_FAIL(new_json_info->set_master_cluster_id(old_cluster_info.cluster_name_,
old_cluster_info.master_cluster_id_))) {
LOG_WARN("fail to set cluster id", K(old_cluster_info), K(ret));
} else if (NULL != sub_cluster_info && OB_FAIL(new_json_info->set_cluster_web_rs_list(old_cluster_info.cluster_name_, old_cluster_info.master_cluster_id_, sub_cluster_info->web_rs_list_, ObString::make_string(cluster_role_to_str(sub_cluster_info->role_))))) {
} else if (NULL != sub_cluster_info
&& OB_FAIL(new_json_info->set_cluster_web_rs_list(old_cluster_info.cluster_name_, old_cluster_info.master_cluster_id_,
sub_cluster_info->web_rs_list_, sub_cluster_info->origin_web_rs_list_,
ObString::make_string(cluster_role_to_str(sub_cluster_info->role_))))) {
if (OB_ENTRY_NOT_EXIST != ret && OB_EAGAIN != ret) {
LOG_WARN("fail to set cluster web rs_list", K(old_cluster_info), K(ret));
} else {
......@@ -861,7 +864,8 @@ int ObConfigServerProcessor::swap_with_rslist(ObProxyJsonConfigInfo *new_json_in
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(new_json_info->set_cluster_web_rs_list(old_it->cluster_name_, sub_it->cluster_id_,
sub_it->web_rs_list_, ObString::make_string(cluster_role_to_str(sub_it->role_))))) {
sub_it->web_rs_list_, sub_it->origin_web_rs_list_,
ObString::make_string(cluster_role_to_str(sub_it->role_))))) {
if (OB_ENTRY_NOT_EXIST != ret && OB_EAGAIN != ret) {
LOG_WARN("fail to set cluster web rs_list", KPC(old_it.value_), K(ret));
} else if (OB_EAGAIN == ret) {
......@@ -1938,6 +1942,17 @@ int ObConfigServerProcessor::fetch_rs_list_from_url(const char *url, const ObStr
return ret;
}
int ObConfigServerProcessor::swap_origin_web_rslist_and_build_sys(const ObString &cluster, const int64_t cluster_id, const bool need_save_rslist_hash)
{
int ret = OB_SUCCESS;
if (OB_FAIL(json_config_info_->swap_origin_web_rslist_and_build_sys(cluster, cluster_id, need_save_rslist_hash))) {
LOG_WARN("fail to parse remote rslist", K(cluster), K(cluster_id), K(ret));
}
return ret;
}
int ObConfigServerProcessor::refresh_idc_list_from_url(const char *url,
const ObString &cluster_name, const int64_t cluster_id, ObProxyIDCList &idc_list)
{
......@@ -1951,7 +1966,7 @@ int ObConfigServerProcessor::refresh_idc_list_from_url(const char *url,
LOG_ERROR("fail to alloc memory for region idc json info", K(ret));
} else if (FALSE_IT(json.assign_buffer(buf, static_cast<int32_t>(OB_PROXY_CONFIG_BUFFER_SIZE)))) {
// impossible
} else if (OB_FAIL(do_fetch_json_info(url, json))) {
} else if (OB_FAIL(do_fetch_json_info(url, json, CURL_IDC_TRANSFER_TIMEOUT))) {
LOG_INFO("fail to fetch region idc json info", K(json), K(ret));
} else {
Value *root = NULL;
......@@ -1996,7 +2011,7 @@ int ObConfigServerProcessor::refresh_idc_list_from_url(const char *url,
return ret;
}
int ObConfigServerProcessor::do_fetch_json_info(const char *url, ObString &json)
int ObConfigServerProcessor::do_fetch_json_info(const char *url, ObString &json, int64_t timeout)
{
int ret = OB_SUCCESS;
......@@ -2006,7 +2021,7 @@ int ObConfigServerProcessor::do_fetch_json_info(const char *url, ObString &json)
} else {
int64_t fetch_attempts = 0;
do {
if (OB_FAIL(fetch_by_curl(url, CURL_TRANSFER_TIMEOUT,
if (OB_FAIL(fetch_by_curl(url, timeout,
static_cast<void *>(&json), write_data))) {
LOG_WARN("fail to fetch json info", "try attempts:", fetch_attempts, K(url), K(is_inited_), K(ret));
}
......
......@@ -57,6 +57,7 @@ public:
const int64_t cluster_id,
common::ObIArray<common::ObAddr> &rs_list,
const bool need_update_dummy_entry = true);
int swap_origin_web_rslist_and_build_sys(const ObString &cluster, const int64_t cluster_id, const bool need_save_rslist_hash);
int refresh_idc_list(const common::ObString &cluster_name, const int64_t cluster_id, ObProxyIDCList &idc_list);
......@@ -176,7 +177,7 @@ private:
int refresh_json_config_info(const bool force_refresh = false);
int get_json_config_info(const char *url, const bool version_only = false);
int parse_json_config_info(const common::ObString &json_str, const bool version_only = false);
virtual int do_fetch_json_info(const char *url, common::ObString &json);
virtual int do_fetch_json_info(const char *url, common::ObString &json, int64_t timeout = CURL_TRANSFER_TIMEOUT);
int handle_content_string(char *content, const int64_t content_length);
int init_json(const common::ObString &json_str, json::Value *&json_root, common::ObArenaAllocator &allocator);
......@@ -200,6 +201,7 @@ private:
static const int64_t ITEM_STR_SIZE = 512;
static const int64_t CURL_CONNECTION_TIMEOUT = 10;
static const int64_t CURL_TRANSFER_TIMEOUT = 5;
static const int64_t CURL_IDC_TRANSFER_TIMEOUT = 1;
static const int64_t CURL_TRANSFER_TIMEOUT_LARGE = 120;
static const ObConfigServerHeaderVersion HEADER_VERSION = HEADER_VERSION_ZLIB_COMPRESS;
......
......@@ -156,6 +156,7 @@ public:
ObCongestionZoneState *get_zone_state(const common::ObString &zone_name);
bool is_base_servers_added() const { return is_base_servers_added_; }
void set_base_servers_added() { is_base_servers_added_ = true; }
void clear_base_servers_added() { is_base_servers_added_ = false; }
bool is_congestion_avail();
int update_tc_congestion_map(ObCongestionEntry &entry);
DECLARE_TO_STRING;
......
......@@ -1318,6 +1318,7 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O
//1. get config server username and passwd
ObString string_username;
ObString string_passwd;
ObString string_passwd1;
ObString string_db;
char full_user_name[OB_PROXY_FULL_USER_NAME_MAX_LEN + 1] = {0};
char passwd_staged1_buf[ENC_STRING_BUF_LEN] = {0}; // 1B '*' + 40B octal num
......@@ -1360,6 +1361,8 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O
string_username.assign_ptr(full_user_name, static_cast<ObString::obstr_size_t>(pos));
string_passwd.assign_ptr(get_global_proxy_config().observer_sys_password.str(),
static_cast<ObString::obstr_size_t>(strlen(get_global_proxy_config().observer_sys_password.str())));
string_passwd1.assign_ptr(get_global_proxy_config().observer_sys_password1.str(),
static_cast<ObString::obstr_size_t>(strlen(get_global_proxy_config().observer_sys_password1.str())));
string_db.assign_ptr(ObProxyTableInfo::READ_ONLY_DATABASE,
static_cast<ObString::obstr_size_t>(STRLEN(ObProxyTableInfo::READ_ONLY_DATABASE)));
}
......@@ -1394,7 +1397,7 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O
LOG_WARN("fail to set addr", K(proxy_ip_), K(proxy_port_), K(ret));
} else if (OB_FAIL(local_addrs.push_back(addr))) {
LOG_WARN("fail to push addr to local_addrs", K(addr), K(ret));
} else if (OB_FAIL(raw_client.init(string_username, string_passwd, string_db))) {
} else if (OB_FAIL(raw_client.init(string_username, string_passwd, string_db, string_passwd1))) {
LOG_WARN("fail to init raw mysql client", K(string_username), K(string_db), K(ret));
} else if (OB_FAIL(raw_client.set_server_addr(local_addrs))) {
LOG_WARN("fail to set server addr", K(ret));
......
......@@ -200,7 +200,7 @@ public:
//net related
DEF_BOOL(frequent_accept, "true", "frequent accept", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_INT(net_accept_threads, "2", "[0,8]", "net accept threads num, [0, 8]", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_TIME(net_config_poll_timeout, "1ms", "[0,]", "epoll_wait timeout for net events, [0, +∞], if set a value <= 0, proxy treat it as 0", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_TIME(net_config_poll_timeout, "1ms", "[0,]", "not used, just for compatible", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_TIME(default_inactivity_timeout, "180000s", "[1s,30d]", "default inactivity timeout, [1s, 30d]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_CAP(sock_recv_buffer_size_out, "0", "[0,8MB]", "sock param, recv buffer size, [0, 8MB], if set a negative value, proxy treat it as 0", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_CAP(sock_send_buffer_size_out, "0", "[0,8MB]", "sock param, send buffer size, [0, 8MB], if set a negative value, proxy treat it as 0", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
......@@ -283,7 +283,7 @@ public:
DEF_BOOL(enable_bad_route_reject, "false", "if enabled, bad route request will be rejected, e.g. first statement of transaction opened by BEGIN(or START TRANSACTION) without table name", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_BOOL(enable_partition_table_route, "true", "if enabled, partition table will be accurate routing", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_BOOL(enable_compression_protocol, "true", "if enabled, proxy will use compression protocol with server", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_BOOL(enable_ob_protocol_v2, "false", "if enabled, proxy will use oceanbase protocol 2.0 with server", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_BOOL(enable_ob_protocol_v2, "true", "if enabled, proxy will use oceanbase protocol 2.0 with server", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_BOOL(enable_reroute, "false", "if this and protocol_v2 enabled, proxy will reroute when routing error", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_BOOL(enable_pl_route, "true", "if enabled, pl will be accurate routing", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
......@@ -345,6 +345,7 @@ public:
// in public cloud, will assign a vip addr to proxy. qa_mode_mock_slb_vip is a vip addr for testing
DEF_STR(qa_mode_mock_public_cloud_slb_addr, "127.0.0.1:33045", "mock public cloud slb addr", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_INT(qa_mode_mock_public_cloud_vid, "1", "[1,102400]", "mock public cloud vid", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_STR(proxy_route_policy, "", "proxy route policy", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS);
DEF_STR(mysql_version, "5.6.25", "returned version for mysql mode, default value is 5.6.25. If set, proxy will send new version when user connect to proxy", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER)
// sql table cache
......@@ -354,7 +355,7 @@ public:
DEF_BOOL(enable_cloud_full_username, "false", "used for cloud user, if set false, treat all login user as username", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS);
DEF_BOOL(skip_proxyro_check, "false", "used for proxro@sys, if set false, access denied", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS);
DEF_BOOL(skip_proxy_sys_private_check, "false", "skip_proxy_sys_private_check", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
DEF_BOOL(skip_proxy_sys_private_check, "true", "skip_proxy_sys_private_check", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER);
// SSL related config
DEF_BOOL(enable_client_ssl, "false", "if enabled, proxy will try best to connect client with ssl",
CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS);
......@@ -436,6 +437,7 @@ public:
DEF_STR(inspector_password, "", "password for inspector user", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS);
DEF_STR(obproxy_sys_password, "", "password for obproxy sys user", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS);
DEF_STR(observer_sys_password, "", "password for observer sys user", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS);
DEF_STR(observer_sys_password1, "", "password for observer sys user", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS);
};
ObProxyConfig &get_global_proxy_config();
......
......@@ -1839,13 +1839,7 @@ int ObProxyConfigProcessor::update_global_proxy_config(const ObProxyAppConfig &n
ret = OB_ERR_NULL_VALUE;
LOG_WARN("fail to get reload config", K(ret));
}
if (OB_SUCC(ret)) {
if (NULL == cur_app_config || new_app_config.init_config_.version_ != cur_app_config->init_config_.version_) {
if (OB_FAIL(do_update_global_proxy_config(new_app_config.init_config_, old_global_config_items))) {
LOG_WARN("fail to update init config to global proxy config", K_(new_app_config.init_config), K(ret));
}
}
}
// Update the configuration of dynamic_config, the init configuration passes in the parameters at startup
if (OB_SUCC(ret)) {
if (NULL == cur_app_config || new_app_config.dynamic_config_.version_ != cur_app_config->dynamic_config_.version_) {
if (OB_FAIL(do_update_global_proxy_config(new_app_config.dynamic_config_, old_global_config_items))) {
......
......@@ -413,7 +413,7 @@ int ObProxyCreateServerConnCont::do_create_server_conn()
LOG_WARN("fail to init proxy", K(login_info.username_), K(login_info.db_));
} else if (DB_OB_ORACLE == server_type || DB_OB_MYSQL == server_type) {
if (OB_FAIL(proxy->rebuild_client_pool(cr_, is_meta_mysql_client,
cluster_name, OB_DEFAULT_CLUSTER_ID, login_info.username_, passwd_string, login_info.db_, &client_pool_option))) {
cluster_name, OB_DEFAULT_CLUSTER_ID, login_info.username_, passwd_string, login_info.db_, "", &client_pool_option))) {
LOG_WARN("fail to create mysql client pool", K(login_info), K(ret));
} else {
LOG_DEBUG("succ to create ob client pool", K(login_info.username_), K(server_type),
......@@ -421,7 +421,7 @@ int ObProxyCreateServerConnCont::do_create_server_conn()
}
} else if (DB_MYSQL == server_type) {
if (OB_FAIL(proxy->rebuild_client_pool(schema_key.shard_conn_,
is_meta_mysql_client, user_name, passwd_string, database_name, &client_pool_option))) {
is_meta_mysql_client, user_name, passwd_string, database_name, "", &client_pool_option))) {
LOG_WARN("fail to create mysql client pool", K(user_name), K(database_name), K(ret));
} else {
LOG_DEBUG("succ to create mysql clinet pool", K(login_info.username_), K(database_name), K(server_type),
......
......@@ -811,11 +811,44 @@ int ObProxyJsonConfigInfo::parse(const Value *json_value)
int ObProxyJsonConfigInfo::parse_local_rslist(const Value *root)
{
int ret = OB_SUCCESS;
bool is_from_local = true;
if (OB_FAIL(parse_rslist_array_data(root, ObString::make_empty_string(), is_from_local))) {
LOG_WARN("fail to parse rs list array data for local rslist", K(ret));
if (OB_FAIL(ObProxyJsonUtils::check_config_info_type(root, JT_ARRAY))) {
LOG_WARN("fail to check local rs list", K(ret));
} else {
LOG_DEBUG("succ to parse all local rslist");
bool is_from_local = true;
ObString app_name = ObString::make_empty_string();
int64_t json_cluster_id = OB_DEFAULT_CLUSTER_ID;
LocationList web_rslist;
bool is_primary = false;
ObString cluster_name;
DLIST_FOREACH(it, root->get_array()) {
json_cluster_id = OB_DEFAULT_CLUSTER_ID;
web_rslist.reuse();
is_primary = false;
cluster_name.reset();
if (OB_FAIL(parse_rslist_data(it, app_name, json_cluster_id, web_rslist, is_primary, cluster_name, is_from_local))) {
if (OB_EAGAIN == ret) {
// here e_again means local rslist for this cluster is empty, do nothing and go on parsing
ret = OB_SUCCESS;
} else {
LOG_WARN("fail to parse rslist data", K(ret));
}
}
if (OB_SUCC(ret) && is_primary) {
int64_t master_cluster_id = OB_DEFAULT_CLUSTER_ID;
if (OB_FAIL(get_master_cluster_id(cluster_name, master_cluster_id))) {
LOG_WARN("fail to get master cluster id", K(cluster_name), K(ret));
} else if (OB_DEFAULT_CLUSTER_ID == master_cluster_id) {
if (OB_FAIL(set_master_cluster_id(cluster_name, json_cluster_id))) {
LOG_WARN("fail to set master cluster id", K(json_cluster_id), K(ret));
} else if (OB_FAIL(ObRouteUtils::build_and_add_sys_dummy_entry(cluster_name, OB_DEFAULT_CLUSTER_ID, web_rslist, !is_from_local))) {
LOG_WARN("fail to build and add dummy entry", K(cluster_name), K(web_rslist), K(ret));
}
}
}
} //end traverse rs list array
}
return ret;
}
......@@ -1026,7 +1059,10 @@ int ObProxyJsonConfigInfo::parse_remote_rslist(const Value *root, const ObString
if (OB_FAIL(parse_rslist_data(value, appname, json_cluster_id, web_rslist, is_primary,
cluster_name, is_from_local, need_update_dummy_entry)) && OB_EAGAIN != ret) {
LOG_WARN("fail to parse remote rslist data", K(ret));
} else if (OB_DEFAULT_CLUSTER_ID == cluster_id || is_primary) {
// If there is no cluster id, there must be no active/standby case.
// It must be set, otherwise the cluster resource of the main library cannot be obtained when get_cluster_resource
// If you bring the cluster id, because you want to access a specific library, the main library information is not updated
} else if (OB_DEFAULT_CLUSTER_ID == cluster_id) {
if (OB_FAIL(set_master_cluster_id(is_from_local ? cluster_name : appname, json_cluster_id))) {
LOG_WARN("fail to set master cluster id", K(json_cluster_id), K(ret));
} else if (OB_FAIL(ObRouteUtils::build_and_add_sys_dummy_entry(
......@@ -1116,26 +1152,28 @@ int ObProxyJsonConfigInfo::parse_rslist_data(const Value *json_value, const ObSt
}
}
const bool is_rslist = !is_from_local;
web_rslist.reuse();
if (OB_FAIL(parse_rslist_item(rslist, is_from_local ? cluster_name : appname, web_rslist, false))) {
LOG_WARN("fail to parse rslist item", K(rslist), K(ret));
} else if (NULL != readonly_rslist
&& OB_FAIL(parse_rslist_item(readonly_rslist, is_from_local ? cluster_name : appname, web_rslist, true))) {
LOG_WARN("fail to parse readonly_rslist item", K(readonly_rslist), K(ret));
} else if (OB_FAIL(reset_create_failure_count(is_from_local ? cluster_name : appname, json_cluster_id))) {
LOG_WARN("fail to reset_create_failure_count", K(json_cluster_id), K(ret));
} else if (web_rslist.empty()) {
LOG_INFO("rslist is empty", K(web_rslist), K(json_cluster_id), K(cluster_name));
} else if (OB_FAIL(set_cluster_web_rs_list(is_from_local ? cluster_name : appname, json_cluster_id, web_rslist,
role_str.empty() ? ObString::make_string(PRIMARY_ROLE) : role_str))) {
if (OB_EAGAIN == ret) {
LOG_DEBUG("web rslist is not changed, no need to update", K(role_str), K(ret));
ret = OB_SUCCESS;
} else {
LOG_WARN("fail to set cluster web rs list", K(web_rslist), K(role_str), K(ret));
if (OB_SUCC(ret)) {
web_rslist.reuse();
if (OB_FAIL(parse_rslist_item(rslist, is_from_local ? cluster_name : appname, web_rslist, false))) {
LOG_WARN("fail to parse rslist item", K(rslist), K(ret));
} else if (NULL != readonly_rslist
&& OB_FAIL(parse_rslist_item(readonly_rslist, is_from_local ? cluster_name : appname, web_rslist, true))) {
LOG_WARN("fail to parse readonly_rslist item", K(readonly_rslist), K(ret));
} else if (OB_FAIL(reset_create_failure_count(is_from_local ? cluster_name : appname, json_cluster_id))) {
LOG_WARN("fail to reset_create_failure_count", K(json_cluster_id), K(ret));
} else if (web_rslist.empty()) {
LOG_INFO("rslist is empty", K(web_rslist), K(json_cluster_id), K(cluster_name));
} else if (OB_FAIL(set_cluster_web_rs_list(is_from_local ? cluster_name : appname, json_cluster_id, web_rslist,
web_rslist, role_str.empty() ? ObString::make_string(PRIMARY_ROLE) : role_str))) {
if (OB_EAGAIN == ret) {
LOG_DEBUG("web rslist is not changed, no need to update", K(role_str), K(ret));
ret = OB_SUCCESS;
} else {
LOG_WARN("fail to set cluster web rs list", K(web_rslist), K(role_str), K(ret));
}
}
}
if (OB_SUCC(ret)) {
if (role_str.empty() || role_str.case_compare(PRIMARY_ROLE) == 0) {
is_primary = true;
......@@ -1153,6 +1191,7 @@ int ObProxyJsonConfigInfo::parse_rslist_data(const Value *json_value, const ObSt
}
}
if (OB_SUCC(ret) && need_update_dummy_entry) {
const bool is_rslist = !is_from_local;
if (OB_FAIL(ObRouteUtils::build_and_add_sys_dummy_entry(
is_from_local ? cluster_name : appname, json_cluster_id, web_rslist, is_rslist))) {
LOG_WARN("fail to build and add dummy entry", K(cluster_name), K(cluster_id), K(web_rslist), K(ret));
......@@ -1163,6 +1202,36 @@ int ObProxyJsonConfigInfo::parse_rslist_data(const Value *json_value, const ObSt
return ret;
}
int ObProxyJsonConfigInfo::swap_origin_web_rslist_and_build_sys(const ObString &cluster_name, const int64_t cluster_id, const bool need_save_rslist_hash)
{
int ret = OB_SUCCESS;
ObProxySubClusterInfo *sub_cluster_info = NULL;
if (OB_FAIL(reset_create_failure_count(cluster_name, cluster_id))) {
LOG_WARN("fail to reset_create_failure_count", K(cluster_name), K(cluster_id), K(ret));
} else if (OB_FAIL(get_sub_cluster_info(cluster_name, cluster_id, sub_cluster_info))) {
LOG_WARN("cluster not exist", K(cluster_name), K(cluster_id), K(ret));
} else if (OB_ISNULL(sub_cluster_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("cluster_info is NULL", K(cluster_name), K(cluster_id), K(ret));
} else {
LOG_INFO("will update rslist", K(cluster_name), K(cluster_id),
"real cluster_id", sub_cluster_info->cluster_id_,
"old rslist", sub_cluster_info->web_rs_list_,
"new rslist", sub_cluster_info->origin_web_rs_list_);
if (OB_FAIL(sub_cluster_info->web_rs_list_.assign(sub_cluster_info->origin_web_rs_list_))) {
LOG_WARN("fail to set cluster web_rs_list", K(cluster_name), K(cluster_id),
"origin_web_rs_list", sub_cluster_info->origin_web_rs_list_, K(ret));
} else if (OB_FAIL(ObRouteUtils::build_and_add_sys_dummy_entry(cluster_name, cluster_id, sub_cluster_info->origin_web_rs_list_, true))) {
LOG_WARN("fail to build and add dummy entry", K(cluster_name), K(cluster_id),
"origin_web_rs_list", sub_cluster_info->origin_web_rs_list_, K(ret));
} else if (need_save_rslist_hash) {
sub_cluster_info->rs_list_hash_ = ObProxyClusterInfo::get_server_list_hash(sub_cluster_info->origin_web_rs_list_);
}
}
return ret;
}
//{
// "Message":"successful",
// "Success":true,
......@@ -1701,14 +1770,14 @@ int ObProxyJsonConfigInfo::copy_bin_url(char *bin_url, const int64_t len) const
}
int ObProxyJsonConfigInfo::set_cluster_web_rs_list(const ObString &cluster_name, const int64_t cluster_id,
const LocationList &web_rs_list, const ObString &role, const uint64_t cur_rs_list_hash/*0*/)
const LocationList &web_rs_list, const LocationList &origin_web_rs_list, const ObString &role, const uint64_t cur_rs_list_hash/*0*/)
{
int ret = OB_SUCCESS;
ObProxyClusterInfo *cluster_info = NULL;
ObProxySubClusterInfo *sub_cluster_info = NULL;
bool new_sub_cluster_info = false;
if (web_rs_list.empty()) {
LOG_INFO("rslist is empty", K(web_rs_list), K(cluster_name));
if (web_rs_list.empty() && origin_web_rs_list.empty()) {
LOG_INFO("rslist is empty", K(web_rs_list), K(origin_web_rs_list), K(cluster_name));
} else {
if (cluster_name == OB_META_DB_CLUSTER_NAME) {
cluster_info = const_cast<ObProxyClusterInfo *>(&data_info_.meta_table_info_.cluster_info_);
......@@ -1739,30 +1808,34 @@ int ObProxyJsonConfigInfo::set_cluster_web_rs_list(const ObString &cluster_name,
if (OB_ISNULL(sub_cluster_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("sub cluster info is null", K(ret));
} else if (!sub_cluster_info->is_web_rs_list_changed(web_rs_list)
&& !sub_cluster_info->is_cluster_role_changed(role)) {
ret = OB_EAGAIN;
} else {
LOG_INFO("will update rslist",
"old rslist", sub_cluster_info->web_rs_list_,
"new rslist", web_rs_list,
"old cluster role", cluster_role_to_str(sub_cluster_info->role_),
K(role), K(cluster_name), K(cluster_id));
if (OB_FAIL(sub_cluster_info->web_rs_list_.assign(web_rs_list))) {
LOG_WARN("fail to set cluster web_rs_list", K(cluster_name), K(cluster_id), K(web_rs_list), K(ret));
} else if (!origin_web_rs_list.empty() && OB_FAIL(sub_cluster_info->origin_web_rs_list_.assign(origin_web_rs_list))) {
LOG_WARN("fail to set cluster origin_web_rs_list", K(cluster_name), K(cluster_id), K(origin_web_rs_list), K(ret));
} else if (!web_rs_list.empty()) {
if (!sub_cluster_info->is_web_rs_list_changed(web_rs_list)
&& !sub_cluster_info->is_cluster_role_changed(role)) {
ret = OB_EAGAIN;
} else {
if (0 == cur_rs_list_hash) {
sub_cluster_info->rs_list_hash_ = ObProxyClusterInfo::get_server_list_hash(web_rs_list);
LOG_INFO("will update rslist",
"old rslist", sub_cluster_info->web_rs_list_,
"new rslist", web_rs_list,
"old cluster role", cluster_role_to_str(sub_cluster_info->role_),
K(role), K(cluster_name), K(cluster_id));
if (OB_FAIL(sub_cluster_info->web_rs_list_.assign(web_rs_list))) {
LOG_WARN("fail to set cluster web_rs_list", K(cluster_name), K(cluster_id), K(web_rs_list), K(ret));
} else {
sub_cluster_info->rs_list_hash_ = cur_rs_list_hash;
}
if (role.case_compare(PRIMARY_ROLE) == 0) {
sub_cluster_info->role_ = PRIMARY;
} else if (role.case_compare(STANDBY_ROLE) == 0) {
sub_cluster_info->role_ = STANDBY;
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected role", K(role), K(cluster_name), K(cluster_id), K(ret));
if (0 == cur_rs_list_hash) {
sub_cluster_info->rs_list_hash_ = ObProxyClusterInfo::get_server_list_hash(web_rs_list);
} else {
sub_cluster_info->rs_list_hash_ = cur_rs_list_hash;
}
if (role.case_compare(PRIMARY_ROLE) == 0) {
sub_cluster_info->role_ = PRIMARY;
} else if (role.case_compare(STANDBY_ROLE) == 0) {
sub_cluster_info->role_ = STANDBY;
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected role", K(role), K(cluster_name), K(cluster_id), K(ret));
}
}
}
}
......@@ -1886,7 +1959,7 @@ int ObProxyJsonConfigInfo::add_default_cluster_info(ObProxyClusterInfo *cluster_
{
int ret = OB_SUCCESS;
int64_t default_cluster_id = OB_DEFAULT_CLUSTER_ID;
bool is_rslist = true;
bool is_rslist = false;
ObProxySubClusterInfo *sub_cluster_info = NULL;
if (OB_ISNULL(cluster_info)) {
ret = OB_INVALID_ARGUMENT;
......@@ -1898,7 +1971,9 @@ int ObProxyJsonConfigInfo::add_default_cluster_info(ObProxyClusterInfo *cluster_
cluster_info->master_cluster_id_ = default_cluster_id;
sub_cluster_info->cluster_id_ = default_cluster_id;
sub_cluster_info->role_ = PRIMARY;
if (OB_FAIL(sub_cluster_info->web_rs_list_.assign(web_rs_list))) {
if (OB_FAIL(sub_cluster_info->origin_web_rs_list_.assign(web_rs_list))) {
LOG_WARN("fail to set default cluster origin_web_rs_list", K(cluster_info), K(web_rs_list), K(ret));
} else if (OB_FAIL(sub_cluster_info->web_rs_list_.assign(web_rs_list))) {
LOG_WARN("fail to set default cluster web_rs_list", K(cluster_info), K(web_rs_list), K(ret));
} else if (OB_FAIL(ObRouteUtils::build_and_add_sys_dummy_entry(
cluster_info->cluster_name_, default_cluster_id, web_rs_list, is_rslist))) {
......
......@@ -357,7 +357,9 @@ public:
int update_rslist(const LocationList &rs_list, const uint64_t hash = 0);
int get_idc_region(const common::ObString &idc_name,
ObProxyNameString &region_name) const;
void reuse_rslist() { web_rs_list_.reuse(); }
void reuse_rslist() {
web_rs_list_.reuse();
}
void reuse_idc_list() { idc_list_.reuse(); }
DECLARE_TO_STRING;
......@@ -369,6 +371,7 @@ public:
uint64_t rs_list_hash_;
int64_t create_failure_count_;//if cnt > 3 && rslist exist , reset rslist;
LocationList web_rs_list_;
LocationList origin_web_rs_list_;
ObProxyIDCList idc_list_;
LINK(ObProxySubClusterInfo, sub_cluster_link_);
......@@ -666,6 +669,7 @@ public:
int parse_rslist_item(const json::Value *root, const common::ObString &appname,
LocationList &web_rslist, const bool is_readonly_zone);
int get_rslist_file_max_size(int64_t &max_size);
int swap_origin_web_rslist_and_build_sys(const ObString &cluster_name, const int64_t cluster_id, const bool need_save_rslist_hash);
int idc_list_to_json(char *buf, const int64_t buf_len, int64_t &data_len);
int parse_local_idc_list(const json::Value *root);
......@@ -753,6 +757,7 @@ public:
int set_cluster_web_rs_list(const common::ObString &cluster_name, const int64_t cluster_id,
const LocationList &web_rs_list,
const LocationList &origin_web_rs_list,
const common::ObString &role,
const uint64_t cur_rs_list_hash = 0);
int set_master_cluster_id(const common::ObString &cluster_name, const int64_t cluster_id);
......
......@@ -868,6 +868,7 @@ int ObProxySqlParser::parse_sql(const ObString &sql,
const ObProxyParseMode parse_mode,
ObSqlParseResult &sql_parse_result,
const bool use_lower_case_name,
ObCollationType connection_collation,
const bool drop_origin_db_table_name /*false*/,
const bool is_sharding_request /*false*/)
{
......@@ -887,7 +888,7 @@ int ObProxySqlParser::parse_sql(const ObString &sql,
ObProxyParseResult obproxy_parse_result;
int tmp_ret = OB_SUCCESS;
if (OB_SUCCESS != (tmp_ret = obproxy_parser.parse(sql, obproxy_parse_result))) {
if (OB_SUCCESS != (tmp_ret = obproxy_parser.parse(sql, obproxy_parse_result, connection_collation))) {
LOG_INFO("fail to parse sql, will go on anyway", K(sql), K(tmp_ret));
} else if (OB_SUCCESS != (tmp_ret = sql_parse_result.load_result(obproxy_parse_result, use_lower_case_name,
drop_origin_db_table_name, is_sharding_request))) {
......
......@@ -888,6 +888,7 @@ public:
const ObProxyParseMode parse_mode,
ObSqlParseResult &sql_parse_result,
const bool use_lower_case_name,
common::ObCollationType connection_collation,
const bool drop_origin_db_table_name = false,
const bool is_sharding_request = false);
......
......@@ -165,9 +165,10 @@ int ObRslistFetchCont::init_task()
{
int ret = OB_SUCCESS;
ObConfigServerProcessor &cs_processor = get_global_config_server_processor();
if (OB_LIKELY(get_global_proxy_config().with_config_server_)) {
ObSEArray<ObAddr, 5> rs_list;
ObConfigServerProcessor &cs_processor = get_global_config_server_processor();
if (OB_FAIL(cs_processor.get_newest_cluster_rs_list(cr_->get_cluster_name(),
cr_->get_cluster_id(), rs_list, need_update_dummy_entry_))) {
LOG_WARN("fail to get cluster rslist", K_(cr_->cluster_info_key), K(ret));
......@@ -178,6 +179,16 @@ int ObRslistFetchCont::init_task()
fetch_result_ = true;
}
if (!fetch_result_) {
// If rstlist is started, do not modify the rslist_hash value
bool need_save_rslist_hash = get_global_proxy_config().with_config_server_;
if (OB_FAIL(cs_processor.swap_origin_web_rslist_and_build_sys(cr_->get_cluster_name(), cr_->get_cluster_id(), need_save_rslist_hash))) {
LOG_WARN("fail to swap origin web rslist", K_(cr_->cluster_info_key), K(ret));
} else {
fetch_result_ = true;
}
}
LOG_DEBUG("finish to ObRslistFetchCont", K_(cr_->cluster_info_key), K(ret));
need_callback_ = true;
......@@ -204,6 +215,7 @@ int ObIDCListFetchCont::init_task()
if (OB_FAIL(cs_processor.refresh_idc_list(cr_->get_cluster_name(), cr_->get_cluster_id(), idc_list))) {
LOG_INFO("fail to refresh_idc_list", "cluster_name", cr_->get_cluster_name(),
"cluster_id", cr_->get_cluster_id(), K(ret));
fetch_result_ = true;
} else {
fetch_result_ = true;
}
......@@ -1464,8 +1476,9 @@ int ObClusterResource::init_local_config(const ObResourcePoolConfig &config)
const ObString user_name(ObProxyTableInfo::READ_ONLY_USERNAME);
const ObString database(ObProxyTableInfo::READ_ONLY_DATABASE);
ObString password(get_global_proxy_config().observer_sys_password.str());
ObString password1(get_global_proxy_config().observer_sys_password1.str());
if (OB_FAIL(mysql_proxy_.init(timeout_ms, user_name, password, database))) {
if (OB_FAIL(mysql_proxy_.init(timeout_ms, user_name, password, database, password1))) {
LOG_WARN("fail to init mysql proxy", K(ret));
} else if (OB_FAIL(rebuild_mysql_client_pool(
get_global_resource_pool_processor().get_default_cluster_resource()))) {
......@@ -1594,9 +1607,10 @@ int ObClusterResource::rebuild_mysql_client_pool(ObClusterResource *cr)
const ObString user_name(ObProxyTableInfo::READ_ONLY_USERNAME);
const ObString database(ObProxyTableInfo::READ_ONLY_DATABASE);
ObString password(get_global_proxy_config().observer_sys_password.str());
ObString password1(get_global_proxy_config().observer_sys_password1.str());
const bool is_meta_mysql_client = (get_global_resource_pool_processor().get_default_cluster_resource() == cr);
if (OB_FAIL(mysql_proxy_.rebuild_client_pool(cr, is_meta_mysql_client, get_cluster_name(), get_cluster_id(), user_name,
password, database))) {
password, database, password1))) {
LOG_WARN("fail to create mysql client pool", K(ret));
}
}
......
......@@ -975,7 +975,7 @@ int ObServerStateRefreshCont::handle_rs_changed(const ObIArray<ObServerStateInfo
for (int64_t i = 0; found_rs && i < rslist.count(); ++i) {
found_rs = false;
for (int64_t j = 0; !found_rs && j < servers_state.count(); ++j) {
if (rslist.at(i).server_ == servers_state.at(j).replica_.server_) {
if (rslist.at(i).server_.is_ip_loopback() || rslist.at(i).server_ == servers_state.at(j).replica_.server_) {
found_rs = true;
}
}
......@@ -1157,6 +1157,9 @@ int ObServerStateRefreshCont::add_refresh_rslist_task(const bool need_update_dum
cont->destroy();
cont = NULL;
}
} else {
congestion_manager_->clear_base_servers_added();
LOG_INFO("congestion manager's base servers has cleared", K_(cluster_name), K_(cluster_id));
}
} else {
LOG_DEBUG("refresh rslist task has been scheduled", K_(cluster_name), K_(cluster_id),
......
......@@ -4,11 +4,14 @@ obproxy/opsql/ob_proxy_parse_type.h\
obproxy/opsql/ob_proxy_parse_malloc.h\
obproxy/opsql/ob_proxy_parse_malloc.cpp
opsql_parser_utf8_sources:=\
obproxy/opsql/parser/ob_proxy_parser_utf8_lex.c\
obproxy/opsql/parser/ob_proxy_parser_utf8_lex.h\
obproxy/opsql/parser/ob_proxy_parser_utf8_tab.c\
obproxy/opsql/parser/ob_proxy_parser_utf8_tab.h
opsql_parser_sources:=\
obproxy/opsql/parser/ob_proxy_parser_lex.c\
obproxy/opsql/parser/ob_proxy_parser_lex.h\
obproxy/opsql/parser/ob_proxy_parser_tab.c\
obproxy/opsql/parser/ob_proxy_parser_tab.h\
${opsql_parser_utf8_sources}\
obproxy/opsql/parser/ob_proxy_parse_result.h\
obproxy/opsql/parser/ob_proxy_parse_result.cpp\
obproxy/opsql/parser/ob_proxy_parser.h
......@@ -17,11 +20,14 @@ opsql_dual_parser_sources:=\
obproxy/opsql/dual_parser/ob_dual_parser.h\
obproxy/opsql/dual_parser/ob_dual_parser.cpp
opsql_expr_utf8_parser_sources:=\
obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.c\
obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.h\
obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.c\
obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.h
opsql_expr_parser_sources:=\
obproxy/opsql/expr_parser/ob_expr_parser_lex.c\
obproxy/opsql/expr_parser/ob_expr_parser_lex.h\
obproxy/opsql/expr_parser/ob_expr_parser_tab.c\
obproxy/opsql/expr_parser/ob_expr_parser_tab.h\
${opsql_expr_utf8_parser_sources}\
obproxy/opsql/expr_parser/ob_expr_parse_result.h\
obproxy/opsql/expr_parser/ob_expr_parse_result.cpp\
obproxy/opsql/expr_parser/ob_expr_parser_utils.h\
......
......@@ -382,7 +382,7 @@ int ObProxyDualParser::parse_where_key_word()
return OB_SUCCESS;
}
int ObProxyDualParser::parse_where_fields()
int ObProxyDualParser::parse_where_fields(ObCollationType connection_collation)
{
int ret = OB_SUCCESS;
// OB_PROXY_MAX_CONFIG_STRING_LENGTH is 512
......@@ -416,7 +416,7 @@ int ObProxyDualParser::parse_where_fields()
expr_sql += (len_before_where - 1);
}
}
if (OB_FAIL(expr_parser.parse(expr_sql, expr_result))) {
if (OB_FAIL(expr_parser.parse(expr_sql, expr_result, connection_collation))) {
LOG_DEBUG("parse failed ", K(expr_sql));
} else {
LOG_DEBUG("expr_sql", K(expr_sql));
......@@ -426,7 +426,8 @@ int ObProxyDualParser::parse_where_fields()
}
int ObProxyDualParser::parse(const common::ObString &sql_string,
ObProxyDualParseResult &parse_result)
ObProxyDualParseResult &parse_result,
ObCollationType connection_collation)
{
int ret = OB_SUCCESS;
reset();
......@@ -445,7 +446,7 @@ int ObProxyDualParser::parse(const common::ObString &sql_string,
LOG_WARN("parse_key_word DUAL failed");
} else if (OB_FAIL(parse_where_key_word())) {
LOG_DEBUG("parse_where_and_fields failed");
} else if (OB_FAIL(parse_where_fields())) {
} else if (OB_FAIL(parse_where_fields(connection_collation))) {
LOG_DEBUG("parse_where_fields failed");
}
return ret;
......
......@@ -28,14 +28,15 @@ public:
ObProxyDualParser();
~ObProxyDualParser();
int parse(const common::ObString &sql_string,
obutils::ObProxyDualParseResult &parse_result);
obutils::ObProxyDualParseResult &parse_result,
common::ObCollationType connection_collation);
bool is_valid_result();
private:
int skip_comments();
int parse_key_word(const char* key, bool allow_semi = false);
int parse_seqs_and_fields();
int parse_where_key_word();
int parse_where_fields();
int parse_where_fields(common::ObCollationType connection_collation);
inline bool is_slash_char(const char c) {
return c == '/';
......@@ -90,4 +91,4 @@ private:
} // end of namespace opsql
} // end of namespace obproxy
} // end of namespace oceanbase
#endif // OB_PROXY_DUAL_PARSER_H_
\ No newline at end of file
#endif // OB_PROXY_DUAL_PARSER_H_
......@@ -7,9 +7,30 @@ set +x
CURDIR="$(dirname $(readlink -f "$0"))"
export PATH=${CURDIR}/../../../..//deps/3rd/usr/local/oceanbase/devtools/bin/:/usr/local/bin:$PATH
export BISON_PKGDATADIR=${CURDIR}/../../../../deps/3rd/usr/local/oceanbase/devtools/share/bison/
# generate oracle utf8 expr_parser(support multi_byte_space, multi_byte_comma, multi_byte_left_parenthesis, multi_byte_right_parenthesis)
##1.copy lex and yacc files
cat ob_expr_parser.y > ob_expr_parser_utf8.y
cat ob_expr_parser.l > ob_expr_parser_utf8.l
##2.replace name
sed "s/ob_expr_parser_yy/ob_expr_parser_utf8_yy/g" -i ob_expr_parser_utf8.y
sed "s/ob_expr_parser_yy/ob_expr_parser_utf8_yy/g" -i ob_expr_parser_utf8.l
sed "s/ob_expr_parser_lex/ob_expr_parser_utf8_lex/g" -i ob_expr_parser_utf8.y
sed "s/ob_expr_parser_lex/ob_expr_parser_utf8_lex/g" -i ob_expr_parser_utf8.l
sed "s/ob_expr_parser_tab/ob_expr_parser_utf8_tab/g" -i ob_expr_parser_utf8.l
sed "s/ob_expr_parser_fatal_error/ob_expr_utf8_parser_fatal_error/g" -i ob_expr_parser_utf8.y
sed "s/ob_expr_parser_fatal_error/ob_expr_utf8_parser_fatal_error/g" -i ob_expr_parser_utf8.l
sed "s/ob_expr_parse_sql/ob_expr_parse_utf8_sql/g" -i ob_expr_parser_utf8.y
##3.add multi_byte_space, multi_byte_comma, multi_byte_left_parenthesis, multi_byte_right_parenthesis code.
sed "s/multi_byte_space \[\\\u3000\]/multi_byte_space ([\\\xe3\][\\\x80\][\\\x80])/g" -i ob_expr_parser_utf8.l
sed "s/multi_byte_comma \[\\\uff0c\]/multi_byte_comma ([\\\xef\][\\\xbc\][\\\x8c])/g" -i ob_expr_parser_utf8.l
sed "s/multi_byte_left_parenthesis \[\\\uff08\]/multi_byte_left_parenthesis ([\\\xef\][\\\xbc\][\\\x88])/g" -i ob_expr_parser_utf8.l
sed "s/multi_byte_right_parenthesis \[\\\uff09\]/multi_byte_right_parenthesis ([\\\xef\][\\\xbc\][\\\x89])/g" -i ob_expr_parser_utf8.l
sed 's/space \[ \\t\\n\\r\\f\]/space (\[ \\t\\n\\r\\f\]|{multi_byte_space})/g' -i ob_expr_parser_utf8.l
##4.generate oracle utf8 parser files
# run bison
#bison -p obexpr -v -Werror -d ob_expr_parser.y -o ob_expr_parser_tab.c
bison -p obexpr -v -Werror -d ob_expr_parser.y -o ob_expr_parser_tab.c
bison -v -Werror -d ob_expr_parser_utf8.y -o ob_expr_parser_utf8_tab.c
if [ $? -ne 0 ]
then
echo Compile error[$?], abort.
......@@ -17,68 +38,72 @@ then
fi
# format tab.h
sed "s/YY\([a-zA-Z_]*\)/OBEXPR\1/g" -i ob_expr_parser_tab.h
sed "s/yy\([a-zA-Z_]*\)/obexpr\1/g" -i ob_expr_parser_tab.h
sed "s/YY\([a-zA-Z_]*\)/OBEXPR\1/g" -i ob_expr_parser_utf8_tab.h
sed "s/yy\([a-zA-Z_]*\)/obexpr\1/g" -i ob_expr_parser_utf8_tab.h
sed "/Tokens/i #ifndef YY_OBEXPR_OB_EXPR_PARSER_TAB_H_INCLUDED\n\
# define YY_OBEXPR_OB_EXPR_PARSER_TAB_H_INCLUDED\n\
/* Debug traces. */\n\
#ifndef OBEXPRDEBUG\n\
#ifndef OBEXPR_UTF8_DEBUG\n\
# if defined YYDEBUG\n\
#if YYDEBUG\n\
# define OBEXPRDEBUG 1\n\
# define OBEXPR_UTF8_DEBUG 1\n\
# else\n\
# define OBEXPRDEBUG 0\n\
# define OBEXPR_UTF8_DEBUG 0\n\
# endif\n\
# else /* ! defined YYDEBUG */\n\
# define OBEXPRDEBUG 0\n\
# define OBEXPR_UTF8_DEBUG 0\n\
# endif /* ! defined YYDEBUG */\n\
#endif /* ! defined OBEXPRDEBUG */\n\
#if OBEXPRDEBUG\n\
extern int obexprdebug;\n\
#endif" -i ob_expr_parser_tab.h
echo "#endif" >> ob_expr_parser_tab.h
#endif /* ! defined OBEXPR_UTF8_DEBUG */\n\
#if OBEXPR_UTF8_DEBUG\n\
extern int ob_expr_parser_utf8_yydebug;\n\
#endif" -i ob_expr_parser_utf8_tab.h
echo "#endif" >> ob_expr_parser_utf8_tab.h
# formart tab.c
sed "/#define yyparse/i #define YYSTYPE OBEXPRSTYPE\n#define YYLTYPE OBEXPRLTYPE" -i ob_expr_parser_tab.c
sed "/Tokens/,/Copy the second/{s/YY\([a-zA-Z_]\)/OBEXPR\1/g}" -i ob_expr_parser_tab.c
sed "/Tokens/,/Copy the second/{s/yy\([a-zA-Z_]\)/obexpr\1/g}" -i ob_expr_parser_tab.c
sed "s/yylex (\&yylval, \&yylloc)/yylex (\&yylval, \&yylloc, YYLEX_PARAM)/g" -i ob_expr_parser_tab.c
sed "/#define yyparse/i #define YYSTYPE OBEXPRSTYPE\n#define YYLTYPE OBEXPRLTYPE" -i ob_expr_parser_utf8_tab.c
sed "/Tokens/,/Copy the second/{s/YY\([a-zA-Z_]\)/OBEXPR\1/g}" -i ob_expr_parser_utf8_tab.c
sed "/Tokens/,/Copy the second/{s/yy\([a-zA-Z_]\)/obexpr\1/g}" -i ob_expr_parser_utf8_tab.c
sed "s/yylex (\&yylval, \&yylloc)/yylex (\&yylval, \&yylloc, YYLEX_PARAM)/g" -i ob_expr_parser_utf8_tab.c
sed "/Tokens/i #ifndef YY_OBEXPR_OB_EXPR_PARSER_TAB_H_INCLUDED\n\
# define YY_OBEXPR_OB_EXPR_PARSER_TAB_H_INCLUDED\n\
/* Debug traces. */\n\
#ifndef OBEXPRDEBUG\n\
#ifndef OBEXPR_UTF8_DEBUG\n\
# if defined YYDEBUG\n\
#if YYDEBUG\n\
# define OBEXPRDEBUG 1\n\
# define OBEXPR_UTF8_DEBUG 1\n\
# else\n\
# define OBEXPRDEBUG 0\n\
# define OBEXPR_UTF8_DEBUG 0\n\
# endif\n\
# else /* ! defined YYDEBUG */\n\
# define OBEXPRDEBUG 0\n\
# define OBEXPR_UTF8_DEBUG 0\n\
# endif /* ! defined YYDEBUG */\n\
#endif /* ! defined OBEXPRDEBUG */\n\
#if OBEXPRDEBUG\n\
extern int obexprdebug;\n\
#endif" -i ob_expr_parser_tab.c
sed "/Copy the second/i #endif" -i ob_expr_parser_tab.c
#endif /* ! defined OBEXPR_UTF8_DEBUG */\n\
#if OBEXPR_UTF8_DEBUG\n\
extern int ob_expr_parser_utf8_yydebug;\n\
#endif" -i ob_expr_parser_utf8_tab.c
sed "/Copy the second/i #endif" -i ob_expr_parser_utf8_tab.c
sed "/Cause a token to be read/a \
\ \ if (SELECT_STMT_PARSE_MODE == result->parse_mode_) {\n\
yychar = DUMMY_SELECT_CLAUSE;\n\
} else if (INSERT_STMT_PARSE_MODE == result->parse_mode_) {\n\
yychar = DUMMY_INSERT_CLAUSE;\n\
}\n\
" -i ob_expr_parser_tab.c
" -i ob_expr_parser_utf8_tab.c
# run flex
#flex -P obexpr -Cfea -o ob_expr_parser_lex.c ob_expr_parser.l ob_expr_parser_tab.h
flex -P obexpr -o ob_expr_parser_lex.c ob_expr_parser.l ob_expr_parser_tab.h
flex -o ob_expr_parser_utf8_lex.c ob_expr_parser_utf8.l ob_expr_parser_utf8_tab.h
# format lex.h
sed "s/YYSTYPE/OBEXPRSTYPE/g" -i ob_expr_parser_lex.h
sed "s/YYLTYPE/OBEXPRLTYPE/g" -i ob_expr_parser_lex.h
sed "/static int yy_top_state (yyscan_t yyscanner );/d" -i ob_expr_parser_lex.c
sed "/static int yy_top_state/,/\}/d" -i ob_expr_parser_lex.c
sed "/\*yy_cp = '\\\0';/d" -i ob_expr_parser_lex.c
sed "/Setup the input buffer state to scan the given bytes/,/}/{/int i/d}" -i ob_expr_parser_lex.c
sed "/Setup the input buffer state to scan the given bytes/,/}/{/for ( i = 0; i < _yybytes_len; ++i )/d}" -i ob_expr_parser_lex.c
sed "/Setup the input buffer state to scan the given bytes/,/}/{s/\tbuf\[i\] = yybytes\[i\]/memcpy(buf, yybytes, _yybytes_len)/g}" -i ob_expr_parser_lex.c
sed "s/YYSTYPE/OBEXPRSTYPE/g" -i ob_expr_parser_utf8_lex.h
sed "s/YYLTYPE/OBEXPRLTYPE/g" -i ob_expr_parser_utf8_lex.h
sed "/static int yy_top_state (yyscan_t yyscanner );/d" -i ob_expr_parser_utf8_lex.c
sed "/static int yy_top_state/,/\}/d" -i ob_expr_parser_utf8_lex.c
sed "/\*yy_cp = '\\\0';/d" -i ob_expr_parser_utf8_lex.c
sed "/Setup the input buffer state to scan the given bytes/,/}/{/int i/d}" -i ob_expr_parser_utf8_lex.c
sed "/Setup the input buffer state to scan the given bytes/,/}/{/for ( i = 0; i < _yybytes_len; ++i )/d}" -i ob_expr_parser_utf8_lex.c
sed "/Setup the input buffer state to scan the given bytes/,/}/{s/\tbuf\[i\] = yybytes\[i\]/memcpy(buf, yybytes, _yybytes_len)/g}" -i ob_expr_parser_utf8_lex.c
##5.clean useless files
rm -f ob_expr_parser_utf8.l
rm -f ob_expr_parser_utf8.y
rm -f ob_expr_parser_utf8.output
......@@ -19,7 +19,7 @@
#include "proxy/mysqllib/ob_proxy_mysql_request.h"
#include "lib/string/ob_string.h"
extern "C" int ob_expr_parse_sql(ObExprParseResult *p, const char *pszSql, size_t iLen);
extern "C" int ob_expr_parse_utf8_sql(ObExprParseResult *p, const char *pszSql, size_t iLen);
namespace oceanbase
{
......@@ -39,9 +39,12 @@ public:
// will not be inherited, do not set to virtual
~ObExprParser() {}
int parse(const common::ObString &sql_string, ObExprParseResult &parse_result);
int parse(const common::ObString &sql_string, ObExprParseResult &parse_result,
common::ObCollationType connection_collation);
int parse_reqsql(const common::ObString &req_sql, int64_t parsed_length, ObExprParseResult &parse_result, ObProxyBasicStmtType stmt_type);
int parse_reqsql(const common::ObString &req_sql, int64_t parsed_length,
ObExprParseResult &parse_result, ObProxyBasicStmtType stmt_type,
common::ObCollationType connection_collation);
void free_result(ObExprParseResult &parse_result);
private:
......@@ -100,21 +103,33 @@ inline void ObExprParser::free_result(ObExprParseResult &parse_result)
}
inline int ObExprParser::parse(const common::ObString &sql_string,
ObExprParseResult &parse_result)
ObExprParseResult &parse_result,
common::ObCollationType connection_collation)
{
int ret = common::OB_SUCCESS;
if (common::OB_SUCCESS != init_result(parse_result, sql_string.ptr())) {
ret = common::OB_ERR_PARSER_INIT;
PROXY_LOG(WARN, "failed to initialized parser", KERRMSGS, K(ret));
} else if (common::OB_SUCCESS != ob_expr_parse_sql(&parse_result,
sql_string.ptr(),
static_cast<size_t>(sql_string.length()))) {
ret = common::OB_ERR_PARSE_SQL;
} else {
switch (connection_collation) {
case 45/*CS_TYPE_UTF8MB4_GENERAL_CI*/:
case 46/*CS_TYPE_UTF8MB4_BIN*/:
default:
if (common::OB_SUCCESS != ob_expr_parse_utf8_sql(&parse_result,
sql_string.ptr(),
static_cast<size_t>(sql_string.length()))) {
ret = common::OB_ERR_PARSE_SQL;
PROXY_LOG(WARN, "failed to parser utf8 sql", KERRMSGS, K(connection_collation), K(ret));
}
break;
}
}
return ret;
}
inline int ObExprParser::parse_reqsql(const common::ObString &req_sql, int64_t parsed_length, ObExprParseResult &expr_result, ObProxyBasicStmtType stmt_type)
inline int ObExprParser::parse_reqsql(const common::ObString &req_sql, int64_t parsed_length,
ObExprParseResult &expr_result, ObProxyBasicStmtType stmt_type,
common::ObCollationType connection_collation)
{
int ret = common::OB_SUCCESS;
common::ObString expr_sql = obproxy::proxy::ObProxyMysqlRequest::get_expr_sql(req_sql, parsed_length);
......@@ -142,11 +157,10 @@ inline int ObExprParser::parse_reqsql(const common::ObString &req_sql, int64_t p
}
if (NULL != pos) {
const int32_t len_before_where = static_cast<int32_t>(pos - expr_sql_str);
expr_sql += (len_before_where - 1);
expr_sql += static_cast<int32_t>(pos - expr_sql_str);
}
}
if (OB_FAIL(parse(expr_sql, expr_result))) {
if (OB_FAIL(parse(expr_sql, expr_result, connection_collation))) {
PROXY_LOG(DEBUG, "fail to do expr parse", K(expr_sql), K(ret));
} else {
PROXY_LOG(DEBUG, "succ to do expr parse", "expr_result", ObExprParseResultPrintWrapper(expr_result), K(expr_sql));
......
%option noyywrap nounput noinput case-insensitive
%option stack noyyalloc noyyrealloc noyyfree
%option reentrant bison-bridge bison-locations
%option prefix="ob_expr_parser_yy"
%option header-file="ob_expr_parser_lex.h"
%{
#define YYSTYPE OBEXPRSTYPE
......@@ -49,6 +50,11 @@ do {\
%x dq
%x bt
/*following character status will be rewrite by gen_parse.sh according to connection character*/
multi_byte_space [\u3000]
multi_byte_comma [\uff0c]
multi_byte_left_parenthesis [\uff08]
multi_byte_right_parenthesis [\uff09]
space [ \t\n\r\f]
identifer ([A-Za-z0-9$_]*)
int_num [0-9]+
......@@ -81,6 +87,7 @@ btend {backtick}
btdouble {backtick}{backtick}
btcontent [^`]+
comma ,
leftbracket \(
rightbracket \)
......@@ -118,7 +125,10 @@ IN { return IN; }
{number} { RETURN_NUMBER_VAL(); }
{identifer} { RETURN_NAME_OB(); }
{whitespace} { }
[-+().;*&~|^/%,:!@=] { return yytext[0]; }
{comma}|{multi_byte_comma} { return ','; }
{leftbracket}|{multi_byte_left_parenthesis} { return '('; }
{rightbracket}|{multi_byte_right_parenthesis} { return ')'; }
[-+.;*&~|^/%:!@=] { return yytext[0]; }
/* comment */
{c_cmt_begin} { PUSH_STATE(in_c_comment); }
......
%define api.pure
%parse-param {ObExprParseResult* result}
%name-prefix "ob_expr_parser_yy"
%locations
%no-lines
%verbose
......@@ -562,7 +563,7 @@ void yyerror(YYLTYPE* yylloc, ObExprParseResult* p, char* s, ...)
void ob_expr_parser_fatal_error(yyconst char *msg, yyscan_t yyscanner)
{
fprintf(stderr, "FATAL ERROR:%s\n", msg);
ObExprParseResult *p = obexprget_extra(yyscanner);
ObExprParseResult *p = ob_expr_parser_yyget_extra(yyscanner);
if (OB_ISNULL(p)) {
fprintf(stderr, "unexpected null parse result\n");
} else {
......@@ -577,15 +578,15 @@ int ob_expr_parse_sql(ObExprParseResult* p, const char* buf, size_t len)
if (OB_ISNULL(p) || OB_ISNULL(buf) || OB_UNLIKELY(len <= 0)) {
ret = OB_INVALID_ARGUMENT;
// print err msg later
} else if (OB_FAIL(obexprlex_init_extra(p, &(p->yyscan_info_)))) {
} else if (OB_FAIL(ob_expr_parser_yylex_init_extra(p, &(p->yyscan_info_)))) {
// print err msg later
} else {
int val = setjmp(p->jmp_buf_);
if (val) {
ret = OB_PARSER_ERR_PARSE_SQL;
} else {
obexpr_scan_buffer((char *)buf, len, p->yyscan_info_);
if (OB_FAIL(obexprparse(p))) {
ob_expr_parser_yy_scan_buffer((char *)buf, len, p->yyscan_info_);
if (OB_FAIL(ob_expr_parser_yyparse(p))) {
// print err msg later
} else {
// do nothing
......
此差异已折叠。
#ifndef ob_expr_parser_utf8_yyHEADER_H
#define ob_expr_parser_utf8_yyHEADER_H 1
#define ob_expr_parser_utf8_yyIN_HEADER 1
#line 6 "ob_expr_parser_utf8_lex.h"
#line 8 "ob_expr_parser_utf8_lex.h"
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 35
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
/* First, we deal with platform-specific or compiler-specific issues. */
/* begin standard C headers. */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
/* end standard C headers. */
/* flex integer type definitions */
#ifndef FLEXINT_H
#define FLEXINT_H
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
* if you want the limit (max/min) macros for int types.
*/
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
#endif
#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;
typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
#endif /* ! C99 */
/* Limits of integral types. */
#ifndef INT8_MIN
#define INT8_MIN (-128)
#endif
#ifndef INT16_MIN
#define INT16_MIN (-32767-1)
#endif
#ifndef INT32_MIN
#define INT32_MIN (-2147483647-1)
#endif
#ifndef INT8_MAX
#define INT8_MAX (127)
#endif
#ifndef INT16_MAX
#define INT16_MAX (32767)
#endif
#ifndef INT32_MAX
#define INT32_MAX (2147483647)
#endif
#ifndef UINT8_MAX
#define UINT8_MAX (255U)
#endif
#ifndef UINT16_MAX
#define UINT16_MAX (65535U)
#endif
#ifndef UINT32_MAX
#define UINT32_MAX (4294967295U)
#endif
#endif /* ! FLEXINT_H */
#ifdef __cplusplus
/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST
#else /* ! __cplusplus */
/* C99 requires __STDC__ to be defined as 1. */
#if defined (__STDC__)
#define YY_USE_CONST
#endif /* defined (__STDC__) */
#endif /* ! __cplusplus */
#ifdef YY_USE_CONST
#define yyconst const
#else
#define yyconst
#endif
/* An opaque pointer. */
#ifndef YY_TYPEDEF_YY_SCANNER_T
#define YY_TYPEDEF_YY_SCANNER_T
typedef void* yyscan_t;
#endif
/* For convenience, these vars (plus the bison vars far below)
are macros in the reentrant scanner. */
#define yyin yyg->yyin_r
#define yyout yyg->yyout_r
#define yyextra yyg->yyextra_r
#define yyleng yyg->yyleng_r
#define yytext yyg->yytext_r
#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
#define yy_flex_debug yyg->yy_flex_debug_r
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
#define YY_BUF_SIZE 16384
#endif
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
{
FILE *yy_input_file;
char *yy_ch_buf; /* input buffer */
char *yy_buf_pos; /* current position in input buffer */
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
yy_size_t yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
* delete it.
*/
int yy_is_our_buffer;
/* Whether this is an "interactive" input source; if so, and
* if we're using stdio for input, then we want to use getc()
* instead of fread(), to make sure we stop fetching input after
* each newline.
*/
int yy_is_interactive;
/* Whether we're considered to be at the beginning of a line.
* If so, '^' rules will be active on the next match, otherwise
* not.
*/
int yy_at_bol;
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
int yy_fill_buffer;
int yy_buffer_status;
};
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
void ob_expr_parser_utf8_yyrestart (FILE *input_file ,yyscan_t yyscanner );
void ob_expr_parser_utf8_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
YY_BUFFER_STATE ob_expr_parser_utf8_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
void ob_expr_parser_utf8_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
void ob_expr_parser_utf8_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
void ob_expr_parser_utf8_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
void ob_expr_parser_utf8_yypop_buffer_state (yyscan_t yyscanner );
YY_BUFFER_STATE ob_expr_parser_utf8_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
YY_BUFFER_STATE ob_expr_parser_utf8_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
YY_BUFFER_STATE ob_expr_parser_utf8_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
void *ob_expr_parser_utf8_yyalloc (yy_size_t ,yyscan_t yyscanner );
void *ob_expr_parser_utf8_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
void ob_expr_parser_utf8_yyfree (void * ,yyscan_t yyscanner );
/* Begin user sect3 */
#define ob_expr_parser_utf8_yywrap(n) 1
#define YY_SKIP_YYWRAP
#define yytext_ptr yytext_r
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
#define INITIAL 0
#define in_c_comment 1
#define sq 2
#define dq 3
#define bt 4
#endif
#ifndef YY_NO_UNISTD_H
/* Special case for "unistd.h", since it is non-ANSI. We include it way
* down here because we want the user's section 1 to have been scanned first.
* The user has a chance to override it with an option.
*/
#include <unistd.h>
#endif
#ifndef YY_EXTRA_TYPE
#define YY_EXTRA_TYPE void *
#endif
int ob_expr_parser_utf8_yylex_init (yyscan_t* scanner);
int ob_expr_parser_utf8_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
int ob_expr_parser_utf8_yylex_destroy (yyscan_t yyscanner );
int ob_expr_parser_utf8_yyget_debug (yyscan_t yyscanner );
void ob_expr_parser_utf8_yyset_debug (int debug_flag ,yyscan_t yyscanner );
YY_EXTRA_TYPE ob_expr_parser_utf8_yyget_extra (yyscan_t yyscanner );
void ob_expr_parser_utf8_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
FILE *ob_expr_parser_utf8_yyget_in (yyscan_t yyscanner );
void ob_expr_parser_utf8_yyset_in (FILE * in_str ,yyscan_t yyscanner );
FILE *ob_expr_parser_utf8_yyget_out (yyscan_t yyscanner );
void ob_expr_parser_utf8_yyset_out (FILE * out_str ,yyscan_t yyscanner );
int ob_expr_parser_utf8_yyget_leng (yyscan_t yyscanner );
char *ob_expr_parser_utf8_yyget_text (yyscan_t yyscanner );
int ob_expr_parser_utf8_yyget_lineno (yyscan_t yyscanner );
void ob_expr_parser_utf8_yyset_lineno (int line_number ,yyscan_t yyscanner );
OBEXPRSTYPE * ob_expr_parser_utf8_yyget_lval (yyscan_t yyscanner );
void ob_expr_parser_utf8_yyset_lval (OBEXPRSTYPE * yylval_param ,yyscan_t yyscanner );
OBEXPRLTYPE *ob_expr_parser_utf8_yyget_lloc (yyscan_t yyscanner );
void ob_expr_parser_utf8_yyset_lloc (OBEXPRLTYPE * yylloc_param ,yyscan_t yyscanner );
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
extern "C" int ob_expr_parser_utf8_yywrap (yyscan_t yyscanner );
#else
extern int ob_expr_parser_utf8_yywrap (yyscan_t yyscanner );
#endif
#endif
#ifndef yytext_ptr
static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
#endif
#ifdef YY_NEED_STRLEN
static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
#endif
#ifndef YY_NO_INPUT
#endif
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#define YY_READ_BUF_SIZE 8192
#endif
/* Number of entries by which start-condition stack grows. */
#ifndef YY_START_STACK_INCR
#define YY_START_STACK_INCR 25
#endif
/* Default declaration of generated scanner - a define so the user can
* easily add parameters.
*/
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
extern int ob_expr_parser_utf8_yylex \
(OBEXPRSTYPE * yylval_param,OBEXPRLTYPE * yylloc_param ,yyscan_t yyscanner);
#define YY_DECL int ob_expr_parser_utf8_yylex \
(OBEXPRSTYPE * yylval_param, OBEXPRLTYPE * yylloc_param , yyscan_t yyscanner)
#endif /* !YY_DECL */
/* yy_get_previous_state - get the state just before the EOB char was reached */
#undef YY_NEW_FILE
#undef YY_FLUSH_BUFFER
#undef yy_set_bol
#undef yy_new_buffer
#undef yy_set_interactive
#undef YY_DO_BEFORE_ACTION
#ifdef YY_DECL_IS_OURS
#undef YY_DECL_IS_OURS
#undef YY_DECL
#endif
#line 256 "ob_expr_parser_utf8.l"
#line 348 "ob_expr_parser_utf8_lex.h"
#undef ob_expr_parser_utf8_yyIN_HEADER
#endif /* ob_expr_parser_utf8_yyHEADER_H */
此差异已折叠。
/* A Bison parser, made by GNU Bison 2.4.1. */
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_OBEXPR_OB_EXPR_PARSER_TAB_H_INCLUDED
# define YY_OBEXPR_OB_EXPR_PARSER_TAB_H_INCLUDED
/* Debug traces. */
#ifndef OBEXPR_UTF8_DEBUG
# if defined YYDEBUG
#if YYDEBUG
# define OBEXPR_UTF8_DEBUG 1
# else
# define OBEXPR_UTF8_DEBUG 0
# endif
# else /* ! defined YYDEBUG */
# define OBEXPR_UTF8_DEBUG 0
# endif /* ! defined YYDEBUG */
#endif /* ! defined OBEXPR_UTF8_DEBUG */
#if OBEXPR_UTF8_DEBUG
extern int ob_expr_parser_utf8_yydebug;
#endif
/* Tokens. */
#ifndef OBEXPRTOKENTYPE
# define OBEXPRTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum obexprtokentype {
DUMMY_SELECT_CLAUSE = 258,
DUMMY_INSERT_CLAUSE = 259,
WHERE = 260,
AS = 261,
VALUES = 262,
SET = 263,
END_WHERE = 264,
JOIN = 265,
AND_OP = 266,
OR_OP = 267,
IN = 268,
ON = 269,
BETWEEN = 270,
ROWID = 271,
COMP_EQ = 272,
COMP_NSEQ = 273,
COMP_GE = 274,
COMP_GT = 275,
COMP_LE = 276,
COMP_LT = 277,
COMP_NE = 278,
PLACE_HOLDER = 279,
END_P = 280,
ERROR = 281,
IGNORED_WORD = 282,
NAME_OB = 283,
STR_VAL = 284,
INT_VAL = 285,
POS_PLACE_HOLDER = 286
};
#endif
#if ! defined OBEXPRSTYPE && ! defined OBEXPRSTYPE_IS_DECLARED
typedef union OBEXPRSTYPE
{
int64_t num;
ObProxyParseString str;
ObProxyFunctionType func;
ObProxyOperatorType operator;
ObProxyTokenNode *node;
ObProxyTokenList *list;
ObProxyRelationExpr *relation;
} OBEXPRSTYPE;
# define OBEXPRSTYPE_IS_TRIVIAL 1
# define obexprstype OBEXPRSTYPE /* obsolescent; will be withdrawn */
# define OBEXPRSTYPE_IS_DECLARED 1
#endif
#if ! defined OBEXPRLTYPE && ! defined OBEXPRLTYPE_IS_DECLARED
typedef struct OBEXPRLTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
} OBEXPRLTYPE;
# define obexprltype OBEXPRLTYPE /* obsolescent; will be withdrawn */
# define OBEXPRLTYPE_IS_DECLARED 1
# define OBEXPRLTYPE_IS_TRIVIAL 1
#endif
#endif
......@@ -96,7 +96,7 @@ int ObExprResolver::resolve(ObExprResolverContext &ctx, ObExprResolverResult &re
* for normal ps sql, placeholder_idx_ in token node means the pos of '?'
* for normal pl sql, placeholder_idx_ in token node means the index of call_info.params_
* for pl sql with ps, placeholder_idx_ in call_info_node_ means the pos of '?'
* for example: ps sql = call func1(11, ?, 22, ?),
* for example: ps sql = call func1(11, ?, 22, ?),
* the first sql of func1 is select * from t1 where a = :1 and b = :2 and c =:3 and d = :4
* result:
* call_info_.params_[1].placeholder_idx_ = 0, call_info_.params_[3].placeholder_idx_ = 1
......@@ -169,6 +169,11 @@ int ObExprResolver::resolve_token_list(ObProxyRelationExpr *relation,
}
}
if (OB_SUCC(ret) && ObStringTC == target_obj->get_type_class()) {
// The character set of the string parsed from the parser uses the value of the variable collation_connection
target_obj->set_collation_type(static_cast<common::ObCollationType>(client_info->get_collation_connection()));
}
if (OB_SUCC(ret)) {
switch (func_type) {
case F_COMP_EQ:
......
......@@ -17,12 +17,13 @@
#include "opsql/parser/ob_proxy_parse_result.h"
#include "lib/string/ob_string.h"
#include "utils/ob_proxy_lib.h"
#include "lib/charset/ob_charset.h"
#include <ob_sql_parser.h>
#include <parse_malloc.h>
#include <parse_node.h>
extern "C" int obproxy_parse_sql(ObProxyParseResult *p, const char *pszSql, size_t iLen);
extern "C" int obproxy_parse_utf8_sql(ObProxyParseResult *p, const char *pszSql, size_t iLen);
namespace oceanbase
{
......@@ -42,7 +43,8 @@ public:
// will not be inherited, do not set to virtual
~ObProxyParser() {}
int parse(const common::ObString &sql_string, ObProxyParseResult &parse_result);
int parse(const common::ObString &sql_string, ObProxyParseResult &parse_result,
common::ObCollationType connection_collation);
void free_result(ObProxyParseResult &parse_result);
// the following function use ob parser
int obparse(const common::ObString &sql_string, ParseResult &parse_result);
......@@ -184,16 +186,25 @@ inline int ObProxyParser::obparse(const common::ObString &sql_string,
}
inline int ObProxyParser::parse(const common::ObString &sql_string,
ObProxyParseResult &parse_result)
ObProxyParseResult &parse_result,
common::ObCollationType connection_collation)
{
int ret = common::OB_SUCCESS;
if (0 != init_result(parse_result, sql_string.ptr())) {
ret = common::OB_ERR_PARSER_INIT;
PROXY_LOG(WARN, "failed to initialized parser", KERRMSGS, K(ret));
} else if (0 != obproxy_parse_sql(&parse_result,
sql_string.ptr(),
static_cast<size_t>(sql_string.length()))) {
ret = common::OB_ERR_PARSE_SQL;
} else {
switch (connection_collation) {
case 45/*CS_TYPE_UTF8MB4_GENERAL_CI*/:
case 46/*CS_TYPE_UTF8MB4_BIN*/:
default:
if (common::OB_SUCCESS != obproxy_parse_utf8_sql(&parse_result,
sql_string.ptr(),
static_cast<size_t>(sql_string.length()))) {
ret = common::OB_ERR_PARSE_SQL;
}
break;
}
}
return ret;
}
......
%define api.pure
%parse-param {ObProxyParseResult* result}
%name-prefix "ob_proxy_parser_yy"
%locations
%no-lines
%verbose
......@@ -23,7 +24,7 @@ do {\
result->end_pos_ = result->table_info_.table_name_.end_ptr_;\
}\
} else {\
result->end_pos_ = obproxyget_text(result->yyscan_info_);\
result->end_pos_ = ob_proxy_parser_yyget_text(result->yyscan_info_);\
}\
YYACCEPT;\
} while (0);
......@@ -1129,7 +1130,7 @@ void yyerror(YYLTYPE* yylloc, ObProxyParseResult* p, char* s, ...)
void ob_proxy_parser_fatal_error(yyconst char *msg, yyscan_t yyscanner)
{
fprintf(stderr, "FATAL ERROR:%s\n", msg);
ObProxyParseResult *p = obproxyget_extra(yyscanner);
ObProxyParseResult *p = ob_proxy_parser_yyget_extra(yyscanner);
if (OB_ISNULL(p)) {
fprintf(stderr, "unexpected null parse result\n");
} else {
......@@ -1144,15 +1145,15 @@ int obproxy_parse_sql(ObProxyParseResult* p, const char* buf, size_t len)
if (OB_ISNULL(p) || OB_ISNULL(buf) || OB_UNLIKELY(len <= 0)) {
ret = OB_INVALID_ARGUMENT;
// print err msg later
} else if (OB_FAIL(obproxylex_init_extra(p, &(p->yyscan_info_)))) {
} else if (OB_FAIL(ob_proxy_parser_yylex_init_extra(p, &(p->yyscan_info_)))) {
// print err msg later
} else {
int val = setjmp(p->jmp_buf_);
if (val) {
ret = OB_PARSER_ERR_PARSE_SQL;
} else {
obproxy_scan_buffer((char *)buf, len, p->yyscan_info_);
if (OB_FAIL(obproxyparse(p))) {
ob_proxy_parser_yy_scan_buffer((char *)buf, len, p->yyscan_info_);
if (OB_FAIL(ob_proxy_parser_yyparse(p))) {
// print err msg later
} else {
// do nothing
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -21,7 +21,7 @@
#include "proxy/plugins/ob_mysql_response_prepare_transform_plugin.h"
#include "proxy/plugins/ob_mysql_request_compress_transform_plugin.h"
#include "proxy/plugins/ob_mysql_response_cursor_transform_plugin.h"
#include "proxy/plugins/ob_mysql_response_prepare_execute_transform_plugin.h"
#include "proxy/plugins/ob_mysql_response_new_ps_transform_plugin.h"
/****************************************************************
* IMPORTANT - READ ME
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。