When inserting into a join-based view the update fields from the ON DUPLICATE
KEY UPDATE wasn't checked to be from the table being inserted into and were
silently ignored.
The new check_view_single_update() function is added to check that
insert/update fields are being from the same single table of the view.
After fix for bug#21798 JOIN stores the pointer to the buffer for sorting
fields. It is used while sorting for grouping and for ordering. If ORDER BY
clause has more elements then the GROUP BY clause then a memory overrun occurs.
Now the length of the ORDER BY list is always passed to the
make_unireg_sortorder() function and it allocates buffer big enough to be
used for bigger list.
UNION over correlated and uncorrelated SELECTS.
In such subqueries each uncorrelated SELECT should be considered as
uncacheable. Otherwise join_free is called for it and in many cases
it causes some problems.
crashes server
Check for null value is reliable only after calling some of the
val_xxx() methods. If the val_xxx() method is not called
the null_value flag will be set only for certain types of NULL
values (like SQL constant NULLs for example).
This caused a crash while trying to dereference a NULL pointer
that is returned by val_str() for NULL values.
Fixed by swapping the order of val_xxx() and null_value check.
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.
The optimizer needs to evaluate whether predicates are better
evaluated using an index. IN is one such predicate.
To qualify an IN predicate must involve a field of the index
on the left and constant arguments on the right.
However whether an expression is a constant can be determined only
by knowing the preceding tables in the join order.
Assuming that only IN predicates with expressions on the right that
are constant for the whole query qualify limits the scope of
possible optimizations of the IN predicate (more specifically it
doesn't allow the "Range checked for each record" optimization for
such an IN predicate.
Fixed by not pre-determining the optimizability of the IN predicate
in the case when all right IN operands are not SQL constant expressions
for queries using 'range checked for each record'.
The problem was fixed in 5.0 by the patch for bug 12291.
This patch down-ported the corresponding code from 5.0 into
QUICK_SELECT::init() and added a new test case.
in a select list.
The objects of the Item_trigger_field class inherited the implementations
of the methods copy_or_same, get_tmp_table_item and get_tmp_table_field
from the class Item_field while they rather should have used the default
implementations defined for the base class Item.
It could cause catastrophic problems for triggers that used SELECTs
with select list containing trigger fields such as NEW.<table column>
under DISTINCT.
Currently in the ONLY_FULL_GROUP_BY mode no hidden fields are allowed in the
select list. To ensure this each expression in the select list is checked
to be a constant, an aggregate function or to occur in the GROUP BY list.
The last two requirements are wrong and doesn't allow valid expressions like
"MAX(b) - MIN(b)" or "a + 1" in a query with grouping by a.
The correct check implemented by the patch will ensure that:
any field reference in the [sub]expressions of the select list
is under an aggregate function or
is mentioned as member of the group list or
is an outer reference or
is part of the select list element that coincide with a grouping element.
The Item_field objects now can contain the position of the select list
expression which they belong to. The position is saved during the
field's Item_field::fix_fields() call.
The non_agg_fields list for non-aggregated fields is added to the SELECT_LEX
class. The SELECT_LEX::cur_pos_in_select_list now contains the position in the
select list of the expression being currently fixed.
aliases ignored
When a column reference to a column in JOIN USING is resolved and a new
Item is created for this column the user defined name was lost.
This fix preserves the alias by setting the name of the new Item to the
original alias.
correctly.
The Item_func::print method was used to print the Item_func_encode and the
Item_func_decode objects. The last argument to ENCODE and DECODE functions
is a plain C string and thus Item_func::print wasn't able to print it.
The print() method is added to the Item_func_encode class. It correctly
prints the Item_func_encode and the Item_func_decode objects.
WHERE is present.
If a DELETE statement with ORDER BY and LIMIT contains a WHERE clause
with conditions that for sure cannot be used for index access (like in
WHERE @var:= field) the execution always follows the filesort path.
It happens currently even when for the above case there is an index that
can be used to speedup sorting by the order by list.
Now if a DELETE statement with ORDER BY and LIMIT contains such WHERE
clause conditions that cannot be used to build any quick select then
the mysql_delete() tries to use an index like there is no WHERE clause at all.
In the method Item_field::fix_fields we try to resolve the name of
the field against the names of the aliases that occur in the select
list. This is done by a call of the function find_item_in_list.
When this function finds several occurrences of the field name
it sends an error message to the error queue and returns 0.
Yet the code did not take into account that find_item_in_list
could return 0 and tried to dereference the returned value.
used.
The Item::save_in_field() function is called from fill_record() to fill the
new row with data while execution of the CREATE TABLE ... SELECT statement.
Item::save_in_field() calls val_xxx() methods in order to get values.
val_xxx() methods do not take into account the result field. Due to this
Item_func_set_user_var::val_xxx() methods returns values from the original
table, not from the temporary one.
The save_in_field() member function is added to the Item_func_set_user_var
class. It detects whether the result field should be used and properly updates
the value of the user variable.
A BINARY field is represented by the Field_string class. The space character
is used as the filler for unused characters in such a field. But a BINARY field
should use \x00 instead.
Field_string:reset() now detects whether the current field is a BINARY one
and if so uses the \x00 character as a default value filler.