Merge branch '2.3' into 2.4
This commit is contained in:
@ -1259,7 +1259,7 @@ mxs_pcre2_result_t modutil_mysql_wildcard_match(const char* pattern, const char*
|
||||
return rval;
|
||||
}
|
||||
|
||||
static inline bool is_next(mxs::Buffer::iterator it, mxs::Buffer::iterator end, const std::string& str)
|
||||
static inline bool is_next(uint8_t* it, uint8_t* end, const std::string& str)
|
||||
{
|
||||
mxb_assert(it != end);
|
||||
for (auto s_it = str.begin(); s_it != str.end(); ++s_it, ++it)
|
||||
@ -1316,12 +1316,11 @@ static const LUT is_special([](uint8_t c) {
|
||||
c) != std::string::npos;
|
||||
});
|
||||
|
||||
static std::pair<bool, mxs::Buffer::iterator> probe_number(mxs::Buffer::iterator it,
|
||||
mxs::Buffer::iterator end)
|
||||
static inline std::pair<bool, uint8_t*> probe_number(uint8_t* it, uint8_t* end)
|
||||
{
|
||||
mxb_assert(it != end);
|
||||
mxb_assert(is_digit(*it));
|
||||
std::pair<bool, mxs::Buffer::iterator> rval = std::make_pair(true, it);
|
||||
std::pair<bool, uint8_t*> rval = std::make_pair(true, it);
|
||||
bool is_hex = *it == '0';
|
||||
bool allow_hex = false;
|
||||
|
||||
@ -1348,7 +1347,7 @@ static std::pair<bool, mxs::Buffer::iterator> probe_number(mxs::Buffer::iterator
|
||||
else if (*it == 'e')
|
||||
{
|
||||
// Possible scientific notation number
|
||||
auto next_it = std::next(it);
|
||||
auto next_it = it + 1;
|
||||
|
||||
if (next_it == end || (!is_digit(*next_it) && *next_it != '-'))
|
||||
{
|
||||
@ -1365,7 +1364,7 @@ static std::pair<bool, mxs::Buffer::iterator> probe_number(mxs::Buffer::iterator
|
||||
else if (*it == '.')
|
||||
{
|
||||
// Possible decimal number
|
||||
auto next_it = std::next(it);
|
||||
auto next_it = it + 1;
|
||||
|
||||
if (next_it != end && !is_digit(*next_it))
|
||||
{
|
||||
@ -1415,7 +1414,7 @@ static inline bool is_negation(const std::string& str, int i)
|
||||
return rval;
|
||||
}
|
||||
|
||||
mxs::Buffer::iterator find_char(mxs::Buffer::iterator it, const mxs::Buffer::iterator& end, char c)
|
||||
static inline uint8_t* find_char(uint8_t* it, uint8_t* end, char c)
|
||||
{
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
@ -1440,13 +1439,13 @@ namespace maxscale
|
||||
|
||||
std::string get_canonical(GWBUF* querybuf)
|
||||
{
|
||||
std::string rval;
|
||||
mxb_assert(GWBUF_IS_CONTIGUOUS(querybuf));
|
||||
uint8_t* it = GWBUF_DATA(querybuf) + MYSQL_HEADER_LEN + 1;
|
||||
uint8_t* end = GWBUF_DATA(querybuf) + gwbuf_length(querybuf);
|
||||
std::string rval(end - it, 0);
|
||||
int i = 0;
|
||||
rval.resize(gwbuf_length(querybuf) - MYSQL_HEADER_LEN + 1);
|
||||
mxs::Buffer buf(querybuf);
|
||||
|
||||
for (auto it = std::next(buf.begin(), MYSQL_HEADER_LEN + 1); // Skip packet header and command
|
||||
it != buf.end(); ++it)
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if (!is_special(*it))
|
||||
{
|
||||
@ -1456,9 +1455,9 @@ std::string get_canonical(GWBUF* querybuf)
|
||||
else if (*it == '\\')
|
||||
{
|
||||
// Jump over any escaped values
|
||||
rval[i++] += *it++;
|
||||
rval[i++] = *it++;
|
||||
|
||||
if (it != buf.end())
|
||||
if (it != end)
|
||||
{
|
||||
rval[i++] = *it;
|
||||
}
|
||||
@ -1479,19 +1478,19 @@ std::string get_canonical(GWBUF* querybuf)
|
||||
rval[i++] = ' ';
|
||||
}
|
||||
}
|
||||
else if (*it == '/' && is_next(it, buf.end(), "/*"))
|
||||
else if (*it == '/' && is_next(it, end, "/*"))
|
||||
{
|
||||
auto comment_start = std::next(it, 2);
|
||||
if (comment_start == buf.end())
|
||||
if (comment_start == end)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (*comment_start != '!' && *comment_start != 'M')
|
||||
{
|
||||
// Non-executable comment
|
||||
while (it != buf.end())
|
||||
while (it != end)
|
||||
{
|
||||
if (is_next(it, buf.end(), "*/"))
|
||||
if (is_next(it, end, "*/"))
|
||||
{
|
||||
// Comment end marker, return to normal parsing
|
||||
++it;
|
||||
@ -1500,7 +1499,7 @@ std::string get_canonical(GWBUF* querybuf)
|
||||
++it;
|
||||
}
|
||||
|
||||
if (it == buf.end())
|
||||
if (it == end)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -1512,10 +1511,10 @@ std::string get_canonical(GWBUF* querybuf)
|
||||
}
|
||||
}
|
||||
else if ((*it == '#' || *it == '-')
|
||||
&& (is_next(it, buf.end(), "# ") || is_next(it, buf.end(), "-- ")))
|
||||
&& (is_next(it, end, "# ") || is_next(it, end, "-- ")))
|
||||
{
|
||||
// End-of-line comment, jump to the next line if one exists
|
||||
while (it != buf.end())
|
||||
while (it != end)
|
||||
{
|
||||
if (*it == '\n')
|
||||
{
|
||||
@ -1523,7 +1522,7 @@ std::string get_canonical(GWBUF* querybuf)
|
||||
}
|
||||
else if (*it == '\r')
|
||||
{
|
||||
if ((is_next(it, buf.end(), "\r\n")))
|
||||
if ((is_next(it, end, "\r\n")))
|
||||
{
|
||||
++it;
|
||||
}
|
||||
@ -1533,14 +1532,14 @@ std::string get_canonical(GWBUF* querybuf)
|
||||
++it;
|
||||
}
|
||||
|
||||
if (it == buf.end())
|
||||
if (it == end)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (is_digit(*it) && (i == 0 || (!is_alnum(rval[i - 1]) && rval[i - 1] != '_')))
|
||||
{
|
||||
auto num_end = probe_number(it, buf.end());
|
||||
auto num_end = probe_number(it, end);
|
||||
|
||||
if (num_end.first)
|
||||
{
|
||||
@ -1556,7 +1555,7 @@ std::string get_canonical(GWBUF* querybuf)
|
||||
else if (*it == '\'' || *it == '"')
|
||||
{
|
||||
char c = *it;
|
||||
if ((it = find_char(std::next(it), buf.end(), c)) == buf.end())
|
||||
if ((it = find_char(it + 1, end, c)) == end)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -1565,7 +1564,7 @@ std::string get_canonical(GWBUF* querybuf)
|
||||
else if (*it == '`')
|
||||
{
|
||||
auto start = it;
|
||||
if ((it = find_char(std::next(it), buf.end(), '`')) == buf.end())
|
||||
if ((it = find_char(it + 1, end, '`')) == end)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -1578,7 +1577,7 @@ std::string get_canonical(GWBUF* querybuf)
|
||||
rval[i++] = *it;
|
||||
}
|
||||
|
||||
mxb_assert(it != buf.end());
|
||||
mxb_assert(it != end);
|
||||
}
|
||||
|
||||
// Remove trailing whitespace
|
||||
@ -1590,8 +1589,6 @@ std::string get_canonical(GWBUF* querybuf)
|
||||
// Shrink the buffer so that the internal bookkeeping of std::string remains up to date
|
||||
rval.resize(i);
|
||||
|
||||
buf.release();
|
||||
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,6 +208,24 @@ void ResultSet::write(DCB* dcb)
|
||||
mysql_send_eof(dcb, seqno);
|
||||
}
|
||||
|
||||
json_t* ResultSet::get_json_value(const std::string& s)
|
||||
{
|
||||
json_t* js;
|
||||
char* end;
|
||||
long l = strtol(s.c_str(), &end, 10);
|
||||
|
||||
if (end != s.c_str() && *end == '\0')
|
||||
{
|
||||
js = json_integer(l);
|
||||
}
|
||||
else
|
||||
{
|
||||
js = json_string(s.c_str());
|
||||
}
|
||||
|
||||
return js;
|
||||
}
|
||||
|
||||
void ResultSet::write_as_json(DCB* dcb)
|
||||
{
|
||||
json_t* arr = json_array();
|
||||
@ -218,7 +236,7 @@ void ResultSet::write_as_json(DCB* dcb)
|
||||
|
||||
for (size_t i = 0; i < row.size(); i++)
|
||||
{
|
||||
json_object_set_new(obj, m_columns[i].c_str(), json_string(row[i].c_str()));
|
||||
json_object_set_new(obj, m_columns[i].c_str(), get_json_value(row[i]));
|
||||
}
|
||||
|
||||
json_array_append_new(arr, obj);
|
||||
@ -227,4 +245,6 @@ void ResultSet::write_as_json(DCB* dcb)
|
||||
char* js = json_dumps(arr, JSON_INDENT(4));
|
||||
dcb_printf(dcb, "%s", js);
|
||||
MXS_FREE(js);
|
||||
|
||||
json_decref(arr);
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ struct
|
||||
uint64_t next_session_id;
|
||||
uint32_t retain_last_statements;
|
||||
session_dump_statements_t dump_statements;
|
||||
uint32_t session_trace;
|
||||
uint32_t session_trace;
|
||||
} this_unit =
|
||||
{
|
||||
1,
|
||||
@ -160,7 +160,6 @@ bool session_start(MXS_SESSION* session)
|
||||
|
||||
session->state = SESSION_STATE_STARTED;
|
||||
mxb::atomic::add(&session->service->stats.n_sessions, 1, mxb::atomic::RELAXED);
|
||||
mxb::atomic::add(&session->service->stats.n_current, 1, mxb::atomic::RELAXED);
|
||||
|
||||
MXS_INFO("Started %s client session [%" PRIu64 "] for '%s' from %s",
|
||||
session->service->name(), session->ses_id,
|
||||
@ -279,8 +278,6 @@ static void session_final_free(MXS_SESSION* ses)
|
||||
|
||||
session->state = SESSION_STATE_TO_BE_FREED;
|
||||
|
||||
mxb::atomic::add(&session->service->stats.n_current, -1, mxb::atomic::RELAXED);
|
||||
|
||||
if (session->client_dcb)
|
||||
{
|
||||
dcb_free_all_memory(session->client_dcb);
|
||||
@ -1162,6 +1159,9 @@ Session::Session(const SListener& listener)
|
||||
{
|
||||
m_retain_last_statements = this_unit.retain_last_statements;
|
||||
}
|
||||
|
||||
mxb::atomic::add(&service->stats.n_current, 1, mxb::atomic::RELAXED);
|
||||
mxb_assert(service->stats.n_current >= 0);
|
||||
}
|
||||
|
||||
Session::~Session()
|
||||
@ -1176,6 +1176,9 @@ Session::~Session()
|
||||
f.filter->obj->closeSession(f.instance, f.session);
|
||||
f.filter->obj->freeSession(f.instance, f.session);
|
||||
}
|
||||
|
||||
mxb::atomic::add(&service->stats.n_current, -1, mxb::atomic::RELAXED);
|
||||
mxb_assert(service->stats.n_current >= 0);
|
||||
}
|
||||
|
||||
void Session::set_client_dcb(DCB* dcb)
|
||||
@ -1696,6 +1699,6 @@ void Session::dump_session_log()
|
||||
log += s;
|
||||
}
|
||||
|
||||
MXS_NOTICE("Session log for session (%" PRIu64"): \n%s ", ses_id, log.c_str());
|
||||
MXS_NOTICE("Session log for session (%" PRIu64 "): \n%s ", ses_id, log.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
add_executable(profile_trxboundaryparser profile_trxboundaryparser.cc)
|
||||
add_executable(profile_get_canonical profile_get_canonical.cc)
|
||||
add_executable(test_adminusers test_adminusers.cc)
|
||||
add_executable(test_atomic test_atomic.cc)
|
||||
add_executable(test_buffer test_buffer.cc)
|
||||
@ -28,6 +29,7 @@ add_executable(test_utils test_utils.cc)
|
||||
add_executable(test_session_track test_session_track.cc)
|
||||
|
||||
target_link_libraries(profile_trxboundaryparser maxscale-common)
|
||||
target_link_libraries(profile_get_canonical maxscale-common)
|
||||
target_link_libraries(test_adminusers maxscale-common)
|
||||
target_link_libraries(test_atomic maxscale-common)
|
||||
target_link_libraries(test_buffer maxscale-common)
|
||||
|
||||
46
server/core/test/profile_get_canonical.cc
Normal file
46
server/core/test/profile_get_canonical.cc
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
|
||||
*
|
||||
* Change Date: 2022-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <maxscale/modutil.hh>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <chrono>
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::milliseconds;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ITERATIONS = 10000000;
|
||||
|
||||
for (std::string line; std::getline(std::cin, line);)
|
||||
{
|
||||
GWBUF* buf = modutil_create_query(line.c_str());
|
||||
auto start = Clock::now();
|
||||
|
||||
for (int i = 0; i < ITERATIONS; i++)
|
||||
{
|
||||
auto str = mxs::get_canonical(buf);
|
||||
}
|
||||
|
||||
auto end = Clock::now();
|
||||
gwbuf_free(buf);
|
||||
|
||||
std::cout << line << "\n"
|
||||
<< duration_cast<milliseconds>(end - start).count() << "ms\n\n";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user