Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 93 additions & 1 deletion mysql-test/main/vector2.result
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ drop table t;
# MDEV-35141 Server crashes in Field_vector::report_wrong_value upon statistic collection
#
create table t1 (v vector(64) not null);
insert into t1 select vec_fromtext(concat('[',group_concat(1),']')) from seq_1_to_64;
insert into t1 select vec_fromtext(cast(concat('[',group_concat(1),']') as char(130))) from seq_1_to_64;
analyze table t1 persistent for all;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
Expand Down Expand Up @@ -565,4 +565,96 @@ tmp CREATE TABLE `tmp` (
c
drop table tmp, t1, t2;
set sql_mode=@old_sql_mode;
#
# MDEV-40486 ER_TOO_BIG_FIELDLENGTH or assertion failure upon creating vector from blob
#
## Original testcase
CREATE TABLE t (a TEXT) AS SELECT '[1]' AS a;
CREATE TABLE tt AS SELECT VEC_FROMTEXT(a) AS f FROM t;
ERROR 42000: Column length too big for column 'f' (max = 16383); use BLOB or TEXT instead
DROP TABLE t;
## Another case, which would have failed with ERROR 1292
## without the fix
CREATE TABLE t SELECT VEC_FROMTEXT('[1]');
DROP TABLE t;
## Conversion from max varchar length
CREATE TABLE t (a VARCHAR(16383)) AS
SELECT concat('[1', repeat(',1', 8190), ']') AS a;
CREATE TABLE tt AS SELECT VEC_FROMTEXT(a) AS f FROM t;
DROP TABLE t,tt;
## Conversion to max vector dimension
CREATE TABLE tt AS
SELECT VEC_FROMTEXT(concat('[1', repeat(',1', 16382), ']')) AS f;
DROP TABLE tt;
CREATE TABLE tt AS
SELECT VEC_FROMTEXT(concat('[1', repeat(',1', 16383), ']')) AS f;
ERROR 42000: Column length too big for column 'f' (max = 16383); use BLOB or TEXT instead
## Zero length: no underflow and not allowed for table creation
SELECT VEC_FROMTEXT('[]') as f;
f

CREATE TABLE t1 SELECT VEC_FROMTEXT('[]');
ERROR 22007: Incorrect vector value: '' for column `test`.`t1`.`VEC_FROMTEXT('[]')` at row 1
SELECT VEC_FROMTEXT('') AS f;
ERROR HY000: Incorrect arguments to VEC_FromText
CREATE TABLE tt AS SELECT VEC_FROMTEXT('') AS f;
ERROR HY000: Incorrect arguments to VEC_FromText
CREATE TABLE t1 (a CHAR(1));
CREATE TABLE t2 AS SELECT VEC_FROMTEXT(a) AS f FROM t1;
ERROR HY000: Incorrect arguments to VEC_FromText
DROP TABLE t1;
CREATE TABLE t3 (f VECTOR(0));
ERROR 42000: Incorrect column specifier for column 'f'
## Fails because concat('[',group_concat(1),']') is mediumblob
create view v1 as select vec_fromtext(concat('[',group_concat(1),']')) from seq_1_to_64;
ERROR 42000: Column length too big for column 'vec_fromtext(concat('[',group_concat(1),']'))' (max = 16383); use BLOB or TEXT instead
## NULLs
select vec_fromtext(NULL);
ERROR HY000: Incorrect arguments to VEC_FromText
select vec_fromtext(NULL + NULL);
vec_fromtext(NULL + NULL)
NULL
create table t1 select vec_fromtext(NULL) as c;
ERROR HY000: Incorrect arguments to VEC_FromText
create table t1 select vec_fromtext(NULL + NULL) as c;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` vector(8) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
drop table t1;
create table t1 select vec_fromtext(c) from (select '[1,2]' as c) d;
DROP TABLE t1;
create table t1 select vec_fromtext(c) from (select '' as c) d;
ERROR HY000: Incorrect arguments to VEC_FromText
create table t1 select vec_fromtext(c) from (select NULL as c) d;
ERROR HY000: Incorrect arguments to VEC_FromText
create table t2 (c varchar(5));
insert into t2 values (NULL);
create table t1 select vec_fromtext(c) from t2;
drop table t1, t2;
## Prepared statements with placeholders
prepare p1 from 'select vec_fromtext(?)';
execute p1 using '[1,2]';
execute p1 using NULL;
ERROR HY000: Incorrect arguments to VEC_FromText
execute p1 using '[]';
vec_fromtext(?)

deallocate prepare p1;
prepare p1 from 'create table t1 select vec_fromtext(?)';
execute p1 using '[1,2]';
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`vec_fromtext(?)` vector(2) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
DROP TABLE t1;
execute p1 using NULL;
ERROR HY000: Incorrect arguments to VEC_FromText
execute p1 using '[]';
ERROR 22007: Incorrect vector value: '' for column `test`.`t1`.`vec_fromtext(?)` at row 1
execute p1 using '';
ERROR HY000: Incorrect arguments to VEC_FromText
deallocate prepare p1;
# End of 11.8 tests
97 changes: 96 additions & 1 deletion mysql-test/main/vector2.test
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ drop table t;
--echo # MDEV-35141 Server crashes in Field_vector::report_wrong_value upon statistic collection
--echo #
create table t1 (v vector(64) not null);
insert into t1 select vec_fromtext(concat('[',group_concat(1),']')) from seq_1_to_64;
insert into t1 select vec_fromtext(cast(concat('[',group_concat(1),']') as char(130))) from seq_1_to_64;
analyze table t1 persistent for all;
drop table t1;

Expand Down Expand Up @@ -447,4 +447,99 @@ drop table tmp, t1, t2;

set sql_mode=@old_sql_mode;

--echo #
--echo # MDEV-40486 ER_TOO_BIG_FIELDLENGTH or assertion failure upon creating vector from blob
--echo #

--echo ## Original testcase
CREATE TABLE t (a TEXT) AS SELECT '[1]' AS a;
--error ER_TOO_BIG_FIELDLENGTH
CREATE TABLE tt AS SELECT VEC_FROMTEXT(a) AS f FROM t;
DROP TABLE t;

--echo ## Another case, which would have failed with ERROR 1292
--echo ## without the fix
CREATE TABLE t SELECT VEC_FROMTEXT('[1]');
DROP TABLE t;

--echo ## Conversion from max varchar length
CREATE TABLE t (a VARCHAR(16383)) AS
SELECT concat('[1', repeat(',1', 8190), ']') AS a;
CREATE TABLE tt AS SELECT VEC_FROMTEXT(a) AS f FROM t;
DROP TABLE t,tt;

--echo ## Conversion to max vector dimension
CREATE TABLE tt AS
SELECT VEC_FROMTEXT(concat('[1', repeat(',1', 16382), ']')) AS f;
DROP TABLE tt;

--error ER_TOO_BIG_FIELDLENGTH
CREATE TABLE tt AS
SELECT VEC_FROMTEXT(concat('[1', repeat(',1', 16383), ']')) AS f;

--echo ## Zero length: no underflow and not allowed for table creation
SELECT VEC_FROMTEXT('[]') as f;
--error ER_TRUNCATED_WRONG_VALUE
CREATE TABLE t1 SELECT VEC_FROMTEXT('[]');
--error ER_WRONG_ARGUMENTS
SELECT VEC_FROMTEXT('') AS f;
--error ER_WRONG_ARGUMENTS
CREATE TABLE tt AS SELECT VEC_FROMTEXT('') AS f;

CREATE TABLE t1 (a CHAR(1));
--error ER_WRONG_ARGUMENTS
CREATE TABLE t2 AS SELECT VEC_FROMTEXT(a) AS f FROM t1;
DROP TABLE t1;

--error ER_WRONG_FIELD_SPEC
CREATE TABLE t3 (f VECTOR(0));

--echo ## Fails because concat('[',group_concat(1),']') is mediumblob
--error ER_TOO_BIG_FIELDLENGTH
create view v1 as select vec_fromtext(concat('[',group_concat(1),']')) from seq_1_to_64;

--echo ## NULLs
--error ER_WRONG_ARGUMENTS
select vec_fromtext(NULL);
select vec_fromtext(NULL + NULL);
--error ER_WRONG_ARGUMENTS
create table t1 select vec_fromtext(NULL) as c;
create table t1 select vec_fromtext(NULL + NULL) as c;
show create table t1;
drop table t1;

create table t1 select vec_fromtext(c) from (select '[1,2]' as c) d;
DROP TABLE t1;
--error ER_WRONG_ARGUMENTS
create table t1 select vec_fromtext(c) from (select '' as c) d;
--error ER_WRONG_ARGUMENTS
create table t1 select vec_fromtext(c) from (select NULL as c) d;

create table t2 (c varchar(5));
insert into t2 values (NULL);
create table t1 select vec_fromtext(c) from t2;
drop table t1, t2;

--echo ## Prepared statements with placeholders
prepare p1 from 'select vec_fromtext(?)';
--disable_result_log
execute p1 using '[1,2]';
--enable_result_log
--error ER_WRONG_ARGUMENTS
execute p1 using NULL;
execute p1 using '[]';
deallocate prepare p1;

prepare p1 from 'create table t1 select vec_fromtext(?)';
execute p1 using '[1,2]';
show create table t1;
DROP TABLE t1;
--error ER_WRONG_ARGUMENTS
execute p1 using NULL;
--error ER_TRUNCATED_WRONG_VALUE
execute p1 using '[]';
--error ER_WRONG_ARGUMENTS
execute p1 using '';
deallocate prepare p1;

--echo # End of 11.8 tests
3 changes: 1 addition & 2 deletions mysql-test/main/vector_funcs.result
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ drop table t1;
# MDEV-35212 Server crashes in Item_func_vec_fromtext::val_str upon query from empty table
#
select vec_fromtext(NULL);
vec_fromtext(NULL)
NULL
ERROR HY000: Incorrect arguments to VEC_FromText
#
# MDEV-35210 Vector type cannot store values which VEC_FromText produces and VEC_ToText accepts
#
Expand Down
1 change: 1 addition & 0 deletions mysql-test/main/vector_funcs.test
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ drop table t1;
--echo #
--echo # MDEV-35212 Server crashes in Item_func_vec_fromtext::val_str upon query from empty table
--echo #
--error ER_WRONG_ARGUMENTS
select vec_fromtext(NULL);

--echo #
Expand Down
19 changes: 16 additions & 3 deletions sql/item_vectorfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,25 @@ Item_func_vec_fromtext::Item_func_vec_fromtext(THD *thd, Item *a)

bool Item_func_vec_fromtext::fix_length_and_dec(THD *thd)
{
uint maxlen= args[0]->max_char_length();
decimals= 0;
/* Worst case scenario, for a valid input we have a string of the form:
[1,2,3,4,5,...] single digit numbers.
This means we can have (max_length - 1) / 2 floats.
Each float takes 4 bytes, so we do (max_length - 1) * 2. */
fix_length_and_charset((args[0]->max_length - 1) * 2, &my_charset_bin);
This means we can have (maxlen - 1) / 2 floats.
Each float takes 4 bytes, so we do (maxlen - 1) * 2. */
fix_length_and_charset(maxlen ? (maxlen - 1) * 2 : 0, &my_charset_bin);
/* Zero-length vectors are not allowed to be table fields */
if (max_length == 0 && args[0]->type() != PARAM_ITEM)
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), func_name());
return true;
}
if (max_length > MAX_FIELD_VARCHARLENGTH)
{
my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), name.str,
static_cast<ulong>(MAX_FIELD_VARCHARLENGTH / sizeof(float)));
return true;
}
set_maybe_null();
return false;
}
Expand Down