Commit graph

41 commits

Author SHA1 Message Date
Jorgen Loland
7f9a504745 Bug#48177 - SELECTs with NOT IN subqueries containing NULL
values return too many records

WHERE clauses with "outer_value_list NOT IN subselect" were
handled incorrectly if the outer value list contained multiple 
items where at least one of these could be NULL. The first 
outer record with NULL value was handled correctly, but if a 
second record with NULL value existed, the optimizer would 
choose to reuse the result it got on the last execution of the 
subselect. This is incorrect if the outer value list has 
multiple items.
     
The fix is to make Item_in_optimizer::val_int (in 
item_cmpfunc.cc) reuse the result of the latest execution
for NULL values only if all values in the outer_value_list 
are NULL.
2009-11-03 13:48:59 +01:00
Gleb Shchepa
0fc6777ce7 auto-upmerge 5.0-bugteam --> 5.1-bugteam (bug 37362) 2009-05-01 00:27:10 +05:00
Gleb Shchepa
480fac6107 Bug #37362: Crash in do_field_eq
EXPLAIN EXTENDED of nested query containing a error:

   1054 Unknown column '...' in 'field list'

may cause a server crash.


Parse error like described above forces a call to
JOIN::destroy() on malformed subquery.
That JOIN::destroy function closes and frees temporary
tables. However, temporary fields of these tables
may be listed in st_select_lex::group_list of outer
query, and that st_select_lex may not cleanup them
properly. So, after the JOIN::destroy call that
st_select_lex::group_list may have Item_field
objects with dangling pointers to freed temporary
table Field objects. That caused a crash.
2009-05-01 00:20:37 +05:00
Gleb Shchepa
64c0951fde automerge 5.0-bugteam --> 5.1-bugteam (bug 39069) 2009-01-28 22:48:41 +04:00
Gleb Shchepa
b41c1a45f1 Bug #39069: <row constructor> IN <table-subquery> seriously
messed up

"ROW(...) IN (SELECT ... FROM DUAL)" always returned TRUE.

Item_in_subselect::row_value_transformer rewrites "ROW(...)
IN SELECT" conditions into the "EXISTS (SELECT ... HAVING ...)"
form.
For a subquery from the DUAL pseudotable resulting HAVING
condition is an expression on constant values, so further
transformation with optimize_cond() eliminates this HAVING
condition and resets JOIN::having to NULL.
Then JOIN::exec treated that NULL as an always-true-HAVING
and that caused a bug.

To distinguish an optimized out "HAVING TRUE" clause from
"HAVING FALSE" we already have the JOIN::having_value flag.
However, JOIN::exec() ignored JOIN::having_value as described
above as if it always set to COND_TRUE.

The JOIN::exec method has been modified to take into account
the value of the JOIN::having_value field.
2009-01-28 22:46:45 +04:00
Gleb Shchepa
a99bc69558 manual merge 5.0-bugteam --> 5.1-bugteam 2008-10-10 16:48:47 +05:00
Gleb Shchepa
27f4c34beb Bug #37894: Assertion in init_read_record_seq in handler.h line 1444
Select with a "NULL NOT IN" condition containing complex
subselect from the same table as in the outer select failed
with an assertion.


The failure was caused by a concatenation of circumstances:
1) an inner select was optimized by make_join_statistics to use
   the QUICK_RANGE_SELECT access method (that implies an index
   scan of the table);
2) a subselect was independent (constant) from the outer select;
3) a condition was pushed down into inner select.

During the evaluation of a constant IN expression an optimizer
temporary changed the access method from index scan to table
scan, but an engine handler was already initialized for index
access by make_join_statistics. That caused an assertion.


Unnecessary index initialization has been removed from
the QUICK_RANGE_SELECT::init method (QUICK_RANGE_SELECT::reset
reinvokes this initialization).
2008-10-10 15:27:58 +05:00
Sergey Petrunia
869c86b318 BUG#36135: void Diagnostics_area::set_eof_status(THD*): Assertion `! is_set()' failed.
- Before sending EOF, check if we've already sent an error.
2008-08-19 17:15:29 +04:00
gshchepa/uchum@host.loc
cdd0428ac8 Merge host.loc:/home/uchum/work/5.0-bugteam
into  host.loc:/home/uchum/work/5.1-bugteam
2008-04-23 11:06:26 +05:00
gshchepa/uchum@host.loc
a0c5b495cb Fixed bug#36005: server crashes inside NOT IN clause subquery with
impossible WHERE/HAVING clause
                 (subselect_single_select_engine::exec).

