Commit c05ecda6 authored by Sergei Golubchik's avatar Sergei Golubchik

fix string literal escaping in views

process multibyte characters correctly, don't escape half of the character
parent 69684f68
...@@ -76,6 +76,15 @@ INSERT INTO t1 VALUES (_BINARY'\\'' ...@@ -76,6 +76,15 @@ INSERT INTO t1 VALUES (_BINARY'\\''
SELECT a, HEX(a) FROM t1; SELECT a, HEX(a) FROM t1;
DROP TABLE t1; DROP TABLE t1;
#
# test how strings are written into view's frm
#
disable_view_protocol;
create view v1 as select hex('\'), hex('\t');
select * from v1;
drop view v1;
enable_view_protocol;
# Checking that with character_set_client=binary 0x5C in 0xE05C # Checking that with character_set_client=binary 0x5C in 0xE05C
# is treated as escape rather than the second byte of a multi-byte character, # is treated as escape rather than the second byte of a multi-byte character,
# even if character_set_connection is big5/cp932/gbk/sjis. # even if character_set_connection is big5/cp932/gbk/sjis.
...@@ -109,5 +118,5 @@ SELECT HEX(a) FROM t1; ...@@ -109,5 +118,5 @@ SELECT HEX(a) FROM t1;
DROP TABLE t1; DROP TABLE t1;
--enable_view_protocol --enable_view_protocol
--echo # Start of ctype_E05C.inc --echo # End of ctype_E05C.inc
...@@ -537,15 +537,15 @@ create table t1 (a blob); ...@@ -537,15 +537,15 @@ create table t1 (a blob);
insert into t1 values (0xEE00); insert into t1 values (0xEE00);
select * into outfile 'test/t1.txt' from t1; select * into outfile 'test/t1.txt' from t1;
delete from t1; delete from t1;
select hex(load_file('MYSQLD_DATADIR/test/t1.txt'));; select hex(load_file('MYSQLD_DATADIR/test/t1.txt')) as lf;
hex(load_file('MYSQLD_DATADIR/test/t1.txt')) lf
5CEE5C300A 5CEE5C300A
load data infile 't1.txt' into table t1; load data infile 't1.txt' into table t1;
select hex(a) from t1; select hex(a) from t1;
hex(a) hex(a)
EE00 EE00
drop table t1; drop table t1;
End of 5.0 tests # End of 5.0 tests
# #
# Start of 5.5 tests # Start of 5.5 tests
# #
...@@ -4705,6 +4705,11 @@ a HEX(a) ...@@ -4705,6 +4705,11 @@ a HEX(a)
\'\ 5C27E05C \'\ 5C27E05C
\'\ E05C275C \'\ E05C275C
DROP TABLE t1; DROP TABLE t1;
create view v1 as select hex('\'), hex('\t');
select * from v1;
hex('\') hex('\t')
E05C E05C74
drop view v1;
SET character_set_client=binary, character_set_results=binary; SET character_set_client=binary, character_set_results=binary;
SELECT @@character_set_client, @@character_set_connection, @@character_set_results; SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
@@character_set_client @@character_set_connection @@character_set_results @@character_set_client @@character_set_connection @@character_set_results
...@@ -4744,7 +4749,7 @@ HEX(a) ...@@ -4744,7 +4749,7 @@ HEX(a)
E05C5B E05C5B
E05B E05B
DROP TABLE t1; DROP TABLE t1;
# Start of ctype_E05C.inc # End of ctype_E05C.inc
SET NAMES big5; SET NAMES big5;
CREATE TABLE t1 (a ENUM('@') CHARACTER SET big5); CREATE TABLE t1 (a ENUM('@') CHARACTER SET big5);
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
......
...@@ -79,18 +79,15 @@ create table t1 (a blob); ...@@ -79,18 +79,15 @@ create table t1 (a blob);
insert into t1 values (0xEE00); insert into t1 values (0xEE00);
select * into outfile 'test/t1.txt' from t1; select * into outfile 'test/t1.txt' from t1;
delete from t1; delete from t1;
#enable after fix MDEV-27871
--disable_view_protocol
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
--eval select hex(load_file('$MYSQLD_DATADIR/test/t1.txt')); --eval select hex(load_file('$MYSQLD_DATADIR/test/t1.txt')) as lf
load data infile 't1.txt' into table t1; load data infile 't1.txt' into table t1;
select hex(a) from t1; select hex(a) from t1;
--remove_file $MYSQLD_DATADIR/test/t1.txt --remove_file $MYSQLD_DATADIR/test/t1.txt
drop table t1; drop table t1;
#enable_view_protocol
# #
--echo End of 5.0 tests --echo # End of 5.0 tests
--echo # --echo #
......
...@@ -20413,6 +20413,11 @@ a HEX(a) ...@@ -20413,6 +20413,11 @@ a HEX(a)
\'à\ 5C27E05C \'à\ 5C27E05C
à\'\ E05C275C à\'\ E05C275C
DROP TABLE t1; DROP TABLE t1;
create view v1 as select hex('à\'), hex('à\t');
select * from v1;
hex('à\') hex('à\t')
E05C E05C74
drop view v1;
SET character_set_client=binary, character_set_results=binary; SET character_set_client=binary, character_set_results=binary;
SELECT @@character_set_client, @@character_set_connection, @@character_set_results; SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
@@character_set_client @@character_set_connection @@character_set_results @@character_set_client @@character_set_connection @@character_set_results
...@@ -20452,7 +20457,7 @@ HEX(a) ...@@ -20452,7 +20457,7 @@ HEX(a)
E05C5B E05C5B
E05B E05B
DROP TABLE t1; DROP TABLE t1;
# Start of ctype_E05C.inc # End of ctype_E05C.inc
# #
# End of 10.0 tests # End of 10.0 tests
# #
...@@ -5053,6 +5053,11 @@ a HEX(a) ...@@ -5053,6 +5053,11 @@ a HEX(a)
\'\ 5C27E05C \'\ 5C27E05C
\'\ E05C275C \'\ E05C275C
DROP TABLE t1; DROP TABLE t1;
create view v1 as select hex('\'), hex('\t');
select * from v1;
hex('\') hex('\t')
E05C E05C74
drop view v1;
SET character_set_client=binary, character_set_results=binary; SET character_set_client=binary, character_set_results=binary;
SELECT @@character_set_client, @@character_set_connection, @@character_set_results; SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
@@character_set_client @@character_set_connection @@character_set_results @@character_set_client @@character_set_connection @@character_set_results
...@@ -5092,7 +5097,7 @@ HEX(a) ...@@ -5092,7 +5097,7 @@ HEX(a)
E05C5B E05C5B
E05B E05B
DROP TABLE t1; DROP TABLE t1;
# Start of ctype_E05C.inc # End of ctype_E05C.inc
SET NAMES utf8, character_set_connection=gbk; SET NAMES utf8, character_set_connection=gbk;
# #
# MDEV-13118 Wrong results with LOWER and UPPER and subquery # MDEV-13118 Wrong results with LOWER and UPPER and subquery
......
...@@ -18677,6 +18677,11 @@ a HEX(a) ...@@ -18677,6 +18677,11 @@ a HEX(a)
\'\ 5C27E05C \'\ 5C27E05C
\'\ E05C275C \'\ E05C275C
DROP TABLE t1; DROP TABLE t1;
create view v1 as select hex('\'), hex('\t');
select * from v1;
hex('\') hex('\t')
E05C E05C74
drop view v1;
SET character_set_client=binary, character_set_results=binary; SET character_set_client=binary, character_set_results=binary;
SELECT @@character_set_client, @@character_set_connection, @@character_set_results; SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
@@character_set_client @@character_set_connection @@character_set_results @@character_set_client @@character_set_connection @@character_set_results
...@@ -18716,7 +18721,7 @@ HEX(a) ...@@ -18716,7 +18721,7 @@ HEX(a)
E05C5B E05C5B
E05B E05B
DROP TABLE t1; DROP TABLE t1;
# Start of ctype_E05C.inc # End of ctype_E05C.inc
# #
# End of 10.0 tests # End of 10.0 tests
# #
......
...@@ -1115,22 +1115,28 @@ String_copier::well_formed_copy(CHARSET_INFO *to_cs, ...@@ -1115,22 +1115,28 @@ String_copier::well_formed_copy(CHARSET_INFO *to_cs,
characters with backslashes as necessary. characters with backslashes as necessary.
Does not add the enclosing quotes, this is left up to caller. Does not add the enclosing quotes, this is left up to caller.
*/ */
#define APPEND(X) if (append(X)) return 1; else break #define APPEND(...) if (append(__VA_ARGS__)) return 1;
bool String::append_for_single_quote(const char *st, size_t len) bool String::append_for_single_quote(const char *st, size_t len)
{ {
const char *end= st+len; const char *end= st+len;
int chlen;
for (; st < end; st++) for (; st < end; st++)
{ {
uchar c= *st; switch (*st)
switch (c)
{ {
case '\\': APPEND(STRING_WITH_LEN("\\\\")); case '\\': APPEND(STRING_WITH_LEN("\\\\")); break;
case '\0': APPEND(STRING_WITH_LEN("\\0")); case '\0': APPEND(STRING_WITH_LEN("\\0")); break;
case '\'': APPEND(STRING_WITH_LEN("\\'")); case '\'': APPEND(STRING_WITH_LEN("\\'")); break;
case '\n': APPEND(STRING_WITH_LEN("\\n")); case '\n': APPEND(STRING_WITH_LEN("\\n")); break;
case '\r': APPEND(STRING_WITH_LEN("\\r")); case '\r': APPEND(STRING_WITH_LEN("\\r")); break;
case '\032': APPEND(STRING_WITH_LEN("\\Z")); case '\032': APPEND(STRING_WITH_LEN("\\Z")); break;
default: APPEND(c); default: if ((chlen= my_charlen(charset(), st, end)) > 0)
{
APPEND(st, chlen);
st+= chlen-1;
}
else
APPEND(*st);
} }
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment