diff --git a/include/MySQL_Protocol.h b/include/MySQL_Protocol.h index 69ea80509..28df8a4dc 100644 --- a/include/MySQL_Protocol.h +++ b/include/MySQL_Protocol.h @@ -11,6 +11,7 @@ extern MySQL_Variables mysql_variables; class MySQL_ResultSet { private: + bool deprecate_eof_active; public: bool transfer_started; bool resultset_completed; @@ -76,7 +77,7 @@ class MySQL_Protocol { // - a pointer to void pointer, used to return the packet if not NULL // - a pointer to unsigned int, used to return the size of the packet if not NULL // for now, they all return true - bool generate_pkt_OK(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, unsigned int affected_rows, uint64_t last_insert_id, uint16_t status, uint16_t warnings, char *msg); + bool generate_pkt_OK(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, unsigned int affected_rows, uint64_t last_insert_id, uint16_t status, uint16_t warnings, char *msg, bool eof_identifier=false); bool generate_pkt_ERR(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, uint16_t error_code, char *sql_state, const char *sql_message, bool track=false); bool generate_pkt_EOF(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, uint16_t warnings, uint16_t status, MySQL_ResultSet *myrs=NULL); // bool generate_COM_INIT_DB(bool send, void **ptr, unsigned int *len, char *schema); diff --git a/lib/MySQL_Protocol.cpp b/lib/MySQL_Protocol.cpp index 796d7e5f0..98d682cc1 100644 --- a/lib/MySQL_Protocol.cpp +++ b/lib/MySQL_Protocol.cpp @@ -604,7 +604,7 @@ bool MySQL_Protocol::generate_pkt_ERR(bool send, void **ptr, unsigned int *len, return true; } -bool MySQL_Protocol::generate_pkt_OK(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, unsigned int affected_rows, uint64_t last_insert_id, uint16_t status, uint16_t warnings, char *msg) { +bool MySQL_Protocol::generate_pkt_OK(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, unsigned int affected_rows, uint64_t last_insert_id, uint16_t status, uint16_t warnings, char *msg, bool eof_identifier) { if ((*myds)->sess->mirror==true) { return true; } @@ -652,7 +652,18 @@ bool MySQL_Protocol::generate_pkt_OK(bool send, void **ptr, unsigned int *len, u unsigned char *_ptr=(unsigned char *)l_alloc(size); memcpy(_ptr, &myhdr, sizeof(mysql_hdr)); int l=sizeof(mysql_hdr); - _ptr[l]=0x00; l++; + + /* + * Use 0xFE packet header if eof_identifier is true. + * OK packet with 0xFE replaces EOF packet for clients + * supporting CLIENT_DEPRECATE_EOF flag + */ + if (eof_identifier) + _ptr[l]=0xFE; + else + _ptr[l]=0x00; + + l++; l+=write_encoded_length(_ptr+l, affected_rows, affected_rows_len, affected_rows_prefix); l+=write_encoded_length(_ptr+l, last_insert_id, last_insert_id_len, last_insert_id_prefix); int16_t internal_status = status; @@ -2387,6 +2398,9 @@ void MySQL_ResultSet::init(MySQL_Protocol *_myprot, MYSQL_RES *_res, MYSQL *_my, } } } + + deprecate_eof_active = c_myds->myconn && (c_myds->myconn->options.client_flag & CLIENT_DEPRECATE_EOF); + // first EOF unsigned int nTrx=myds->sess->NumActiveTransactions(); uint16_t setStatus = (nTrx ? SERVER_STATUS_IN_TRANS : 0 ); @@ -2402,7 +2416,7 @@ void MySQL_ResultSet::init(MySQL_Protocol *_myprot, MYSQL_RES *_res, MYSQL *_my, if (RESULTSET_BUFLEN <= (buffer_used + 9)) { buffer_to_PSarrayOut(); } - if (myds->com_field_list==false) { + if (!deprecate_eof_active && myds->com_field_list==false) { myprot->generate_pkt_EOF(false, NULL, NULL, sid, 0, setStatus, this); sid++; resultset_size += 9; @@ -2602,7 +2616,6 @@ unsigned int MySQL_ResultSet::add_row2(MYSQL_ROWS *row, unsigned char *offset) { } void MySQL_ResultSet::add_eof() { - //PtrSize_t pkt; if (myprot) { unsigned int nTrx=myds->sess->NumActiveTransactions(); uint16_t setStatus = (nTrx ? SERVER_STATUS_IN_TRANS : 0 ); @@ -2613,13 +2626,23 @@ void MySQL_ResultSet::add_eof() { //PSarrayOUT->add(pkt.ptr,pkt.size); //sid++; //resultset_size+=pkt.size; - if (RESULTSET_BUFLEN <= (buffer_used + 9)) { + + if (deprecate_eof_active) { + PtrSize_t pkt; buffer_to_PSarrayOut(); + myprot->generate_pkt_OK(false, &pkt.ptr, &pkt.size, sid, 0, 0, setStatus, 0, NULL, true); + PSarrayOUT.add(pkt.ptr, pkt.size); + resultset_size += pkt.size; + } + else { + if (RESULTSET_BUFLEN <= (buffer_used + 9)) { + buffer_to_PSarrayOut(); + } + myprot->generate_pkt_EOF(false, NULL, NULL, sid, 0, setStatus, this); + resultset_size += 9; + buffer_to_PSarrayOut(true); } - myprot->generate_pkt_EOF(false, NULL, NULL, sid, 0, setStatus, this); sid++; - resultset_size += 9; - buffer_to_PSarrayOut(true); } resultset_completed=true; }