sql/sql_insert.cc:
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
******
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
sql/sql_table.cc:
small cleanup
******
small cleanup
Amendment to previous patch:
Failure in CONV() should return NULL instead of
empty set.
When compiled on Windows or Solaris the function
Item_func_conv::val_str() doesn't fail on
longlong2str() but finds an earlier exit path
based on the attributes of the arguments.
This exit path returns NULL on failure and as a
consequence the original patch caused different
test results depending on the OS used.
Failure to check the return state of a longlong2str() call
caused a crash. This could happen if a user executed the sql
function CONV() with certain parameters.
The patch fixes the issue by checking that the returned pointer
isn't NULL.
mysql-test/r/type_float.result:
New test case.
mysql-test/t/type_float.test:
New test case.
sql/item_strfunc.cc:
There was a buffer over/under-run when inserting decimal point into an empty string.
The patch replaces the use of the POSIX I/O interfaces in mysys on Windows with
the Win32 API calls (CreateFile, WriteFile, etc). The Windows HANDLE for the open
file is stored in the my_file_info struct, along with a flag for append mode
(because the Windows API does not support opening files in append mode in all cases)
The default max open files has been increased to 16384 and can be increased further
by setting --max-open-files=<value> during the server start.
Noteworthy benefit of this patch is that it removes limits from the table_cache size -
allowing for more simultaneus users
A lot of small fixes and new test cases.
client/mysqlbinlog.cc:
Cast removed
client/mysqltest.cc:
Added missing DBUG_RETURN
include/my_pthread.h:
set_timespec_time_nsec() now only takes one argument
mysql-test/t/date_formats.test:
Remove --disable_ps_protocl as now also ps supports microseconds
mysys/my_uuid.c:
Changed to use my_interval_timer() instead of my_getsystime()
mysys/waiting_threads.c:
Changed to use my_hrtime()
sql/field.h:
Added bool special_const_compare() for fields that may convert values before compare (like year)
sql/field_conv.cc:
Added test to get optimal copying of identical temporal values.
sql/item.cc:
Return that item_int is equal if it's positive, even if unsigned flag is different.
Fixed Item_cache_str::save_in_field() to have identical null check as other similar functions
Added proper NULL check to Item_cache_int::save_in_field()
sql/item_cmpfunc.cc:
Don't call convert_constant_item() if there is nothing that is worth converting.
Simplified test when years should be converted
sql/item_sum.cc:
Mark cache values in Item_sum_hybrid as not constants to ensure they are not replaced by other cache values in compare_datetime()
sql/item_timefunc.cc:
Changed sec_to_time() to take a my_decimal argument to ensure we don't loose any sub seconds.
Added Item_temporal_func::get_time() (This simplifies some things)
sql/mysql_priv.h:
Added Lazy_string_decimal()
sql/mysqld.cc:
Added my_decimal constants max_seconds_for_time_type, time_second_part_factor
sql/table.cc:
Changed expr_arena to be of type CONVENTIONAL_EXECUTION to ensure that we don't loose any items that are created by fix_fields()
sql/tztime.cc:
TIME_to_gmt_sec() now sets *in_dst_time_gap in case of errors
This is needed to be able to detect if timestamp is 0
storage/maria/lockman.c:
Changed from my_getsystime() to set_timespec_time_nsec()
storage/maria/ma_loghandler.c:
Changed from my_getsystime() to my_hrtime()
storage/maria/ma_recovery.c:
Changed from my_getsystime() to mmicrosecond_interval_timer()
storage/maria/unittest/trnman-t.c:
Changed from my_getsystime() to mmicrosecond_interval_timer()
storage/xtradb/handler/ha_innodb.cc:
Added support for new time,datetime and timestamp
unittest/mysys/thr_template.c:
my_getsystime() -> my_interval_timer()
unittest/mysys/waiting_threads-t.c:
my_getsystime() -> my_interval_timer()
* my_getsystime() is only an interval timer. Its value can beused for calculating
time intervals.
* renamed my_getsystime() to my_interval_timer(), to make the semantics
clearer and let the compiler catch wrong usages of my_getsystime()
(also future ones, that may come in merges).
* increased its granularity from 100ns to 1ns, old value was for UUID,
but as UUID can no longer use it directly there is no need to downgrade
the OS provided value
* fixed the UUID code to anchor the my_interval_timer() on the epoch, as
required by the UUID standard. That is, this was only needed by UUID,
and now I've moved it to UUID code from my_getsystime().
* fixed other wrong usages of my_getsystime() - e.g. in calculating
times for pthread_cond_timedwait. It was buggy and could've caused
long waits if OS clock would be changed.
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"
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
- COLUMN_CREATE(column_nr, value, [column_nr,value]...)
- COLUMN_ADD(blob,column_nr, value, column_nr,value]...)
- COLUMN_DELETE(blob, column_nr, column_nr...)
- COLUMN_EXISTS(blob, column_nr)
- COLUMN_LIST(blob, column_nr)
- COLUMN_GET(string, column_nr AS type)
Added cast(X as DOUBLE) and cast(x as INT)
Better warning and error messages for wrong cast's
Created some sub functions to simplify and reuse code.
Added a lot of conversation functions with error/warnings for what went wrong.
Fixed some issues when casting time to datetime.
Added functions to dynamic strings and Strings to allow one to move a string buffer from dynamic strings to String (to save malloc+ copy)
Added dynamic columns library to libmysqlclient
include/Makefile.am:
Added ma_dyncol.h
include/decimal.h:
Added 'const' to arguments for some functions.
include/my_sys.h:
Added dynstr_reassociate()
include/my_time.h:
Added TIME_SUBSECOND_RANGE
Added double_to_datetime()
Added flag argument to str_to_time()
libmysql/CMakeLists.txt:
Added mysys/ma_dyncol.c
libmysql/Makefile.shared:
Added ma_dyncol
libmysql/libmysql.c:
Added argument to str_to_time()
mysql-test/r/bigint.result:
Better error messages
mysql-test/r/cast.result:
Better warning and error messages
A lot of new cast() tests
mysql-test/r/func_math.result:
Better warning messages
mysql-test/r/func_str.result:
Better warning messages
mysql-test/r/func_time.result:
Better warning messages
mysql-test/r/sp-vars.result:
Better warning messages
mysql-test/r/strict.result:
Better warning messages
New test result
mysql-test/r/type_newdecimal.result:
Better warning messages
mysql-test/r/warnings.result:
Better warning messages
mysql-test/suite/funcs_1/r/innodb_func_view.result:
Updated results after better cast warnings
mysql-test/suite/funcs_1/r/memory_func_view.result:
Updated results after better cast warnings
mysql-test/suite/funcs_1/r/myisam_func_view.result:
Updated results after better cast warnings
mysql-test/suite/optimizer_unfixed_bugs/t/bug43448.test:
Added begin...commit to speed up test.
mysql-test/suite/parts/inc/part_supported_sql_funcs_delete.inc:
Added begin...commit to speed up test.
mysql-test/suite/parts/inc/partition_supported_sql_funcs.inc:
Added begin...commit to speed up test.
mysql-test/suite/parts/r/part_supported_sql_func_innodb.result:
Added begin...commit to speed up test.
mysql-test/suite/parts/r/part_supported_sql_func_myisam.result:
Added begin...commit to speed up test.
mysql-test/suite/parts/r/rpl_partition.result:
Added begin...commit to speed up test.
mysql-test/suite/parts/t/part_supported_sql_func_innodb.test:
Removed duplicated --big_test
mysql-test/suite/parts/t/rpl_partition.test:
Added begin...commit to speed up test.
mysql-test/suite/pbxt/r/cast.result:
Updated results after better cast warnings
mysql-test/suite/pbxt/r/func_str.result:
Updated results after better cast warnings
mysql-test/suite/pbxt/r/type_newdecimal.result:
Updated results after better cast warnings
mysql-test/suite/rpl/r/rpl_innodb_bug28430.result:
Added begin...commit to speed up test.
mysql-test/suite/rpl/t/rpl_innodb_bug28430.test:
Added begin...commit to speed up test.
mysql-test/suite/vcol/r/vcol_supported_sql_funcs_innodb.result:
More warnings
mysql-test/suite/vcol/r/vcol_supported_sql_funcs_myisam.result:
More warnings
mysql-test/t/cast.test:
A lot of new cast() tests
mysql-test/t/strict.test:
Added new test
mysys/CMakeLists.txt:
Added ma_dyncol.c
mysys/Makefile.am:
Added ma_dyncol.c
mysys/string.c:
Added dynstr_reassociate() to move a buffer from dynamic_strings to some other allocator
sql-common/my_time.c:
Added 'fuzzydate' flag to str_to_time()
Added support for microseconds to my_time_to_str() and my_datetime_to_str()
Reset second_parts in number_to_datetime()
Added double_to_datetime()
sql/field.cc:
Added double_to_longlong() and truncate_double() to simplify and reuse code
sql/field.h:
New prototypes
sql/item.cc:
Changed Item::get_date(MYSQL_TIME *ltime,uint fuzzydate) to be aware of type of argument.
(Needed to make it microsecond safe and get better warnings).
Updated call to str_to_time_with_warn()
sql/item.h:
Added struct st_dyncall_create_def used by dynamic columns
Added virtual bool dynamic_result() to tell if type of argument may change over calls.
sql/item_cmpfunc.cc:
Added Item_func_dyncol_exists()
sql/item_cmpfunc.h:
Added class Item_func_dyncol_exists
sql/item_create.cc:
Added get_length_and_scale() to simplify other functions
Simplified and extended create_func_cast()
Added support for cast(X as double(X,Y))
Added functions to create dynamic column functions.
sql/item_create.h:
Added prototypes
sql/item_func.cc:
Extended cast functions Item_func_signed() and Item_func_unsigned() to work with dynamic types
Added Item_double_typecast()
sql/item_func.h:
Added class Item_double_typecast()
sql/item_strfunc.cc:
Added functions for COLUMN_CREATE(), COLUMN_ADD(), COLUMN_GET() and COLUMN_LIST()
sql/item_strfunc.h:
Added classes for COLUMN_CREATE(), COLUMN_ADD(), COLUMN_GET() and COLUMN_LIST()
sql/item_timefunc.cc:
Added flag argument to str_to_time_with_warn()
Updated Item_char_typecast() to handle result type that may change between calls (for dynamic columns)
Added Item_time_typecast::get_date() to ensure that we cast a datetime to time properly.
sql/item_timefunc.h:
Added get_date() to Item_time_typecast() to allow proper results for casting time to datetime
sql/lex.h:
Added new SQL function names
sql/my_decimal.cc:
Added 'const' to some arguments.
Better error message in case of errors (we now print out the wrong value)
Added my_decimal2int()
sql/my_decimal.h:
Moved some constants to my_decimal_limits.h
Updated prototypes.
Made my_decimal2int() a function as it's rather long (no reason to have it inline)
Added decimal2my_decimal() function.
sql/mysql_priv.h:
Prototypes for new functions
sql/share/errmsg.txt:
New error messages for wrong casts and dynamic columns
sql/sql_acl.cc:
Fixed indentation
sql/sql_base.cc:
Added dynamic_column_error_message()
sql/sql_string.h:
Added reassociate() to move a buffer to be owned by String object.
sql/sql_yacc.yy:
Added syntax for COLUMN_ functions.
sql/time.cc:
Updated str_to_datetime_with_warn() flag argument to same type as other functions
Added conversion flag to str_to_time_with_warn() (Similar to all datetime functions)
Added conversion functions with warnings: double_to_datetime_with_warn() and decimal_to_datetime_with_warn()
strings/decimal.c:
Added 'const' to arguments for some functions.
unittest/mysys/Makefile.am:
Added test for dynamic columns code
(SUBSTRING inside a stored function works too slow).
Background:
- THD classes derives from Query_arena, thus inherits the 'state'
attribute and related operations (is_stmt_prepare() & co).
- Although these operations are available in THD, they must not
be used. THD has its own attribute to point to the active
Query_arena -- stmt_arena.
- So, instead of using thd->is_stmt_prepare(),
thd->stmt_arena->is_stmt_prepare() must be used. This was the root
cause of Bug 60025.
This patch enforces the proper way of calling those operations.
is_stmt_prepare() & co are declared as private operations
in THD (thus, they are hidden from being called on THD instance).
The patch tries to minimize changes in 5.5.
Problem: comparison of a DATETIME sp variable and NOW()
led to Illegal mix of collations error when
character_set_connection=utf8.
Introduced by "WL#2649 Number-to-string conversions".
Error happened in Arg_comparator::set_compare_func(),
because the first argument was errouneously converted to utf8,
while the second argument was not.
Fix: separate agg_arg_charsets_for_comparison() into two functions:
- agg_arg_charsets_for_comparison() - for pure comparison,
when we don't need to return any string result and therefore
don't need to convert arguments to @@character_set_connection:
SELECT a = b;
- agg_arg_charsets_for_string_results_with_comparison() - when
we need to return a string result, but we also need to do
comparison internally: SELECT REPLACE(a,b,c)
If all arguments are numbers:
SELECT REPLACE(123,2,3) -> 133
we convert arguments to @@character_set_connection.
@ mysql-test/include/ctype_numconv.inc
@ mysql-test/r/ctype_binary.result
@ mysql-test/r/ctype_cp1251.result
@ mysql-test/r/ctype_latin1.result
@ mysql-test/r/ctype_ucs.result
@ mysql-test/r/ctype_utf8.result
Adding tests
@ sql/item.cc
@ sql/item.h
@ sql/item_func.cc
@ sql/item_func.h
@ sql/item_strfunc.cc
Introducing and using new function
agg_item_charsets_for_string_result_with_comparison() and
its Item_func wrapper agg_arg_charsets_for_string_result_with_comparison().
Analysis:
A query with implicit grouping is one with aggregate functions and
no GROUP BY clause. MariaDB inherits from MySQL an SQL extenstion
that allows mixing aggregate functions with non-aggregate fields.
If a query with such mixed select clause produces an empty result
set, the meaning of aggregate functions is well defined - either
NULL (MIN, MAX, etc.), or 0 (count(*)). However the non-aggregated
fields must also have some value, and the only reasonable value in
the case of empty result is NULL.
The cause of the many wrong results was that if a field is declared
as non-nullable (e.g. because it is a PK or NOT NULL), the semantic
analysis and the optimization phases treat this field as non-nullable,
and generate all related query plan elements based on this assumption.
Later during execution, these incorrectly configured/generated query
plan elements result in a wrong result because the selected fields
are not null due to the not-null assumption during optimization.
Solution:
Detect before the context analysys phase that a query uses implicit
grouping with mixed aggregates/non-aggregates, and set all fields
as nullable. The parser already walks the SELECT clause, and
already sets Item::with_sum_func for Items that reference aggreagate
functions. The patch adds a symmetric Item::with_field so that all
Items that reference an Item_field are marked during their
construction at parse time in the same way as with aggregate function
use.
Part 2. Function QUOTE() was not multi-byte safe.
@ mysql-test/r/ctype_ucs.result
@ mysql-test/t/ctype_ucs.test
Adding tests
@ sql/item_strfunc.cc
Fixing Item_func_quote::val_str to be multi-byte safe.
@ sql/item_strfunc.h
Multiple size needed for quote characters to mbmaxlen
Problem: wrong character set pointer was passed to my_strtoll10_mb2,
which led to DBUG_ASSERT failure in some cases.
@ mysql-test/r/func_encrypt_ucs2.result
@ mysql-test/t/func_encrypt_ucs2.test
@ mysql-test/r/ctype_ucs.result
@ mysql-test/t/ctype_ucs.test
Adding tests
@ sql/item_func.cc
"cs" initialization was wrong (res does not necessarily point to &str_value)
@ sql/item_strfunc.cc
Item_func_dec_encrypt::val_str() and Item_func_des_descrypt::val_str()
did not set character set for tmp_value (the returned value),
so the old value, which was previously copied from args[1]->val_str(),
was incorrectly returned with tmp_value.
- Fixed some issues with partitions and connection_string, which also fixed lp:716890 "Pre- and post-recovery crash in Aria"
- Fixed wrong assert in Aria
Now need to merge with latest xtradb before pushing
sql/ha_partition.cc:
Ensure that m_ordered_rec_buffer is not freed before close.
sql/mysqld.cc:
Changed to use opt_stack_trace instead of opt_pstack.
Removed references to pstack
sql/partition_element.h:
Ensure that connect_string is initialized
storage/maria/ma_key_recover.c:
Fixed wrong assert
Introduced by the fix for bug#44766.
Problem: it's not correct to use args[0]->str_value as a buffer,
because args[0] may need this buffer for its own purposes.
Fix: adding a new class member tmp_value to use as return value.
@ mysql-test/r/ctype_many.result
@ mysql-test/t/ctype_many.test
Adding tests
@ sql/item_strfunc.cc
Changing code into traditional style:
use "str" as a buffer for the argument and tmp_value for the result value.
@ sql/item_strfunc.h
Adding tmp_value
other crashes
Some string manipulating SQL functions use a shared string object intended to
contain an immutable empty string. This object was used by the SQL function
SUBSTRING_INDEX() to return an empty string when one argument was of the wrong
datatype. If the string object was then modified by the sql function INSERT(),
undefined behavior ensued.
Fixed by instead modifying the string object representing the function's
result value whenever string manipulating SQL functions return an empty
string.
Relevant code has also been documented.
Problem: DATE_ADD() is a hybrid function and can return
DATE, DATETIME or VARCHAR data type depending on arguments.
In case of VARCHAR data type, DATE_ADD() reported "binary" character set,
which was wrong.
Fix: make DATE_ADD() return @character_set_connection in VARCHAR context.
@ mysql-test/include/ctype_numconv.inc
Adding tests
@ mysql-test/r/ctype_binary.result
Adding tests
@ mysql-test/r/ctype_cp1251.result
Adding tests
@ mysql-test/r/ctype_latin1.result
Adding tests
@ mysql-test/r/ctype_ucs.result
Adding tests
@ mysql-test/r/ctype_utf8.result
Adding tests
@ sql/item_strfunc.cc
- Moving code from Item_str_ascii_func::val_str() to
Item_str_func::val_str_from_val_str_ascii(), as
this code needs to be shared by Item_date_add_interval.
- Adding str2 parameter to be used as a buffer, instead of
using private ascii_buf member.
@ sql/item_strfunc.h
- Moving code from Item_str_ascii_func::val_str() to
Item_str_func::val_str_from_val_str_ascii()
- Removing "String *val_str_convert_from_ascii(String *str, String *ascii_buf)"
prototype as it was neither used nor declared.
@ sql/item_timefunc.h
- Overwriting parent's charset_for_protocol() method,
becase we need to behave differenlty in VARCHAR and DATE/DATETYPE context.
- Adding ascii_buf for conversion.
- Adding val_str_ascii() prototype.
- Adding val_str() which uses newly added
Item_str_func::val_str_from_val_str_ascii(),
passing ascii_buf as a conversion buffer.