MXS-2490: Add direct execution support
Certain MariaDB connectors will use the direct execution for batching COM_STMT_PREPARE and COM_STMT_EXECUTE execution without waiting for the COM_STMT_PREPARE to complete. In these cases the COM_STMT_EXECUTE (and other COM_STMT commands as well) will use the special ID 0xffffffff. When this is detected, it should be substituted with the ID of the latest statement that was prepared.
This commit is contained in:
parent
5aa9daaeea
commit
8a176d64aa
@ -363,7 +363,7 @@ private:
|
||||
*/
|
||||
bool query_type_is_read_only(uint32_t qtype) const;
|
||||
|
||||
void process_routing_hints(HINT* pHints, uint32_t* target);
|
||||
void process_routing_hints(HINT* pHints, uint32_t* target);
|
||||
uint32_t get_route_target(uint8_t command, uint32_t qtype);
|
||||
|
||||
MXS_SESSION* session() const
|
||||
@ -415,5 +415,8 @@ private:
|
||||
RouteInfo m_route_info;
|
||||
bool m_trx_is_read_only;
|
||||
bool m_ps_continuation;
|
||||
|
||||
uint32_t m_prev_ps_id = 0; /**< For direct PS execution, storest latest prepared PS ID.
|
||||
* https://mariadb.com/kb/en/library/com_stmt_execute/#statement-id **/
|
||||
};
|
||||
}
|
||||
|
@ -969,6 +969,9 @@ add_test_executable(mxs2563_concurrent_slave_failure.cpp mxs2563_concurrent_slav
|
||||
# MXS-2521: COM_STMT_EXECUTE maybe return empty result
|
||||
add_test_executable(mxs2521_double_exec.cpp mxs2521_double_exec mxs2521_double_exec LABELS REPL_BACKEND readwritesplit)
|
||||
|
||||
# MXS-2490: Direct execution doesn't work with MaxScale
|
||||
add_test_executable(mxs2490_ps_execute_direct.cpp mxs2490_ps_execute_direct replication LABELS REPL_BACKEND readwritesplit)
|
||||
|
||||
############################################
|
||||
# BEGIN: binlogrouter and avrorouter tests #
|
||||
############################################
|
||||
|
26
maxscale-system-test/mxs2490_ps_execute_direct.cpp
Normal file
26
maxscale-system-test/mxs2490_ps_execute_direct.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* MXS-2490: Unknown prepared statement handler (0) given to mysqld_stmt_execute
|
||||
*
|
||||
* See:
|
||||
*
|
||||
* https://mariadb.com/kb/en/library/mariadb_stmt_execute_direct/
|
||||
* https://mariadb.com/kb/en/library/com_stmt_execute/#statement-id
|
||||
*/
|
||||
|
||||
#include "testconnections.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
TestConnections test(argc, argv);
|
||||
|
||||
test.set_timeout(30);
|
||||
test.maxscales->connect();
|
||||
|
||||
MYSQL_STMT* stmt = mysql_stmt_init(test.maxscales->conn_rwsplit[0]);
|
||||
std::string query = "SELECT user FROM mysql.user";
|
||||
test.expect(mariadb_stmt_execute_direct(stmt, query.c_str(), query.length()) == 0,
|
||||
"execute_direct should work: %s", mysql_stmt_error(stmt));
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
return test.global_result;
|
||||
}
|
@ -644,6 +644,13 @@ uint32_t QueryClassifier::ps_id_internal_get(GWBUF* pBuffer)
|
||||
|
||||
// All COM_STMT type statements store the ID in the same place
|
||||
uint32_t external_id = mysql_extract_ps_id(pBuffer);
|
||||
|
||||
if (external_id == 0xffffffff)
|
||||
{
|
||||
// "Direct execution" that refers to the latest prepared statement
|
||||
external_id = m_prev_ps_id;
|
||||
}
|
||||
|
||||
auto it = m_ps_handles.find(external_id);
|
||||
|
||||
if (it != m_ps_handles.end())
|
||||
@ -663,6 +670,7 @@ uint32_t QueryClassifier::ps_id_internal_get(GWBUF* pBuffer)
|
||||
void QueryClassifier::ps_store_response(uint32_t internal_id, GWBUF* buffer)
|
||||
{
|
||||
auto external_id = qc_mysql_extract_ps_id(buffer);
|
||||
m_prev_ps_id = external_id;
|
||||
m_ps_handles[external_id] = internal_id;
|
||||
|
||||
if (auto param_count = qc_extract_ps_param_count(buffer))
|
||||
|
Loading…
x
Reference in New Issue
Block a user