summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <gshchepa/uchum@host.loc>2008-02-07 02:33:21 +0400
committerunknown <gshchepa/uchum@host.loc>2008-02-07 02:33:21 +0400
commit3891d43617e82dcb1a1ecdf876fa2094d672cb79 (patch)
treeff291bc2f29088223b8c4d9ca51b5f4dc2d2ec2e
parent1919d238e530d6c551ca60893f62e51dbad325cd (diff)
downloadmariadb-git-3891d43617e82dcb1a1ecdf876fa2094d672cb79.tar.gz
Fixed bug#30059.
Server handles truncation for assignment of too-long values into CHAR/VARCHAR/TEXT columns in a different ways when the truncated characters are spaces: 1. CHAR(N) columns silently ignore end-space truncation; 2. TEXT columns post a truncation warning/error in the non-strict/strict mode. 3. VARCHAR columns always post a truncation note in any mode. Space truncation processing has been synchronised over CHAR/VARCHAR/TEXT columns: current behavior of VARCHAR columns has been propagated as standard. Binary-encoded string/BLOB columns are not affected. mysql-test/r/heap.result: Updated test case for bug#30059. mysql-test/r/innodb.result: Updated test case for bug#30059. mysql-test/r/myisam.result: Updated test case for bug#30059. mysql-test/r/strict.result: Updated test case for bug#30059. mysql-test/r/type_binary.result: Updated test case for bug#30059. mysql-test/r/warnings.result: Added test case for bug#30059. mysql-test/t/warnings.test: Added test case for bug#30059. sql/field.cc: Fixed bug#30059. The report_data_too_long function was replaced with the Field_longstr::report_if_important_data method. The Field_string::store and the Field_blob::store methods was synchronized with the Field_varstring::store method. Changes: 1. to CHAR(N): posting of space truncation note has been added in both (strict and non-strict) modes; 2. to BLOBs: a check for space truncation has been added, a warning in the non-strict mode and an error message in the strict mode have been replaced with a truncation note. Similar parts of Field_string::store, Field_blob::store and Field_varstring::store have been moved to the Field_longstr::report_if_important_data method. sql/field.h: Fixed bug#30059. The Field_longstr::report_if_important_data method has been declared.
-rw-r--r--mysql-test/r/heap.result1
-rw-r--r--mysql-test/r/innodb.result1
-rw-r--r--mysql-test/r/myisam.result1
-rw-r--r--mysql-test/r/strict.result2
-rw-r--r--mysql-test/r/type_binary.result1
-rw-r--r--mysql-test/r/warnings.result38
-rw-r--r--mysql-test/t/warnings.test33
-rw-r--r--sql/field.cc74
-rw-r--r--sql/field.h2
9 files changed, 110 insertions, 43 deletions
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index 906c431b834..adfcc00174f 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -256,6 +256,7 @@ set @a=repeat(' ',20);
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
Warnings:
Note 1265 Data truncated for column 'v' at row 1
+Note 1265 Data truncated for column 'c' at row 1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+ *+*+ *
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 854712fdb1d..774e0bd167b 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1901,6 +1901,7 @@ set @a=repeat(' ',20);
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
Warnings:
Note 1265 Data truncated for column 'v' at row 1
+Note 1265 Data truncated for column 'c' at row 1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+ *+*+ *
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 33f64d600bb..24c1cecfb4f 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1104,6 +1104,7 @@ set @a=repeat(' ',20);
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
Warnings:
Note 1265 Data truncated for column 'v' at row 1
+Note 1265 Data truncated for column 'c' at row 1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+ *+*+ *
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 34869862a63..0a714635f70 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -934,6 +934,8 @@ NULL NULL
DROP TABLE t1;
CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(6));
INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello ');
+Warnings:
+Note 1265 Data truncated for column 'col1' at row 3
INSERT INTO t1 (col1) VALUES ('hellobob');
ERROR 22001: Data too long for column 'col1' at row 1
INSERT INTO t1 (col2) VALUES ('hellobob');
diff --git a/mysql-test/r/type_binary.result b/mysql-test/r/type_binary.result
index debf4ff8fb8..aaa46ab415e 100644
--- a/mysql-test/r/type_binary.result
+++ b/mysql-test/r/type_binary.result
@@ -125,6 +125,7 @@ create table t1 (c char(2), vc varchar(2));
insert into t1 values(0x4120, 0x4120);
insert into t1 values(0x412020, 0x412020);
Warnings:
+Note 1265 Data truncated for column 'c' at row 1
Note 1265 Data truncated for column 'vc' at row 1
drop table t1;
set @old_sql_mode= @@sql_mode, sql_mode= 'traditional';
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
index 9ce1f9c825d..e74f92205aa 100644
--- a/mysql-test/r/warnings.result
+++ b/mysql-test/r/warnings.result
@@ -298,4 +298,42 @@ DROP TABLE t3;
DROP PROCEDURE sp1;
DROP PROCEDURE sp2;
DROP PROCEDURE sp3;
+create table t1 (c_char char(255), c_varchar varchar(255), c_tinytext tinytext);
+create table t2 (c_tinyblob tinyblob);
+set @c = repeat(' ', 256);
+set @q = repeat('q', 256);
+set sql_mode = '';
+insert into t1 values(@c, @c, @c);
+Warnings:
+Note 1265 Data truncated for column 'c_char' at row 1
+Note 1265 Data truncated for column 'c_varchar' at row 1
+Note 1265 Data truncated for column 'c_tinytext' at row 1
+insert into t2 values(@c);
+Warnings:
+Warning 1265 Data truncated for column 'c_tinyblob' at row 1
+insert into t1 values(@q, @q, @q);
+Warnings:
+Warning 1265 Data truncated for column 'c_char' at row 1
+Warning 1265 Data truncated for column 'c_varchar' at row 1
+Warning 1265 Data truncated for column 'c_tinytext' at row 1
+insert into t2 values(@q);
+Warnings:
+Warning 1265 Data truncated for column 'c_tinyblob' at row 1
+set sql_mode = 'traditional';
+insert into t1 values(@c, @c, @c);
+Warnings:
+Note 1265 Data truncated for column 'c_char' at row 1
+Note 1265 Data truncated for column 'c_varchar' at row 1
+Note 1265 Data truncated for column 'c_tinytext' at row 1
+insert into t2 values(@c);
+ERROR 22001: Data too long for column 'c_tinyblob' at row 1
+insert into t1 values(@q, NULL, NULL);
+ERROR 22001: Data too long for column 'c_char' at row 1
+insert into t1 values(NULL, @q, NULL);
+ERROR 22001: Data too long for column 'c_varchar' at row 1
+insert into t1 values(NULL, NULL, @q);
+ERROR 22001: Data too long for column 'c_tinytext' at row 1
+insert into t2 values(@q);
+ERROR 22001: Data too long for column 'c_tinyblob' at row 1
+drop table t1, t2;
End of 5.0 tests
diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test
index 5e9d25aa09b..c42dd22024c 100644
--- a/mysql-test/t/warnings.test
+++ b/mysql-test/t/warnings.test
@@ -212,4 +212,37 @@ DROP PROCEDURE sp1;
DROP PROCEDURE sp2;
DROP PROCEDURE sp3;
+
+#
+# Bug#30059: End-space truncation warnings are inconsistent or incorrect
+#
+
+create table t1 (c_char char(255), c_varchar varchar(255), c_tinytext tinytext);
+create table t2 (c_tinyblob tinyblob); # not affected by bug, for regression testing
+set @c = repeat(' ', 256);
+set @q = repeat('q', 256);
+
+set sql_mode = '';
+
+insert into t1 values(@c, @c, @c);
+insert into t2 values(@c);
+insert into t1 values(@q, @q, @q);
+insert into t2 values(@q);
+
+set sql_mode = 'traditional';
+
+insert into t1 values(@c, @c, @c);
+--error 1406
+insert into t2 values(@c);
+--error 1406
+insert into t1 values(@q, NULL, NULL);
+--error 1406
+insert into t1 values(NULL, @q, NULL);
+--error 1406
+insert into t1 values(NULL, NULL, @q);
+--error 1406
+insert into t2 values(@q);
+
+drop table t1, t2;
+
--echo End of 5.0 tests
diff --git a/sql/field.cc b/sql/field.cc
index f1e2b6a4f27..3753318b8fa 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5861,26 +5861,41 @@ check_string_copy_error(Field_str *field,
}
-
/*
- Send a truncation warning or a truncation error
- after storing a too long character string info a field.
+ Check if we lost any important data and send a truncation error/warning
SYNOPSIS
- report_data_too_long()
- field - Field
+ Field_longstr::report_if_important_data()
+ ptr - Truncated rest of string
+ end - End of truncated string
- RETURN
- N/A
+ RETURN VALUES
+ 0 - None was truncated (or we don't count cut fields)
+ 2 - Some bytes was truncated
+
+ NOTE
+ Check if we lost any important data (anything in a binary string,
+ or any non-space in others). If only trailing spaces was lost,
+ send a truncation note, otherwise send a truncation error.
*/
-inline void
-report_data_too_long(Field_str *field)
+int
+Field_longstr::report_if_important_data(const char *ptr, const char *end)
{
- if (field->table->in_use->abort_on_warning)
- field->set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
- else
- field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ if ((ptr < end) && table->in_use->count_cuted_fields)
+ {
+ if (test_if_important_data(field_charset, ptr, end))
+ {
+ if (table->in_use->abort_on_warning)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
+ else
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ }
+ else /* If we lost only spaces then produce a NOTE, not a WARNING */
+ set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
+ return 2;
+ }
+ return 0;
}
@@ -5914,19 +5929,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length))
return 2;
- /*
- Check if we lost any important data (anything in a binary string,
- or any non-space in others).
- */
- if ((from_end_pos < from + length) && table->in_use->count_cuted_fields)
- {
- if (test_if_important_data(field_charset, from_end_pos, from + length))
- {
- report_data_too_long(this);
- return 2;
- }
- }
- return 0;
+ return report_if_important_data(from_end_pos, from + length);
}
@@ -6385,16 +6388,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length))
return 2;
- // Check if we lost something other than just trailing spaces
- if ((from_end_pos < from + length) && table->in_use->count_cuted_fields)
- {
- if (test_if_important_data(field_charset, from_end_pos, from + length))
- report_data_too_long(this);
- else /* If we lost only spaces then produce a NOTE, not a WARNING */
- set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
- return 2;
- }
- return 0;
+ return report_if_important_data(from_end_pos, from + length);
}
@@ -7030,13 +7024,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length))
return 2;
- if (from_end_pos < from + length)
- {
- report_data_too_long(this);
- return 2;
- }
-
- return 0;
+ return report_if_important_data(from_end_pos, from + length);
oom_error:
/* Fatal OOM error */
diff --git a/sql/field.h b/sql/field.h
index d681229a9fd..c82d65147ac 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -454,6 +454,8 @@ public:
class Field_longstr :public Field_str
{
+protected:
+ int report_if_important_data(const char *ptr, const char *end);
public:
Field_longstr(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,