Two problems here:
Problem 1:
While constructing the join columns list the optimizer does as follows:
1. Sets the join_using_fields/natural_join members of the right JOIN
operand.
2. Makes a "table reference" (TABLE_LIST) to parent the two tables.
3. Assigns the join_using_fields/is_natural_join of the wrapper table
using join_using_fields/natural_join of the rightmost table
4. Sets join_using_fields to NULL for the right JOIN operand.
5. Passes the parent table up to the same procedure on the upper
level.
Step 1 overrides the the join_using_fields that are set for a nested
join wrapping table in step 4.
Fixed by making a designated variable SELECT_LEX::prev_join_using to
pass the data from step 1 to step 4 without destroying the wrapping
table data.
Problem 2:
The optimizer checks for ambiguous columns while transforming
NATURAL JOIN/JOIN USING to JOIN ON. While doing that there was no
distinction between columns that are used in the generated join
condition (where ambiguity can be checked) and the other columns
(where ambiguity can be checked only when resolving references
coming from outside the JOIN construct itself).
Fixed by allowing the non-USING columns to be present in multiple
copies in both sides of the join and moving the ambiguity check
to the place where unqualified references to the join columns are
resolved (find_field_in_natural_join()).
When a merge table is opened compare column and key definition of
underlying tables against column and key definition of merge table.
If any of underlying tables have different column/key definition
refuse to open merge table.
The optimizer takes away columns from GROUP BY/DISTINCT if they constitute
all the parts of an unique index.
However if some of the columns can contain NULLs this cannot be done
(because an UNIQUE index can have multiple rows with NULL values).
Fixed by not using UNIQUE indexes with nullable columns to remove
grouping columns from GROUP BY/DISTINCT.
Depending on the queries we use different data processing methods
and can lose some data in case of double (and decimal in 4.1) fields.
The fix consists of two parts:
1. double comparison changed, now double a is equal to double b
if (a-b) is less than 5*0.1^(1 + max(a->decimals, b->decimals)).
For example, if a->decimals==1, b->decimals==2, a==b if (a-b)<0.005
2. if we use a temporary table, store double values there as is
to avoid any data conversion (rounding).
Checking for NULL before calling the val_xxx()
methods only checks for such arguments that are
known to be NULLs at compile time.
The arguments that may or may not contain
NULLs (e.g. function calls and possibly others)
are not checked at all.
Fixed by first calling the val_xxx() method and
then checking for null in SEC_TO_TIME().
In addition QUARTER() was not returning 0 (as all the
val_int() functions do when processing a NULL value).
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.
The bug report has demonstrated the following two problems.
1. If an ORDER/GROUP BY list includes a constant expression being
optimized away and, at the same time, containing single-row
subselects that return more that one row, no error is reported.
Strictly speaking the standard allows to ignore error in this case.
Yet, now a corresponding fatal error is reported in this case.
2. If a query requires sorting by expressions containing single-row
subselects that, however, return more than one row, then the execution
of the query may cause a server crash.
To fix this some code has been added that blocks execution of a subselect
item in case of a fatal error in the method Item_subselect::exec.
on duplicate key".
INSERT ... SELECT ... ON DUPLICATE KEY UPDATE which was used in
stored routine or as prepared statement and which in its ON DUPLICATE
KEY clause erroneously tried to assign value to a column mentioned only
in its SELECT part was properly emitting error on the first execution
but succeeded on the second and following executions.
Code which is responsible for name resolution of fields mentioned in
UPDATE clause (e.g. see select_insert::prepare()) modifies table list
and Name_resolution_context used in this process. It uses
Name_resolution_context_state::save_state/restore_state() to revert
these modifications. Unfortunately those two methods failed to revert
properly modifications to TABLE_LIST::next_name_resolution_table
and this broke name resolution process for successive executions.
This patch fixes Name_resolution_context_state::save_state/restore_state()
in such way that it properly handles TABLE_LIST::next_name_resolution_table.
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.
We use INT_RESULT type if all arguments are of type INT for 'if', 'case',
'coalesce' functions regardless of arguments' unsigned flag, so sometimes we can
exceed the INT bounds.
tables' lock."
Execution of ALTER TABLE ... ENABLE KEYS on a table (which can take rather
long time) prevented concurrent execution of all statements using tables.
The problem was caused by the fact that we were holding LOCK_open mutex
during whole duration of this statement and particularly during call
to handler::enable_indexes(). This behavior was introduced as part of the
fix for bug 14262 "SP: DROP PROCEDURE|VIEW (maybe more) write to binlog
too late (race cond)"
The patch simply restores old behavior. Note that we can safely do this as
this operation takes exclusive lock (similar to name-lock) which blocks both
DML and DDL on the table being altered.
It also introduces mysql-test/include/wait_show_pattern.inc helper script
which is used to make test-case for this bug robust enough.
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.
WL#3681 (ALTER TABLE ORDER BY)
Before this fix, the ALTER TABLE statement implemented an ORDER BY option
with the following characteristics :
1) The order by clause accepts a list of criteria, with optional ASC or
DESC keywords
2) Each criteria can be a general expression, involving operators,
native functions, stored functions, user defined functions, subselects ...
With this fix :
1) has been left unchanged, since it's a de-facto existing feature,
that was already present in the code base and partially covered in the test
suite. Code coverage for ASC and DESC was missing and has been improved.
2) has been changed to limit the kind of criteria that are permissible:
now only a column name is valid.
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.
The problem was that if a prepared statement accessed a view, the
access to the tables listed in the query after that view was done in
the security context of the view.
The bug was in the assigning of the security context to the tables
belonging to a view: we traversed the list of all query tables
instead. It didn't show up in the normal (non-prepared) statements
because of the different order of the steps of checking privileges
and descending into a view for normal and prepared statements.
The solution is to traverse the list and stop once the last table
belonging to the view was processed.
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.