diff --git a/server/core/modutil.cc b/server/core/modutil.cc index a5850ac6b..172f317aa 100644 --- a/server/core/modutil.cc +++ b/server/core/modutil.cc @@ -628,10 +628,9 @@ GWBUF* modutil_get_complete_packets(GWBUF **p_readbuf) return complete; } -int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more_dest, modutil_state* state) +int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more_out, modutil_state* state) { unsigned int len = gwbuf_length(reply); - ss_debug(int real_offset = 0); int eof = 0; int err = 0; size_t offset = 0; @@ -661,18 +660,18 @@ int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more_dest, mod if (command == MYSQL_REPLY_ERR) { - err++; + /** Any errors in the packet stream mean that the result set + * generation was aborted due to an error. No more results will + * follow after this. */ + *more_out = false; + return 2; } else if (command == MYSQL_REPLY_EOF && pktlen == MYSQL_EOF_PACKET_LEN) { eof++; } - else if (more && command == MYSQL_REPLY_OK) + else if (command == MYSQL_REPLY_OK && pktlen >= MYSQL_OK_PACKET_MIN_LEN) { - // This should not be the first packet - ss_dassert(pktlen >= MYSQL_OK_PACKET_MIN_LEN); - ss_dassert(real_offset > 0); - uint8_t data[payloadlen - 1]; gwbuf_copy_data(reply, offset + MYSQL_HEADER_LEN + 1, sizeof(data), data); @@ -693,7 +692,6 @@ int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more_dest, mod } offset += pktlen; - ss_debug(real_offset += pktlen); if (offset >= GWBUF_LENGTH(reply) && reply->next) { @@ -709,7 +707,7 @@ int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more_dest, mod state->state = skip_next; } - *more_dest = more; + *more_out = more; return total; } diff --git a/server/modules/routing/readwritesplit/readwritesplit.cc b/server/modules/routing/readwritesplit/readwritesplit.cc index 24260c7b7..e9eda014b 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.cc +++ b/server/modules/routing/readwritesplit/readwritesplit.cc @@ -537,6 +537,16 @@ bool reply_is_complete(SRWBackend& backend, GWBUF *buffer) LOG_RS(backend, REPLY_STATE_DONE); backend->set_reply_state(REPLY_STATE_DONE); } + else + { + // This is an OK packet and more results will follow + ss_dassert(mxs_mysql_is_ok_packet(buffer) && + mxs_mysql_more_results_after_ok(buffer)); + + LOG_RS(backend, REPLY_STATE_RSET_COLDEF); + backend->set_reply_state(REPLY_STATE_RSET_COLDEF); + return reply_is_complete(backend, buffer); + } } else { @@ -546,6 +556,16 @@ bool reply_is_complete(SRWBackend& backend, GWBUF *buffer) int n_eof = modutil_count_signal_packets(buffer, n_old_eof, &more, &state); backend->set_large_packet(state.state); + if (n_eof > 2) + { + /** + * We have multiple results in the buffer, we only care about + * the state of the last one. Skip the complete result sets and act + * like we're processing a single result set. + */ + n_eof = n_eof % 2 ? 1 : 2; + } + if (n_eof == 0) { /** Waiting for the EOF packet after the column definitions */