Commit 3dec6c48 authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-15762 - VARCHAR(0) COMPRESSED crashes the server

Character set safe truncation is done when storing non-empty string in
VARCHAR(0) COMPRESSED column, so that string becomes empty. The code
didn't expect empty string after truncation.

Fixed by moving empty string check after truncation.
parent 43ab88f0
...@@ -1373,3 +1373,16 @@ bar ...@@ -1373,3 +1373,16 @@ bar
foo foo
SET SESSION optimizer_switch=DEFAULT; SET SESSION optimizer_switch=DEFAULT;
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-15762 - VARCHAR(0) COMPRESSED crashes the server
#
CREATE TABLE t1(a VARCHAR(0) COMPRESSED);
INSERT INTO t1 VALUES('a');
ERROR 22001: Data too long for column 'a' at row 1
INSERT INTO t1 VALUES(' ');
Warnings:
Note 1265 Data truncated for column 'a' at row 1
SELECT LENGTH(a) FROM t1;
LENGTH(a)
0
DROP TABLE t1;
...@@ -91,3 +91,14 @@ SET SESSION optimizer_switch = 'derived_merge=off'; ...@@ -91,3 +91,14 @@ SET SESSION optimizer_switch = 'derived_merge=off';
SELECT * FROM ( SELECT * FROM t1 ) AS sq ORDER BY b; SELECT * FROM ( SELECT * FROM t1 ) AS sq ORDER BY b;
SET SESSION optimizer_switch=DEFAULT; SET SESSION optimizer_switch=DEFAULT;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-15762 - VARCHAR(0) COMPRESSED crashes the server
--echo #
CREATE TABLE t1(a VARCHAR(0) COMPRESSED);
--error ER_DATA_TOO_LONG
INSERT INTO t1 VALUES('a');
INSERT INTO t1 VALUES(' ');
SELECT LENGTH(a) FROM t1;
DROP TABLE t1;
...@@ -7958,12 +7958,6 @@ int Field_longstr::compress(char *to, uint *to_length, ...@@ -7958,12 +7958,6 @@ int Field_longstr::compress(char *to, uint *to_length,
char *buf= 0; char *buf= 0;
int rc= 0; int rc= 0;
if (length == 0)
{
*to_length= 0;
return 0;
}
if (String::needs_conversion_on_storage(length, cs, field_charset) || if (String::needs_conversion_on_storage(length, cs, field_charset) ||
*to_length <= length) *to_length <= length)
{ {
...@@ -7981,10 +7975,11 @@ int Field_longstr::compress(char *to, uint *to_length, ...@@ -7981,10 +7975,11 @@ int Field_longstr::compress(char *to, uint *to_length,
(*to_length - 1) / field_charset->mbmaxlen); (*to_length - 1) / field_charset->mbmaxlen);
rc= check_conversion_status(&copier, end, cs, true); rc= check_conversion_status(&copier, end, cs, true);
from= buf; from= buf;
DBUG_ASSERT(length > 0);
} }
if (length >= thd->variables.column_compression_threshold && if (length == 0)
*to_length= 0;
else if (length >= thd->variables.column_compression_threshold &&
(*to_length= compression_method()->compress(thd, to, from, length))) (*to_length= compression_method()->compress(thd, to, from, length)))
status_var_increment(thd->status_var.column_compressions); status_var_increment(thd->status_var.column_compressions);
else else
......
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