diff --git a/Documentation/Filters/Database-Firewall-Filter.md b/Documentation/Filters/Database-Firewall-Filter.md index 6e6c5612f..b4af5f030 100644 --- a/Documentation/Filters/Database-Firewall-Filter.md +++ b/Documentation/Filters/Database-Firewall-Filter.md @@ -88,6 +88,9 @@ action=block rules=/home/user/blacklist-rules.txt ``` +If a query is blocked, the filter will return an error to the client with the +error number 1141 and an SQL state of HY000. + #### `log_match` Log all queries that match a rule. For the `any` matching mode, the name of the @@ -326,6 +329,9 @@ values are: |use |USE operations | |load |LOAD DATA operations | +Multiple values can be combined using the pipe character `|` e.g. +` on_queries select|insert|update`. + ### Applying rules to users The `users` directive defines the users to which the rule should be applied. diff --git a/maxscale-system-test/mxs2043_select_for_update.cpp b/maxscale-system-test/mxs2043_select_for_update.cpp index 855ab7971..0c008ce90 100644 --- a/maxscale-system-test/mxs2043_select_for_update.cpp +++ b/maxscale-system-test/mxs2043_select_for_update.cpp @@ -78,7 +78,7 @@ bool create_user(TestConnections& test, MYSQL* pMysql) drop_user(test, pMysql, true); - test.try_query(pMysql, "CREATE USER '%s' IDENTIFIED by '%s'", ZUSER, ZPASSWORD); + test.try_query(pMysql, "CREATE USER '%s'@'%%' IDENTIFIED by '%s'", ZUSER, ZPASSWORD); test.try_query(pMysql, "GRANT SELECT, UPDATE ON %s TO '%s'@'%%'", ZTABLE, ZUSER); return test.global_result == 0; @@ -149,6 +149,8 @@ int main(int argc, char* argv[]) if (create_user(test, pMysql)) { int rv = test.repl->connect(); + test.repl->sync_slaves(); + test.expect(rv == 0, "Could not connect to MS."); if (rv == 0) diff --git a/maxscale-system-test/temporal_tables.cpp b/maxscale-system-test/temporal_tables.cpp index 80c425d23..c28d132ab 100644 --- a/maxscale-system-test/temporal_tables.cpp +++ b/maxscale-system-test/temporal_tables.cpp @@ -59,5 +59,12 @@ int main(int argc, char* argv[]) test.maxscales->close_maxscale_connections(0); + // MXS-2103 + test.maxscales->connect(); + test.try_query(test.maxscales->conn_rwsplit[0], "CREATE TEMPORARY TABLE temp.dummy5 (dum INT);"); + test.try_query(test.maxscales->conn_rwsplit[0], "INSERT INTO temp.dummy5 VALUES(1),(2);"); + test.try_query(test.maxscales->conn_rwsplit[0], "SELECT * FROM temp.dummy5;"); + test.maxscales->disconnect(); + return test.global_result; } diff --git a/server/core/queryclassifier.cc b/server/core/queryclassifier.cc index 00f649f6b..57e69489b 100644 --- a/server/core/queryclassifier.cc +++ b/server/core/queryclassifier.cc @@ -710,20 +710,36 @@ void QueryClassifier::check_create_tmp_table(GWBUF* querybuf, uint32_t type) if (qc_query_is_type(type, QUERY_TYPE_CREATE_TMP_TABLE)) { set_have_tmp_tables(true); - char* tblname = qc_get_created_table_name(querybuf); + int size = 0; + char** tblname = qc_get_table_names(querybuf, &size, true); std::string table; - if (tblname && *tblname && strchr(tblname, '.') == NULL) + for (int i = 0; i < size; i++) { - const char* db = qc_mysql_get_current_db(session()); - table += db; - table += "."; - table += tblname; + if (tblname[i] && *tblname[i]) + { + table = tblname[i]; + + if (strchr(tblname[i], '.') == NULL) + { + const char* db = qc_mysql_get_current_db(session()); + table = db; + table += "."; + table += tblname[i]; + } + break; + } } + MXS_INFO("Added temporary table %s", table.c_str()); + /** Add the table to the set of temporary tables */ add_tmp_table(table); + for (int i = 0; i < size; i++) + { + MXS_FREE(tblname[i]); + } MXS_FREE(tblname); } } diff --git a/server/modules/routing/readwritesplit/rwsplitsession.cc b/server/modules/routing/readwritesplit/rwsplitsession.cc index a899a930e..a70003314 100644 --- a/server/modules/routing/readwritesplit/rwsplitsession.cc +++ b/server/modules/routing/readwritesplit/rwsplitsession.cc @@ -987,14 +987,21 @@ bool RWSplitSession::handle_error_new_connection(DCB* backend_dcb, GWBUF* errmsg route_stored_query(); } - bool succp; + bool succp = false; /** * Try to get replacement slave or at least the minimum * number of slave connections for router session. */ if (m_recv_sescmd > 0 && m_config.disable_sescmd_history) { - succp = m_router->have_enough_servers(); + for (const auto& a : m_backends) + { + if (a->in_use()) + { + succp = true; + break; + } + } } else {