Skip to content

Commit

Permalink
MDEV-32645 CAST(AS UNSIGNED) fails with --view-protocol
Browse files Browse the repository at this point in the history
Item_float::neg() did not preserve the "presentation" from "this".
So
  CAST(-1e0 AS UNSIGNED)  -- cast from double to unsigned
changes its meaning to:
  CAST(-1 AS UNSIGNED)  -- cast signed to undigned

Fixing Item_float::neg() to construct the new value for
Item_float::presentation as follows:
- if the old value starts with minus, then the minus is truncated:
  '-2e0' -> '2e0'
- otherwise, minus sign followed by its old value:
  '1e0'  -> '-1e0'
  • Loading branch information
abarkov committed Jan 9, 2024
1 parent ca276a0 commit 9322ef0
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 4 deletions.
3 changes: 0 additions & 3 deletions mysql-test/main/cast.test
Original file line number Diff line number Diff line change
Expand Up @@ -768,14 +768,11 @@ INSERT INTO t1 VALUES (-1.0);
SELECT * FROM t1;
DROP TABLE t1;

#enable after MDEV-32645 is fixed
--disable_view_protocol
SELECT CAST(-1e0 AS UNSIGNED);
CREATE TABLE t1 (a BIGINT UNSIGNED);
INSERT INTO t1 VALUES (-1e0);
SELECT * FROM t1;
DROP TABLE t1;
--enable_view_protocol

SELECT CAST(-1e308 AS UNSIGNED);
CREATE TABLE t1 (a BIGINT UNSIGNED);
Expand Down
37 changes: 37 additions & 0 deletions mysql-test/main/type_float.result
Original file line number Diff line number Diff line change
Expand Up @@ -1167,5 +1167,42 @@ d 50
fdbl 123.456.789,12345678000000000000000000000000000000
fdec 123.456.789,12345678900000000000000000000000000000
#
# MDEV-32645 CAST(AS UNSIGNED) fails with --view-protocol
#
SELECT
CAST(-1e0 AS UNSIGNED),
CAST(--2e0 AS UNSIGNED),
CAST(---3e0 AS UNSIGNED),
CAST(----4e0 AS UNSIGNED);
CAST(-1e0 AS UNSIGNED) CAST(--2e0 AS UNSIGNED) CAST(---3e0 AS UNSIGNED) CAST(----4e0 AS UNSIGNED)
0 2 0 4
Warnings:
Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated
Note 1916 Got overflow when converting '-3' to UNSIGNED BIGINT. Value truncated
EXPLAIN EXTENDED SELECT
CAST(-1e0 AS UNSIGNED),
CAST(--2e0 AS UNSIGNED),
CAST(---3e0 AS UNSIGNED),
CAST(----4e0 AS UNSIGNED);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select cast(-1e0 as unsigned) AS `CAST(-1e0 AS UNSIGNED)`,cast(2e0 as unsigned) AS `CAST(--2e0 AS UNSIGNED)`,cast(-3e0 as unsigned) AS `CAST(---3e0 AS UNSIGNED)`,cast(4e0 as unsigned) AS `CAST(----4e0 AS UNSIGNED)`
CREATE VIEW v1 AS SELECT
CAST(-1e0 AS UNSIGNED),
CAST(--2e0 AS UNSIGNED),
CAST(---3e0 AS UNSIGNED),
CAST(----4e0 AS UNSIGNED);
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(-1e0 as unsigned) AS `CAST(-1e0 AS UNSIGNED)`,cast(2e0 as unsigned) AS `CAST(--2e0 AS UNSIGNED)`,cast(-3e0 as unsigned) AS `CAST(---3e0 AS UNSIGNED)`,cast(4e0 as unsigned) AS `CAST(----4e0 AS UNSIGNED)` latin1 latin1_swedish_ci
SELECT * FROM v1;
CAST(-1e0 AS UNSIGNED) CAST(--2e0 AS UNSIGNED) CAST(---3e0 AS UNSIGNED) CAST(----4e0 AS UNSIGNED)
0 2 0 4
Warnings:
Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated
Note 1916 Got overflow when converting '-3' to UNSIGNED BIGINT. Value truncated
DROP VIEW v1;
#
# End of 10.4 tests
#
26 changes: 26 additions & 0 deletions mysql-test/main/type_float.test
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,32 @@ $$
DELIMITER ;$$
--horizontal_results

--echo #
--echo # MDEV-32645 CAST(AS UNSIGNED) fails with --view-protocol
--echo #

SELECT
CAST(-1e0 AS UNSIGNED),
CAST(--2e0 AS UNSIGNED),
CAST(---3e0 AS UNSIGNED),
CAST(----4e0 AS UNSIGNED);

EXPLAIN EXTENDED SELECT
CAST(-1e0 AS UNSIGNED),
CAST(--2e0 AS UNSIGNED),
CAST(---3e0 AS UNSIGNED),
CAST(----4e0 AS UNSIGNED);

CREATE VIEW v1 AS SELECT
CAST(-1e0 AS UNSIGNED),
CAST(--2e0 AS UNSIGNED),
CAST(---3e0 AS UNSIGNED),
CAST(----4e0 AS UNSIGNED);

SHOW CREATE VIEW v1;
SELECT * FROM v1;
DROP VIEW v1;

--echo #
--echo # End of 10.4 tests
--echo #
20 changes: 19 additions & 1 deletion sql/item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6896,7 +6896,25 @@ Item *Item_float::neg(THD *thd)
else if (value < 0 && max_length)
max_length--;
value= -value;
presentation= 0;
if (presentation)
{
if (*presentation == '-')
{
// Strip double minus: -(-1) -> '1' instead of '--1'
presentation++;
}
else
{
size_t presentation_length= strlen(presentation);
if (char *tmp= (char*) thd->alloc(presentation_length + 2))
{
tmp[0]= '-';
// Copy with the trailing '\0'
memcpy(tmp + 1, presentation, presentation_length + 1);
presentation= tmp;
}
}
}
name= null_clex_str;
return this;
}
Expand Down

0 comments on commit 9322ef0

Please sign in to comment.