Resolved all conflicts, bad merges and fixed a few minor bugs in the code.
Commented out the queries from multi_update, view, subselect_sj, func_str,
derived_view, view_grant that failed either with crashes in ps-protocol or
with wrong results.
The failures are clear indications of some bugs in the code and these bugs
are to be fixed.
Analysis:
The subquery is evaluated first during ref-optimization of the outer
query because the subquery is considered constant from the perspective
of the outer query. Thus an attempt is made to evaluate the MAX subquery
and use the new constant to drive an index nested loops join.
During this evaluation the inner-most subquery replaces the JOIN_TAB
with a new one that fetches the data from a temp table.
The function select_describe crashes at the lines:
TABLE_LIST *real_table= table->pos_in_table_list;
item_list.push_back(new Item_string(real_table->alias,
strlen(real_table->alias),
cs));
because 'table' is a temp table, and it has no corresponding table
reference. This 'real_table' is NULL, and real_table->alias results
in a crash.
Solution:
In the spirit of MWL#89 prevent the evaluation of expensive predicates
during optimization. This patch prevents the evaluation of expensive
predicates during ref optimization.
sql/item_subselect.h:
Remove unused class member. Not needed for the fix, but noticed now and removed.
In sql_class.cc, 'row_count', of type 'ha_rows', was used as last argument for
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD which is
"Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %ld".
So 'ha_rows' was used as 'long'.
On SPARC32 Solaris builds, 'long' is 4 bytes and 'ha_rows' is 'longlong' i.e. 8 bytes.
So the printf-like code was reading only the first 4 bytes.
Because the CPU is big-endian, 1LL is 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01
so the first four bytes yield 0. So the warning message had "row 0" instead of
"row 1" in test outfile_loaddata.test:
-Warning 1366 Incorrect string value: '\xE1\xE2\xF7' for column 'b' at row 1
+Warning 1366 Incorrect string value: '\xE1\xE2\xF7' for column 'b' at row 0
All error-messaging functions which internally invoke some printf-life function
are potential candidate for such mistakes.
One apparently easy way to catch such mistakes is to use
ATTRIBUTE_FORMAT (from my_attribute.h).
But this works only when call site has both:
a) the format as a string literal
b) the types of arguments.
So:
func(ER(ER_BLAH), 10);
will silently not be checked, because ER(ER_BLAH) is not known at
compile time (it is known at run-time, and depends on the chosen
language).
And
func("%s", a va_list argument);
has the same problem, as the *real* type of arguments is not
known at this site at compile time (it's known in some caller).
Moreover,
func(ER(ER_BLAH));
though possibly correct (if ER(ER_BLAH) has no '%' markers), will not
compile (gcc says "error: format not a string literal and no format
arguments").
Consequences:
1) ATTRIBUTE_FORMAT is here added only to functions which in practice
take "string literal" formats: "my_error_reporter" and "print_admin_msg".
2) it cannot be added to the other functions: my_error(),
push_warning_printf(), Table_check_intact::report_error(),
general_log_print().
To do a one-time check of functions listed in (2), the following
"static code analysis" has been done:
1) replace
my_error(ER_xxx, arguments for substitution in format)
with the equivalent
my_printf_error(ER_xxx,ER(ER_xxx), arguments for substitution in
format),
so that we have ER(ER_xxx) and the arguments *in the same call site*
2) add ATTRIBUTE_FORMAT to push_warning_printf(),
Table_check_intact::report_error(), general_log_print()
3) replace ER(xxx) with the hard-coded English text found in
errmsg.txt (like: ER(ER_UNKNOWN_ERROR) is replaced with
"Unknown error"), so that a call site has the format as string literal
4) this way, ATTRIBUTE_FORMAT can effectively do its job
5) compile, fix errors detected by ATTRIBUTE_FORMAT
6) revert steps 1-2-3.
The present patch has no compiler error when submitted again to the
static code analysis above.
It cannot catch all problems though: see Field::set_warning(), in
which a call to push_warning_printf() has a variable error
(thus, not replacable by a string literal); I checked set_warning() calls
by hand though.
See also WL 5883 for one proposal to avoid such bugs from appearing
again in the future.
The issues fixed in the patch are:
a) mismatch in types (like 'int' passed to '%ld')
b) more arguments passed than specified in the format.
This patch resolves mismatches by changing the type/number of arguments,
not by changing error messages of sql/share/errmsg.txt. The latter would be wrong,
per the following old rule: errmsg.txt must be as stable as possible; no insertions
or deletions of messages, no changes of type or number of printf-like format specifiers,
are allowed, as long as the change impacts a message already released in a GA version.
If this rule is not followed:
- Connectors, which use error message numbers, will be confused (by insertions/deletions
of messages)
- using errmsg.sys of MySQL 5.1.n with mysqld of MySQL 5.1.(n+1)
could produce wrong messages or crash; such usage can easily happen if
installing 5.1.(n+1) while /etc/my.cnf still has --language=/path/to/5.1.n/xxx;
or if copying mysqld from 5.1.(n+1) into a 5.1.n installation.
When fixing b), I have verified that the superfluous arguments were not used in the format
in the first 5.1 GA (5.1.30 'bteam@astra04-20081114162938-z8mctjp6st27uobm').
Had they been used, then passing them today, even if the message doesn't use them
anymore, would have been necessary, as explained above.
include/my_getopt.h:
this function pointer is used only with "string literal" formats, so we can add
ATTRIBUTE_FORMAT.
mysql-test/collections/default.experimental:
test should pass now
sql/derror.cc:
by having a format as string literal, ATTRIBUTE_FORMAT check becomes effective.
sql/events.cc:
Change justified by the following excerpt from sql/share/errmsg.txt:
ER_EVENT_SAME_NAME
eng "Same old and new event name"
ER_EVENT_SET_VAR_ERROR
eng "Error during starting/stopping of the scheduler. Error code %u"
sql/field.cc:
ER_TOO_BIG_SCALE 42000 S1009
eng "Too big scale %d specified for column '%-.192s'. Maximum is %lu."
ER_TOO_BIG_PRECISION 42000 S1009
eng "Too big precision %d specified for column '%-.192s'. Maximum is %lu."
ER_TOO_BIG_DISPLAYWIDTH 42000 S1009
eng "Display width out of range for column '%-.192s' (max = %lu)"
sql/ha_ndbcluster.cc:
ER_OUTOFMEMORY HY001 S1001
eng "Out of memory; restart server and try again (needed %d bytes)"
(sizeof() returns size_t)
sql/ha_ndbcluster_binlog.cc:
Too many arguments for:
ER_GET_ERRMSG
eng "Got error %d '%-.100s' from %s"
Patch by Jonas Oreland.
sql/ha_partition.cc:
print_admin_msg() is used only with a literal as format, so ATTRIBUTE_FORMAT
works.
sql/handler.cc:
ER_OUTOFMEMORY HY001 S1001
eng "Out of memory; restart server and try again (needed %d bytes)"
(sizeof() returns size_t)
sql/item_create.cc:
ER_TOO_BIG_SCALE 42000 S1009
eng "Too big scale %d specified for column '%-.192s'. Maximum is %lu."
ER_TOO_BIG_PRECISION 42000 S1009
eng "Too big precision %d specified for column '%-.192s'. Maximum is %lu."
'c_len' and 'c_dec' are char*, passed as %d !! We don't know their value
(as strtoul() failed), but they are likely big, so we use INT_MAX.
'len' is ulong.
sql/item_func.cc:
ER_WARN_DATA_OUT_OF_RANGE 22003
eng "Out of range value for column '%s' at row %ld"
ER_CANT_FIND_UDF
eng "Can't load function '%-.192s'"
sql/item_strfunc.cc:
ER_TOO_BIG_FOR_UNCOMPRESS
eng "Uncompressed data size too large; the maximum size is %d (probably, length of uncompressed data was corrupted)"
max_allowed_packet is ulong.
sql/mysql_priv.h:
sql_print_message_func is a function _pointer_.
sql/sp_head.cc:
ER_SP_RECURSION_LIMIT
eng "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.192s"
max_sp_recursion_depth is ulong
sql/sql_acl.cc:
ER_PASSWORD_NO_MATCH 42000
eng "Can't find any matching row in the user table"
ER_CANT_CREATE_USER_WITH_GRANT 42000
eng "You are not allowed to create a user with GRANT"
sql/sql_base.cc:
ER_NOT_KEYFILE
eng "Incorrect key file for table '%-.200s'; try to repair it"
ER_TOO_MANY_TABLES
eng "Too many tables; MySQL can only use %d tables in a join"
MAX_TABLES is size_t.
sql/sql_binlog.cc:
ER_UNKNOWN_ERROR
eng "Unknown error"
sql/sql_class.cc:
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
eng "Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %ld"
WARN_DATA_TRUNCATED 01000
eng "Data truncated for column '%s' at row %ld"
sql/sql_connect.cc:
ER_HANDSHAKE_ERROR 08S01
eng "Bad handshake"
ER_BAD_HOST_ERROR 08S01
eng "Can't get hostname for your address"
sql/sql_insert.cc:
ER_WRONG_VALUE_COUNT_ON_ROW 21S01
eng "Column count doesn't match value count at row %ld"
sql/sql_parse.cc:
ER_WARN_HOSTNAME_WONT_WORK
eng "MySQL is started in --skip-name-resolve mode; you must restart it without this switch for this grant to work"
ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT
eng "Too high level of nesting for select"
ER_UNKNOWN_ERROR
eng "Unknown error"
sql/sql_partition.cc:
ER_OUTOFMEMORY HY001 S1001
eng "Out of memory; restart server and try again (needed %d bytes)"
sql/sql_plugin.cc:
ER_OUTOFMEMORY HY001 S1001
eng "Out of memory; restart server and try again (needed %d bytes)"
sql/sql_prepare.cc:
ER_OUTOFMEMORY HY001 S1001
eng "Out of memory; restart server and try again (needed %d bytes)"
ER_UNKNOWN_STMT_HANDLER
eng "Unknown prepared statement handler (%.*s) given to %s"
length value (for '%.*s') must be 'int', per the doc of printf()
and the code of my_vsnprintf().
sql/sql_show.cc:
ER_OUTOFMEMORY HY001 S1001
eng "Out of memory; restart server and try again (needed %d bytes)"
sql/sql_table.cc:
ER_TOO_BIG_FIELDLENGTH 42000 S1009
eng "Column length too big for column '%-.192s' (max = %lu); use BLOB or TEXT instead"
sql/table.cc:
ER_NOT_FORM_FILE
eng "Incorrect information in file: '%-.200s'"
ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE
eng "Column count of mysql.%s is wrong. Expected %d, found %d. Created with MySQL %d, now running %d. Please use mysql_upgrade to fix this error."
table->s->mysql_version is ulong.
sql/unireg.cc:
ER_TOO_LONG_TABLE_COMMENT
eng "Comment for table '%-.64s' is too long (max = %lu)"
ER_TOO_LONG_FIELD_COMMENT
eng "Comment for field '%-.64s' is too long (max = %lu)"
ER_TOO_BIG_ROWSIZE 42000
eng "Row size too large. The maximum row size for the used table type, not counting BLOBs, is %ld. You have to change some columns to TEXT or BLOBs"
.-> USING PASSWORD: NO
The server was always setting the flag for using password to NO and
then relying on the server authentication plugin to update it if it uses
a password.
This creates compatibility problems with 5.1 when rejecting a
nonexistent user login.
Set the default for the password supplied flag for non-existing users
as the default plugin (native password authentication) would do it
for compatibility reasons.
Test case added.
federated.result updated with the correct error message.
Field_geom::reset() failed to reset its base Field_blob.
The range optimizer used the un-initilized field during optimization and execution.
mysql-test/r/gis.result:
New test case.
mysql-test/t/gis.test:
New test case.
sql/field.h:
Field_geom::reset() must call Field_blob::reset(), even if the field is not nullable.
Impementing Test Review Comment.
Bug test scenario:
SELECT is not returning result set for "equal" (=) and "NULL safe equal
operator" (<=>) on BIT data type. Extending this scenario for all data types
Analysis:
During optimization of the subquery, in the call chain:
update_ref_and_keys -> add_key_fields ->
merge_key_fields -> Item_direct_ref::is_null -> Item_cache::is_null
The call to Item_cache::is_null() returns TRUE, which is wrong.
This results in Item_null replacing the field 'f3' in the KEY_FIELD,
then this Item_null is used for index access, producing a wrong result.
The reason why Item_cache::is_null returns wrong result is that
this Item_cache object is a cache of the left operand of IN, and was
updated in Item_in_optimizer::val_int. In MWL#89 the latter method is
called during the execution phase, which is after we optimize the subquery.
Therefore during the optization phase the left operand cache of IN was
not updated.
Solution:
Update the left operand cache during optimization if it is a constant.
This bug fix also discoveres and fixes a wrong IF statement in
convert_constant_item().
mysql-test/mysql-test-run.pl:
Directories added for mac to lybrary search paths.
plugin/handler_socket/libhsclient/Makefile.am:
Static build of library removed.
aria_chk now returns 1 if one got any warnings during check and 2 if one got errors.
lp:728919 maria_chk should fail on all detected corruptions
mysql-test/lib/My/SafeProcess.pm:
Removed ^M lines from the file
storage/maria/ma_check.c:
Fixed indentation
storage/maria/maria_chk.c:
aria_chk now returns 1 if one got any warnings during check and 2 if one got errors.
storage/maria/unittest/ma_control_file-t.c:
Use unique sub directory for test results
storage/maria/unittest/ma_maria_log_cleanup.c:
Added help function create_tmpdir()
storage/maria/unittest/ma_pagecache_consist.c:
Use unique sub directory for test results
storage/maria/unittest/ma_pagecache_rwconsist.c:
Use unique sub directory for test results
storage/maria/unittest/ma_pagecache_rwconsist2.c:
Use unique sub directory for test results
storage/maria/unittest/ma_pagecache_single.c:
Use unique sub directory for test results
storage/maria/unittest/ma_test_all-t:
Use unique sub directory for test results
storage/maria/unittest/ma_test_loghandler-t.c:
Use unique sub directory for test results
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Use unique sub directory for test results
remove delete of files that are already deleted by maria_log_remove()
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Use unique sub directory for test results
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Use unique sub directory for test results
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Use unique sub directory for test results
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Use unique sub directory for test results
remove delete of files that are already deleted by maria_log_remove()
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
Use unique sub directory for test results
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Use unique sub directory for test results
remove delete of files that are already deleted by maria_log_remove()
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Use unique sub directory for test results
support-files/compiler_warnings.supp:
Supress some warnings
unittest/unit.pl:
Run 4 unittests in parallel
This assert could be triggered during two phase commit if binary
log was used as transaction coordinator log. The triggered assert
checks that the same number of transaction IDs are processed in
the prepare and commit phases.
The reason it was triggered, was that the transaction consisted
of an INSERT/UPDATE IGNORE that had an ignorable error. Since it
had an error, no row log events were made and therefore
prepared_xids was 0. However, since it was an IGNORE statement,
the statement started a read/write statement transaction, committed
it and completed successfully.
This patch fixes the problem by adjusting the assert to take
this possibility into account.
Test case added to binlog.binlog_innodb_row.test.
If LOAD DATA INFILE featured a SET clause, the name=value pairs
would be regenerated using item::print. Unfortunately, that code
is mostly optimized for EXPLAIN EXTENDED output and such, and can
not be relied on to return valid SQL.
We now name each value its original, user-supplied form and use
that to create LOAD DATA INFILE statements for statement-based
replication.
mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result:
minor change in syntactic sugar
mysql-test/suite/rpl/r/rpl_loaddatalocal.result:
add test case
mysql-test/suite/rpl/t/rpl_loaddatalocal.test:
add test case
sql/sql_load.cc:
Do not try to item::print values in LOAD DATA INFILE's
SET clause; they might not even be valid SQL at this
point. Use our saved version instead.
sql/sql_yacc.yy:
If LOAD DATA INFILE has SET name=val clauses, tag the
individual val-parts with the user's version so we can
later replicate that, rather than the smashed pieces
we'd get from item::print once the optimizer's through
with our poor values.
Store decimal 0.0 in zero bytes in dynamic strings.
mysqltest: Don't ignore error from mysql_stmt_fetch; This could cause rows to be missing from log when running with --ps-protocol
Fixed wrong result length for CAST(... as TIME)
client/mysqltest.cc:
Don't ignore error from mysql_stmt_fetch; This could cause rows to be missing from log when running with --ps-protocol
libmysql/libmysql.c:
The max length for a TIME column is 17, not 15.
mysql-test/r/dyncol.result:
More tests
mysql-test/t/dyncol.test:
More tests
mysys/ma_dyncol.c:
Check content of decimal value on read and store to not get assert in decimal_bin_size().
Store decimal 0.0 in zero bytes in dynamic strings. This also solves a problem where decimal 0 had different internal representations.
sql-common/my_time.c:
Fixed DBUG_PRINT
sql/item_timefunc.h:
Fixed wrong result length for CAST(... as TIME). This was the cause of failures in buildbot when doing cast(... as time);
sql/protocol.cc:
More DBUG_PRINT
and innodb
The 5.5 version of the patch.
The server doesn't restrict the data that can be inserted into integer columns
with explicitly specified length that's smaller than what the type can handle,
e.g. 1234 can be inserted into an INT(2) column just fine.
Thus, when calcualting the maximum width of expressions involving such
restricted integer columns we need to use the implicit maximum width of
the field instead of the explicitly speficied one.
Fixed the server to use the implicit maximum in such cases and made sure
the implicit maximum is addjusted the same way as the explicit one wrt
signedness.
Fixed several test case results (ctype_*.result, metadata.result and
type_ranges.result) to reflect the extended column widths.
Added a regression test case in distinct.test.
Note : this is the behavior preserving fix that makes 5.5 behave as 5.1 and
earlier. In the mysql trunk we'll add a insert time check for the explict
maximum size.
mysql-test/r/create.result:
test of renaming
mysql-test/r/upgrade.result:
Now such behaviour prohibited to avoid problems.
mysql-test/t/create.test:
test of renaming
mysql-test/t/upgrade.test:
Now such behaviour prohibited to avoid problems.
sql/mysql_priv.h:
Function to test table name presence added.
sql/sql_rename.cc:
Rename fixed.
sql/sql_table.cc:
Function to test table name presence added.
Create fixed.
mysql-test/r/dyncol.result:
Updated test results
mysql-test/r/index_intersect.result:
Updated results
mysql-test/r/index_intersect_innodb.result:
Updated results
mysql-test/t/dyncol.test:
Added replace_result for floating point results that are different on windows
Added round() around a result to get same result on all platforms.
mysql-test/t/index_intersect.test:
Added replace_result to fix that index_merge may put key names in different order.
mysys/ma_dyncol.c:
Fixed compiler warnings on Solaris
sql/key.cc:
Fixed compiler warnings on Solaris
sql/mysqld.cc:
Fixed compiler warning on windows
support-files/compiler_warnings.supp:
Suppressed an unintersting warning on Solaris
- add support for choosing the engine of test
table(t1) with $engine_type
- add primary key to the test table(t1) to support
replication of BLOB/TEXT (also with ENGINE=ndb)
- change the suppression since the warning printed to error log
now says "Column 1"
The problem was that connection con5, which is supposed to be the leader for
the third group, could if timing was bad end up as participant in the second
group, causing the test to fail.
Fixed by ensuring that group 2 is running before starting the transaction
for group 3.
Bugs fixed:
- Added automatic detection of unsigned arguments to COLUMN_CREATE()
- If string length is not know for COLUMN_GET() use MAX_DYNAMIC_COLUMN_LENGTH instead of MAX_FIELD_BLOBLENGTH
- null_value flag was not propery reset for COLUMN_LIST() and COLUMN_CREATE() which could lead to crashes later:
- lp:778905 Assertion `value->year <= 9999' failed in dynamic_column_date_store
- lp:778912 Assertion `field_pos < field_count' failed in Protocol_text::store in maria-5.3-mwl34
include/ma_dyncol.h:
Added define for max dynamic column length.
mysql-test/r/cast.result:
Added test of cast big unsigned int to signed (this test case was missing)
mysql-test/r/dyncol.result:
Added tests from reported bugs
Added testing of automatic store of signed/unsigned integers
mysql-test/t/cast.test:
Added test of cast big unsigned int to signed (this test case was missing)
mysql-test/t/dyncol.test:
Added tests from reported bugs
Added testing of automatic store of signed/unsigned integers
sql/item.cc:
Added assert to catch cases where null_value is not set properly
sql/item_strfunc.cc:
Added automatic detection of unsigned arguments to COLUMN_CREATE()
COLUMN_GET() returned wrong value for illegal strings which lead to assert later
null_value flag was not propery reset for COLUMN_LIST() and COLUMN_CREATE() which could lead to crashes later.
sql/item_strfunc.h:
If string length is not know for COLUMN_GET() use MAX_DYNAMIC_COLUMN_LENGTH
- In eliminate_item_equal(), we could end up in a situation where:
= The multiple equality has a constant C1 (and so it is the "head item")
= The join order was such that we've generated "sj_inner_table1=C1" equality,
and now are looking to generate "sj_inner_table2_=..." equality.
When looking for what should be the other member of equality, we run
Item *head_item= current_sjm? current_sjm_head: head;
which sees current_sjm!=NULL, and takes current_sjm_head (which is NULL because
the constant C1 is the head for all cases).
- Fixed in a trivial way: take current_sjm_head if we don't have constant.
IN WAIT_SHOW_CONDITION)
There was a typo in the name of one of the parameters to the
include file wait_show_condition. The parameter name was being
set to "connection" instead of "condition".
We fix this typo, improve one instruction in the test case and
deploy parameter checks inside wait_show_condition.inc.