out of a nested join to the on conditions for the nest.
The bug happened due to:
1. The function simplify_joins could change on expressions for nested joins.
Yet modified on expressions were not saved in prep_on_expr.
2. On expressions were not restored for nested joins in
reinit_stmt_before_use.
When there is conjunction of conds, the substitute_for_best_equal_field()
will call the eliminate_item_equal() function in loop to build final
expression. But if eliminate_item_equal() finds that some cond will always
evaluate to 0, then that cond will be substituted by Item_int with value ==
0. In this case on the next iteration eliminate_item_equal() will get that
Item_int and treat it as Item_cond. This is leads to memory corruption and
server crash on cleanup phase.
To the eliminate_item_equal() function was added DBUG_ASSERT for checking
that all items treaten as Item_cond are really Item_cond.
The substitute_for_best_equal_field() now checks that if
eliminate_item_equal() returns Item_int and it's value is 0 then this
value is returned as the result of whole conjunction.
fix_fields() was not called for "order by" variables if the type was a
"constant integer", and thus interpreted as a column index.
However, a local variable is an expression and should not be interpreted
as a column index. Instead it behaves just like when using a user variable
for instance (i.e. it will not affect the ordering).
1. dbug state is now local to a thread
2. new macros: DBUG_EXPLAIN, DBUG_EXPLAIN_INITIAL,
DBUG_SET, DBUG_SET_INITIAL, DBUG_EVALUATE, DBUG_EVALUATE_IF
3. macros are do{}while(0) wrapped
4. incremental modifications to the dbug state (e.g. "+d,info:-t")
5. dbug code cleanup, style fixes
6. _db_on_ and DEBUGGER_ON/OFF removed
7. rest of MySQL code fixed because of 3 (missing ;) and 6
8. dbug manual updated
9. server variable @@debug (global and local) to control dbug from SQL!
a. -#T to print timestamps in the log
A subquery transformation changes the HAVING clause of the embedding query if the subquery contains
a GROUP BY clause. Yet the split_sum_func2 function was not applied to the modified HAVING clause.
This could result in wrong answers.
and possibly server crash in mysqld v5.0.
Reported MyISAM table was created in mysqld 4.1 and contains varchar field.
When binary files of that table was moved to 5.0, mysqld treats that varchar
field as a string field.
In order to make grouping server calculates group buffer, and because
that field is string server assumes it has fixed length and doesn't add
space for length, but later that field is converted to varchar field.
Due to this, when field values were actually copied, additional space for
length bytes is taken and buffer overrun occurs, which may lead to server crash.
The calc_group_buffer() function now reserves additional space for length
bytes for VAR_STRING fields, like for VARCHAR fields.
When an ambiguous field name is used in a group by clause a warning is issued
in the find_order_in_list function by a call to push_warning_printf.
An expression that was not always valid was passed to this call as the field
name parameter.
A query with a group by and having clauses could return a wrong
result set if the having condition contained a constant conjunct
evaluated to FALSE.
It happened because the pushdown condition for table with
grouping columns lost its constant conjuncts.
Pushdown conditions are always built by the function make_cond_for_table
that ignores constant conjuncts. This is apparently not correct when
constant false conjuncts are present.
The problem has manifested itself in the cases when we have a nested outer join
for which it can be inferred that one of the inner tables is a single row table.
functions are involved.
When subselect is a join with set functions and no record have been found in
it, end_send_group() sets null_row for all tables in order aggregate functions
to calculate their values correctly. Normally this null_row flag is cleared for
each table in sub_select(), but flush_cached_records() doesn't do so.
Due to this all fields from the table processed by flush_cached_records() are
always evaluated as nulls and whole select produces wrong result.
flush_cached_records() now clears null_row flag at the very beginning.