3102 Mats Kindahl 2010-10-27 [merge]
Merging patch for BUG#52131 with mysql-5.5-bugteam.
modified:
sql/field.cc
sql/field.h
sql/rpl_record.cc
3101 Georgi Kodinov 2010-10-25
Bug #57689: mysql_change_user() breaks user connection on older clients
COM_CHANGE_USER was always handled like an implicit request to change the
client plugin, so that the client can re-use the same code path for both normal
login and COM_CHANGE_USER. However this doesn't really work well with old
clients because they don't understand the request to change a client plugin.
Fixed by implementing a special state in the code (and old client issuing
COM_CHANGE_USER). In this state the server parses the COM_CHANGE_USER
package and pushes back the password hash, the user name and the database
to the input stream in the same order that the native password server side plugin
expects. As a result it replies with an OK/FAIL just like the old server does thus
making the new server compatible with older clients.
No test case added, since it would requre an old client binary. Tested using
accounts with and without passwords. Tested with a correct and incorrect
password.
modified:
sql/sql_acl.cc
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2010-10-19 06:45:18 +0000
+++ b/sql/field.cc 2010-10-27 21:12:45 +0000
@@ -7725,12 +7725,6 @@ void Field_blob::sql_type(String &res) c
uchar *Field_blob::pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first)
{
- DBUG_ENTER("Field_blob::pack");
- DBUG_PRINT("enter", ("to: 0x%lx; from: 0x%lx;"
- " max_length: %u; low_byte_first: %d",
- (ulong) to, (ulong) from,
- max_length, low_byte_first));
- DBUG_DUMP("record", from, table->s->reclength);
uchar *save= ptr;
ptr= (uchar*) from;
uint32 length=get_length(); // Length of from string
@@ -7751,8 +7745,7 @@ uchar *Field_blob::pack(uchar *to, const
memcpy(to+packlength, from,length);
}
ptr=save; // Restore org row pointer
- DBUG_DUMP("packed", to, packlength + length);
- DBUG_RETURN(to+packlength+length);
+ return to+packlength+length;
}
@@ -8396,6 +8389,50 @@ uint Field_enum::is_equal(Create_field *
}
+uchar *Field_enum::pack(uchar *to, const uchar *from,
+ uint max_length, bool low_byte_first)
+{
+ DBUG_ENTER("Field_enum::pack");
+ DBUG_PRINT("debug", ("packlength: %d", packlength));
+ DBUG_DUMP("from", from, packlength);
+
+ switch (packlength)
+ {
+ case 1:
+ *to = *from;
+ DBUG_RETURN(to + 1);
+ case 2: DBUG_RETURN(pack_int16(to, from, low_byte_first));
+ case 3: DBUG_RETURN(pack_int24(to, from, low_byte_first));
+ case 4: DBUG_RETURN(pack_int32(to, from, low_byte_first));
+ case 8: DBUG_RETURN(pack_int64(to, from, low_byte_first));
+ default:
+ DBUG_ASSERT(0);
+ }
+}
+
+const uchar *Field_enum::unpack(uchar *to, const uchar *from,
+ uint param_data, bool low_byte_first)
+{
+ DBUG_ENTER("Field_enum::unpack");
+ DBUG_PRINT("debug", ("packlength: %d", packlength));
+ DBUG_DUMP("from", from, packlength);
+
+ switch (packlength)
+ {
+ case 1:
+ *to = *from;
+ DBUG_RETURN(from + 1);
+
+ case 2: DBUG_RETURN(unpack_int16(to, from, low_byte_first));
+ case 3: DBUG_RETURN(unpack_int24(to, from, low_byte_first));
+ case 4: DBUG_RETURN(unpack_int32(to, from, low_byte_first));
+ case 8: DBUG_RETURN(unpack_int64(to, from, low_byte_first));
+ default:
+ DBUG_ASSERT(0);
+ }
+}
+
+
/**
@return
returns 1 if the fields are equally defined
=== modified file 'sql/field.h'
--- a/sql/field.h 2010-07-23 20:17:55 +0000
+++ b/sql/field.h 2010-10-06 17:20:18 +0000
@@ -554,6 +554,48 @@ private:
{ return 0; }
protected:
+ static void handle_int16(uchar *to, const uchar *from,
+ bool low_byte_first_from, bool low_byte_first_to)
+ {
+ int16 val;
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_from)
+ val = sint2korr(from);
+ else
+#endif
+ shortget(val, from);
+
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_to)
+ int2store(to, val);
+ else
+#endif
+ shortstore(to, val);
+ }
+
+ static void handle_int24(uchar *to, const uchar *from,
+ bool low_byte_first_from, bool low_byte_first_to)
+ {
+ int32 val;
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_from)
+ val = sint3korr(from);
+ else
+#endif
+ val= (from[0] << 16) + (from[1] << 8) + from[2];
+
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_to)
+ int2store(to, val);
+ else
+#endif
+ {
+ to[0]= 0xFF & (val >> 16);
+ to[1]= 0xFF & (val >> 8);
+ to[2]= 0xFF & val;
+ }
+ }
+
/*
Helper function to pack()/unpack() int32 values
*/
@@ -598,6 +640,32 @@ protected:
longlongstore(to, val);
}
+ uchar *pack_int16(uchar *to, const uchar *from, bool low_byte_first_to)
+ {
+ handle_int16(to, from, table->s->db_low_byte_first, low_byte_first_to);
+ return to + sizeof(int16);
+ }
+
+ const uchar *unpack_int16(uchar* to, const uchar *from,
+ bool low_byte_first_from)
+ {
+ handle_int16(to, from, low_byte_first_from, table->s->db_low_byte_first);
+ return from + sizeof(int16);
+ }
+
+ uchar *pack_int24(uchar *to, const uchar *from, bool low_byte_first_to)
+ {
+ handle_int24(to, from, table->s->db_low_byte_first, low_byte_first_to);
+ return to + 3;
+ }
+
+ const uchar *unpack_int24(uchar* to, const uchar *from,
+ bool low_byte_first_from)
+ {
+ handle_int24(to, from, low_byte_first_from, table->s->db_low_byte_first);
+ return from + 3;
+ }
+
uchar *pack_int32(uchar *to, const uchar *from, bool low_byte_first_to)
{
handle_int32(to, from, table->s->db_low_byte_first, low_byte_first_to);
@@ -918,41 +986,13 @@ public:
virtual uchar *pack(uchar* to, const uchar *from,
uint max_length, bool low_byte_first)
{
- int16 val;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- val = sint2korr(from);
- else
-#endif
- shortget(val, from);
-
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- int2store(to, val);
- else
-#endif
- shortstore(to, val);
- return to + sizeof(val);
+ return pack_int16(to, from, low_byte_first);
}
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first)
{
- int16 val;
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- val = sint2korr(from);
- else
-#endif
- shortget(val, from);
-
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- int2store(to, val);
- else
-#endif
- shortstore(to, val);
- return from + sizeof(val);
+ return unpack_int16(to, from, low_byte_first);
}
};
@@ -1895,6 +1935,12 @@ public:
bool has_charset(void) const { return TRUE; }
/* enum and set are sorted as integers */
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
+
+ virtual uchar *pack(uchar *to, const uchar *from,
+ uint max_length, bool low_byte_first);
+ virtual const uchar *unpack(uchar *to, const uchar *from,
+ uint param_data, bool low_byte_first);
+
private:
int do_save_field_metadata(uchar *first_byte);
uint is_equal(Create_field *new_field);
=== modified file 'sql/rpl_record.cc'
--- a/sql/rpl_record.cc 2010-07-24 13:31:48 +0000
+++ b/sql/rpl_record.cc 2010-10-06 17:20:18 +0000
@@ -78,8 +78,6 @@ pack_row(TABLE *table, MY_BITMAP const*
unsigned int null_mask= 1U;
for ( ; (field= *p_field) ; p_field++)
{
- DBUG_PRINT("debug", ("null_mask=%d; null_ptr=%p; row_data=%p; null_byte_count=%d",
- null_mask, null_ptr, row_data, null_byte_count));
if (bitmap_is_set(cols, p_field - table->field))
{
my_ptrdiff_t offset;
@@ -110,6 +108,7 @@ pack_row(TABLE *table, MY_BITMAP const*
field->field_name, field->real_type(),
(ulong) old_pack_ptr, (ulong) pack_ptr,
(int) (pack_ptr - old_pack_ptr)));
+ DBUG_DUMP("packed_data", old_pack_ptr, pack_ptr - old_pack_ptr);
}
null_mask <<= 1;
@@ -380,8 +379,11 @@ unpack_row(Relay_log_info const *rli,
}
DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set
- if (!((null_bits & null_mask) && tabledef->maybe_null(i)))
- pack_ptr+= tabledef->calc_field_size(i, (uchar *) pack_ptr);
+ if (!((null_bits & null_mask) && tabledef->maybe_null(i))) {
+ uint32 len= tabledef->calc_field_size(i, (uchar *) pack_ptr);
+ DBUG_DUMP("field_data", pack_ptr, len);
+ pack_ptr+= len;
+ }
null_mask <<= 1;
}
}
Attachment: [text/bzr-bundle] bzr/mats.kindahl@oracle.com-20101027211245-nzxjdnbrz78vav6s.bundle
| Thread |
|---|
| • bzr push into mysql-5.5-bugteam branch (mats.kindahl:3101 to 3102) Bug#52131 | Mats Kindahl | 27 Oct |