From ef3478c5c2ebb002a786f59c2b590804cb5ebf22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20S=C3=A1nchez=20Parra?= Date: Wed, 30 Nov 2022 10:24:59 +0100 Subject: [PATCH] Fix warnings and status position in EOF to OK package conversion If a client connects to ProxySQL not using CLIENT_DEPRECATE_EOF and it caches a resultset, when a client using CLIENT_DEPRECATE_EOF executes the same query it will get a resultset with wrong warnings and status flags. This is because warnings and status flags position must be swapped when converting an EOF packet to an OK packet. More info about warnings and status flags position in EOF and OK packets: https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_eof_packet.html https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_ok_packet.html --- lib/Query_Cache.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/Query_Cache.cpp b/lib/Query_Cache.cpp index c20ac38a9..0b9163af2 100644 --- a/lib/Query_Cache.cpp +++ b/lib/Query_Cache.cpp @@ -515,8 +515,20 @@ unsigned char* eof_to_ok_packet(QC_entry_t* entry) { // Initialize affected_rows and last_insert_id to zero memset(vp, 0, 2); vp += 2; - // Copy the warning an status flags - memcpy(vp, it, 4); + // Extract warning flags and status from 'EOF_packet' + char* eof_packet = entry->value + entry->row_eof_pkt_offset; + eof_packet += sizeof(mysql_hdr); + // Skip the '0xFE EOF packet header' + eof_packet += 1; + uint16_t warnings; + memcpy(&warnings, eof_packet, sizeof(uint16_t)); + eof_packet += 2; + uint16_t status_flags; + memcpy(&status_flags, eof_packet, sizeof(uint16_t)); + // Copy warnings an status flags + memcpy(vp, &status_flags, sizeof(uint16_t)); + vp += 2; + memcpy(vp, &warnings, sizeof(uint16_t)); // ======================================= // Decrement ids after the first EOF