Bug #1651 incorrect select results with spaces in a where clause
Submitted: 24 Oct 2003 16:33 Modified: 12 Dec 2003 4:21
Reporter: Christian Hammers (Silver Quality Contributor) (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: MyISAM storage engine Severity:S2 (Serious)
Version:4.0.15 OS:Linux (Debian GNU/Linux)
Assigned to: Michael Widenius CPU Architecture:Any

[24 Oct 2003 16:33] Christian Hammers
Description:
The following was filed as Debian bug report and is available here:
http://bugs.debian.org/211618

There is a different result when prepending a string with a space in a specific situation. See How to repeat below.

-christian-

How to repeat:
From: David Fries <dfries@mail.win.org>
See Debian bug report if the formatting gets screwed up.

Here is a bug I just stumbled accross.  This is based off a real
(world) example.  Create a table with two columns, one of them an
index, the other a text field.  Insert 'Chevy', 'Chevy ', and 'Ford'.
Start doing some select queries.  If you look for any one item you get
what you expect, if you search for both Chevy values you only get the
first one you listed.  If you search for all three or both Chevy's and
something not in the table you get both Chevy rows and the Ford if it was
listed.

For correct operation I expect when I put an 'or' in the where statement
it would find all rows that match at least one of the conditions, this
is not happening, one of the rows is getting lost, some of the time.

mysql> create table makes ( make_id integer primary key auto_increment, make_desc text not null, unique index make_desc_index
+(make_desc (20)));
Query OK, 0 rows affected (0.08 sec)

mysql> insert into makes (make_desc) values ('Chevy');
Query OK, 1 row affected (0.02 sec)

mysql> insert into makes (make_desc) values ('Chevy ');
Query OK, 1 row affected (0.00 sec)

mysql> select * from makes where make_desc='Chevy';
+---------+-----------+
| make_id | make_desc |
+---------+-----------+
|       1 | Chevy     |
+---------+-----------+
1 row in set (0.05 sec)

mysql> select * from makes where make_desc='Chevy ';
+---------+-----------+
| make_id | make_desc |
+---------+-----------+
|       2 | Chevy     |
+---------+-----------+
1 row in set (0.00 sec)

mysql> select * from makes where make_desc='Chevy ' or make_desc='Chevy';
+---------+-----------+
| make_id | make_desc |
+---------+-----------+
|       2 | Chevy     |
+---------+-----------+
1 row in set (0.00 sec)

mysql> select * from makes where make_desc='Chevy' or make_desc='Chevy ';
+---------+-----------+
| make_id | make_desc |
+---------+-----------+
|       1 | Chevy     |
+---------+-----------+
1 row in set (0.00 sec)

mysql> select * from makes where make_id='1' or make_id='2';
+---------+-----------+
| make_id | make_desc |
+---------+-----------+
|       1 | Chevy     |
|       2 | Chevy     |
+---------+-----------+
2 rows in set (0.04 sec)

mysql> insert into makes (make_desc) values('Ford');
Query OK, 1 row affected (0.00 sec)

mysql> select * from makes where make_desc='Chevy' or make_desc='Chevy ' or make_desc='Ford';
+---------+-----------+
| make_id | make_desc |
+---------+-----------+
|       1 | Chevy     |
|       2 | Chevy     |
|       3 | Ford      |
+---------+-----------+
3 rows in set (0.02 sec)

---------------- the relevant two queries -----------------
------------- take special note on the spaces before(!) and after the words ---

mysql> select * from makes where make_desc='Chevy' or make_desc='Chevy ';
+---------+-----------+
| make_id | make_desc |
+---------+-----------+
|       1 | Chevy     |
+---------+-----------+
1 row in set (0.00 sec)

mysql> select * from makes where make_desc='Chevy' or make_desc='Chevy ' or make_desc=' Chevy';
+---------+-----------+
| make_id | make_desc |
+---------+-----------+
|       1 | Chevy     |
|       2 | Chevy     |
+---------+-----------+
2 rows in set (0.00 sec)

Suggested fix:
none
[27 Oct 2003 6:27] Indrek Siitan
One more test, just in case:

mysql> select * from makes where make_desc in ('Chevy ','Chevy');
+---------+-----------+
| make_id | make_desc |
+---------+-----------+
|       1 | Chevy     |
|       2 | Chevy     |
+---------+-----------+
2 rows in set (0.00 sec)
[12 Dec 2003 4:21] Michael Widenius
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

I have now fixed several small problems with TEXT and end space handling in the code.  We didn't for example take into account that for a unique TEXT field there may be many matching strings.

The fix will be in 4.0.17