diff --git a/mysql-test/main/gis.result b/mysql-test/main/gis.result index 90c8f34e68d4f..9138141dae0bd 100644 --- a/mysql-test/main/gis.result +++ b/mysql-test/main/gis.result @@ -5602,3 +5602,14 @@ SELECT HEX(ST_GeometryN(0x000000000107000000010000000101000000, 1)); HEX(ST_GeometryN(0x000000000107000000010000000101000000, 1)) NULL # End of 10.6 tests +# +# MDEV-31182 ASAN errors in String_copier::well_formed_copy / calculate_cond_selectivity_for_table +# +CREATE TABLE t (a INT,b GEOMETRY NOT NULL,SPATIAL KEY idx (b)); +INSERT INTO t (a,b) VALUES (0,ST_GEOMFROMTEXT ('POINT(537323 35)')); +INSERT INTO t (a,b) VALUES (0,ST_GEOMFROMTEXT ('POINT(537323 35)')); +SET optimizer_trace='enabled=on'; +SELECT * FROM t WHERE MBRCONTAINS (ST_GEOMFROMTEXT ('LINESTRING (68466 35,139.68804 35.71411)'),b); +a b +DROP TABLE t; +# End of 10.11 tests diff --git a/mysql-test/main/gis.test b/mysql-test/main/gis.test index 24d5582ee3c8d..cd1b6257e9643 100644 --- a/mysql-test/main/gis.test +++ b/mysql-test/main/gis.test @@ -3574,3 +3574,16 @@ SELECT ST_GeomFromWKB(x'01070000000100000001070000000100000001070000000100000001 SELECT HEX(ST_GeometryN(0x000000000107000000010000000101000000, 1)); --echo # End of 10.6 tests + +--echo # +--echo # MDEV-31182 ASAN errors in String_copier::well_formed_copy / calculate_cond_selectivity_for_table +--echo # + +CREATE TABLE t (a INT,b GEOMETRY NOT NULL,SPATIAL KEY idx (b)); +INSERT INTO t (a,b) VALUES (0,ST_GEOMFROMTEXT ('POINT(537323 35)')); +INSERT INTO t (a,b) VALUES (0,ST_GEOMFROMTEXT ('POINT(537323 35)')); +SET optimizer_trace='enabled=on'; +SELECT * FROM t WHERE MBRCONTAINS (ST_GEOMFROMTEXT ('LINESTRING (68466 35,139.68804 35.71411)'),b); +DROP TABLE t; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/type_blob.result b/mysql-test/main/type_blob.result index fb6132e74b76e..c866bebbee30b 100644 --- a/mysql-test/main/type_blob.result +++ b/mysql-test/main/type_blob.result @@ -1609,3 +1609,19 @@ Warning 1292 Truncated incorrect DECIMAL value: '#' Warning 1292 Truncated incorrect DECIMAL value: '#' Warning 1292 Truncated incorrect DECIMAL value: '#' DROP TABLE t1; +# +# MDEV-31182 ASAN errors in String_copier::well_formed_copy / calculate_cond_selectivity_for_table +# +SET histogram_type = DOUBLE_PREC_HB; +CREATE TABLE t (a INT); +INSERT INTO t VALUES (1),(2); +ANALYZE TABLE t PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t analyze status Engine-independent statistics collected +test.t analyze status OK +ALTER TABLE t MODIFY a BLOB, ALGORITHM=COPY; +SELECT a FROM t WHERE a LIKE '1%'; +a +1 +DROP TABLE t; +# end of 10.11 tests diff --git a/mysql-test/main/type_blob.test b/mysql-test/main/type_blob.test index bb90e7434d6ba..b5c3d4ca6ee6b 100644 --- a/mysql-test/main/type_blob.test +++ b/mysql-test/main/type_blob.test @@ -853,3 +853,20 @@ INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2),(3),(4),(5); SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1); SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0; DROP TABLE t1; + +--echo # +--echo # MDEV-31182 ASAN errors in String_copier::well_formed_copy / calculate_cond_selectivity_for_table +--echo # + +SET histogram_type = DOUBLE_PREC_HB; + +CREATE TABLE t (a INT); +INSERT INTO t VALUES (1),(2); +ANALYZE TABLE t PERSISTENT FOR ALL; +ALTER TABLE t MODIFY a BLOB, ALGORITHM=COPY; + +SELECT a FROM t WHERE a LIKE '1%'; + +DROP TABLE t; + +--echo # end of 10.11 tests diff --git a/sql/field.h b/sql/field.h index c31b38d78e623..9b117e5ff0b4a 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1671,7 +1671,7 @@ class Field: public Value_source bool set_warning(Sql_condition::enum_warning_level, unsigned int code, int cuted_increment, ulong current_row=0) const; virtual void print_key_value(String *out, uint32 length); - void print_key_part_value(String *out, const uchar *key, uint32 length); + virtual void print_key_part_value(String *out, const uchar *key, uint32 length); void print_key_value_binary(String *out, const uchar* key, uint32 length); void raise_note_cannot_use_key_part(THD *thd, uint keynr, uint part, const LEX_CSTRING &op, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index b042445a7aa1a..02a1ae3d13d33 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3241,7 +3241,8 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param, store_length= key_part->length; if (field->real_maybe_null()) store_length+= HA_KEY_NULL_LENGTH; - if (field->real_type() == MYSQL_TYPE_VARCHAR) + if (field->real_type() == MYSQL_TYPE_VARCHAR || + field->real_type() == MYSQL_TYPE_BLOB) store_length+= HA_KEY_BLOB_LENGTH; if (max_key_len < store_length) max_key_len= store_length; @@ -8930,7 +8931,7 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param, if (length != key_part->length + maybe_null) { - /* key packed with length prefix */ + /* BLOB or VARCHAR: key packed with length prefix */ offset+= HA_KEY_BLOB_LENGTH; field_length= length - HA_KEY_BLOB_LENGTH; } @@ -16776,8 +16777,7 @@ void print_range(String *out, const KEY_PART_INFO *key_part, uint flag= range->range_flag; String key_name; key_name.set_charset(system_charset_info); - key_part_map keypart_map= range->start_key.keypart_map | - range->end_key.keypart_map; + key_part_map keypart_map= range->start_key.keypart_map; if (flag & GEOM_FLAG) { @@ -16793,6 +16793,7 @@ void print_range(String *out, const KEY_PART_INFO *key_part, return; } + keypart_map|= range->end_key.keypart_map; if (range->start_key.length) { print_key_value(out, key_part, range->start_key.key, diff --git a/sql/sql_type_geom.cc b/sql/sql_type_geom.cc index 6c46c80c05984..10ad5da527160 100644 --- a/sql/sql_type_geom.cc +++ b/sql/sql_type_geom.cc @@ -962,4 +962,21 @@ Binlog_type_info Field_geom::binlog_type_info() const field_charset(), type_handler_geom()->geometry_type()); } +void +Field_geom::print_key_part_value(String *out, const uchar* key, uint32) +{ + if (real_maybe_null() && *key) + { + /* + Byte 0 of key is the null-byte. If set, key is NULL. + Otherwise, print the key value starting immediately after the + null-byte + */ + out->append(NULL_clex_str); + return; + } + + out->append(STRING_WITH_LEN("unprintable_geometry_value")); +} + #endif // HAVE_SPATIAL diff --git a/sql/sql_type_geom.h b/sql/sql_type_geom.h index 14d3d062ef94a..7c7503a17bb38 100644 --- a/sql/sql_type_geom.h +++ b/sql/sql_type_geom.h @@ -419,6 +419,12 @@ class Field_geom :public Field_blob uint32 key_length() const override{ return packlength; } uint get_key_image(uchar *buff,uint length, const uchar *ptr_arg, imagetype type_arg) const override; + /* + GIS indexes do not store the whole data, so it makes no sense to + call Field_geom::set_key_image to restore the key to the column + */ + void set_key_image(const uchar *, uint) override + { DBUG_ASSERT(0); } /** Non-nullable GEOMETRY types cannot have defaults, @@ -429,11 +435,14 @@ class Field_geom :public Field_blob bool load_data_set_no_data(THD *thd, bool fixed_format) override; uint get_srid() const { return srid; } - void print_key_value(String *out, uint32 length) override - { - out->append(STRING_WITH_LEN("unprintable_geometry_value")); - } + /* + GIS indexes do not store the whole data, so it makes no sense to + call Field_geom::print_key_value to print the key value + */ + void print_key_value(String *, uint32) override + { DBUG_ASSERT(0); } Binlog_type_info binlog_type_info() const override; + void print_key_part_value(String *out, const uchar* key, uint32 length) override; }; #endif // HAVE_SPATIAL