Allocation and initialization of joined table list t1, t2... of
subqueries like:

    NOT IN (SELECT ... FROM t1,t2,... WHERE 0)

is optimized out, however server tries to traverse this list.
2008-04-23 02:27:23 +05:00
gshchepa/uchum@host.loc
9b6f0f3a79 Merge host.loc:/home/uchum/work/PA/5.0-opt-34763
into  host.loc:/home/uchum/work/5.1-opt
2008-03-20 00:30:37 +04:00
gshchepa/uchum@host.loc
cf90fb5571 Fixed bug #34763.
Queries like:

  SELECT ROW(1, 2) IN (SELECT t1.a, 2)
    FROM t1 GROUP BY t1.a

or 

  SELECT ROW(1, 2) IN (SELECT t1.a, 2 FROM t2)
    FROM t1 GROUP BY t1.a

lead to assertion failure in the
Item_in_subselect::row_value_transformer method in debugging
build, or to unexpected error message in release build:

  ERROR 1247 (42S22): Reference '<list ref>' not supported (forward
                      reference in item list)

Unexpected error message and assertion failure have been
eliminated.
2008-03-14 23:11:59 +04:00
gkodinov/kgeorge@magare.gmz
9d860c8cdf Merge magare.gmz:/home/kgeorge/mysql/work/B30788-5.0-opt
into  magare.gmz:/home/kgeorge/mysql/work/B30788-5.1-opt
2007-11-21 13:19:50 +02:00
gkodinov/kgeorge@magare.gmz
2e2ac428ae Bug #30788: Inconsistent retrieval of char/varchar
Index lookup does not always guarantee that we can
simply remove the relevant conditions from the WHERE
clause. Reasons can be e.g. conversion errors, 
partial indexes etc. 
The optimizer was removing these parts of the WHERE 
condition without any further checking.
This leads to "false positives" when using indexes.
Fixed by checking the index reference conditions
(using WHERE) when using indexes with sub-queries.
2007-11-21 11:40:05 +02:00
gkodinov/kgeorge@macbook.gmz
fe03f6bbe0 Bug #27531: 5.1 part of the fix
- Renamed "Using join cache" to "Using join buffer".
- "Using join buffer" is now printed on the last
  table that "reads" from the join buffer cache.
