diff options
-rw-r--r-- | mysql-test/r/analyse.result | 6 | ||||
-rw-r--r-- | mysql-test/t/analyse.test | 4 | ||||
-rw-r--r-- | sql/sql_analyse.cc | 59 |
3 files changed, 68 insertions, 1 deletions
diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result index b51afab5b54..8013bc516bb 100644 --- a/mysql-test/r/analyse.result +++ b/mysql-test/r/analyse.result @@ -96,3 +96,9 @@ select * from t2; Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype test.t1.a 1 2 1 1 0 0 1.5000 0.5000 ENUM('1','2') NOT NULL drop table t1,t2; +create table t1 (v varchar(128)); +insert into t1 values ('abc'),('abc\'def\\hij\"klm\0opq'),('\''),('\"'),('\\'),('a\0'),('b\''),('c\"'),('d\\'),('\'b'),('\"c'),('\\d'),('a\0\0\0b'),('a\'\'\'\'b'),('a\"\"\"\"b'),('a\\\\\\\\b'),('\'\0\\\"'),('\'\''),('\"\"'),('\\\\'),('The\ZEnd'); +select * from t1 procedure analyse(); +Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype +test.t1.v " \\ 1 19 0 0 3.7619 NULL ENUM('"','""','"c','\'\0\\"','\'','\'\'','\'b','a\0\0\0b','a\0','a""""b','a\'\'\'\'b','abc','abc\'def\\hij"klm\0opq','a\\\\\\\\b','b\'','c"','d\\','The\ZEnd','\\','\\d','\\\\') NOT NULL +drop table t1; diff --git a/mysql-test/t/analyse.test b/mysql-test/t/analyse.test index 47f3473584b..34343c2b7bf 100644 --- a/mysql-test/t/analyse.test +++ b/mysql-test/t/analyse.test @@ -38,3 +38,7 @@ select * from t2; insert into t2 select * from t1 procedure analyse(); select * from t2; drop table t1,t2; +create table t1 (v varchar(128)); +insert into t1 values ('abc'),('abc\'def\\hij\"klm\0opq'),('\''),('\"'),('\\'),('a\0'),('b\''),('c\"'),('d\\'),('\'b'),('\"c'),('\\d'),('a\0\0\0b'),('a\'\'\'\'b'),('a\"\"\"\"b'),('a\\\\\\\\b'),('\'\0\\\"'),('\'\''),('\"\"'),('\\\\'),('The\ZEnd'); +select * from t1 procedure analyse(); +drop table t1; diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 1e0aebbc1ec..5265857f3b1 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -59,6 +59,7 @@ int compare_ulonglong2(void* cmp_arg __attribute__((unused)), return compare_ulonglong(s,t); } +static bool append_escaped(String *to_str, String *from_str); Procedure * proc_analyse_init(THD *thd, ORDER *param, select_result *result, @@ -890,7 +891,8 @@ int collect_string(String *element, else info->found = 1; info->str->append('\''); - info->str->append(*element); + if (append_escaped(info->str, element)) + return 1; info->str->append('\''); return 0; } // collect_string @@ -1025,3 +1027,58 @@ uint check_ulonglong(const char *str, uint length) while (*cmp && *cmp++ == *str++) ; return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger; } /* check_ulonlong */ + + + +/* + FUNCTION: append_escaped() + + DESCRIPTION + append_escaped() takes a String type variable, where it appends + escaped the second argument. Only characters that require escaping + will be escaped. + + ARGUMENTS + A pointer to a String variable, where results will be appended + A pointer to a String variable, which is appended to the result + String, escaping those characters that require it. + + RETURN VALUES + 0 Success + 1 Out of memory +*/ + +static bool append_escaped(String *to_str, String *from_str) +{ + char *from, *end, c; + + if (to_str->realloc(to_str->length() + from_str->length())) + return 1; + + from= (char*) from_str->ptr(); + end= from + from_str->length(); + for (; from < end; from++) + { + c= *from; + switch (c) { + case '\0': + c= '0'; + break; + case '\032': + c= 'Z'; + break; + case '\\': + case '\'': + break; + default: + goto normal_character; + } + if (to_str->append('\\')) + return 1; + + normal_character: + if (to_str->append(c)) + return 1; + } + return 0; +} |