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
29 changes: 29 additions & 0 deletions mysql-test/main/vector2.result
Original file line number Diff line number Diff line change
Expand Up @@ -565,4 +565,33 @@ 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;
## 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
## Note that CREATE ... SELECT raises warning as error
SELECT VEC_FROMTEXT('') AS f;
f
NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'VEC_FromText'
CREATE TABLE tt AS SELECT VEC_FROMTEXT('') AS f;
ERROR HY000: Unexpected end of JSON text in argument 1 to function 'VEC_FromText'
# End of 11.8 tests
31 changes: 31 additions & 0 deletions mysql-test/main/vector2.test
Original file line number Diff line number Diff line change
Expand Up @@ -447,4 +447,35 @@ 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 ## 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
--echo ## Note that CREATE ... SELECT raises warning as error
SELECT VEC_FROMTEXT('') AS f;
--error ER_JSON_EOS
CREATE TABLE tt AS SELECT VEC_FROMTEXT('') AS f;

--echo # End of 11.8 tests
7 changes: 4 additions & 3 deletions sql/item_vectorfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,13 @@ 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);
set_maybe_null();
return false;
}
Expand Down
10 changes: 9 additions & 1 deletion sql/item_vectorfunc.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,15 @@ class Item_func_vec_fromtext: public Item_str_func
const Type_handler *type_handler() const override
{ return &type_handler_vector; }
Field *create_field_for_create_select(MEM_ROOT *root, TABLE *table) override
{ return create_table_field_from_handler(root, table); }
{
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 NULL;
}
return create_table_field_from_handler(root, table);
}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= { STRING_WITH_LEN("VEC_FromText") };
Expand Down