mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge rurik.mysql.com:/home/igor/mysql-4.1
into rurik.mysql.com:/home/igor/dev/mysql-4.1-0
This commit is contained in:
@ -788,7 +788,6 @@ extern my_bool init_compiled_charsets(myf flags);
|
||||
extern void add_compiled_collation(CHARSET_INFO *cs);
|
||||
extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to,
|
||||
const char *from, ulong length);
|
||||
extern char *bare_str_to_hex(char *to, const char *from, uint len);
|
||||
#ifdef __WIN__
|
||||
#define BACKSLASH_MBTAIL
|
||||
/* File system character set */
|
||||
|
@ -8576,6 +8576,20 @@ FC4B
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t3;
|
||||
CREATE TABLE t1(f1 blob);
|
||||
PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
|
||||
SET @var1= x'8300';
|
||||
EXECUTE stmt1 USING @var1;
|
||||
SHOW BINLOG EVENTS FROM 27642;
|
||||
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||
master-bin.000001 27642 Query 1 27642 use `test`; CREATE TABLE t1(f1 blob)
|
||||
master-bin.000001 27701 Query 1 27701 use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8
|
||||
master-bin.000001 27837 User var 1 27837 @`var1`=_binary 0x8300 COLLATE binary
|
||||
master-bin.000001 27876 Query 1 27876 use `test`; INSERT INTO t1 VALUES(@'var1')
|
||||
SELECT HEX(f1) FROM t1;
|
||||
HEX(f1)
|
||||
8300
|
||||
DROP table t1;
|
||||
SET collation_connection='cp932_japanese_ci';
|
||||
create table t1 select repeat('a',4000) a;
|
||||
delete from t1;
|
||||
|
@ -401,6 +401,26 @@ DROP TABLE t2;
|
||||
DROP TABLE t3;
|
||||
#DROP TABLE t4;
|
||||
|
||||
# Test prepared statement with 0x8300 sequence in parameter while
|
||||
# running with cp932 client character set.
|
||||
CREATE TABLE t1(f1 blob);
|
||||
PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
|
||||
SET @var1= x'8300';
|
||||
# TODO: Note that this doesn't actually test the code which was added for
|
||||
# bug#11338 because this syntax for prepared statements causes the PS to
|
||||
# be replicated differently than if we executed the PS from C or Java.
|
||||
# Using this syntax, variable names are inserted into the binlog instead
|
||||
# of values. The real goal of this test is to check the code that was
|
||||
# added to Item_param::query_val_str() in order to do hex encoding of
|
||||
# PS parameters when the client character set is cp932;
|
||||
# Bug#11338 has an example java program which can be used to verify this
|
||||
# code (and I have used it to test the fix) until there is some way to
|
||||
# exercise this code from mysql-test-run.
|
||||
EXECUTE stmt1 USING @var1;
|
||||
SHOW BINLOG EVENTS FROM 27642;
|
||||
SELECT HEX(f1) FROM t1;
|
||||
DROP table t1;
|
||||
# end test for bug#11338
|
||||
|
||||
SET collation_connection='cp932_japanese_ci';
|
||||
-- source include/ctype_filesort.inc
|
||||
|
@ -663,21 +663,3 @@ CHARSET_INFO *fs_character_set()
|
||||
return fs_cset_cache;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Transforms a string into hex form.
|
||||
*/
|
||||
char *bare_str_to_hex(char *to, const char *from, uint len)
|
||||
{
|
||||
char *p= to;
|
||||
uint i;
|
||||
for (i= 0; i < len; i++, p+= 2)
|
||||
{
|
||||
/* val[i] is char. Casting to uchar helps greatly if val[i] < 0 */
|
||||
uint tmp= (uint) (uchar) from[i];
|
||||
p[0]= _dig_vec_upper[tmp >> 4];
|
||||
p[1]= _dig_vec_upper[tmp & 15];
|
||||
}
|
||||
*p= 0;
|
||||
return p; // pointer to end 0 of 'to'
|
||||
}
|
||||
|
15
sql/item.cc
15
sql/item.cc
@ -1230,7 +1230,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
|
||||
CHARSET_INFO *tocs= thd->variables.collation_connection;
|
||||
uint32 dummy_offset;
|
||||
|
||||
value.cs_info.character_set_client= fromcs;
|
||||
value.cs_info.character_set_of_placeholder= fromcs;
|
||||
/*
|
||||
Setup source and destination character sets so that they
|
||||
are different only if conversion is necessary: this will
|
||||
@ -1443,7 +1443,7 @@ String *Item_param::val_str(String* str)
|
||||
and avoid one more memcpy/alloc between str and log string.
|
||||
*/
|
||||
|
||||
const String *Item_param::query_val_str(String* str, THD *thd) const
|
||||
const String *Item_param::query_val_str(String* str) const
|
||||
{
|
||||
switch (state) {
|
||||
case INT_VALUE:
|
||||
@ -1482,18 +1482,17 @@ const String *Item_param::query_val_str(String* str, THD *thd) const
|
||||
|
||||
buf= str->c_ptr_quick();
|
||||
ptr= buf;
|
||||
if (thd->charset()->escape_with_backslash_is_dangerous)
|
||||
if (value.cs_info.character_set_client->escape_with_backslash_is_dangerous)
|
||||
{
|
||||
ptr= strmov(ptr, "x\'");
|
||||
ptr= bare_str_to_hex(ptr, str_value.ptr(), str_value.length());
|
||||
ptr= str_to_hex(ptr, str_value.ptr(), str_value.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr++= '\'';
|
||||
ptr+= escape_string_for_mysql(str_value.charset(), ptr,
|
||||
str_value.ptr(), str_value.length());
|
||||
*ptr++='\'';
|
||||
}
|
||||
*ptr++='\'';
|
||||
str->length(ptr - buf);
|
||||
break;
|
||||
}
|
||||
@ -1523,10 +1522,10 @@ bool Item_param::convert_str_value(THD *thd)
|
||||
here only if conversion is really necessary.
|
||||
*/
|
||||
if (value.cs_info.final_character_set_of_str_value !=
|
||||
value.cs_info.character_set_client)
|
||||
value.cs_info.character_set_of_placeholder)
|
||||
{
|
||||
rc= thd->convert_string(&str_value,
|
||||
value.cs_info.character_set_client,
|
||||
value.cs_info.character_set_of_placeholder,
|
||||
value.cs_info.final_character_set_of_str_value);
|
||||
}
|
||||
else
|
||||
|
@ -532,6 +532,7 @@ public:
|
||||
struct CONVERSION_INFO
|
||||
{
|
||||
CHARSET_INFO *character_set_client;
|
||||
CHARSET_INFO *character_set_of_placeholder;
|
||||
/*
|
||||
This points at character set of connection if conversion
|
||||
to it is required (i. e. if placeholder typecode is not BLOB).
|
||||
@ -591,7 +592,7 @@ public:
|
||||
*/
|
||||
void (*set_param_func)(Item_param *param, uchar **pos, ulong len);
|
||||
|
||||
const String *query_val_str(String *str, THD *thd) const;
|
||||
const String *query_val_str(String *str) const;
|
||||
|
||||
bool convert_str_value(THD *thd);
|
||||
|
||||
|
@ -207,7 +207,7 @@ static inline int read_str(char * &buf, char *buf_end, char * &str,
|
||||
/*
|
||||
Transforms a string into "" or its expression in 0x... form.
|
||||
*/
|
||||
static char *str_to_hex(char *to, char *from, uint len)
|
||||
char *str_to_hex(char *to, const char *from, uint len)
|
||||
{
|
||||
char *p= to;
|
||||
if (len)
|
||||
|
@ -1069,5 +1069,5 @@ public:
|
||||
bool is_valid() { return 1; }
|
||||
};
|
||||
#endif
|
||||
|
||||
char *str_to_hex(char *to, const char *from, uint len);
|
||||
#endif /* _log_event_h */
|
||||
|
@ -528,7 +528,9 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
param->set_param_func= set_param_str;
|
||||
param->value.cs_info.character_set_client= &my_charset_bin;
|
||||
param->value.cs_info.character_set_of_placeholder= &my_charset_bin;
|
||||
param->value.cs_info.character_set_client=
|
||||
thd->variables.character_set_client;
|
||||
param->value.cs_info.final_character_set_of_str_value= &my_charset_bin;
|
||||
param->item_type= Item::STRING_ITEM;
|
||||
param->item_result_type= STRING_RESULT;
|
||||
@ -544,6 +546,7 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
|
||||
CHARSET_INFO *tocs= thd->variables.collation_connection;
|
||||
uint32 dummy_offset;
|
||||
|
||||
param->value.cs_info.character_set_of_placeholder= fromcs;
|
||||
param->value.cs_info.character_set_client= fromcs;
|
||||
|
||||
/*
|
||||
@ -601,7 +604,7 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array,
|
||||
param->set_param_func(param, &read_pos, data_end - read_pos);
|
||||
}
|
||||
}
|
||||
res= param->query_val_str(&str, thd);
|
||||
res= param->query_val_str(&str);
|
||||
if (param->convert_str_value(thd))
|
||||
DBUG_RETURN(1); /* out of memory */
|
||||
|
||||
@ -749,7 +752,7 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt, String *query)
|
||||
client_param->buffer_length);
|
||||
}
|
||||
}
|
||||
res= param->query_val_str(&str, thd);
|
||||
res= param->query_val_str(&str);
|
||||
if (param->convert_str_value(thd))
|
||||
DBUG_RETURN(1); /* out of memory */
|
||||
|
||||
|
Reference in New Issue
Block a user