From: ahmad.abdullateef Date: November 8 2012 6:43am Subject: bzr push into mysql-trunk branch (ahmad.abdullateef:4933 to 4934) Bug#14670465 List-Archive: http://lists.mysql.com/commits/145210 X-Bug: 14670465 Message-Id: <20121108064344.9644.64360.4934@AHABDULL-IN.idc.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4934 Ahmad Abdullateef 2012-11-08 BUG#14670465 - PLEASE PRINT HUMAN READABLE, ESCAPED XID DATA IN XA RECOVER OUTPUT DESCRIPTION: xa recover command was not diplaying non printable ASCII characters in the XID data. FIX : Now XID is Hex encoded if it contains un-printable characters. modified: mysql-test/r/xa.result mysql-test/t/xa.test sql/handler.cc sql/sql_string.cc sql/sql_string.h 4933 Joerg Bruehe 2012-11-07 [merge] Upmerge. renamed: SPECIFIC-ULN/ => packaging/rpm-uln/ modified: CMakeLists.txt cmake/install_layout.cmake packaging/rpm-uln/mysql.spec.sh === modified file 'mysql-test/r/xa.result' --- a/mysql-test/r/xa.result 2012-03-15 09:54:32 +0000 +++ b/mysql-test/r/xa.result 2012-11-08 06:42:57 +0000 @@ -231,3 +231,26 @@ XA PREPARE 'xid1'; XA ROLLBACK 'xid1'; # Connection default DROP TABLE t1, t2; +# +# Bug#14670465 PLEASE PRINT HUMAN READABLE, ESCAPED +# XID DATA IN XA RECOVER OUTPUT +# +# +# xa Recover command was not diplaying non printable ASCII +# characters in the XID previosuly. Now there is another column +# in the result set which is a Hex Encoded String of the XID. +# +xa start 0xABCDEF1234567890, 0x01, 0x02 ; +xa end 0xABCDEF1234567890, 0x01, 0x02 ; +xa prepare 0xABCDEF1234567890, 0x01, 0x02 ; +xa recover; +formatID gtrid_length bqual_length data +2 8 1 0xABCDEF123456789001 +xa rollback 0xABCDEF1234567890, 0x01, 0x02 ; +xa start 0x4142434445, 0x46, 0x02 ; +xa end 0x4142434445, 0x46, 0x02 ; +xa prepare 0x4142434445, 0x46, 0x02 ; +xa recover; +formatID gtrid_length bqual_length data +2 5 1 ABCDEF +xa rollback 0x4142434445, 0x46, 0x02 ; === modified file 'mysql-test/t/xa.test' --- a/mysql-test/t/xa.test 2012-03-15 09:54:32 +0000 +++ b/mysql-test/t/xa.test 2012-11-08 06:42:57 +0000 @@ -399,3 +399,24 @@ disconnect con2; # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc +--echo # +--echo # Bug#14670465 PLEASE PRINT HUMAN READABLE, ESCAPED +--echo # XID DATA IN XA RECOVER OUTPUT +--echo # +--echo # +--echo # xa Recover command was not diplaying non printable ASCII +--echo # characters in the XID previosuly. Now there is another column +--echo # in the result set which is a Hex Encoded String of the XID. +--echo # +xa start 0xABCDEF1234567890, 0x01, 0x02 ; +xa end 0xABCDEF1234567890, 0x01, 0x02 ; +xa prepare 0xABCDEF1234567890, 0x01, 0x02 ; +xa recover; +xa rollback 0xABCDEF1234567890, 0x01, 0x02 ; + +xa start 0x4142434445, 0x46, 0x02 ; +xa end 0x4142434445, 0x46, 0x02 ; +xa prepare 0x4142434445, 0x46, 0x02 ; +xa recover; +xa rollback 0x4142434445, 0x46, 0x02 ; + === modified file 'sql/handler.cc' --- a/sql/handler.cc 2012-11-07 11:45:06 +0000 +++ b/sql/handler.cc 2012-11-08 06:42:57 +0000 @@ -1654,6 +1654,21 @@ int ha_commit_or_rollback_by_xid(THD *th } +/** + This function converts the XID to HEX string form prefixed by '0x' + + @buf has to be atleast (XIDDATASIZE*2+2+1) in size +*/ +static uint xid_to_hex_str(char *buf, size_t buf_len, XID *xid) +{ + *buf++= '0'; + *buf++= 'x'; + + return bin_to_hex_str(buf, buf_len-2, (char*)&xid->data, + xid->gtrid_length+xid->bqual_length) + 2; +} + + #ifndef DBUG_OFF /** @note @@ -1858,6 +1873,31 @@ int ha_recover(HASH *commit_list) DBUG_RETURN(0); } + +/** + This function checks if the XID consists of all printable charaters + i.e ASCII 32 - 127 and returns true if it is so. + + @xid has to be pointer to a valid XID +*/ +static bool is_printable_xid(XID *xid) +{ + int i; + unsigned char *c= (unsigned char*)&xid->data; + int xid_len= xid->gtrid_length+xid->bqual_length; + + for (i=0; i < xid_len; i++, c++) + { + if(*c < 32 || *c > 127) + { + return false; + } + } + + return true; +} + + /** return the list of XID's to a client, the same way SHOW commands do. @@ -1877,7 +1917,7 @@ bool mysql_xa_recover(THD *thd) field_list.push_back(new Item_int(NAME_STRING("formatID"), 0, MY_INT32_NUM_DECIMAL_DIGITS)); field_list.push_back(new Item_int(NAME_STRING("gtrid_length"), 0, MY_INT32_NUM_DECIMAL_DIGITS)); field_list.push_back(new Item_int(NAME_STRING("bqual_length"), 0, MY_INT32_NUM_DECIMAL_DIGITS)); - field_list.push_back(new Item_empty_string("data",XIDDATASIZE)); + field_list.push_back(new Item_empty_string("data", XIDDATASIZE*2+2)); if (protocol->send_result_set_metadata(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) @@ -1892,8 +1932,25 @@ bool mysql_xa_recover(THD *thd) protocol->store_longlong((longlong)xs->xid.formatID, FALSE); protocol->store_longlong((longlong)xs->xid.gtrid_length, FALSE); protocol->store_longlong((longlong)xs->xid.bqual_length, FALSE); - protocol->store(xs->xid.data, xs->xid.gtrid_length+xs->xid.bqual_length, - &my_charset_bin); + + if(is_printable_xid(&xs->xid) == true) + { + protocol->store(xs->xid.data, xs->xid.gtrid_length+xs->xid.bqual_length, + &my_charset_bin); + } + else + { + uint xid_str_len; + /* + xid_buf contains enough space for 0x followed by HEX representation of + the binary XID data and one null termination character. + */ + char xid_buf[XIDDATASIZE*2+2+1]; + + xid_str_len= xid_to_hex_str(xid_buf, sizeof(xid_buf), &xs->xid); + protocol->store(xid_buf, xid_str_len, &my_charset_bin); + } + if (protocol->write()) { mysql_mutex_unlock(&LOCK_xid_cache); @@ -1907,6 +1964,7 @@ bool mysql_xa_recover(THD *thd) DBUG_RETURN(0); } + /** @details This function should be called when MySQL sends rows of a SELECT result set === modified file 'sql/sql_string.cc' --- a/sql/sql_string.cc 2012-11-06 09:20:51 +0000 +++ b/sql/sql_string.cc 2012-11-08 06:42:57 +0000 @@ -1131,3 +1131,40 @@ uint convert_to_printable(char *to, size *t= '\0'; return t - to; } + + +/** + Convert a buffer to printable HEX encoded string + For eg: ABCDEF1234 + + + @param to output buffer + @param to_len size of the output buffer (from_len*2 + 1 or greater) + @param from input buffer + @param from_len size of the input buffer + + @return number of bytes in the output string +*/ +uint bin_to_hex_str(char *to, size_t to_len, char *from, size_t from_len) +{ + char *out; + char *in; + size_t i; + + if (to_len < ((from_len * 2) + 1)) + return 0 ; + + out= to; + in= from; + + for (i=0; i < from_len; i++, in++) + { + *out++=_dig_vec_upper[((unsigned char) *in) >> 4]; + *out++=_dig_vec_upper[((unsigned char) *in) & 0xF]; + } + + *out= '\0'; + + return out - to; +} + === modified file 'sql/sql_string.h' --- a/sql/sql_string.h 2012-11-06 14:16:49 +0000 +++ b/sql/sql_string.h 2012-11-08 06:42:57 +0000 @@ -136,6 +136,8 @@ uint convert_to_printable(char *to, size const char *from, size_t from_len, const CHARSET_INFO *from_cs, size_t nbytes= 0); +uint bin_to_hex_str(char *to, size_t to_len, char *from, size_t from_len); + class String { char *Ptr; No bundle (reason: useless for push emails).