- Changed ER(ER_...) to ER_THD(thd, ER_...) when thd was known or if there was many calls to current_thd in the same function.
- Changed ER(ER_..) to ER_THD_OR_DEFAULT(current_thd, ER...) in some places where current_thd is not necessary defined.
- Removing calls to current_thd when we have access to thd
Part of this is optimization (not calling current_thd when not needed),
but part is bug fixing for error condition when current_thd is not defined
(For example on startup and end of mysqld)
Notable renames done as otherwise a lot of functions would have to be changed:
- In JOIN structure renamed:
examined_rows -> join_examined_rows
record_count -> join_record_count
- In Field, renamed new_field() to make_new_field()
Other things:
- Added DBUG_ASSERT(thd == tmp_thd) in Item_singlerow_subselect() just to be safe.
- Removed old 'tab' prefix in JOIN_TAB::save_explain_data() and use members directly
- Added 'thd' as argument to a few functions to avoid calling current_thd.
This is MDEV-7601, including it's sub tasks MDEV-7594, MDEV-7555, MDEV-7590, MDEV-7581, MDEV-7589
The problem was that select_lex->non_agg_fields was not properly reset for re-execution and this caused an overwrite of a random memory position.
The fix was move non_agg_fields from select_lext to JOIN, which is properly reset.
Handle the case where the optimizer decides to use
handler->delete_all_rows(), but then this call returns
HA_ERR_UNSUPPORTED and execution switches to regular
row-by-row deletion.
To make st_select_lex::master_unit() inlinable:
- moved it's definition to sql_lex.h
- removed base class virtual master_unit() declaration since this method is
specific to st_select_lex
Overhead change:
st_select_lex::master_unit() 0.17% -> out of radar
execute_sqlcom_select() 0.13% -> 0.12%
JOIN::save_explain_data_intern() 0.27% -> 0.23%
JOIN::optimize_inner() 0.76% -> 0.72%
JOIN::exec_inner() 0.30% -> 0.24%
JOIN::prepare() 0.30% -> 0.29%
JOIN::optimize() 0.05% -> 0.05%
sql_alloc() has additional costs compared to direct mem_root allocation:
- function call: it is defined in a separate translation unit and can't be
inlined
- it needs to call pthread_getspecific() to get THD::mem_root
It is called dozens of times implicitely at least by:
- List<>::push_back()
- List<>::push_front()
- new (for Sql_alloc derived classes)
- sql_memdup()
Replaced lots of implicit sql_alloc() calls with direct mem_root allocation,
passing through THD pointer whenever it is needed.
Number of sql_alloc() calls reduced 345 -> 41 per OLTP RO transaction.
pthread_getspecific() overhead dropped 0.76 -> 0.59
sql_alloc() overhed dropped 0.25 -> 0.06
delete_dynamic() was called 9-11x per OLTP RO query + 3x per BEGIN/COMMIT.
3 calls were performed by LEX_MASTER_INFO. Added condition to call those only
for CHANGE MASTER.
1 call was performed by lock_table_names()/Hash_set/my_hash_free(). Hash_set was
supposed to be used for DDL and LOCK TABLES to gather database names, while it
was initialized/freed for DML too. In fact Hash_set didn't do any useful job
here. Hash_set was removed and MDL requests are now added directly to the list.
The rest 5-7 calls are done by optimizer, mostly by Explain_query and friends.
Since dynamic arrays are used in most cases, they can hardly be optimized.
my_hash_free() overhead dropped 0.02 -> out of radar.
delete_dynamic() overhead dropped 0.12 -> 0.04.
including the big commit
commit 305130361bf72726de220f3d2b2787395e10be61
Author: Marc Alff <marc.alff@oracle.com>
Date: Tue Feb 10 11:31:32 2015 +0100
WL#8354 BACKPORT DIGEST IMPROVEMENTS TO MYSQL 5.6
(with the following commits) and related changes in sql/
- Remove ANALYZE's timing code off the the execution path of regular
SELECTs.
- Improve the tracker that tracks counts/execution times of SELECTs or
DML statements:
= regular execution just increments counters
= ANALYZE will also collect timings.
MDEV-6218 Wrong result of CHAR_LENGTH(non-BMP-character) with 3-byte utf8
- Moving get_text() as a method to Lex_input_stream.
- Moving the unescaping part into a separate function,
this piece of code will later go to /strings most likely.
- Removing Lex_input_string::yytoklen, as it's not needed any more.
fixed embedded server tests
MDEV-7009: SET STATEMENT min_examined_row_limit has no effect
MDEV-6948:SET STATEMENT gtid_domain_id = ... FOR has no effect (same for gtid_seq_no and server_id)
old values of SET STATENENT variables now saved in its own Query_arena and restored later
length/dec/charset are still in LEX, because they're also used
for CAST and dynamic columns.
also
1. fix "MDEV-7041 COLLATION(CAST('a' AS CHAR BINARY)) returns a wrong result"
2. allow BINARY modifier in stored function RETURN clause
3. allow "COLLATION without CHARSET" in SP/SF (parameters, RETURN, DECLARE)
4. print correct variable name in error messages for stored routine parameters
* pass LEX_STRING's from the parser, don't ignore the length only to strlen later
* init LEX::server_options only for SERVER commands, not for every statement
* don't put temporary values into a global persistent memroot
but really it's just scratching a surface
When parsing a field declaration, grab type information from LEX before it's overwritten
by further rules. Pass type information through the parser stack to the rule that needs it.
~40% bugfixed(*) applied
~40$ bugfixed reverted (incorrect or we're not buggy)
~20% bugfixed applied, despite us being not buggy
(*) only changes in the server code, e.g. not cmakefiles
Backport of the fix:
: Bug 18017820: BISON 3 BREAKS MYSQL BUILD
: ========================================
:
: The source of the reported problem is a removal of a few deprecated
: things from Bison 3.x:
: * YYPARSE_PARAM macro (use the %parse-param bison directive instead),
: * YYLEX_PARAM macro (use %lex-param instead),
:
: The fix removes obsolete macro calls and introduces use of
: %parse-param and %lex-param directives.
Backport of the fix:
: Bug 18017820: BISON 3 BREAKS MYSQL BUILD
: ========================================
:
: The source of the reported problem is a removal of a few deprecated
: things from Bison 3.x:
: * YYPARSE_PARAM macro (use the %parse-param bison directive instead),
: * YYLEX_PARAM macro (use %lex-param instead),
:
: The fix removes obsolete macro calls and introduces use of
: %parse-param and %lex-param directives.
- First code, "EXPLAIN FORMAT=JSON stmt" and "ANALYZE FORMAT=JSON stmt"
work for basic queries. Complex constructs (e.g subqueries, etc) not
yet supported.
- No test infrastructure yet
MDEV-406: ANALYZE $stmt
- Ported the old patch to new explain code
- New SQL syntax (ANALYZE $stmt)
- ANALYZE UPDATE/DELETE is now supported (because EXPLAIN UPDATE/DELETE is supported)
- Basic counters are calculated for basic kinds of queries
(still need to see what happens with join buffer, ORDER BY...LIMIT queries, etc)
This is port of fix for MySQL BUG#17647863.
revno: 5572
revision-id: jon.hauglid@oracle.com-20131030232243-b0pw98oy72uka2sj
committer: Jon Olav Hauglid <jon.hauglid@oracle.com>
timestamp: Thu 2013-10-31 00:22:43 +0100
message:
Bug#17647863: MYSQL DOES NOT COMPILE ON OSX 10.9 GM
Rename test() macro to MY_TEST() to avoid conflict with libc++.
Materialization forced in case if rand() used in view or derived table to avoud several calls of rand for gting value of a field.
Fixed set variable uncachable flag from - it shouldbe a side effect not a random value.
mysql-test/r/acl_roles_show_grants.result:
one can do SHOW GRANTS for himself
mysql-test/t/acl_roles_set_role-table-column-priv.test:
correct error message
mysql-test/t/acl_roles_show_grants.test:
one can SHOW GRANTS for himself
sql/sql_acl.cc:
bugfixing:
* don't assign with && - it can shortcut and the second assignment won't be executed
* correct the test in check_grant_all_columns() - want_access should not be modified
*
sql/sql_cmd.h.OTHER:
add new commands at the end
sql/sql_db.cc:
don't call acl_get() if all privileges are already satisfied
(crashes when run with --skip-grants, because acl data stuctures aren't initialized)
sql/sql_parse.cc:
* test for current_user in get_current_user()
* map explicitly specified user@host to current_user
The output is not completely correct due to recursive role grants not
being completly implemented. However, this will help with testing the
implementation of set role with recursive grants.
- It turns out, there are statements that will call lex_start(thd->lex)
after parsing has been finished. lex_start() will set lex->explain=NULL,
which will lose the pointer to already allocated Explain_plan object.
- To get rid of this, switch to lazy creation of lex->explain. Now, it is
created only when we get a part ot query plan.
Update the SHOW EXPLAIN code to work with the
new architecture (part#1):
Before, SHOW EXPLAIN operated on real query plan structures,
which meant it had to check when SELECTs are created/deleted.
SELECTs would call apc_target->enable() when they got a query
plan and disable() when their query plan was deleted.
Now, Explain data structure becomes available at once (and we
call apc_target->enable()) and then it stays until it is deleted
(when that happens, we call apc_target->disable()).
- Generate correct contents of `Extra` column for UPDATEs/DELETEs that use quick selects
- UPDATEs with used_key_is_modified=true will show "Using buffer"
- YYPARSE_PARAM and YYLEX_PARAM are removed in Bison 3.0. Deprecated
since Bison 1.875 in favor of %lex-param, %parse-param.
- %parse-param adds an argument to yyerror() as well, updated
MYSQLerror() accordingly.
- %parse-param allows to declare proper type for argument. That's
what 99% of this patch is about.
includes:
* remove some remnants of "Bug#14521864: MYSQL 5.1 TO 5.5 BUGS PARTITIONING"
* introduce LOCK_share, now LOCK_ha_data is strictly for engines
* rea_create_table() always creates .par file (even in "frm-only" mode)
* fix a 5.6 bug, temp file leak on dummy ALTER TABLE
- Update view.result (old EXPLAIN didn't match the execution)
- Put in a stub code to work around the
SELECT ... UNION SELECT ... ORDER BY (subuqery) problem
LOAD DATA CAN CAUSE SQL INJECTION
Problem:
=======
A long SET expression in LOAD DATA is incorrectly truncated
when written to the binary log.
Analysis:
========
LOAD DATA statements are reconstructed once again before
they are written to the binary log. When SET clauses are
specified as part of LOAD DATA statement, these SET clause
user command strings need to be stored as it is inorder to
reconstruct the original user command. At present these
strings are stored as part of SET clause item tree's
top most Item node's name itself which is incorrect. As an
Item::name can be of MAX_ALIAS_NAME (256) size. Hence the
name will get truncated to "255".
Because of this the rewritten LOAD DATA statement will be
terminated incorrectly. When this statment is read back by
the mysqlbinlog tool it reads a starting single quote and
continuos to read till it finds an ending quote. Hence any
statement written post ending quote will be considered as
a new statement.
Fix:
===
As name field has length restriction the string value
should not be stored in Item::name. A new String list is
maintained to store the SET expression values and this list
is read during reconstrution.
sql/sql_lex.cc:
Clear the load data set string list during each query
execution.
sql/sql_lex.h:
Added a new String list to store the load data operation's
SET clause user command strings.
sql/sql_load.cc:
Read the SET clause user command strings from load data
set string list.
sql/sql_yacc.yy:
Store the SET caluse user command string as part of load
data set string list.
LOAD DATA CAN CAUSE SQL INJECTION
Problem:
=======
A long SET expression in LOAD DATA is incorrectly truncated
when written to the binary log.
Analysis:
========
LOAD DATA statements are reconstructed once again before
they are written to the binary log. When SET clauses are
specified as part of LOAD DATA statement, these SET clause
user command strings need to be stored as it is inorder to
reconstruct the original user command. At present these
strings are stored as part of SET clause item tree's
top most Item node's name itself which is incorrect. As an
Item::name can be of MAX_ALIAS_NAME (256) size. Hence the
name will get truncated to "255".
Because of this the rewritten LOAD DATA statement will be
terminated incorrectly. When this statment is read back by
the mysqlbinlog tool it reads a starting single quote and
continuos to read till it finds an ending quote. Hence any
statement written post ending quote will be considered as
a new statement.
Fix:
===
As name field has length restriction the string value
should not be stored in Item::name. A new String list is
maintained to store the SET expression values and this list
is read during reconstrution.
- Handle statements inside SPs:
= regular statements
= SET command, which does not have its own statement.
- Handle execution of subquery from range optimizer:
allocate subquery QPFs on the same MEM_ROOT as the whole
query plan was allocated.