This commit is contained in:
Georgi Kodinov 2009-11-10 10:58:43 +02:00
commit 0daad80228
3 changed files with 107 additions and 50 deletions

View File

@ -1444,6 +1444,27 @@ FROM t3;
2 2
NULL NULL
DROP TABLE t1, t2, t3; DROP TABLE t1, t2, t3;
#
# Bug #42760: Select doesn't return desired results when we have null
# values
#
CREATE TABLE t1 (
a INT,
c INT,
UNIQUE KEY a_c (a,c),
KEY (a));
INSERT INTO t1 VALUES (1, 10), (2, NULL);
# Must use ref-or-null on the a_c index
EXPLAIN
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref_or_null a_c,a a_c 10 const,const 1 Using where
# Must return 1 row
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
col
1
DROP TABLE t1;
End of 5.0 tests
CREATE TABLE t2 (a varchar(32), b int(11), c float, d double, CREATE TABLE t2 (a varchar(32), b int(11), c float, d double,
UNIQUE KEY a (a,b,c), KEY b (b), KEY c (c)); UNIQUE KEY a (a,b,c), KEY b (b), KEY c (c));
CREATE TABLE t1 (a varchar(32), b char(3), UNIQUE KEY a (a,b), KEY b (b)); CREATE TABLE t1 (a varchar(32), b char(3), UNIQUE KEY a (a,b), KEY b (b));

View File

@ -867,6 +867,31 @@ SELECT
DROP TABLE t1, t2, t3; DROP TABLE t1, t2, t3;
--echo #
--echo # Bug #42760: Select doesn't return desired results when we have null
--echo # values
--echo #
CREATE TABLE t1 (
a INT,
c INT,
UNIQUE KEY a_c (a,c),
KEY (a));
INSERT INTO t1 VALUES (1, 10), (2, NULL);
--echo # Must use ref-or-null on the a_c index
EXPLAIN
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
--echo # Must return 1 row
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
DROP TABLE t1;
--echo End of 5.0 tests
# #
# Bug #35206: select query result different if the key is indexed or not # Bug #35206: select query result different if the key is indexed or not
# #

View File

@ -6487,6 +6487,56 @@ void rr_unlock_row(st_join_table *tab)
/**
Pick the appropriate access method functions
Sets the functions for the selected table access method
@param tab Table reference to put access method
*/
static void
pick_table_access_method(JOIN_TAB *tab)
{
switch (tab->type)
{
case JT_REF:
tab->read_first_record= join_read_always_key;
tab->read_record.read_record= join_read_next_same;
break;
case JT_REF_OR_NULL:
tab->read_first_record= join_read_always_key_or_null;
tab->read_record.read_record= join_read_next_same_or_null;
break;
case JT_CONST:
tab->read_first_record= join_read_const;
tab->read_record.read_record= join_no_more_records;
break;
case JT_EQ_REF:
tab->read_first_record= join_read_key;
tab->read_record.read_record= join_no_more_records;
break;
case JT_FT:
tab->read_first_record= join_ft_read_first;
tab->read_record.read_record= join_ft_read_next;
break;
case JT_SYSTEM:
tab->read_first_record= join_read_system;
tab->read_record.read_record= join_no_more_records;
break;
/* keep gcc happy */
default:
break;
}
}
static void static void
make_join_readinfo(JOIN *join, ulonglong options) make_join_readinfo(JOIN *join, ulonglong options)
{ {
@ -6521,45 +6571,15 @@ make_join_readinfo(JOIN *join, ulonglong options)
tab->sorted= sorted; tab->sorted= sorted;
sorted= 0; // only first must be sorted sorted= 0; // only first must be sorted
table->status=STATUS_NO_RECORD;
pick_table_access_method (tab);
switch (tab->type) { switch (tab->type) {
case JT_SYSTEM: // Only happens with left join
table->status=STATUS_NO_RECORD;
tab->read_first_record= join_read_system;
tab->read_record.read_record= join_no_more_records;
break;
case JT_CONST: // Only happens with left join
table->status=STATUS_NO_RECORD;
tab->read_first_record= join_read_const;
tab->read_record.read_record= join_no_more_records;
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
break;
case JT_EQ_REF: case JT_EQ_REF:
table->status=STATUS_NO_RECORD;
if (tab->select)
{
delete tab->select->quick;
tab->select->quick=0;
}
delete tab->quick;
tab->quick=0;
tab->read_first_record= join_read_key;
tab->read_record.unlock_row= join_read_key_unlock_row; tab->read_record.unlock_row= join_read_key_unlock_row;
tab->read_record.read_record= join_no_more_records; /* fall through */
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
break;
case JT_REF_OR_NULL: case JT_REF_OR_NULL:
case JT_REF: case JT_REF:
table->status=STATUS_NO_RECORD;
if (tab->select) if (tab->select)
{ {
delete tab->select->quick; delete tab->select->quick;
@ -6567,34 +6587,20 @@ make_join_readinfo(JOIN *join, ulonglong options)
} }
delete tab->quick; delete tab->quick;
tab->quick=0; tab->quick=0;
/* fall through */
case JT_CONST: // Only happens with left join
if (table->covering_keys.is_set(tab->ref.key) && if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread) !table->no_keyread)
{ {
table->key_read=1; table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD); table->file->extra(HA_EXTRA_KEYREAD);
} }
if (tab->type == JT_REF)
{
tab->read_first_record= join_read_always_key;
tab->read_record.read_record= join_read_next_same;
}
else
{
tab->read_first_record= join_read_always_key_or_null;
tab->read_record.read_record= join_read_next_same_or_null;
}
break;
case JT_FT:
table->status=STATUS_NO_RECORD;
tab->read_first_record= join_ft_read_first;
tab->read_record.read_record= join_ft_read_next;
break; break;
case JT_ALL: case JT_ALL:
/* /*
If previous table use cache If previous table use cache
If the incoming data set is already sorted don't use cache. If the incoming data set is already sorted don't use cache.
*/ */
table->status=STATUS_NO_RECORD;
if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) && if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
tab->use_quick != 2 && !tab->first_inner && !ordered_set) tab->use_quick != 2 && !tab->first_inner && !ordered_set)
{ {
@ -6674,6 +6680,9 @@ make_join_readinfo(JOIN *join, ulonglong options)
} }
} }
break; break;
case JT_FT:
case JT_SYSTEM:
break;
default: default:
DBUG_PRINT("error",("Table type %d found",tab->type)); /* purecov: deadcode */ DBUG_PRINT("error",("Table type %d found",tab->type)); /* purecov: deadcode */
break; /* purecov: deadcode */ break; /* purecov: deadcode */
@ -13195,6 +13204,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if (create_ref_for_key(tab->join, tab, keyuse, if (create_ref_for_key(tab->join, tab, keyuse,
tab->join->const_table_map)) tab->join->const_table_map))
DBUG_RETURN(0); DBUG_RETURN(0);
pick_table_access_method(tab);
} }
else else
{ {