Bug #25580 | The Parsing difers from a direct select to a create view | ||
---|---|---|---|
Submitted: | 12 Jan 2007 11:53 | Modified: | 8 Feb 2007 18:16 |
Reporter: | João Mota | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Views | Severity: | S2 (Serious) |
Version: | 5.0.34-BK, 5.0.27-community | OS: | Linux (Linux, WIN32) |
Assigned to: | Igor Babaev | CPU Architecture: | Any |
[12 Jan 2007 11:53]
João Mota
[12 Jan 2007 12:37]
Valeriy Kravchuk
Thank you for a bug report. Verified just as described with latest 5.0.34-BK on Linux: openxs@suse:~/dbs/5.0> bin/mysql -uroot test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.0.34-debug Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> select !0*5 as x; +---+ | x | +---+ | 5 | +---+ 1 row in set (0.00 sec) mysql> create table tt as select !0*5 as x; Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> show create table tt\G *************************** 1. row *************************** Table: tt Create Table: CREATE TABLE `tt` ( `x` int(3) NOT NULL default '0' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 1 row in set (0.00 sec) mysql> select * from tt; +---+ | x | +---+ | 5 | +---+ 1 row in set (0.01 sec) mysql> create view tv as select !0*5 as x; Query OK, 0 rows affected (0.00 sec) mysql> select * from tv; +---+ | x | +---+ | 1 | +---+ 1 row in set (0.00 sec) mysql> show create view tv\G *************************** 1. row *************************** View: tv Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `tv` AS select not((0 * 5)) AS `x` 1 row in set (0.00 sec) So, as we can see, view is created incorrectly.
[17 Jan 2007 22:39]
Igor Babaev
This problem can be demostrated without using views: mysql> SELECT (not(0) * 5) AS X FROM DUAL; +---+ | X | +---+ | 1 | +---+ 1 row in set (0.00 sec) mysql> EXPLAIN EXTENDED SELECT (not(0) * 5) AS X FROM DUAL; +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS; +-------+------+----------------------------+ | Level | Code | Message | +-------+------+----------------------------+ | Note | 1003 | select not((0 * 5)) AS `X` | +-------+------+----------------------------+ 1 row in set (0.00 sec) The problem is not observed for 4.1 though: mysql> SELECT VERSION(); +--------------+ | VERSION() | +--------------+ | 4.1.23-debug | +--------------+ 1 row in set (0.00 sec) mysql> EXPLAIN EXTENDED SELECT (not(0) * 5) AS X FROM DUAL; +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ 1 row in set, 1 warning (0.01 sec) mysql> SHOW WARNINGS; +-------+------+----------------------------+ | Level | Code | Message | +-------+------+----------------------------+ | Note | 1003 | select (not(0) * 5) AS `X` | +-------+------+----------------------------+ 1 row in set (0.00 sec)
[18 Jan 2007 2:08]
Igor Babaev
The following result can be explained by the fact that 'not' has a lower precedence than '*': mysql> SELECT (not(0) * 5) AS X FROM DUAL; +---+ | X | +---+ | 1 | +---+ If we make 'not' to have the highest precedence the result is different: mysql> SET sql_mode = HIGH_NOT_PRECEDENCE; Query OK, 0 rows affected (0.00 sec) mysql> SELECT (not(0) * 5) AS X FROM DUAL; +---+ | X | +---+ | 5 | +---+ 1 row in set (0.00 sec) mysql> EXPLAIN EXTENDED SELECT (not(0) * 5) AS X FROM DUAL; +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used | +----+-------------+-------+------+---------------+------+---------+------+------+----------------+ 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS; +-------+------+----------------------------+ | Level | Code | Message | +-------+------+----------------------------+ | Note | 1003 | select (not(0) * 5) AS `X` | +-------+------+----------------------------+ 1 row in set (0.00 sec) However '!' has a higher precedence than '*'. This explains why we have the correct result if we use '!' instead of 'not': mysql> SELECT (!(0) * 5) AS X FROM DUAL; +---+ | X | +---+ | 5 | +---+ 1 row in set (0.00 sec) The problem with views is that in internal stored representations of views any '!' operator is always replaced by a 'not' operator. This problem can be resolved by putting expressions under 'not' into parentheses.
[18 Jan 2007 4:11]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/18306 ChangeSet@1.2385, 2007-01-17 20:13:45-08:00, igor@olga.mysql.com +6 -0 Fixed bug #25580: incorrect stored representations of views in cases when they contain the '!' operator. Added an implementation for the method Item_func_not::print. The method encloses any NOT expression into extra parentheses to avoid incorrect stored representations of views that use the '!' operators. Without this change when a view was created that contained the expression !0*5 its stored representation contained not this expression but rather the expression not(0)*5 . The operator '!' is of a higher precedence than '*', while NOT is of a lower precedence than '*'. That's why the expression !0*5 is interpreted as not(0)*5, while the expression not(0)*5 is interpreted as not((0)*5) unless sql_mode is set to HIGH_NOT_PRECEDENCE. Now we translate !0*5 into (not(0))*5.
[28 Jan 2007 2:26]
Igor Babaev
The fix has been pushed into 5.0.36, 5.1.16-beta main trees.
[8 Feb 2007 18:16]
Paul DuBois
Noted in 5.0.36, 5.1.16 changelogs. View definitions that used the ! operator were treated as containing the NOT operator, which has a different precedence and can produce different results.