The reported problems were due to two completely unrelated omissions.
1) The file sort procedure didn't correctly create the sort key in
make_sortkey when the sortkey was an unsigned integer.
2) The name resolution procedure for column references inside a HAVING
clause did not propagate the unsigned_flag of the resolved references.
This patch corrects both problems.
fixing test results accordingly.
func_system.test:
New test that illegal mix of collations does not happen anymore.
item_strfunc.h:
safe_charset_converter() was added for system constants.
item_strfunc.cc:
safe_charset_converter() was added for system constants.
item_func.cc, item.h, item.cc:
Bug#8291: Illegal collation mix with USER() function.
After discussion with PeterG and Serge, a new coercibility
level for "system constants" was introduced, between
COERRIBLE and IMPLICIT. Thus:
SELECT col1 = USER() FROM t1; - is done according to col1 collation.
SELECT 'string' = USER(); - is done according to USER() collation.
At the same time, "nagg" and "strong" members were removed as unused.
item_create.cc:
Version is a system constant too.
Change string->float conversion to delay division as long as possible.
This gives us more exact integer->float conversion for numbers of type '123.45E+02' (Bug #7740)
Ensure that references in HAVING, ORDER BY or GROUP BY are calculated after fields in SELECT.
This will ensure that any reference to these has a valid value.
Generalized the code for split_sum_func()
not default_charset_into. It fixes the
problem that in some cases numbers where
treated as CHAR(N), not as BINARY(N), e.g.
wrong 'charsetnr' when sent to the client side.
2. IFNULL didn't aggregate argument charsets
and collations, so IFNULL(1,'a') produced
a CHAR(N). Now produces a BINARY(N).
3. SELECT PROCEDURE ANALIZE now returns
BINARY columns, which is much better than it worked
previously: CHAR with the default character set.
But in the future it's worth to fix the fields
'Field_name' and 'Optimal_fieldtype' to use UTF8,
and 'Min_value' and 'Max_value' to inherit their charsets
from the original items. But it is not important,
and BINARY(N) is OK for now.
4. Tests were fixed accordingly. No new tests were
made, as the old onces cover everything.
* Added Item_ref::set_properties
* Item_ref::Item_ref now expects to get in *item either
NULL - then fix_fields() will be called later or
ptr to Item it will refer to - then an equivalent of fix_fields() call is performed
The problem in 4.1 was the same as in 4.0 - fix_fields() not called for created Item_ref.
The fix is similar too - initialize Item_refs in ctor (but don't interfere with cases when
Item_ref is used by subselects).
In server we assume that datetime values stored in MYSQL_TIME struct
are normalized (and year is not greater than 9999), so we should
perform range checks in all places then we convert something to
MYSQL_TIME.
the result takes its charset/collation
attributes from the character string,
e.g. SELECT func(NULL, _latin2'string')
now returns a latin2 result. This is
done by introducing a new derivation
(aka coercibility) level DERIVATION_IGNORABLE,
which is used with Item_null.
2. 'Pure' NULL is now BINARY(0), not CHAR(0).
I.e. NULL is now more typeless.
of client equals to character set of connection, possibly required
conversion to character set of column is not performed
(prepared statements, data is supplied using placeholders).
constant with a column. The string is converted into the column
character set. It conversion doesn't lose data, then operation
is possible. Otherwise, give an error, as it was earlier.
Simple optimzations and cleanups
Removed compiler warnings and fixed portability issues
Added client functions 'mysql_embedded()' to allow client to check if we are using embedded server
Fixes for purify
statements and negative time/date values".
The bug was in wrong sprintf format used in the client library.
The fix moves TIME -> string conversion functions to sql-common and
utilized them in the client library.
crashes server (prepared statements)": the bug was that all boolean
items always recovered its original arguments at statement cleanup
stage.
This collided with Item_subselect::select_transformer, which tries to
permanently change the item tree to use a transformed subselect instead of
original one.
So we had this call sequence for prepare:
mysql_stmt_prepare -> JOIN::prepare ->
Item_subselect::fix_fields -> the item tree gets transformed ->
Item_bool_rowready_func2::cleanup, item tree is recovered to original
state, while it shouldn't have been;
mysql_stmt_execute -> attempts to execute a broken tree -> crash.
Now instead of bluntly recovering all arguments of bool functions in
Item_bool_rowready_func2::cleanup, we recover only those
which were changed, and do it in one place.
There still would exist a possibility for a collision with subselect
tranformation, if permanent and temporary changes were performed at the
same stage.
But fortunately subselect transformation is always done first, so it
doesn't conflict with the optimization done by propogate_cond_constants.
Now we have:
mysql_stmt_prepare -> JOIN::prepare -> subselect transformation
permanently changes the tree -> cleanup doesn't recover anything,
because nothing was registered for recovery.
mysql_stmt_execute -> JOIN::prepare (the tree is already transformed,
so it doesn't change), JOIN::optimize ->
propogate_cond_constants -> temporary changes the item tree
with constants -> JOIN::execute -> cleanup ->
the changes done by propogate_cond_constants are recovered, as
they were registered for recovery.
crashes mysqld": implementation for a generic item tree modifications
registry. Every item tree modification which should be rolled back for
subsequent execution of a prepared statement or stored procedure should
be saved in the registry. All such modifications are rolled back at once
during cleanup stage of PS.
Actual fix for the bug just adds a call to register modifications to
convert_constant_item.
Post review fixes implemented.
identical to another in result"
According to SQL standard queries like
"select t1.a as col from t1, t2 order by a" should return an error if
both tables contain field a.