MXS-2785: Make rewrite_src a regular expression
The use of a regular expression allows multiple rewrite rules to be combined into one. This allows more versatile conversions but, given the simple nature of regular expressions, also makes accidental changes more likely. Addd mxs::pcre2_substitute that is a more C++-friendly version of mxs_pcre2_substitute to make. This makes string replacement a lot easier to do when the source and destination are not C strings.
This commit is contained in:
@ -36,7 +36,7 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
{"match", MXS_MODULE_PARAM_REGEX },
|
||||
{"exclude", MXS_MODULE_PARAM_REGEX },
|
||||
{REWRITE_SRC, MXS_MODULE_PARAM_STRING },
|
||||
{REWRITE_SRC, MXS_MODULE_PARAM_REGEX },
|
||||
{REWRITE_DEST, MXS_MODULE_PARAM_STRING },
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ struct BinlogConfig
|
||||
, md_match(match ? pcre2_match_data_create_from_pattern(match, nullptr) : nullptr)
|
||||
, exclude(pParams->get_compiled_regex("exclude", 0, nullptr).release())
|
||||
, md_exclude(exclude ? pcre2_match_data_create_from_pattern(exclude, nullptr) : nullptr)
|
||||
, rewrite_src(pParams->get_string(REWRITE_SRC))
|
||||
, rewrite_src(pParams->get_compiled_regex(REWRITE_SRC, 0, nullptr).release())
|
||||
, rewrite_dest(pParams->get_string(REWRITE_DEST))
|
||||
{
|
||||
}
|
||||
@ -38,7 +38,7 @@ struct BinlogConfig
|
||||
pcre2_match_data* md_match;
|
||||
pcre2_code* exclude;
|
||||
pcre2_match_data* md_exclude;
|
||||
std::string rewrite_src;
|
||||
pcre2_code* rewrite_src;
|
||||
std::string rewrite_dest;
|
||||
};
|
||||
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
#include <maxbase/alloc.h>
|
||||
#include <maxscale/poll.hh>
|
||||
#include <maxscale/modutil.hh>
|
||||
#include <maxscale/pcre2.hh>
|
||||
|
||||
#include "binlogfilter.hh"
|
||||
#include "binlogfiltersession.hh"
|
||||
@ -138,13 +139,12 @@ int BinlogFilterSession::routeQuery(GWBUF* pPacket)
|
||||
m_state = BINLOG_MODE;
|
||||
MXS_INFO("Slave server %u is waiting for binlog events.", m_serverid);
|
||||
|
||||
if (!m_is_gtid
|
||||
&& m_filter.getConfig().rewrite_src.length() != m_filter.getConfig().rewrite_dest.length())
|
||||
if (!m_is_gtid)
|
||||
{
|
||||
gwbuf_free(pPacket);
|
||||
std::ostringstream ss;
|
||||
ss << "GTID replication is required when '"
|
||||
<< REWRITE_SRC << "' and '" << REWRITE_DEST << "' are of different length";
|
||||
<< REWRITE_SRC << "' and '" << REWRITE_DEST << "' are used";
|
||||
mxs::FilterSession::clientReply(
|
||||
modutil_create_mysql_err_msg(1, 0, ER_MASTER_FATAL_ERROR_READING_BINLOG, "HY000",
|
||||
ss.str().c_str()));
|
||||
@ -849,30 +849,17 @@ void BinlogFilterSession::checkStatement(GWBUF** buffer, const REP_HEADER& hdr)
|
||||
m_skip = should_skip_query(config, sql, db);
|
||||
MXS_INFO("[%s] (%s) %s", m_skip ? "SKIP" : " ", db.c_str(), sql.c_str());
|
||||
|
||||
if (!m_skip && !config.rewrite_src.empty())
|
||||
if (!m_skip && config.rewrite_src)
|
||||
{
|
||||
bool replace = false;
|
||||
auto new_db = mxs::pcre2_substitute(config.rewrite_src, db, config.rewrite_dest);
|
||||
auto new_sql = mxs::pcre2_substitute(config.rewrite_src, sql, config.rewrite_dest);
|
||||
|
||||
if (db == config.rewrite_src)
|
||||
{
|
||||
replace = true;
|
||||
db = config.rewrite_dest;
|
||||
}
|
||||
|
||||
size_t pos = 0;
|
||||
|
||||
while ((pos = sql.find(config.rewrite_src, pos)) != std::string::npos)
|
||||
{
|
||||
replace = true;
|
||||
sql.replace(pos, config.rewrite_src.length(), config.rewrite_dest);
|
||||
pos += config.rewrite_dest.length();
|
||||
}
|
||||
|
||||
if (replace)
|
||||
if (db != new_db || sql != new_sql)
|
||||
{
|
||||
db = new_db;
|
||||
sql = new_sql;
|
||||
int len = sql.length() + db.length() - statement_len - db_name_len;
|
||||
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
// Buffer is too short, extend it
|
||||
|
||||
Reference in New Issue
Block a user