2007-05-29 15:58:18 +03:00
gkodinov/kgeorge@magare.gmz
eec6b028e3 Merge magare.gmz:/home/kgeorge/mysql/work/B22855-5.0-opt
into  magare.gmz:/home/kgeorge/mysql/work/B22855-5.1-opt
2007-05-21 10:22:44 +03:00
gkodinov/kgeorge@magare.gmz
6c8e7952a1 Merge macbook:mysql/work/B22855-5.0-opt
into  magare.gmz:/home/kgeorge/mysql/work/B22855-5.0-opt
2007-05-21 10:21:55 +03:00
gkodinov/kgeorge@macbook.gmz
a9b348c71c Bug#22855:
Conversion errors when constructing the condition for an
IN predicates were treated as if the affected column contains
NULL. If such a IN predicate is inside NOT we get wrong 
results.
Corrected the handling of conversion errors in an IN predicate 
that is resolved by unique_subquery (through 
subselect_uniquesubquery_engine).
2007-05-17 19:38:34 +03:00
igor@olga.mysql.com
82239b3e9c Merge olga.mysql.com:/home/igor/mysql-5.0-opt
into  olga.mysql.com:/home/igor/mysql-5.1-opt
2007-05-12 10:54:23 -07:00
igor@olga.mysql.com
11d5f7ee1c Fixed bug #28375: a query with an NOT IN subquery predicate may cause
a crash when the left operand of the predicate is evaluated to NULL.
It happens when the rows from the inner tables (tables from the subquery)
are accessed by index methods with key values obtained by evaluation of
the left operand of the subquery predicate. When this predicate is
evaluated to NULL an alternative access with full table scan is used
to check whether the result set returned by the subquery is empty or not.
The crash was due to the fact the info about the access methods used for
regular key values was not properly restored after a switch back from the
full scan access method had occurred.
The patch restores this info properly.
The same problem existed for queries with IN subquery predicates if they
were used not at the top level of the queries.
2007-05-11 19:37:32 -07:00
gkodinov/kgeorge@magare.gmz
306371a850 bug #27531: 5.1 part of the fix:
- added join cache indication in EXPLAIN (Extra column).
 - prefer filesort over full scan over 
   index for ORDER BY (because it's faster).
 - when switching from REF to RANGE because
   RANGE uses longer key turn off sort on
   the head table only as the resulting 
   RANGE access is a candidate for join cache
   and we don't want to disable it by sorting
   on the first table only.
2007-05-04 18:06:06 +03:00
igor@olga.mysql.com
8c85357ea3 Post-merge fix. 2007-04-20 17:47:14 -07:00
evgen@moonbone.local
4434ff13a9 Merge moonbone.local:/mnt/gentoo64/work/bk-trees/mysql-5.0-opt
into  moonbone.local:/mnt/gentoo64/work/bk-trees/mysql-5.1-opt
2007-04-21 00:33:56 +04:00
igor@olga.mysql.com
6ad81b4e13 Fixed bug #27870. The bug that causes crashes manifests itself at some
conditions when executing an equijoin query with WHERE condition
containing a subquery predicate of the form join_attr NOT IN (SELECT ...).

To resolve a problem of the correct evaluation of the expression
  attr NOT IN (SELECT ...)
an array of guards is created to make it possible to filter out some 
predicates of the EXISTS subquery into which the original subquery 
predicate is transformed, in the cases when a takes the NULL value. 
If attr is defined as a field that cannot be NULL than such an array 
is not needed and is not created. 
However if the field a occurred also an an equijoin predicate t2.a=t1.b
and table t1 is accessed before table t2 then it may happen that the 
the EXISTS subquery is pushed down to the condition evaluated just after
table t1 has been accessed. In this case any occurrence of t2.a is 
substituted for t1.b. When t1.b takes the value of NULL an attempt is 
made to turn on the corresponding guard. This action caused a crash as 
no guard array had been created.

Now the code of Item_in_subselect::set_cond_guard_var checks that the guard
array has been created before setting a guard variable on. Otherwise the
method does nothing. It cannot results in returning a row that could be
rejected as the condition t2.a=t1.b will be checked later anyway.
2007-04-17 17:35:29 -07:00
evgen@moonbone.local
392fb72f5c Merge moonbone.local:/mnt/gentoo64/work/27321-bug-5.0-opt-mysql
into  moonbone.local:/mnt/gentoo64/work/bk-trees/mysql-5.1-opt
2007-04-15 12:05:13 +04:00
evgen@moonbone.local
3113ce6383 Bug#27321: Wrong subquery result in a grouping select.
The Item_outer_ref class based on the Item_direct_ref class was always used
to represent an outer field. But if the outer select is a grouping one and the 
outer field isn't under an aggregate function which is aggregated in that
outer select an Item_ref object should be used to represent such a field.
If the outer select in which the outer field is resolved isn't grouping then
the Item_field class should be used to represent such a field.
This logic also should be used for an outer field resolved through its alias
name.

Now the Item_field::fix_outer_field() uses Item_outer_field objects to
represent aliased and non-aliased outer fields for grouping outer selects
only.
Now the fix_inner_refs() function chooses which class to use to access outer
field - the Item_ref or the Item_direct_ref. An object of the chosen class
substitutes the original field in the Item_outer_ref object.
The direct_ref and the found_in_select_list fields were added to the
Item_outer_ref class.
2007-04-15 08:31:34 +04:00
evgen@moonbone.local
f470ac2000 Merge moonbone.local:/mnt/gentoo64/work/bk-trees/mysql-5.0-opt
into  moonbone.local:/mnt/gentoo64/work/bk-trees/mysql-5.1-opt
2007-03-31 02:42:40 +04:00
gkodinov/kgeorge@magare.gmz
9c55cd3e03 disabled a test reuturning wrong result (reported separately) 2007-03-28 12:09:30 +03:00
holyfoot/hf@hfmain.(none)
d24fb40374 Merge mysql.com:/home/hf/work/mrg/mysql-5.0-opt
into  mysql.com:/home/hf/work/mrg/mysql-5.1-opt
2007-03-22 11:43:23 +04:00
gkodinov/kgeorge@magare.gmz
354c364ad4 Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into  magare.gmz:/home/kgeorge/mysql/autopush/B24484-5.0
2007-03-20 19:49:38 +02:00
gkodinov/kgeorge@macbook.local
28962a76a3 Bug #24484:
To correctly decide which predicates can be evaluated with a given table
the optimizer must know the exact set of tables that a predicate depends 
on. If that mask is too wide (refer to non-existing tables) the optimizer
can erroneously skip a predicate.
One such case of wrong table usage mask were the aggregate functions.
The have a all-1 mask (meaning depend on all tables, including non-existent
ones).
Fixed by making a real used_tables mask for the aggregates. The mask is
constructed in the following way :
1. OR the table dependency masks of all the arguments of the aggregate.
2. If all the arguments of the function are from the local name resolution 
  context and it is evaluated in the same name resolution
  context where it is referenced all the tables from that name resolution 
  context are OR-ed to the dependency mask. This is to denote that an
  aggregate function depends on the number of rows it processes.
3. Handle correctly the case of an aggregate function optimization (such that
  the aggregate function can be pre-calculated and made a constant).

Made sure that an aggregate function is never a constant (unless subject of a 
specific optimization and pre-calculation).  

One other flaw was revealed and fixed in the process : references were 
not calling the recalculation method for used_tables of their targets.
2007-03-20 19:46:02 +02:00
gluh@eagle.(none)
975a23ed0f Merge mysql.com:/home/gluh/MySQL/Merge/5.0-opt
into  mysql.com:/home/gluh/MySQL/Merge/5.1-opt
2007-02-26 15:54:43 +04:00
evgen@moonbone.local
9a233742b8 Bug#23800: Outer fields in correlated subqueries is used in a temporary table
created for sorting.

Any outer reference in a subquery was represented by an Item_field object.
If the outer select employs a temporary table all such fields should be
replaced with fields from that temporary table in order to point to the 
actual data. This replacement wasn't done and that resulted in a wrong
subquery evaluation and a wrong result of the whole query.

Now any outer field is represented by two objects - Item_field placed in the
outer select and Item_outer_ref in the subquery. Item_field object is
processed as a normal field and the reference to it is saved in the
ref_pointer_array. Thus the Item_outer_ref is always references the correct
field. The original field is substituted for a reference in the
Item_field::fix_outer_field() function.

New function called fix_inner_refs() is added to fix fields referenced from
inner selects and to fix references (Item_ref objects) to these fields.

The new Item_outer_ref class is a descendant of the Item_direct_ref class.
It additionally stores a reference to the original field and designed to
behave more like a field.
2007-02-21 23:00:32 +03:00
gluh@eagle.(none)
7849d31923 Merge mysql.com:/home/gluh/MySQL/Merge/5.0-opt
into  mysql.com:/home/gluh/MySQL/Merge/5.1-opt
2007-02-02 10:25:45 +04:00
igor@olga.mysql.com
e897780919 Fixed bug #24420.
Objects of the classes Item_func_is_not_null_test and Item_func_trig_cond
must be transparent for the method Item::split_sum_func2 as these classes
are pure helpers. It means that the method Item::split_sum_func2 should
look at those objects as at pure wrappers.
2007-01-26 17:10:45 -08:00
sergefp@mysql.com
8a3592d4e2 BUG#24127: merge: update tests results 2007-01-25 10:00:09 +03:00
sergefp@pylon.mylan
5bc7d596cc Merge mysql.com:/home/psergey/mysql-5.0-bug8804-r12
into  mysql.com:/home/psergey/mysql-5.1-bug8804-r12-merge
2007-01-24 22:28:28 +03:00
sergefp@mysql.com
c3f46e1f26 BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
  compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
  ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
  displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
2007-01-12 23:22:41 +03:00
sergefp@mysql.com
5236794855 BUG#24085: Wrong result for NULL IN (SELECT not_null_val FROM ...)
When transforming "oe IN (SELECT ie ...)" wrap the pushed-down predicates
iff "oe can be null", not "ie can be null".
The fix doesn't cover row-based subqueries, those will be fixed in #24127.
2007-01-12 22:11:40 +03:00
holyfoot/hf@mysql.com/deer.(none)
c40b292e84 merging 2006-11-09 12:49:39 +04:00
sergefp@mysql.com
54a713aac5 BUG#8804: wrong results for NULL IN (SELECT ...)
Evaluate "NULL IN (SELECT ...)" in a special way: Disable pushed-down 
conditions and their "consequences": 
 = Do full table scans instead of unique_[index_subquery] lookups.
 = Change appropriate "ref_or_null" accesses to full table scans in
   subquery's joins.
Also cache value of NULL IN (SELECT ...) if the SELECT is not correlated 
wrt any upper select.
2006-10-31 20:51:09 +03:00