2002-05-12 22:46:42 +02:00
|
|
|
/* Copyright (C) 2000 MySQL AB
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2006-12-23 20:17:15 +01:00
|
|
|
the Free Software Foundation; version 2 of the License.
|
2002-05-12 22:46:42 +02:00
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
@file
|
|
|
|
|
|
|
|
@brief
|
|
|
|
subselect Item
|
2002-05-12 22:46:42 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@todo
|
|
|
|
- add function from mysql_select that use JOIN* as parameter to JOIN
|
|
|
|
methods (sql_select.h/sql_select.cc)
|
2002-05-12 22:46:42 +02:00
|
|
|
*/
|
|
|
|
|
2005-05-26 12:09:14 +02:00
|
|
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
2002-05-12 22:46:42 +02:00
|
|
|
#pragma implementation // gcc: Class implementation
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "mysql_priv.h"
|
|
|
|
#include "sql_select.h"
|
|
|
|
|
2002-12-28 00:01:05 +01:00
|
|
|
|
2002-10-08 22:49:59 +02:00
|
|
|
Item_subselect::Item_subselect():
|
2004-02-08 19:14:13 +01:00
|
|
|
Item_result_field(), value_assigned(0), thd(0), substitution(0),
|
|
|
|
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
|
2010-03-20 13:01:47 +01:00
|
|
|
const_item_cache(1),
|
|
|
|
inside_first_fix_fields(0), done_first_fix_fields(FALSE),
|
|
|
|
eliminated(FALSE),
|
2010-02-12 00:59:58 +01:00
|
|
|
engine_changed(0), changed(0), is_correlated(FALSE)
|
2002-05-12 22:46:42 +02:00
|
|
|
{
|
2006-05-17 22:55:28 +02:00
|
|
|
with_subselect= 1;
|
2002-12-06 20:55:53 +01:00
|
|
|
reset();
|
2002-10-08 22:49:59 +02:00
|
|
|
/*
|
2010-01-28 14:48:33 +01:00
|
|
|
Item value is NULL if select_result_interceptor didn't change this value
|
2002-10-08 22:49:59 +02:00
|
|
|
(i.e. some rows will be found returned)
|
|
|
|
*/
|
|
|
|
null_value= 1;
|
|
|
|
}
|
|
|
|
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2003-10-02 21:19:41 +02:00
|
|
|
void Item_subselect::init(st_select_lex *select_lex,
|
2010-01-28 14:48:33 +01:00
|
|
|
select_result_interceptor *result)
|
2002-10-08 22:49:59 +02:00
|
|
|
{
|
Bug#21904 (parser problem when using IN with a double "(())")
Before this fix, a IN predicate of the form: "IN (( subselect ))", with two
parenthesis, would be evaluated as a single row subselect: if the subselect
returns more that 1 row, the statement would fail.
The SQL:2003 standard defines a special exception in the specification,
and mandates that this particular form of IN predicate shall be equivalent
to "IN ( subselect )", which involves a table subquery and works with more
than 1 row.
This fix implements "IN (( subselect ))", "IN ((( subselect )))" etc
as per the SQL:2003 requirement.
All the details related to the implementation of this change have been
commented in the code, and the relevant sections of the SQL:2003 spec
are given for reference, so they are not repeated here.
Having access to the spec is a requirement to review in depth this patch.
mysql-test/r/subselect.result:
Implement IN predicate special exceptions with subselects.
mysql-test/t/subselect.test:
Implement IN predicate special exceptions with subselects.
sql/item_subselect.cc:
Implement IN predicate special exceptions with subselects.
sql/item_subselect.h:
Implement IN predicate special exceptions with subselects.
sql/sql_yacc.yy:
Implement IN predicate special exceptions with subselects, cleanup.
2007-01-30 01:32:52 +01:00
|
|
|
/*
|
|
|
|
Please see Item_singlerow_subselect::invalidate_and_restore_select_lex(),
|
|
|
|
which depends on alterations to the parse tree implemented here.
|
|
|
|
*/
|
2002-10-08 22:49:59 +02:00
|
|
|
|
|
|
|
DBUG_ENTER("Item_subselect::init");
|
2006-11-20 21:42:06 +01:00
|
|
|
DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
|
2004-02-08 19:14:13 +01:00
|
|
|
unit= select_lex->master_unit();
|
2010-09-05 17:43:47 +02:00
|
|
|
thd= unit->thd;
|
|
|
|
is_min_max_optimized= FALSE;
|
2004-05-07 22:06:11 +02:00
|
|
|
if (unit->item)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Item can be changed in JOIN::prepare while engine in JOIN::optimize
|
|
|
|
=> we do not copy old_engine here
|
|
|
|
*/
|
|
|
|
engine= unit->item->engine;
|
2004-08-13 09:01:30 +02:00
|
|
|
parsing_place= unit->item->parsing_place;
|
2004-05-07 22:06:11 +02:00
|
|
|
unit->item->engine= 0;
|
|
|
|
unit->item= this;
|
2004-10-20 03:04:37 +02:00
|
|
|
engine->change_result(this, result);
|
2004-05-07 22:06:11 +02:00
|
|
|
}
|
2002-09-03 08:50:36 +02:00
|
|
|
else
|
2004-05-07 22:06:11 +02:00
|
|
|
{
|
2004-08-23 21:31:01 +02:00
|
|
|
SELECT_LEX *outer_select= unit->outer_select();
|
|
|
|
/*
|
|
|
|
do not take into account expression inside aggregate functions because
|
|
|
|
they can access original table fields
|
|
|
|
*/
|
|
|
|
parsing_place= (outer_select->in_sum_expr ?
|
|
|
|
NO_MATTER :
|
|
|
|
outer_select->parsing_place);
|
2007-04-23 13:16:49 +02:00
|
|
|
if (unit->is_union())
|
2004-05-07 22:06:11 +02:00
|
|
|
engine= new subselect_union_engine(unit, result, this);
|
|
|
|
else
|
|
|
|
engine= new subselect_single_select_engine(select_lex, result, this);
|
|
|
|
}
|
2004-06-09 22:32:20 +02:00
|
|
|
{
|
|
|
|
SELECT_LEX *upper= unit->outer_select();
|
2004-08-13 09:01:30 +02:00
|
|
|
if (upper->parsing_place == IN_HAVING)
|
2004-06-09 22:32:20 +02:00
|
|
|
upper->subquery_in_having= 1;
|
2010-07-10 12:37:30 +02:00
|
|
|
/* The subquery is an expression cache candidate */
|
|
|
|
upper->expr_cache_may_be_used[upper->parsing_place]= TRUE;
|
2004-06-09 22:32:20 +02:00
|
|
|
}
|
2002-05-12 22:46:42 +02:00
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
Bug#21904 (parser problem when using IN with a double "(())")
Before this fix, a IN predicate of the form: "IN (( subselect ))", with two
parenthesis, would be evaluated as a single row subselect: if the subselect
returns more that 1 row, the statement would fail.
The SQL:2003 standard defines a special exception in the specification,
and mandates that this particular form of IN predicate shall be equivalent
to "IN ( subselect )", which involves a table subquery and works with more
than 1 row.
This fix implements "IN (( subselect ))", "IN ((( subselect )))" etc
as per the SQL:2003 requirement.
All the details related to the implementation of this change have been
commented in the code, and the relevant sections of the SQL:2003 spec
are given for reference, so they are not repeated here.
Having access to the spec is a requirement to review in depth this patch.
mysql-test/r/subselect.result:
Implement IN predicate special exceptions with subselects.
mysql-test/t/subselect.test:
Implement IN predicate special exceptions with subselects.
sql/item_subselect.cc:
Implement IN predicate special exceptions with subselects.
sql/item_subselect.h:
Implement IN predicate special exceptions with subselects.
sql/sql_yacc.yy:
Implement IN predicate special exceptions with subselects, cleanup.
2007-01-30 01:32:52 +01:00
|
|
|
st_select_lex *
|
|
|
|
Item_subselect::get_select_lex()
|
|
|
|
{
|
|
|
|
return unit->first_select();
|
|
|
|
}
|
|
|
|
|
2003-12-30 11:08:19 +01:00
|
|
|
void Item_subselect::cleanup()
|
|
|
|
{
|
2004-02-08 19:14:13 +01:00
|
|
|
DBUG_ENTER("Item_subselect::cleanup");
|
2003-12-30 11:08:19 +01:00
|
|
|
Item_result_field::cleanup();
|
2004-02-08 19:14:13 +01:00
|
|
|
if (old_engine)
|
|
|
|
{
|
2004-05-07 22:06:11 +02:00
|
|
|
if (engine)
|
|
|
|
engine->cleanup();
|
2004-02-08 19:14:13 +01:00
|
|
|
engine= old_engine;
|
|
|
|
old_engine= 0;
|
|
|
|
}
|
2004-05-07 22:06:11 +02:00
|
|
|
if (engine)
|
|
|
|
engine->cleanup();
|
2010-07-10 12:37:30 +02:00
|
|
|
depends_on.empty();
|
2004-02-08 19:14:13 +01:00
|
|
|
reset();
|
|
|
|
value_assigned= 0;
|
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
2010-04-06 09:26:59 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
We cannot use generic Item::safe_charset_converter() because
|
|
|
|
Subselect transformation does not happen in view_prepare_mode
|
|
|
|
and thus we can not evaluate val_...() for const items.
|
|
|
|
*/
|
|
|
|
|
|
|
|
Item *Item_subselect::safe_charset_converter(CHARSET_INFO *tocs)
|
|
|
|
{
|
|
|
|
Item_func_conv_charset *conv=
|
|
|
|
new Item_func_conv_charset(this, tocs, thd->lex->view_prepare_mode ? 0 : 1);
|
|
|
|
return conv->safe ? conv : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-08 19:14:13 +01:00
|
|
|
void Item_singlerow_subselect::cleanup()
|
|
|
|
{
|
|
|
|
DBUG_ENTER("Item_singlerow_subselect::cleanup");
|
|
|
|
value= 0; row= 0;
|
|
|
|
Item_subselect::cleanup();
|
|
|
|
DBUG_VOID_RETURN;
|
2003-12-30 11:08:19 +01:00
|
|
|
}
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
|
|
|
|
void Item_in_subselect::cleanup()
|
|
|
|
{
|
|
|
|
DBUG_ENTER("Item_in_subselect::cleanup");
|
|
|
|
if (left_expr_cache)
|
|
|
|
{
|
|
|
|
left_expr_cache->delete_elements();
|
|
|
|
delete left_expr_cache;
|
|
|
|
left_expr_cache= NULL;
|
|
|
|
}
|
|
|
|
first_execution= TRUE;
|
2010-02-19 22:55:57 +01:00
|
|
|
is_constant= FALSE;
|
2010-09-05 17:43:47 +02:00
|
|
|
if (exec_method == MATERIALIZATION)
|
|
|
|
exec_method= NOT_TRANSFORMED;
|
|
|
|
pushed_cond_guards= NULL;
|
2010-01-28 14:48:33 +01:00
|
|
|
Item_subselect::cleanup();
|
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
2002-09-03 08:50:36 +02:00
|
|
|
Item_subselect::~Item_subselect()
|
|
|
|
{
|
2003-10-27 00:01:27 +01:00
|
|
|
delete engine;
|
2010-07-16 12:52:02 +02:00
|
|
|
engine= NULL;
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
|
|
|
|
2003-05-14 20:51:33 +02:00
|
|
|
Item_subselect::trans_res
|
2004-07-04 07:46:28 +02:00
|
|
|
Item_subselect::select_transformer(JOIN *join)
|
2002-10-27 22:27:00 +01:00
|
|
|
{
|
|
|
|
DBUG_ENTER("Item_subselect::select_transformer");
|
2003-08-28 12:21:30 +02:00
|
|
|
DBUG_RETURN(RES_OK);
|
2002-10-27 22:27:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-01 06:05:42 +02:00
|
|
|
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
|
2002-05-12 22:46:42 +02:00
|
|
|
{
|
2004-09-06 14:14:10 +02:00
|
|
|
char const *save_where= thd_param->where;
|
Table definition cache, part 2
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
Other noteworthy changes:
- In TABLE_SHARE the most common strings are now LEX_STRING's
- Better error message when table is not found
- Variable table_cache is now renamed 'table_open_cache'
- New variable 'table_definition_cache' that is the number of table defintions that will be cached
- strxnmov() calls are now fixed to avoid overflows
- strxnmov() will now always add one end \0 to result
- engine objects are now created with a TABLE_SHARE object instead of a TABLE object.
- After creating a field object one must call field->init(table) before using it
- For a busy system this change will give you:
- Less memory usage for table object
- Faster opening of tables (if it's has been in use or is in table definition cache)
- Allow you to cache many table definitions objects
- Faster drop of table
mysql-test/mysql-test-run.sh:
Fixed some problems with --gdb option
Test both with socket and tcp/ip port that all old servers are killed
mysql-test/r/flush_table.result:
More tests with lock table with 2 threads + flush table
mysql-test/r/information_schema.result:
Removed old (now wrong) result
mysql-test/r/innodb.result:
Better error messages (thanks to TDC patch)
mysql-test/r/merge.result:
Extra flush table test
mysql-test/r/ndb_bitfield.result:
Better error messages (thanks to TDC patch)
mysql-test/r/ndb_partition_error.result:
Better error messages (thanks to TDC patch)
mysql-test/r/query_cache.result:
Remove tables left from old tests
mysql-test/r/temp_table.result:
Test truncate with temporary tables
mysql-test/r/variables.result:
Table_cache -> Table_open_cache
mysql-test/t/flush_table.test:
More tests with lock table with 2 threads + flush table
mysql-test/t/merge.test:
Extra flush table test
mysql-test/t/multi_update.test:
Added 'sleep' to make test predictable
mysql-test/t/query_cache.test:
Remove tables left from old tests
mysql-test/t/temp_table.test:
Test truncate with temporary tables
mysql-test/t/variables.test:
Table_cache -> Table_open_cache
mysql-test/valgrind.supp:
Remove warning that may happens becasue threads dies in different order
mysys/hash.c:
Fixed wrong DBUG_PRINT
mysys/mf_dirname.c:
More DBUG
mysys/mf_pack.c:
Better comment
mysys/mf_tempdir.c:
More DBUG
Ensure that we call cleanup_dirname() on all temporary directory paths.
If we don't do this, we will get a failure when comparing temporary table
names as in some cases the temporary table name is run through convert_dirname())
mysys/my_alloc.c:
Indentation fix
sql/examples/ha_example.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_example.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/field.cc:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Use s->db instead of s->table_cache_key
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/field.h:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/ha_archive.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_archive.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_berkeley.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Changed name of argument create() to not hide internal 'table' variable.
table->s -> table_share
sql/ha_berkeley.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_federated.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed comments
Remove index variable and replace with pointers (simple optimization)
move_field() -> move_field_offset()
Removed some strlen() calls
sql/ha_federated.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_heap.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Simplify delete_table() and create() as the given file names are now without extension
sql/ha_heap.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisam.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Remove not needed fn_format()
Fixed for new table->s structure
sql/ha_myisam.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisammrg.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Don't set 'is_view' for MERGE tables
Use new interface to find_temporary_table()
sql/ha_myisammrg.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Added flag HA_NO_COPY_ON_ALTER
sql/ha_ndbcluster.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed wrong calls to strxnmov()
Give error HA_ERR_TABLE_DEF_CHANGED if table definition has changed
drop_table -> intern_drop_table()
table->s -> table_share
Move part_info to TABLE
Fixed comments & DBUG print's
New arguments to print_error()
sql/ha_ndbcluster.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_partition.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
We can't set up or use part_info when creating handler as there is not yet any table object
New ha_intialise() to work with TDC (Done by Mikael)
sql/ha_partition.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Got set_part_info() from Mikael
sql/handler.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
ha_delete_table() now also takes database as an argument
handler::ha_open() now takes TABLE as argument
ha_open() now calls ha_allocate_read_write_set()
Simplify ha_allocate_read_write_set()
Remove ha_deallocate_read_write_set()
Use table_share (Cached by table definition cache)
sql/handler.h:
New table flag: HA_NO_COPY_ON_ALTER (used by merge tables)
Remove ha_deallocate_read_write_set()
get_new_handler() now takes TABLE_SHARE as argument
ha_delete_table() now gets database as argument
sql/item.cc:
table_name and db are now LEX_STRING objects
When creating fields, we have now have to call field->init(table)
move_field -> move_field_offset()
sql/item.h:
tmp_table_field_from_field_type() now takes an extra paramenter 'fixed_length' to allow one to force usage of CHAR
instead of BLOB
sql/item_cmpfunc.cc:
Fixed call to tmp_table_field_from_field_type()
sql/item_create.cc:
Assert if new not handled cast type
sql/item_func.cc:
When creating fields, we have now have to call field->init(table)
dummy_table used by 'sp' now needs a TABLE_SHARE object
sql/item_subselect.cc:
Trivial code cleanups
sql/item_sum.cc:
When creating fields, we have now have to call field->init(table)
sql/item_timefunc.cc:
Item_func_str_to_date::tmp_table_field() now replaced by call to
tmp_table_field_from_field_type() (see item_timefunc.h)
sql/item_timefunc.h:
Simply tmp_table_field()
sql/item_uniq.cc:
When creating fields, we have now have to call field->init(table)
sql/key.cc:
Added 'KEY' argument to 'find_ref_key' to simplify code
sql/lock.cc:
More debugging
Use create_table_def_key() to create key for table cache
Allocate TABLE_SHARE properly when creating name lock
Fix that locked_table_name doesn't test same table twice
sql/mysql_priv.h:
New functions for table definition cache
New interfaces to a lot of functions.
New faster interface to find_temporary_table() and close_temporary_table()
sql/mysqld.cc:
Added support for table definition cache of size 'table_def_size'
Fixed som calls to strnmov()
Changed name of 'table_cache' to 'table_open_cache'
sql/opt_range.cc:
Use new interfaces
Fixed warnings from valgrind
sql/parse_file.cc:
Safer calls to strxnmov()
Fixed typo
sql/set_var.cc:
Added variable 'table_definition_cache'
Variable table_cache renamed to 'table_open_cache'
sql/slave.cc:
Use new interface
sql/sp.cc:
Proper use of TABLE_SHARE
sql/sp_head.cc:
Remove compiler warnings
We have now to call field->init(table)
sql/sp_head.h:
Pointers to parsed strings are now const
sql/sql_acl.cc:
table_name is now a LEX_STRING
sql/sql_base.cc:
Main implementation of table definition cache
(The #ifdef's are there for the future when table definition cache will replace open table cache)
Now table definitions are cached indepndent of open tables, which will speed up things when a table is in use at once from several places
Views are not yet cached; For the moment we only cache if a table is a view or not.
Faster implementation of find_temorary_table()
Replace 'wait_for_refresh()' with the more general function 'wait_for_condition()'
Drop table is slightly faster as we can use the table definition cache to know the type of the table
sql/sql_cache.cc:
table_cache_key and table_name are now LEX_STRING
'sDBUG print fixes
sql/sql_class.cc:
table_cache_key is now a LEX_STRING
safer strxnmov()
sql/sql_class.h:
Added number of open table shares (table definitions)
sql/sql_db.cc:
safer strxnmov()
sql/sql_delete.cc:
Use new interface to find_temporary_table()
sql/sql_derived.cc:
table_name is now a LEX_STRING
sql/sql_handler.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_insert.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_lex.cc:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_lex.h:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_load.cc:
Safer strxnmov()
sql/sql_parse.cc:
Better error if wrong DB name
sql/sql_partition.cc:
part_info moved to TABLE from TABLE_SHARE
Indentation changes
sql/sql_select.cc:
Indentation fixes
Call field->init(TABLE) for new created fields
Update create_tmp_table() to use TABLE_SHARE properly
sql/sql_select.h:
Call field->init(TABLE) for new created fields
sql/sql_show.cc:
table_name is now a LEX_STRING
part_info moved to TABLE
sql/sql_table.cc:
Use table definition cache to speed up delete of tables
Fixed calls to functions with new interfaces
Don't use 'share_not_to_be_used'
Instead of doing openfrm() when doing repair, we now have to call
get_table_share() followed by open_table_from_share().
Replace some fn_format() with faster unpack_filename().
Safer strxnmov()
part_info is now in TABLE
Added Mikaels patch for partition and ALTER TABLE
Instead of using 'TABLE_SHARE->is_view' use 'table_flags() & HA_NO_COPY_ON_ALTER
sql/sql_test.cc:
table_name and table_cache_key are now LEX_STRING's
sql/sql_trigger.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
safer strxnmov()
Removed compiler warnings
sql/sql_update.cc:
Call field->init(TABLE) after field is created
sql/sql_view.cc:
safer strxnmov()
Create common TABLE_SHARE object for views to allow us to cache if table is a view
sql/structs.h:
Added SHOW_TABLE_DEFINITIONS
sql/table.cc:
Creation and destruct of TABLE_SHARE objects that are common for many TABLE objects
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
open_table_def() is written in such a way that it should be trival to add parsing of the .frm files in new formats
sql/table.h:
TABLE objects for the same database table now share a common TABLE_SHARE object
In TABLE_SHARE the most common strings are now LEX_STRING's
sql/unireg.cc:
Changed arguments to rea_create_table() to have same order as other functions
Call field->init(table) for new created fields
sql/unireg.h:
Added OPEN_VIEW
strings/strxnmov.c:
Change strxnmov() to always add end \0
This makes usage of strxnmov() safer as most of MySQL code assumes that strxnmov() will create a null terminated string
2005-11-23 21:45:02 +01:00
|
|
|
uint8 uncacheable;
|
2004-10-20 03:04:37 +02:00
|
|
|
bool res;
|
2004-09-06 14:14:10 +02:00
|
|
|
|
2004-03-17 13:26:26 +01:00
|
|
|
DBUG_ASSERT(fixed == 0);
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_ASSERT(thd == thd_param);
|
|
|
|
engine->set_thd(thd);
|
2010-02-12 00:59:58 +01:00
|
|
|
if (!done_first_fix_fields)
|
|
|
|
{
|
|
|
|
done_first_fix_fields= TRUE;
|
|
|
|
inside_first_fix_fields= TRUE;
|
2010-02-20 09:23:29 +01:00
|
|
|
upper_refs.empty();
|
|
|
|
/*
|
|
|
|
psergey-todo: remove _first_fix_fields calls, we need changes on every
|
|
|
|
execution
|
|
|
|
*/
|
2010-02-12 00:59:58 +01:00
|
|
|
}
|
|
|
|
|
2009-06-22 13:46:31 +02:00
|
|
|
eliminated= FALSE;
|
2010-02-12 00:59:58 +01:00
|
|
|
parent_select= thd_param->lex->current_select;
|
2003-05-28 15:52:56 +02:00
|
|
|
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
BitKeeper/etc/ignore:
added libmysqld/ha_ndbcluster_cond.cc
---
added debian/defs.mk debian/control
client/completion_hash.cc:
Remove not needed casts
client/my_readline.h:
Remove some old types
client/mysql.cc:
Simplify types
client/mysql_upgrade.c:
Remove some old types
Update call to dirname_part
client/mysqladmin.cc:
Remove some old types
client/mysqlbinlog.cc:
Remove some old types
Change some buffers to be uchar to avoid casts
client/mysqlcheck.c:
Remove some old types
client/mysqldump.c:
Remove some old types
Remove some not needed casts
Change some string lengths to size_t
client/mysqlimport.c:
Remove some old types
client/mysqlshow.c:
Remove some old types
client/mysqlslap.c:
Remove some old types
Remove some not needed casts
client/mysqltest.c:
Removed some old types
Removed some not needed casts
Updated hash-get-key function arguments
Updated parameters to dirname_part()
client/readline.cc:
Removed some old types
Removed some not needed casts
Changed some string lengths to use size_t
client/sql_string.cc:
Removed some old types
dbug/dbug.c:
Removed some old types
Changed some string lengths to use size_t
Changed some prototypes to avoid casts
extra/comp_err.c:
Removed some old types
extra/innochecksum.c:
Removed some old types
extra/my_print_defaults.c:
Removed some old types
extra/mysql_waitpid.c:
Removed some old types
extra/perror.c:
Removed some old types
extra/replace.c:
Removed some old types
Updated parameters to dirname_part()
extra/resolve_stack_dump.c:
Removed some old types
extra/resolveip.c:
Removed some old types
include/config-win.h:
Removed some old types
include/decimal.h:
Changed binary strings to be uchar* instead of char*
include/ft_global.h:
Removed some old types
include/hash.h:
Removed some old types
include/heap.h:
Removed some old types
Changed records_under_level to be 'ulong' instead of 'uint' to clarify usage of variable
include/keycache.h:
Removed some old types
include/m_ctype.h:
Removed some old types
Changed some string lengths to use size_t
Changed character length functions to return uint
unsigned char -> uchar
include/m_string.h:
Removed some old types
Changed some string lengths to use size_t
include/my_alloc.h:
Changed some string lengths to use size_t
include/my_base.h:
Removed some old types
include/my_dbug.h:
Removed some old types
Changed some string lengths to use size_t
Changed db_dump() to take uchar * as argument for memory to reduce number of casts in usage
include/my_getopt.h:
Removed some old types
include/my_global.h:
Removed old types:
my_size_t -> size_t
byte -> uchar
gptr -> uchar *
include/my_list.h:
Removed some old types
include/my_nosys.h:
Removed some old types
include/my_pthread.h:
Removed some old types
include/my_sys.h:
Removed some old types
Changed MY_FILE_ERROR to be in line with new definitions of my_write()/my_read()
Changed some string lengths to use size_t
my_malloc() / my_free() now uses void *
Updated parameters to dirname_part() & my_uncompress()
include/my_tree.h:
Removed some old types
include/my_trie.h:
Removed some old types
include/my_user.h:
Changed some string lengths to use size_t
include/my_vle.h:
Removed some old types
include/my_xml.h:
Removed some old types
Changed some string lengths to use size_t
include/myisam.h:
Removed some old types
include/myisammrg.h:
Removed some old types
include/mysql.h:
Removed some old types
Changed byte streams to use uchar* instead of char*
include/mysql_com.h:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
include/queues.h:
Removed some old types
include/sql_common.h:
Removed some old types
include/sslopt-longopts.h:
Removed some old types
include/violite.h:
Removed some old types
Changed some string lengths to use size_t
libmysql/client_settings.h:
Removed some old types
libmysql/libmysql.c:
Removed some old types
libmysql/manager.c:
Removed some old types
libmysqld/emb_qcache.cc:
Removed some old types
libmysqld/emb_qcache.h:
Removed some old types
libmysqld/lib_sql.cc:
Removed some old types
Removed some not needed casts
Changed some buffers to be uchar* to avoid casts
true -> TRUE, false -> FALSE
mysys/array.c:
Removed some old types
mysys/charset.c:
Changed some string lengths to use size_t
mysys/checksum.c:
Include zlib to get definition for crc32
Removed some old types
mysys/default.c:
Removed some old types
Changed some string lengths to use size_t
mysys/default_modify.c:
Changed some string lengths to use size_t
Removed some not needed casts
mysys/hash.c:
Removed some old types
Changed some string lengths to use size_t
Note: Prototype of hash_key() has changed which may cause problems if client uses hash_init() with a cast for the hash-get-key function.
hash_element now takes 'ulong' as the index type (cleanup)
mysys/list.c:
Removed some old types
mysys/mf_cache.c:
Changed some string lengths to use size_t
mysys/mf_dirname.c:
Removed some old types
Changed some string lengths to use size_t
Added argument to dirname_part() to avoid calculation of length for 'to'
mysys/mf_fn_ext.c:
Removed some old types
Updated parameters to dirname_part()
mysys/mf_format.c:
Removed some old types
Changed some string lengths to use size_t
mysys/mf_getdate.c:
Removed some old types
mysys/mf_iocache.c:
Removed some old types
Changed some string lengths to use size_t
Changed calculation of 'max_length' to be done the same way in all functions
mysys/mf_iocache2.c:
Removed some old types
Changed some string lengths to use size_t
Clean up comments
Removed not needed indentation
mysys/mf_keycache.c:
Removed some old types
mysys/mf_keycaches.c:
Removed some old types
mysys/mf_loadpath.c:
Removed some old types
mysys/mf_pack.c:
Removed some old types
Changed some string lengths to use size_t
Removed some not needed casts
Removed very old VMS code
Updated parameters to dirname_part()
Use result of dirnam_part() to remove call to strcat()
mysys/mf_path.c:
Removed some old types
mysys/mf_radix.c:
Removed some old types
mysys/mf_same.c:
Removed some old types
mysys/mf_sort.c:
Removed some old types
mysys/mf_soundex.c:
Removed some old types
mysys/mf_strip.c:
Removed some old types
mysys/mf_tempdir.c:
Removed some old types
mysys/mf_unixpath.c:
Removed some old types
mysys/mf_wfile.c:
Removed some old types
mysys/mulalloc.c:
Removed some old types
mysys/my_alloc.c:
Removed some old types
Changed some string lengths to use size_t
Use void* as type for allocated memory area
Removed some not needed casts
Changed argument 'Size' to 'length' according coding guidelines
mysys/my_chsize.c:
Changed some buffers to be uchar* to avoid casts
mysys/my_compress.c:
More comments
Removed some old types
Changed string lengths to use size_t
Changed arguments to my_uncompress() to make them easier to understand
Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix)
Changed type of 'pack_data' argument to packfrm() to avoid casts.
mysys/my_conio.c:
Changed some string lengths to use size_t
mysys/my_create.c:
Removed some old types
mysys/my_div.c:
Removed some old types
mysys/my_error.c:
Removed some old types
mysys/my_fopen.c:
Removed some old types
mysys/my_fstream.c:
Removed some old types
Changed some string lengths to use size_t
writen -> written
mysys/my_getopt.c:
Removed some old types
mysys/my_getwd.c:
Removed some old types
More comments
mysys/my_init.c:
Removed some old types
mysys/my_largepage.c:
Removed some old types
Changed some string lengths to use size_t
mysys/my_lib.c:
Removed some old types
mysys/my_lockmem.c:
Removed some old types
mysys/my_malloc.c:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed all functions to use size_t
mysys/my_memmem.c:
Indentation cleanup
mysys/my_once.c:
Removed some old types
Changed malloc(), free() and related functions to use void *
mysys/my_open.c:
Removed some old types
mysys/my_pread.c:
Removed some old types
Changed all functions to use size_t
Added comment for how my_pread() / my_pwrite() are supposed to work.
Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe.
(If we ever would really need this, it should be enabled only with a flag argument)
mysys/my_quick.c:
Removed some old types
Changed all functions to use size_t
mysys/my_read.c:
Removed some old types
Changed all functions to use size_t
mysys/my_realloc.c:
Removed some old types
Use void* as type for allocated memory area
Changed all functions to use size_t
mysys/my_static.c:
Removed some old types
mysys/my_static.h:
Removed some old types
mysys/my_vle.c:
Removed some old types
mysys/my_wincond.c:
Removed some old types
mysys/my_windac.c:
Removed some old types
mysys/my_write.c:
Removed some old types
Changed all functions to use size_t
mysys/ptr_cmp.c:
Removed some old types
Changed all functions to use size_t
mysys/queues.c:
Removed some old types
mysys/safemalloc.c:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed all functions to use size_t
mysys/string.c:
Removed some old types
Changed all functions to use size_t
mysys/testhash.c:
Removed some old types
mysys/thr_alarm.c:
Removed some old types
mysys/thr_lock.c:
Removed some old types
mysys/tree.c:
Removed some old types
mysys/trie.c:
Removed some old types
mysys/typelib.c:
Removed some old types
plugin/daemon_example/daemon_example.cc:
Removed some old types
regex/reginit.c:
Removed some old types
server-tools/instance-manager/buffer.cc:
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/buffer.h:
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/commands.cc:
Removed some old types
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/instance_map.cc:
Removed some old types
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/instance_options.cc:
Changed buffer to be of type uchar*
Replaced alloc_root + strcpy() with strdup_root()
server-tools/instance-manager/mysql_connection.cc:
Changed buffer to be of type uchar*
server-tools/instance-manager/options.cc:
Removed some old types
server-tools/instance-manager/parse.cc:
Changed some string lengths to use size_t
server-tools/instance-manager/parse.h:
Removed some old types
Changed some string lengths to use size_t
server-tools/instance-manager/protocol.cc:
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
server-tools/instance-manager/protocol.h:
Changed some string lengths to use size_t
server-tools/instance-manager/user_map.cc:
Removed some old types
Changed some string lengths to use size_t
sql/derror.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
sql/discover.cc:
Changed in readfrm() and writefrom() the type for argument 'frmdata' to uchar** to avoid casts
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
sql/event_data_objects.cc:
Removed some old types
Added missing casts for alloc() and sprintf()
sql/event_db_repository.cc:
Changed some buffers to be uchar* to avoid casts
Added missing casts for sprintf()
sql/event_queue.cc:
Removed some old types
sql/field.cc:
Removed some old types
Changed memory buffers to be uchar*
Changed some string lengths to use size_t
Removed a lot of casts
Safety fix in Field_blob::val_decimal() to not access zero pointer
sql/field.h:
Removed some old types
Changed memory buffers to be uchar* (except of store() as this would have caused too many other changes).
Changed some string lengths to use size_t
Removed some not needed casts
Changed val_xxx(xxx, new_ptr) to take const pointers
sql/field_conv.cc:
Removed some old types
Added casts required because memory area pointers are now uchar*
sql/filesort.cc:
Initalize variable that was used unitialized in error conditions
sql/gen_lex_hash.cc:
Removed some old types
Changed memory buffers to be uchar*
Changed some string lengths to use size_t
Removed a lot of casts
Safety fix in Field_blob::val_decimal() to not access zero pointer
sql/gstream.h:
Added required cast
sql/ha_ndbcluster.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some buffers to be uchar* to avoid casts
Added required casts
Removed some not needed casts
sql/ha_ndbcluster.h:
Removed some old types
sql/ha_ndbcluster_binlog.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Replaced sql_alloc() + memcpy() + set end 0 with sql_strmake()
Changed some string lengths to use size_t
Added missing casts for alloc() and sprintf()
sql/ha_ndbcluster_binlog.h:
Removed some old types
sql/ha_ndbcluster_cond.cc:
Removed some old types
Removed some not needed casts
sql/ha_ndbcluster_cond.h:
Removed some old types
sql/ha_partition.cc:
Removed some old types
Changed prototype for change_partition() to avoid casts
sql/ha_partition.h:
Removed some old types
sql/handler.cc:
Removed some old types
Changed some string lengths to use size_t
sql/handler.h:
Removed some old types
Changed some string lengths to use size_t
Changed type for 'frmblob' parameter for discover() and ha_discover() to get fewer casts
sql/hash_filo.h:
Removed some old types
Changed all functions to use size_t
sql/hostname.cc:
Removed some old types
sql/item.cc:
Removed some old types
Changed some string lengths to use size_t
Use strmake() instead of memdup() to create a null terminated string.
Updated calls to new Field()
sql/item.h:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed some buffers to be uchar* to avoid casts
sql/item_cmpfunc.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/item_cmpfunc.h:
Removed some old types
sql/item_create.cc:
Removed some old types
sql/item_func.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
Added test for failing alloc() in init_result_field()
Remove old confusing comment
Fixed compiler warning
sql/item_func.h:
Removed some old types
sql/item_row.cc:
Removed some old types
sql/item_row.h:
Removed some old types
sql/item_strfunc.cc:
Include zlib (needed becasue we call crc32)
Removed some old types
sql/item_strfunc.h:
Removed some old types
Changed some types to match new function prototypes
sql/item_subselect.cc:
Removed some old types
sql/item_subselect.h:
Removed some old types
sql/item_sum.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/item_sum.h:
Removed some old types
sql/item_timefunc.cc:
Removed some old types
Changed some string lengths to use size_t
sql/item_timefunc.h:
Removed some old types
sql/item_xmlfunc.cc:
Changed some string lengths to use size_t
sql/item_xmlfunc.h:
Removed some old types
sql/key.cc:
Removed some old types
Removed some not needed casts
sql/lock.cc:
Removed some old types
Added some cast to my_multi_malloc() arguments for safety
sql/log.cc:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
Changed usage of pwrite() to not assume it holds the cursor position for the file
Made usage of my_read() safer
sql/log_event.cc:
Removed some old types
Added checking of return value of malloc() in pack_info()
Changed some buffers to be uchar* to avoid casts
Removed some 'const' to avoid casts
Added missing casts for alloc() and sprintf()
Added required casts
Removed some not needed casts
Added some cast to my_multi_malloc() arguments for safety
sql/log_event.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/log_event_old.cc:
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/log_event_old.h:
Changed some buffers to be uchar* to avoid casts
sql/mf_iocache.cc:
Removed some old types
sql/my_decimal.cc:
Changed memory area to use uchar*
sql/my_decimal.h:
Changed memory area to use uchar*
sql/mysql_priv.h:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed some string lengths to use size_t
Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid long overflow
Changed some buffers to be uchar* to avoid casts
sql/mysqld.cc:
Removed some old types
sql/net_serv.cc:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
Ensure that vio_read()/vio_write() return values are stored in a size_t variable
Removed some not needed casts
sql/opt_range.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/opt_range.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/opt_sum.cc:
Removed some old types
Removed some not needed casts
sql/parse_file.cc:
Removed some old types
Changed some string lengths to use size_t
Changed alloc_root + memcpy + set end 0 -> strmake_root()
sql/parse_file.h:
Removed some old types
sql/partition_info.cc:
Removed some old types
Added missing casts for alloc()
Changed some buffers to be uchar* to avoid casts
sql/partition_info.h:
Changed some buffers to be uchar* to avoid casts
sql/protocol.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/protocol.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
sql/records.cc:
Removed some old types
sql/repl_failsafe.cc:
Removed some old types
Changed some string lengths to use size_t
Added required casts
sql/rpl_filter.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some string lengths to use size_t
sql/rpl_filter.h:
Changed some string lengths to use size_t
sql/rpl_injector.h:
Removed some old types
sql/rpl_record.cc:
Removed some old types
Removed some not needed casts
Changed some buffers to be uchar* to avoid casts
sql/rpl_record.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/rpl_record_old.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/rpl_record_old.h:
Removed some old types
Changed some buffers to be uchar* to avoid cast
sql/rpl_rli.cc:
Removed some old types
sql/rpl_tblmap.cc:
Removed some old types
sql/rpl_tblmap.h:
Removed some old types
sql/rpl_utility.cc:
Removed some old types
sql/rpl_utility.h:
Removed some old types
Changed type of m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length
sql/set_var.cc:
Removed some old types
Updated parameters to dirname_part()
sql/set_var.h:
Removed some old types
sql/slave.cc:
Removed some old types
Changed some string lengths to use size_t
sql/slave.h:
Removed some old types
sql/sp.cc:
Removed some old types
Added missing casts for printf()
sql/sp.h:
Removed some old types
Updated hash-get-key function arguments
sql/sp_cache.cc:
Removed some old types
Added missing casts for printf()
Updated hash-get-key function arguments
sql/sp_head.cc:
Removed some old types
Added missing casts for alloc() and printf()
Added required casts
Updated hash-get-key function arguments
sql/sp_head.h:
Removed some old types
sql/sp_pcontext.cc:
Removed some old types
sql/sp_pcontext.h:
Removed some old types
sql/sql_acl.cc:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
Added required casts
sql/sql_analyse.cc:
Changed some buffers to be uchar* to avoid casts
sql/sql_analyse.h:
Changed some buffers to be uchar* to avoid casts
sql/sql_array.h:
Removed some old types
sql/sql_base.cc:
Removed some old types
Updated hash-get-key function arguments
sql/sql_binlog.cc:
Removed some old types
Added missing casts for printf()
sql/sql_cache.cc:
Removed some old types
Updated hash-get-key function arguments
Removed some not needed casts
Changed some string lengths to use size_t
sql/sql_cache.h:
Removed some old types
Removed reference to not existing function cache_key()
Updated hash-get-key function arguments
sql/sql_class.cc:
Removed some old types
Updated hash-get-key function arguments
Added missing casts for alloc()
Updated hash-get-key function arguments
Moved THD::max_row_length() to table.cc (as it's not depending on THD)
Removed some not needed casts
sql/sql_class.h:
Removed some old types
Changed malloc(), free() and related functions to use void *
Removed some not needed casts
Changed some string lengths to use size_t
Moved max_row_length and max_row_length_blob() to table.cc, as they are not depending on THD
sql/sql_connect.cc:
Removed some old types
Added required casts
sql/sql_db.cc:
Removed some old types
Removed some not needed casts
Added some cast to my_multi_malloc() arguments for safety
Added missing casts for alloc()
sql/sql_delete.cc:
Removed some old types
sql/sql_handler.cc:
Removed some old types
Updated hash-get-key function arguments
Added some cast to my_multi_malloc() arguments for safety
sql/sql_help.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/sql_insert.cc:
Removed some old types
Added missing casts for alloc() and printf()
sql/sql_lex.cc:
Removed some old types
sql/sql_lex.h:
Removed some old types
Removed some not needed casts
sql/sql_list.h:
Removed some old types
Removed some not needed casts
sql/sql_load.cc:
Removed some old types
Removed compiler warning
sql/sql_manager.cc:
Removed some old types
sql/sql_map.cc:
Removed some old types
sql/sql_map.h:
Removed some old types
sql/sql_olap.cc:
Removed some old types
sql/sql_parse.cc:
Removed some old types
Trivial move of code lines to make things more readable
Changed some string lengths to use size_t
Added missing casts for alloc()
sql/sql_partition.cc:
Removed some old types
Removed compiler warnings about not used functions
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/sql_partition.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/sql_plugin.cc:
Removed some old types
Added missing casts for alloc()
Updated hash-get-key function arguments
sql/sql_prepare.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Added missing casts for alloc() and printf()
sql-common/client.c:
Removed some old types
Changed some memory areas to use uchar*
sql-common/my_user.c:
Changed some string lengths to use size_t
sql-common/pack.c:
Changed some buffers to be uchar* to avoid casts
sql/sql_repl.cc:
Added required casts
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
sql/sql_select.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some old types
sql/sql_select.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/sql_servers.cc:
Removed some old types
Updated hash-get-key function arguments
sql/sql_show.cc:
Removed some old types
Added missing casts for alloc()
Removed some not needed casts
sql/sql_string.cc:
Removed some old types
Added required casts
sql/sql_table.cc:
Removed some old types
Removed compiler warning about not used variable
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/sql_test.cc:
Removed some old types
sql/sql_trigger.cc:
Removed some old types
Added missing casts for alloc()
sql/sql_udf.cc:
Removed some old types
Updated hash-get-key function arguments
sql/sql_union.cc:
Removed some old types
sql/sql_update.cc:
Removed some old types
Removed some not needed casts
sql/sql_view.cc:
Removed some old types
sql/sql_yacc.yy:
Removed some old types
Changed some string lengths to use size_t
Added missing casts for alloc()
sql/stacktrace.c:
Removed some old types
sql/stacktrace.h:
Removed some old types
sql/structs.h:
Removed some old types
sql/table.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some buffers to be uchar* to avoid casts
Removed setting of LEX_STRING() arguments in declaration
Added required casts
More function comments
Moved max_row_length() here from sql_class.cc/sql_class.h
sql/table.h:
Removed some old types
Changed some string lengths to use size_t
sql/thr_malloc.cc:
Use void* as type for allocated memory area
Changed all functions to use size_t
sql/tzfile.h:
Changed some buffers to be uchar* to avoid casts
sql/tztime.cc:
Changed some buffers to be uchar* to avoid casts
Updated hash-get-key function arguments
Added missing casts for alloc()
Removed some not needed casts
sql/uniques.cc:
Removed some old types
Removed some not needed casts
sql/unireg.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
Added missing casts for alloc()
storage/archive/archive_reader.c:
Removed some old types
storage/archive/azio.c:
Removed some old types
Removed some not needed casts
storage/archive/ha_archive.cc:
Removed some old types
Changed type for 'frmblob' in archive_discover() to match handler
Updated hash-get-key function arguments
Removed some not needed casts
storage/archive/ha_archive.h:
Removed some old types
storage/blackhole/ha_blackhole.cc:
Removed some old types
storage/blackhole/ha_blackhole.h:
Removed some old types
storage/csv/ha_tina.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some buffers to be uchar* to avoid casts
storage/csv/ha_tina.h:
Removed some old types
Removed some not needed casts
storage/csv/transparent_file.cc:
Removed some old types
Changed type of 'bytes_read' to be able to detect read errors
Fixed indentation
storage/csv/transparent_file.h:
Removed some old types
storage/example/ha_example.cc:
Removed some old types
Updated hash-get-key function arguments
storage/example/ha_example.h:
Removed some old types
storage/federated/ha_federated.cc:
Removed some old types
Updated hash-get-key function arguments
Removed some not needed casts
storage/federated/ha_federated.h:
Removed some old types
storage/heap/_check.c:
Changed some buffers to be uchar* to avoid casts
storage/heap/_rectest.c:
Removed some old types
storage/heap/ha_heap.cc:
Removed some old types
storage/heap/ha_heap.h:
Removed some old types
storage/heap/heapdef.h:
Removed some old types
storage/heap/hp_block.c:
Removed some old types
Changed some string lengths to use size_t
storage/heap/hp_clear.c:
Removed some old types
storage/heap/hp_close.c:
Removed some old types
storage/heap/hp_create.c:
Removed some old types
storage/heap/hp_delete.c:
Removed some old types
storage/heap/hp_hash.c:
Removed some old types
storage/heap/hp_info.c:
Removed some old types
storage/heap/hp_open.c:
Removed some old types
storage/heap/hp_rfirst.c:
Removed some old types
storage/heap/hp_rkey.c:
Removed some old types
storage/heap/hp_rlast.c:
Removed some old types
storage/heap/hp_rnext.c:
Removed some old types
storage/heap/hp_rprev.c:
Removed some old types
storage/heap/hp_rrnd.c:
Removed some old types
storage/heap/hp_rsame.c:
Removed some old types
storage/heap/hp_scan.c:
Removed some old types
storage/heap/hp_test1.c:
Removed some old types
storage/heap/hp_test2.c:
Removed some old types
storage/heap/hp_update.c:
Removed some old types
storage/heap/hp_write.c:
Removed some old types
Changed some string lengths to use size_t
storage/innobase/handler/ha_innodb.cc:
Removed some old types
Updated hash-get-key function arguments
Added missing casts for alloc() and printf()
Removed some not needed casts
storage/innobase/handler/ha_innodb.h:
Removed some old types
storage/myisam/ft_boolean_search.c:
Removed some old types
storage/myisam/ft_nlq_search.c:
Removed some old types
storage/myisam/ft_parser.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/ft_static.c:
Removed some old types
storage/myisam/ft_stopwords.c:
Removed some old types
storage/myisam/ft_update.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/ftdefs.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/fulltext.h:
Removed some old types
storage/myisam/ha_myisam.cc:
Removed some old types
storage/myisam/ha_myisam.h:
Removed some old types
storage/myisam/mi_cache.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/mi_check.c:
Removed some old types
storage/myisam/mi_checksum.c:
Removed some old types
storage/myisam/mi_close.c:
Removed some old types
storage/myisam/mi_create.c:
Removed some old types
storage/myisam/mi_delete.c:
Removed some old types
storage/myisam/mi_delete_all.c:
Removed some old types
storage/myisam/mi_dynrec.c:
Removed some old types
storage/myisam/mi_extra.c:
Removed some old types
storage/myisam/mi_key.c:
Removed some old types
storage/myisam/mi_locking.c:
Removed some old types
storage/myisam/mi_log.c:
Removed some old types
storage/myisam/mi_open.c:
Removed some old types
Removed some not needed casts
Check argument of my_write()/my_pwrite() in functions returning int
Added casting of string lengths to size_t
storage/myisam/mi_packrec.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/mi_page.c:
Removed some old types
storage/myisam/mi_preload.c:
Removed some old types
storage/myisam/mi_range.c:
Removed some old types
storage/myisam/mi_rfirst.c:
Removed some old types
storage/myisam/mi_rkey.c:
Removed some old types
storage/myisam/mi_rlast.c:
Removed some old types
storage/myisam/mi_rnext.c:
Removed some old types
storage/myisam/mi_rnext_same.c:
Removed some old types
storage/myisam/mi_rprev.c:
Removed some old types
storage/myisam/mi_rrnd.c:
Removed some old types
storage/myisam/mi_rsame.c:
Removed some old types
storage/myisam/mi_rsamepos.c:
Removed some old types
storage/myisam/mi_scan.c:
Removed some old types
storage/myisam/mi_search.c:
Removed some old types
storage/myisam/mi_static.c:
Removed some old types
storage/myisam/mi_statrec.c:
Removed some old types
storage/myisam/mi_test1.c:
Removed some old types
storage/myisam/mi_test2.c:
Removed some old types
storage/myisam/mi_test3.c:
Removed some old types
storage/myisam/mi_unique.c:
Removed some old types
storage/myisam/mi_update.c:
Removed some old types
storage/myisam/mi_write.c:
Removed some old types
storage/myisam/myisam_ftdump.c:
Removed some old types
storage/myisam/myisamchk.c:
Removed some old types
storage/myisam/myisamdef.h:
Removed some old types
storage/myisam/myisamlog.c:
Removed some old types
Indentation fix
storage/myisam/myisampack.c:
Removed some old types
storage/myisam/rt_index.c:
Removed some old types
storage/myisam/rt_split.c:
Removed some old types
storage/myisam/sort.c:
Removed some old types
storage/myisam/sp_defs.h:
Removed some old types
storage/myisam/sp_key.c:
Removed some old types
storage/myisammrg/ha_myisammrg.cc:
Removed some old types
storage/myisammrg/ha_myisammrg.h:
Removed some old types
storage/myisammrg/myrg_close.c:
Removed some old types
storage/myisammrg/myrg_def.h:
Removed some old types
storage/myisammrg/myrg_delete.c:
Removed some old types
storage/myisammrg/myrg_open.c:
Removed some old types
Updated parameters to dirname_part()
storage/myisammrg/myrg_queue.c:
Removed some old types
storage/myisammrg/myrg_rfirst.c:
Removed some old types
storage/myisammrg/myrg_rkey.c:
Removed some old types
storage/myisammrg/myrg_rlast.c:
Removed some old types
storage/myisammrg/myrg_rnext.c:
Removed some old types
storage/myisammrg/myrg_rnext_same.c:
Removed some old types
storage/myisammrg/myrg_rprev.c:
Removed some old types
storage/myisammrg/myrg_rrnd.c:
Removed some old types
storage/myisammrg/myrg_rsame.c:
Removed some old types
storage/myisammrg/myrg_update.c:
Removed some old types
storage/myisammrg/myrg_write.c:
Removed some old types
storage/ndb/include/util/ndb_opts.h:
Removed some old types
storage/ndb/src/cw/cpcd/main.cpp:
Removed some old types
storage/ndb/src/kernel/vm/Configuration.cpp:
Removed some old types
storage/ndb/src/mgmclient/main.cpp:
Removed some old types
storage/ndb/src/mgmsrv/InitConfigFileParser.cpp:
Removed some old types
Removed old disabled code
storage/ndb/src/mgmsrv/main.cpp:
Removed some old types
storage/ndb/src/ndbapi/NdbBlob.cpp:
Removed some old types
storage/ndb/src/ndbapi/NdbOperationDefine.cpp:
Removed not used variable
storage/ndb/src/ndbapi/NdbOperationInt.cpp:
Added required casts
storage/ndb/src/ndbapi/NdbScanOperation.cpp:
Added required casts
storage/ndb/tools/delete_all.cpp:
Removed some old types
storage/ndb/tools/desc.cpp:
Removed some old types
storage/ndb/tools/drop_index.cpp:
Removed some old types
storage/ndb/tools/drop_tab.cpp:
Removed some old types
storage/ndb/tools/listTables.cpp:
Removed some old types
storage/ndb/tools/ndb_config.cpp:
Removed some old types
storage/ndb/tools/restore/consumer_restore.cpp:
Changed some buffers to be uchar* to avoid casts with new defintion of packfrm()
storage/ndb/tools/restore/restore_main.cpp:
Removed some old types
storage/ndb/tools/select_all.cpp:
Removed some old types
storage/ndb/tools/select_count.cpp:
Removed some old types
storage/ndb/tools/waiter.cpp:
Removed some old types
strings/bchange.c:
Changed function to use uchar * and size_t
strings/bcmp.c:
Changed function to use uchar * and size_t
strings/bmove512.c:
Changed function to use uchar * and size_t
strings/bmove_upp.c:
Changed function to use uchar * and size_t
strings/ctype-big5.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-bin.c:
Changed functions to use size_t
strings/ctype-cp932.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-czech.c:
Fixed indentation
Changed functions to use size_t
strings/ctype-euc_kr.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-eucjpms.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-gb2312.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-gbk.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-latin1.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-mb.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-simple.c:
Changed functions to use size_t
Simpler loops for caseup/casedown
unsigned int -> uint
unsigned char -> uchar
strings/ctype-sjis.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-tis620.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-uca.c:
Changed functions to use size_t
unsigned char -> uchar
strings/ctype-ucs2.c:
Moved inclusion of stdarg.h to other includes
usigned char -> uchar
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-ujis.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-utf8.c:
Changed functions to use size_t
unsigned char -> uchar
Indentation fixes
strings/ctype-win1250ch.c:
Indentation fixes
Changed functions to use size_t
strings/ctype.c:
Changed functions to use size_t
strings/decimal.c:
Changed type for memory argument to uchar *
strings/do_ctype.c:
Indentation fixes
strings/my_strtoll10.c:
unsigned char -> uchar
strings/my_vsnprintf.c:
Changed functions to use size_t
strings/r_strinstr.c:
Removed some old types
Changed functions to use size_t
strings/str_test.c:
Removed some old types
strings/strappend.c:
Changed functions to use size_t
strings/strcont.c:
Removed some old types
strings/strfill.c:
Removed some old types
strings/strinstr.c:
Changed functions to use size_t
strings/strlen.c:
Changed functions to use size_t
strings/strmake.c:
Changed functions to use size_t
strings/strnlen.c:
Changed functions to use size_t
strings/strnmov.c:
Changed functions to use size_t
strings/strto.c:
unsigned char -> uchar
strings/strtod.c:
Changed functions to use size_t
strings/strxnmov.c:
Changed functions to use size_t
strings/xml.c:
Changed functions to use size_t
Indentation fixes
tests/mysql_client_test.c:
Removed some old types
tests/thread_test.c:
Removed some old types
vio/test-ssl.c:
Removed some old types
vio/test-sslclient.c:
Removed some old types
vio/test-sslserver.c:
Removed some old types
vio/vio.c:
Removed some old types
vio/vio_priv.h:
Removed some old types
Changed vio_read()/vio_write() to work with size_t
vio/viosocket.c:
Changed vio_read()/vio_write() to work with size_t
Indentation fixes
vio/viossl.c:
Changed vio_read()/vio_write() to work with size_t
Indentation fixes
vio/viosslfactories.c:
Removed some old types
vio/viotest-ssl.c:
Removed some old types
win/README:
More explanations
2007-05-10 11:59:39 +02:00
|
|
|
if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
|
2004-10-20 03:04:37 +02:00
|
|
|
return TRUE;
|
2009-06-22 13:46:31 +02:00
|
|
|
|
2004-02-08 19:14:13 +01:00
|
|
|
|
2009-09-04 10:14:54 +02:00
|
|
|
if (!(res= engine->prepare()))
|
2002-10-12 00:09:47 +02:00
|
|
|
{
|
2009-09-04 10:14:54 +02:00
|
|
|
// all transformation is done (used by prepared statements)
|
|
|
|
changed= 1;
|
2010-09-05 17:43:47 +02:00
|
|
|
inside_first_fix_fields= FALSE;
|
2010-01-28 14:48:33 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Substitute the current item with an Item_in_optimizer that was
|
|
|
|
created by Item_in_subselect::select_in_like_transformer and
|
|
|
|
call fix_fields for the substituted item which in turn calls
|
|
|
|
engine->prepare for the subquery predicate.
|
|
|
|
*/
|
2003-05-14 20:51:33 +02:00
|
|
|
if (substitution)
|
|
|
|
{
|
2010-09-05 17:43:47 +02:00
|
|
|
/*
|
|
|
|
If the top item of the WHERE/HAVING condition changed,
|
|
|
|
set correct WHERE/HAVING for PS.
|
|
|
|
*/
|
2004-02-08 19:14:13 +01:00
|
|
|
if (unit->outer_select()->where == (*ref))
|
2010-09-05 17:43:47 +02:00
|
|
|
thd->change_item_tree(&(unit->outer_select()->where), substitution);
|
2004-12-08 22:37:17 +01:00
|
|
|
else if (unit->outer_select()->having == (*ref))
|
2010-09-05 17:43:47 +02:00
|
|
|
thd->change_item_tree(&(unit->outer_select()->having), substitution);
|
2004-02-08 19:14:13 +01:00
|
|
|
|
2003-05-14 20:51:33 +02:00
|
|
|
(*ref)= substitution;
|
|
|
|
substitution->name= name;
|
|
|
|
if (have_to_be_excluded)
|
|
|
|
engine->exclude();
|
|
|
|
substitution= 0;
|
2004-07-04 07:46:28 +02:00
|
|
|
thd->where= "checking transformed subquery";
|
2004-03-17 13:26:26 +01:00
|
|
|
if (!(*ref)->fixed)
|
2009-11-16 21:49:51 +01:00
|
|
|
res= (*ref)->fix_fields(thd, ref);
|
|
|
|
goto end;
|
2010-03-20 13:01:47 +01:00
|
|
|
//psergey-merge: done_first_fix_fields= FALSE;
|
2003-05-14 20:51:33 +02:00
|
|
|
}
|
2002-10-12 00:09:47 +02:00
|
|
|
// Is it one field subselect?
|
|
|
|
if (engine->cols() > max_columns)
|
2004-07-04 07:46:28 +02:00
|
|
|
{
|
2003-10-06 21:35:05 +02:00
|
|
|
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
|
2010-03-20 13:01:47 +01:00
|
|
|
//psergey-merge: done_first_fix_fields= FALSE;
|
2009-11-16 21:49:51 +01:00
|
|
|
goto end;
|
2002-10-12 00:09:47 +02:00
|
|
|
}
|
2002-10-08 13:50:12 +02:00
|
|
|
fix_length_and_dec();
|
2002-10-12 00:09:47 +02:00
|
|
|
}
|
2005-01-18 15:26:05 +01:00
|
|
|
else
|
2009-11-16 21:49:51 +01:00
|
|
|
goto end;
|
Table definition cache, part 2
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
Other noteworthy changes:
- In TABLE_SHARE the most common strings are now LEX_STRING's
- Better error message when table is not found
- Variable table_cache is now renamed 'table_open_cache'
- New variable 'table_definition_cache' that is the number of table defintions that will be cached
- strxnmov() calls are now fixed to avoid overflows
- strxnmov() will now always add one end \0 to result
- engine objects are now created with a TABLE_SHARE object instead of a TABLE object.
- After creating a field object one must call field->init(table) before using it
- For a busy system this change will give you:
- Less memory usage for table object
- Faster opening of tables (if it's has been in use or is in table definition cache)
- Allow you to cache many table definitions objects
- Faster drop of table
mysql-test/mysql-test-run.sh:
Fixed some problems with --gdb option
Test both with socket and tcp/ip port that all old servers are killed
mysql-test/r/flush_table.result:
More tests with lock table with 2 threads + flush table
mysql-test/r/information_schema.result:
Removed old (now wrong) result
mysql-test/r/innodb.result:
Better error messages (thanks to TDC patch)
mysql-test/r/merge.result:
Extra flush table test
mysql-test/r/ndb_bitfield.result:
Better error messages (thanks to TDC patch)
mysql-test/r/ndb_partition_error.result:
Better error messages (thanks to TDC patch)
mysql-test/r/query_cache.result:
Remove tables left from old tests
mysql-test/r/temp_table.result:
Test truncate with temporary tables
mysql-test/r/variables.result:
Table_cache -> Table_open_cache
mysql-test/t/flush_table.test:
More tests with lock table with 2 threads + flush table
mysql-test/t/merge.test:
Extra flush table test
mysql-test/t/multi_update.test:
Added 'sleep' to make test predictable
mysql-test/t/query_cache.test:
Remove tables left from old tests
mysql-test/t/temp_table.test:
Test truncate with temporary tables
mysql-test/t/variables.test:
Table_cache -> Table_open_cache
mysql-test/valgrind.supp:
Remove warning that may happens becasue threads dies in different order
mysys/hash.c:
Fixed wrong DBUG_PRINT
mysys/mf_dirname.c:
More DBUG
mysys/mf_pack.c:
Better comment
mysys/mf_tempdir.c:
More DBUG
Ensure that we call cleanup_dirname() on all temporary directory paths.
If we don't do this, we will get a failure when comparing temporary table
names as in some cases the temporary table name is run through convert_dirname())
mysys/my_alloc.c:
Indentation fix
sql/examples/ha_example.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_example.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/field.cc:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Use s->db instead of s->table_cache_key
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/field.h:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/ha_archive.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_archive.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_berkeley.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Changed name of argument create() to not hide internal 'table' variable.
table->s -> table_share
sql/ha_berkeley.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_federated.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed comments
Remove index variable and replace with pointers (simple optimization)
move_field() -> move_field_offset()
Removed some strlen() calls
sql/ha_federated.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_heap.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Simplify delete_table() and create() as the given file names are now without extension
sql/ha_heap.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisam.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Remove not needed fn_format()
Fixed for new table->s structure
sql/ha_myisam.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisammrg.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Don't set 'is_view' for MERGE tables
Use new interface to find_temporary_table()
sql/ha_myisammrg.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Added flag HA_NO_COPY_ON_ALTER
sql/ha_ndbcluster.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed wrong calls to strxnmov()
Give error HA_ERR_TABLE_DEF_CHANGED if table definition has changed
drop_table -> intern_drop_table()
table->s -> table_share
Move part_info to TABLE
Fixed comments & DBUG print's
New arguments to print_error()
sql/ha_ndbcluster.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_partition.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
We can't set up or use part_info when creating handler as there is not yet any table object
New ha_intialise() to work with TDC (Done by Mikael)
sql/ha_partition.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Got set_part_info() from Mikael
sql/handler.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
ha_delete_table() now also takes database as an argument
handler::ha_open() now takes TABLE as argument
ha_open() now calls ha_allocate_read_write_set()
Simplify ha_allocate_read_write_set()
Remove ha_deallocate_read_write_set()
Use table_share (Cached by table definition cache)
sql/handler.h:
New table flag: HA_NO_COPY_ON_ALTER (used by merge tables)
Remove ha_deallocate_read_write_set()
get_new_handler() now takes TABLE_SHARE as argument
ha_delete_table() now gets database as argument
sql/item.cc:
table_name and db are now LEX_STRING objects
When creating fields, we have now have to call field->init(table)
move_field -> move_field_offset()
sql/item.h:
tmp_table_field_from_field_type() now takes an extra paramenter 'fixed_length' to allow one to force usage of CHAR
instead of BLOB
sql/item_cmpfunc.cc:
Fixed call to tmp_table_field_from_field_type()
sql/item_create.cc:
Assert if new not handled cast type
sql/item_func.cc:
When creating fields, we have now have to call field->init(table)
dummy_table used by 'sp' now needs a TABLE_SHARE object
sql/item_subselect.cc:
Trivial code cleanups
sql/item_sum.cc:
When creating fields, we have now have to call field->init(table)
sql/item_timefunc.cc:
Item_func_str_to_date::tmp_table_field() now replaced by call to
tmp_table_field_from_field_type() (see item_timefunc.h)
sql/item_timefunc.h:
Simply tmp_table_field()
sql/item_uniq.cc:
When creating fields, we have now have to call field->init(table)
sql/key.cc:
Added 'KEY' argument to 'find_ref_key' to simplify code
sql/lock.cc:
More debugging
Use create_table_def_key() to create key for table cache
Allocate TABLE_SHARE properly when creating name lock
Fix that locked_table_name doesn't test same table twice
sql/mysql_priv.h:
New functions for table definition cache
New interfaces to a lot of functions.
New faster interface to find_temporary_table() and close_temporary_table()
sql/mysqld.cc:
Added support for table definition cache of size 'table_def_size'
Fixed som calls to strnmov()
Changed name of 'table_cache' to 'table_open_cache'
sql/opt_range.cc:
Use new interfaces
Fixed warnings from valgrind
sql/parse_file.cc:
Safer calls to strxnmov()
Fixed typo
sql/set_var.cc:
Added variable 'table_definition_cache'
Variable table_cache renamed to 'table_open_cache'
sql/slave.cc:
Use new interface
sql/sp.cc:
Proper use of TABLE_SHARE
sql/sp_head.cc:
Remove compiler warnings
We have now to call field->init(table)
sql/sp_head.h:
Pointers to parsed strings are now const
sql/sql_acl.cc:
table_name is now a LEX_STRING
sql/sql_base.cc:
Main implementation of table definition cache
(The #ifdef's are there for the future when table definition cache will replace open table cache)
Now table definitions are cached indepndent of open tables, which will speed up things when a table is in use at once from several places
Views are not yet cached; For the moment we only cache if a table is a view or not.
Faster implementation of find_temorary_table()
Replace 'wait_for_refresh()' with the more general function 'wait_for_condition()'
Drop table is slightly faster as we can use the table definition cache to know the type of the table
sql/sql_cache.cc:
table_cache_key and table_name are now LEX_STRING
'sDBUG print fixes
sql/sql_class.cc:
table_cache_key is now a LEX_STRING
safer strxnmov()
sql/sql_class.h:
Added number of open table shares (table definitions)
sql/sql_db.cc:
safer strxnmov()
sql/sql_delete.cc:
Use new interface to find_temporary_table()
sql/sql_derived.cc:
table_name is now a LEX_STRING
sql/sql_handler.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_insert.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_lex.cc:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_lex.h:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_load.cc:
Safer strxnmov()
sql/sql_parse.cc:
Better error if wrong DB name
sql/sql_partition.cc:
part_info moved to TABLE from TABLE_SHARE
Indentation changes
sql/sql_select.cc:
Indentation fixes
Call field->init(TABLE) for new created fields
Update create_tmp_table() to use TABLE_SHARE properly
sql/sql_select.h:
Call field->init(TABLE) for new created fields
sql/sql_show.cc:
table_name is now a LEX_STRING
part_info moved to TABLE
sql/sql_table.cc:
Use table definition cache to speed up delete of tables
Fixed calls to functions with new interfaces
Don't use 'share_not_to_be_used'
Instead of doing openfrm() when doing repair, we now have to call
get_table_share() followed by open_table_from_share().
Replace some fn_format() with faster unpack_filename().
Safer strxnmov()
part_info is now in TABLE
Added Mikaels patch for partition and ALTER TABLE
Instead of using 'TABLE_SHARE->is_view' use 'table_flags() & HA_NO_COPY_ON_ALTER
sql/sql_test.cc:
table_name and table_cache_key are now LEX_STRING's
sql/sql_trigger.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
safer strxnmov()
Removed compiler warnings
sql/sql_update.cc:
Call field->init(TABLE) after field is created
sql/sql_view.cc:
safer strxnmov()
Create common TABLE_SHARE object for views to allow us to cache if table is a view
sql/structs.h:
Added SHOW_TABLE_DEFINITIONS
sql/table.cc:
Creation and destruct of TABLE_SHARE objects that are common for many TABLE objects
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
open_table_def() is written in such a way that it should be trival to add parsing of the .frm files in new formats
sql/table.h:
TABLE objects for the same database table now share a common TABLE_SHARE object
In TABLE_SHARE the most common strings are now LEX_STRING's
sql/unireg.cc:
Changed arguments to rea_create_table() to have same order as other functions
Call field->init(table) for new created fields
sql/unireg.h:
Added OPEN_VIEW
strings/strxnmov.c:
Change strxnmov() to always add end \0
This makes usage of strxnmov() safer as most of MySQL code assumes that strxnmov() will create a null terminated string
2005-11-23 21:45:02 +01:00
|
|
|
|
|
|
|
if ((uncacheable= engine->uncacheable()))
|
2003-10-23 19:50:53 +02:00
|
|
|
{
|
|
|
|
const_item_cache= 0;
|
2003-11-17 19:53:40 +01:00
|
|
|
if (uncacheable & UNCACHEABLE_RAND)
|
|
|
|
used_tables_cache|= RAND_TABLE_BIT;
|
2003-10-23 19:50:53 +02:00
|
|
|
}
|
2002-11-21 10:01:33 +01:00
|
|
|
fixed= 1;
|
Table definition cache, part 2
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
Other noteworthy changes:
- In TABLE_SHARE the most common strings are now LEX_STRING's
- Better error message when table is not found
- Variable table_cache is now renamed 'table_open_cache'
- New variable 'table_definition_cache' that is the number of table defintions that will be cached
- strxnmov() calls are now fixed to avoid overflows
- strxnmov() will now always add one end \0 to result
- engine objects are now created with a TABLE_SHARE object instead of a TABLE object.
- After creating a field object one must call field->init(table) before using it
- For a busy system this change will give you:
- Less memory usage for table object
- Faster opening of tables (if it's has been in use or is in table definition cache)
- Allow you to cache many table definitions objects
- Faster drop of table
mysql-test/mysql-test-run.sh:
Fixed some problems with --gdb option
Test both with socket and tcp/ip port that all old servers are killed
mysql-test/r/flush_table.result:
More tests with lock table with 2 threads + flush table
mysql-test/r/information_schema.result:
Removed old (now wrong) result
mysql-test/r/innodb.result:
Better error messages (thanks to TDC patch)
mysql-test/r/merge.result:
Extra flush table test
mysql-test/r/ndb_bitfield.result:
Better error messages (thanks to TDC patch)
mysql-test/r/ndb_partition_error.result:
Better error messages (thanks to TDC patch)
mysql-test/r/query_cache.result:
Remove tables left from old tests
mysql-test/r/temp_table.result:
Test truncate with temporary tables
mysql-test/r/variables.result:
Table_cache -> Table_open_cache
mysql-test/t/flush_table.test:
More tests with lock table with 2 threads + flush table
mysql-test/t/merge.test:
Extra flush table test
mysql-test/t/multi_update.test:
Added 'sleep' to make test predictable
mysql-test/t/query_cache.test:
Remove tables left from old tests
mysql-test/t/temp_table.test:
Test truncate with temporary tables
mysql-test/t/variables.test:
Table_cache -> Table_open_cache
mysql-test/valgrind.supp:
Remove warning that may happens becasue threads dies in different order
mysys/hash.c:
Fixed wrong DBUG_PRINT
mysys/mf_dirname.c:
More DBUG
mysys/mf_pack.c:
Better comment
mysys/mf_tempdir.c:
More DBUG
Ensure that we call cleanup_dirname() on all temporary directory paths.
If we don't do this, we will get a failure when comparing temporary table
names as in some cases the temporary table name is run through convert_dirname())
mysys/my_alloc.c:
Indentation fix
sql/examples/ha_example.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_example.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/field.cc:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Use s->db instead of s->table_cache_key
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/field.h:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/ha_archive.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_archive.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_berkeley.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Changed name of argument create() to not hide internal 'table' variable.
table->s -> table_share
sql/ha_berkeley.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_federated.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed comments
Remove index variable and replace with pointers (simple optimization)
move_field() -> move_field_offset()
Removed some strlen() calls
sql/ha_federated.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_heap.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Simplify delete_table() and create() as the given file names are now without extension
sql/ha_heap.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisam.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Remove not needed fn_format()
Fixed for new table->s structure
sql/ha_myisam.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisammrg.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Don't set 'is_view' for MERGE tables
Use new interface to find_temporary_table()
sql/ha_myisammrg.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Added flag HA_NO_COPY_ON_ALTER
sql/ha_ndbcluster.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed wrong calls to strxnmov()
Give error HA_ERR_TABLE_DEF_CHANGED if table definition has changed
drop_table -> intern_drop_table()
table->s -> table_share
Move part_info to TABLE
Fixed comments & DBUG print's
New arguments to print_error()
sql/ha_ndbcluster.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_partition.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
We can't set up or use part_info when creating handler as there is not yet any table object
New ha_intialise() to work with TDC (Done by Mikael)
sql/ha_partition.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Got set_part_info() from Mikael
sql/handler.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
ha_delete_table() now also takes database as an argument
handler::ha_open() now takes TABLE as argument
ha_open() now calls ha_allocate_read_write_set()
Simplify ha_allocate_read_write_set()
Remove ha_deallocate_read_write_set()
Use table_share (Cached by table definition cache)
sql/handler.h:
New table flag: HA_NO_COPY_ON_ALTER (used by merge tables)
Remove ha_deallocate_read_write_set()
get_new_handler() now takes TABLE_SHARE as argument
ha_delete_table() now gets database as argument
sql/item.cc:
table_name and db are now LEX_STRING objects
When creating fields, we have now have to call field->init(table)
move_field -> move_field_offset()
sql/item.h:
tmp_table_field_from_field_type() now takes an extra paramenter 'fixed_length' to allow one to force usage of CHAR
instead of BLOB
sql/item_cmpfunc.cc:
Fixed call to tmp_table_field_from_field_type()
sql/item_create.cc:
Assert if new not handled cast type
sql/item_func.cc:
When creating fields, we have now have to call field->init(table)
dummy_table used by 'sp' now needs a TABLE_SHARE object
sql/item_subselect.cc:
Trivial code cleanups
sql/item_sum.cc:
When creating fields, we have now have to call field->init(table)
sql/item_timefunc.cc:
Item_func_str_to_date::tmp_table_field() now replaced by call to
tmp_table_field_from_field_type() (see item_timefunc.h)
sql/item_timefunc.h:
Simply tmp_table_field()
sql/item_uniq.cc:
When creating fields, we have now have to call field->init(table)
sql/key.cc:
Added 'KEY' argument to 'find_ref_key' to simplify code
sql/lock.cc:
More debugging
Use create_table_def_key() to create key for table cache
Allocate TABLE_SHARE properly when creating name lock
Fix that locked_table_name doesn't test same table twice
sql/mysql_priv.h:
New functions for table definition cache
New interfaces to a lot of functions.
New faster interface to find_temporary_table() and close_temporary_table()
sql/mysqld.cc:
Added support for table definition cache of size 'table_def_size'
Fixed som calls to strnmov()
Changed name of 'table_cache' to 'table_open_cache'
sql/opt_range.cc:
Use new interfaces
Fixed warnings from valgrind
sql/parse_file.cc:
Safer calls to strxnmov()
Fixed typo
sql/set_var.cc:
Added variable 'table_definition_cache'
Variable table_cache renamed to 'table_open_cache'
sql/slave.cc:
Use new interface
sql/sp.cc:
Proper use of TABLE_SHARE
sql/sp_head.cc:
Remove compiler warnings
We have now to call field->init(table)
sql/sp_head.h:
Pointers to parsed strings are now const
sql/sql_acl.cc:
table_name is now a LEX_STRING
sql/sql_base.cc:
Main implementation of table definition cache
(The #ifdef's are there for the future when table definition cache will replace open table cache)
Now table definitions are cached indepndent of open tables, which will speed up things when a table is in use at once from several places
Views are not yet cached; For the moment we only cache if a table is a view or not.
Faster implementation of find_temorary_table()
Replace 'wait_for_refresh()' with the more general function 'wait_for_condition()'
Drop table is slightly faster as we can use the table definition cache to know the type of the table
sql/sql_cache.cc:
table_cache_key and table_name are now LEX_STRING
'sDBUG print fixes
sql/sql_class.cc:
table_cache_key is now a LEX_STRING
safer strxnmov()
sql/sql_class.h:
Added number of open table shares (table definitions)
sql/sql_db.cc:
safer strxnmov()
sql/sql_delete.cc:
Use new interface to find_temporary_table()
sql/sql_derived.cc:
table_name is now a LEX_STRING
sql/sql_handler.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_insert.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_lex.cc:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_lex.h:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_load.cc:
Safer strxnmov()
sql/sql_parse.cc:
Better error if wrong DB name
sql/sql_partition.cc:
part_info moved to TABLE from TABLE_SHARE
Indentation changes
sql/sql_select.cc:
Indentation fixes
Call field->init(TABLE) for new created fields
Update create_tmp_table() to use TABLE_SHARE properly
sql/sql_select.h:
Call field->init(TABLE) for new created fields
sql/sql_show.cc:
table_name is now a LEX_STRING
part_info moved to TABLE
sql/sql_table.cc:
Use table definition cache to speed up delete of tables
Fixed calls to functions with new interfaces
Don't use 'share_not_to_be_used'
Instead of doing openfrm() when doing repair, we now have to call
get_table_share() followed by open_table_from_share().
Replace some fn_format() with faster unpack_filename().
Safer strxnmov()
part_info is now in TABLE
Added Mikaels patch for partition and ALTER TABLE
Instead of using 'TABLE_SHARE->is_view' use 'table_flags() & HA_NO_COPY_ON_ALTER
sql/sql_test.cc:
table_name and table_cache_key are now LEX_STRING's
sql/sql_trigger.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
safer strxnmov()
Removed compiler warnings
sql/sql_update.cc:
Call field->init(TABLE) after field is created
sql/sql_view.cc:
safer strxnmov()
Create common TABLE_SHARE object for views to allow us to cache if table is a view
sql/structs.h:
Added SHOW_TABLE_DEFINITIONS
sql/table.cc:
Creation and destruct of TABLE_SHARE objects that are common for many TABLE objects
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
open_table_def() is written in such a way that it should be trival to add parsing of the .frm files in new formats
sql/table.h:
TABLE objects for the same database table now share a common TABLE_SHARE object
In TABLE_SHARE the most common strings are now LEX_STRING's
sql/unireg.cc:
Changed arguments to rea_create_table() to have same order as other functions
Call field->init(table) for new created fields
sql/unireg.h:
Added OPEN_VIEW
strings/strxnmov.c:
Change strxnmov() to always add end \0
This makes usage of strxnmov() safer as most of MySQL code assumes that strxnmov() will create a null terminated string
2005-11-23 21:45:02 +01:00
|
|
|
|
2009-11-16 21:49:51 +01:00
|
|
|
end:
|
2010-02-21 04:36:18 +01:00
|
|
|
done_first_fix_fields= FALSE;
|
2002-11-24 20:10:52 +01:00
|
|
|
thd->where= save_where;
|
2002-09-28 17:34:56 +02:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
This changeset is largely a handler cleanup changeset (WL#3281), but includes fixes and cleanups that was found necessary while testing the handler changes
Changes that requires code changes in other code of other storage engines.
(Note that all changes are very straightforward and one should find all issues
by compiling a --debug build and fixing all compiler errors and all
asserts in field.cc while running the test suite),
- New optional handler function introduced: reset()
This is called after every DML statement to make it easy for a handler to
statement specific cleanups.
(The only case it's not called is if force the file to be closed)
- handler::extra(HA_EXTRA_RESET) is removed. Code that was there before
should be moved to handler::reset()
- table->read_set contains a bitmap over all columns that are needed
in the query. read_row() and similar functions only needs to read these
columns
- table->write_set contains a bitmap over all columns that will be updated
in the query. write_row() and update_row() only needs to update these
columns.
The above bitmaps should now be up to date in all context
(including ALTER TABLE, filesort()).
The handler is informed of any changes to the bitmap after
fix_fields() by calling the virtual function
handler::column_bitmaps_signal(). If the handler does caching of
these bitmaps (instead of using table->read_set, table->write_set),
it should redo the caching in this code. as the signal() may be sent
several times, it's probably best to set a variable in the signal
and redo the caching on read_row() / write_row() if the variable was
set.
- Removed the read_set and write_set bitmap objects from the handler class
- Removed all column bit handling functions from the handler class.
(Now one instead uses the normal bitmap functions in my_bitmap.c instead
of handler dedicated bitmap functions)
- field->query_id is removed. One should instead instead check
table->read_set and table->write_set if a field is used in the query.
- handler::extra(HA_EXTRA_RETRIVE_ALL_COLS) and
handler::extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY) are removed. One should now
instead use table->read_set to check for which columns to retrieve.
- If a handler needs to call Field->val() or Field->store() on columns
that are not used in the query, one should install a temporary
all-columns-used map while doing so. For this, we provide the following
functions:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
field->val();
dbug_tmp_restore_column_map(table->read_set, old_map);
and similar for the write map:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
field->val();
dbug_tmp_restore_column_map(table->write_set, old_map);
If this is not done, you will sooner or later hit a DBUG_ASSERT
in the field store() / val() functions.
(For not DBUG binaries, the dbug_tmp_restore_column_map() and
dbug_tmp_restore_column_map() are inline dummy functions and should
be optimized away be the compiler).
- If one needs to temporary set the column map for all binaries (and not
just to avoid the DBUG_ASSERT() in the Field::store() / Field::val()
methods) one should use the functions tmp_use_all_columns() and
tmp_restore_column_map() instead of the above dbug_ variants.
- All 'status' fields in the handler base class (like records,
data_file_length etc) are now stored in a 'stats' struct. This makes
it easier to know what status variables are provided by the base
handler. This requires some trivial variable names in the extra()
function.
- New virtual function handler::records(). This is called to optimize
COUNT(*) if (handler::table_flags() & HA_HAS_RECORDS()) is true.
(stats.records is not supposed to be an exact value. It's only has to
be 'reasonable enough' for the optimizer to be able to choose a good
optimization path).
- Non virtual handler::init() function added for caching of virtual
constants from engine.
- Removed has_transactions() virtual method. Now one should instead return
HA_NO_TRANSACTIONS in table_flags() if the table handler DOES NOT support
transactions.
- The 'xxxx_create_handler()' function now has a MEM_ROOT_root argument
that is to be used with 'new handler_name()' to allocate the handler
in the right area. The xxxx_create_handler() function is also
responsible for any initialization of the object before returning.
For example, one should change:
static handler *myisam_create_handler(TABLE_SHARE *table)
{
return new ha_myisam(table);
}
->
static handler *myisam_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
{
return new (mem_root) ha_myisam(table);
}
- New optional virtual function: use_hidden_primary_key().
This is called in case of an update/delete when
(table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
but we don't have a primary key. This allows the handler to take precisions
in remembering any hidden primary key to able to update/delete any
found row. The default handler marks all columns to be read.
- handler::table_flags() now returns a ulonglong (to allow for more flags).
- New/changed table_flags()
- HA_HAS_RECORDS Set if ::records() is supported
- HA_NO_TRANSACTIONS Set if engine doesn't support transactions
- HA_PRIMARY_KEY_REQUIRED_FOR_DELETE
Set if we should mark all primary key columns for
read when reading rows as part of a DELETE
statement. If there is no primary key,
all columns are marked for read.
- HA_PARTIAL_COLUMN_READ Set if engine will not read all columns in some
cases (based on table->read_set)
- HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS
Renamed to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION.
- HA_DUPP_POS Renamed to HA_DUPLICATE_POS
- HA_REQUIRES_KEY_COLUMNS_FOR_DELETE
Set this if we should mark ALL key columns for
read when when reading rows as part of a DELETE
statement. In case of an update we will mark
all keys for read for which key part changed
value.
- HA_STATS_RECORDS_IS_EXACT
Set this if stats.records is exact.
(This saves us some extra records() calls
when optimizing COUNT(*))
- Removed table_flags()
- HA_NOT_EXACT_COUNT Now one should instead use HA_HAS_RECORDS if
handler::records() gives an exact count() and
HA_STATS_RECORDS_IS_EXACT if stats.records is exact.
- HA_READ_RND_SAME Removed (no one supported this one)
- Removed not needed functions ha_retrieve_all_cols() and ha_retrieve_all_pk()
- Renamed handler::dupp_pos to handler::dup_pos
- Removed not used variable handler::sortkey
Upper level handler changes:
- ha_reset() now does some overall checks and calls ::reset()
- ha_table_flags() added. This is a cached version of table_flags(). The
cache is updated on engine creation time and updated on open.
MySQL level changes (not obvious from the above):
- DBUG_ASSERT() added to check that column usage matches what is set
in the column usage bit maps. (This found a LOT of bugs in current
column marking code).
- In 5.1 before, all used columns was marked in read_set and only updated
columns was marked in write_set. Now we only mark columns for which we
need a value in read_set.
- Column bitmaps are created in open_binary_frm() and open_table_from_share().
(Before this was in table.cc)
- handler::table_flags() calls are replaced with handler::ha_table_flags()
- For calling field->val() you must have the corresponding bit set in
table->read_set. For calling field->store() you must have the
corresponding bit set in table->write_set. (There are asserts in
all store()/val() functions to catch wrong usage)
- thd->set_query_id is renamed to thd->mark_used_columns and instead
of setting this to an integer value, this has now the values:
MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE
Changed also all variables named 'set_query_id' to mark_used_columns.
- In filesort() we now inform the handler of exactly which columns are needed
doing the sort and choosing the rows.
- The TABLE_SHARE object has a 'all_set' column bitmap one can use
when one needs a column bitmap with all columns set.
(This is used for table->use_all_columns() and other places)
- The TABLE object has 3 column bitmaps:
- def_read_set Default bitmap for columns to be read
- def_write_set Default bitmap for columns to be written
- tmp_set Can be used as a temporary bitmap when needed.
The table object has also two pointer to bitmaps read_set and write_set
that the handler should use to find out which columns are used in which way.
- count() optimization now calls handler::records() instead of using
handler->stats.records (if (table_flags() & HA_HAS_RECORDS) is true).
- Added extra argument to Item::walk() to indicate if we should also
traverse sub queries.
- Added TABLE parameter to cp_buffer_from_ref()
- Don't close tables created with CREATE ... SELECT but keep them in
the table cache. (Faster usage of newly created tables).
New interfaces:
- table->clear_column_bitmaps() to initialize the bitmaps for tables
at start of new statements.
- table->column_bitmaps_set() to set up new column bitmaps and signal
the handler about this.
- table->column_bitmaps_set_no_signal() for some few cases where we need
to setup new column bitmaps but don't signal the handler (as the handler
has already been signaled about these before). Used for the momement
only in opt_range.cc when doing ROR scans.
- table->use_all_columns() to install a bitmap where all columns are marked
as use in the read and the write set.
- table->default_column_bitmaps() to install the normal read and write
column bitmaps, but not signaling the handler about this.
This is mainly used when creating TABLE instances.
- table->mark_columns_needed_for_delete(),
table->mark_columns_needed_for_delete() and
table->mark_columns_needed_for_insert() to allow us to put additional
columns in column usage maps if handler so requires.
(The handler indicates what it neads in handler->table_flags())
- table->prepare_for_position() to allow us to tell handler that it
needs to read primary key parts to be able to store them in
future table->position() calls.
(This replaces the table->file->ha_retrieve_all_pk function)
- table->mark_auto_increment_column() to tell handler are going to update
columns part of any auto_increment key.
- table->mark_columns_used_by_index() to mark all columns that is part of
an index. It will also send extra(HA_EXTRA_KEYREAD) to handler to allow
it to quickly know that it only needs to read colums that are part
of the key. (The handler can also use the column map for detecting this,
but simpler/faster handler can just monitor the extra() call).
- table->mark_columns_used_by_index_no_reset() to in addition to other columns,
also mark all columns that is used by the given key.
- table->restore_column_maps_after_mark_index() to restore to default
column maps after a call to table->mark_columns_used_by_index().
- New item function register_field_in_read_map(), for marking used columns
in table->read_map. Used by filesort() to mark all used columns
- Maintain in TABLE->merge_keys set of all keys that are used in query.
(Simplices some optimization loops)
- Maintain Field->part_of_key_not_clustered which is like Field->part_of_key
but the field in the clustered key is not assumed to be part of all index.
(used in opt_range.cc for faster loops)
- dbug_tmp_use_all_columns(), dbug_tmp_restore_column_map()
tmp_use_all_columns() and tmp_restore_column_map() functions to temporally
mark all columns as usable. The 'dbug_' version is primarily intended
inside a handler when it wants to just call Field:store() & Field::val()
functions, but don't need the column maps set for any other usage.
(ie:: bitmap_is_set() is never called)
- We can't use compare_records() to skip updates for handlers that returns
a partial column set and the read_set doesn't cover all columns in the
write set. The reason for this is that if we have a column marked only for
write we can't in the MySQL level know if the value changed or not.
The reason this worked before was that MySQL marked all to be written
columns as also to be read. The new 'optimal' bitmaps exposed this 'hidden
bug'.
- open_table_from_share() does not anymore setup temporary MEM_ROOT
object as a thread specific variable for the handler. Instead we
send the to-be-used MEMROOT to get_new_handler().
(Simpler, faster code)
Bugs fixed:
- Column marking was not done correctly in a lot of cases.
(ALTER TABLE, when using triggers, auto_increment fields etc)
(Could potentially result in wrong values inserted in table handlers
relying on that the old column maps or field->set_query_id was correct)
Especially when it comes to triggers, there may be cases where the
old code would cause lost/wrong values for NDB and/or InnoDB tables.
- Split thd->options flag OPTION_STATUS_NO_TRANS_UPDATE to two flags:
OPTION_STATUS_NO_TRANS_UPDATE and OPTION_KEEP_LOG.
This allowed me to remove some wrong warnings about:
"Some non-transactional changed tables couldn't be rolled back"
- Fixed handling of INSERT .. SELECT and CREATE ... SELECT that wrongly reset
(thd->options & OPTION_STATUS_NO_TRANS_UPDATE) which caused us to loose
some warnings about
"Some non-transactional changed tables couldn't be rolled back")
- Fixed use of uninitialized memory in ha_ndbcluster.cc::delete_table()
which could cause delete_table to report random failures.
- Fixed core dumps for some tests when running with --debug
- Added missing FN_LIBCHAR in mysql_rm_tmp_tables()
(This has probably caused us to not properly remove temporary files after
crash)
- slow_logs was not properly initialized, which could maybe cause
extra/lost entries in slow log.
- If we get an duplicate row on insert, change column map to read and
write all columns while retrying the operation. This is required by
the definition of REPLACE and also ensures that fields that are only
part of UPDATE are properly handled. This fixed a bug in NDB and
REPLACE where REPLACE wrongly copied some column values from the replaced
row.
- For table handler that doesn't support NULL in keys, we would give an error
when creating a primary key with NULL fields, even after the fields has been
automaticly converted to NOT NULL.
- Creating a primary key on a SPATIAL key, would fail if field was not
declared as NOT NULL.
Cleanups:
- Removed not used condition argument to setup_tables
- Removed not needed item function reset_query_id_processor().
- Field->add_index is removed. Now this is instead maintained in
(field->flags & FIELD_IN_ADD_INDEX)
- Field->fieldnr is removed (use field->field_index instead)
- New argument to filesort() to indicate that it should return a set of
row pointers (not used columns). This allowed me to remove some references
to sql_command in filesort and should also enable us to return column
results in some cases where we couldn't before.
- Changed column bitmap handling in opt_range.cc to be aligned with TABLE
bitmap, which allowed me to use bitmap functions instead of looping over
all fields to create some needed bitmaps. (Faster and smaller code)
- Broke up found too long lines
- Moved some variable declaration at start of function for better code
readability.
- Removed some not used arguments from functions.
(setup_fields(), mysql_prepare_insert_check_table())
- setup_fields() now takes an enum instead of an int for marking columns
usage.
- For internal temporary tables, use handler::write_row(),
handler::delete_row() and handler::update_row() instead of
handler::ha_xxxx() for faster execution.
- Changed some constants to enum's and define's.
- Using separate column read and write sets allows for easier checking
of timestamp field was set by statement.
- Remove calls to free_io_cache() as this is now done automaticly in ha_reset()
- Don't build table->normalized_path as this is now identical to table->path
(after bar's fixes to convert filenames)
- Fixed some missed DBUG_PRINT(.."%lx") to use "0x%lx" to make it easier to
do comparision with the 'convert-dbug-for-diff' tool.
Things left to do in 5.1:
- We wrongly log failed CREATE TABLE ... SELECT in some cases when using
row based logging (as shown by testcase binlog_row_mix_innodb_myisam.result)
Mats has promised to look into this.
- Test that my fix for CREATE TABLE ... SELECT is indeed correct.
(I added several test cases for this, but in this case it's better that
someone else also tests this throughly).
Lars has promosed to do this.
BitKeeper/etc/ignore:
added mysys/test_bitmap
include/base64.h:
Removed my_global.h, as this must be included first in any program
include/heap.h:
Added heap_reset() (Required by new handler interface)
include/my_base.h:
Removed HA_EXTRA_RESET. MySQL will now call ::reset() instead of ::extra(HA_EXTRA_RESET).
HA_EXTRA_RETRIVE_ALL_COLS and HA_EXTRA_RETRIVE_PRIMARY key are deleted as the column bitmaps makes these unnecessary
include/my_bitmap.h:
Remove my_pthread.h (should be included at upper level)
Introduced my_bitmap_map typedef to make it the bitmap handling more like a black box
Added bitmap_is_overlapping(), bitmap_test_and_clear(), bitmap_copy() and bitmap_cmp()
Made bitmap_set_bit(), bitmap_flip_bit(), bitmap_clear_bit() return void
include/myisam.h:
Added mi_reset() (Required by new handler interface)
include/myisammrg.h:
Added myrg_reset() (Required by new handler interface)
include/mysql_com.h:
Added flag FIELD_IN_ADD_INDEX to be able to remove Field->add_index
mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test:
Added testing of CREATE ... SELECT in a mixed environment
(This found some bugs that Mats is going to fix shortly)
mysql-test/install_test_db.sh:
Simplify ldata usage
Added --tmpdir=. option to mysqld bootstrap (Removed some warnings when TMPDIR was wrongly set)
mysql-test/mysql-test-run.pl:
Added --tmpdir=. to bootstrap
mysql-test/mysql-test-run.sh:
Use copy instead of INSTALL_DB for master and slave databases.
(Speeds up startup time a lot!)
Remove snapshot directories at startup (removes some strange warnings)
mysql-test/r/binlog_row_mix_innodb_myisam.result:
Added testing of CREATE ... SELECT in a mixed environment
(This found some bugs that Mats is going to fix shortly)
mysql-test/r/binlog_stm_mix_innodb_myisam.result:
Added testing of CREATE ... SELECT in a mixed environment
mysql-test/r/create.result:
Some extra tests of warnings and number of tables opened by CREATE ... SELECT
mysql-test/r/federated.result:
Drop some left over tables
Added testing of multiple table update and multiple table delete (with and without keys)
mysql-test/r/func_gconcat.result:
Enable some disabled tests (converted them slightly to be predictable)
mysql-test/r/func_time.result:
Added drop of test function
mysql-test/r/innodb_mysql.result:
Added tests for CREATE ... SELECT
mysql-test/r/insert.result:
More tests
Added testing of duplicate columns in insert
mysql-test/r/loaddata.result:
Added testing LOAD DATA ... SET ...
mysql-test/r/multi_update.result:
Test multi updates and deletes using primary key and without
mysql-test/r/ndb_index_unique.result:
Better error message
mysql-test/r/ndb_replace.result:
New correct result after fixing REPLACE handling with NDB
mysql-test/r/rpl_ddl.result:
Now we don't get these (wrong) warnings anymore
mysql-test/r/view_grant.result:
Drop used views
mysql-test/t/create.test:
Some extra tests of warnings and number of tables opened by CREATE ... SELECT
mysql-test/t/federated.test:
Drop some left over tables
Added testing of multiple table update and multiple table delete (with and without keys)
mysql-test/t/func_gconcat.test:
Enable some disabled tests (converted them slightly to be predictable)
mysql-test/t/func_time.test:
Added drop of test function
mysql-test/t/innodb_mysql.test:
Added tests for CREATE ... SELECT
mysql-test/t/insert.test:
More tests
Added testing of duplicate columns in insert
mysql-test/t/loaddata.test:
Added testing LOAD DATA ... SET ...
mysql-test/t/multi_update.test:
Test multi updates and deletes using primary key and without
mysql-test/t/view_grant.test:
Drop used views
mysql-test/valgrind.supp:
Added supression of not needed warnings when printing stack trace
mysys/base64.c:
Include my_global.h first
mysys/my_bitmap.c:
Added bitmap_is_overlapping(), bitmap_test_and_clear() and bitmap_copy()
Changed logic of bitmap handling to be a bit more efficent (Did this together with Mikael Ronström)
Now the 'extra, not used bits' in the bitmap are assumed to have a 'random value' and the bitmap functions are free to change them whenever needed.
Changed how mutex is allocated to make 'bitmap_free()' function simpler.
mysys/thr_lock.c:
Added 0x before thread pointers (for easier comparison of DBUG traces)
sql/event.cc:
Ensure 'use_all_columns()' is used for event tables
Don't print warning that event table is damaged if it doesn't exists.
sql/field.cc:
Added ASSERT_COLUMN_MARKED_FOR_WRITE in all store() methods and ASSERT_COLUMN_MARKED_FOR_READ in all val() methods to catch wrong setting if table->read_set and table->write_set
(Rest of changes are only indentation cleanups)
sql/field.h:
Removed Field->query_id (replaced by table->read_set and table->write_set)
Removed Field->fieldnr (use Field->field_index instead)
Removed Field->add_index (Use Field->flags instead)
Add Field->part_of_key_not_clustered (for usage in opt_range.cc)
sql/filesort.cc:
Added paramater sort_postion to filesort() to force sorting by position instead of storing all fields in the result set.
This allowed me to remove checking of sql_command.
Create a temporary column bitmap for fields that are used by the sorting process.
Use column bitmaps instead of query_id
sql/ha_berkeley.cc:
Update to 'newer' table handler interface
sql/ha_berkeley.h:
Update to 'newer' table handler interface
sql/ha_federated.cc:
Update to 'newer' table handler interface
Only read columns that are needed from remote server.
In case of eq ranges, don't generate two conditions in the WHERE clause
(this can still be optimized, but would require a bigger code change)
Use 'simpler to use' XXXX_LEN' macros
A bit simpler logic in ::write_row() when creating statements.
In update, only include test of fields actually read.
(This greatly simplifies the queries sent by the federated engine)
Similar changes done for delete_row()
sql/ha_federated.h:
Update to 'newer' table handler interface
Changed XXX_LEN macros to use sizeof(...)-1, to simplify usage in ha_federated.cc
Added HA_PRIMARY_KEY_REQUIRED_FOR_DELETE to tell MySQL to read all primary key columns in case of DELETE
sql/ha_heap.cc:
Update to 'newer' table handler interface
sql/ha_heap.h:
Update to 'newer' table handler interface
sql/ha_innodb.cc:
Update to 'newer' table handler interface
- Update innobase_create_handler() to new interface
- Removed HA_NOT_EXACT_COUNT (not needed)
- Renamed HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION.
- Prefixed base status variables with 'stats'
- Use table column bitmaps instead of ha_get_bit_in_read_set()
- Added ::reset(), with code from ::extra(HA_EXTRA_RESET)
- Removed HA_EXTRA_RETRIVE_ALL_COLS and HA_EXTRA_RETRIEVE_PRIMARY_KEY as
the table->read_set and table->write_set bitmaps now are accurate
sql/ha_innodb.h:
Update to 'newer' table handler interface
- table_flags are now ulonglong
- Added reset() method
- Removed not needed ha_retrieve_all_cols() and ha_retrieve_all_pk() columns.
- Made build_template() a class function to be able to easier access class variables
sql/ha_myisam.cc:
Update to 'newer' table handler interface
sql/ha_myisam.h:
Update to 'newer' table handler interface
sql/ha_myisammrg.cc:
Update to 'newer' table handler interface
sql/ha_myisammrg.h:
Update to 'newer' table handler interface
sql/ha_ndbcluster.cc:
Update to 'newer' table handler interface
Fixed use_blob_value() to be accurate
In ::complemented_read() we have to check both the read and write bitmap as the old code did mark all changed columns also in the read map
Correct dumping of field data with DBUG_DUMP
Prefix addresses in DBUG_PRINT with 0x
Fixed usage of not initialized memory
Update to use field->flags & FIELD_IN_ADD_INDEX instead of field->add_index.
sql/ha_ndbcluster.h:
Update to 'newer' table handler interface
sql/ha_ndbcluster_binlog.cc:
Mark usage of all columns in ndbcluster binlog tables
false -> FALSE, true -> TRUE
Use table->s->all_set instead of creating a temporary bitmap.
sql/ha_partition.cc:
Update to 'newer' table handler interface
Added memroot to initialise_partitions() and related functions to get faster memory allocation.
partition_create_handler() is now responsible for initialisation of the partition object
Some trivial optimizations and indentation fixes
Ensure that table_flags() are up to date
Removed documentation for removed HA_EXTRA flags
Fixed 'strange' usage of m_file[i] in new_handlers_from_part_info()that worked in current code 'by chance'
sql/ha_partition.h:
Update to 'newer' table handler interface
sql/handler.cc:
create_xxx handler now takes MEMROOT as an argument to simplify memory allocation.
Much simpler get_new_handler()
(Initialization of the object is now handled by the create method for the engine)
Moved all allocation of bitmap handling to the TABLE object (in table.cc)
Added column_bitmaps_signal() to signal column usage changes.
Changed binlog_log_row() to use the exiusting all_set bitmap in the table object.
Added ha_reset() function to test that the file object is ok at end of statement and call handler::reset()
Added use_hidden_primary_key() to signal handler that we we are going to read and update + delete the row and the handler should thus remember the position for the row
sql/handler.h:
Added HA_NO_TRANSACTIONS, HA_PARTIAL_COLUMN_READ, HA_REQUIRES_KEY_COLUMNS_FOR_DELETE,HA_PRIMARY_KEY_REQUIRED_FOR_DELETE and HA_HAS_RECORDS
Removed HA_NOT_EXACT_COUNT, HA_READ_RND_SAME
HA_DUPP_POS -> HA_DUPLICATE_POS
HA_NOT_EXACT_COUNT replaced by HA_STATS_RECORDS_IS_EXACT, HA_HAS_RECORDS and records()
HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS renamed to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
Added future row type 'ROW_TYPE_PAGES'
Added MEM_ROOT to handlerton 'create' function
Added ha_statistics, a structure for all status variable in the base handler class.
Moved all status variables in the handler class into a stats structs to improve readability.
ha_table_flags() is now a cached (not virtual) version of table_flags()
reset() doesn't anymore call extra(HA_EXTRA_RESET) but is a function of it's own.
Renamed dupp_ref to dup_ref
Renamed not used handler::sortkey
Moved read_set and write_set to TABLE structure
handler::init() function added for cacheing of virtual constants from engine.
sql/item.cc:
Added register_field_in_read_map() for marking used columns in expression.
This is used by filesort() for creating an optimal column bitmap while retrieving columns for sorting.
Initalize value.cs_info.character_set_client to fix core dump bug with --debug
set_query_id -> mark_used_columns
Mark used columns in read_set OR write_set.
sql/item.h:
Removed reset_query_id_processor() as it's not needed anymore.
Added register_field_in_read_map()
Added extra argument to Item::walk() to indicate if we should also
traverse sub queries.
sql/item_cmpfunc.cc:
Temporary mark used columns to be read/writable
Update Item::walk to new interface
sql/item_cmpfunc.h:
Added extra argument to Item::walk() to indicate if we should also traverse sub queries.
sql/item_func.cc:
Update Item::walk() to new interface
table_flags() -> ha_table_flags()
sql/item_func.h:
Update Item::walk() to new interface
sql/item_row.cc:
Update Item::walk() to new interface
sql/item_row.h:
Update Item::walk() to new interface
sql/item_strfunc.h:
Update Item::walk() to new interface
sql/item_subselect.cc:
Added Item_subselect::walk()
(It was a bug it was missing before. Not sure what kind of bugs this could have caused)
sql/item_subselect.h:
Update Item::walk() to new interface
sql/item_sum.cc:
Update Item::walk() to new interface
Updates for new handler interace
sql/item_sum.h:
Update Item::walk() to new interface
sql/key.cc:
Updates for new handler interace
sql/log.cc:
Mark all columns used for log tables
Split options flag
Ensured that second argument to trans_register_ha is a bool
sql/log_event.cc:
Fixed comments to be withing 79 characters
Use OPTION_KEEP_LOG instead of OPTION_STATUS_NO_TRANS_UPDATE to remove wrong warnings
Updates for new handler interface
Use 0x%lx instead of %p (portability problem)
sql/mysql_priv.h:
Added OPTION_KEEP_LOG to indicate that we should replicate the binlog even on rollback
Removed not used 'conds' argument to setup_tables
sql/mysqld.cc:
Indentation fixes and removed old comment
sql/opt_range.cc:
Update to new handler and bitmap interface.
Fixed calls to cp_buffer_from_ref() and walk() (new argument).
Create new temporary bitmaps for ror scans.
(Needed because of handler changes and to get more accurate column bitmaps than before)
Remove not needed file->ha_reset() call before file->close().
Some trivial optimization and indentation fixes.
Use Field->part_of_key_not_clustered() to check if field is part of a key, instead of looping over all key parts.
Added flag 'in_ror_merged_scan' to allow ::get_next() to know that we need a special column bitmap to only fetch pointer to record.
This is needed because ror scan uses the same TABLE object but different file objects, which creates problem for the column bitmap handling.
(This is a temporary solution. A better one would be to allocate an own TABLE object for ROR scans)
Optimized bitmap handling in ror scans:
- Start bitmap at position 0, not 1
- Use same bitmap size as in TABLE
- Use table->read_set and table->write_set to create column bitmaps instead of looping over all fields in table
sql/opt_range.h:
Added 'in_ror_merged_scan' to indicate if we are doing a ROR scan
Added temporary column bitmaps used in ROR scans
sql/opt_sum.cc:
Added get_ext_record_count() which is used in COUNT() optimization if handler has HA_HAS_RECORDS
Note that we don't call this if handler has HA_STATS_RECORDS_IS_EXACT set.
sql/protocol.cc:
We need to mark columns as readable in ::store() as we sometimes return default value for fields to the user
sql/records.cc:
Updates for new handler interface
sql/set_var.cc:
Handle splitting OPTION_STATUS_NO_TRANS_UPDATE to two flags
sql/share/errmsg.txt:
Fixed wrong
sql/sp.cc:
Mark that we are using all columns for the proc table
Update call to setup_tables() to use new prototype
sql/sp_head.cc:
Removed QQ comment
sql/spatial.cc:
Removed wrong QQ comment
sql/sql_acl.cc:
Mark that we need all columns for acl tables
Supply memroot to some 'new' calls.
Indentation fixes
sql/sql_base.cc:
set_query_id removed
Ensure we call ha_reset() at end of each statement
Mark read columns in read_set and changed columns in write_set (Before all columns was marked in read set)
Fixed marking of some columns that was not proplerly marked before
Maintain in TABLE->merge_keys set of all keys that are used in some way
Removed not used 'conds' argument from setup_tables()
Remove not used setting of 'dupp_field' in insert_fields()
Added missing FN_LIBCHAR in mysql_rm_tmp_tables()
(This has probably caused us to not properly remove temporary files after crash)
sql/sql_bitmap.h:
Added is_overlapping()
sql/sql_class.cc:
Slow_logs was not properly initialized, which could maybe cause extra/lost entries in slow log.
set_query_id -> mark_used_columns
Simpler variable usage in pack_row() (cleanup)
Moved some variable declartion at start of function for better code readability
sql/sql_class.h:
Added enum_mark_columns
Updated comments
Renamed dupp_field -> dup_field
Added virtual function 'can_rollback_data()' to select_insert() to be used in CREATE ... SELECT to optimize use of OPTION_STATUS_NO_TRANS_UPDATE.
(This fixes a bug in CREATE ... SELECT where we did give wrong warnings when using non transacational tables)
sql/sql_delete.cc:
Updates to new handler interface
Call table->mark_columns_needed_for_delete() to allow us to put additional columns in column usage maps if handler so requires.
Call table->prepare_for_position() to tell handler that we are going to call ha_position().
Removed call to free_io_cache(). (io_cache is now removed in ha_reset()).
Fixed calls to setup_tables()
sql/sql_do.cc:
Update call to setup_fields()
sql/sql_handler.cc:
Tell handler tables to always read all columns.
Use temporary column map when storing value in field for later index usage
sql/sql_help.cc:
Makr all used fields to be read
Update call to setup_fields()
sql/sql_insert.cc:
Tell handler we are going to update the auto_increment column
dupp_field -> dup_field
Set column usage bits for timestamp field.
Call table->mark_columns_needed_for_insert() and table->mark_auto_increment_column()
Removed not used argument from mysql_prepare_insert_check_table().
If we get an duplicate row on insert, change column map to read and write all columns while retrying the operatation.
This is required by the definition of REPLACE and also ensures that fields that are only part of UPDATE are properly handled.
This fixed a bug in NDB and REPLACE where REPLACE wrongly copied some column values from the replaced row.
Setup new bitmaps for delayed insert rows
Remove reseting of next_number_fields as it will be reset on next call to handler_insert()
Fixed usage of thd->options and OPTION_STATUS_NO_TRANS_UPDATE.
The issue was that one should not to reset this flag as it may be set by a previous statement.
The way it was now used caused us to loose some warnings and get other wrong warnings when using non transactional tables mixed with transactional.
I fixed it by introducing 'select_insert::can_rollback_data' to inform send_error() that the given statement can be rolled back (which in case of CREATE TABLE can always be done)
Don't close tables created with CREATE ... SELECT but keep them in the table cache.
Moved out MY_HOOKS from inside function (better readability)
sql/sql_load.cc:
Update to use new handler and column marking interface
Update using setup_tables()
sql/sql_olap.cc:
Update calls to setup_tables
Use enums instead of constants to setup_fields()
sql/sql_parse.cc:
Handle OPTION_KEEP_LOG:
- Set it on CREATE TEMPORARY TABLE / DROP TABLE
- Reset it when OPTION_STATUS_NO_TRANS_UPDATE is reset
- Don't set it for CREATE ... SELECT (this is handled in select_create class)
Remove reseting of OPTION_STATUS_NO_TRANS_UPDATE in begin_trans() as this should already be reset.
If in autocommit mode, reset OPTION_KEEP_LOG and OPTION_STATUS_NO_TRANS_UPDATE to not give warnings in future commands
sql/sql_partition.cc:
Update walk() usage
Trivial indentation fixes
sql/sql_plugin.cc:
Mark all columns as used for plugins
sql/sql_prepare.cc:
Added assert to find out hidden bugs in character_set_client (got an error in debug binary when this not set correctly)
Updates for new handler interface
Update calls to setup_fields()
sql/sql_repl.cc:
Indentation fixes
sql/sql_select.cc:
Update call to setup_tables() and setup_fields()
Remove some old disabled code
Update to new hadler interface
Indentation cleanups
Added column bitmaps for temporary tables.
Remove updating of the removed slots in the Field class
Added TABLE argument to cp_buffer_from_ref() (To be able to install temporary column maps)
For internal temporary tables, use handler::write_row(), handler::delete_row() and handler::update_row() instead of handler::ha_xxxx() for faster execution.
sql/sql_select.h:
Indentaition fixes.
Install temporary column usage maps when needed
Added TABLE element to cp_buffer_from_ref()
sql/sql_show.cc:
Update to new handler interface
Mark all columns used for internal tables.
Style fixes.
Added support for 'future' ROW_TYPE_PAGES.
Don't allocate TMP_TABLE_PARAM with calloc. The 'init()' function will initialize the structure properly.
sql/sql_table.cc:
Update to new handler interface
Simple my_snprintf -> strmake()
Changed some constants to defines
Don't test for NULL in primary key (as we a couple of line above force the PRIMARY KEY to be NOT NULL)
Change field->add_index to use field->flags & FIELD_IN_ADD_INDEX
Mark all columns as used for ALTER TABLE
Style fixes
Update call to filesort()
sql/sql_trigger.h:
Added friend functions to be able to test if triggers exists for table we are going to insert/update or delete in.
sql/sql_udf.cc:
Mark all columns as used for udf system table.
sql/sql_union.cc:
Update call to walk()
Update to new handler interface
sql/sql_update.cc:
Remove query_id argument from compare_record()
Use column bitmaps instead of query_id.
We can't use compare_records() to skip updates for handlers that returns a partial column set and the read_set doesn't cover all columns in the write set, because compare_record() can't in this case know if a not read column changed value.
Update call to setup_fields()
Using separate column read and write sets allows for easier checking of timestamp field was set by statement.
Removed call to free_io_cache() as this is now done in ha_reset()
Call table->mark_columns_needed_for_update() and table->prepare_for_position()
Style fixes
sql/sql_view.cc:
Style fixes
sql/table.cc:
Remove implicitely include 'errno.h'
Remove code for building normalized path, as this is now identical to 'path'
Remove field->fieldnr
Added update of field->part_of_key_not_clustered()
Create column bitmaps in TABLE and TABLE_SHARE
Don't setup a temporary MEM_ROOT object as a thread specific variable for the handler. Instead we send the to-be-used MEMROOT to get_new_handler()
Update to new handler interface
Update call to walk()
Added new functions:
- st_table::clear_column_bitmaps()
- st_table::prepare_for_position()
- st_table::mark_columns_used_by_index()
- st_table::restore_column_maps_after_mark_index()
- st_table::mark_columns_used_by_index_no_reset()
- st_table::mark_auto_increment_column()
- st_table::mark_columns_needed_for_delete()
- st_table::mark_columns_needed_for_update()
- st_table::mark_columns_needed_for_insert()
sql/table.h:
Moved column usage bitmaps from handler to TABLE
Added to TABLE_SHARE all_set and column_bitmap_size
Added to TABLE merge_keys, bitmap_init_values, def_read_set, def_write_set, tmp_set, read_set and write_set.
Declared all new table column bitmap functions
Added TABLE functions column_bitmaps_set(), column_bitmaps_set_no_signal(), use_all_columns() and default_column_bitmaps()
Added functions: tmp_use_all_columns() and tmp_restore_column_map() to temporarly switch column bitmaps
Added functions: dbug_tmp_use_all_columns() and dbug_tmp_restore_column_map() to temporarly switch column bitmaps to avoid asserts in Field::store() and Field::val().
sql/tztime.cc:
Mark all columns as used for timezone tables
storage/archive/ha_archive.cc:
Update to new handler interface
storage/archive/ha_archive.h:
Update to new handler interface
storage/blackhole/ha_blackhole.cc:
Update to new handler interface
storage/blackhole/ha_blackhole.h:
Update to new handler interface
removed not needed flag HA_DUPP_POS
storage/csv/ha_tina.cc:
Update to new handler interface
storage/csv/ha_tina.h:
Update to new handler interface
storage/example/ha_example.cc:
Update to new handler interface
storage/example/ha_example.h:
Update to new handler interface
storage/heap/hp_extra.c:
Added heap_reset() (Required by new handler interface)
storage/heap/hp_test2.c:
Use heap_reset()
storage/myisam/ft_boolean_search.c:
Fixed compiler warning
storage/myisam/mi_extra.c:
Added mi_reset() (Required by new handler interface)
storage/myisam/mi_search.c:
Fixed DBUG_PRINT messages to use 0x%lx instead of %lx
storage/myisam/mi_test2.c:
Use mi_reset()
storage/myisam/myisampack.c:
Use mi_reset()
storage/myisammrg/myrg_extra.c:
Added myrg_reset() (Required by new handler interface)
unittest/mysys/base64.t.c:
Include my_global.h
Don't include implictely include file 'stdlib.h'
2006-06-04 17:52:22 +02:00
|
|
|
|
2009-08-31 22:02:09 +02:00
|
|
|
bool Item_subselect::enumerate_field_refs_processor(uchar *arg)
|
2009-06-22 13:46:31 +02:00
|
|
|
{
|
2010-02-12 00:59:58 +01:00
|
|
|
List_iterator<Ref_to_outside> it(upper_refs);
|
|
|
|
Ref_to_outside *upper;
|
|
|
|
|
|
|
|
while ((upper= it++))
|
2009-06-22 13:46:31 +02:00
|
|
|
{
|
2010-02-12 00:59:58 +01:00
|
|
|
if (upper->item->walk(&Item::enumerate_field_refs_processor, FALSE, arg))
|
2009-06-22 13:46:31 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Item_subselect::mark_as_eliminated_processor(uchar *arg)
|
|
|
|
{
|
|
|
|
eliminated= TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-02-12 00:59:58 +01:00
|
|
|
|
2010-09-05 17:43:47 +02:00
|
|
|
bool Item_subselect::eliminate_subselect_processor(uchar *arg)
|
|
|
|
{
|
|
|
|
unit->item= NULL;
|
|
|
|
unit->exclude_from_tree();
|
|
|
|
eliminated= TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Adjust the master select of the subquery to be the fake_select which
|
|
|
|
represents the whole UNION right above the subquery, instead of the
|
|
|
|
last query of the UNION.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Item_subselect::set_fake_select_as_master_processor(uchar *arg)
|
|
|
|
{
|
|
|
|
SELECT_LEX *fake_select= (SELECT_LEX*) arg;
|
|
|
|
/*
|
|
|
|
Apply the substitution only for immediate child subqueries of a
|
|
|
|
UNION query.
|
|
|
|
*/
|
|
|
|
if (unit->outer_select()->master_unit()->fake_select_lex == fake_select)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Include the st_select_lex_unit of a subquery from a global ORDER BY
|
|
|
|
clause as a direct child of the fake_select of a UNION. In this way
|
|
|
|
the ORDER BY is applied to the temporary table that contains the
|
|
|
|
result of the whole UNION, and all columns in the subquery are
|
|
|
|
resolved against this table.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
Set the master of the subquery to be the fake select (i.e. the whole
|
|
|
|
UNION, instead of the last query in the UNION.
|
|
|
|
TODO: this is a hack, instead we should call:
|
|
|
|
unit->include_down(fake_select);
|
|
|
|
however, this call results in an infinite loop where
|
|
|
|
some_select_lex->master == some_select_lex.
|
|
|
|
*/
|
|
|
|
unit->set_master(fake_select);
|
|
|
|
/* Adjust the name resolution context hierarchy accordingly. */
|
|
|
|
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
|
|
|
|
sl->context.outer_context= &(fake_select->context);
|
|
|
|
/*
|
|
|
|
Undo Item_subselect::eliminate_subselect_processor because at that
|
|
|
|
phase we don't know yet (or don't know how to figure it out) that
|
|
|
|
the ORDER clause will be moved to the fake select.
|
|
|
|
*/
|
|
|
|
unit->item= this;
|
|
|
|
eliminated= FALSE;
|
|
|
|
}
|
|
|
|
return FALSE; // return TRUE ? because we need to stop processing down
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-12 00:59:58 +01:00
|
|
|
bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select,
|
|
|
|
Item *item)
|
|
|
|
{
|
|
|
|
if (inside_first_fix_fields)
|
|
|
|
{
|
|
|
|
is_correlated= TRUE;
|
|
|
|
Ref_to_outside *upper;
|
|
|
|
if (!(upper= new (thd->stmt_arena->mem_root) Ref_to_outside()))
|
|
|
|
return TRUE;
|
|
|
|
upper->select= select;
|
|
|
|
upper->item= item;
|
|
|
|
if (upper_refs.push_back(upper, thd->stmt_arena->mem_root))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-02-21 04:36:18 +01:00
|
|
|
|
2010-02-12 00:59:58 +01:00
|
|
|
/*
|
|
|
|
Adjust attributes after our parent select has been merged into grandparent
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Subquery is a composite object which may be correlated, that is, it may
|
|
|
|
have
|
|
|
|
1. references to tables of the parent select (i.e. one that has the clause
|
|
|
|
with the subquery predicate)
|
|
|
|
2. references to tables of the grandparent select
|
|
|
|
3. references to tables of further ancestors.
|
|
|
|
|
|
|
|
Before the pullout, this item indicates:
|
|
|
|
- #1 with table bits in used_tables()
|
|
|
|
- #2 and #3 with OUTER_REF_TABLE_BIT.
|
|
|
|
|
|
|
|
After parent has been merged with grandparent:
|
|
|
|
- references to parent and grandparent tables should be indicated with
|
|
|
|
table bits.
|
|
|
|
- references to greatgrandparent and further ancestors - with
|
|
|
|
OUTER_REF_TABLE_BIT.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void Item_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
|
|
|
{
|
|
|
|
recalc_used_tables(new_parent, TRUE);
|
|
|
|
parent_select= new_parent;
|
|
|
|
}
|
|
|
|
|
2010-02-21 04:36:18 +01:00
|
|
|
|
2010-02-12 00:59:58 +01:00
|
|
|
class Field_fixer: public Field_enumerator
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
table_map used_tables; /* Collect used_tables here */
|
|
|
|
st_select_lex *new_parent; /* Select we're in */
|
2010-02-21 07:32:23 +01:00
|
|
|
virtual void visit_field(Item_field *item)
|
2010-02-12 00:59:58 +01:00
|
|
|
{
|
|
|
|
//for (TABLE_LIST *tbl= new_parent->leaf_tables; tbl; tbl= tbl->next_local)
|
|
|
|
//{
|
|
|
|
// if (tbl->table == field->table)
|
|
|
|
// {
|
2010-02-21 07:32:23 +01:00
|
|
|
used_tables|= item->field->table->map;
|
2010-02-12 00:59:58 +01:00
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//used_tables |= OUTER_REF_TABLE_BIT;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Recalculate used_tables_cache
|
|
|
|
*/
|
|
|
|
|
|
|
|
void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
|
|
|
|
bool after_pullout)
|
|
|
|
{
|
|
|
|
List_iterator<Ref_to_outside> it(upper_refs);
|
|
|
|
Ref_to_outside *upper;
|
|
|
|
|
|
|
|
used_tables_cache= 0;
|
|
|
|
while ((upper= it++))
|
|
|
|
{
|
|
|
|
bool found= FALSE;
|
|
|
|
/*
|
|
|
|
Check if
|
|
|
|
1. the upper reference refers to the new immediate parent select, or
|
|
|
|
2. one of the further ancestors.
|
|
|
|
|
|
|
|
We rely on the fact that the tree of selects is modified by some kind of
|
|
|
|
'flattening', i.e. a process where child selects are merged into their
|
|
|
|
parents.
|
|
|
|
The merged selects are removed from the select tree but keep pointers to
|
|
|
|
their parents.
|
|
|
|
*/
|
|
|
|
for (st_select_lex *sel= upper->select; sel; sel= sel->outer_select())
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
If we've reached the new parent select by walking upwards from
|
|
|
|
reference's original select, this means that the reference is now
|
|
|
|
referring to the direct parent:
|
|
|
|
*/
|
|
|
|
if (sel == new_parent)
|
|
|
|
{
|
|
|
|
found= TRUE;
|
|
|
|
/*
|
|
|
|
upper->item may be NULL when we've referred to a grouping function,
|
|
|
|
in which case we don't care about what it's table_map really is,
|
|
|
|
because item->with_sum_func==1 will ensure correct placement of the
|
|
|
|
item.
|
|
|
|
*/
|
|
|
|
if (upper->item)
|
|
|
|
{
|
|
|
|
// Now, iterate over fields and collect used_tables() attribute:
|
|
|
|
Field_fixer fixer;
|
|
|
|
fixer.used_tables= 0;
|
|
|
|
fixer.new_parent= new_parent;
|
|
|
|
upper->item->walk(&Item::enumerate_field_refs_processor, FALSE,
|
|
|
|
(uchar*)&fixer);
|
|
|
|
used_tables_cache |= fixer.used_tables;
|
|
|
|
/*
|
|
|
|
if (after_pullout)
|
|
|
|
upper->item->fix_after_pullout(new_parent, &(upper->item));
|
|
|
|
upper->item->update_used_tables();
|
|
|
|
used_tables_cache |= upper->item->used_tables();
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found)
|
|
|
|
used_tables_cache|= OUTER_REF_TABLE_BIT;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
Don't update const_tables_cache yet as we don't yet know which of the
|
|
|
|
parent's tables are constant. Parent will call update_used_tables() after
|
|
|
|
he has done const table detection, and that will be our chance to update
|
|
|
|
const_tables_cache.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
This changeset is largely a handler cleanup changeset (WL#3281), but includes fixes and cleanups that was found necessary while testing the handler changes
Changes that requires code changes in other code of other storage engines.
(Note that all changes are very straightforward and one should find all issues
by compiling a --debug build and fixing all compiler errors and all
asserts in field.cc while running the test suite),
- New optional handler function introduced: reset()
This is called after every DML statement to make it easy for a handler to
statement specific cleanups.
(The only case it's not called is if force the file to be closed)
- handler::extra(HA_EXTRA_RESET) is removed. Code that was there before
should be moved to handler::reset()
- table->read_set contains a bitmap over all columns that are needed
in the query. read_row() and similar functions only needs to read these
columns
- table->write_set contains a bitmap over all columns that will be updated
in the query. write_row() and update_row() only needs to update these
columns.
The above bitmaps should now be up to date in all context
(including ALTER TABLE, filesort()).
The handler is informed of any changes to the bitmap after
fix_fields() by calling the virtual function
handler::column_bitmaps_signal(). If the handler does caching of
these bitmaps (instead of using table->read_set, table->write_set),
it should redo the caching in this code. as the signal() may be sent
several times, it's probably best to set a variable in the signal
and redo the caching on read_row() / write_row() if the variable was
set.
- Removed the read_set and write_set bitmap objects from the handler class
- Removed all column bit handling functions from the handler class.
(Now one instead uses the normal bitmap functions in my_bitmap.c instead
of handler dedicated bitmap functions)
- field->query_id is removed. One should instead instead check
table->read_set and table->write_set if a field is used in the query.
- handler::extra(HA_EXTRA_RETRIVE_ALL_COLS) and
handler::extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY) are removed. One should now
instead use table->read_set to check for which columns to retrieve.
- If a handler needs to call Field->val() or Field->store() on columns
that are not used in the query, one should install a temporary
all-columns-used map while doing so. For this, we provide the following
functions:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
field->val();
dbug_tmp_restore_column_map(table->read_set, old_map);
and similar for the write map:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
field->val();
dbug_tmp_restore_column_map(table->write_set, old_map);
If this is not done, you will sooner or later hit a DBUG_ASSERT
in the field store() / val() functions.
(For not DBUG binaries, the dbug_tmp_restore_column_map() and
dbug_tmp_restore_column_map() are inline dummy functions and should
be optimized away be the compiler).
- If one needs to temporary set the column map for all binaries (and not
just to avoid the DBUG_ASSERT() in the Field::store() / Field::val()
methods) one should use the functions tmp_use_all_columns() and
tmp_restore_column_map() instead of the above dbug_ variants.
- All 'status' fields in the handler base class (like records,
data_file_length etc) are now stored in a 'stats' struct. This makes
it easier to know what status variables are provided by the base
handler. This requires some trivial variable names in the extra()
function.
- New virtual function handler::records(). This is called to optimize
COUNT(*) if (handler::table_flags() & HA_HAS_RECORDS()) is true.
(stats.records is not supposed to be an exact value. It's only has to
be 'reasonable enough' for the optimizer to be able to choose a good
optimization path).
- Non virtual handler::init() function added for caching of virtual
constants from engine.
- Removed has_transactions() virtual method. Now one should instead return
HA_NO_TRANSACTIONS in table_flags() if the table handler DOES NOT support
transactions.
- The 'xxxx_create_handler()' function now has a MEM_ROOT_root argument
that is to be used with 'new handler_name()' to allocate the handler
in the right area. The xxxx_create_handler() function is also
responsible for any initialization of the object before returning.
For example, one should change:
static handler *myisam_create_handler(TABLE_SHARE *table)
{
return new ha_myisam(table);
}
->
static handler *myisam_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
{
return new (mem_root) ha_myisam(table);
}
- New optional virtual function: use_hidden_primary_key().
This is called in case of an update/delete when
(table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
but we don't have a primary key. This allows the handler to take precisions
in remembering any hidden primary key to able to update/delete any
found row. The default handler marks all columns to be read.
- handler::table_flags() now returns a ulonglong (to allow for more flags).
- New/changed table_flags()
- HA_HAS_RECORDS Set if ::records() is supported
- HA_NO_TRANSACTIONS Set if engine doesn't support transactions
- HA_PRIMARY_KEY_REQUIRED_FOR_DELETE
Set if we should mark all primary key columns for
read when reading rows as part of a DELETE
statement. If there is no primary key,
all columns are marked for read.
- HA_PARTIAL_COLUMN_READ Set if engine will not read all columns in some
cases (based on table->read_set)
- HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS
Renamed to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION.
- HA_DUPP_POS Renamed to HA_DUPLICATE_POS
- HA_REQUIRES_KEY_COLUMNS_FOR_DELETE
Set this if we should mark ALL key columns for
read when when reading rows as part of a DELETE
statement. In case of an update we will mark
all keys for read for which key part changed
value.
- HA_STATS_RECORDS_IS_EXACT
Set this if stats.records is exact.
(This saves us some extra records() calls
when optimizing COUNT(*))
- Removed table_flags()
- HA_NOT_EXACT_COUNT Now one should instead use HA_HAS_RECORDS if
handler::records() gives an exact count() and
HA_STATS_RECORDS_IS_EXACT if stats.records is exact.
- HA_READ_RND_SAME Removed (no one supported this one)
- Removed not needed functions ha_retrieve_all_cols() and ha_retrieve_all_pk()
- Renamed handler::dupp_pos to handler::dup_pos
- Removed not used variable handler::sortkey
Upper level handler changes:
- ha_reset() now does some overall checks and calls ::reset()
- ha_table_flags() added. This is a cached version of table_flags(). The
cache is updated on engine creation time and updated on open.
MySQL level changes (not obvious from the above):
- DBUG_ASSERT() added to check that column usage matches what is set
in the column usage bit maps. (This found a LOT of bugs in current
column marking code).
- In 5.1 before, all used columns was marked in read_set and only updated
columns was marked in write_set. Now we only mark columns for which we
need a value in read_set.
- Column bitmaps are created in open_binary_frm() and open_table_from_share().
(Before this was in table.cc)
- handler::table_flags() calls are replaced with handler::ha_table_flags()
- For calling field->val() you must have the corresponding bit set in
table->read_set. For calling field->store() you must have the
corresponding bit set in table->write_set. (There are asserts in
all store()/val() functions to catch wrong usage)
- thd->set_query_id is renamed to thd->mark_used_columns and instead
of setting this to an integer value, this has now the values:
MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE
Changed also all variables named 'set_query_id' to mark_used_columns.
- In filesort() we now inform the handler of exactly which columns are needed
doing the sort and choosing the rows.
- The TABLE_SHARE object has a 'all_set' column bitmap one can use
when one needs a column bitmap with all columns set.
(This is used for table->use_all_columns() and other places)
- The TABLE object has 3 column bitmaps:
- def_read_set Default bitmap for columns to be read
- def_write_set Default bitmap for columns to be written
- tmp_set Can be used as a temporary bitmap when needed.
The table object has also two pointer to bitmaps read_set and write_set
that the handler should use to find out which columns are used in which way.
- count() optimization now calls handler::records() instead of using
handler->stats.records (if (table_flags() & HA_HAS_RECORDS) is true).
- Added extra argument to Item::walk() to indicate if we should also
traverse sub queries.
- Added TABLE parameter to cp_buffer_from_ref()
- Don't close tables created with CREATE ... SELECT but keep them in
the table cache. (Faster usage of newly created tables).
New interfaces:
- table->clear_column_bitmaps() to initialize the bitmaps for tables
at start of new statements.
- table->column_bitmaps_set() to set up new column bitmaps and signal
the handler about this.
- table->column_bitmaps_set_no_signal() for some few cases where we need
to setup new column bitmaps but don't signal the handler (as the handler
has already been signaled about these before). Used for the momement
only in opt_range.cc when doing ROR scans.
- table->use_all_columns() to install a bitmap where all columns are marked
as use in the read and the write set.
- table->default_column_bitmaps() to install the normal read and write
column bitmaps, but not signaling the handler about this.
This is mainly used when creating TABLE instances.
- table->mark_columns_needed_for_delete(),
table->mark_columns_needed_for_delete() and
table->mark_columns_needed_for_insert() to allow us to put additional
columns in column usage maps if handler so requires.
(The handler indicates what it neads in handler->table_flags())
- table->prepare_for_position() to allow us to tell handler that it
needs to read primary key parts to be able to store them in
future table->position() calls.
(This replaces the table->file->ha_retrieve_all_pk function)
- table->mark_auto_increment_column() to tell handler are going to update
columns part of any auto_increment key.
- table->mark_columns_used_by_index() to mark all columns that is part of
an index. It will also send extra(HA_EXTRA_KEYREAD) to handler to allow
it to quickly know that it only needs to read colums that are part
of the key. (The handler can also use the column map for detecting this,
but simpler/faster handler can just monitor the extra() call).
- table->mark_columns_used_by_index_no_reset() to in addition to other columns,
also mark all columns that is used by the given key.
- table->restore_column_maps_after_mark_index() to restore to default
column maps after a call to table->mark_columns_used_by_index().
- New item function register_field_in_read_map(), for marking used columns
in table->read_map. Used by filesort() to mark all used columns
- Maintain in TABLE->merge_keys set of all keys that are used in query.
(Simplices some optimization loops)
- Maintain Field->part_of_key_not_clustered which is like Field->part_of_key
but the field in the clustered key is not assumed to be part of all index.
(used in opt_range.cc for faster loops)
- dbug_tmp_use_all_columns(), dbug_tmp_restore_column_map()
tmp_use_all_columns() and tmp_restore_column_map() functions to temporally
mark all columns as usable. The 'dbug_' version is primarily intended
inside a handler when it wants to just call Field:store() & Field::val()
functions, but don't need the column maps set for any other usage.
(ie:: bitmap_is_set() is never called)
- We can't use compare_records() to skip updates for handlers that returns
a partial column set and the read_set doesn't cover all columns in the
write set. The reason for this is that if we have a column marked only for
write we can't in the MySQL level know if the value changed or not.
The reason this worked before was that MySQL marked all to be written
columns as also to be read. The new 'optimal' bitmaps exposed this 'hidden
bug'.
- open_table_from_share() does not anymore setup temporary MEM_ROOT
object as a thread specific variable for the handler. Instead we
send the to-be-used MEMROOT to get_new_handler().
(Simpler, faster code)
Bugs fixed:
- Column marking was not done correctly in a lot of cases.
(ALTER TABLE, when using triggers, auto_increment fields etc)
(Could potentially result in wrong values inserted in table handlers
relying on that the old column maps or field->set_query_id was correct)
Especially when it comes to triggers, there may be cases where the
old code would cause lost/wrong values for NDB and/or InnoDB tables.
- Split thd->options flag OPTION_STATUS_NO_TRANS_UPDATE to two flags:
OPTION_STATUS_NO_TRANS_UPDATE and OPTION_KEEP_LOG.
This allowed me to remove some wrong warnings about:
"Some non-transactional changed tables couldn't be rolled back"
- Fixed handling of INSERT .. SELECT and CREATE ... SELECT that wrongly reset
(thd->options & OPTION_STATUS_NO_TRANS_UPDATE) which caused us to loose
some warnings about
"Some non-transactional changed tables couldn't be rolled back")
- Fixed use of uninitialized memory in ha_ndbcluster.cc::delete_table()
which could cause delete_table to report random failures.
- Fixed core dumps for some tests when running with --debug
- Added missing FN_LIBCHAR in mysql_rm_tmp_tables()
(This has probably caused us to not properly remove temporary files after
crash)
- slow_logs was not properly initialized, which could maybe cause
extra/lost entries in slow log.
- If we get an duplicate row on insert, change column map to read and
write all columns while retrying the operation. This is required by
the definition of REPLACE and also ensures that fields that are only
part of UPDATE are properly handled. This fixed a bug in NDB and
REPLACE where REPLACE wrongly copied some column values from the replaced
row.
- For table handler that doesn't support NULL in keys, we would give an error
when creating a primary key with NULL fields, even after the fields has been
automaticly converted to NOT NULL.
- Creating a primary key on a SPATIAL key, would fail if field was not
declared as NOT NULL.
Cleanups:
- Removed not used condition argument to setup_tables
- Removed not needed item function reset_query_id_processor().
- Field->add_index is removed. Now this is instead maintained in
(field->flags & FIELD_IN_ADD_INDEX)
- Field->fieldnr is removed (use field->field_index instead)
- New argument to filesort() to indicate that it should return a set of
row pointers (not used columns). This allowed me to remove some references
to sql_command in filesort and should also enable us to return column
results in some cases where we couldn't before.
- Changed column bitmap handling in opt_range.cc to be aligned with TABLE
bitmap, which allowed me to use bitmap functions instead of looping over
all fields to create some needed bitmaps. (Faster and smaller code)
- Broke up found too long lines
- Moved some variable declaration at start of function for better code
readability.
- Removed some not used arguments from functions.
(setup_fields(), mysql_prepare_insert_check_table())
- setup_fields() now takes an enum instead of an int for marking columns
usage.
- For internal temporary tables, use handler::write_row(),
handler::delete_row() and handler::update_row() instead of
handler::ha_xxxx() for faster execution.
- Changed some constants to enum's and define's.
- Using separate column read and write sets allows for easier checking
of timestamp field was set by statement.
- Remove calls to free_io_cache() as this is now done automaticly in ha_reset()
- Don't build table->normalized_path as this is now identical to table->path
(after bar's fixes to convert filenames)
- Fixed some missed DBUG_PRINT(.."%lx") to use "0x%lx" to make it easier to
do comparision with the 'convert-dbug-for-diff' tool.
Things left to do in 5.1:
- We wrongly log failed CREATE TABLE ... SELECT in some cases when using
row based logging (as shown by testcase binlog_row_mix_innodb_myisam.result)
Mats has promised to look into this.
- Test that my fix for CREATE TABLE ... SELECT is indeed correct.
(I added several test cases for this, but in this case it's better that
someone else also tests this throughly).
Lars has promosed to do this.
BitKeeper/etc/ignore:
added mysys/test_bitmap
include/base64.h:
Removed my_global.h, as this must be included first in any program
include/heap.h:
Added heap_reset() (Required by new handler interface)
include/my_base.h:
Removed HA_EXTRA_RESET. MySQL will now call ::reset() instead of ::extra(HA_EXTRA_RESET).
HA_EXTRA_RETRIVE_ALL_COLS and HA_EXTRA_RETRIVE_PRIMARY key are deleted as the column bitmaps makes these unnecessary
include/my_bitmap.h:
Remove my_pthread.h (should be included at upper level)
Introduced my_bitmap_map typedef to make it the bitmap handling more like a black box
Added bitmap_is_overlapping(), bitmap_test_and_clear(), bitmap_copy() and bitmap_cmp()
Made bitmap_set_bit(), bitmap_flip_bit(), bitmap_clear_bit() return void
include/myisam.h:
Added mi_reset() (Required by new handler interface)
include/myisammrg.h:
Added myrg_reset() (Required by new handler interface)
include/mysql_com.h:
Added flag FIELD_IN_ADD_INDEX to be able to remove Field->add_index
mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test:
Added testing of CREATE ... SELECT in a mixed environment
(This found some bugs that Mats is going to fix shortly)
mysql-test/install_test_db.sh:
Simplify ldata usage
Added --tmpdir=. option to mysqld bootstrap (Removed some warnings when TMPDIR was wrongly set)
mysql-test/mysql-test-run.pl:
Added --tmpdir=. to bootstrap
mysql-test/mysql-test-run.sh:
Use copy instead of INSTALL_DB for master and slave databases.
(Speeds up startup time a lot!)
Remove snapshot directories at startup (removes some strange warnings)
mysql-test/r/binlog_row_mix_innodb_myisam.result:
Added testing of CREATE ... SELECT in a mixed environment
(This found some bugs that Mats is going to fix shortly)
mysql-test/r/binlog_stm_mix_innodb_myisam.result:
Added testing of CREATE ... SELECT in a mixed environment
mysql-test/r/create.result:
Some extra tests of warnings and number of tables opened by CREATE ... SELECT
mysql-test/r/federated.result:
Drop some left over tables
Added testing of multiple table update and multiple table delete (with and without keys)
mysql-test/r/func_gconcat.result:
Enable some disabled tests (converted them slightly to be predictable)
mysql-test/r/func_time.result:
Added drop of test function
mysql-test/r/innodb_mysql.result:
Added tests for CREATE ... SELECT
mysql-test/r/insert.result:
More tests
Added testing of duplicate columns in insert
mysql-test/r/loaddata.result:
Added testing LOAD DATA ... SET ...
mysql-test/r/multi_update.result:
Test multi updates and deletes using primary key and without
mysql-test/r/ndb_index_unique.result:
Better error message
mysql-test/r/ndb_replace.result:
New correct result after fixing REPLACE handling with NDB
mysql-test/r/rpl_ddl.result:
Now we don't get these (wrong) warnings anymore
mysql-test/r/view_grant.result:
Drop used views
mysql-test/t/create.test:
Some extra tests of warnings and number of tables opened by CREATE ... SELECT
mysql-test/t/federated.test:
Drop some left over tables
Added testing of multiple table update and multiple table delete (with and without keys)
mysql-test/t/func_gconcat.test:
Enable some disabled tests (converted them slightly to be predictable)
mysql-test/t/func_time.test:
Added drop of test function
mysql-test/t/innodb_mysql.test:
Added tests for CREATE ... SELECT
mysql-test/t/insert.test:
More tests
Added testing of duplicate columns in insert
mysql-test/t/loaddata.test:
Added testing LOAD DATA ... SET ...
mysql-test/t/multi_update.test:
Test multi updates and deletes using primary key and without
mysql-test/t/view_grant.test:
Drop used views
mysql-test/valgrind.supp:
Added supression of not needed warnings when printing stack trace
mysys/base64.c:
Include my_global.h first
mysys/my_bitmap.c:
Added bitmap_is_overlapping(), bitmap_test_and_clear() and bitmap_copy()
Changed logic of bitmap handling to be a bit more efficent (Did this together with Mikael Ronström)
Now the 'extra, not used bits' in the bitmap are assumed to have a 'random value' and the bitmap functions are free to change them whenever needed.
Changed how mutex is allocated to make 'bitmap_free()' function simpler.
mysys/thr_lock.c:
Added 0x before thread pointers (for easier comparison of DBUG traces)
sql/event.cc:
Ensure 'use_all_columns()' is used for event tables
Don't print warning that event table is damaged if it doesn't exists.
sql/field.cc:
Added ASSERT_COLUMN_MARKED_FOR_WRITE in all store() methods and ASSERT_COLUMN_MARKED_FOR_READ in all val() methods to catch wrong setting if table->read_set and table->write_set
(Rest of changes are only indentation cleanups)
sql/field.h:
Removed Field->query_id (replaced by table->read_set and table->write_set)
Removed Field->fieldnr (use Field->field_index instead)
Removed Field->add_index (Use Field->flags instead)
Add Field->part_of_key_not_clustered (for usage in opt_range.cc)
sql/filesort.cc:
Added paramater sort_postion to filesort() to force sorting by position instead of storing all fields in the result set.
This allowed me to remove checking of sql_command.
Create a temporary column bitmap for fields that are used by the sorting process.
Use column bitmaps instead of query_id
sql/ha_berkeley.cc:
Update to 'newer' table handler interface
sql/ha_berkeley.h:
Update to 'newer' table handler interface
sql/ha_federated.cc:
Update to 'newer' table handler interface
Only read columns that are needed from remote server.
In case of eq ranges, don't generate two conditions in the WHERE clause
(this can still be optimized, but would require a bigger code change)
Use 'simpler to use' XXXX_LEN' macros
A bit simpler logic in ::write_row() when creating statements.
In update, only include test of fields actually read.
(This greatly simplifies the queries sent by the federated engine)
Similar changes done for delete_row()
sql/ha_federated.h:
Update to 'newer' table handler interface
Changed XXX_LEN macros to use sizeof(...)-1, to simplify usage in ha_federated.cc
Added HA_PRIMARY_KEY_REQUIRED_FOR_DELETE to tell MySQL to read all primary key columns in case of DELETE
sql/ha_heap.cc:
Update to 'newer' table handler interface
sql/ha_heap.h:
Update to 'newer' table handler interface
sql/ha_innodb.cc:
Update to 'newer' table handler interface
- Update innobase_create_handler() to new interface
- Removed HA_NOT_EXACT_COUNT (not needed)
- Renamed HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION.
- Prefixed base status variables with 'stats'
- Use table column bitmaps instead of ha_get_bit_in_read_set()
- Added ::reset(), with code from ::extra(HA_EXTRA_RESET)
- Removed HA_EXTRA_RETRIVE_ALL_COLS and HA_EXTRA_RETRIEVE_PRIMARY_KEY as
the table->read_set and table->write_set bitmaps now are accurate
sql/ha_innodb.h:
Update to 'newer' table handler interface
- table_flags are now ulonglong
- Added reset() method
- Removed not needed ha_retrieve_all_cols() and ha_retrieve_all_pk() columns.
- Made build_template() a class function to be able to easier access class variables
sql/ha_myisam.cc:
Update to 'newer' table handler interface
sql/ha_myisam.h:
Update to 'newer' table handler interface
sql/ha_myisammrg.cc:
Update to 'newer' table handler interface
sql/ha_myisammrg.h:
Update to 'newer' table handler interface
sql/ha_ndbcluster.cc:
Update to 'newer' table handler interface
Fixed use_blob_value() to be accurate
In ::complemented_read() we have to check both the read and write bitmap as the old code did mark all changed columns also in the read map
Correct dumping of field data with DBUG_DUMP
Prefix addresses in DBUG_PRINT with 0x
Fixed usage of not initialized memory
Update to use field->flags & FIELD_IN_ADD_INDEX instead of field->add_index.
sql/ha_ndbcluster.h:
Update to 'newer' table handler interface
sql/ha_ndbcluster_binlog.cc:
Mark usage of all columns in ndbcluster binlog tables
false -> FALSE, true -> TRUE
Use table->s->all_set instead of creating a temporary bitmap.
sql/ha_partition.cc:
Update to 'newer' table handler interface
Added memroot to initialise_partitions() and related functions to get faster memory allocation.
partition_create_handler() is now responsible for initialisation of the partition object
Some trivial optimizations and indentation fixes
Ensure that table_flags() are up to date
Removed documentation for removed HA_EXTRA flags
Fixed 'strange' usage of m_file[i] in new_handlers_from_part_info()that worked in current code 'by chance'
sql/ha_partition.h:
Update to 'newer' table handler interface
sql/handler.cc:
create_xxx handler now takes MEMROOT as an argument to simplify memory allocation.
Much simpler get_new_handler()
(Initialization of the object is now handled by the create method for the engine)
Moved all allocation of bitmap handling to the TABLE object (in table.cc)
Added column_bitmaps_signal() to signal column usage changes.
Changed binlog_log_row() to use the exiusting all_set bitmap in the table object.
Added ha_reset() function to test that the file object is ok at end of statement and call handler::reset()
Added use_hidden_primary_key() to signal handler that we we are going to read and update + delete the row and the handler should thus remember the position for the row
sql/handler.h:
Added HA_NO_TRANSACTIONS, HA_PARTIAL_COLUMN_READ, HA_REQUIRES_KEY_COLUMNS_FOR_DELETE,HA_PRIMARY_KEY_REQUIRED_FOR_DELETE and HA_HAS_RECORDS
Removed HA_NOT_EXACT_COUNT, HA_READ_RND_SAME
HA_DUPP_POS -> HA_DUPLICATE_POS
HA_NOT_EXACT_COUNT replaced by HA_STATS_RECORDS_IS_EXACT, HA_HAS_RECORDS and records()
HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS renamed to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
Added future row type 'ROW_TYPE_PAGES'
Added MEM_ROOT to handlerton 'create' function
Added ha_statistics, a structure for all status variable in the base handler class.
Moved all status variables in the handler class into a stats structs to improve readability.
ha_table_flags() is now a cached (not virtual) version of table_flags()
reset() doesn't anymore call extra(HA_EXTRA_RESET) but is a function of it's own.
Renamed dupp_ref to dup_ref
Renamed not used handler::sortkey
Moved read_set and write_set to TABLE structure
handler::init() function added for cacheing of virtual constants from engine.
sql/item.cc:
Added register_field_in_read_map() for marking used columns in expression.
This is used by filesort() for creating an optimal column bitmap while retrieving columns for sorting.
Initalize value.cs_info.character_set_client to fix core dump bug with --debug
set_query_id -> mark_used_columns
Mark used columns in read_set OR write_set.
sql/item.h:
Removed reset_query_id_processor() as it's not needed anymore.
Added register_field_in_read_map()
Added extra argument to Item::walk() to indicate if we should also
traverse sub queries.
sql/item_cmpfunc.cc:
Temporary mark used columns to be read/writable
Update Item::walk to new interface
sql/item_cmpfunc.h:
Added extra argument to Item::walk() to indicate if we should also traverse sub queries.
sql/item_func.cc:
Update Item::walk() to new interface
table_flags() -> ha_table_flags()
sql/item_func.h:
Update Item::walk() to new interface
sql/item_row.cc:
Update Item::walk() to new interface
sql/item_row.h:
Update Item::walk() to new interface
sql/item_strfunc.h:
Update Item::walk() to new interface
sql/item_subselect.cc:
Added Item_subselect::walk()
(It was a bug it was missing before. Not sure what kind of bugs this could have caused)
sql/item_subselect.h:
Update Item::walk() to new interface
sql/item_sum.cc:
Update Item::walk() to new interface
Updates for new handler interace
sql/item_sum.h:
Update Item::walk() to new interface
sql/key.cc:
Updates for new handler interace
sql/log.cc:
Mark all columns used for log tables
Split options flag
Ensured that second argument to trans_register_ha is a bool
sql/log_event.cc:
Fixed comments to be withing 79 characters
Use OPTION_KEEP_LOG instead of OPTION_STATUS_NO_TRANS_UPDATE to remove wrong warnings
Updates for new handler interface
Use 0x%lx instead of %p (portability problem)
sql/mysql_priv.h:
Added OPTION_KEEP_LOG to indicate that we should replicate the binlog even on rollback
Removed not used 'conds' argument to setup_tables
sql/mysqld.cc:
Indentation fixes and removed old comment
sql/opt_range.cc:
Update to new handler and bitmap interface.
Fixed calls to cp_buffer_from_ref() and walk() (new argument).
Create new temporary bitmaps for ror scans.
(Needed because of handler changes and to get more accurate column bitmaps than before)
Remove not needed file->ha_reset() call before file->close().
Some trivial optimization and indentation fixes.
Use Field->part_of_key_not_clustered() to check if field is part of a key, instead of looping over all key parts.
Added flag 'in_ror_merged_scan' to allow ::get_next() to know that we need a special column bitmap to only fetch pointer to record.
This is needed because ror scan uses the same TABLE object but different file objects, which creates problem for the column bitmap handling.
(This is a temporary solution. A better one would be to allocate an own TABLE object for ROR scans)
Optimized bitmap handling in ror scans:
- Start bitmap at position 0, not 1
- Use same bitmap size as in TABLE
- Use table->read_set and table->write_set to create column bitmaps instead of looping over all fields in table
sql/opt_range.h:
Added 'in_ror_merged_scan' to indicate if we are doing a ROR scan
Added temporary column bitmaps used in ROR scans
sql/opt_sum.cc:
Added get_ext_record_count() which is used in COUNT() optimization if handler has HA_HAS_RECORDS
Note that we don't call this if handler has HA_STATS_RECORDS_IS_EXACT set.
sql/protocol.cc:
We need to mark columns as readable in ::store() as we sometimes return default value for fields to the user
sql/records.cc:
Updates for new handler interface
sql/set_var.cc:
Handle splitting OPTION_STATUS_NO_TRANS_UPDATE to two flags
sql/share/errmsg.txt:
Fixed wrong
sql/sp.cc:
Mark that we are using all columns for the proc table
Update call to setup_tables() to use new prototype
sql/sp_head.cc:
Removed QQ comment
sql/spatial.cc:
Removed wrong QQ comment
sql/sql_acl.cc:
Mark that we need all columns for acl tables
Supply memroot to some 'new' calls.
Indentation fixes
sql/sql_base.cc:
set_query_id removed
Ensure we call ha_reset() at end of each statement
Mark read columns in read_set and changed columns in write_set (Before all columns was marked in read set)
Fixed marking of some columns that was not proplerly marked before
Maintain in TABLE->merge_keys set of all keys that are used in some way
Removed not used 'conds' argument from setup_tables()
Remove not used setting of 'dupp_field' in insert_fields()
Added missing FN_LIBCHAR in mysql_rm_tmp_tables()
(This has probably caused us to not properly remove temporary files after crash)
sql/sql_bitmap.h:
Added is_overlapping()
sql/sql_class.cc:
Slow_logs was not properly initialized, which could maybe cause extra/lost entries in slow log.
set_query_id -> mark_used_columns
Simpler variable usage in pack_row() (cleanup)
Moved some variable declartion at start of function for better code readability
sql/sql_class.h:
Added enum_mark_columns
Updated comments
Renamed dupp_field -> dup_field
Added virtual function 'can_rollback_data()' to select_insert() to be used in CREATE ... SELECT to optimize use of OPTION_STATUS_NO_TRANS_UPDATE.
(This fixes a bug in CREATE ... SELECT where we did give wrong warnings when using non transacational tables)
sql/sql_delete.cc:
Updates to new handler interface
Call table->mark_columns_needed_for_delete() to allow us to put additional columns in column usage maps if handler so requires.
Call table->prepare_for_position() to tell handler that we are going to call ha_position().
Removed call to free_io_cache(). (io_cache is now removed in ha_reset()).
Fixed calls to setup_tables()
sql/sql_do.cc:
Update call to setup_fields()
sql/sql_handler.cc:
Tell handler tables to always read all columns.
Use temporary column map when storing value in field for later index usage
sql/sql_help.cc:
Makr all used fields to be read
Update call to setup_fields()
sql/sql_insert.cc:
Tell handler we are going to update the auto_increment column
dupp_field -> dup_field
Set column usage bits for timestamp field.
Call table->mark_columns_needed_for_insert() and table->mark_auto_increment_column()
Removed not used argument from mysql_prepare_insert_check_table().
If we get an duplicate row on insert, change column map to read and write all columns while retrying the operatation.
This is required by the definition of REPLACE and also ensures that fields that are only part of UPDATE are properly handled.
This fixed a bug in NDB and REPLACE where REPLACE wrongly copied some column values from the replaced row.
Setup new bitmaps for delayed insert rows
Remove reseting of next_number_fields as it will be reset on next call to handler_insert()
Fixed usage of thd->options and OPTION_STATUS_NO_TRANS_UPDATE.
The issue was that one should not to reset this flag as it may be set by a previous statement.
The way it was now used caused us to loose some warnings and get other wrong warnings when using non transactional tables mixed with transactional.
I fixed it by introducing 'select_insert::can_rollback_data' to inform send_error() that the given statement can be rolled back (which in case of CREATE TABLE can always be done)
Don't close tables created with CREATE ... SELECT but keep them in the table cache.
Moved out MY_HOOKS from inside function (better readability)
sql/sql_load.cc:
Update to use new handler and column marking interface
Update using setup_tables()
sql/sql_olap.cc:
Update calls to setup_tables
Use enums instead of constants to setup_fields()
sql/sql_parse.cc:
Handle OPTION_KEEP_LOG:
- Set it on CREATE TEMPORARY TABLE / DROP TABLE
- Reset it when OPTION_STATUS_NO_TRANS_UPDATE is reset
- Don't set it for CREATE ... SELECT (this is handled in select_create class)
Remove reseting of OPTION_STATUS_NO_TRANS_UPDATE in begin_trans() as this should already be reset.
If in autocommit mode, reset OPTION_KEEP_LOG and OPTION_STATUS_NO_TRANS_UPDATE to not give warnings in future commands
sql/sql_partition.cc:
Update walk() usage
Trivial indentation fixes
sql/sql_plugin.cc:
Mark all columns as used for plugins
sql/sql_prepare.cc:
Added assert to find out hidden bugs in character_set_client (got an error in debug binary when this not set correctly)
Updates for new handler interface
Update calls to setup_fields()
sql/sql_repl.cc:
Indentation fixes
sql/sql_select.cc:
Update call to setup_tables() and setup_fields()
Remove some old disabled code
Update to new hadler interface
Indentation cleanups
Added column bitmaps for temporary tables.
Remove updating of the removed slots in the Field class
Added TABLE argument to cp_buffer_from_ref() (To be able to install temporary column maps)
For internal temporary tables, use handler::write_row(), handler::delete_row() and handler::update_row() instead of handler::ha_xxxx() for faster execution.
sql/sql_select.h:
Indentaition fixes.
Install temporary column usage maps when needed
Added TABLE element to cp_buffer_from_ref()
sql/sql_show.cc:
Update to new handler interface
Mark all columns used for internal tables.
Style fixes.
Added support for 'future' ROW_TYPE_PAGES.
Don't allocate TMP_TABLE_PARAM with calloc. The 'init()' function will initialize the structure properly.
sql/sql_table.cc:
Update to new handler interface
Simple my_snprintf -> strmake()
Changed some constants to defines
Don't test for NULL in primary key (as we a couple of line above force the PRIMARY KEY to be NOT NULL)
Change field->add_index to use field->flags & FIELD_IN_ADD_INDEX
Mark all columns as used for ALTER TABLE
Style fixes
Update call to filesort()
sql/sql_trigger.h:
Added friend functions to be able to test if triggers exists for table we are going to insert/update or delete in.
sql/sql_udf.cc:
Mark all columns as used for udf system table.
sql/sql_union.cc:
Update call to walk()
Update to new handler interface
sql/sql_update.cc:
Remove query_id argument from compare_record()
Use column bitmaps instead of query_id.
We can't use compare_records() to skip updates for handlers that returns a partial column set and the read_set doesn't cover all columns in the write set, because compare_record() can't in this case know if a not read column changed value.
Update call to setup_fields()
Using separate column read and write sets allows for easier checking of timestamp field was set by statement.
Removed call to free_io_cache() as this is now done in ha_reset()
Call table->mark_columns_needed_for_update() and table->prepare_for_position()
Style fixes
sql/sql_view.cc:
Style fixes
sql/table.cc:
Remove implicitely include 'errno.h'
Remove code for building normalized path, as this is now identical to 'path'
Remove field->fieldnr
Added update of field->part_of_key_not_clustered()
Create column bitmaps in TABLE and TABLE_SHARE
Don't setup a temporary MEM_ROOT object as a thread specific variable for the handler. Instead we send the to-be-used MEMROOT to get_new_handler()
Update to new handler interface
Update call to walk()
Added new functions:
- st_table::clear_column_bitmaps()
- st_table::prepare_for_position()
- st_table::mark_columns_used_by_index()
- st_table::restore_column_maps_after_mark_index()
- st_table::mark_columns_used_by_index_no_reset()
- st_table::mark_auto_increment_column()
- st_table::mark_columns_needed_for_delete()
- st_table::mark_columns_needed_for_update()
- st_table::mark_columns_needed_for_insert()
sql/table.h:
Moved column usage bitmaps from handler to TABLE
Added to TABLE_SHARE all_set and column_bitmap_size
Added to TABLE merge_keys, bitmap_init_values, def_read_set, def_write_set, tmp_set, read_set and write_set.
Declared all new table column bitmap functions
Added TABLE functions column_bitmaps_set(), column_bitmaps_set_no_signal(), use_all_columns() and default_column_bitmaps()
Added functions: tmp_use_all_columns() and tmp_restore_column_map() to temporarly switch column bitmaps
Added functions: dbug_tmp_use_all_columns() and dbug_tmp_restore_column_map() to temporarly switch column bitmaps to avoid asserts in Field::store() and Field::val().
sql/tztime.cc:
Mark all columns as used for timezone tables
storage/archive/ha_archive.cc:
Update to new handler interface
storage/archive/ha_archive.h:
Update to new handler interface
storage/blackhole/ha_blackhole.cc:
Update to new handler interface
storage/blackhole/ha_blackhole.h:
Update to new handler interface
removed not needed flag HA_DUPP_POS
storage/csv/ha_tina.cc:
Update to new handler interface
storage/csv/ha_tina.h:
Update to new handler interface
storage/example/ha_example.cc:
Update to new handler interface
storage/example/ha_example.h:
Update to new handler interface
storage/heap/hp_extra.c:
Added heap_reset() (Required by new handler interface)
storage/heap/hp_test2.c:
Use heap_reset()
storage/myisam/ft_boolean_search.c:
Fixed compiler warning
storage/myisam/mi_extra.c:
Added mi_reset() (Required by new handler interface)
storage/myisam/mi_search.c:
Fixed DBUG_PRINT messages to use 0x%lx instead of %lx
storage/myisam/mi_test2.c:
Use mi_reset()
storage/myisam/myisampack.c:
Use mi_reset()
storage/myisammrg/myrg_extra.c:
Added myrg_reset() (Required by new handler interface)
unittest/mysys/base64.t.c:
Include my_global.h
Don't include implictely include file 'stdlib.h'
2006-06-04 17:52:22 +02:00
|
|
|
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
BitKeeper/etc/ignore:
added libmysqld/ha_ndbcluster_cond.cc
---
added debian/defs.mk debian/control
client/completion_hash.cc:
Remove not needed casts
client/my_readline.h:
Remove some old types
client/mysql.cc:
Simplify types
client/mysql_upgrade.c:
Remove some old types
Update call to dirname_part
client/mysqladmin.cc:
Remove some old types
client/mysqlbinlog.cc:
Remove some old types
Change some buffers to be uchar to avoid casts
client/mysqlcheck.c:
Remove some old types
client/mysqldump.c:
Remove some old types
Remove some not needed casts
Change some string lengths to size_t
client/mysqlimport.c:
Remove some old types
client/mysqlshow.c:
Remove some old types
client/mysqlslap.c:
Remove some old types
Remove some not needed casts
client/mysqltest.c:
Removed some old types
Removed some not needed casts
Updated hash-get-key function arguments
Updated parameters to dirname_part()
client/readline.cc:
Removed some old types
Removed some not needed casts
Changed some string lengths to use size_t
client/sql_string.cc:
Removed some old types
dbug/dbug.c:
Removed some old types
Changed some string lengths to use size_t
Changed some prototypes to avoid casts
extra/comp_err.c:
Removed some old types
extra/innochecksum.c:
Removed some old types
extra/my_print_defaults.c:
Removed some old types
extra/mysql_waitpid.c:
Removed some old types
extra/perror.c:
Removed some old types
extra/replace.c:
Removed some old types
Updated parameters to dirname_part()
extra/resolve_stack_dump.c:
Removed some old types
extra/resolveip.c:
Removed some old types
include/config-win.h:
Removed some old types
include/decimal.h:
Changed binary strings to be uchar* instead of char*
include/ft_global.h:
Removed some old types
include/hash.h:
Removed some old types
include/heap.h:
Removed some old types
Changed records_under_level to be 'ulong' instead of 'uint' to clarify usage of variable
include/keycache.h:
Removed some old types
include/m_ctype.h:
Removed some old types
Changed some string lengths to use size_t
Changed character length functions to return uint
unsigned char -> uchar
include/m_string.h:
Removed some old types
Changed some string lengths to use size_t
include/my_alloc.h:
Changed some string lengths to use size_t
include/my_base.h:
Removed some old types
include/my_dbug.h:
Removed some old types
Changed some string lengths to use size_t
Changed db_dump() to take uchar * as argument for memory to reduce number of casts in usage
include/my_getopt.h:
Removed some old types
include/my_global.h:
Removed old types:
my_size_t -> size_t
byte -> uchar
gptr -> uchar *
include/my_list.h:
Removed some old types
include/my_nosys.h:
Removed some old types
include/my_pthread.h:
Removed some old types
include/my_sys.h:
Removed some old types
Changed MY_FILE_ERROR to be in line with new definitions of my_write()/my_read()
Changed some string lengths to use size_t
my_malloc() / my_free() now uses void *
Updated parameters to dirname_part() & my_uncompress()
include/my_tree.h:
Removed some old types
include/my_trie.h:
Removed some old types
include/my_user.h:
Changed some string lengths to use size_t
include/my_vle.h:
Removed some old types
include/my_xml.h:
Removed some old types
Changed some string lengths to use size_t
include/myisam.h:
Removed some old types
include/myisammrg.h:
Removed some old types
include/mysql.h:
Removed some old types
Changed byte streams to use uchar* instead of char*
include/mysql_com.h:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
include/queues.h:
Removed some old types
include/sql_common.h:
Removed some old types
include/sslopt-longopts.h:
Removed some old types
include/violite.h:
Removed some old types
Changed some string lengths to use size_t
libmysql/client_settings.h:
Removed some old types
libmysql/libmysql.c:
Removed some old types
libmysql/manager.c:
Removed some old types
libmysqld/emb_qcache.cc:
Removed some old types
libmysqld/emb_qcache.h:
Removed some old types
libmysqld/lib_sql.cc:
Removed some old types
Removed some not needed casts
Changed some buffers to be uchar* to avoid casts
true -> TRUE, false -> FALSE
mysys/array.c:
Removed some old types
mysys/charset.c:
Changed some string lengths to use size_t
mysys/checksum.c:
Include zlib to get definition for crc32
Removed some old types
mysys/default.c:
Removed some old types
Changed some string lengths to use size_t
mysys/default_modify.c:
Changed some string lengths to use size_t
Removed some not needed casts
mysys/hash.c:
Removed some old types
Changed some string lengths to use size_t
Note: Prototype of hash_key() has changed which may cause problems if client uses hash_init() with a cast for the hash-get-key function.
hash_element now takes 'ulong' as the index type (cleanup)
mysys/list.c:
Removed some old types
mysys/mf_cache.c:
Changed some string lengths to use size_t
mysys/mf_dirname.c:
Removed some old types
Changed some string lengths to use size_t
Added argument to dirname_part() to avoid calculation of length for 'to'
mysys/mf_fn_ext.c:
Removed some old types
Updated parameters to dirname_part()
mysys/mf_format.c:
Removed some old types
Changed some string lengths to use size_t
mysys/mf_getdate.c:
Removed some old types
mysys/mf_iocache.c:
Removed some old types
Changed some string lengths to use size_t
Changed calculation of 'max_length' to be done the same way in all functions
mysys/mf_iocache2.c:
Removed some old types
Changed some string lengths to use size_t
Clean up comments
Removed not needed indentation
mysys/mf_keycache.c:
Removed some old types
mysys/mf_keycaches.c:
Removed some old types
mysys/mf_loadpath.c:
Removed some old types
mysys/mf_pack.c:
Removed some old types
Changed some string lengths to use size_t
Removed some not needed casts
Removed very old VMS code
Updated parameters to dirname_part()
Use result of dirnam_part() to remove call to strcat()
mysys/mf_path.c:
Removed some old types
mysys/mf_radix.c:
Removed some old types
mysys/mf_same.c:
Removed some old types
mysys/mf_sort.c:
Removed some old types
mysys/mf_soundex.c:
Removed some old types
mysys/mf_strip.c:
Removed some old types
mysys/mf_tempdir.c:
Removed some old types
mysys/mf_unixpath.c:
Removed some old types
mysys/mf_wfile.c:
Removed some old types
mysys/mulalloc.c:
Removed some old types
mysys/my_alloc.c:
Removed some old types
Changed some string lengths to use size_t
Use void* as type for allocated memory area
Removed some not needed casts
Changed argument 'Size' to 'length' according coding guidelines
mysys/my_chsize.c:
Changed some buffers to be uchar* to avoid casts
mysys/my_compress.c:
More comments
Removed some old types
Changed string lengths to use size_t
Changed arguments to my_uncompress() to make them easier to understand
Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix)
Changed type of 'pack_data' argument to packfrm() to avoid casts.
mysys/my_conio.c:
Changed some string lengths to use size_t
mysys/my_create.c:
Removed some old types
mysys/my_div.c:
Removed some old types
mysys/my_error.c:
Removed some old types
mysys/my_fopen.c:
Removed some old types
mysys/my_fstream.c:
Removed some old types
Changed some string lengths to use size_t
writen -> written
mysys/my_getopt.c:
Removed some old types
mysys/my_getwd.c:
Removed some old types
More comments
mysys/my_init.c:
Removed some old types
mysys/my_largepage.c:
Removed some old types
Changed some string lengths to use size_t
mysys/my_lib.c:
Removed some old types
mysys/my_lockmem.c:
Removed some old types
mysys/my_malloc.c:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed all functions to use size_t
mysys/my_memmem.c:
Indentation cleanup
mysys/my_once.c:
Removed some old types
Changed malloc(), free() and related functions to use void *
mysys/my_open.c:
Removed some old types
mysys/my_pread.c:
Removed some old types
Changed all functions to use size_t
Added comment for how my_pread() / my_pwrite() are supposed to work.
Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe.
(If we ever would really need this, it should be enabled only with a flag argument)
mysys/my_quick.c:
Removed some old types
Changed all functions to use size_t
mysys/my_read.c:
Removed some old types
Changed all functions to use size_t
mysys/my_realloc.c:
Removed some old types
Use void* as type for allocated memory area
Changed all functions to use size_t
mysys/my_static.c:
Removed some old types
mysys/my_static.h:
Removed some old types
mysys/my_vle.c:
Removed some old types
mysys/my_wincond.c:
Removed some old types
mysys/my_windac.c:
Removed some old types
mysys/my_write.c:
Removed some old types
Changed all functions to use size_t
mysys/ptr_cmp.c:
Removed some old types
Changed all functions to use size_t
mysys/queues.c:
Removed some old types
mysys/safemalloc.c:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed all functions to use size_t
mysys/string.c:
Removed some old types
Changed all functions to use size_t
mysys/testhash.c:
Removed some old types
mysys/thr_alarm.c:
Removed some old types
mysys/thr_lock.c:
Removed some old types
mysys/tree.c:
Removed some old types
mysys/trie.c:
Removed some old types
mysys/typelib.c:
Removed some old types
plugin/daemon_example/daemon_example.cc:
Removed some old types
regex/reginit.c:
Removed some old types
server-tools/instance-manager/buffer.cc:
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/buffer.h:
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/commands.cc:
Removed some old types
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/instance_map.cc:
Removed some old types
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/instance_options.cc:
Changed buffer to be of type uchar*
Replaced alloc_root + strcpy() with strdup_root()
server-tools/instance-manager/mysql_connection.cc:
Changed buffer to be of type uchar*
server-tools/instance-manager/options.cc:
Removed some old types
server-tools/instance-manager/parse.cc:
Changed some string lengths to use size_t
server-tools/instance-manager/parse.h:
Removed some old types
Changed some string lengths to use size_t
server-tools/instance-manager/protocol.cc:
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
server-tools/instance-manager/protocol.h:
Changed some string lengths to use size_t
server-tools/instance-manager/user_map.cc:
Removed some old types
Changed some string lengths to use size_t
sql/derror.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
sql/discover.cc:
Changed in readfrm() and writefrom() the type for argument 'frmdata' to uchar** to avoid casts
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
sql/event_data_objects.cc:
Removed some old types
Added missing casts for alloc() and sprintf()
sql/event_db_repository.cc:
Changed some buffers to be uchar* to avoid casts
Added missing casts for sprintf()
sql/event_queue.cc:
Removed some old types
sql/field.cc:
Removed some old types
Changed memory buffers to be uchar*
Changed some string lengths to use size_t
Removed a lot of casts
Safety fix in Field_blob::val_decimal() to not access zero pointer
sql/field.h:
Removed some old types
Changed memory buffers to be uchar* (except of store() as this would have caused too many other changes).
Changed some string lengths to use size_t
Removed some not needed casts
Changed val_xxx(xxx, new_ptr) to take const pointers
sql/field_conv.cc:
Removed some old types
Added casts required because memory area pointers are now uchar*
sql/filesort.cc:
Initalize variable that was used unitialized in error conditions
sql/gen_lex_hash.cc:
Removed some old types
Changed memory buffers to be uchar*
Changed some string lengths to use size_t
Removed a lot of casts
Safety fix in Field_blob::val_decimal() to not access zero pointer
sql/gstream.h:
Added required cast
sql/ha_ndbcluster.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some buffers to be uchar* to avoid casts
Added required casts
Removed some not needed casts
sql/ha_ndbcluster.h:
Removed some old types
sql/ha_ndbcluster_binlog.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Replaced sql_alloc() + memcpy() + set end 0 with sql_strmake()
Changed some string lengths to use size_t
Added missing casts for alloc() and sprintf()
sql/ha_ndbcluster_binlog.h:
Removed some old types
sql/ha_ndbcluster_cond.cc:
Removed some old types
Removed some not needed casts
sql/ha_ndbcluster_cond.h:
Removed some old types
sql/ha_partition.cc:
Removed some old types
Changed prototype for change_partition() to avoid casts
sql/ha_partition.h:
Removed some old types
sql/handler.cc:
Removed some old types
Changed some string lengths to use size_t
sql/handler.h:
Removed some old types
Changed some string lengths to use size_t
Changed type for 'frmblob' parameter for discover() and ha_discover() to get fewer casts
sql/hash_filo.h:
Removed some old types
Changed all functions to use size_t
sql/hostname.cc:
Removed some old types
sql/item.cc:
Removed some old types
Changed some string lengths to use size_t
Use strmake() instead of memdup() to create a null terminated string.
Updated calls to new Field()
sql/item.h:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed some buffers to be uchar* to avoid casts
sql/item_cmpfunc.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/item_cmpfunc.h:
Removed some old types
sql/item_create.cc:
Removed some old types
sql/item_func.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
Added test for failing alloc() in init_result_field()
Remove old confusing comment
Fixed compiler warning
sql/item_func.h:
Removed some old types
sql/item_row.cc:
Removed some old types
sql/item_row.h:
Removed some old types
sql/item_strfunc.cc:
Include zlib (needed becasue we call crc32)
Removed some old types
sql/item_strfunc.h:
Removed some old types
Changed some types to match new function prototypes
sql/item_subselect.cc:
Removed some old types
sql/item_subselect.h:
Removed some old types
sql/item_sum.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/item_sum.h:
Removed some old types
sql/item_timefunc.cc:
Removed some old types
Changed some string lengths to use size_t
sql/item_timefunc.h:
Removed some old types
sql/item_xmlfunc.cc:
Changed some string lengths to use size_t
sql/item_xmlfunc.h:
Removed some old types
sql/key.cc:
Removed some old types
Removed some not needed casts
sql/lock.cc:
Removed some old types
Added some cast to my_multi_malloc() arguments for safety
sql/log.cc:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
Changed usage of pwrite() to not assume it holds the cursor position for the file
Made usage of my_read() safer
sql/log_event.cc:
Removed some old types
Added checking of return value of malloc() in pack_info()
Changed some buffers to be uchar* to avoid casts
Removed some 'const' to avoid casts
Added missing casts for alloc() and sprintf()
Added required casts
Removed some not needed casts
Added some cast to my_multi_malloc() arguments for safety
sql/log_event.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/log_event_old.cc:
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/log_event_old.h:
Changed some buffers to be uchar* to avoid casts
sql/mf_iocache.cc:
Removed some old types
sql/my_decimal.cc:
Changed memory area to use uchar*
sql/my_decimal.h:
Changed memory area to use uchar*
sql/mysql_priv.h:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed some string lengths to use size_t
Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid long overflow
Changed some buffers to be uchar* to avoid casts
sql/mysqld.cc:
Removed some old types
sql/net_serv.cc:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
Ensure that vio_read()/vio_write() return values are stored in a size_t variable
Removed some not needed casts
sql/opt_range.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/opt_range.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/opt_sum.cc:
Removed some old types
Removed some not needed casts
sql/parse_file.cc:
Removed some old types
Changed some string lengths to use size_t
Changed alloc_root + memcpy + set end 0 -> strmake_root()
sql/parse_file.h:
Removed some old types
sql/partition_info.cc:
Removed some old types
Added missing casts for alloc()
Changed some buffers to be uchar* to avoid casts
sql/partition_info.h:
Changed some buffers to be uchar* to avoid casts
sql/protocol.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/protocol.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
sql/records.cc:
Removed some old types
sql/repl_failsafe.cc:
Removed some old types
Changed some string lengths to use size_t
Added required casts
sql/rpl_filter.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some string lengths to use size_t
sql/rpl_filter.h:
Changed some string lengths to use size_t
sql/rpl_injector.h:
Removed some old types
sql/rpl_record.cc:
Removed some old types
Removed some not needed casts
Changed some buffers to be uchar* to avoid casts
sql/rpl_record.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/rpl_record_old.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/rpl_record_old.h:
Removed some old types
Changed some buffers to be uchar* to avoid cast
sql/rpl_rli.cc:
Removed some old types
sql/rpl_tblmap.cc:
Removed some old types
sql/rpl_tblmap.h:
Removed some old types
sql/rpl_utility.cc:
Removed some old types
sql/rpl_utility.h:
Removed some old types
Changed type of m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length
sql/set_var.cc:
Removed some old types
Updated parameters to dirname_part()
sql/set_var.h:
Removed some old types
sql/slave.cc:
Removed some old types
Changed some string lengths to use size_t
sql/slave.h:
Removed some old types
sql/sp.cc:
Removed some old types
Added missing casts for printf()
sql/sp.h:
Removed some old types
Updated hash-get-key function arguments
sql/sp_cache.cc:
Removed some old types
Added missing casts for printf()
Updated hash-get-key function arguments
sql/sp_head.cc:
Removed some old types
Added missing casts for alloc() and printf()
Added required casts
Updated hash-get-key function arguments
sql/sp_head.h:
Removed some old types
sql/sp_pcontext.cc:
Removed some old types
sql/sp_pcontext.h:
Removed some old types
sql/sql_acl.cc:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
Added required casts
sql/sql_analyse.cc:
Changed some buffers to be uchar* to avoid casts
sql/sql_analyse.h:
Changed some buffers to be uchar* to avoid casts
sql/sql_array.h:
Removed some old types
sql/sql_base.cc:
Removed some old types
Updated hash-get-key function arguments
sql/sql_binlog.cc:
Removed some old types
Added missing casts for printf()
sql/sql_cache.cc:
Removed some old types
Updated hash-get-key function arguments
Removed some not needed casts
Changed some string lengths to use size_t
sql/sql_cache.h:
Removed some old types
Removed reference to not existing function cache_key()
Updated hash-get-key function arguments
sql/sql_class.cc:
Removed some old types
Updated hash-get-key function arguments
Added missing casts for alloc()
Updated hash-get-key function arguments
Moved THD::max_row_length() to table.cc (as it's not depending on THD)
Removed some not needed casts
sql/sql_class.h:
Removed some old types
Changed malloc(), free() and related functions to use void *
Removed some not needed casts
Changed some string lengths to use size_t
Moved max_row_length and max_row_length_blob() to table.cc, as they are not depending on THD
sql/sql_connect.cc:
Removed some old types
Added required casts
sql/sql_db.cc:
Removed some old types
Removed some not needed casts
Added some cast to my_multi_malloc() arguments for safety
Added missing casts for alloc()
sql/sql_delete.cc:
Removed some old types
sql/sql_handler.cc:
Removed some old types
Updated hash-get-key function arguments
Added some cast to my_multi_malloc() arguments for safety
sql/sql_help.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/sql_insert.cc:
Removed some old types
Added missing casts for alloc() and printf()
sql/sql_lex.cc:
Removed some old types
sql/sql_lex.h:
Removed some old types
Removed some not needed casts
sql/sql_list.h:
Removed some old types
Removed some not needed casts
sql/sql_load.cc:
Removed some old types
Removed compiler warning
sql/sql_manager.cc:
Removed some old types
sql/sql_map.cc:
Removed some old types
sql/sql_map.h:
Removed some old types
sql/sql_olap.cc:
Removed some old types
sql/sql_parse.cc:
Removed some old types
Trivial move of code lines to make things more readable
Changed some string lengths to use size_t
Added missing casts for alloc()
sql/sql_partition.cc:
Removed some old types
Removed compiler warnings about not used functions
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/sql_partition.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/sql_plugin.cc:
Removed some old types
Added missing casts for alloc()
Updated hash-get-key function arguments
sql/sql_prepare.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Added missing casts for alloc() and printf()
sql-common/client.c:
Removed some old types
Changed some memory areas to use uchar*
sql-common/my_user.c:
Changed some string lengths to use size_t
sql-common/pack.c:
Changed some buffers to be uchar* to avoid casts
sql/sql_repl.cc:
Added required casts
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
sql/sql_select.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some old types
sql/sql_select.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/sql_servers.cc:
Removed some old types
Updated hash-get-key function arguments
sql/sql_show.cc:
Removed some old types
Added missing casts for alloc()
Removed some not needed casts
sql/sql_string.cc:
Removed some old types
Added required casts
sql/sql_table.cc:
Removed some old types
Removed compiler warning about not used variable
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/sql_test.cc:
Removed some old types
sql/sql_trigger.cc:
Removed some old types
Added missing casts for alloc()
sql/sql_udf.cc:
Removed some old types
Updated hash-get-key function arguments
sql/sql_union.cc:
Removed some old types
sql/sql_update.cc:
Removed some old types
Removed some not needed casts
sql/sql_view.cc:
Removed some old types
sql/sql_yacc.yy:
Removed some old types
Changed some string lengths to use size_t
Added missing casts for alloc()
sql/stacktrace.c:
Removed some old types
sql/stacktrace.h:
Removed some old types
sql/structs.h:
Removed some old types
sql/table.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some buffers to be uchar* to avoid casts
Removed setting of LEX_STRING() arguments in declaration
Added required casts
More function comments
Moved max_row_length() here from sql_class.cc/sql_class.h
sql/table.h:
Removed some old types
Changed some string lengths to use size_t
sql/thr_malloc.cc:
Use void* as type for allocated memory area
Changed all functions to use size_t
sql/tzfile.h:
Changed some buffers to be uchar* to avoid casts
sql/tztime.cc:
Changed some buffers to be uchar* to avoid casts
Updated hash-get-key function arguments
Added missing casts for alloc()
Removed some not needed casts
sql/uniques.cc:
Removed some old types
Removed some not needed casts
sql/unireg.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
Added missing casts for alloc()
storage/archive/archive_reader.c:
Removed some old types
storage/archive/azio.c:
Removed some old types
Removed some not needed casts
storage/archive/ha_archive.cc:
Removed some old types
Changed type for 'frmblob' in archive_discover() to match handler
Updated hash-get-key function arguments
Removed some not needed casts
storage/archive/ha_archive.h:
Removed some old types
storage/blackhole/ha_blackhole.cc:
Removed some old types
storage/blackhole/ha_blackhole.h:
Removed some old types
storage/csv/ha_tina.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some buffers to be uchar* to avoid casts
storage/csv/ha_tina.h:
Removed some old types
Removed some not needed casts
storage/csv/transparent_file.cc:
Removed some old types
Changed type of 'bytes_read' to be able to detect read errors
Fixed indentation
storage/csv/transparent_file.h:
Removed some old types
storage/example/ha_example.cc:
Removed some old types
Updated hash-get-key function arguments
storage/example/ha_example.h:
Removed some old types
storage/federated/ha_federated.cc:
Removed some old types
Updated hash-get-key function arguments
Removed some not needed casts
storage/federated/ha_federated.h:
Removed some old types
storage/heap/_check.c:
Changed some buffers to be uchar* to avoid casts
storage/heap/_rectest.c:
Removed some old types
storage/heap/ha_heap.cc:
Removed some old types
storage/heap/ha_heap.h:
Removed some old types
storage/heap/heapdef.h:
Removed some old types
storage/heap/hp_block.c:
Removed some old types
Changed some string lengths to use size_t
storage/heap/hp_clear.c:
Removed some old types
storage/heap/hp_close.c:
Removed some old types
storage/heap/hp_create.c:
Removed some old types
storage/heap/hp_delete.c:
Removed some old types
storage/heap/hp_hash.c:
Removed some old types
storage/heap/hp_info.c:
Removed some old types
storage/heap/hp_open.c:
Removed some old types
storage/heap/hp_rfirst.c:
Removed some old types
storage/heap/hp_rkey.c:
Removed some old types
storage/heap/hp_rlast.c:
Removed some old types
storage/heap/hp_rnext.c:
Removed some old types
storage/heap/hp_rprev.c:
Removed some old types
storage/heap/hp_rrnd.c:
Removed some old types
storage/heap/hp_rsame.c:
Removed some old types
storage/heap/hp_scan.c:
Removed some old types
storage/heap/hp_test1.c:
Removed some old types
storage/heap/hp_test2.c:
Removed some old types
storage/heap/hp_update.c:
Removed some old types
storage/heap/hp_write.c:
Removed some old types
Changed some string lengths to use size_t
storage/innobase/handler/ha_innodb.cc:
Removed some old types
Updated hash-get-key function arguments
Added missing casts for alloc() and printf()
Removed some not needed casts
storage/innobase/handler/ha_innodb.h:
Removed some old types
storage/myisam/ft_boolean_search.c:
Removed some old types
storage/myisam/ft_nlq_search.c:
Removed some old types
storage/myisam/ft_parser.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/ft_static.c:
Removed some old types
storage/myisam/ft_stopwords.c:
Removed some old types
storage/myisam/ft_update.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/ftdefs.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/fulltext.h:
Removed some old types
storage/myisam/ha_myisam.cc:
Removed some old types
storage/myisam/ha_myisam.h:
Removed some old types
storage/myisam/mi_cache.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/mi_check.c:
Removed some old types
storage/myisam/mi_checksum.c:
Removed some old types
storage/myisam/mi_close.c:
Removed some old types
storage/myisam/mi_create.c:
Removed some old types
storage/myisam/mi_delete.c:
Removed some old types
storage/myisam/mi_delete_all.c:
Removed some old types
storage/myisam/mi_dynrec.c:
Removed some old types
storage/myisam/mi_extra.c:
Removed some old types
storage/myisam/mi_key.c:
Removed some old types
storage/myisam/mi_locking.c:
Removed some old types
storage/myisam/mi_log.c:
Removed some old types
storage/myisam/mi_open.c:
Removed some old types
Removed some not needed casts
Check argument of my_write()/my_pwrite() in functions returning int
Added casting of string lengths to size_t
storage/myisam/mi_packrec.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/mi_page.c:
Removed some old types
storage/myisam/mi_preload.c:
Removed some old types
storage/myisam/mi_range.c:
Removed some old types
storage/myisam/mi_rfirst.c:
Removed some old types
storage/myisam/mi_rkey.c:
Removed some old types
storage/myisam/mi_rlast.c:
Removed some old types
storage/myisam/mi_rnext.c:
Removed some old types
storage/myisam/mi_rnext_same.c:
Removed some old types
storage/myisam/mi_rprev.c:
Removed some old types
storage/myisam/mi_rrnd.c:
Removed some old types
storage/myisam/mi_rsame.c:
Removed some old types
storage/myisam/mi_rsamepos.c:
Removed some old types
storage/myisam/mi_scan.c:
Removed some old types
storage/myisam/mi_search.c:
Removed some old types
storage/myisam/mi_static.c:
Removed some old types
storage/myisam/mi_statrec.c:
Removed some old types
storage/myisam/mi_test1.c:
Removed some old types
storage/myisam/mi_test2.c:
Removed some old types
storage/myisam/mi_test3.c:
Removed some old types
storage/myisam/mi_unique.c:
Removed some old types
storage/myisam/mi_update.c:
Removed some old types
storage/myisam/mi_write.c:
Removed some old types
storage/myisam/myisam_ftdump.c:
Removed some old types
storage/myisam/myisamchk.c:
Removed some old types
storage/myisam/myisamdef.h:
Removed some old types
storage/myisam/myisamlog.c:
Removed some old types
Indentation fix
storage/myisam/myisampack.c:
Removed some old types
storage/myisam/rt_index.c:
Removed some old types
storage/myisam/rt_split.c:
Removed some old types
storage/myisam/sort.c:
Removed some old types
storage/myisam/sp_defs.h:
Removed some old types
storage/myisam/sp_key.c:
Removed some old types
storage/myisammrg/ha_myisammrg.cc:
Removed some old types
storage/myisammrg/ha_myisammrg.h:
Removed some old types
storage/myisammrg/myrg_close.c:
Removed some old types
storage/myisammrg/myrg_def.h:
Removed some old types
storage/myisammrg/myrg_delete.c:
Removed some old types
storage/myisammrg/myrg_open.c:
Removed some old types
Updated parameters to dirname_part()
storage/myisammrg/myrg_queue.c:
Removed some old types
storage/myisammrg/myrg_rfirst.c:
Removed some old types
storage/myisammrg/myrg_rkey.c:
Removed some old types
storage/myisammrg/myrg_rlast.c:
Removed some old types
storage/myisammrg/myrg_rnext.c:
Removed some old types
storage/myisammrg/myrg_rnext_same.c:
Removed some old types
storage/myisammrg/myrg_rprev.c:
Removed some old types
storage/myisammrg/myrg_rrnd.c:
Removed some old types
storage/myisammrg/myrg_rsame.c:
Removed some old types
storage/myisammrg/myrg_update.c:
Removed some old types
storage/myisammrg/myrg_write.c:
Removed some old types
storage/ndb/include/util/ndb_opts.h:
Removed some old types
storage/ndb/src/cw/cpcd/main.cpp:
Removed some old types
storage/ndb/src/kernel/vm/Configuration.cpp:
Removed some old types
storage/ndb/src/mgmclient/main.cpp:
Removed some old types
storage/ndb/src/mgmsrv/InitConfigFileParser.cpp:
Removed some old types
Removed old disabled code
storage/ndb/src/mgmsrv/main.cpp:
Removed some old types
storage/ndb/src/ndbapi/NdbBlob.cpp:
Removed some old types
storage/ndb/src/ndbapi/NdbOperationDefine.cpp:
Removed not used variable
storage/ndb/src/ndbapi/NdbOperationInt.cpp:
Added required casts
storage/ndb/src/ndbapi/NdbScanOperation.cpp:
Added required casts
storage/ndb/tools/delete_all.cpp:
Removed some old types
storage/ndb/tools/desc.cpp:
Removed some old types
storage/ndb/tools/drop_index.cpp:
Removed some old types
storage/ndb/tools/drop_tab.cpp:
Removed some old types
storage/ndb/tools/listTables.cpp:
Removed some old types
storage/ndb/tools/ndb_config.cpp:
Removed some old types
storage/ndb/tools/restore/consumer_restore.cpp:
Changed some buffers to be uchar* to avoid casts with new defintion of packfrm()
storage/ndb/tools/restore/restore_main.cpp:
Removed some old types
storage/ndb/tools/select_all.cpp:
Removed some old types
storage/ndb/tools/select_count.cpp:
Removed some old types
storage/ndb/tools/waiter.cpp:
Removed some old types
strings/bchange.c:
Changed function to use uchar * and size_t
strings/bcmp.c:
Changed function to use uchar * and size_t
strings/bmove512.c:
Changed function to use uchar * and size_t
strings/bmove_upp.c:
Changed function to use uchar * and size_t
strings/ctype-big5.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-bin.c:
Changed functions to use size_t
strings/ctype-cp932.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-czech.c:
Fixed indentation
Changed functions to use size_t
strings/ctype-euc_kr.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-eucjpms.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-gb2312.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-gbk.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-latin1.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-mb.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-simple.c:
Changed functions to use size_t
Simpler loops for caseup/casedown
unsigned int -> uint
unsigned char -> uchar
strings/ctype-sjis.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-tis620.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-uca.c:
Changed functions to use size_t
unsigned char -> uchar
strings/ctype-ucs2.c:
Moved inclusion of stdarg.h to other includes
usigned char -> uchar
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-ujis.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-utf8.c:
Changed functions to use size_t
unsigned char -> uchar
Indentation fixes
strings/ctype-win1250ch.c:
Indentation fixes
Changed functions to use size_t
strings/ctype.c:
Changed functions to use size_t
strings/decimal.c:
Changed type for memory argument to uchar *
strings/do_ctype.c:
Indentation fixes
strings/my_strtoll10.c:
unsigned char -> uchar
strings/my_vsnprintf.c:
Changed functions to use size_t
strings/r_strinstr.c:
Removed some old types
Changed functions to use size_t
strings/str_test.c:
Removed some old types
strings/strappend.c:
Changed functions to use size_t
strings/strcont.c:
Removed some old types
strings/strfill.c:
Removed some old types
strings/strinstr.c:
Changed functions to use size_t
strings/strlen.c:
Changed functions to use size_t
strings/strmake.c:
Changed functions to use size_t
strings/strnlen.c:
Changed functions to use size_t
strings/strnmov.c:
Changed functions to use size_t
strings/strto.c:
unsigned char -> uchar
strings/strtod.c:
Changed functions to use size_t
strings/strxnmov.c:
Changed functions to use size_t
strings/xml.c:
Changed functions to use size_t
Indentation fixes
tests/mysql_client_test.c:
Removed some old types
tests/thread_test.c:
Removed some old types
vio/test-ssl.c:
Removed some old types
vio/test-sslclient.c:
Removed some old types
vio/test-sslserver.c:
Removed some old types
vio/vio.c:
Removed some old types
vio/vio_priv.h:
Removed some old types
Changed vio_read()/vio_write() to work with size_t
vio/viosocket.c:
Changed vio_read()/vio_write() to work with size_t
Indentation fixes
vio/viossl.c:
Changed vio_read()/vio_write() to work with size_t
Indentation fixes
vio/viosslfactories.c:
Removed some old types
vio/viotest-ssl.c:
Removed some old types
win/README:
More explanations
2007-05-10 11:59:39 +02:00
|
|
|
uchar *argument)
|
This changeset is largely a handler cleanup changeset (WL#3281), but includes fixes and cleanups that was found necessary while testing the handler changes
Changes that requires code changes in other code of other storage engines.
(Note that all changes are very straightforward and one should find all issues
by compiling a --debug build and fixing all compiler errors and all
asserts in field.cc while running the test suite),
- New optional handler function introduced: reset()
This is called after every DML statement to make it easy for a handler to
statement specific cleanups.
(The only case it's not called is if force the file to be closed)
- handler::extra(HA_EXTRA_RESET) is removed. Code that was there before
should be moved to handler::reset()
- table->read_set contains a bitmap over all columns that are needed
in the query. read_row() and similar functions only needs to read these
columns
- table->write_set contains a bitmap over all columns that will be updated
in the query. write_row() and update_row() only needs to update these
columns.
The above bitmaps should now be up to date in all context
(including ALTER TABLE, filesort()).
The handler is informed of any changes to the bitmap after
fix_fields() by calling the virtual function
handler::column_bitmaps_signal(). If the handler does caching of
these bitmaps (instead of using table->read_set, table->write_set),
it should redo the caching in this code. as the signal() may be sent
several times, it's probably best to set a variable in the signal
and redo the caching on read_row() / write_row() if the variable was
set.
- Removed the read_set and write_set bitmap objects from the handler class
- Removed all column bit handling functions from the handler class.
(Now one instead uses the normal bitmap functions in my_bitmap.c instead
of handler dedicated bitmap functions)
- field->query_id is removed. One should instead instead check
table->read_set and table->write_set if a field is used in the query.
- handler::extra(HA_EXTRA_RETRIVE_ALL_COLS) and
handler::extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY) are removed. One should now
instead use table->read_set to check for which columns to retrieve.
- If a handler needs to call Field->val() or Field->store() on columns
that are not used in the query, one should install a temporary
all-columns-used map while doing so. For this, we provide the following
functions:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
field->val();
dbug_tmp_restore_column_map(table->read_set, old_map);
and similar for the write map:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
field->val();
dbug_tmp_restore_column_map(table->write_set, old_map);
If this is not done, you will sooner or later hit a DBUG_ASSERT
in the field store() / val() functions.
(For not DBUG binaries, the dbug_tmp_restore_column_map() and
dbug_tmp_restore_column_map() are inline dummy functions and should
be optimized away be the compiler).
- If one needs to temporary set the column map for all binaries (and not
just to avoid the DBUG_ASSERT() in the Field::store() / Field::val()
methods) one should use the functions tmp_use_all_columns() and
tmp_restore_column_map() instead of the above dbug_ variants.
- All 'status' fields in the handler base class (like records,
data_file_length etc) are now stored in a 'stats' struct. This makes
it easier to know what status variables are provided by the base
handler. This requires some trivial variable names in the extra()
function.
- New virtual function handler::records(). This is called to optimize
COUNT(*) if (handler::table_flags() & HA_HAS_RECORDS()) is true.
(stats.records is not supposed to be an exact value. It's only has to
be 'reasonable enough' for the optimizer to be able to choose a good
optimization path).
- Non virtual handler::init() function added for caching of virtual
constants from engine.
- Removed has_transactions() virtual method. Now one should instead return
HA_NO_TRANSACTIONS in table_flags() if the table handler DOES NOT support
transactions.
- The 'xxxx_create_handler()' function now has a MEM_ROOT_root argument
that is to be used with 'new handler_name()' to allocate the handler
in the right area. The xxxx_create_handler() function is also
responsible for any initialization of the object before returning.
For example, one should change:
static handler *myisam_create_handler(TABLE_SHARE *table)
{
return new ha_myisam(table);
}
->
static handler *myisam_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
{
return new (mem_root) ha_myisam(table);
}
- New optional virtual function: use_hidden_primary_key().
This is called in case of an update/delete when
(table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
but we don't have a primary key. This allows the handler to take precisions
in remembering any hidden primary key to able to update/delete any
found row. The default handler marks all columns to be read.
- handler::table_flags() now returns a ulonglong (to allow for more flags).
- New/changed table_flags()
- HA_HAS_RECORDS Set if ::records() is supported
- HA_NO_TRANSACTIONS Set if engine doesn't support transactions
- HA_PRIMARY_KEY_REQUIRED_FOR_DELETE
Set if we should mark all primary key columns for
read when reading rows as part of a DELETE
statement. If there is no primary key,
all columns are marked for read.
- HA_PARTIAL_COLUMN_READ Set if engine will not read all columns in some
cases (based on table->read_set)
- HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS
Renamed to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION.
- HA_DUPP_POS Renamed to HA_DUPLICATE_POS
- HA_REQUIRES_KEY_COLUMNS_FOR_DELETE
Set this if we should mark ALL key columns for
read when when reading rows as part of a DELETE
statement. In case of an update we will mark
all keys for read for which key part changed
value.
- HA_STATS_RECORDS_IS_EXACT
Set this if stats.records is exact.
(This saves us some extra records() calls
when optimizing COUNT(*))
- Removed table_flags()
- HA_NOT_EXACT_COUNT Now one should instead use HA_HAS_RECORDS if
handler::records() gives an exact count() and
HA_STATS_RECORDS_IS_EXACT if stats.records is exact.
- HA_READ_RND_SAME Removed (no one supported this one)
- Removed not needed functions ha_retrieve_all_cols() and ha_retrieve_all_pk()
- Renamed handler::dupp_pos to handler::dup_pos
- Removed not used variable handler::sortkey
Upper level handler changes:
- ha_reset() now does some overall checks and calls ::reset()
- ha_table_flags() added. This is a cached version of table_flags(). The
cache is updated on engine creation time and updated on open.
MySQL level changes (not obvious from the above):
- DBUG_ASSERT() added to check that column usage matches what is set
in the column usage bit maps. (This found a LOT of bugs in current
column marking code).
- In 5.1 before, all used columns was marked in read_set and only updated
columns was marked in write_set. Now we only mark columns for which we
need a value in read_set.
- Column bitmaps are created in open_binary_frm() and open_table_from_share().
(Before this was in table.cc)
- handler::table_flags() calls are replaced with handler::ha_table_flags()
- For calling field->val() you must have the corresponding bit set in
table->read_set. For calling field->store() you must have the
corresponding bit set in table->write_set. (There are asserts in
all store()/val() functions to catch wrong usage)
- thd->set_query_id is renamed to thd->mark_used_columns and instead
of setting this to an integer value, this has now the values:
MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE
Changed also all variables named 'set_query_id' to mark_used_columns.
- In filesort() we now inform the handler of exactly which columns are needed
doing the sort and choosing the rows.
- The TABLE_SHARE object has a 'all_set' column bitmap one can use
when one needs a column bitmap with all columns set.
(This is used for table->use_all_columns() and other places)
- The TABLE object has 3 column bitmaps:
- def_read_set Default bitmap for columns to be read
- def_write_set Default bitmap for columns to be written
- tmp_set Can be used as a temporary bitmap when needed.
The table object has also two pointer to bitmaps read_set and write_set
that the handler should use to find out which columns are used in which way.
- count() optimization now calls handler::records() instead of using
handler->stats.records (if (table_flags() & HA_HAS_RECORDS) is true).
- Added extra argument to Item::walk() to indicate if we should also
traverse sub queries.
- Added TABLE parameter to cp_buffer_from_ref()
- Don't close tables created with CREATE ... SELECT but keep them in
the table cache. (Faster usage of newly created tables).
New interfaces:
- table->clear_column_bitmaps() to initialize the bitmaps for tables
at start of new statements.
- table->column_bitmaps_set() to set up new column bitmaps and signal
the handler about this.
- table->column_bitmaps_set_no_signal() for some few cases where we need
to setup new column bitmaps but don't signal the handler (as the handler
has already been signaled about these before). Used for the momement
only in opt_range.cc when doing ROR scans.
- table->use_all_columns() to install a bitmap where all columns are marked
as use in the read and the write set.
- table->default_column_bitmaps() to install the normal read and write
column bitmaps, but not signaling the handler about this.
This is mainly used when creating TABLE instances.
- table->mark_columns_needed_for_delete(),
table->mark_columns_needed_for_delete() and
table->mark_columns_needed_for_insert() to allow us to put additional
columns in column usage maps if handler so requires.
(The handler indicates what it neads in handler->table_flags())
- table->prepare_for_position() to allow us to tell handler that it
needs to read primary key parts to be able to store them in
future table->position() calls.
(This replaces the table->file->ha_retrieve_all_pk function)
- table->mark_auto_increment_column() to tell handler are going to update
columns part of any auto_increment key.
- table->mark_columns_used_by_index() to mark all columns that is part of
an index. It will also send extra(HA_EXTRA_KEYREAD) to handler to allow
it to quickly know that it only needs to read colums that are part
of the key. (The handler can also use the column map for detecting this,
but simpler/faster handler can just monitor the extra() call).
- table->mark_columns_used_by_index_no_reset() to in addition to other columns,
also mark all columns that is used by the given key.
- table->restore_column_maps_after_mark_index() to restore to default
column maps after a call to table->mark_columns_used_by_index().
- New item function register_field_in_read_map(), for marking used columns
in table->read_map. Used by filesort() to mark all used columns
- Maintain in TABLE->merge_keys set of all keys that are used in query.
(Simplices some optimization loops)
- Maintain Field->part_of_key_not_clustered which is like Field->part_of_key
but the field in the clustered key is not assumed to be part of all index.
(used in opt_range.cc for faster loops)
- dbug_tmp_use_all_columns(), dbug_tmp_restore_column_map()
tmp_use_all_columns() and tmp_restore_column_map() functions to temporally
mark all columns as usable. The 'dbug_' version is primarily intended
inside a handler when it wants to just call Field:store() & Field::val()
functions, but don't need the column maps set for any other usage.
(ie:: bitmap_is_set() is never called)
- We can't use compare_records() to skip updates for handlers that returns
a partial column set and the read_set doesn't cover all columns in the
write set. The reason for this is that if we have a column marked only for
write we can't in the MySQL level know if the value changed or not.
The reason this worked before was that MySQL marked all to be written
columns as also to be read. The new 'optimal' bitmaps exposed this 'hidden
bug'.
- open_table_from_share() does not anymore setup temporary MEM_ROOT
object as a thread specific variable for the handler. Instead we
send the to-be-used MEMROOT to get_new_handler().
(Simpler, faster code)
Bugs fixed:
- Column marking was not done correctly in a lot of cases.
(ALTER TABLE, when using triggers, auto_increment fields etc)
(Could potentially result in wrong values inserted in table handlers
relying on that the old column maps or field->set_query_id was correct)
Especially when it comes to triggers, there may be cases where the
old code would cause lost/wrong values for NDB and/or InnoDB tables.
- Split thd->options flag OPTION_STATUS_NO_TRANS_UPDATE to two flags:
OPTION_STATUS_NO_TRANS_UPDATE and OPTION_KEEP_LOG.
This allowed me to remove some wrong warnings about:
"Some non-transactional changed tables couldn't be rolled back"
- Fixed handling of INSERT .. SELECT and CREATE ... SELECT that wrongly reset
(thd->options & OPTION_STATUS_NO_TRANS_UPDATE) which caused us to loose
some warnings about
"Some non-transactional changed tables couldn't be rolled back")
- Fixed use of uninitialized memory in ha_ndbcluster.cc::delete_table()
which could cause delete_table to report random failures.
- Fixed core dumps for some tests when running with --debug
- Added missing FN_LIBCHAR in mysql_rm_tmp_tables()
(This has probably caused us to not properly remove temporary files after
crash)
- slow_logs was not properly initialized, which could maybe cause
extra/lost entries in slow log.
- If we get an duplicate row on insert, change column map to read and
write all columns while retrying the operation. This is required by
the definition of REPLACE and also ensures that fields that are only
part of UPDATE are properly handled. This fixed a bug in NDB and
REPLACE where REPLACE wrongly copied some column values from the replaced
row.
- For table handler that doesn't support NULL in keys, we would give an error
when creating a primary key with NULL fields, even after the fields has been
automaticly converted to NOT NULL.
- Creating a primary key on a SPATIAL key, would fail if field was not
declared as NOT NULL.
Cleanups:
- Removed not used condition argument to setup_tables
- Removed not needed item function reset_query_id_processor().
- Field->add_index is removed. Now this is instead maintained in
(field->flags & FIELD_IN_ADD_INDEX)
- Field->fieldnr is removed (use field->field_index instead)
- New argument to filesort() to indicate that it should return a set of
row pointers (not used columns). This allowed me to remove some references
to sql_command in filesort and should also enable us to return column
results in some cases where we couldn't before.
- Changed column bitmap handling in opt_range.cc to be aligned with TABLE
bitmap, which allowed me to use bitmap functions instead of looping over
all fields to create some needed bitmaps. (Faster and smaller code)
- Broke up found too long lines
- Moved some variable declaration at start of function for better code
readability.
- Removed some not used arguments from functions.
(setup_fields(), mysql_prepare_insert_check_table())
- setup_fields() now takes an enum instead of an int for marking columns
usage.
- For internal temporary tables, use handler::write_row(),
handler::delete_row() and handler::update_row() instead of
handler::ha_xxxx() for faster execution.
- Changed some constants to enum's and define's.
- Using separate column read and write sets allows for easier checking
of timestamp field was set by statement.
- Remove calls to free_io_cache() as this is now done automaticly in ha_reset()
- Don't build table->normalized_path as this is now identical to table->path
(after bar's fixes to convert filenames)
- Fixed some missed DBUG_PRINT(.."%lx") to use "0x%lx" to make it easier to
do comparision with the 'convert-dbug-for-diff' tool.
Things left to do in 5.1:
- We wrongly log failed CREATE TABLE ... SELECT in some cases when using
row based logging (as shown by testcase binlog_row_mix_innodb_myisam.result)
Mats has promised to look into this.
- Test that my fix for CREATE TABLE ... SELECT is indeed correct.
(I added several test cases for this, but in this case it's better that
someone else also tests this throughly).
Lars has promosed to do this.
BitKeeper/etc/ignore:
added mysys/test_bitmap
include/base64.h:
Removed my_global.h, as this must be included first in any program
include/heap.h:
Added heap_reset() (Required by new handler interface)
include/my_base.h:
Removed HA_EXTRA_RESET. MySQL will now call ::reset() instead of ::extra(HA_EXTRA_RESET).
HA_EXTRA_RETRIVE_ALL_COLS and HA_EXTRA_RETRIVE_PRIMARY key are deleted as the column bitmaps makes these unnecessary
include/my_bitmap.h:
Remove my_pthread.h (should be included at upper level)
Introduced my_bitmap_map typedef to make it the bitmap handling more like a black box
Added bitmap_is_overlapping(), bitmap_test_and_clear(), bitmap_copy() and bitmap_cmp()
Made bitmap_set_bit(), bitmap_flip_bit(), bitmap_clear_bit() return void
include/myisam.h:
Added mi_reset() (Required by new handler interface)
include/myisammrg.h:
Added myrg_reset() (Required by new handler interface)
include/mysql_com.h:
Added flag FIELD_IN_ADD_INDEX to be able to remove Field->add_index
mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test:
Added testing of CREATE ... SELECT in a mixed environment
(This found some bugs that Mats is going to fix shortly)
mysql-test/install_test_db.sh:
Simplify ldata usage
Added --tmpdir=. option to mysqld bootstrap (Removed some warnings when TMPDIR was wrongly set)
mysql-test/mysql-test-run.pl:
Added --tmpdir=. to bootstrap
mysql-test/mysql-test-run.sh:
Use copy instead of INSTALL_DB for master and slave databases.
(Speeds up startup time a lot!)
Remove snapshot directories at startup (removes some strange warnings)
mysql-test/r/binlog_row_mix_innodb_myisam.result:
Added testing of CREATE ... SELECT in a mixed environment
(This found some bugs that Mats is going to fix shortly)
mysql-test/r/binlog_stm_mix_innodb_myisam.result:
Added testing of CREATE ... SELECT in a mixed environment
mysql-test/r/create.result:
Some extra tests of warnings and number of tables opened by CREATE ... SELECT
mysql-test/r/federated.result:
Drop some left over tables
Added testing of multiple table update and multiple table delete (with and without keys)
mysql-test/r/func_gconcat.result:
Enable some disabled tests (converted them slightly to be predictable)
mysql-test/r/func_time.result:
Added drop of test function
mysql-test/r/innodb_mysql.result:
Added tests for CREATE ... SELECT
mysql-test/r/insert.result:
More tests
Added testing of duplicate columns in insert
mysql-test/r/loaddata.result:
Added testing LOAD DATA ... SET ...
mysql-test/r/multi_update.result:
Test multi updates and deletes using primary key and without
mysql-test/r/ndb_index_unique.result:
Better error message
mysql-test/r/ndb_replace.result:
New correct result after fixing REPLACE handling with NDB
mysql-test/r/rpl_ddl.result:
Now we don't get these (wrong) warnings anymore
mysql-test/r/view_grant.result:
Drop used views
mysql-test/t/create.test:
Some extra tests of warnings and number of tables opened by CREATE ... SELECT
mysql-test/t/federated.test:
Drop some left over tables
Added testing of multiple table update and multiple table delete (with and without keys)
mysql-test/t/func_gconcat.test:
Enable some disabled tests (converted them slightly to be predictable)
mysql-test/t/func_time.test:
Added drop of test function
mysql-test/t/innodb_mysql.test:
Added tests for CREATE ... SELECT
mysql-test/t/insert.test:
More tests
Added testing of duplicate columns in insert
mysql-test/t/loaddata.test:
Added testing LOAD DATA ... SET ...
mysql-test/t/multi_update.test:
Test multi updates and deletes using primary key and without
mysql-test/t/view_grant.test:
Drop used views
mysql-test/valgrind.supp:
Added supression of not needed warnings when printing stack trace
mysys/base64.c:
Include my_global.h first
mysys/my_bitmap.c:
Added bitmap_is_overlapping(), bitmap_test_and_clear() and bitmap_copy()
Changed logic of bitmap handling to be a bit more efficent (Did this together with Mikael Ronström)
Now the 'extra, not used bits' in the bitmap are assumed to have a 'random value' and the bitmap functions are free to change them whenever needed.
Changed how mutex is allocated to make 'bitmap_free()' function simpler.
mysys/thr_lock.c:
Added 0x before thread pointers (for easier comparison of DBUG traces)
sql/event.cc:
Ensure 'use_all_columns()' is used for event tables
Don't print warning that event table is damaged if it doesn't exists.
sql/field.cc:
Added ASSERT_COLUMN_MARKED_FOR_WRITE in all store() methods and ASSERT_COLUMN_MARKED_FOR_READ in all val() methods to catch wrong setting if table->read_set and table->write_set
(Rest of changes are only indentation cleanups)
sql/field.h:
Removed Field->query_id (replaced by table->read_set and table->write_set)
Removed Field->fieldnr (use Field->field_index instead)
Removed Field->add_index (Use Field->flags instead)
Add Field->part_of_key_not_clustered (for usage in opt_range.cc)
sql/filesort.cc:
Added paramater sort_postion to filesort() to force sorting by position instead of storing all fields in the result set.
This allowed me to remove checking of sql_command.
Create a temporary column bitmap for fields that are used by the sorting process.
Use column bitmaps instead of query_id
sql/ha_berkeley.cc:
Update to 'newer' table handler interface
sql/ha_berkeley.h:
Update to 'newer' table handler interface
sql/ha_federated.cc:
Update to 'newer' table handler interface
Only read columns that are needed from remote server.
In case of eq ranges, don't generate two conditions in the WHERE clause
(this can still be optimized, but would require a bigger code change)
Use 'simpler to use' XXXX_LEN' macros
A bit simpler logic in ::write_row() when creating statements.
In update, only include test of fields actually read.
(This greatly simplifies the queries sent by the federated engine)
Similar changes done for delete_row()
sql/ha_federated.h:
Update to 'newer' table handler interface
Changed XXX_LEN macros to use sizeof(...)-1, to simplify usage in ha_federated.cc
Added HA_PRIMARY_KEY_REQUIRED_FOR_DELETE to tell MySQL to read all primary key columns in case of DELETE
sql/ha_heap.cc:
Update to 'newer' table handler interface
sql/ha_heap.h:
Update to 'newer' table handler interface
sql/ha_innodb.cc:
Update to 'newer' table handler interface
- Update innobase_create_handler() to new interface
- Removed HA_NOT_EXACT_COUNT (not needed)
- Renamed HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION.
- Prefixed base status variables with 'stats'
- Use table column bitmaps instead of ha_get_bit_in_read_set()
- Added ::reset(), with code from ::extra(HA_EXTRA_RESET)
- Removed HA_EXTRA_RETRIVE_ALL_COLS and HA_EXTRA_RETRIEVE_PRIMARY_KEY as
the table->read_set and table->write_set bitmaps now are accurate
sql/ha_innodb.h:
Update to 'newer' table handler interface
- table_flags are now ulonglong
- Added reset() method
- Removed not needed ha_retrieve_all_cols() and ha_retrieve_all_pk() columns.
- Made build_template() a class function to be able to easier access class variables
sql/ha_myisam.cc:
Update to 'newer' table handler interface
sql/ha_myisam.h:
Update to 'newer' table handler interface
sql/ha_myisammrg.cc:
Update to 'newer' table handler interface
sql/ha_myisammrg.h:
Update to 'newer' table handler interface
sql/ha_ndbcluster.cc:
Update to 'newer' table handler interface
Fixed use_blob_value() to be accurate
In ::complemented_read() we have to check both the read and write bitmap as the old code did mark all changed columns also in the read map
Correct dumping of field data with DBUG_DUMP
Prefix addresses in DBUG_PRINT with 0x
Fixed usage of not initialized memory
Update to use field->flags & FIELD_IN_ADD_INDEX instead of field->add_index.
sql/ha_ndbcluster.h:
Update to 'newer' table handler interface
sql/ha_ndbcluster_binlog.cc:
Mark usage of all columns in ndbcluster binlog tables
false -> FALSE, true -> TRUE
Use table->s->all_set instead of creating a temporary bitmap.
sql/ha_partition.cc:
Update to 'newer' table handler interface
Added memroot to initialise_partitions() and related functions to get faster memory allocation.
partition_create_handler() is now responsible for initialisation of the partition object
Some trivial optimizations and indentation fixes
Ensure that table_flags() are up to date
Removed documentation for removed HA_EXTRA flags
Fixed 'strange' usage of m_file[i] in new_handlers_from_part_info()that worked in current code 'by chance'
sql/ha_partition.h:
Update to 'newer' table handler interface
sql/handler.cc:
create_xxx handler now takes MEMROOT as an argument to simplify memory allocation.
Much simpler get_new_handler()
(Initialization of the object is now handled by the create method for the engine)
Moved all allocation of bitmap handling to the TABLE object (in table.cc)
Added column_bitmaps_signal() to signal column usage changes.
Changed binlog_log_row() to use the exiusting all_set bitmap in the table object.
Added ha_reset() function to test that the file object is ok at end of statement and call handler::reset()
Added use_hidden_primary_key() to signal handler that we we are going to read and update + delete the row and the handler should thus remember the position for the row
sql/handler.h:
Added HA_NO_TRANSACTIONS, HA_PARTIAL_COLUMN_READ, HA_REQUIRES_KEY_COLUMNS_FOR_DELETE,HA_PRIMARY_KEY_REQUIRED_FOR_DELETE and HA_HAS_RECORDS
Removed HA_NOT_EXACT_COUNT, HA_READ_RND_SAME
HA_DUPP_POS -> HA_DUPLICATE_POS
HA_NOT_EXACT_COUNT replaced by HA_STATS_RECORDS_IS_EXACT, HA_HAS_RECORDS and records()
HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS renamed to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
Added future row type 'ROW_TYPE_PAGES'
Added MEM_ROOT to handlerton 'create' function
Added ha_statistics, a structure for all status variable in the base handler class.
Moved all status variables in the handler class into a stats structs to improve readability.
ha_table_flags() is now a cached (not virtual) version of table_flags()
reset() doesn't anymore call extra(HA_EXTRA_RESET) but is a function of it's own.
Renamed dupp_ref to dup_ref
Renamed not used handler::sortkey
Moved read_set and write_set to TABLE structure
handler::init() function added for cacheing of virtual constants from engine.
sql/item.cc:
Added register_field_in_read_map() for marking used columns in expression.
This is used by filesort() for creating an optimal column bitmap while retrieving columns for sorting.
Initalize value.cs_info.character_set_client to fix core dump bug with --debug
set_query_id -> mark_used_columns
Mark used columns in read_set OR write_set.
sql/item.h:
Removed reset_query_id_processor() as it's not needed anymore.
Added register_field_in_read_map()
Added extra argument to Item::walk() to indicate if we should also
traverse sub queries.
sql/item_cmpfunc.cc:
Temporary mark used columns to be read/writable
Update Item::walk to new interface
sql/item_cmpfunc.h:
Added extra argument to Item::walk() to indicate if we should also traverse sub queries.
sql/item_func.cc:
Update Item::walk() to new interface
table_flags() -> ha_table_flags()
sql/item_func.h:
Update Item::walk() to new interface
sql/item_row.cc:
Update Item::walk() to new interface
sql/item_row.h:
Update Item::walk() to new interface
sql/item_strfunc.h:
Update Item::walk() to new interface
sql/item_subselect.cc:
Added Item_subselect::walk()
(It was a bug it was missing before. Not sure what kind of bugs this could have caused)
sql/item_subselect.h:
Update Item::walk() to new interface
sql/item_sum.cc:
Update Item::walk() to new interface
Updates for new handler interace
sql/item_sum.h:
Update Item::walk() to new interface
sql/key.cc:
Updates for new handler interace
sql/log.cc:
Mark all columns used for log tables
Split options flag
Ensured that second argument to trans_register_ha is a bool
sql/log_event.cc:
Fixed comments to be withing 79 characters
Use OPTION_KEEP_LOG instead of OPTION_STATUS_NO_TRANS_UPDATE to remove wrong warnings
Updates for new handler interface
Use 0x%lx instead of %p (portability problem)
sql/mysql_priv.h:
Added OPTION_KEEP_LOG to indicate that we should replicate the binlog even on rollback
Removed not used 'conds' argument to setup_tables
sql/mysqld.cc:
Indentation fixes and removed old comment
sql/opt_range.cc:
Update to new handler and bitmap interface.
Fixed calls to cp_buffer_from_ref() and walk() (new argument).
Create new temporary bitmaps for ror scans.
(Needed because of handler changes and to get more accurate column bitmaps than before)
Remove not needed file->ha_reset() call before file->close().
Some trivial optimization and indentation fixes.
Use Field->part_of_key_not_clustered() to check if field is part of a key, instead of looping over all key parts.
Added flag 'in_ror_merged_scan' to allow ::get_next() to know that we need a special column bitmap to only fetch pointer to record.
This is needed because ror scan uses the same TABLE object but different file objects, which creates problem for the column bitmap handling.
(This is a temporary solution. A better one would be to allocate an own TABLE object for ROR scans)
Optimized bitmap handling in ror scans:
- Start bitmap at position 0, not 1
- Use same bitmap size as in TABLE
- Use table->read_set and table->write_set to create column bitmaps instead of looping over all fields in table
sql/opt_range.h:
Added 'in_ror_merged_scan' to indicate if we are doing a ROR scan
Added temporary column bitmaps used in ROR scans
sql/opt_sum.cc:
Added get_ext_record_count() which is used in COUNT() optimization if handler has HA_HAS_RECORDS
Note that we don't call this if handler has HA_STATS_RECORDS_IS_EXACT set.
sql/protocol.cc:
We need to mark columns as readable in ::store() as we sometimes return default value for fields to the user
sql/records.cc:
Updates for new handler interface
sql/set_var.cc:
Handle splitting OPTION_STATUS_NO_TRANS_UPDATE to two flags
sql/share/errmsg.txt:
Fixed wrong
sql/sp.cc:
Mark that we are using all columns for the proc table
Update call to setup_tables() to use new prototype
sql/sp_head.cc:
Removed QQ comment
sql/spatial.cc:
Removed wrong QQ comment
sql/sql_acl.cc:
Mark that we need all columns for acl tables
Supply memroot to some 'new' calls.
Indentation fixes
sql/sql_base.cc:
set_query_id removed
Ensure we call ha_reset() at end of each statement
Mark read columns in read_set and changed columns in write_set (Before all columns was marked in read set)
Fixed marking of some columns that was not proplerly marked before
Maintain in TABLE->merge_keys set of all keys that are used in some way
Removed not used 'conds' argument from setup_tables()
Remove not used setting of 'dupp_field' in insert_fields()
Added missing FN_LIBCHAR in mysql_rm_tmp_tables()
(This has probably caused us to not properly remove temporary files after crash)
sql/sql_bitmap.h:
Added is_overlapping()
sql/sql_class.cc:
Slow_logs was not properly initialized, which could maybe cause extra/lost entries in slow log.
set_query_id -> mark_used_columns
Simpler variable usage in pack_row() (cleanup)
Moved some variable declartion at start of function for better code readability
sql/sql_class.h:
Added enum_mark_columns
Updated comments
Renamed dupp_field -> dup_field
Added virtual function 'can_rollback_data()' to select_insert() to be used in CREATE ... SELECT to optimize use of OPTION_STATUS_NO_TRANS_UPDATE.
(This fixes a bug in CREATE ... SELECT where we did give wrong warnings when using non transacational tables)
sql/sql_delete.cc:
Updates to new handler interface
Call table->mark_columns_needed_for_delete() to allow us to put additional columns in column usage maps if handler so requires.
Call table->prepare_for_position() to tell handler that we are going to call ha_position().
Removed call to free_io_cache(). (io_cache is now removed in ha_reset()).
Fixed calls to setup_tables()
sql/sql_do.cc:
Update call to setup_fields()
sql/sql_handler.cc:
Tell handler tables to always read all columns.
Use temporary column map when storing value in field for later index usage
sql/sql_help.cc:
Makr all used fields to be read
Update call to setup_fields()
sql/sql_insert.cc:
Tell handler we are going to update the auto_increment column
dupp_field -> dup_field
Set column usage bits for timestamp field.
Call table->mark_columns_needed_for_insert() and table->mark_auto_increment_column()
Removed not used argument from mysql_prepare_insert_check_table().
If we get an duplicate row on insert, change column map to read and write all columns while retrying the operatation.
This is required by the definition of REPLACE and also ensures that fields that are only part of UPDATE are properly handled.
This fixed a bug in NDB and REPLACE where REPLACE wrongly copied some column values from the replaced row.
Setup new bitmaps for delayed insert rows
Remove reseting of next_number_fields as it will be reset on next call to handler_insert()
Fixed usage of thd->options and OPTION_STATUS_NO_TRANS_UPDATE.
The issue was that one should not to reset this flag as it may be set by a previous statement.
The way it was now used caused us to loose some warnings and get other wrong warnings when using non transactional tables mixed with transactional.
I fixed it by introducing 'select_insert::can_rollback_data' to inform send_error() that the given statement can be rolled back (which in case of CREATE TABLE can always be done)
Don't close tables created with CREATE ... SELECT but keep them in the table cache.
Moved out MY_HOOKS from inside function (better readability)
sql/sql_load.cc:
Update to use new handler and column marking interface
Update using setup_tables()
sql/sql_olap.cc:
Update calls to setup_tables
Use enums instead of constants to setup_fields()
sql/sql_parse.cc:
Handle OPTION_KEEP_LOG:
- Set it on CREATE TEMPORARY TABLE / DROP TABLE
- Reset it when OPTION_STATUS_NO_TRANS_UPDATE is reset
- Don't set it for CREATE ... SELECT (this is handled in select_create class)
Remove reseting of OPTION_STATUS_NO_TRANS_UPDATE in begin_trans() as this should already be reset.
If in autocommit mode, reset OPTION_KEEP_LOG and OPTION_STATUS_NO_TRANS_UPDATE to not give warnings in future commands
sql/sql_partition.cc:
Update walk() usage
Trivial indentation fixes
sql/sql_plugin.cc:
Mark all columns as used for plugins
sql/sql_prepare.cc:
Added assert to find out hidden bugs in character_set_client (got an error in debug binary when this not set correctly)
Updates for new handler interface
Update calls to setup_fields()
sql/sql_repl.cc:
Indentation fixes
sql/sql_select.cc:
Update call to setup_tables() and setup_fields()
Remove some old disabled code
Update to new hadler interface
Indentation cleanups
Added column bitmaps for temporary tables.
Remove updating of the removed slots in the Field class
Added TABLE argument to cp_buffer_from_ref() (To be able to install temporary column maps)
For internal temporary tables, use handler::write_row(), handler::delete_row() and handler::update_row() instead of handler::ha_xxxx() for faster execution.
sql/sql_select.h:
Indentaition fixes.
Install temporary column usage maps when needed
Added TABLE element to cp_buffer_from_ref()
sql/sql_show.cc:
Update to new handler interface
Mark all columns used for internal tables.
Style fixes.
Added support for 'future' ROW_TYPE_PAGES.
Don't allocate TMP_TABLE_PARAM with calloc. The 'init()' function will initialize the structure properly.
sql/sql_table.cc:
Update to new handler interface
Simple my_snprintf -> strmake()
Changed some constants to defines
Don't test for NULL in primary key (as we a couple of line above force the PRIMARY KEY to be NOT NULL)
Change field->add_index to use field->flags & FIELD_IN_ADD_INDEX
Mark all columns as used for ALTER TABLE
Style fixes
Update call to filesort()
sql/sql_trigger.h:
Added friend functions to be able to test if triggers exists for table we are going to insert/update or delete in.
sql/sql_udf.cc:
Mark all columns as used for udf system table.
sql/sql_union.cc:
Update call to walk()
Update to new handler interface
sql/sql_update.cc:
Remove query_id argument from compare_record()
Use column bitmaps instead of query_id.
We can't use compare_records() to skip updates for handlers that returns a partial column set and the read_set doesn't cover all columns in the write set, because compare_record() can't in this case know if a not read column changed value.
Update call to setup_fields()
Using separate column read and write sets allows for easier checking of timestamp field was set by statement.
Removed call to free_io_cache() as this is now done in ha_reset()
Call table->mark_columns_needed_for_update() and table->prepare_for_position()
Style fixes
sql/sql_view.cc:
Style fixes
sql/table.cc:
Remove implicitely include 'errno.h'
Remove code for building normalized path, as this is now identical to 'path'
Remove field->fieldnr
Added update of field->part_of_key_not_clustered()
Create column bitmaps in TABLE and TABLE_SHARE
Don't setup a temporary MEM_ROOT object as a thread specific variable for the handler. Instead we send the to-be-used MEMROOT to get_new_handler()
Update to new handler interface
Update call to walk()
Added new functions:
- st_table::clear_column_bitmaps()
- st_table::prepare_for_position()
- st_table::mark_columns_used_by_index()
- st_table::restore_column_maps_after_mark_index()
- st_table::mark_columns_used_by_index_no_reset()
- st_table::mark_auto_increment_column()
- st_table::mark_columns_needed_for_delete()
- st_table::mark_columns_needed_for_update()
- st_table::mark_columns_needed_for_insert()
sql/table.h:
Moved column usage bitmaps from handler to TABLE
Added to TABLE_SHARE all_set and column_bitmap_size
Added to TABLE merge_keys, bitmap_init_values, def_read_set, def_write_set, tmp_set, read_set and write_set.
Declared all new table column bitmap functions
Added TABLE functions column_bitmaps_set(), column_bitmaps_set_no_signal(), use_all_columns() and default_column_bitmaps()
Added functions: tmp_use_all_columns() and tmp_restore_column_map() to temporarly switch column bitmaps
Added functions: dbug_tmp_use_all_columns() and dbug_tmp_restore_column_map() to temporarly switch column bitmaps to avoid asserts in Field::store() and Field::val().
sql/tztime.cc:
Mark all columns as used for timezone tables
storage/archive/ha_archive.cc:
Update to new handler interface
storage/archive/ha_archive.h:
Update to new handler interface
storage/blackhole/ha_blackhole.cc:
Update to new handler interface
storage/blackhole/ha_blackhole.h:
Update to new handler interface
removed not needed flag HA_DUPP_POS
storage/csv/ha_tina.cc:
Update to new handler interface
storage/csv/ha_tina.h:
Update to new handler interface
storage/example/ha_example.cc:
Update to new handler interface
storage/example/ha_example.h:
Update to new handler interface
storage/heap/hp_extra.c:
Added heap_reset() (Required by new handler interface)
storage/heap/hp_test2.c:
Use heap_reset()
storage/myisam/ft_boolean_search.c:
Fixed compiler warning
storage/myisam/mi_extra.c:
Added mi_reset() (Required by new handler interface)
storage/myisam/mi_search.c:
Fixed DBUG_PRINT messages to use 0x%lx instead of %lx
storage/myisam/mi_test2.c:
Use mi_reset()
storage/myisam/myisampack.c:
Use mi_reset()
storage/myisammrg/myrg_extra.c:
Added myrg_reset() (Required by new handler interface)
unittest/mysys/base64.t.c:
Include my_global.h
Don't include implictely include file 'stdlib.h'
2006-06-04 17:52:22 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
if (walk_subquery)
|
|
|
|
{
|
|
|
|
for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
|
|
|
|
{
|
|
|
|
List_iterator<Item> li(lex->item_list);
|
|
|
|
Item *item;
|
|
|
|
ORDER *order;
|
|
|
|
|
|
|
|
if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
|
|
|
|
return 1;
|
|
|
|
if (lex->having && (lex->having)->walk(processor, walk_subquery,
|
|
|
|
argument))
|
|
|
|
return 1;
|
2009-06-25 12:05:53 +02:00
|
|
|
/* TODO: why does this walk WHERE/HAVING but not ON expressions of outer joins? */
|
This changeset is largely a handler cleanup changeset (WL#3281), but includes fixes and cleanups that was found necessary while testing the handler changes
Changes that requires code changes in other code of other storage engines.
(Note that all changes are very straightforward and one should find all issues
by compiling a --debug build and fixing all compiler errors and all
asserts in field.cc while running the test suite),
- New optional handler function introduced: reset()
This is called after every DML statement to make it easy for a handler to
statement specific cleanups.
(The only case it's not called is if force the file to be closed)
- handler::extra(HA_EXTRA_RESET) is removed. Code that was there before
should be moved to handler::reset()
- table->read_set contains a bitmap over all columns that are needed
in the query. read_row() and similar functions only needs to read these
columns
- table->write_set contains a bitmap over all columns that will be updated
in the query. write_row() and update_row() only needs to update these
columns.
The above bitmaps should now be up to date in all context
(including ALTER TABLE, filesort()).
The handler is informed of any changes to the bitmap after
fix_fields() by calling the virtual function
handler::column_bitmaps_signal(). If the handler does caching of
these bitmaps (instead of using table->read_set, table->write_set),
it should redo the caching in this code. as the signal() may be sent
several times, it's probably best to set a variable in the signal
and redo the caching on read_row() / write_row() if the variable was
set.
- Removed the read_set and write_set bitmap objects from the handler class
- Removed all column bit handling functions from the handler class.
(Now one instead uses the normal bitmap functions in my_bitmap.c instead
of handler dedicated bitmap functions)
- field->query_id is removed. One should instead instead check
table->read_set and table->write_set if a field is used in the query.
- handler::extra(HA_EXTRA_RETRIVE_ALL_COLS) and
handler::extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY) are removed. One should now
instead use table->read_set to check for which columns to retrieve.
- If a handler needs to call Field->val() or Field->store() on columns
that are not used in the query, one should install a temporary
all-columns-used map while doing so. For this, we provide the following
functions:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
field->val();
dbug_tmp_restore_column_map(table->read_set, old_map);
and similar for the write map:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
field->val();
dbug_tmp_restore_column_map(table->write_set, old_map);
If this is not done, you will sooner or later hit a DBUG_ASSERT
in the field store() / val() functions.
(For not DBUG binaries, the dbug_tmp_restore_column_map() and
dbug_tmp_restore_column_map() are inline dummy functions and should
be optimized away be the compiler).
- If one needs to temporary set the column map for all binaries (and not
just to avoid the DBUG_ASSERT() in the Field::store() / Field::val()
methods) one should use the functions tmp_use_all_columns() and
tmp_restore_column_map() instead of the above dbug_ variants.
- All 'status' fields in the handler base class (like records,
data_file_length etc) are now stored in a 'stats' struct. This makes
it easier to know what status variables are provided by the base
handler. This requires some trivial variable names in the extra()
function.
- New virtual function handler::records(). This is called to optimize
COUNT(*) if (handler::table_flags() & HA_HAS_RECORDS()) is true.
(stats.records is not supposed to be an exact value. It's only has to
be 'reasonable enough' for the optimizer to be able to choose a good
optimization path).
- Non virtual handler::init() function added for caching of virtual
constants from engine.
- Removed has_transactions() virtual method. Now one should instead return
HA_NO_TRANSACTIONS in table_flags() if the table handler DOES NOT support
transactions.
- The 'xxxx_create_handler()' function now has a MEM_ROOT_root argument
that is to be used with 'new handler_name()' to allocate the handler
in the right area. The xxxx_create_handler() function is also
responsible for any initialization of the object before returning.
For example, one should change:
static handler *myisam_create_handler(TABLE_SHARE *table)
{
return new ha_myisam(table);
}
->
static handler *myisam_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
{
return new (mem_root) ha_myisam(table);
}
- New optional virtual function: use_hidden_primary_key().
This is called in case of an update/delete when
(table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
but we don't have a primary key. This allows the handler to take precisions
in remembering any hidden primary key to able to update/delete any
found row. The default handler marks all columns to be read.
- handler::table_flags() now returns a ulonglong (to allow for more flags).
- New/changed table_flags()
- HA_HAS_RECORDS Set if ::records() is supported
- HA_NO_TRANSACTIONS Set if engine doesn't support transactions
- HA_PRIMARY_KEY_REQUIRED_FOR_DELETE
Set if we should mark all primary key columns for
read when reading rows as part of a DELETE
statement. If there is no primary key,
all columns are marked for read.
- HA_PARTIAL_COLUMN_READ Set if engine will not read all columns in some
cases (based on table->read_set)
- HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS
Renamed to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION.
- HA_DUPP_POS Renamed to HA_DUPLICATE_POS
- HA_REQUIRES_KEY_COLUMNS_FOR_DELETE
Set this if we should mark ALL key columns for
read when when reading rows as part of a DELETE
statement. In case of an update we will mark
all keys for read for which key part changed
value.
- HA_STATS_RECORDS_IS_EXACT
Set this if stats.records is exact.
(This saves us some extra records() calls
when optimizing COUNT(*))
- Removed table_flags()
- HA_NOT_EXACT_COUNT Now one should instead use HA_HAS_RECORDS if
handler::records() gives an exact count() and
HA_STATS_RECORDS_IS_EXACT if stats.records is exact.
- HA_READ_RND_SAME Removed (no one supported this one)
- Removed not needed functions ha_retrieve_all_cols() and ha_retrieve_all_pk()
- Renamed handler::dupp_pos to handler::dup_pos
- Removed not used variable handler::sortkey
Upper level handler changes:
- ha_reset() now does some overall checks and calls ::reset()
- ha_table_flags() added. This is a cached version of table_flags(). The
cache is updated on engine creation time and updated on open.
MySQL level changes (not obvious from the above):
- DBUG_ASSERT() added to check that column usage matches what is set
in the column usage bit maps. (This found a LOT of bugs in current
column marking code).
- In 5.1 before, all used columns was marked in read_set and only updated
columns was marked in write_set. Now we only mark columns for which we
need a value in read_set.
- Column bitmaps are created in open_binary_frm() and open_table_from_share().
(Before this was in table.cc)
- handler::table_flags() calls are replaced with handler::ha_table_flags()
- For calling field->val() you must have the corresponding bit set in
table->read_set. For calling field->store() you must have the
corresponding bit set in table->write_set. (There are asserts in
all store()/val() functions to catch wrong usage)
- thd->set_query_id is renamed to thd->mark_used_columns and instead
of setting this to an integer value, this has now the values:
MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE
Changed also all variables named 'set_query_id' to mark_used_columns.
- In filesort() we now inform the handler of exactly which columns are needed
doing the sort and choosing the rows.
- The TABLE_SHARE object has a 'all_set' column bitmap one can use
when one needs a column bitmap with all columns set.
(This is used for table->use_all_columns() and other places)
- The TABLE object has 3 column bitmaps:
- def_read_set Default bitmap for columns to be read
- def_write_set Default bitmap for columns to be written
- tmp_set Can be used as a temporary bitmap when needed.
The table object has also two pointer to bitmaps read_set and write_set
that the handler should use to find out which columns are used in which way.
- count() optimization now calls handler::records() instead of using
handler->stats.records (if (table_flags() & HA_HAS_RECORDS) is true).
- Added extra argument to Item::walk() to indicate if we should also
traverse sub queries.
- Added TABLE parameter to cp_buffer_from_ref()
- Don't close tables created with CREATE ... SELECT but keep them in
the table cache. (Faster usage of newly created tables).
New interfaces:
- table->clear_column_bitmaps() to initialize the bitmaps for tables
at start of new statements.
- table->column_bitmaps_set() to set up new column bitmaps and signal
the handler about this.
- table->column_bitmaps_set_no_signal() for some few cases where we need
to setup new column bitmaps but don't signal the handler (as the handler
has already been signaled about these before). Used for the momement
only in opt_range.cc when doing ROR scans.
- table->use_all_columns() to install a bitmap where all columns are marked
as use in the read and the write set.
- table->default_column_bitmaps() to install the normal read and write
column bitmaps, but not signaling the handler about this.
This is mainly used when creating TABLE instances.
- table->mark_columns_needed_for_delete(),
table->mark_columns_needed_for_delete() and
table->mark_columns_needed_for_insert() to allow us to put additional
columns in column usage maps if handler so requires.
(The handler indicates what it neads in handler->table_flags())
- table->prepare_for_position() to allow us to tell handler that it
needs to read primary key parts to be able to store them in
future table->position() calls.
(This replaces the table->file->ha_retrieve_all_pk function)
- table->mark_auto_increment_column() to tell handler are going to update
columns part of any auto_increment key.
- table->mark_columns_used_by_index() to mark all columns that is part of
an index. It will also send extra(HA_EXTRA_KEYREAD) to handler to allow
it to quickly know that it only needs to read colums that are part
of the key. (The handler can also use the column map for detecting this,
but simpler/faster handler can just monitor the extra() call).
- table->mark_columns_used_by_index_no_reset() to in addition to other columns,
also mark all columns that is used by the given key.
- table->restore_column_maps_after_mark_index() to restore to default
column maps after a call to table->mark_columns_used_by_index().
- New item function register_field_in_read_map(), for marking used columns
in table->read_map. Used by filesort() to mark all used columns
- Maintain in TABLE->merge_keys set of all keys that are used in query.
(Simplices some optimization loops)
- Maintain Field->part_of_key_not_clustered which is like Field->part_of_key
but the field in the clustered key is not assumed to be part of all index.
(used in opt_range.cc for faster loops)
- dbug_tmp_use_all_columns(), dbug_tmp_restore_column_map()
tmp_use_all_columns() and tmp_restore_column_map() functions to temporally
mark all columns as usable. The 'dbug_' version is primarily intended
inside a handler when it wants to just call Field:store() & Field::val()
functions, but don't need the column maps set for any other usage.
(ie:: bitmap_is_set() is never called)
- We can't use compare_records() to skip updates for handlers that returns
a partial column set and the read_set doesn't cover all columns in the
write set. The reason for this is that if we have a column marked only for
write we can't in the MySQL level know if the value changed or not.
The reason this worked before was that MySQL marked all to be written
columns as also to be read. The new 'optimal' bitmaps exposed this 'hidden
bug'.
- open_table_from_share() does not anymore setup temporary MEM_ROOT
object as a thread specific variable for the handler. Instead we
send the to-be-used MEMROOT to get_new_handler().
(Simpler, faster code)
Bugs fixed:
- Column marking was not done correctly in a lot of cases.
(ALTER TABLE, when using triggers, auto_increment fields etc)
(Could potentially result in wrong values inserted in table handlers
relying on that the old column maps or field->set_query_id was correct)
Especially when it comes to triggers, there may be cases where the
old code would cause lost/wrong values for NDB and/or InnoDB tables.
- Split thd->options flag OPTION_STATUS_NO_TRANS_UPDATE to two flags:
OPTION_STATUS_NO_TRANS_UPDATE and OPTION_KEEP_LOG.
This allowed me to remove some wrong warnings about:
"Some non-transactional changed tables couldn't be rolled back"
- Fixed handling of INSERT .. SELECT and CREATE ... SELECT that wrongly reset
(thd->options & OPTION_STATUS_NO_TRANS_UPDATE) which caused us to loose
some warnings about
"Some non-transactional changed tables couldn't be rolled back")
- Fixed use of uninitialized memory in ha_ndbcluster.cc::delete_table()
which could cause delete_table to report random failures.
- Fixed core dumps for some tests when running with --debug
- Added missing FN_LIBCHAR in mysql_rm_tmp_tables()
(This has probably caused us to not properly remove temporary files after
crash)
- slow_logs was not properly initialized, which could maybe cause
extra/lost entries in slow log.
- If we get an duplicate row on insert, change column map to read and
write all columns while retrying the operation. This is required by
the definition of REPLACE and also ensures that fields that are only
part of UPDATE are properly handled. This fixed a bug in NDB and
REPLACE where REPLACE wrongly copied some column values from the replaced
row.
- For table handler that doesn't support NULL in keys, we would give an error
when creating a primary key with NULL fields, even after the fields has been
automaticly converted to NOT NULL.
- Creating a primary key on a SPATIAL key, would fail if field was not
declared as NOT NULL.
Cleanups:
- Removed not used condition argument to setup_tables
- Removed not needed item function reset_query_id_processor().
- Field->add_index is removed. Now this is instead maintained in
(field->flags & FIELD_IN_ADD_INDEX)
- Field->fieldnr is removed (use field->field_index instead)
- New argument to filesort() to indicate that it should return a set of
row pointers (not used columns). This allowed me to remove some references
to sql_command in filesort and should also enable us to return column
results in some cases where we couldn't before.
- Changed column bitmap handling in opt_range.cc to be aligned with TABLE
bitmap, which allowed me to use bitmap functions instead of looping over
all fields to create some needed bitmaps. (Faster and smaller code)
- Broke up found too long lines
- Moved some variable declaration at start of function for better code
readability.
- Removed some not used arguments from functions.
(setup_fields(), mysql_prepare_insert_check_table())
- setup_fields() now takes an enum instead of an int for marking columns
usage.
- For internal temporary tables, use handler::write_row(),
handler::delete_row() and handler::update_row() instead of
handler::ha_xxxx() for faster execution.
- Changed some constants to enum's and define's.
- Using separate column read and write sets allows for easier checking
of timestamp field was set by statement.
- Remove calls to free_io_cache() as this is now done automaticly in ha_reset()
- Don't build table->normalized_path as this is now identical to table->path
(after bar's fixes to convert filenames)
- Fixed some missed DBUG_PRINT(.."%lx") to use "0x%lx" to make it easier to
do comparision with the 'convert-dbug-for-diff' tool.
Things left to do in 5.1:
- We wrongly log failed CREATE TABLE ... SELECT in some cases when using
row based logging (as shown by testcase binlog_row_mix_innodb_myisam.result)
Mats has promised to look into this.
- Test that my fix for CREATE TABLE ... SELECT is indeed correct.
(I added several test cases for this, but in this case it's better that
someone else also tests this throughly).
Lars has promosed to do this.
BitKeeper/etc/ignore:
added mysys/test_bitmap
include/base64.h:
Removed my_global.h, as this must be included first in any program
include/heap.h:
Added heap_reset() (Required by new handler interface)
include/my_base.h:
Removed HA_EXTRA_RESET. MySQL will now call ::reset() instead of ::extra(HA_EXTRA_RESET).
HA_EXTRA_RETRIVE_ALL_COLS and HA_EXTRA_RETRIVE_PRIMARY key are deleted as the column bitmaps makes these unnecessary
include/my_bitmap.h:
Remove my_pthread.h (should be included at upper level)
Introduced my_bitmap_map typedef to make it the bitmap handling more like a black box
Added bitmap_is_overlapping(), bitmap_test_and_clear(), bitmap_copy() and bitmap_cmp()
Made bitmap_set_bit(), bitmap_flip_bit(), bitmap_clear_bit() return void
include/myisam.h:
Added mi_reset() (Required by new handler interface)
include/myisammrg.h:
Added myrg_reset() (Required by new handler interface)
include/mysql_com.h:
Added flag FIELD_IN_ADD_INDEX to be able to remove Field->add_index
mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test:
Added testing of CREATE ... SELECT in a mixed environment
(This found some bugs that Mats is going to fix shortly)
mysql-test/install_test_db.sh:
Simplify ldata usage
Added --tmpdir=. option to mysqld bootstrap (Removed some warnings when TMPDIR was wrongly set)
mysql-test/mysql-test-run.pl:
Added --tmpdir=. to bootstrap
mysql-test/mysql-test-run.sh:
Use copy instead of INSTALL_DB for master and slave databases.
(Speeds up startup time a lot!)
Remove snapshot directories at startup (removes some strange warnings)
mysql-test/r/binlog_row_mix_innodb_myisam.result:
Added testing of CREATE ... SELECT in a mixed environment
(This found some bugs that Mats is going to fix shortly)
mysql-test/r/binlog_stm_mix_innodb_myisam.result:
Added testing of CREATE ... SELECT in a mixed environment
mysql-test/r/create.result:
Some extra tests of warnings and number of tables opened by CREATE ... SELECT
mysql-test/r/federated.result:
Drop some left over tables
Added testing of multiple table update and multiple table delete (with and without keys)
mysql-test/r/func_gconcat.result:
Enable some disabled tests (converted them slightly to be predictable)
mysql-test/r/func_time.result:
Added drop of test function
mysql-test/r/innodb_mysql.result:
Added tests for CREATE ... SELECT
mysql-test/r/insert.result:
More tests
Added testing of duplicate columns in insert
mysql-test/r/loaddata.result:
Added testing LOAD DATA ... SET ...
mysql-test/r/multi_update.result:
Test multi updates and deletes using primary key and without
mysql-test/r/ndb_index_unique.result:
Better error message
mysql-test/r/ndb_replace.result:
New correct result after fixing REPLACE handling with NDB
mysql-test/r/rpl_ddl.result:
Now we don't get these (wrong) warnings anymore
mysql-test/r/view_grant.result:
Drop used views
mysql-test/t/create.test:
Some extra tests of warnings and number of tables opened by CREATE ... SELECT
mysql-test/t/federated.test:
Drop some left over tables
Added testing of multiple table update and multiple table delete (with and without keys)
mysql-test/t/func_gconcat.test:
Enable some disabled tests (converted them slightly to be predictable)
mysql-test/t/func_time.test:
Added drop of test function
mysql-test/t/innodb_mysql.test:
Added tests for CREATE ... SELECT
mysql-test/t/insert.test:
More tests
Added testing of duplicate columns in insert
mysql-test/t/loaddata.test:
Added testing LOAD DATA ... SET ...
mysql-test/t/multi_update.test:
Test multi updates and deletes using primary key and without
mysql-test/t/view_grant.test:
Drop used views
mysql-test/valgrind.supp:
Added supression of not needed warnings when printing stack trace
mysys/base64.c:
Include my_global.h first
mysys/my_bitmap.c:
Added bitmap_is_overlapping(), bitmap_test_and_clear() and bitmap_copy()
Changed logic of bitmap handling to be a bit more efficent (Did this together with Mikael Ronström)
Now the 'extra, not used bits' in the bitmap are assumed to have a 'random value' and the bitmap functions are free to change them whenever needed.
Changed how mutex is allocated to make 'bitmap_free()' function simpler.
mysys/thr_lock.c:
Added 0x before thread pointers (for easier comparison of DBUG traces)
sql/event.cc:
Ensure 'use_all_columns()' is used for event tables
Don't print warning that event table is damaged if it doesn't exists.
sql/field.cc:
Added ASSERT_COLUMN_MARKED_FOR_WRITE in all store() methods and ASSERT_COLUMN_MARKED_FOR_READ in all val() methods to catch wrong setting if table->read_set and table->write_set
(Rest of changes are only indentation cleanups)
sql/field.h:
Removed Field->query_id (replaced by table->read_set and table->write_set)
Removed Field->fieldnr (use Field->field_index instead)
Removed Field->add_index (Use Field->flags instead)
Add Field->part_of_key_not_clustered (for usage in opt_range.cc)
sql/filesort.cc:
Added paramater sort_postion to filesort() to force sorting by position instead of storing all fields in the result set.
This allowed me to remove checking of sql_command.
Create a temporary column bitmap for fields that are used by the sorting process.
Use column bitmaps instead of query_id
sql/ha_berkeley.cc:
Update to 'newer' table handler interface
sql/ha_berkeley.h:
Update to 'newer' table handler interface
sql/ha_federated.cc:
Update to 'newer' table handler interface
Only read columns that are needed from remote server.
In case of eq ranges, don't generate two conditions in the WHERE clause
(this can still be optimized, but would require a bigger code change)
Use 'simpler to use' XXXX_LEN' macros
A bit simpler logic in ::write_row() when creating statements.
In update, only include test of fields actually read.
(This greatly simplifies the queries sent by the federated engine)
Similar changes done for delete_row()
sql/ha_federated.h:
Update to 'newer' table handler interface
Changed XXX_LEN macros to use sizeof(...)-1, to simplify usage in ha_federated.cc
Added HA_PRIMARY_KEY_REQUIRED_FOR_DELETE to tell MySQL to read all primary key columns in case of DELETE
sql/ha_heap.cc:
Update to 'newer' table handler interface
sql/ha_heap.h:
Update to 'newer' table handler interface
sql/ha_innodb.cc:
Update to 'newer' table handler interface
- Update innobase_create_handler() to new interface
- Removed HA_NOT_EXACT_COUNT (not needed)
- Renamed HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION.
- Prefixed base status variables with 'stats'
- Use table column bitmaps instead of ha_get_bit_in_read_set()
- Added ::reset(), with code from ::extra(HA_EXTRA_RESET)
- Removed HA_EXTRA_RETRIVE_ALL_COLS and HA_EXTRA_RETRIEVE_PRIMARY_KEY as
the table->read_set and table->write_set bitmaps now are accurate
sql/ha_innodb.h:
Update to 'newer' table handler interface
- table_flags are now ulonglong
- Added reset() method
- Removed not needed ha_retrieve_all_cols() and ha_retrieve_all_pk() columns.
- Made build_template() a class function to be able to easier access class variables
sql/ha_myisam.cc:
Update to 'newer' table handler interface
sql/ha_myisam.h:
Update to 'newer' table handler interface
sql/ha_myisammrg.cc:
Update to 'newer' table handler interface
sql/ha_myisammrg.h:
Update to 'newer' table handler interface
sql/ha_ndbcluster.cc:
Update to 'newer' table handler interface
Fixed use_blob_value() to be accurate
In ::complemented_read() we have to check both the read and write bitmap as the old code did mark all changed columns also in the read map
Correct dumping of field data with DBUG_DUMP
Prefix addresses in DBUG_PRINT with 0x
Fixed usage of not initialized memory
Update to use field->flags & FIELD_IN_ADD_INDEX instead of field->add_index.
sql/ha_ndbcluster.h:
Update to 'newer' table handler interface
sql/ha_ndbcluster_binlog.cc:
Mark usage of all columns in ndbcluster binlog tables
false -> FALSE, true -> TRUE
Use table->s->all_set instead of creating a temporary bitmap.
sql/ha_partition.cc:
Update to 'newer' table handler interface
Added memroot to initialise_partitions() and related functions to get faster memory allocation.
partition_create_handler() is now responsible for initialisation of the partition object
Some trivial optimizations and indentation fixes
Ensure that table_flags() are up to date
Removed documentation for removed HA_EXTRA flags
Fixed 'strange' usage of m_file[i] in new_handlers_from_part_info()that worked in current code 'by chance'
sql/ha_partition.h:
Update to 'newer' table handler interface
sql/handler.cc:
create_xxx handler now takes MEMROOT as an argument to simplify memory allocation.
Much simpler get_new_handler()
(Initialization of the object is now handled by the create method for the engine)
Moved all allocation of bitmap handling to the TABLE object (in table.cc)
Added column_bitmaps_signal() to signal column usage changes.
Changed binlog_log_row() to use the exiusting all_set bitmap in the table object.
Added ha_reset() function to test that the file object is ok at end of statement and call handler::reset()
Added use_hidden_primary_key() to signal handler that we we are going to read and update + delete the row and the handler should thus remember the position for the row
sql/handler.h:
Added HA_NO_TRANSACTIONS, HA_PARTIAL_COLUMN_READ, HA_REQUIRES_KEY_COLUMNS_FOR_DELETE,HA_PRIMARY_KEY_REQUIRED_FOR_DELETE and HA_HAS_RECORDS
Removed HA_NOT_EXACT_COUNT, HA_READ_RND_SAME
HA_DUPP_POS -> HA_DUPLICATE_POS
HA_NOT_EXACT_COUNT replaced by HA_STATS_RECORDS_IS_EXACT, HA_HAS_RECORDS and records()
HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS renamed to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
Added future row type 'ROW_TYPE_PAGES'
Added MEM_ROOT to handlerton 'create' function
Added ha_statistics, a structure for all status variable in the base handler class.
Moved all status variables in the handler class into a stats structs to improve readability.
ha_table_flags() is now a cached (not virtual) version of table_flags()
reset() doesn't anymore call extra(HA_EXTRA_RESET) but is a function of it's own.
Renamed dupp_ref to dup_ref
Renamed not used handler::sortkey
Moved read_set and write_set to TABLE structure
handler::init() function added for cacheing of virtual constants from engine.
sql/item.cc:
Added register_field_in_read_map() for marking used columns in expression.
This is used by filesort() for creating an optimal column bitmap while retrieving columns for sorting.
Initalize value.cs_info.character_set_client to fix core dump bug with --debug
set_query_id -> mark_used_columns
Mark used columns in read_set OR write_set.
sql/item.h:
Removed reset_query_id_processor() as it's not needed anymore.
Added register_field_in_read_map()
Added extra argument to Item::walk() to indicate if we should also
traverse sub queries.
sql/item_cmpfunc.cc:
Temporary mark used columns to be read/writable
Update Item::walk to new interface
sql/item_cmpfunc.h:
Added extra argument to Item::walk() to indicate if we should also traverse sub queries.
sql/item_func.cc:
Update Item::walk() to new interface
table_flags() -> ha_table_flags()
sql/item_func.h:
Update Item::walk() to new interface
sql/item_row.cc:
Update Item::walk() to new interface
sql/item_row.h:
Update Item::walk() to new interface
sql/item_strfunc.h:
Update Item::walk() to new interface
sql/item_subselect.cc:
Added Item_subselect::walk()
(It was a bug it was missing before. Not sure what kind of bugs this could have caused)
sql/item_subselect.h:
Update Item::walk() to new interface
sql/item_sum.cc:
Update Item::walk() to new interface
Updates for new handler interace
sql/item_sum.h:
Update Item::walk() to new interface
sql/key.cc:
Updates for new handler interace
sql/log.cc:
Mark all columns used for log tables
Split options flag
Ensured that second argument to trans_register_ha is a bool
sql/log_event.cc:
Fixed comments to be withing 79 characters
Use OPTION_KEEP_LOG instead of OPTION_STATUS_NO_TRANS_UPDATE to remove wrong warnings
Updates for new handler interface
Use 0x%lx instead of %p (portability problem)
sql/mysql_priv.h:
Added OPTION_KEEP_LOG to indicate that we should replicate the binlog even on rollback
Removed not used 'conds' argument to setup_tables
sql/mysqld.cc:
Indentation fixes and removed old comment
sql/opt_range.cc:
Update to new handler and bitmap interface.
Fixed calls to cp_buffer_from_ref() and walk() (new argument).
Create new temporary bitmaps for ror scans.
(Needed because of handler changes and to get more accurate column bitmaps than before)
Remove not needed file->ha_reset() call before file->close().
Some trivial optimization and indentation fixes.
Use Field->part_of_key_not_clustered() to check if field is part of a key, instead of looping over all key parts.
Added flag 'in_ror_merged_scan' to allow ::get_next() to know that we need a special column bitmap to only fetch pointer to record.
This is needed because ror scan uses the same TABLE object but different file objects, which creates problem for the column bitmap handling.
(This is a temporary solution. A better one would be to allocate an own TABLE object for ROR scans)
Optimized bitmap handling in ror scans:
- Start bitmap at position 0, not 1
- Use same bitmap size as in TABLE
- Use table->read_set and table->write_set to create column bitmaps instead of looping over all fields in table
sql/opt_range.h:
Added 'in_ror_merged_scan' to indicate if we are doing a ROR scan
Added temporary column bitmaps used in ROR scans
sql/opt_sum.cc:
Added get_ext_record_count() which is used in COUNT() optimization if handler has HA_HAS_RECORDS
Note that we don't call this if handler has HA_STATS_RECORDS_IS_EXACT set.
sql/protocol.cc:
We need to mark columns as readable in ::store() as we sometimes return default value for fields to the user
sql/records.cc:
Updates for new handler interface
sql/set_var.cc:
Handle splitting OPTION_STATUS_NO_TRANS_UPDATE to two flags
sql/share/errmsg.txt:
Fixed wrong
sql/sp.cc:
Mark that we are using all columns for the proc table
Update call to setup_tables() to use new prototype
sql/sp_head.cc:
Removed QQ comment
sql/spatial.cc:
Removed wrong QQ comment
sql/sql_acl.cc:
Mark that we need all columns for acl tables
Supply memroot to some 'new' calls.
Indentation fixes
sql/sql_base.cc:
set_query_id removed
Ensure we call ha_reset() at end of each statement
Mark read columns in read_set and changed columns in write_set (Before all columns was marked in read set)
Fixed marking of some columns that was not proplerly marked before
Maintain in TABLE->merge_keys set of all keys that are used in some way
Removed not used 'conds' argument from setup_tables()
Remove not used setting of 'dupp_field' in insert_fields()
Added missing FN_LIBCHAR in mysql_rm_tmp_tables()
(This has probably caused us to not properly remove temporary files after crash)
sql/sql_bitmap.h:
Added is_overlapping()
sql/sql_class.cc:
Slow_logs was not properly initialized, which could maybe cause extra/lost entries in slow log.
set_query_id -> mark_used_columns
Simpler variable usage in pack_row() (cleanup)
Moved some variable declartion at start of function for better code readability
sql/sql_class.h:
Added enum_mark_columns
Updated comments
Renamed dupp_field -> dup_field
Added virtual function 'can_rollback_data()' to select_insert() to be used in CREATE ... SELECT to optimize use of OPTION_STATUS_NO_TRANS_UPDATE.
(This fixes a bug in CREATE ... SELECT where we did give wrong warnings when using non transacational tables)
sql/sql_delete.cc:
Updates to new handler interface
Call table->mark_columns_needed_for_delete() to allow us to put additional columns in column usage maps if handler so requires.
Call table->prepare_for_position() to tell handler that we are going to call ha_position().
Removed call to free_io_cache(). (io_cache is now removed in ha_reset()).
Fixed calls to setup_tables()
sql/sql_do.cc:
Update call to setup_fields()
sql/sql_handler.cc:
Tell handler tables to always read all columns.
Use temporary column map when storing value in field for later index usage
sql/sql_help.cc:
Makr all used fields to be read
Update call to setup_fields()
sql/sql_insert.cc:
Tell handler we are going to update the auto_increment column
dupp_field -> dup_field
Set column usage bits for timestamp field.
Call table->mark_columns_needed_for_insert() and table->mark_auto_increment_column()
Removed not used argument from mysql_prepare_insert_check_table().
If we get an duplicate row on insert, change column map to read and write all columns while retrying the operatation.
This is required by the definition of REPLACE and also ensures that fields that are only part of UPDATE are properly handled.
This fixed a bug in NDB and REPLACE where REPLACE wrongly copied some column values from the replaced row.
Setup new bitmaps for delayed insert rows
Remove reseting of next_number_fields as it will be reset on next call to handler_insert()
Fixed usage of thd->options and OPTION_STATUS_NO_TRANS_UPDATE.
The issue was that one should not to reset this flag as it may be set by a previous statement.
The way it was now used caused us to loose some warnings and get other wrong warnings when using non transactional tables mixed with transactional.
I fixed it by introducing 'select_insert::can_rollback_data' to inform send_error() that the given statement can be rolled back (which in case of CREATE TABLE can always be done)
Don't close tables created with CREATE ... SELECT but keep them in the table cache.
Moved out MY_HOOKS from inside function (better readability)
sql/sql_load.cc:
Update to use new handler and column marking interface
Update using setup_tables()
sql/sql_olap.cc:
Update calls to setup_tables
Use enums instead of constants to setup_fields()
sql/sql_parse.cc:
Handle OPTION_KEEP_LOG:
- Set it on CREATE TEMPORARY TABLE / DROP TABLE
- Reset it when OPTION_STATUS_NO_TRANS_UPDATE is reset
- Don't set it for CREATE ... SELECT (this is handled in select_create class)
Remove reseting of OPTION_STATUS_NO_TRANS_UPDATE in begin_trans() as this should already be reset.
If in autocommit mode, reset OPTION_KEEP_LOG and OPTION_STATUS_NO_TRANS_UPDATE to not give warnings in future commands
sql/sql_partition.cc:
Update walk() usage
Trivial indentation fixes
sql/sql_plugin.cc:
Mark all columns as used for plugins
sql/sql_prepare.cc:
Added assert to find out hidden bugs in character_set_client (got an error in debug binary when this not set correctly)
Updates for new handler interface
Update calls to setup_fields()
sql/sql_repl.cc:
Indentation fixes
sql/sql_select.cc:
Update call to setup_tables() and setup_fields()
Remove some old disabled code
Update to new hadler interface
Indentation cleanups
Added column bitmaps for temporary tables.
Remove updating of the removed slots in the Field class
Added TABLE argument to cp_buffer_from_ref() (To be able to install temporary column maps)
For internal temporary tables, use handler::write_row(), handler::delete_row() and handler::update_row() instead of handler::ha_xxxx() for faster execution.
sql/sql_select.h:
Indentaition fixes.
Install temporary column usage maps when needed
Added TABLE element to cp_buffer_from_ref()
sql/sql_show.cc:
Update to new handler interface
Mark all columns used for internal tables.
Style fixes.
Added support for 'future' ROW_TYPE_PAGES.
Don't allocate TMP_TABLE_PARAM with calloc. The 'init()' function will initialize the structure properly.
sql/sql_table.cc:
Update to new handler interface
Simple my_snprintf -> strmake()
Changed some constants to defines
Don't test for NULL in primary key (as we a couple of line above force the PRIMARY KEY to be NOT NULL)
Change field->add_index to use field->flags & FIELD_IN_ADD_INDEX
Mark all columns as used for ALTER TABLE
Style fixes
Update call to filesort()
sql/sql_trigger.h:
Added friend functions to be able to test if triggers exists for table we are going to insert/update or delete in.
sql/sql_udf.cc:
Mark all columns as used for udf system table.
sql/sql_union.cc:
Update call to walk()
Update to new handler interface
sql/sql_update.cc:
Remove query_id argument from compare_record()
Use column bitmaps instead of query_id.
We can't use compare_records() to skip updates for handlers that returns a partial column set and the read_set doesn't cover all columns in the write set, because compare_record() can't in this case know if a not read column changed value.
Update call to setup_fields()
Using separate column read and write sets allows for easier checking of timestamp field was set by statement.
Removed call to free_io_cache() as this is now done in ha_reset()
Call table->mark_columns_needed_for_update() and table->prepare_for_position()
Style fixes
sql/sql_view.cc:
Style fixes
sql/table.cc:
Remove implicitely include 'errno.h'
Remove code for building normalized path, as this is now identical to 'path'
Remove field->fieldnr
Added update of field->part_of_key_not_clustered()
Create column bitmaps in TABLE and TABLE_SHARE
Don't setup a temporary MEM_ROOT object as a thread specific variable for the handler. Instead we send the to-be-used MEMROOT to get_new_handler()
Update to new handler interface
Update call to walk()
Added new functions:
- st_table::clear_column_bitmaps()
- st_table::prepare_for_position()
- st_table::mark_columns_used_by_index()
- st_table::restore_column_maps_after_mark_index()
- st_table::mark_columns_used_by_index_no_reset()
- st_table::mark_auto_increment_column()
- st_table::mark_columns_needed_for_delete()
- st_table::mark_columns_needed_for_update()
- st_table::mark_columns_needed_for_insert()
sql/table.h:
Moved column usage bitmaps from handler to TABLE
Added to TABLE_SHARE all_set and column_bitmap_size
Added to TABLE merge_keys, bitmap_init_values, def_read_set, def_write_set, tmp_set, read_set and write_set.
Declared all new table column bitmap functions
Added TABLE functions column_bitmaps_set(), column_bitmaps_set_no_signal(), use_all_columns() and default_column_bitmaps()
Added functions: tmp_use_all_columns() and tmp_restore_column_map() to temporarly switch column bitmaps
Added functions: dbug_tmp_use_all_columns() and dbug_tmp_restore_column_map() to temporarly switch column bitmaps to avoid asserts in Field::store() and Field::val().
sql/tztime.cc:
Mark all columns as used for timezone tables
storage/archive/ha_archive.cc:
Update to new handler interface
storage/archive/ha_archive.h:
Update to new handler interface
storage/blackhole/ha_blackhole.cc:
Update to new handler interface
storage/blackhole/ha_blackhole.h:
Update to new handler interface
removed not needed flag HA_DUPP_POS
storage/csv/ha_tina.cc:
Update to new handler interface
storage/csv/ha_tina.h:
Update to new handler interface
storage/example/ha_example.cc:
Update to new handler interface
storage/example/ha_example.h:
Update to new handler interface
storage/heap/hp_extra.c:
Added heap_reset() (Required by new handler interface)
storage/heap/hp_test2.c:
Use heap_reset()
storage/myisam/ft_boolean_search.c:
Fixed compiler warning
storage/myisam/mi_extra.c:
Added mi_reset() (Required by new handler interface)
storage/myisam/mi_search.c:
Fixed DBUG_PRINT messages to use 0x%lx instead of %lx
storage/myisam/mi_test2.c:
Use mi_reset()
storage/myisam/myisampack.c:
Use mi_reset()
storage/myisammrg/myrg_extra.c:
Added myrg_reset() (Required by new handler interface)
unittest/mysys/base64.t.c:
Include my_global.h
Don't include implictely include file 'stdlib.h'
2006-06-04 17:52:22 +02:00
|
|
|
|
|
|
|
while ((item=li++))
|
|
|
|
{
|
|
|
|
if (item->walk(processor, walk_subquery, argument))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
for (order= (ORDER*) lex->order_list.first ; order; order= order->next)
|
|
|
|
{
|
|
|
|
if ((*order->item)->walk(processor, walk_subquery, argument))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
for (order= (ORDER*) lex->group_list.first ; order; order= order->next)
|
|
|
|
{
|
|
|
|
if ((*order->item)->walk(processor, walk_subquery, argument))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (this->*processor)(argument);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
bool Item_subselect::exec()
|
2003-05-28 15:52:56 +02:00
|
|
|
{
|
2003-07-07 17:40:19 +02:00
|
|
|
int res;
|
2004-11-08 00:13:54 +01:00
|
|
|
|
2010-03-09 13:51:56 +01:00
|
|
|
/*
|
|
|
|
Do not execute subselect in case of a fatal error
|
|
|
|
or if the query has been killed.
|
|
|
|
*/
|
|
|
|
if (thd->is_error() || thd->killed)
|
2007-01-26 03:44:35 +01:00
|
|
|
return 1;
|
2010-03-09 13:51:56 +01:00
|
|
|
|
2008-07-04 16:02:17 +02:00
|
|
|
/*
|
|
|
|
Simulate a failure in sub-query execution. Used to test e.g.
|
|
|
|
out of memory or query being killed conditions.
|
|
|
|
*/
|
|
|
|
DBUG_EXECUTE_IF("subselect_exec_fail", return 1;);
|
2004-11-08 00:13:54 +01:00
|
|
|
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
res= engine->exec();
|
2004-11-08 00:13:54 +01:00
|
|
|
|
2003-07-07 17:40:19 +02:00
|
|
|
if (engine_changed)
|
|
|
|
{
|
|
|
|
engine_changed= 0;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
return exec();
|
2003-07-07 17:40:19 +02:00
|
|
|
}
|
|
|
|
return (res);
|
2003-05-28 15:52:56 +02:00
|
|
|
}
|
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-07-10 12:37:30 +02:00
|
|
|
/**
|
|
|
|
Check if an expression cache is needed for this subquery
|
|
|
|
|
|
|
|
@param thd Thread handle
|
|
|
|
|
|
|
|
@details
|
|
|
|
The function checks whether a cache is needed for a subquery and whether
|
|
|
|
the result of the subquery can be put in cache.
|
|
|
|
|
|
|
|
@retval TRUE cache is needed
|
|
|
|
@retval FALSE otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Item_subselect::expr_cache_is_needed(THD *thd)
|
|
|
|
{
|
|
|
|
return (depends_on.elements &&
|
|
|
|
engine->cols() == 1 &&
|
|
|
|
optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) &&
|
|
|
|
!(engine->uncacheable() & (UNCACHEABLE_RAND |
|
|
|
|
UNCACHEABLE_SIDEEFFECT)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Check if an expression cache is needed for this subquery
|
|
|
|
|
|
|
|
@param thd Thread handle
|
|
|
|
|
|
|
|
@details
|
|
|
|
The function checks whether a cache is needed for a subquery and whether
|
|
|
|
the result of the subquery can be put in cache.
|
|
|
|
|
|
|
|
@note
|
|
|
|
This method allows many columns in the subquery because it is supported by
|
|
|
|
Item_in optimizer and result of the IN subquery will be scalar in this
|
|
|
|
case.
|
|
|
|
|
|
|
|
@retval TRUE cache is needed
|
|
|
|
@retval FALSE otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Item_in_subselect::expr_cache_is_needed(THD *thd)
|
|
|
|
{
|
|
|
|
return (depends_on.elements &&
|
|
|
|
optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) &&
|
|
|
|
!(engine->uncacheable() & (UNCACHEABLE_RAND |
|
|
|
|
UNCACHEABLE_SIDEEFFECT)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
/*
|
|
|
|
Compute the IN predicate if the left operand's cache changed.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Item_in_subselect::exec()
|
|
|
|
{
|
|
|
|
DBUG_ENTER("Item_in_subselect::exec");
|
|
|
|
/*
|
|
|
|
Initialize the cache of the left predicate operand. This has to be done as
|
|
|
|
late as now, because Cached_item directly contains a resolved field (not
|
|
|
|
an item, and in some cases (when temp tables are created), these fields
|
|
|
|
end up pointing to the wrong field. One solution is to change Cached_item
|
|
|
|
to not resolve its field upon creation, but to resolve it dynamically
|
|
|
|
from a given Item_ref object.
|
|
|
|
TODO: the cache should be applied conditionally based on:
|
|
|
|
- rules - e.g. only if the left operand is known to be ordered, and/or
|
|
|
|
- on a cost-based basis, that takes into account the cost of a cache
|
|
|
|
lookup, the cache hit rate, and the savings per cache hit.
|
|
|
|
*/
|
|
|
|
if (!left_expr_cache && exec_method == MATERIALIZATION)
|
|
|
|
init_left_expr_cache();
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
|
|
|
If the new left operand is already in the cache, reuse the old result.
|
|
|
|
Use the cached result only if this is not the first execution of IN
|
|
|
|
because the cache is not valid for the first execution.
|
|
|
|
*/
|
|
|
|
if (!first_execution && left_expr_cache &&
|
|
|
|
test_if_item_cache_changed(*left_expr_cache) < 0)
|
|
|
|
DBUG_RETURN(FALSE);
|
2010-01-28 14:48:33 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
The exec() method below updates item::value, and item::null_value, thus if
|
|
|
|
we don't call it, the next call to item::val_int() will return whatever
|
|
|
|
result was computed by its previous call.
|
|
|
|
*/
|
|
|
|
DBUG_RETURN(Item_subselect::exec());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-04 07:46:28 +02:00
|
|
|
Item::Type Item_subselect::type() const
|
2002-12-19 06:38:33 +01:00
|
|
|
{
|
|
|
|
return SUBSELECT_ITEM;
|
|
|
|
}
|
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2002-09-28 17:34:56 +02:00
|
|
|
void Item_subselect::fix_length_and_dec()
|
|
|
|
{
|
2002-12-19 06:38:33 +01:00
|
|
|
engine->fix_length_and_dec(0);
|
2002-05-12 22:46:42 +02:00
|
|
|
}
|
2002-06-19 16:52:44 +02:00
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2003-10-16 23:36:01 +02:00
|
|
|
table_map Item_subselect::used_tables() const
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
2003-11-17 19:53:40 +01:00
|
|
|
return (table_map) (engine->uncacheable() ? used_tables_cache : 0L);
|
2002-06-19 16:52:44 +02:00
|
|
|
}
|
|
|
|
|
2003-10-28 11:45:37 +01:00
|
|
|
|
2003-10-16 23:36:01 +02:00
|
|
|
bool Item_subselect::const_item() const
|
|
|
|
{
|
2003-10-23 19:50:53 +02:00
|
|
|
return const_item_cache;
|
2003-10-16 23:36:01 +02:00
|
|
|
}
|
|
|
|
|
2006-12-14 23:51:37 +01:00
|
|
|
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
|
2003-12-06 20:37:24 +01:00
|
|
|
{
|
|
|
|
if (!with_sum_func && !const_item())
|
2004-03-20 12:36:26 +01:00
|
|
|
return new Item_field(result_field);
|
2006-12-14 23:51:37 +01:00
|
|
|
return copy_or_same(thd_arg);
|
2003-12-06 20:37:24 +01:00
|
|
|
}
|
2003-10-28 11:45:37 +01:00
|
|
|
|
2003-10-16 23:36:01 +02:00
|
|
|
void Item_subselect::update_used_tables()
|
|
|
|
{
|
2010-02-12 00:59:58 +01:00
|
|
|
recalc_used_tables(parent_select, FALSE);
|
2003-10-16 23:36:01 +02:00
|
|
|
if (!engine->uncacheable())
|
|
|
|
{
|
2005-02-08 23:50:45 +01:00
|
|
|
// did all used tables become static?
|
2003-11-01 18:02:43 +01:00
|
|
|
if (!(used_tables_cache & ~engine->upper_select_const_tables()))
|
2003-10-16 23:36:01 +02:00
|
|
|
const_item_cache= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_subselect::print(String *str, enum_query_type query_type)
|
2003-10-16 14:54:47 +02:00
|
|
|
{
|
2010-01-28 14:48:33 +01:00
|
|
|
if (engine)
|
|
|
|
{
|
|
|
|
str->append('(');
|
|
|
|
engine->print(str, query_type);
|
|
|
|
str->append(')');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
str->append("(...)");
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-07 07:51:09 +02:00
|
|
|
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
|
2003-08-12 11:38:03 +02:00
|
|
|
:Item_subselect(), value(0)
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
2002-12-19 20:15:09 +01:00
|
|
|
DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect");
|
2003-10-02 21:19:41 +02:00
|
|
|
init(select_lex, new select_singlerow_subselect(this));
|
2002-06-19 16:52:44 +02:00
|
|
|
maybe_null= 1;
|
2002-12-19 06:38:33 +01:00
|
|
|
max_columns= UINT_MAX;
|
2002-10-27 22:27:00 +01:00
|
|
|
DBUG_VOID_RETURN;
|
2002-06-19 16:52:44 +02:00
|
|
|
}
|
|
|
|
|
Bug#21904 (parser problem when using IN with a double "(())")
Before this fix, a IN predicate of the form: "IN (( subselect ))", with two
parenthesis, would be evaluated as a single row subselect: if the subselect
returns more that 1 row, the statement would fail.
The SQL:2003 standard defines a special exception in the specification,
and mandates that this particular form of IN predicate shall be equivalent
to "IN ( subselect )", which involves a table subquery and works with more
than 1 row.
This fix implements "IN (( subselect ))", "IN ((( subselect )))" etc
as per the SQL:2003 requirement.
All the details related to the implementation of this change have been
commented in the code, and the relevant sections of the SQL:2003 spec
are given for reference, so they are not repeated here.
Having access to the spec is a requirement to review in depth this patch.
mysql-test/r/subselect.result:
Implement IN predicate special exceptions with subselects.
mysql-test/t/subselect.test:
Implement IN predicate special exceptions with subselects.
sql/item_subselect.cc:
Implement IN predicate special exceptions with subselects.
sql/item_subselect.h:
Implement IN predicate special exceptions with subselects.
sql/sql_yacc.yy:
Implement IN predicate special exceptions with subselects, cleanup.
2007-01-30 01:32:52 +01:00
|
|
|
st_select_lex *
|
|
|
|
Item_singlerow_subselect::invalidate_and_restore_select_lex()
|
|
|
|
{
|
|
|
|
DBUG_ENTER("Item_singlerow_subselect::invalidate_and_restore_select_lex");
|
|
|
|
st_select_lex *result= get_select_lex();
|
|
|
|
|
|
|
|
DBUG_ASSERT(result);
|
|
|
|
|
|
|
|
/*
|
|
|
|
This code restore the parse tree in it's state before the execution of
|
|
|
|
Item_singlerow_subselect::Item_singlerow_subselect(),
|
|
|
|
and in particular decouples this object from the SELECT_LEX,
|
|
|
|
so that the SELECT_LEX can be used with a different flavor
|
|
|
|
or Item_subselect instead, as part of query rewriting.
|
|
|
|
*/
|
|
|
|
unit->item= NULL;
|
|
|
|
|
|
|
|
DBUG_RETURN(result);
|
|
|
|
}
|
|
|
|
|
2004-09-10 12:09:27 +02:00
|
|
|
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
|
|
|
|
Item_subselect *parent,
|
2003-10-27 00:01:27 +01:00
|
|
|
st_select_lex *select_lex,
|
2003-10-16 14:54:47 +02:00
|
|
|
bool max_arg)
|
2004-11-18 17:10:07 +01:00
|
|
|
:Item_singlerow_subselect(), was_values(TRUE)
|
2003-08-12 11:38:03 +02:00
|
|
|
{
|
|
|
|
DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect");
|
2003-10-16 14:54:47 +02:00
|
|
|
max= max_arg;
|
|
|
|
init(select_lex, new select_max_min_finder_subselect(this, max_arg));
|
2003-08-12 11:38:03 +02:00
|
|
|
max_columns= 1;
|
|
|
|
maybe_null= 1;
|
|
|
|
max_columns= 1;
|
2003-10-27 00:01:27 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Following information was collected during performing fix_fields()
|
|
|
|
of Items belonged to subquery, which will be not repeated
|
|
|
|
*/
|
|
|
|
used_tables_cache= parent->get_used_tables_cache();
|
|
|
|
const_item_cache= parent->get_const_item_cache();
|
2004-07-04 07:46:28 +02:00
|
|
|
|
2004-09-10 12:09:27 +02:00
|
|
|
/*
|
2005-02-08 23:50:45 +01:00
|
|
|
this subquery always creates during preparation, so we can assign
|
2004-09-10 12:09:27 +02:00
|
|
|
thd here
|
|
|
|
*/
|
|
|
|
thd= thd_param;
|
|
|
|
|
2003-08-12 11:38:03 +02:00
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
2004-11-18 17:10:07 +01:00
|
|
|
void Item_maxmin_subselect::cleanup()
|
|
|
|
{
|
2004-12-07 20:18:15 +01:00
|
|
|
DBUG_ENTER("Item_maxmin_subselect::cleanup");
|
|
|
|
Item_singlerow_subselect::cleanup();
|
|
|
|
|
2004-11-18 17:10:07 +01:00
|
|
|
/*
|
2004-12-07 20:18:15 +01:00
|
|
|
By default it is TRUE to avoid TRUE reporting by
|
2004-11-18 17:10:07 +01:00
|
|
|
Item_func_not_all/Item_func_nop_all if this item was never called.
|
|
|
|
|
|
|
|
Engine exec() set it to FALSE by reset_value_registration() call.
|
2004-12-07 20:18:15 +01:00
|
|
|
select_max_min_finder_subselect::send_data() set it back to TRUE if some
|
|
|
|
value will be found.
|
2004-11-18 17:10:07 +01:00
|
|
|
*/
|
|
|
|
was_values= TRUE;
|
2004-12-07 20:18:15 +01:00
|
|
|
DBUG_VOID_RETURN;
|
2004-11-18 17:10:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
|
2003-10-16 14:54:47 +02:00
|
|
|
{
|
2003-10-30 11:57:26 +01:00
|
|
|
str->append(max?"<max>":"<min>", 5);
|
2008-02-22 11:30:33 +01:00
|
|
|
Item_singlerow_subselect::print(str, query_type);
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
|
|
|
|
2004-11-18 17:10:07 +01:00
|
|
|
|
2002-12-19 20:15:09 +01:00
|
|
|
void Item_singlerow_subselect::reset()
|
2002-09-28 17:34:56 +02:00
|
|
|
{
|
2010-03-09 16:03:54 +01:00
|
|
|
eliminated= FALSE;
|
2002-12-19 06:38:32 +01:00
|
|
|
null_value= 1;
|
|
|
|
if (value)
|
|
|
|
value->null_value= 1;
|
2002-09-28 17:34:56 +02:00
|
|
|
}
|
|
|
|
|
2004-11-18 17:10:07 +01:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
@todo
|
|
|
|
- We cant change name of Item_field or Item_ref, because it will
|
|
|
|
prevent it's correct resolving, but we should save name of
|
|
|
|
removed item => we do not make optimization if top item of
|
|
|
|
list is field or reference.
|
|
|
|
- switch off this optimization for prepare statement,
|
|
|
|
because we do not rollback this changes.
|
|
|
|
Make rollback for it, or special name resolving mode in 5.0.
|
|
|
|
*/
|
2003-05-14 20:51:33 +02:00
|
|
|
Item_subselect::trans_res
|
2003-07-02 00:45:22 +02:00
|
|
|
Item_singlerow_subselect::select_transformer(JOIN *join)
|
2002-12-26 00:28:59 +01:00
|
|
|
{
|
2010-01-28 14:48:33 +01:00
|
|
|
DBUG_ENTER("Item_singlerow_subselect::select_transformer");
|
2004-02-08 19:14:13 +01:00
|
|
|
if (changed)
|
2010-01-28 14:48:33 +01:00
|
|
|
DBUG_RETURN(RES_OK);
|
2004-07-04 07:46:28 +02:00
|
|
|
|
2003-05-14 20:51:33 +02:00
|
|
|
SELECT_LEX *select_lex= join->select_lex;
|
2005-09-02 15:21:19 +02:00
|
|
|
Query_arena *arena= thd->stmt_arena;
|
2004-10-29 18:26:52 +02:00
|
|
|
|
2007-04-23 13:16:49 +02:00
|
|
|
if (!select_lex->master_unit()->is_union() &&
|
2003-05-14 20:51:33 +02:00
|
|
|
!select_lex->table_list.elements &&
|
2002-12-31 17:39:16 +01:00
|
|
|
select_lex->item_list.elements == 1 &&
|
2004-10-27 20:11:06 +02:00
|
|
|
!select_lex->item_list.head()->with_sum_func &&
|
2003-02-02 22:30:01 +01:00
|
|
|
/*
|
|
|
|
We cant change name of Item_field or Item_ref, because it will
|
|
|
|
prevent it's correct resolving, but we should save name of
|
|
|
|
removed item => we do not make optimization if top item of
|
|
|
|
list is field or reference.
|
|
|
|
TODO: solve above problem
|
|
|
|
*/
|
2002-12-31 17:39:16 +01:00
|
|
|
!(select_lex->item_list.head()->type() == FIELD_ITEM ||
|
2004-10-27 20:11:06 +02:00
|
|
|
select_lex->item_list.head()->type() == REF_ITEM) &&
|
2006-12-12 03:57:23 +01:00
|
|
|
!join->conds && !join->having &&
|
2004-10-27 20:11:06 +02:00
|
|
|
/*
|
2005-02-08 23:50:45 +01:00
|
|
|
switch off this optimization for prepare statement,
|
2004-10-27 20:11:06 +02:00
|
|
|
because we do not rollback this changes
|
|
|
|
TODO: make rollback for it, or special name resolving mode in 5.0.
|
|
|
|
*/
|
2005-06-02 22:02:47 +02:00
|
|
|
!arena->is_stmt_prepare_or_first_sp_execute()
|
2002-12-31 17:39:16 +01:00
|
|
|
)
|
2002-12-26 00:28:59 +01:00
|
|
|
{
|
2004-07-04 07:46:28 +02:00
|
|
|
|
2002-12-26 00:28:59 +01:00
|
|
|
have_to_be_excluded= 1;
|
2004-09-10 01:22:44 +02:00
|
|
|
if (thd->lex->describe)
|
2002-12-26 00:28:59 +01:00
|
|
|
{
|
|
|
|
char warn_buff[MYSQL_ERRMSG_SIZE];
|
|
|
|
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
|
2004-09-10 01:22:44 +02:00
|
|
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
2002-12-26 00:28:59 +01:00
|
|
|
ER_SELECT_REDUCED, warn_buff);
|
|
|
|
}
|
|
|
|
substitution= select_lex->item_list.head();
|
2003-07-02 12:12:18 +02:00
|
|
|
/*
|
2005-02-08 23:50:45 +01:00
|
|
|
as far as we moved content to upper level, field which depend of
|
2003-07-02 12:12:18 +02:00
|
|
|
'upper' select is not really dependent => we remove this dependence
|
|
|
|
*/
|
This changeset is largely a handler cleanup changeset (WL#3281), but includes fixes and cleanups that was found necessary while testing the handler changes
Changes that requires code changes in other code of other storage engines.
(Note that all changes are very straightforward and one should find all issues
by compiling a --debug build and fixing all compiler errors and all
asserts in field.cc while running the test suite),
- New optional handler function introduced: reset()
This is called after every DML statement to make it easy for a handler to
statement specific cleanups.
(The only case it's not called is if force the file to be closed)
- handler::extra(HA_EXTRA_RESET) is removed. Code that was there before
should be moved to handler::reset()
- table->read_set contains a bitmap over all columns that are needed
in the query. read_row() and similar functions only needs to read these
columns
- table->write_set contains a bitmap over all columns that will be updated
in the query. write_row() and update_row() only needs to update these
columns.
The above bitmaps should now be up to date in all context
(including ALTER TABLE, filesort()).
The handler is informed of any changes to the bitmap after
fix_fields() by calling the virtual function
handler::column_bitmaps_signal(). If the handler does caching of
these bitmaps (instead of using table->read_set, table->write_set),
it should redo the caching in this code. as the signal() may be sent
several times, it's probably best to set a variable in the signal
and redo the caching on read_row() / write_row() if the variable was
set.
- Removed the read_set and write_set bitmap objects from the handler class
- Removed all column bit handling functions from the handler class.
(Now one instead uses the normal bitmap functions in my_bitmap.c instead
of handler dedicated bitmap functions)
- field->query_id is removed. One should instead instead check
table->read_set and table->write_set if a field is used in the query.
- handler::extra(HA_EXTRA_RETRIVE_ALL_COLS) and
handler::extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY) are removed. One should now
instead use table->read_set to check for which columns to retrieve.
- If a handler needs to call Field->val() or Field->store() on columns
that are not used in the query, one should install a temporary
all-columns-used map while doing so. For this, we provide the following
functions:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
field->val();
dbug_tmp_restore_column_map(table->read_set, old_map);
and similar for the write map:
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
field->val();
dbug_tmp_restore_column_map(table->write_set, old_map);
If this is not done, you will sooner or later hit a DBUG_ASSERT
in the field store() / val() functions.
(For not DBUG binaries, the dbug_tmp_restore_column_map() and
dbug_tmp_restore_column_map() are inline dummy functions and should
be optimized away be the compiler).
- If one needs to temporary set the column map for all binaries (and not
just to avoid the DBUG_ASSERT() in the Field::store() / Field::val()
methods) one should use the functions tmp_use_all_columns() and
tmp_restore_column_map() instead of the above dbug_ variants.
- All 'status' fields in the handler base class (like records,
data_file_length etc) are now stored in a 'stats' struct. This makes
it easier to know what status variables are provided by the base
handler. This requires some trivial variable names in the extra()
function.
- New virtual function handler::records(). This is called to optimize
COUNT(*) if (handler::table_flags() & HA_HAS_RECORDS()) is true.
(stats.records is not supposed to be an exact value. It's only has to
be 'reasonable enough' for the optimizer to be able to choose a good
optimization path).
- Non virtual handler::init() function added for caching of virtual
constants from engine.
- Removed has_transactions() virtual method. Now one should instead return
HA_NO_TRANSACTIONS in table_flags() if the table handler DOES NOT support
transactions.
- The 'xxxx_create_handler()' function now has a MEM_ROOT_root argument
that is to be used with 'new handler_name()' to allocate the handler
in the right area. The xxxx_create_handler() function is also
responsible for any initialization of the object before returning.
For example, one should change:
static handler *myisam_create_handler(TABLE_SHARE *table)
{
return new ha_myisam(table);
}
->
static handler *myisam_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
{
return new (mem_root) ha_myisam(table);
}
- New optional virtual function: use_hidden_primary_key().
This is called in case of an update/delete when
(table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
but we don't have a primary key. This allows the handler to take precisions
in remembering any hidden primary key to able to update/delete any
found row. The default handler marks all columns to be read.
- handler::table_flags() now returns a ulonglong (to allow for more flags).
- New/changed table_flags()
- HA_HAS_RECORDS Set if ::records() is supported
- HA_NO_TRANSACTIONS Set if engine doesn't support transactions
- HA_PRIMARY_KEY_REQUIRED_FOR_DELETE
Set if we should mark all primary key columns for
read when reading rows as part of a DELETE
statement. If there is no primary key,
all columns are marked for read.
- HA_PARTIAL_COLUMN_READ Set if engine will not read all columns in some
cases (based on table->read_set)
- HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS
Renamed to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION.
- HA_DUPP_POS Renamed to HA_DUPLICATE_POS
- HA_REQUIRES_KEY_COLUMNS_FOR_DELETE
Set this if we should mark ALL key columns for
read when when reading rows as part of a DELETE
statement. In case of an update we will mark
all keys for read for which key part changed
value.
- HA_STATS_RECORDS_IS_EXACT
Set this if stats.records is exact.
(This saves us some extra records() calls
when optimizing COUNT(*))
- Removed table_flags()
- HA_NOT_EXACT_COUNT Now one should instead use HA_HAS_RECORDS if
handler::records() gives an exact count() and
HA_STATS_RECORDS_IS_EXACT if stats.records is exact.
- HA_READ_RND_SAME Removed (no one supported this one)
- Removed not needed functions ha_retrieve_all_cols() and ha_retrieve_all_pk()
- Renamed handler::dupp_pos to handler::dup_pos
- Removed not used variable handler::sortkey
Upper level handler changes:
- ha_reset() now does some overall checks and calls ::reset()
- ha_table_flags() added. This is a cached version of table_flags(). The
cache is updated on engine creation time and updated on open.
MySQL level changes (not obvious from the above):
- DBUG_ASSERT() added to check that column usage matches what is set
in the column usage bit maps. (This found a LOT of bugs in current
column marking code).
- In 5.1 before, all used columns was marked in read_set and only updated
columns was marked in write_set. Now we only mark columns for which we
need a value in read_set.
- Column bitmaps are created in open_binary_frm() and open_table_from_share().
(Before this was in table.cc)
- handler::table_flags() calls are replaced with handler::ha_table_flags()
- For calling field->val() you must have the corresponding bit set in
table->read_set. For calling field->store() you must have the
corresponding bit set in table->write_set. (There are asserts in
all store()/val() functions to catch wrong usage)
- thd->set_query_id is renamed to thd->mark_used_columns and instead
of setting this to an integer value, this has now the values:
MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE
Changed also all variables named 'set_query_id' to mark_used_columns.
- In filesort() we now inform the handler of exactly which columns are needed
doing the sort and choosing the rows.
- The TABLE_SHARE object has a 'all_set' column bitmap one can use
when one needs a column bitmap with all columns set.
(This is used for table->use_all_columns() and other places)
- The TABLE object has 3 column bitmaps:
- def_read_set Default bitmap for columns to be read
- def_write_set Default bitmap for columns to be written
- tmp_set Can be used as a temporary bitmap when needed.
The table object has also two pointer to bitmaps read_set and write_set
that the handler should use to find out which columns are used in which way.
- count() optimization now calls handler::records() instead of using
handler->stats.records (if (table_flags() & HA_HAS_RECORDS) is true).
- Added extra argument to Item::walk() to indicate if we should also
traverse sub queries.
- Added TABLE parameter to cp_buffer_from_ref()
- Don't close tables created with CREATE ... SELECT but keep them in
the table cache. (Faster usage of newly created tables).
New interfaces:
- table->clear_column_bitmaps() to initialize the bitmaps for tables
at start of new statements.
- table->column_bitmaps_set() to set up new column bitmaps and signal
the handler about this.
- table->column_bitmaps_set_no_signal() for some few cases where we need
to setup new column bitmaps but don't signal the handler (as the handler
has already been signaled about these before). Used for the momement
only in opt_range.cc when doing ROR scans.
- table->use_all_columns() to install a bitmap where all columns are marked
as use in the read and the write set.
- table->default_column_bitmaps() to install the normal read and write
column bitmaps, but not signaling the handler about this.
This is mainly used when creating TABLE instances.
- table->mark_columns_needed_for_delete(),
table->mark_columns_needed_for_delete() and
table->mark_columns_needed_for_insert() to allow us to put additional
columns in column usage maps if handler so requires.
(The handler indicates what it neads in handler->table_flags())
- table->prepare_for_position() to allow us to tell handler that it
needs to read primary key parts to be able to store them in
future table->position() calls.
(This replaces the table->file->ha_retrieve_all_pk function)
- table->mark_auto_increment_column() to tell handler are going to update
columns part of any auto_increment key.
- table->mark_columns_used_by_index() to mark all columns that is part of
an index. It will also send extra(HA_EXTRA_KEYREAD) to handler to allow
it to quickly know that it only needs to read colums that are part
of the key. (The handler can also use the column map for detecting this,
but simpler/faster handler can just monitor the extra() call).
- table->mark_columns_used_by_index_no_reset() to in addition to other columns,
also mark all columns that is used by the given key.
- table->restore_column_maps_after_mark_index() to restore to default
column maps after a call to table->mark_columns_used_by_index().
- New item function register_field_in_read_map(), for marking used columns
in table->read_map. Used by filesort() to mark all used columns
- Maintain in TABLE->merge_keys set of all keys that are used in query.
(Simplices some optimization loops)
- Maintain Field->part_of_key_not_clustered which is like Field->part_of_key
but the field in the clustered key is not assumed to be part of all index.
(used in opt_range.cc for faster loops)
- dbug_tmp_use_all_columns(), dbug_tmp_restore_column_map()
tmp_use_all_columns() and tmp_restore_column_map() functions to temporally
mark all columns as usable. The 'dbug_' version is primarily intended
inside a handler when it wants to just call Field:store() & Field::val()
functions, but don't need the column maps set for any other usage.
(ie:: bitmap_is_set() is never called)
- We can't use compare_records() to skip updates for handlers that returns
a partial column set and the read_set doesn't cover all columns in the
write set. The reason for this is that if we have a column marked only for
write we can't in the MySQL level know if the value changed or not.
The reason this worked before was that MySQL marked all to be written
columns as also to be read. The new 'optimal' bitmaps exposed this 'hidden
bug'.
- open_table_from_share() does not anymore setup temporary MEM_ROOT
object as a thread specific variable for the handler. Instead we
send the to-be-used MEMROOT to get_new_handler().
(Simpler, faster code)
Bugs fixed:
- Column marking was not done correctly in a lot of cases.
(ALTER TABLE, when using triggers, auto_increment fields etc)
(Could potentially result in wrong values inserted in table handlers
relying on that the old column maps or field->set_query_id was correct)
Especially when it comes to triggers, there may be cases where the
old code would cause lost/wrong values for NDB and/or InnoDB tables.
- Split thd->options flag OPTION_STATUS_NO_TRANS_UPDATE to two flags:
OPTION_STATUS_NO_TRANS_UPDATE and OPTION_KEEP_LOG.
This allowed me to remove some wrong warnings about:
"Some non-transactional changed tables couldn't be rolled back"
- Fixed handling of INSERT .. SELECT and CREATE ... SELECT that wrongly reset
(thd->options & OPTION_STATUS_NO_TRANS_UPDATE) which caused us to loose
some warnings about
"Some non-transactional changed tables couldn't be rolled back")
- Fixed use of uninitialized memory in ha_ndbcluster.cc::delete_table()
which could cause delete_table to report random failures.
- Fixed core dumps for some tests when running with --debug
- Added missing FN_LIBCHAR in mysql_rm_tmp_tables()
(This has probably caused us to not properly remove temporary files after
crash)
- slow_logs was not properly initialized, which could maybe cause
extra/lost entries in slow log.
- If we get an duplicate row on insert, change column map to read and
write all columns while retrying the operation. This is required by
the definition of REPLACE and also ensures that fields that are only
part of UPDATE are properly handled. This fixed a bug in NDB and
REPLACE where REPLACE wrongly copied some column values from the replaced
row.
- For table handler that doesn't support NULL in keys, we would give an error
when creating a primary key with NULL fields, even after the fields has been
automaticly converted to NOT NULL.
- Creating a primary key on a SPATIAL key, would fail if field was not
declared as NOT NULL.
Cleanups:
- Removed not used condition argument to setup_tables
- Removed not needed item function reset_query_id_processor().
- Field->add_index is removed. Now this is instead maintained in
(field->flags & FIELD_IN_ADD_INDEX)
- Field->fieldnr is removed (use field->field_index instead)
- New argument to filesort() to indicate that it should return a set of
row pointers (not used columns). This allowed me to remove some references
to sql_command in filesort and should also enable us to return column
results in some cases where we couldn't before.
- Changed column bitmap handling in opt_range.cc to be aligned with TABLE
bitmap, which allowed me to use bitmap functions instead of looping over
all fields to create some needed bitmaps. (Faster and smaller code)
- Broke up found too long lines
- Moved some variable declaration at start of function for better code
readability.
- Removed some not used arguments from functions.
(setup_fields(), mysql_prepare_insert_check_table())
- setup_fields() now takes an enum instead of an int for marking columns
usage.
- For internal temporary tables, use handler::write_row(),
handler::delete_row() and handler::update_row() instead of
handler::ha_xxxx() for faster execution.
- Changed some constants to enum's and define's.
- Using separate column read and write sets allows for easier checking
of timestamp field was set by statement.
- Remove calls to free_io_cache() as this is now done automaticly in ha_reset()
- Don't build table->normalized_path as this is now identical to table->path
(after bar's fixes to convert filenames)
- Fixed some missed DBUG_PRINT(.."%lx") to use "0x%lx" to make it easier to
do comparision with the 'convert-dbug-for-diff' tool.
Things left to do in 5.1:
- We wrongly log failed CREATE TABLE ... SELECT in some cases when using
row based logging (as shown by testcase binlog_row_mix_innodb_myisam.result)
Mats has promised to look into this.
- Test that my fix for CREATE TABLE ... SELECT is indeed correct.
(I added several test cases for this, but in this case it's better that
someone else also tests this throughly).
Lars has promosed to do this.
BitKeeper/etc/ignore:
added mysys/test_bitmap
include/base64.h:
Removed my_global.h, as this must be included first in any program
include/heap.h:
Added heap_reset() (Required by new handler interface)
include/my_base.h:
Removed HA_EXTRA_RESET. MySQL will now call ::reset() instead of ::extra(HA_EXTRA_RESET).
HA_EXTRA_RETRIVE_ALL_COLS and HA_EXTRA_RETRIVE_PRIMARY key are deleted as the column bitmaps makes these unnecessary
include/my_bitmap.h:
Remove my_pthread.h (should be included at upper level)
Introduced my_bitmap_map typedef to make it the bitmap handling more like a black box
Added bitmap_is_overlapping(), bitmap_test_and_clear(), bitmap_copy() and bitmap_cmp()
Made bitmap_set_bit(), bitmap_flip_bit(), bitmap_clear_bit() return void
include/myisam.h:
Added mi_reset() (Required by new handler interface)
include/myisammrg.h:
Added myrg_reset() (Required by new handler interface)
include/mysql_com.h:
Added flag FIELD_IN_ADD_INDEX to be able to remove Field->add_index
mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test:
Added testing of CREATE ... SELECT in a mixed environment
(This found some bugs that Mats is going to fix shortly)
mysql-test/install_test_db.sh:
Simplify ldata usage
Added --tmpdir=. option to mysqld bootstrap (Removed some warnings when TMPDIR was wrongly set)
mysql-test/mysql-test-run.pl:
Added --tmpdir=. to bootstrap
mysql-test/mysql-test-run.sh:
Use copy instead of INSTALL_DB for master and slave databases.
(Speeds up startup time a lot!)
Remove snapshot directories at startup (removes some strange warnings)
mysql-test/r/binlog_row_mix_innodb_myisam.result:
Added testing of CREATE ... SELECT in a mixed environment
(This found some bugs that Mats is going to fix shortly)
mysql-test/r/binlog_stm_mix_innodb_myisam.result:
Added testing of CREATE ... SELECT in a mixed environment
mysql-test/r/create.result:
Some extra tests of warnings and number of tables opened by CREATE ... SELECT
mysql-test/r/federated.result:
Drop some left over tables
Added testing of multiple table update and multiple table delete (with and without keys)
mysql-test/r/func_gconcat.result:
Enable some disabled tests (converted them slightly to be predictable)
mysql-test/r/func_time.result:
Added drop of test function
mysql-test/r/innodb_mysql.result:
Added tests for CREATE ... SELECT
mysql-test/r/insert.result:
More tests
Added testing of duplicate columns in insert
mysql-test/r/loaddata.result:
Added testing LOAD DATA ... SET ...
mysql-test/r/multi_update.result:
Test multi updates and deletes using primary key and without
mysql-test/r/ndb_index_unique.result:
Better error message
mysql-test/r/ndb_replace.result:
New correct result after fixing REPLACE handling with NDB
mysql-test/r/rpl_ddl.result:
Now we don't get these (wrong) warnings anymore
mysql-test/r/view_grant.result:
Drop used views
mysql-test/t/create.test:
Some extra tests of warnings and number of tables opened by CREATE ... SELECT
mysql-test/t/federated.test:
Drop some left over tables
Added testing of multiple table update and multiple table delete (with and without keys)
mysql-test/t/func_gconcat.test:
Enable some disabled tests (converted them slightly to be predictable)
mysql-test/t/func_time.test:
Added drop of test function
mysql-test/t/innodb_mysql.test:
Added tests for CREATE ... SELECT
mysql-test/t/insert.test:
More tests
Added testing of duplicate columns in insert
mysql-test/t/loaddata.test:
Added testing LOAD DATA ... SET ...
mysql-test/t/multi_update.test:
Test multi updates and deletes using primary key and without
mysql-test/t/view_grant.test:
Drop used views
mysql-test/valgrind.supp:
Added supression of not needed warnings when printing stack trace
mysys/base64.c:
Include my_global.h first
mysys/my_bitmap.c:
Added bitmap_is_overlapping(), bitmap_test_and_clear() and bitmap_copy()
Changed logic of bitmap handling to be a bit more efficent (Did this together with Mikael Ronström)
Now the 'extra, not used bits' in the bitmap are assumed to have a 'random value' and the bitmap functions are free to change them whenever needed.
Changed how mutex is allocated to make 'bitmap_free()' function simpler.
mysys/thr_lock.c:
Added 0x before thread pointers (for easier comparison of DBUG traces)
sql/event.cc:
Ensure 'use_all_columns()' is used for event tables
Don't print warning that event table is damaged if it doesn't exists.
sql/field.cc:
Added ASSERT_COLUMN_MARKED_FOR_WRITE in all store() methods and ASSERT_COLUMN_MARKED_FOR_READ in all val() methods to catch wrong setting if table->read_set and table->write_set
(Rest of changes are only indentation cleanups)
sql/field.h:
Removed Field->query_id (replaced by table->read_set and table->write_set)
Removed Field->fieldnr (use Field->field_index instead)
Removed Field->add_index (Use Field->flags instead)
Add Field->part_of_key_not_clustered (for usage in opt_range.cc)
sql/filesort.cc:
Added paramater sort_postion to filesort() to force sorting by position instead of storing all fields in the result set.
This allowed me to remove checking of sql_command.
Create a temporary column bitmap for fields that are used by the sorting process.
Use column bitmaps instead of query_id
sql/ha_berkeley.cc:
Update to 'newer' table handler interface
sql/ha_berkeley.h:
Update to 'newer' table handler interface
sql/ha_federated.cc:
Update to 'newer' table handler interface
Only read columns that are needed from remote server.
In case of eq ranges, don't generate two conditions in the WHERE clause
(this can still be optimized, but would require a bigger code change)
Use 'simpler to use' XXXX_LEN' macros
A bit simpler logic in ::write_row() when creating statements.
In update, only include test of fields actually read.
(This greatly simplifies the queries sent by the federated engine)
Similar changes done for delete_row()
sql/ha_federated.h:
Update to 'newer' table handler interface
Changed XXX_LEN macros to use sizeof(...)-1, to simplify usage in ha_federated.cc
Added HA_PRIMARY_KEY_REQUIRED_FOR_DELETE to tell MySQL to read all primary key columns in case of DELETE
sql/ha_heap.cc:
Update to 'newer' table handler interface
sql/ha_heap.h:
Update to 'newer' table handler interface
sql/ha_innodb.cc:
Update to 'newer' table handler interface
- Update innobase_create_handler() to new interface
- Removed HA_NOT_EXACT_COUNT (not needed)
- Renamed HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION.
- Prefixed base status variables with 'stats'
- Use table column bitmaps instead of ha_get_bit_in_read_set()
- Added ::reset(), with code from ::extra(HA_EXTRA_RESET)
- Removed HA_EXTRA_RETRIVE_ALL_COLS and HA_EXTRA_RETRIEVE_PRIMARY_KEY as
the table->read_set and table->write_set bitmaps now are accurate
sql/ha_innodb.h:
Update to 'newer' table handler interface
- table_flags are now ulonglong
- Added reset() method
- Removed not needed ha_retrieve_all_cols() and ha_retrieve_all_pk() columns.
- Made build_template() a class function to be able to easier access class variables
sql/ha_myisam.cc:
Update to 'newer' table handler interface
sql/ha_myisam.h:
Update to 'newer' table handler interface
sql/ha_myisammrg.cc:
Update to 'newer' table handler interface
sql/ha_myisammrg.h:
Update to 'newer' table handler interface
sql/ha_ndbcluster.cc:
Update to 'newer' table handler interface
Fixed use_blob_value() to be accurate
In ::complemented_read() we have to check both the read and write bitmap as the old code did mark all changed columns also in the read map
Correct dumping of field data with DBUG_DUMP
Prefix addresses in DBUG_PRINT with 0x
Fixed usage of not initialized memory
Update to use field->flags & FIELD_IN_ADD_INDEX instead of field->add_index.
sql/ha_ndbcluster.h:
Update to 'newer' table handler interface
sql/ha_ndbcluster_binlog.cc:
Mark usage of all columns in ndbcluster binlog tables
false -> FALSE, true -> TRUE
Use table->s->all_set instead of creating a temporary bitmap.
sql/ha_partition.cc:
Update to 'newer' table handler interface
Added memroot to initialise_partitions() and related functions to get faster memory allocation.
partition_create_handler() is now responsible for initialisation of the partition object
Some trivial optimizations and indentation fixes
Ensure that table_flags() are up to date
Removed documentation for removed HA_EXTRA flags
Fixed 'strange' usage of m_file[i] in new_handlers_from_part_info()that worked in current code 'by chance'
sql/ha_partition.h:
Update to 'newer' table handler interface
sql/handler.cc:
create_xxx handler now takes MEMROOT as an argument to simplify memory allocation.
Much simpler get_new_handler()
(Initialization of the object is now handled by the create method for the engine)
Moved all allocation of bitmap handling to the TABLE object (in table.cc)
Added column_bitmaps_signal() to signal column usage changes.
Changed binlog_log_row() to use the exiusting all_set bitmap in the table object.
Added ha_reset() function to test that the file object is ok at end of statement and call handler::reset()
Added use_hidden_primary_key() to signal handler that we we are going to read and update + delete the row and the handler should thus remember the position for the row
sql/handler.h:
Added HA_NO_TRANSACTIONS, HA_PARTIAL_COLUMN_READ, HA_REQUIRES_KEY_COLUMNS_FOR_DELETE,HA_PRIMARY_KEY_REQUIRED_FOR_DELETE and HA_HAS_RECORDS
Removed HA_NOT_EXACT_COUNT, HA_READ_RND_SAME
HA_DUPP_POS -> HA_DUPLICATE_POS
HA_NOT_EXACT_COUNT replaced by HA_STATS_RECORDS_IS_EXACT, HA_HAS_RECORDS and records()
HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS renamed to HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
Added future row type 'ROW_TYPE_PAGES'
Added MEM_ROOT to handlerton 'create' function
Added ha_statistics, a structure for all status variable in the base handler class.
Moved all status variables in the handler class into a stats structs to improve readability.
ha_table_flags() is now a cached (not virtual) version of table_flags()
reset() doesn't anymore call extra(HA_EXTRA_RESET) but is a function of it's own.
Renamed dupp_ref to dup_ref
Renamed not used handler::sortkey
Moved read_set and write_set to TABLE structure
handler::init() function added for cacheing of virtual constants from engine.
sql/item.cc:
Added register_field_in_read_map() for marking used columns in expression.
This is used by filesort() for creating an optimal column bitmap while retrieving columns for sorting.
Initalize value.cs_info.character_set_client to fix core dump bug with --debug
set_query_id -> mark_used_columns
Mark used columns in read_set OR write_set.
sql/item.h:
Removed reset_query_id_processor() as it's not needed anymore.
Added register_field_in_read_map()
Added extra argument to Item::walk() to indicate if we should also
traverse sub queries.
sql/item_cmpfunc.cc:
Temporary mark used columns to be read/writable
Update Item::walk to new interface
sql/item_cmpfunc.h:
Added extra argument to Item::walk() to indicate if we should also traverse sub queries.
sql/item_func.cc:
Update Item::walk() to new interface
table_flags() -> ha_table_flags()
sql/item_func.h:
Update Item::walk() to new interface
sql/item_row.cc:
Update Item::walk() to new interface
sql/item_row.h:
Update Item::walk() to new interface
sql/item_strfunc.h:
Update Item::walk() to new interface
sql/item_subselect.cc:
Added Item_subselect::walk()
(It was a bug it was missing before. Not sure what kind of bugs this could have caused)
sql/item_subselect.h:
Update Item::walk() to new interface
sql/item_sum.cc:
Update Item::walk() to new interface
Updates for new handler interace
sql/item_sum.h:
Update Item::walk() to new interface
sql/key.cc:
Updates for new handler interace
sql/log.cc:
Mark all columns used for log tables
Split options flag
Ensured that second argument to trans_register_ha is a bool
sql/log_event.cc:
Fixed comments to be withing 79 characters
Use OPTION_KEEP_LOG instead of OPTION_STATUS_NO_TRANS_UPDATE to remove wrong warnings
Updates for new handler interface
Use 0x%lx instead of %p (portability problem)
sql/mysql_priv.h:
Added OPTION_KEEP_LOG to indicate that we should replicate the binlog even on rollback
Removed not used 'conds' argument to setup_tables
sql/mysqld.cc:
Indentation fixes and removed old comment
sql/opt_range.cc:
Update to new handler and bitmap interface.
Fixed calls to cp_buffer_from_ref() and walk() (new argument).
Create new temporary bitmaps for ror scans.
(Needed because of handler changes and to get more accurate column bitmaps than before)
Remove not needed file->ha_reset() call before file->close().
Some trivial optimization and indentation fixes.
Use Field->part_of_key_not_clustered() to check if field is part of a key, instead of looping over all key parts.
Added flag 'in_ror_merged_scan' to allow ::get_next() to know that we need a special column bitmap to only fetch pointer to record.
This is needed because ror scan uses the same TABLE object but different file objects, which creates problem for the column bitmap handling.
(This is a temporary solution. A better one would be to allocate an own TABLE object for ROR scans)
Optimized bitmap handling in ror scans:
- Start bitmap at position 0, not 1
- Use same bitmap size as in TABLE
- Use table->read_set and table->write_set to create column bitmaps instead of looping over all fields in table
sql/opt_range.h:
Added 'in_ror_merged_scan' to indicate if we are doing a ROR scan
Added temporary column bitmaps used in ROR scans
sql/opt_sum.cc:
Added get_ext_record_count() which is used in COUNT() optimization if handler has HA_HAS_RECORDS
Note that we don't call this if handler has HA_STATS_RECORDS_IS_EXACT set.
sql/protocol.cc:
We need to mark columns as readable in ::store() as we sometimes return default value for fields to the user
sql/records.cc:
Updates for new handler interface
sql/set_var.cc:
Handle splitting OPTION_STATUS_NO_TRANS_UPDATE to two flags
sql/share/errmsg.txt:
Fixed wrong
sql/sp.cc:
Mark that we are using all columns for the proc table
Update call to setup_tables() to use new prototype
sql/sp_head.cc:
Removed QQ comment
sql/spatial.cc:
Removed wrong QQ comment
sql/sql_acl.cc:
Mark that we need all columns for acl tables
Supply memroot to some 'new' calls.
Indentation fixes
sql/sql_base.cc:
set_query_id removed
Ensure we call ha_reset() at end of each statement
Mark read columns in read_set and changed columns in write_set (Before all columns was marked in read set)
Fixed marking of some columns that was not proplerly marked before
Maintain in TABLE->merge_keys set of all keys that are used in some way
Removed not used 'conds' argument from setup_tables()
Remove not used setting of 'dupp_field' in insert_fields()
Added missing FN_LIBCHAR in mysql_rm_tmp_tables()
(This has probably caused us to not properly remove temporary files after crash)
sql/sql_bitmap.h:
Added is_overlapping()
sql/sql_class.cc:
Slow_logs was not properly initialized, which could maybe cause extra/lost entries in slow log.
set_query_id -> mark_used_columns
Simpler variable usage in pack_row() (cleanup)
Moved some variable declartion at start of function for better code readability
sql/sql_class.h:
Added enum_mark_columns
Updated comments
Renamed dupp_field -> dup_field
Added virtual function 'can_rollback_data()' to select_insert() to be used in CREATE ... SELECT to optimize use of OPTION_STATUS_NO_TRANS_UPDATE.
(This fixes a bug in CREATE ... SELECT where we did give wrong warnings when using non transacational tables)
sql/sql_delete.cc:
Updates to new handler interface
Call table->mark_columns_needed_for_delete() to allow us to put additional columns in column usage maps if handler so requires.
Call table->prepare_for_position() to tell handler that we are going to call ha_position().
Removed call to free_io_cache(). (io_cache is now removed in ha_reset()).
Fixed calls to setup_tables()
sql/sql_do.cc:
Update call to setup_fields()
sql/sql_handler.cc:
Tell handler tables to always read all columns.
Use temporary column map when storing value in field for later index usage
sql/sql_help.cc:
Makr all used fields to be read
Update call to setup_fields()
sql/sql_insert.cc:
Tell handler we are going to update the auto_increment column
dupp_field -> dup_field
Set column usage bits for timestamp field.
Call table->mark_columns_needed_for_insert() and table->mark_auto_increment_column()
Removed not used argument from mysql_prepare_insert_check_table().
If we get an duplicate row on insert, change column map to read and write all columns while retrying the operatation.
This is required by the definition of REPLACE and also ensures that fields that are only part of UPDATE are properly handled.
This fixed a bug in NDB and REPLACE where REPLACE wrongly copied some column values from the replaced row.
Setup new bitmaps for delayed insert rows
Remove reseting of next_number_fields as it will be reset on next call to handler_insert()
Fixed usage of thd->options and OPTION_STATUS_NO_TRANS_UPDATE.
The issue was that one should not to reset this flag as it may be set by a previous statement.
The way it was now used caused us to loose some warnings and get other wrong warnings when using non transactional tables mixed with transactional.
I fixed it by introducing 'select_insert::can_rollback_data' to inform send_error() that the given statement can be rolled back (which in case of CREATE TABLE can always be done)
Don't close tables created with CREATE ... SELECT but keep them in the table cache.
Moved out MY_HOOKS from inside function (better readability)
sql/sql_load.cc:
Update to use new handler and column marking interface
Update using setup_tables()
sql/sql_olap.cc:
Update calls to setup_tables
Use enums instead of constants to setup_fields()
sql/sql_parse.cc:
Handle OPTION_KEEP_LOG:
- Set it on CREATE TEMPORARY TABLE / DROP TABLE
- Reset it when OPTION_STATUS_NO_TRANS_UPDATE is reset
- Don't set it for CREATE ... SELECT (this is handled in select_create class)
Remove reseting of OPTION_STATUS_NO_TRANS_UPDATE in begin_trans() as this should already be reset.
If in autocommit mode, reset OPTION_KEEP_LOG and OPTION_STATUS_NO_TRANS_UPDATE to not give warnings in future commands
sql/sql_partition.cc:
Update walk() usage
Trivial indentation fixes
sql/sql_plugin.cc:
Mark all columns as used for plugins
sql/sql_prepare.cc:
Added assert to find out hidden bugs in character_set_client (got an error in debug binary when this not set correctly)
Updates for new handler interface
Update calls to setup_fields()
sql/sql_repl.cc:
Indentation fixes
sql/sql_select.cc:
Update call to setup_tables() and setup_fields()
Remove some old disabled code
Update to new hadler interface
Indentation cleanups
Added column bitmaps for temporary tables.
Remove updating of the removed slots in the Field class
Added TABLE argument to cp_buffer_from_ref() (To be able to install temporary column maps)
For internal temporary tables, use handler::write_row(), handler::delete_row() and handler::update_row() instead of handler::ha_xxxx() for faster execution.
sql/sql_select.h:
Indentaition fixes.
Install temporary column usage maps when needed
Added TABLE element to cp_buffer_from_ref()
sql/sql_show.cc:
Update to new handler interface
Mark all columns used for internal tables.
Style fixes.
Added support for 'future' ROW_TYPE_PAGES.
Don't allocate TMP_TABLE_PARAM with calloc. The 'init()' function will initialize the structure properly.
sql/sql_table.cc:
Update to new handler interface
Simple my_snprintf -> strmake()
Changed some constants to defines
Don't test for NULL in primary key (as we a couple of line above force the PRIMARY KEY to be NOT NULL)
Change field->add_index to use field->flags & FIELD_IN_ADD_INDEX
Mark all columns as used for ALTER TABLE
Style fixes
Update call to filesort()
sql/sql_trigger.h:
Added friend functions to be able to test if triggers exists for table we are going to insert/update or delete in.
sql/sql_udf.cc:
Mark all columns as used for udf system table.
sql/sql_union.cc:
Update call to walk()
Update to new handler interface
sql/sql_update.cc:
Remove query_id argument from compare_record()
Use column bitmaps instead of query_id.
We can't use compare_records() to skip updates for handlers that returns a partial column set and the read_set doesn't cover all columns in the write set, because compare_record() can't in this case know if a not read column changed value.
Update call to setup_fields()
Using separate column read and write sets allows for easier checking of timestamp field was set by statement.
Removed call to free_io_cache() as this is now done in ha_reset()
Call table->mark_columns_needed_for_update() and table->prepare_for_position()
Style fixes
sql/sql_view.cc:
Style fixes
sql/table.cc:
Remove implicitely include 'errno.h'
Remove code for building normalized path, as this is now identical to 'path'
Remove field->fieldnr
Added update of field->part_of_key_not_clustered()
Create column bitmaps in TABLE and TABLE_SHARE
Don't setup a temporary MEM_ROOT object as a thread specific variable for the handler. Instead we send the to-be-used MEMROOT to get_new_handler()
Update to new handler interface
Update call to walk()
Added new functions:
- st_table::clear_column_bitmaps()
- st_table::prepare_for_position()
- st_table::mark_columns_used_by_index()
- st_table::restore_column_maps_after_mark_index()
- st_table::mark_columns_used_by_index_no_reset()
- st_table::mark_auto_increment_column()
- st_table::mark_columns_needed_for_delete()
- st_table::mark_columns_needed_for_update()
- st_table::mark_columns_needed_for_insert()
sql/table.h:
Moved column usage bitmaps from handler to TABLE
Added to TABLE_SHARE all_set and column_bitmap_size
Added to TABLE merge_keys, bitmap_init_values, def_read_set, def_write_set, tmp_set, read_set and write_set.
Declared all new table column bitmap functions
Added TABLE functions column_bitmaps_set(), column_bitmaps_set_no_signal(), use_all_columns() and default_column_bitmaps()
Added functions: tmp_use_all_columns() and tmp_restore_column_map() to temporarly switch column bitmaps
Added functions: dbug_tmp_use_all_columns() and dbug_tmp_restore_column_map() to temporarly switch column bitmaps to avoid asserts in Field::store() and Field::val().
sql/tztime.cc:
Mark all columns as used for timezone tables
storage/archive/ha_archive.cc:
Update to new handler interface
storage/archive/ha_archive.h:
Update to new handler interface
storage/blackhole/ha_blackhole.cc:
Update to new handler interface
storage/blackhole/ha_blackhole.h:
Update to new handler interface
removed not needed flag HA_DUPP_POS
storage/csv/ha_tina.cc:
Update to new handler interface
storage/csv/ha_tina.h:
Update to new handler interface
storage/example/ha_example.cc:
Update to new handler interface
storage/example/ha_example.h:
Update to new handler interface
storage/heap/hp_extra.c:
Added heap_reset() (Required by new handler interface)
storage/heap/hp_test2.c:
Use heap_reset()
storage/myisam/ft_boolean_search.c:
Fixed compiler warning
storage/myisam/mi_extra.c:
Added mi_reset() (Required by new handler interface)
storage/myisam/mi_search.c:
Fixed DBUG_PRINT messages to use 0x%lx instead of %lx
storage/myisam/mi_test2.c:
Use mi_reset()
storage/myisam/myisampack.c:
Use mi_reset()
storage/myisammrg/myrg_extra.c:
Added myrg_reset() (Required by new handler interface)
unittest/mysys/base64.t.c:
Include my_global.h
Don't include implictely include file 'stdlib.h'
2006-06-04 17:52:22 +02:00
|
|
|
substitution->walk(&Item::remove_dependence_processor, 0,
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
BitKeeper/etc/ignore:
added libmysqld/ha_ndbcluster_cond.cc
---
added debian/defs.mk debian/control
client/completion_hash.cc:
Remove not needed casts
client/my_readline.h:
Remove some old types
client/mysql.cc:
Simplify types
client/mysql_upgrade.c:
Remove some old types
Update call to dirname_part
client/mysqladmin.cc:
Remove some old types
client/mysqlbinlog.cc:
Remove some old types
Change some buffers to be uchar to avoid casts
client/mysqlcheck.c:
Remove some old types
client/mysqldump.c:
Remove some old types
Remove some not needed casts
Change some string lengths to size_t
client/mysqlimport.c:
Remove some old types
client/mysqlshow.c:
Remove some old types
client/mysqlslap.c:
Remove some old types
Remove some not needed casts
client/mysqltest.c:
Removed some old types
Removed some not needed casts
Updated hash-get-key function arguments
Updated parameters to dirname_part()
client/readline.cc:
Removed some old types
Removed some not needed casts
Changed some string lengths to use size_t
client/sql_string.cc:
Removed some old types
dbug/dbug.c:
Removed some old types
Changed some string lengths to use size_t
Changed some prototypes to avoid casts
extra/comp_err.c:
Removed some old types
extra/innochecksum.c:
Removed some old types
extra/my_print_defaults.c:
Removed some old types
extra/mysql_waitpid.c:
Removed some old types
extra/perror.c:
Removed some old types
extra/replace.c:
Removed some old types
Updated parameters to dirname_part()
extra/resolve_stack_dump.c:
Removed some old types
extra/resolveip.c:
Removed some old types
include/config-win.h:
Removed some old types
include/decimal.h:
Changed binary strings to be uchar* instead of char*
include/ft_global.h:
Removed some old types
include/hash.h:
Removed some old types
include/heap.h:
Removed some old types
Changed records_under_level to be 'ulong' instead of 'uint' to clarify usage of variable
include/keycache.h:
Removed some old types
include/m_ctype.h:
Removed some old types
Changed some string lengths to use size_t
Changed character length functions to return uint
unsigned char -> uchar
include/m_string.h:
Removed some old types
Changed some string lengths to use size_t
include/my_alloc.h:
Changed some string lengths to use size_t
include/my_base.h:
Removed some old types
include/my_dbug.h:
Removed some old types
Changed some string lengths to use size_t
Changed db_dump() to take uchar * as argument for memory to reduce number of casts in usage
include/my_getopt.h:
Removed some old types
include/my_global.h:
Removed old types:
my_size_t -> size_t
byte -> uchar
gptr -> uchar *
include/my_list.h:
Removed some old types
include/my_nosys.h:
Removed some old types
include/my_pthread.h:
Removed some old types
include/my_sys.h:
Removed some old types
Changed MY_FILE_ERROR to be in line with new definitions of my_write()/my_read()
Changed some string lengths to use size_t
my_malloc() / my_free() now uses void *
Updated parameters to dirname_part() & my_uncompress()
include/my_tree.h:
Removed some old types
include/my_trie.h:
Removed some old types
include/my_user.h:
Changed some string lengths to use size_t
include/my_vle.h:
Removed some old types
include/my_xml.h:
Removed some old types
Changed some string lengths to use size_t
include/myisam.h:
Removed some old types
include/myisammrg.h:
Removed some old types
include/mysql.h:
Removed some old types
Changed byte streams to use uchar* instead of char*
include/mysql_com.h:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
include/queues.h:
Removed some old types
include/sql_common.h:
Removed some old types
include/sslopt-longopts.h:
Removed some old types
include/violite.h:
Removed some old types
Changed some string lengths to use size_t
libmysql/client_settings.h:
Removed some old types
libmysql/libmysql.c:
Removed some old types
libmysql/manager.c:
Removed some old types
libmysqld/emb_qcache.cc:
Removed some old types
libmysqld/emb_qcache.h:
Removed some old types
libmysqld/lib_sql.cc:
Removed some old types
Removed some not needed casts
Changed some buffers to be uchar* to avoid casts
true -> TRUE, false -> FALSE
mysys/array.c:
Removed some old types
mysys/charset.c:
Changed some string lengths to use size_t
mysys/checksum.c:
Include zlib to get definition for crc32
Removed some old types
mysys/default.c:
Removed some old types
Changed some string lengths to use size_t
mysys/default_modify.c:
Changed some string lengths to use size_t
Removed some not needed casts
mysys/hash.c:
Removed some old types
Changed some string lengths to use size_t
Note: Prototype of hash_key() has changed which may cause problems if client uses hash_init() with a cast for the hash-get-key function.
hash_element now takes 'ulong' as the index type (cleanup)
mysys/list.c:
Removed some old types
mysys/mf_cache.c:
Changed some string lengths to use size_t
mysys/mf_dirname.c:
Removed some old types
Changed some string lengths to use size_t
Added argument to dirname_part() to avoid calculation of length for 'to'
mysys/mf_fn_ext.c:
Removed some old types
Updated parameters to dirname_part()
mysys/mf_format.c:
Removed some old types
Changed some string lengths to use size_t
mysys/mf_getdate.c:
Removed some old types
mysys/mf_iocache.c:
Removed some old types
Changed some string lengths to use size_t
Changed calculation of 'max_length' to be done the same way in all functions
mysys/mf_iocache2.c:
Removed some old types
Changed some string lengths to use size_t
Clean up comments
Removed not needed indentation
mysys/mf_keycache.c:
Removed some old types
mysys/mf_keycaches.c:
Removed some old types
mysys/mf_loadpath.c:
Removed some old types
mysys/mf_pack.c:
Removed some old types
Changed some string lengths to use size_t
Removed some not needed casts
Removed very old VMS code
Updated parameters to dirname_part()
Use result of dirnam_part() to remove call to strcat()
mysys/mf_path.c:
Removed some old types
mysys/mf_radix.c:
Removed some old types
mysys/mf_same.c:
Removed some old types
mysys/mf_sort.c:
Removed some old types
mysys/mf_soundex.c:
Removed some old types
mysys/mf_strip.c:
Removed some old types
mysys/mf_tempdir.c:
Removed some old types
mysys/mf_unixpath.c:
Removed some old types
mysys/mf_wfile.c:
Removed some old types
mysys/mulalloc.c:
Removed some old types
mysys/my_alloc.c:
Removed some old types
Changed some string lengths to use size_t
Use void* as type for allocated memory area
Removed some not needed casts
Changed argument 'Size' to 'length' according coding guidelines
mysys/my_chsize.c:
Changed some buffers to be uchar* to avoid casts
mysys/my_compress.c:
More comments
Removed some old types
Changed string lengths to use size_t
Changed arguments to my_uncompress() to make them easier to understand
Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix)
Changed type of 'pack_data' argument to packfrm() to avoid casts.
mysys/my_conio.c:
Changed some string lengths to use size_t
mysys/my_create.c:
Removed some old types
mysys/my_div.c:
Removed some old types
mysys/my_error.c:
Removed some old types
mysys/my_fopen.c:
Removed some old types
mysys/my_fstream.c:
Removed some old types
Changed some string lengths to use size_t
writen -> written
mysys/my_getopt.c:
Removed some old types
mysys/my_getwd.c:
Removed some old types
More comments
mysys/my_init.c:
Removed some old types
mysys/my_largepage.c:
Removed some old types
Changed some string lengths to use size_t
mysys/my_lib.c:
Removed some old types
mysys/my_lockmem.c:
Removed some old types
mysys/my_malloc.c:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed all functions to use size_t
mysys/my_memmem.c:
Indentation cleanup
mysys/my_once.c:
Removed some old types
Changed malloc(), free() and related functions to use void *
mysys/my_open.c:
Removed some old types
mysys/my_pread.c:
Removed some old types
Changed all functions to use size_t
Added comment for how my_pread() / my_pwrite() are supposed to work.
Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe.
(If we ever would really need this, it should be enabled only with a flag argument)
mysys/my_quick.c:
Removed some old types
Changed all functions to use size_t
mysys/my_read.c:
Removed some old types
Changed all functions to use size_t
mysys/my_realloc.c:
Removed some old types
Use void* as type for allocated memory area
Changed all functions to use size_t
mysys/my_static.c:
Removed some old types
mysys/my_static.h:
Removed some old types
mysys/my_vle.c:
Removed some old types
mysys/my_wincond.c:
Removed some old types
mysys/my_windac.c:
Removed some old types
mysys/my_write.c:
Removed some old types
Changed all functions to use size_t
mysys/ptr_cmp.c:
Removed some old types
Changed all functions to use size_t
mysys/queues.c:
Removed some old types
mysys/safemalloc.c:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed all functions to use size_t
mysys/string.c:
Removed some old types
Changed all functions to use size_t
mysys/testhash.c:
Removed some old types
mysys/thr_alarm.c:
Removed some old types
mysys/thr_lock.c:
Removed some old types
mysys/tree.c:
Removed some old types
mysys/trie.c:
Removed some old types
mysys/typelib.c:
Removed some old types
plugin/daemon_example/daemon_example.cc:
Removed some old types
regex/reginit.c:
Removed some old types
server-tools/instance-manager/buffer.cc:
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/buffer.h:
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/commands.cc:
Removed some old types
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/instance_map.cc:
Removed some old types
Changed some string lengths to use size_t
Changed buffer to be of type uchar*
server-tools/instance-manager/instance_options.cc:
Changed buffer to be of type uchar*
Replaced alloc_root + strcpy() with strdup_root()
server-tools/instance-manager/mysql_connection.cc:
Changed buffer to be of type uchar*
server-tools/instance-manager/options.cc:
Removed some old types
server-tools/instance-manager/parse.cc:
Changed some string lengths to use size_t
server-tools/instance-manager/parse.h:
Removed some old types
Changed some string lengths to use size_t
server-tools/instance-manager/protocol.cc:
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
server-tools/instance-manager/protocol.h:
Changed some string lengths to use size_t
server-tools/instance-manager/user_map.cc:
Removed some old types
Changed some string lengths to use size_t
sql/derror.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
sql/discover.cc:
Changed in readfrm() and writefrom() the type for argument 'frmdata' to uchar** to avoid casts
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
sql/event_data_objects.cc:
Removed some old types
Added missing casts for alloc() and sprintf()
sql/event_db_repository.cc:
Changed some buffers to be uchar* to avoid casts
Added missing casts for sprintf()
sql/event_queue.cc:
Removed some old types
sql/field.cc:
Removed some old types
Changed memory buffers to be uchar*
Changed some string lengths to use size_t
Removed a lot of casts
Safety fix in Field_blob::val_decimal() to not access zero pointer
sql/field.h:
Removed some old types
Changed memory buffers to be uchar* (except of store() as this would have caused too many other changes).
Changed some string lengths to use size_t
Removed some not needed casts
Changed val_xxx(xxx, new_ptr) to take const pointers
sql/field_conv.cc:
Removed some old types
Added casts required because memory area pointers are now uchar*
sql/filesort.cc:
Initalize variable that was used unitialized in error conditions
sql/gen_lex_hash.cc:
Removed some old types
Changed memory buffers to be uchar*
Changed some string lengths to use size_t
Removed a lot of casts
Safety fix in Field_blob::val_decimal() to not access zero pointer
sql/gstream.h:
Added required cast
sql/ha_ndbcluster.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some buffers to be uchar* to avoid casts
Added required casts
Removed some not needed casts
sql/ha_ndbcluster.h:
Removed some old types
sql/ha_ndbcluster_binlog.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Replaced sql_alloc() + memcpy() + set end 0 with sql_strmake()
Changed some string lengths to use size_t
Added missing casts for alloc() and sprintf()
sql/ha_ndbcluster_binlog.h:
Removed some old types
sql/ha_ndbcluster_cond.cc:
Removed some old types
Removed some not needed casts
sql/ha_ndbcluster_cond.h:
Removed some old types
sql/ha_partition.cc:
Removed some old types
Changed prototype for change_partition() to avoid casts
sql/ha_partition.h:
Removed some old types
sql/handler.cc:
Removed some old types
Changed some string lengths to use size_t
sql/handler.h:
Removed some old types
Changed some string lengths to use size_t
Changed type for 'frmblob' parameter for discover() and ha_discover() to get fewer casts
sql/hash_filo.h:
Removed some old types
Changed all functions to use size_t
sql/hostname.cc:
Removed some old types
sql/item.cc:
Removed some old types
Changed some string lengths to use size_t
Use strmake() instead of memdup() to create a null terminated string.
Updated calls to new Field()
sql/item.h:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed some buffers to be uchar* to avoid casts
sql/item_cmpfunc.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/item_cmpfunc.h:
Removed some old types
sql/item_create.cc:
Removed some old types
sql/item_func.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
Added test for failing alloc() in init_result_field()
Remove old confusing comment
Fixed compiler warning
sql/item_func.h:
Removed some old types
sql/item_row.cc:
Removed some old types
sql/item_row.h:
Removed some old types
sql/item_strfunc.cc:
Include zlib (needed becasue we call crc32)
Removed some old types
sql/item_strfunc.h:
Removed some old types
Changed some types to match new function prototypes
sql/item_subselect.cc:
Removed some old types
sql/item_subselect.h:
Removed some old types
sql/item_sum.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/item_sum.h:
Removed some old types
sql/item_timefunc.cc:
Removed some old types
Changed some string lengths to use size_t
sql/item_timefunc.h:
Removed some old types
sql/item_xmlfunc.cc:
Changed some string lengths to use size_t
sql/item_xmlfunc.h:
Removed some old types
sql/key.cc:
Removed some old types
Removed some not needed casts
sql/lock.cc:
Removed some old types
Added some cast to my_multi_malloc() arguments for safety
sql/log.cc:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
Changed usage of pwrite() to not assume it holds the cursor position for the file
Made usage of my_read() safer
sql/log_event.cc:
Removed some old types
Added checking of return value of malloc() in pack_info()
Changed some buffers to be uchar* to avoid casts
Removed some 'const' to avoid casts
Added missing casts for alloc() and sprintf()
Added required casts
Removed some not needed casts
Added some cast to my_multi_malloc() arguments for safety
sql/log_event.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/log_event_old.cc:
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/log_event_old.h:
Changed some buffers to be uchar* to avoid casts
sql/mf_iocache.cc:
Removed some old types
sql/my_decimal.cc:
Changed memory area to use uchar*
sql/my_decimal.h:
Changed memory area to use uchar*
sql/mysql_priv.h:
Removed some old types
Changed malloc(), free() and related functions to use void *
Changed some string lengths to use size_t
Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid long overflow
Changed some buffers to be uchar* to avoid casts
sql/mysqld.cc:
Removed some old types
sql/net_serv.cc:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
Ensure that vio_read()/vio_write() return values are stored in a size_t variable
Removed some not needed casts
sql/opt_range.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/opt_range.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/opt_sum.cc:
Removed some old types
Removed some not needed casts
sql/parse_file.cc:
Removed some old types
Changed some string lengths to use size_t
Changed alloc_root + memcpy + set end 0 -> strmake_root()
sql/parse_file.h:
Removed some old types
sql/partition_info.cc:
Removed some old types
Added missing casts for alloc()
Changed some buffers to be uchar* to avoid casts
sql/partition_info.h:
Changed some buffers to be uchar* to avoid casts
sql/protocol.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/protocol.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
sql/records.cc:
Removed some old types
sql/repl_failsafe.cc:
Removed some old types
Changed some string lengths to use size_t
Added required casts
sql/rpl_filter.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some string lengths to use size_t
sql/rpl_filter.h:
Changed some string lengths to use size_t
sql/rpl_injector.h:
Removed some old types
sql/rpl_record.cc:
Removed some old types
Removed some not needed casts
Changed some buffers to be uchar* to avoid casts
sql/rpl_record.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/rpl_record_old.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/rpl_record_old.h:
Removed some old types
Changed some buffers to be uchar* to avoid cast
sql/rpl_rli.cc:
Removed some old types
sql/rpl_tblmap.cc:
Removed some old types
sql/rpl_tblmap.h:
Removed some old types
sql/rpl_utility.cc:
Removed some old types
sql/rpl_utility.h:
Removed some old types
Changed type of m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length
sql/set_var.cc:
Removed some old types
Updated parameters to dirname_part()
sql/set_var.h:
Removed some old types
sql/slave.cc:
Removed some old types
Changed some string lengths to use size_t
sql/slave.h:
Removed some old types
sql/sp.cc:
Removed some old types
Added missing casts for printf()
sql/sp.h:
Removed some old types
Updated hash-get-key function arguments
sql/sp_cache.cc:
Removed some old types
Added missing casts for printf()
Updated hash-get-key function arguments
sql/sp_head.cc:
Removed some old types
Added missing casts for alloc() and printf()
Added required casts
Updated hash-get-key function arguments
sql/sp_head.h:
Removed some old types
sql/sp_pcontext.cc:
Removed some old types
sql/sp_pcontext.h:
Removed some old types
sql/sql_acl.cc:
Removed some old types
Changed some string lengths to use size_t
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
Added required casts
sql/sql_analyse.cc:
Changed some buffers to be uchar* to avoid casts
sql/sql_analyse.h:
Changed some buffers to be uchar* to avoid casts
sql/sql_array.h:
Removed some old types
sql/sql_base.cc:
Removed some old types
Updated hash-get-key function arguments
sql/sql_binlog.cc:
Removed some old types
Added missing casts for printf()
sql/sql_cache.cc:
Removed some old types
Updated hash-get-key function arguments
Removed some not needed casts
Changed some string lengths to use size_t
sql/sql_cache.h:
Removed some old types
Removed reference to not existing function cache_key()
Updated hash-get-key function arguments
sql/sql_class.cc:
Removed some old types
Updated hash-get-key function arguments
Added missing casts for alloc()
Updated hash-get-key function arguments
Moved THD::max_row_length() to table.cc (as it's not depending on THD)
Removed some not needed casts
sql/sql_class.h:
Removed some old types
Changed malloc(), free() and related functions to use void *
Removed some not needed casts
Changed some string lengths to use size_t
Moved max_row_length and max_row_length_blob() to table.cc, as they are not depending on THD
sql/sql_connect.cc:
Removed some old types
Added required casts
sql/sql_db.cc:
Removed some old types
Removed some not needed casts
Added some cast to my_multi_malloc() arguments for safety
Added missing casts for alloc()
sql/sql_delete.cc:
Removed some old types
sql/sql_handler.cc:
Removed some old types
Updated hash-get-key function arguments
Added some cast to my_multi_malloc() arguments for safety
sql/sql_help.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/sql_insert.cc:
Removed some old types
Added missing casts for alloc() and printf()
sql/sql_lex.cc:
Removed some old types
sql/sql_lex.h:
Removed some old types
Removed some not needed casts
sql/sql_list.h:
Removed some old types
Removed some not needed casts
sql/sql_load.cc:
Removed some old types
Removed compiler warning
sql/sql_manager.cc:
Removed some old types
sql/sql_map.cc:
Removed some old types
sql/sql_map.h:
Removed some old types
sql/sql_olap.cc:
Removed some old types
sql/sql_parse.cc:
Removed some old types
Trivial move of code lines to make things more readable
Changed some string lengths to use size_t
Added missing casts for alloc()
sql/sql_partition.cc:
Removed some old types
Removed compiler warnings about not used functions
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/sql_partition.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/sql_plugin.cc:
Removed some old types
Added missing casts for alloc()
Updated hash-get-key function arguments
sql/sql_prepare.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Added missing casts for alloc() and printf()
sql-common/client.c:
Removed some old types
Changed some memory areas to use uchar*
sql-common/my_user.c:
Changed some string lengths to use size_t
sql-common/pack.c:
Changed some buffers to be uchar* to avoid casts
sql/sql_repl.cc:
Added required casts
Changed some buffers to be uchar* to avoid casts
Changed some string lengths to use size_t
sql/sql_select.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some old types
sql/sql_select.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
sql/sql_servers.cc:
Removed some old types
Updated hash-get-key function arguments
sql/sql_show.cc:
Removed some old types
Added missing casts for alloc()
Removed some not needed casts
sql/sql_string.cc:
Removed some old types
Added required casts
sql/sql_table.cc:
Removed some old types
Removed compiler warning about not used variable
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
sql/sql_test.cc:
Removed some old types
sql/sql_trigger.cc:
Removed some old types
Added missing casts for alloc()
sql/sql_udf.cc:
Removed some old types
Updated hash-get-key function arguments
sql/sql_union.cc:
Removed some old types
sql/sql_update.cc:
Removed some old types
Removed some not needed casts
sql/sql_view.cc:
Removed some old types
sql/sql_yacc.yy:
Removed some old types
Changed some string lengths to use size_t
Added missing casts for alloc()
sql/stacktrace.c:
Removed some old types
sql/stacktrace.h:
Removed some old types
sql/structs.h:
Removed some old types
sql/table.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some buffers to be uchar* to avoid casts
Removed setting of LEX_STRING() arguments in declaration
Added required casts
More function comments
Moved max_row_length() here from sql_class.cc/sql_class.h
sql/table.h:
Removed some old types
Changed some string lengths to use size_t
sql/thr_malloc.cc:
Use void* as type for allocated memory area
Changed all functions to use size_t
sql/tzfile.h:
Changed some buffers to be uchar* to avoid casts
sql/tztime.cc:
Changed some buffers to be uchar* to avoid casts
Updated hash-get-key function arguments
Added missing casts for alloc()
Removed some not needed casts
sql/uniques.cc:
Removed some old types
Removed some not needed casts
sql/unireg.cc:
Removed some old types
Changed some buffers to be uchar* to avoid casts
Removed some not needed casts
Added missing casts for alloc()
storage/archive/archive_reader.c:
Removed some old types
storage/archive/azio.c:
Removed some old types
Removed some not needed casts
storage/archive/ha_archive.cc:
Removed some old types
Changed type for 'frmblob' in archive_discover() to match handler
Updated hash-get-key function arguments
Removed some not needed casts
storage/archive/ha_archive.h:
Removed some old types
storage/blackhole/ha_blackhole.cc:
Removed some old types
storage/blackhole/ha_blackhole.h:
Removed some old types
storage/csv/ha_tina.cc:
Removed some old types
Updated hash-get-key function arguments
Changed some buffers to be uchar* to avoid casts
storage/csv/ha_tina.h:
Removed some old types
Removed some not needed casts
storage/csv/transparent_file.cc:
Removed some old types
Changed type of 'bytes_read' to be able to detect read errors
Fixed indentation
storage/csv/transparent_file.h:
Removed some old types
storage/example/ha_example.cc:
Removed some old types
Updated hash-get-key function arguments
storage/example/ha_example.h:
Removed some old types
storage/federated/ha_federated.cc:
Removed some old types
Updated hash-get-key function arguments
Removed some not needed casts
storage/federated/ha_federated.h:
Removed some old types
storage/heap/_check.c:
Changed some buffers to be uchar* to avoid casts
storage/heap/_rectest.c:
Removed some old types
storage/heap/ha_heap.cc:
Removed some old types
storage/heap/ha_heap.h:
Removed some old types
storage/heap/heapdef.h:
Removed some old types
storage/heap/hp_block.c:
Removed some old types
Changed some string lengths to use size_t
storage/heap/hp_clear.c:
Removed some old types
storage/heap/hp_close.c:
Removed some old types
storage/heap/hp_create.c:
Removed some old types
storage/heap/hp_delete.c:
Removed some old types
storage/heap/hp_hash.c:
Removed some old types
storage/heap/hp_info.c:
Removed some old types
storage/heap/hp_open.c:
Removed some old types
storage/heap/hp_rfirst.c:
Removed some old types
storage/heap/hp_rkey.c:
Removed some old types
storage/heap/hp_rlast.c:
Removed some old types
storage/heap/hp_rnext.c:
Removed some old types
storage/heap/hp_rprev.c:
Removed some old types
storage/heap/hp_rrnd.c:
Removed some old types
storage/heap/hp_rsame.c:
Removed some old types
storage/heap/hp_scan.c:
Removed some old types
storage/heap/hp_test1.c:
Removed some old types
storage/heap/hp_test2.c:
Removed some old types
storage/heap/hp_update.c:
Removed some old types
storage/heap/hp_write.c:
Removed some old types
Changed some string lengths to use size_t
storage/innobase/handler/ha_innodb.cc:
Removed some old types
Updated hash-get-key function arguments
Added missing casts for alloc() and printf()
Removed some not needed casts
storage/innobase/handler/ha_innodb.h:
Removed some old types
storage/myisam/ft_boolean_search.c:
Removed some old types
storage/myisam/ft_nlq_search.c:
Removed some old types
storage/myisam/ft_parser.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/ft_static.c:
Removed some old types
storage/myisam/ft_stopwords.c:
Removed some old types
storage/myisam/ft_update.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/ftdefs.h:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/fulltext.h:
Removed some old types
storage/myisam/ha_myisam.cc:
Removed some old types
storage/myisam/ha_myisam.h:
Removed some old types
storage/myisam/mi_cache.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/mi_check.c:
Removed some old types
storage/myisam/mi_checksum.c:
Removed some old types
storage/myisam/mi_close.c:
Removed some old types
storage/myisam/mi_create.c:
Removed some old types
storage/myisam/mi_delete.c:
Removed some old types
storage/myisam/mi_delete_all.c:
Removed some old types
storage/myisam/mi_dynrec.c:
Removed some old types
storage/myisam/mi_extra.c:
Removed some old types
storage/myisam/mi_key.c:
Removed some old types
storage/myisam/mi_locking.c:
Removed some old types
storage/myisam/mi_log.c:
Removed some old types
storage/myisam/mi_open.c:
Removed some old types
Removed some not needed casts
Check argument of my_write()/my_pwrite() in functions returning int
Added casting of string lengths to size_t
storage/myisam/mi_packrec.c:
Removed some old types
Changed some buffers to be uchar* to avoid casts
storage/myisam/mi_page.c:
Removed some old types
storage/myisam/mi_preload.c:
Removed some old types
storage/myisam/mi_range.c:
Removed some old types
storage/myisam/mi_rfirst.c:
Removed some old types
storage/myisam/mi_rkey.c:
Removed some old types
storage/myisam/mi_rlast.c:
Removed some old types
storage/myisam/mi_rnext.c:
Removed some old types
storage/myisam/mi_rnext_same.c:
Removed some old types
storage/myisam/mi_rprev.c:
Removed some old types
storage/myisam/mi_rrnd.c:
Removed some old types
storage/myisam/mi_rsame.c:
Removed some old types
storage/myisam/mi_rsamepos.c:
Removed some old types
storage/myisam/mi_scan.c:
Removed some old types
storage/myisam/mi_search.c:
Removed some old types
storage/myisam/mi_static.c:
Removed some old types
storage/myisam/mi_statrec.c:
Removed some old types
storage/myisam/mi_test1.c:
Removed some old types
storage/myisam/mi_test2.c:
Removed some old types
storage/myisam/mi_test3.c:
Removed some old types
storage/myisam/mi_unique.c:
Removed some old types
storage/myisam/mi_update.c:
Removed some old types
storage/myisam/mi_write.c:
Removed some old types
storage/myisam/myisam_ftdump.c:
Removed some old types
storage/myisam/myisamchk.c:
Removed some old types
storage/myisam/myisamdef.h:
Removed some old types
storage/myisam/myisamlog.c:
Removed some old types
Indentation fix
storage/myisam/myisampack.c:
Removed some old types
storage/myisam/rt_index.c:
Removed some old types
storage/myisam/rt_split.c:
Removed some old types
storage/myisam/sort.c:
Removed some old types
storage/myisam/sp_defs.h:
Removed some old types
storage/myisam/sp_key.c:
Removed some old types
storage/myisammrg/ha_myisammrg.cc:
Removed some old types
storage/myisammrg/ha_myisammrg.h:
Removed some old types
storage/myisammrg/myrg_close.c:
Removed some old types
storage/myisammrg/myrg_def.h:
Removed some old types
storage/myisammrg/myrg_delete.c:
Removed some old types
storage/myisammrg/myrg_open.c:
Removed some old types
Updated parameters to dirname_part()
storage/myisammrg/myrg_queue.c:
Removed some old types
storage/myisammrg/myrg_rfirst.c:
Removed some old types
storage/myisammrg/myrg_rkey.c:
Removed some old types
storage/myisammrg/myrg_rlast.c:
Removed some old types
storage/myisammrg/myrg_rnext.c:
Removed some old types
storage/myisammrg/myrg_rnext_same.c:
Removed some old types
storage/myisammrg/myrg_rprev.c:
Removed some old types
storage/myisammrg/myrg_rrnd.c:
Removed some old types
storage/myisammrg/myrg_rsame.c:
Removed some old types
storage/myisammrg/myrg_update.c:
Removed some old types
storage/myisammrg/myrg_write.c:
Removed some old types
storage/ndb/include/util/ndb_opts.h:
Removed some old types
storage/ndb/src/cw/cpcd/main.cpp:
Removed some old types
storage/ndb/src/kernel/vm/Configuration.cpp:
Removed some old types
storage/ndb/src/mgmclient/main.cpp:
Removed some old types
storage/ndb/src/mgmsrv/InitConfigFileParser.cpp:
Removed some old types
Removed old disabled code
storage/ndb/src/mgmsrv/main.cpp:
Removed some old types
storage/ndb/src/ndbapi/NdbBlob.cpp:
Removed some old types
storage/ndb/src/ndbapi/NdbOperationDefine.cpp:
Removed not used variable
storage/ndb/src/ndbapi/NdbOperationInt.cpp:
Added required casts
storage/ndb/src/ndbapi/NdbScanOperation.cpp:
Added required casts
storage/ndb/tools/delete_all.cpp:
Removed some old types
storage/ndb/tools/desc.cpp:
Removed some old types
storage/ndb/tools/drop_index.cpp:
Removed some old types
storage/ndb/tools/drop_tab.cpp:
Removed some old types
storage/ndb/tools/listTables.cpp:
Removed some old types
storage/ndb/tools/ndb_config.cpp:
Removed some old types
storage/ndb/tools/restore/consumer_restore.cpp:
Changed some buffers to be uchar* to avoid casts with new defintion of packfrm()
storage/ndb/tools/restore/restore_main.cpp:
Removed some old types
storage/ndb/tools/select_all.cpp:
Removed some old types
storage/ndb/tools/select_count.cpp:
Removed some old types
storage/ndb/tools/waiter.cpp:
Removed some old types
strings/bchange.c:
Changed function to use uchar * and size_t
strings/bcmp.c:
Changed function to use uchar * and size_t
strings/bmove512.c:
Changed function to use uchar * and size_t
strings/bmove_upp.c:
Changed function to use uchar * and size_t
strings/ctype-big5.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-bin.c:
Changed functions to use size_t
strings/ctype-cp932.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-czech.c:
Fixed indentation
Changed functions to use size_t
strings/ctype-euc_kr.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-eucjpms.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-gb2312.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-gbk.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-latin1.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-mb.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-simple.c:
Changed functions to use size_t
Simpler loops for caseup/casedown
unsigned int -> uint
unsigned char -> uchar
strings/ctype-sjis.c:
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-tis620.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-uca.c:
Changed functions to use size_t
unsigned char -> uchar
strings/ctype-ucs2.c:
Moved inclusion of stdarg.h to other includes
usigned char -> uchar
Changed functions to use size_t
Changed character length functions to return uint
strings/ctype-ujis.c:
Changed functions to use size_t
Changed character length functions to return uint
unsigned char -> uchar
strings/ctype-utf8.c:
Changed functions to use size_t
unsigned char -> uchar
Indentation fixes
strings/ctype-win1250ch.c:
Indentation fixes
Changed functions to use size_t
strings/ctype.c:
Changed functions to use size_t
strings/decimal.c:
Changed type for memory argument to uchar *
strings/do_ctype.c:
Indentation fixes
strings/my_strtoll10.c:
unsigned char -> uchar
strings/my_vsnprintf.c:
Changed functions to use size_t
strings/r_strinstr.c:
Removed some old types
Changed functions to use size_t
strings/str_test.c:
Removed some old types
strings/strappend.c:
Changed functions to use size_t
strings/strcont.c:
Removed some old types
strings/strfill.c:
Removed some old types
strings/strinstr.c:
Changed functions to use size_t
strings/strlen.c:
Changed functions to use size_t
strings/strmake.c:
Changed functions to use size_t
strings/strnlen.c:
Changed functions to use size_t
strings/strnmov.c:
Changed functions to use size_t
strings/strto.c:
unsigned char -> uchar
strings/strtod.c:
Changed functions to use size_t
strings/strxnmov.c:
Changed functions to use size_t
strings/xml.c:
Changed functions to use size_t
Indentation fixes
tests/mysql_client_test.c:
Removed some old types
tests/thread_test.c:
Removed some old types
vio/test-ssl.c:
Removed some old types
vio/test-sslclient.c:
Removed some old types
vio/test-sslserver.c:
Removed some old types
vio/vio.c:
Removed some old types
vio/vio_priv.h:
Removed some old types
Changed vio_read()/vio_write() to work with size_t
vio/viosocket.c:
Changed vio_read()/vio_write() to work with size_t
Indentation fixes
vio/viossl.c:
Changed vio_read()/vio_write() to work with size_t
Indentation fixes
vio/viosslfactories.c:
Removed some old types
vio/viotest-ssl.c:
Removed some old types
win/README:
More explanations
2007-05-10 11:59:39 +02:00
|
|
|
(uchar *) select_lex->outer_select());
|
2010-01-28 14:48:33 +01:00
|
|
|
DBUG_RETURN(RES_REDUCE);
|
2002-12-26 00:28:59 +01:00
|
|
|
}
|
2010-01-28 14:48:33 +01:00
|
|
|
DBUG_RETURN(RES_OK);
|
2002-12-26 00:28:59 +01:00
|
|
|
}
|
|
|
|
|
2004-10-29 18:26:52 +02:00
|
|
|
|
2002-12-19 20:15:09 +01:00
|
|
|
void Item_singlerow_subselect::store(uint i, Item *item)
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
2002-12-19 06:38:33 +01:00
|
|
|
row[i]->store(item);
|
2010-01-28 14:48:33 +01:00
|
|
|
//psergey-merge: can do without that: row[i]->cache_value();
|
|
|
|
//psergey-backport-timours: ^ really, without that ^
|
2010-03-20 13:01:47 +01:00
|
|
|
//psergey-try-merge-again:
|
2009-11-06 20:34:25 +01:00
|
|
|
row[i]->cache_value();
|
2002-06-19 16:52:44 +02:00
|
|
|
}
|
|
|
|
|
2002-12-19 20:15:09 +01:00
|
|
|
enum Item_result Item_singlerow_subselect::result_type() const
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
2002-12-19 06:38:32 +01:00
|
|
|
return engine->type();
|
|
|
|
}
|
|
|
|
|
2006-11-07 17:16:17 +01:00
|
|
|
/*
|
|
|
|
Don't rely on the result type to calculate field type.
|
|
|
|
Ask the engine instead.
|
|
|
|
*/
|
|
|
|
enum_field_types Item_singlerow_subselect::field_type() const
|
|
|
|
{
|
|
|
|
return engine->field_type();
|
|
|
|
}
|
|
|
|
|
2002-12-19 20:15:09 +01:00
|
|
|
void Item_singlerow_subselect::fix_length_and_dec()
|
2002-09-28 17:34:56 +02:00
|
|
|
{
|
2002-12-19 06:38:33 +01:00
|
|
|
if ((max_columns= engine->cols()) == 1)
|
|
|
|
{
|
|
|
|
engine->fix_length_and_dec(row= &value);
|
|
|
|
}
|
|
|
|
else
|
2002-12-19 06:38:32 +01:00
|
|
|
{
|
2003-11-28 11:18:13 +01:00
|
|
|
if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns)))
|
2002-12-19 06:38:33 +01:00
|
|
|
return;
|
|
|
|
engine->fix_length_and_dec(row);
|
|
|
|
value= *row;
|
2002-12-19 06:38:32 +01:00
|
|
|
}
|
2006-05-25 09:39:18 +02:00
|
|
|
unsigned_flag= value->unsigned_flag;
|
2004-10-27 20:11:06 +02:00
|
|
|
/*
|
|
|
|
If there are not tables in subquery then ability to have NULL value
|
|
|
|
depends on SELECT list (if single row subquery have tables then it
|
|
|
|
always can be NULL if there are not records fetched).
|
|
|
|
*/
|
|
|
|
if (engine->no_tables())
|
|
|
|
maybe_null= engine->may_be_null();
|
2002-09-28 17:34:56 +02:00
|
|
|
}
|
|
|
|
|
2010-07-10 12:37:30 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Add an expression cache for this subquery if it is needed
|
|
|
|
|
|
|
|
@param thd_arg Thread handle
|
|
|
|
|
|
|
|
@details
|
|
|
|
The function checks whether an expression cache is needed for this item
|
|
|
|
and if if so wraps the item into an item of the class
|
|
|
|
Item_exp_cache_wrapper with an appropriate expression cache set up there.
|
|
|
|
|
|
|
|
@note
|
|
|
|
used from Item::transform()
|
|
|
|
|
|
|
|
@return
|
|
|
|
new wrapper item if an expression cache is needed,
|
|
|
|
this item - otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
Item* Item_singlerow_subselect::expr_cache_insert_transformer(uchar *thd_arg)
|
|
|
|
{
|
|
|
|
THD *thd= (THD*) thd_arg;
|
|
|
|
DBUG_ENTER("Item_singlerow_subselect::expr_cache_insert_transformer");
|
|
|
|
|
|
|
|
if (expr_cache_is_needed(thd))
|
|
|
|
DBUG_RETURN(set_expr_cache(thd, depends_on));
|
|
|
|
DBUG_RETURN(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-19 20:15:09 +01:00
|
|
|
uint Item_singlerow_subselect::cols()
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
2002-12-19 06:38:33 +01:00
|
|
|
return engine->cols();
|
|
|
|
}
|
|
|
|
|
2002-12-19 20:15:09 +01:00
|
|
|
bool Item_singlerow_subselect::check_cols(uint c)
|
2002-12-19 06:38:33 +01:00
|
|
|
{
|
|
|
|
if (c != engine->cols())
|
|
|
|
{
|
2003-10-06 21:35:05 +02:00
|
|
|
my_error(ER_OPERAND_COLUMNS, MYF(0), c);
|
2002-12-19 06:38:33 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-12-19 20:15:09 +01:00
|
|
|
bool Item_singlerow_subselect::null_inside()
|
2002-12-19 06:38:33 +01:00
|
|
|
{
|
|
|
|
for (uint i= 0; i < max_columns ; i++)
|
|
|
|
{
|
|
|
|
if (row[i]->null_value)
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-12-19 20:15:09 +01:00
|
|
|
void Item_singlerow_subselect::bring_value()
|
2002-12-19 06:38:33 +01:00
|
|
|
{
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
exec();
|
2002-06-19 16:52:44 +02:00
|
|
|
}
|
|
|
|
|
2004-11-11 19:39:35 +01:00
|
|
|
double Item_singlerow_subselect::val_real()
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (!exec() && !value->null_value)
|
2002-12-19 06:38:32 +01:00
|
|
|
{
|
|
|
|
null_value= 0;
|
2004-11-11 19:39:35 +01:00
|
|
|
return value->val_real();
|
2002-12-19 06:38:32 +01:00
|
|
|
}
|
|
|
|
else
|
2002-10-07 21:21:17 +02:00
|
|
|
{
|
2002-12-06 20:55:53 +01:00
|
|
|
reset();
|
2002-06-19 16:52:44 +02:00
|
|
|
return 0;
|
2002-10-07 21:21:17 +02:00
|
|
|
}
|
2002-06-19 16:52:44 +02:00
|
|
|
}
|
|
|
|
|
2004-07-04 07:46:28 +02:00
|
|
|
longlong Item_singlerow_subselect::val_int()
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (!exec() && !value->null_value)
|
2002-12-19 06:38:32 +01:00
|
|
|
{
|
|
|
|
null_value= 0;
|
|
|
|
return value->val_int();
|
|
|
|
}
|
|
|
|
else
|
2002-10-07 21:21:17 +02:00
|
|
|
{
|
2002-12-06 20:55:53 +01:00
|
|
|
reset();
|
2002-06-19 16:52:44 +02:00
|
|
|
return 0;
|
2002-10-07 21:21:17 +02:00
|
|
|
}
|
2002-06-19 16:52:44 +02:00
|
|
|
}
|
|
|
|
|
2005-02-08 23:50:45 +01:00
|
|
|
String *Item_singlerow_subselect::val_str(String *str)
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (!exec() && !value->null_value)
|
2002-12-19 06:38:32 +01:00
|
|
|
{
|
|
|
|
null_value= 0;
|
|
|
|
return value->val_str(str);
|
|
|
|
}
|
|
|
|
else
|
2002-10-07 21:21:17 +02:00
|
|
|
{
|
2002-12-06 20:55:53 +01:00
|
|
|
reset();
|
2002-06-19 16:52:44 +02:00
|
|
|
return 0;
|
2002-10-07 21:21:17 +02:00
|
|
|
}
|
2002-06-19 16:52:44 +02:00
|
|
|
}
|
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2005-02-08 23:50:45 +01:00
|
|
|
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
|
|
|
|
{
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (!exec() && !value->null_value)
|
2005-02-08 23:50:45 +01:00
|
|
|
{
|
|
|
|
null_value= 0;
|
|
|
|
return value->val_decimal(decimal_value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
reset();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Item_singlerow_subselect::val_bool()
|
|
|
|
{
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (!exec() && !value->null_value)
|
2005-02-08 23:50:45 +01:00
|
|
|
{
|
|
|
|
null_value= 0;
|
|
|
|
return value->val_bool();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
reset();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-02 21:19:41 +02:00
|
|
|
Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
|
2002-10-08 22:49:59 +02:00
|
|
|
Item_subselect()
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
2002-10-27 22:27:00 +01:00
|
|
|
DBUG_ENTER("Item_exists_subselect::Item_exists_subselect");
|
2005-02-08 23:50:45 +01:00
|
|
|
bool val_bool();
|
2003-10-02 21:19:41 +02:00
|
|
|
init(select_lex, new select_exists_subselect(this));
|
2002-06-19 16:52:44 +02:00
|
|
|
max_columns= UINT_MAX;
|
|
|
|
null_value= 0; //can't be NULL
|
|
|
|
maybe_null= 0; //can't be NULL
|
|
|
|
value= 0;
|
2002-10-27 22:27:00 +01:00
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_exists_subselect::print(String *str, enum_query_type query_type)
|
2003-10-16 14:54:47 +02:00
|
|
|
{
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN("exists"));
|
2008-02-22 11:30:33 +01:00
|
|
|
Item_subselect::print(str, query_type);
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-15 15:43:08 +02:00
|
|
|
bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
|
2003-05-14 20:51:33 +02:00
|
|
|
{
|
2006-12-14 23:51:37 +01:00
|
|
|
if (unit_arg->fake_select_lex &&
|
|
|
|
unit_arg->fake_select_lex->test_limit())
|
2003-05-14 20:51:33 +02:00
|
|
|
return(1);
|
2003-07-02 00:45:22 +02:00
|
|
|
|
2006-12-14 23:51:37 +01:00
|
|
|
SELECT_LEX *sl= unit_arg->first_select();
|
2003-05-14 20:51:33 +02:00
|
|
|
for (; sl; sl= sl->next_select())
|
|
|
|
{
|
2003-07-02 00:45:22 +02:00
|
|
|
if (sl->test_limit())
|
2003-05-14 20:51:33 +02:00
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2003-10-02 21:19:41 +02:00
|
|
|
Item_in_subselect::Item_in_subselect(Item * left_exp,
|
2002-10-27 22:27:00 +01:00
|
|
|
st_select_lex *select_lex):
|
2010-01-28 14:48:33 +01:00
|
|
|
Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
|
2010-02-19 22:55:57 +01:00
|
|
|
is_constant(FALSE), optimizer(0), pushed_cond_guards(NULL),
|
|
|
|
exec_method(NOT_TRANSFORMED), upper_item(0)
|
2002-10-27 22:27:00 +01:00
|
|
|
{
|
|
|
|
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
|
2002-11-07 22:45:19 +01:00
|
|
|
left_expr= left_exp;
|
2010-09-05 17:43:47 +02:00
|
|
|
func= &eq_creator;
|
2003-10-02 21:19:41 +02:00
|
|
|
init(select_lex, new select_exists_subselect(this));
|
2002-11-07 22:45:19 +01:00
|
|
|
max_columns= UINT_MAX;
|
2002-12-06 20:55:53 +01:00
|
|
|
maybe_null= 1;
|
2003-05-14 20:51:33 +02:00
|
|
|
abort_on_null= 0;
|
2002-12-06 20:55:53 +01:00
|
|
|
reset();
|
2003-07-02 00:45:22 +02:00
|
|
|
//if test_limit will fail then error will be reported to client
|
2003-05-14 20:51:33 +02:00
|
|
|
test_limit(select_lex->master_unit());
|
2002-11-07 22:45:19 +01:00
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
2010-03-29 16:04:35 +02:00
|
|
|
int Item_in_subselect::get_identifier()
|
|
|
|
{
|
|
|
|
return engine->get_identifier();
|
|
|
|
}
|
|
|
|
|
2003-10-02 21:19:41 +02:00
|
|
|
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
|
2006-07-21 01:04:04 +02:00
|
|
|
chooser_compare_func_creator fc,
|
2003-10-16 14:54:47 +02:00
|
|
|
st_select_lex *select_lex,
|
|
|
|
bool all_arg)
|
2006-07-22 14:18:28 +02:00
|
|
|
:Item_in_subselect(), func_creator(fc), all(all_arg)
|
2002-11-07 22:45:19 +01:00
|
|
|
{
|
2010-01-28 14:48:33 +01:00
|
|
|
DBUG_ENTER("Item_allany_subselect::Item_allany_subselect");
|
2002-11-07 22:45:19 +01:00
|
|
|
left_expr= left_exp;
|
2006-07-21 01:04:04 +02:00
|
|
|
func= func_creator(all_arg);
|
2003-10-02 21:19:41 +02:00
|
|
|
init(select_lex, new select_exists_subselect(this));
|
2002-12-19 20:15:09 +01:00
|
|
|
max_columns= 1;
|
2003-05-14 20:51:33 +02:00
|
|
|
abort_on_null= 0;
|
2002-12-06 20:55:53 +01:00
|
|
|
reset();
|
2003-07-02 00:45:22 +02:00
|
|
|
//if test_limit will fail then error will be reported to client
|
2003-05-14 20:51:33 +02:00
|
|
|
test_limit(select_lex->master_unit());
|
2002-10-27 22:27:00 +01:00
|
|
|
DBUG_VOID_RETURN;
|
2002-06-19 16:52:44 +02:00
|
|
|
}
|
|
|
|
|
2002-10-27 22:27:00 +01:00
|
|
|
|
2002-09-28 17:34:56 +02:00
|
|
|
void Item_exists_subselect::fix_length_and_dec()
|
|
|
|
{
|
2002-12-19 06:38:33 +01:00
|
|
|
decimals= 0;
|
2002-12-06 20:55:53 +01:00
|
|
|
max_length= 1;
|
2002-12-19 20:15:09 +01:00
|
|
|
max_columns= engine->cols();
|
Patch two (the final one) for Bug#7306 "the server side preparedStatement
error for LIMIT placeholder".
The patch adds grammar support for LIMIT ?, ? and changes the
type of ST_SELECT_LEX::select_limit,offset_limit from ha_rows to Item*,
so that it can point to Item_param.
mysql-test/include/ps_modify.inc:
Fix existing tests: now LIMIT can contain placeholders.
mysql-test/include/ps_query.inc:
Fix existing tests: now LIMIT can contain placeholders.
mysql-test/r/ps.result:
Add basic test coverage for LIMIT ?, ? and fix test results.
mysql-test/r/ps_2myisam.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_3innodb.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_4heap.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_5merge.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_6bdb.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/r/ps_7ndb.result:
Fix test results: now LIMIT can contain placeholders.
mysql-test/t/ps.test:
Add basic test coverage for LIMIT ?, ?.
sql/item.h:
Add a short-cut for (ulonglong) val_int() to Item.
Add a constructor to Item_int() that accepts ulonglong.
Simplify Item_uint constructor by using the c-tor above.
sql/item_subselect.cc:
Now select_limit has type Item *.
We can safely create an Item in Item_exists_subselect::fix_length_and_dec():
it will be allocated in runtime memory root and freed in the end of
execution.
sql/sp_head.cc:
Add a special initalization state for stored procedures to
be able to easily distinguish the first execution of a stored procedure
from prepared statement prepare.
sql/sql_class.h:
Introduce new state 'INITIALIZED_FOR_SP' to be able to easily distinguish
the first execution of a stored procedure from prepared statement prepare.
sql/sql_derived.cc:
- use unit->set_limit() to set unit->select_limit_cnt, offset_limit_cnt
evreryplace. Add a warning about use of set_limit in
mysql_derived_filling.
sql/sql_error.cc:
- use unit->set_limit() to set unit->select_limit_cnt, offset_limit_cnt
evreryplace.
- this change is also aware of bug#11095 "show warnings limit 0 returns
all rows instead of zero rows", so the one who merges the bugfix from
4.1 can use local version of sql_error.cc.
sql/sql_handler.cc:
- use unit->set_limit() to initalize
unit->select_limit_cnt,offset_limit_cnt everyplace.
sql/sql_lex.cc:
Now ST_SELECT_LEX::select_limit, offset_limit have type Item *
sql/sql_lex.h:
Now ST_SELECT_LEX::select_limit, offset_limit have type Item *
sql/sql_parse.cc:
- use unit->set_limit() to initalize
unit->select_limit_cnt,offset_limit_cnt everyplace.
- we can create an Item_int to set global limit of a statement:
it will be created in the runtime mem root and freed in the end of
execution.
sql/sql_repl.cc:
Use unit->set_limit to initialize limits.
sql/sql_select.cc:
- select_limit is now Item* so the proper way to check for default value
is to compare it with NULL.
sql/sql_union.cc:
Evaluate offset_limit_cnt using the new type of ST_SELECT_LEX::offset_limit
sql/sql_view.cc:
Now ST_SELECT_LEX::select_limit, offset_limit have type Item *
sql/sql_yacc.yy:
Add grammar support for LIMIT ?, ? clause.
2005-06-07 12:11:36 +02:00
|
|
|
/* We need only 1 row to determine existence */
|
2005-06-08 08:37:43 +02:00
|
|
|
unit->global_parameters->select_limit= new Item_int((int32) 1);
|
2002-09-28 17:34:56 +02:00
|
|
|
}
|
|
|
|
|
2010-07-10 12:37:30 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Add an expression cache for this subquery if it is needed
|
|
|
|
|
|
|
|
@param thd_arg Thread handle
|
|
|
|
|
|
|
|
@details
|
|
|
|
The function checks whether an expression cache is needed for this item
|
|
|
|
and if if so wraps the item into an item of the class
|
|
|
|
Item_exp_cache_wrapper with an appropriate expression cache set up there.
|
|
|
|
|
|
|
|
@note
|
|
|
|
used from Item::transform()
|
|
|
|
|
|
|
|
@return
|
|
|
|
new wrapper item if an expression cache is needed,
|
|
|
|
this item - otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
Item* Item_exists_subselect::expr_cache_insert_transformer(uchar *thd_arg)
|
|
|
|
{
|
|
|
|
THD *thd= (THD*) thd_arg;
|
|
|
|
DBUG_ENTER("Item_exists_subselect::expr_cache_insert_transformer");
|
|
|
|
|
|
|
|
if (substype() == EXISTS_SUBS && expr_cache_is_needed(thd))
|
|
|
|
DBUG_RETURN(set_expr_cache(thd, depends_on));
|
|
|
|
DBUG_RETURN(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-11-11 19:39:35 +01:00
|
|
|
double Item_exists_subselect::val_real()
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (exec())
|
2002-10-07 21:21:17 +02:00
|
|
|
{
|
2002-12-06 20:55:53 +01:00
|
|
|
reset();
|
2002-06-19 16:52:44 +02:00
|
|
|
return 0;
|
2002-10-07 21:21:17 +02:00
|
|
|
}
|
2002-06-19 16:52:44 +02:00
|
|
|
return (double) value;
|
|
|
|
}
|
|
|
|
|
2004-07-04 07:46:28 +02:00
|
|
|
longlong Item_exists_subselect::val_int()
|
2002-06-19 16:52:44 +02:00
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (exec())
|
2002-10-07 21:21:17 +02:00
|
|
|
{
|
2002-12-06 20:55:53 +01:00
|
|
|
reset();
|
2002-06-19 16:52:44 +02:00
|
|
|
return 0;
|
2002-10-07 21:21:17 +02:00
|
|
|
}
|
2002-06-19 16:52:44 +02:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2008-07-04 16:02:17 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Return the result of EXISTS as a string value
|
|
|
|
|
|
|
|
Converts the true/false result into a string value.
|
|
|
|
Note that currently this cannot be NULL, so if the query exection fails
|
|
|
|
it will return 0.
|
|
|
|
|
|
|
|
@param decimal_value[out] buffer to hold the resulting string value
|
|
|
|
@retval Pointer to the converted string.
|
|
|
|
Can't be a NULL pointer, as currently
|
|
|
|
EXISTS cannot return NULL.
|
|
|
|
*/
|
|
|
|
|
2002-06-19 16:52:44 +02:00
|
|
|
String *Item_exists_subselect::val_str(String *str)
|
|
|
|
{
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (exec())
|
2002-12-06 20:55:53 +01:00
|
|
|
reset();
|
2005-04-01 01:14:30 +02:00
|
|
|
str->set((ulonglong)value,&my_charset_bin);
|
2002-12-06 20:55:53 +01:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2005-02-08 23:50:45 +01:00
|
|
|
|
2008-07-04 16:02:17 +02:00
|
|
|
/**
|
|
|
|
Return the result of EXISTS as a decimal value
|
|
|
|
|
|
|
|
Converts the true/false result into a decimal value.
|
|
|
|
Note that currently this cannot be NULL, so if the query exection fails
|
|
|
|
it will return 0.
|
|
|
|
|
|
|
|
@param decimal_value[out] Buffer to hold the resulting decimal value
|
|
|
|
@retval Pointer to the converted decimal.
|
|
|
|
Can't be a NULL pointer, as currently
|
|
|
|
EXISTS cannot return NULL.
|
|
|
|
*/
|
|
|
|
|
2005-02-08 23:50:45 +01:00
|
|
|
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(fixed == 1);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (exec())
|
2005-02-08 23:50:45 +01:00
|
|
|
reset();
|
|
|
|
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
|
|
|
|
return decimal_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Item_exists_subselect::val_bool()
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(fixed == 1);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (exec())
|
2005-02-08 23:50:45 +01:00
|
|
|
{
|
|
|
|
reset();
|
|
|
|
return 0;
|
|
|
|
}
|
2005-03-19 01:12:25 +01:00
|
|
|
return value != 0;
|
2005-02-08 23:50:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-11-11 19:39:35 +01:00
|
|
|
double Item_in_subselect::val_real()
|
2002-12-06 20:55:53 +01:00
|
|
|
{
|
2005-03-30 09:07:08 +02:00
|
|
|
/*
|
|
|
|
As far as Item_in_subselect called only from Item_in_optimizer this
|
|
|
|
method should not be used
|
|
|
|
*/
|
|
|
|
DBUG_ASSERT(0);
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2006-10-20 08:05:53 +02:00
|
|
|
null_value= 0;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (exec())
|
2002-12-06 20:55:53 +01:00
|
|
|
{
|
|
|
|
reset();
|
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (was_null && !value)
|
|
|
|
null_value= 1;
|
|
|
|
return (double) value;
|
|
|
|
}
|
|
|
|
|
2005-03-30 09:07:08 +02:00
|
|
|
|
2004-07-04 07:46:28 +02:00
|
|
|
longlong Item_in_subselect::val_int()
|
2002-12-06 20:55:53 +01:00
|
|
|
{
|
2005-03-31 09:39:48 +02:00
|
|
|
/*
|
|
|
|
As far as Item_in_subselect called only from Item_in_optimizer this
|
|
|
|
method should not be used
|
|
|
|
*/
|
|
|
|
DBUG_ASSERT(0);
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2006-10-20 08:05:53 +02:00
|
|
|
null_value= 0;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (exec())
|
2002-12-06 20:55:53 +01:00
|
|
|
{
|
|
|
|
reset();
|
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (was_null && !value)
|
|
|
|
null_value= 1;
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2005-03-30 09:07:08 +02:00
|
|
|
|
2002-12-06 20:55:53 +01:00
|
|
|
String *Item_in_subselect::val_str(String *str)
|
|
|
|
{
|
2005-03-30 09:07:08 +02:00
|
|
|
/*
|
|
|
|
As far as Item_in_subselect called only from Item_in_optimizer this
|
|
|
|
method should not be used
|
|
|
|
*/
|
|
|
|
DBUG_ASSERT(0);
|
2004-03-18 14:14:36 +01:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
2006-10-20 08:05:53 +02:00
|
|
|
null_value= 0;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (exec())
|
2002-12-06 20:55:53 +01:00
|
|
|
{
|
|
|
|
reset();
|
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (was_null && !value)
|
|
|
|
{
|
|
|
|
null_value= 1;
|
2002-06-19 16:52:44 +02:00
|
|
|
return 0;
|
2002-10-07 21:21:17 +02:00
|
|
|
}
|
2005-04-01 01:14:30 +02:00
|
|
|
str->set((ulonglong)value, &my_charset_bin);
|
2002-06-19 16:52:44 +02:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2002-11-07 22:45:19 +01:00
|
|
|
|
2005-04-01 01:14:30 +02:00
|
|
|
bool Item_in_subselect::val_bool()
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(fixed == 1);
|
2006-10-20 21:41:27 +02:00
|
|
|
null_value= 0;
|
2010-02-19 22:55:57 +01:00
|
|
|
if (is_constant)
|
|
|
|
return value;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (exec())
|
2005-04-01 01:14:30 +02:00
|
|
|
{
|
|
|
|
reset();
|
2007-05-17 18:38:34 +02:00
|
|
|
/*
|
|
|
|
Must mark the IN predicate as NULL so as to make sure an enclosing NOT
|
|
|
|
predicate will return FALSE. See the comments in
|
|
|
|
subselect_uniquesubquery_engine::copy_ref_key for further details.
|
|
|
|
*/
|
2005-04-01 01:14:30 +02:00
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (was_null && !value)
|
|
|
|
null_value= 1;
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
As far as Item_in_subselect called only from Item_in_optimizer this
|
|
|
|
method should not be used
|
|
|
|
*/
|
|
|
|
DBUG_ASSERT(0);
|
2006-10-20 21:41:27 +02:00
|
|
|
null_value= 0;
|
2005-04-01 01:14:30 +02:00
|
|
|
DBUG_ASSERT(fixed == 1);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (exec())
|
2005-04-01 01:14:30 +02:00
|
|
|
{
|
|
|
|
reset();
|
|
|
|
null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (was_null && !value)
|
|
|
|
null_value= 1;
|
|
|
|
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
|
|
|
|
return decimal_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
/*
|
|
|
|
Rewrite a single-column IN/ALL/ANY subselect
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
Item_in_subselect::single_value_transformer()
|
2006-10-31 22:27:51 +01:00
|
|
|
join Join object of the subquery (i.e. 'child' join).
|
|
|
|
func Subquery comparison creator
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Rewrite a single-column subquery using rule-based approach. The subquery
|
|
|
|
|
2006-10-31 22:27:51 +01:00
|
|
|
oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
First, try to convert the subquery to scalar-result subquery in one of
|
|
|
|
the forms:
|
|
|
|
|
|
|
|
- oe $cmp$ (SELECT MAX(...) ) // handled by Item_singlerow_subselect
|
2006-10-31 22:27:51 +01:00
|
|
|
- oe $cmp$ <max>(SELECT ...) // handled by Item_maxmin_subselect
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
If that fails, the subquery will be handled with class Item_in_optimizer,
|
|
|
|
Inject the predicates into subquery, i.e. convert it to:
|
|
|
|
|
|
|
|
- If the subquery has aggregates, GROUP BY, or HAVING, convert to
|
|
|
|
|
2006-10-31 22:27:51 +01:00
|
|
|
SELECT ie FROM ... HAVING subq_having AND
|
2006-10-31 18:51:09 +01:00
|
|
|
trigcond(oe $cmp$ ref_or_null_helper<ie>)
|
|
|
|
|
|
|
|
the addition is wrapped into trigger only when we want to distinguish
|
|
|
|
between NULL and FALSE results.
|
|
|
|
|
2006-10-31 22:27:51 +01:00
|
|
|
- Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
|
|
|
|
following:
|
2006-10-31 18:51:09 +01:00
|
|
|
|
2006-10-31 22:27:51 +01:00
|
|
|
= If we don't need to distinguish between NULL and FALSE subquery:
|
|
|
|
|
|
|
|
SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
|
2006-10-31 18:51:09 +01:00
|
|
|
|
2006-10-31 22:27:51 +01:00
|
|
|
= If we need to distinguish between those:
|
|
|
|
|
|
|
|
SELECT 1 FROM ...
|
|
|
|
WHERE subq_where AND trigcond((oe $cmp$ ie) OR (ie IS NULL))
|
|
|
|
HAVING trigcond(<is_not_null_test>(ie))
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
RETURN
|
2010-01-28 14:48:33 +01:00
|
|
|
RES_OK Either subquery was transformed, or appopriate
|
|
|
|
predicates where injected into it.
|
|
|
|
RES_REDUCE The subquery was reduced to non-subquery
|
|
|
|
RES_ERROR Error
|
2006-10-31 18:51:09 +01:00
|
|
|
*/
|
2004-10-04 16:58:06 +02:00
|
|
|
|
2003-05-14 20:51:33 +02:00
|
|
|
Item_subselect::trans_res
|
2010-09-05 17:43:47 +02:00
|
|
|
Item_in_subselect::single_value_transformer(JOIN *join)
|
2002-11-07 22:45:19 +01:00
|
|
|
{
|
2003-05-14 20:51:33 +02:00
|
|
|
SELECT_LEX *select_lex= join->select_lex;
|
2005-05-30 19:48:40 +02:00
|
|
|
DBUG_ENTER("Item_in_subselect::single_value_transformer");
|
2004-09-06 14:14:10 +02:00
|
|
|
|
2004-10-04 16:58:06 +02:00
|
|
|
/*
|
|
|
|
Check that the right part of the subselect contains no more than one
|
|
|
|
column. E.g. in SELECT 1 IN (SELECT * ..) the right part is (SELECT * ...)
|
|
|
|
*/
|
2010-01-28 14:48:33 +01:00
|
|
|
// psergey: duplicated_subselect_card_check
|
2003-10-23 22:54:21 +02:00
|
|
|
if (select_lex->item_list.elements > 1)
|
|
|
|
{
|
|
|
|
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
2003-10-23 22:54:21 +02:00
|
|
|
}
|
|
|
|
|
2004-10-04 16:58:06 +02:00
|
|
|
/*
|
|
|
|
If this is an ALL/ANY single-value subselect, try to rewrite it with
|
|
|
|
a MIN/MAX subselect. We can do that if a possible NULL result of the
|
|
|
|
subselect can be ignored.
|
|
|
|
E.g. SELECT * FROM t1 WHERE b > ANY (SELECT a FROM t2) can be rewritten
|
|
|
|
with SELECT * FROM t1 WHERE b > (SELECT MAX(a) FROM t2).
|
|
|
|
We can't check that this optimization is safe if it's not a top-level
|
|
|
|
item of the WHERE clause (e.g. because the WHERE clause can contain IS
|
|
|
|
NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS
|
|
|
|
later in this method.
|
|
|
|
*/
|
2004-11-18 17:10:07 +01:00
|
|
|
if ((abort_on_null || (upper_item && upper_item->top_level())) &&
|
2003-11-17 19:53:40 +01:00
|
|
|
!select_lex->master_unit()->uncacheable && !func->eqne_op())
|
2003-07-24 14:26:21 +02:00
|
|
|
{
|
2003-10-27 00:01:27 +01:00
|
|
|
if (substitution)
|
|
|
|
{
|
|
|
|
// It is second (third, ...) SELECT of UNION => All is done
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_OK);
|
2003-10-27 00:01:27 +01:00
|
|
|
}
|
|
|
|
|
2003-08-12 11:38:03 +02:00
|
|
|
Item *subs;
|
|
|
|
if (!select_lex->group_list.elements &&
|
2005-03-30 09:07:08 +02:00
|
|
|
!select_lex->having &&
|
2003-10-27 00:01:27 +01:00
|
|
|
!select_lex->with_sum_func &&
|
2006-07-10 22:34:37 +02:00
|
|
|
!(select_lex->next_select()) &&
|
|
|
|
select_lex->table_list.elements)
|
2003-07-24 14:26:21 +02:00
|
|
|
{
|
2004-11-18 17:10:07 +01:00
|
|
|
Item_sum_hybrid *item;
|
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
mysql-test/r/func_gconcat.result:
Changed a query when fixing bug #12762.
mysql-test/r/subselect.result:
Added test cases for bug #12762.
Allowed set functions aggregated in outer subqueries. Allowed nested set functions.
mysql-test/t/func_gconcat.test:
Changed a query when fixing bug #12762.
mysql-test/t/subselect.test:
Added test cases for bug #12762.
Allowed set functions aggregated in outer subqueries. Allowed nested set functions.
sql/item.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
Changed Item_field::fix_fields to calculate attributes used when checking context conditions
for set functions.
Allowed alliases for set functions defined in outer subqueries.
sql/item.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_cmpfunc.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_func.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_row.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_strfunc.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_subselect.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/item_sum.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added Item_sum methods to check context conditions imposed on set functions.
sql/item_sum.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added Item_sum methods to check context conditions imposed on set functions.
sql/mysql_priv.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a type of bitmaps to be used for nesting constructs.
sql/sql_base.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_class.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_class.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_delete.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_lex.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_lex.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_parse.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries.
sql/sql_prepare.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showingin what subqueries a set function can be aggregated.
sql/sql_select.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_update.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_yacc.yy:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries.
2005-10-15 23:32:37 +02:00
|
|
|
nesting_map save_allow_sum_func;
|
2003-11-03 11:28:36 +01:00
|
|
|
if (func->l_op())
|
2003-08-12 11:38:03 +02:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
(ALL && (> || =>)) || (ANY && (< || =<))
|
|
|
|
for ALL condition is inverted
|
|
|
|
*/
|
|
|
|
item= new Item_sum_max(*select_lex->ref_pointer_array);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
(ALL && (< || =<)) || (ANY && (> || =>))
|
|
|
|
for ALL condition is inverted
|
|
|
|
*/
|
|
|
|
item= new Item_sum_min(*select_lex->ref_pointer_array);
|
|
|
|
}
|
2004-11-18 17:10:07 +01:00
|
|
|
if (upper_item)
|
|
|
|
upper_item->set_sum_test(item);
|
2003-08-12 11:38:03 +02:00
|
|
|
*select_lex->ref_pointer_array= item;
|
2004-05-07 22:06:11 +02:00
|
|
|
{
|
|
|
|
List_iterator<Item> it(select_lex->item_list);
|
|
|
|
it++;
|
|
|
|
it.replace(item);
|
|
|
|
}
|
2004-03-09 11:52:25 +01:00
|
|
|
|
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
mysql-test/r/func_gconcat.result:
Changed a query when fixing bug #12762.
mysql-test/r/subselect.result:
Added test cases for bug #12762.
Allowed set functions aggregated in outer subqueries. Allowed nested set functions.
mysql-test/t/func_gconcat.test:
Changed a query when fixing bug #12762.
mysql-test/t/subselect.test:
Added test cases for bug #12762.
Allowed set functions aggregated in outer subqueries. Allowed nested set functions.
sql/item.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
Changed Item_field::fix_fields to calculate attributes used when checking context conditions
for set functions.
Allowed alliases for set functions defined in outer subqueries.
sql/item.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_cmpfunc.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_func.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_row.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_strfunc.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_subselect.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/item_sum.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added Item_sum methods to check context conditions imposed on set functions.
sql/item_sum.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added Item_sum methods to check context conditions imposed on set functions.
sql/mysql_priv.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a type of bitmaps to be used for nesting constructs.
sql/sql_base.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_class.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_class.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_delete.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_lex.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_lex.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_parse.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries.
sql/sql_prepare.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showingin what subqueries a set function can be aggregated.
sql/sql_select.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_update.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_yacc.yy:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries.
2005-10-15 23:32:37 +02:00
|
|
|
save_allow_sum_func= thd->lex->allow_sum_func;
|
|
|
|
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
|
2004-05-07 22:06:11 +02:00
|
|
|
/*
|
|
|
|
Item_sum_(max|min) can't substitute other item => we can use 0 as
|
2005-02-08 23:50:45 +01:00
|
|
|
reference, also Item_sum_(max|min) can't be fixed after creation, so
|
|
|
|
we do not check item->fixed
|
2004-05-07 22:06:11 +02:00
|
|
|
*/
|
2005-07-01 06:05:42 +02:00
|
|
|
if (item->fix_fields(thd, 0))
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
mysql-test/r/func_gconcat.result:
Changed a query when fixing bug #12762.
mysql-test/r/subselect.result:
Added test cases for bug #12762.
Allowed set functions aggregated in outer subqueries. Allowed nested set functions.
mysql-test/t/func_gconcat.test:
Changed a query when fixing bug #12762.
mysql-test/t/subselect.test:
Added test cases for bug #12762.
Allowed set functions aggregated in outer subqueries. Allowed nested set functions.
sql/item.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
Changed Item_field::fix_fields to calculate attributes used when checking context conditions
for set functions.
Allowed alliases for set functions defined in outer subqueries.
sql/item.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_cmpfunc.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_func.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_row.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_strfunc.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added a parameter to Item::split_sum_func2 aliowing to defer splitting for set functions
aggregated in outer subquries.
sql/item_subselect.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/item_sum.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added Item_sum methods to check context conditions imposed on set functions.
sql/item_sum.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Added Item_sum methods to check context conditions imposed on set functions.
sql/mysql_priv.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a type of bitmaps to be used for nesting constructs.
sql/sql_base.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_class.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_class.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_delete.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_lex.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_lex.h:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_parse.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries.
sql/sql_prepare.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showingin what subqueries a set function can be aggregated.
sql/sql_select.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries and a bitmap of nesting levels showing
in what subqueries a set function can be aggregated.
sql/sql_update.cc:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced a bitmap of nesting levels showing in what subqueries a set function can be aggregated.
sql/sql_yacc.yy:
Fixed bug #12762:
allowed set functions aggregated in outer subqueries, allowed nested set functions.
Introduced next levels for subqueries.
2005-10-15 23:32:37 +02:00
|
|
|
thd->lex->allow_sum_func= save_allow_sum_func;
|
2004-05-07 22:06:11 +02:00
|
|
|
/* we added aggregate function => we have to change statistic */
|
2007-06-29 09:39:17 +02:00
|
|
|
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
|
|
|
|
0);
|
2004-02-08 19:14:13 +01:00
|
|
|
|
2003-10-07 12:31:44 +02:00
|
|
|
subs= new Item_singlerow_subselect(select_lex);
|
2003-07-24 14:26:21 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-11-18 17:10:07 +01:00
|
|
|
Item_maxmin_subselect *item;
|
2004-12-22 12:54:39 +01:00
|
|
|
subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
|
2004-11-18 17:10:07 +01:00
|
|
|
if (upper_item)
|
|
|
|
upper_item->set_sub_test(item);
|
2003-07-24 14:26:21 +02:00
|
|
|
}
|
2005-03-10 13:01:22 +01:00
|
|
|
/* fix fields is already called for left expression */
|
2003-11-03 11:28:36 +01:00
|
|
|
substitution= func->create(left_expr, subs);
|
2010-09-05 17:43:47 +02:00
|
|
|
is_min_max_optimized= TRUE;
|
|
|
|
DBUG_RETURN(RES_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
Item* join_having= join->having ? join->having : join->tmp_having;
|
|
|
|
if (!(join_having || select_lex->with_sum_func ||
|
|
|
|
select_lex->group_list.elements) &&
|
|
|
|
select_lex->table_list.elements == 0 &&
|
|
|
|
!select_lex->master_unit()->is_union())
|
|
|
|
{
|
|
|
|
Item *where_item= (Item*) select_lex->item_list.head();
|
|
|
|
/*
|
|
|
|
it is single select without tables => possible optimization
|
|
|
|
remove the dependence mark since the item is moved to upper
|
|
|
|
select and is not outer anymore.
|
|
|
|
*/
|
|
|
|
where_item->walk(&Item::remove_dependence_processor, 0,
|
|
|
|
(uchar *) select_lex->outer_select());
|
|
|
|
substitution= func->create(left_expr, where_item);
|
|
|
|
have_to_be_excluded= 1;
|
|
|
|
if (thd->lex->describe)
|
|
|
|
{
|
|
|
|
char warn_buff[MYSQL_ERRMSG_SIZE];
|
|
|
|
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
|
|
|
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
|
|
|
ER_SELECT_REDUCED, warn_buff);
|
|
|
|
}
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_OK);
|
2003-07-24 14:26:21 +02:00
|
|
|
}
|
|
|
|
|
2003-05-14 20:51:33 +02:00
|
|
|
if (!substitution)
|
2002-10-27 22:27:00 +01:00
|
|
|
{
|
2007-01-12 20:11:40 +01:00
|
|
|
/* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
|
2006-12-14 23:51:37 +01:00
|
|
|
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
|
2005-03-10 13:01:22 +01:00
|
|
|
substitution= optimizer;
|
2003-05-14 20:51:33 +02:00
|
|
|
|
2008-02-13 20:27:12 +01:00
|
|
|
SELECT_LEX *current= thd->lex->current_select;
|
2003-07-03 01:30:52 +02:00
|
|
|
|
2008-02-13 20:27:12 +01:00
|
|
|
thd->lex->current_select= current->return_after_parsing();
|
2003-05-14 20:51:33 +02:00
|
|
|
//optimizer never use Item **ref => we can pass 0 as parameter
|
2005-07-01 06:05:42 +02:00
|
|
|
if (!optimizer || optimizer->fix_left(thd, 0))
|
2002-12-23 17:25:25 +01:00
|
|
|
{
|
2004-02-08 19:14:13 +01:00
|
|
|
thd->lex->current_select= current;
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
2002-12-23 17:25:25 +01:00
|
|
|
}
|
2004-02-08 19:14:13 +01:00
|
|
|
thd->lex->current_select= current;
|
2002-12-23 17:25:25 +01:00
|
|
|
|
2010-01-17 15:51:10 +01:00
|
|
|
/* We will refer to upper level cache array => we have to save it for SP */
|
|
|
|
optimizer->keep_top_level_cache();
|
|
|
|
|
2003-05-14 20:51:33 +02:00
|
|
|
/*
|
2005-02-08 23:50:45 +01:00
|
|
|
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
|
2003-05-14 20:51:33 +02:00
|
|
|
we can use same item for all selects.
|
|
|
|
*/
|
2005-07-01 06:05:42 +02:00
|
|
|
expr= new Item_direct_ref(&select_lex->context,
|
|
|
|
(Item**)optimizer->get_cache(),
|
2004-12-11 16:13:19 +01:00
|
|
|
(char *)"<no matter>",
|
|
|
|
(char *)in_left_expr_name);
|
2003-05-14 20:51:33 +02:00
|
|
|
|
2006-12-14 23:51:37 +01:00
|
|
|
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
|
2010-09-05 17:43:47 +02:00
|
|
|
//select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
|
2003-05-14 20:51:33 +02:00
|
|
|
}
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_RETURN(RES_OK);
|
2010-01-28 14:48:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Transofrm an IN predicate into EXISTS via predicate injection.
|
|
|
|
|
|
|
|
@details The transformation injects additional predicates into the subquery
|
|
|
|
(and makes the subquery correlated) as follows.
|
|
|
|
|
|
|
|
- If the subquery has aggregates, GROUP BY, or HAVING, convert to
|
|
|
|
|
|
|
|
SELECT ie FROM ... HAVING subq_having AND
|
|
|
|
trigcond(oe $cmp$ ref_or_null_helper<ie>)
|
|
|
|
|
|
|
|
the addition is wrapped into trigger only when we want to distinguish
|
|
|
|
between NULL and FALSE results.
|
|
|
|
|
|
|
|
- Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
|
|
|
|
following:
|
|
|
|
|
|
|
|
= If we don't need to distinguish between NULL and FALSE subquery:
|
|
|
|
|
|
|
|
SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
|
|
|
|
|
|
|
|
= If we need to distinguish between those:
|
|
|
|
|
|
|
|
SELECT 1 FROM ...
|
|
|
|
WHERE subq_where AND trigcond((oe $cmp$ ie) OR (ie IS NULL))
|
|
|
|
HAVING trigcond(<is_not_null_test>(ie))
|
|
|
|
|
|
|
|
@param join Join object of the subquery (i.e. 'child' join).
|
|
|
|
@param func Subquery comparison creator
|
|
|
|
|
|
|
|
@retval RES_OK Either subquery was transformed, or appopriate
|
|
|
|
predicates where injected into it.
|
|
|
|
@retval RES_REDUCE The subquery was reduced to non-subquery
|
|
|
|
@retval RES_ERROR Error
|
|
|
|
*/
|
|
|
|
|
|
|
|
Item_subselect::trans_res
|
2010-09-05 17:43:47 +02:00
|
|
|
Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
|
|
|
|
Item **where_item,
|
|
|
|
Item **having_item)
|
2010-01-28 14:48:33 +01:00
|
|
|
{
|
|
|
|
SELECT_LEX *select_lex= join->select_lex;
|
2010-09-05 17:43:47 +02:00
|
|
|
/*
|
|
|
|
The non-transformed HAVING clause of 'join' may be stored differently in
|
|
|
|
JOIN::optimize:
|
|
|
|
this->tmp_having= this->having
|
|
|
|
this->having= 0;
|
|
|
|
*/
|
|
|
|
Item* join_having= join->having ? join->having : join->tmp_having;
|
|
|
|
|
|
|
|
DBUG_ENTER("Item_in_subselect::create_single_in_to_exists_cond");
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-09-05 17:43:47 +02:00
|
|
|
if (join_having || select_lex->with_sum_func ||
|
2003-05-14 20:51:33 +02:00
|
|
|
select_lex->group_list.elements)
|
|
|
|
{
|
2004-09-06 14:14:10 +02:00
|
|
|
Item *item= func->create(expr,
|
2005-07-01 06:05:42 +02:00
|
|
|
new Item_ref_null_helper(&select_lex->context,
|
|
|
|
this,
|
2004-09-06 14:14:10 +02:00
|
|
|
select_lex->
|
|
|
|
ref_pointer_array,
|
|
|
|
(char *)"<ref>",
|
|
|
|
this->full_name()));
|
2007-01-12 20:11:40 +01:00
|
|
|
if (!abort_on_null && left_expr->maybe_null)
|
2006-10-31 18:51:09 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
We can encounter "NULL IN (SELECT ...)". Wrap the added condition
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
within a trig_cond.
|
2006-10-31 18:51:09 +01:00
|
|
|
*/
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
item= new Item_func_trig_cond(item, get_cond_guard(0));
|
2006-10-31 18:51:09 +01:00
|
|
|
}
|
2010-07-18 13:46:08 +02:00
|
|
|
|
|
|
|
if (item->fix_fields(thd, 0))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
|
2010-07-18 14:59:24 +02:00
|
|
|
*having_item= item;
|
|
|
|
*where_item= NULL;
|
2010-07-18 13:46:08 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Item *item= (Item*) select_lex->item_list.head();
|
|
|
|
|
|
|
|
if (select_lex->table_list.elements)
|
|
|
|
{
|
|
|
|
Item *having= item;
|
|
|
|
Item *orig_item= item;
|
|
|
|
|
|
|
|
item= func->create(expr, item);
|
|
|
|
if (!abort_on_null && orig_item->maybe_null)
|
|
|
|
{
|
|
|
|
having= new Item_is_not_null_test(this, having);
|
|
|
|
if (left_expr->maybe_null)
|
|
|
|
{
|
|
|
|
if (!(having= new Item_func_trig_cond(having,
|
|
|
|
get_cond_guard(0))))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (having->fix_fields(thd, 0))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
|
2010-07-18 14:59:24 +02:00
|
|
|
*having_item= having;
|
2010-07-18 13:46:08 +02:00
|
|
|
|
|
|
|
item= new Item_cond_or(item,
|
|
|
|
new Item_func_isnull(orig_item));
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
If we may encounter NULL IN (SELECT ...) and care whether subquery
|
|
|
|
result is NULL or FALSE, wrap condition in a trig_cond.
|
|
|
|
*/
|
|
|
|
if (!abort_on_null && left_expr->maybe_null)
|
|
|
|
{
|
|
|
|
if (!(item= new Item_func_trig_cond(item, get_cond_guard(0))))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->fix_fields(thd, 0))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
|
2010-07-18 14:59:24 +02:00
|
|
|
*where_item= item;
|
2010-07-18 13:46:08 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (select_lex->master_unit()->is_union())
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
comparison functions can't be changed during fix_fields()
|
|
|
|
we can assign select_lex->having here, and pass 0 as last
|
|
|
|
argument (reference) to fix_fields()
|
|
|
|
*/
|
|
|
|
Item *new_having=
|
|
|
|
func->create(expr,
|
|
|
|
new Item_ref_null_helper(&select_lex->context, this,
|
|
|
|
select_lex->ref_pointer_array,
|
|
|
|
(char *)"<no matter>",
|
|
|
|
(char *)"<result>"));
|
|
|
|
if (!abort_on_null && left_expr->maybe_null)
|
|
|
|
{
|
|
|
|
if (!(new_having= new Item_func_trig_cond(new_having,
|
|
|
|
get_cond_guard(0))))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (new_having->fix_fields(thd, 0))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
|
2010-07-18 14:59:24 +02:00
|
|
|
*having_item= new_having;
|
|
|
|
*where_item= NULL;
|
2010-07-18 13:46:08 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_ASSERT(FALSE);
|
|
|
|
/* TIMOUR TODO */
|
2010-07-18 14:59:24 +02:00
|
|
|
*having_item= NULL;
|
|
|
|
*where_item= (Item*) select_lex->item_list.head();
|
2010-07-18 13:46:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DBUG_RETURN(RES_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Item_subselect::trans_res
|
2010-09-05 17:43:47 +02:00
|
|
|
Item_in_subselect::inject_single_in_to_exists_cond(JOIN * join,
|
|
|
|
Item *where_item,
|
|
|
|
Item *having_item)
|
2010-07-18 13:46:08 +02:00
|
|
|
{
|
|
|
|
SELECT_LEX *select_lex= join->select_lex;
|
2010-09-05 17:43:47 +02:00
|
|
|
/*
|
|
|
|
The non-transformed HAVING clause of 'join' may be stored differently in
|
|
|
|
JOIN::optimize:
|
|
|
|
this->tmp_having= this->having
|
|
|
|
this->having= 0;
|
|
|
|
*/
|
|
|
|
Item* join_having= join->having ? join->having : join->tmp_having;
|
2010-09-06 13:26:30 +02:00
|
|
|
bool fix_res= 0;
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_ENTER("Item_in_subselect::inject_single_in_to_exists_cond");
|
2010-07-18 13:46:08 +02:00
|
|
|
|
2010-09-05 17:43:47 +02:00
|
|
|
if (join_having || select_lex->with_sum_func ||
|
2010-07-18 13:46:08 +02:00
|
|
|
select_lex->group_list.elements)
|
|
|
|
{
|
2004-02-18 21:14:41 +01:00
|
|
|
/*
|
|
|
|
AND and comparison functions can't be changed during fix_fields()
|
|
|
|
we can assign select_lex->having here, and pass 0 as last
|
|
|
|
argument (reference) to fix_fields()
|
|
|
|
*/
|
2010-09-05 17:43:47 +02:00
|
|
|
thd->change_item_tree(&select_lex->having, and_items(join_having, having_item));
|
|
|
|
join->having= select_lex->having;
|
2010-07-18 14:59:24 +02:00
|
|
|
if (join->having == having_item)
|
|
|
|
having_item->name= (char*)in_having_cond;
|
2003-05-14 20:51:33 +02:00
|
|
|
select_lex->having_fix_field= 1;
|
2005-02-08 23:50:45 +01:00
|
|
|
/*
|
|
|
|
we do not check join->having->fixed, because Item_and (from and_items)
|
|
|
|
or comparison function (from func->create) can't be fixed after creation
|
|
|
|
*/
|
2010-07-18 13:46:08 +02:00
|
|
|
if (!join->having->fixed)
|
|
|
|
fix_res= join->having->fix_fields(thd, 0);
|
2003-05-14 20:51:33 +02:00
|
|
|
select_lex->having_fix_field= 0;
|
2010-07-18 13:46:08 +02:00
|
|
|
if (fix_res)
|
2005-03-31 09:39:48 +02:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
2003-05-14 20:51:33 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (select_lex->table_list.elements)
|
2002-10-31 01:11:59 +01:00
|
|
|
{
|
2010-09-05 17:43:47 +02:00
|
|
|
if (!abort_on_null && select_lex->item_list.head()->maybe_null)
|
2002-11-28 18:29:26 +01:00
|
|
|
{
|
2004-02-18 21:14:41 +01:00
|
|
|
/*
|
|
|
|
Item_is_not_null_test can't be changed during fix_fields()
|
|
|
|
we can assign select_lex->having here, and pass 0 as last
|
|
|
|
argument (reference) to fix_fields()
|
|
|
|
*/
|
2010-07-18 14:59:24 +02:00
|
|
|
having_item->name= (char*)in_having_cond;
|
2010-09-05 17:43:47 +02:00
|
|
|
thd->change_item_tree(&select_lex->having, having_item);
|
|
|
|
join->having= select_lex->having;
|
2003-05-14 20:51:33 +02:00
|
|
|
select_lex->having_fix_field= 1;
|
2005-02-08 23:50:45 +01:00
|
|
|
/*
|
|
|
|
we do not check join->having->fixed, because Item_and (from
|
|
|
|
and_items) or comparison function (from func->create) can't be
|
|
|
|
fixed after creation
|
|
|
|
*/
|
2010-07-18 13:46:08 +02:00
|
|
|
if (!join->having->fixed)
|
|
|
|
fix_res= join->having->fix_fields(thd, 0);
|
2004-09-06 14:14:10 +02:00
|
|
|
select_lex->having_fix_field= 0;
|
2010-07-18 13:46:08 +02:00
|
|
|
if (fix_res)
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
2007-01-12 20:11:40 +01:00
|
|
|
}
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
/*
|
|
|
|
TODO: figure out why the following is done here in
|
|
|
|
single_value_transformer but there is no corresponding action in
|
|
|
|
row_value_transformer?
|
|
|
|
*/
|
2010-07-18 14:59:24 +02:00
|
|
|
where_item->name= (char *)in_additional_cond;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
|
2004-02-18 21:14:41 +01:00
|
|
|
/*
|
|
|
|
AND can't be changed during fix_fields()
|
|
|
|
we can assign select_lex->having here, and pass 0 as last
|
|
|
|
argument (reference) to fix_fields()
|
|
|
|
*/
|
2010-09-05 17:43:47 +02:00
|
|
|
thd->change_item_tree(&select_lex->where, and_items(join->conds, where_item));
|
|
|
|
join->conds= select_lex->where;
|
2005-08-13 06:45:14 +02:00
|
|
|
select_lex->where->top_level_item();
|
2005-02-08 23:50:45 +01:00
|
|
|
/*
|
|
|
|
we do not check join->conds->fixed, because Item_and can't be fixed
|
|
|
|
after creation
|
|
|
|
*/
|
2010-07-18 13:46:08 +02:00
|
|
|
if (!join->conds->fixed && join->conds->fix_fields(thd, 0))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
2003-05-14 20:51:33 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-04-23 13:16:49 +02:00
|
|
|
if (select_lex->master_unit()->is_union())
|
2003-05-14 20:51:33 +02:00
|
|
|
{
|
2010-07-18 14:59:24 +02:00
|
|
|
having_item->name= (char*)in_having_cond;
|
2010-09-05 17:43:47 +02:00
|
|
|
thd->change_item_tree(&select_lex->having, having_item);
|
|
|
|
join->having= select_lex->having;
|
2003-05-14 20:51:33 +02:00
|
|
|
select_lex->having_fix_field= 1;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
|
2005-02-08 23:50:45 +01:00
|
|
|
/*
|
|
|
|
we do not check join->having->fixed, because comparison function
|
|
|
|
(from func->create) can't be fixed after creation
|
|
|
|
*/
|
2010-07-18 13:46:08 +02:00
|
|
|
if (!join->having->fixed)
|
|
|
|
fix_res= join->having->fix_fields(thd, 0);
|
2004-09-06 14:14:10 +02:00
|
|
|
select_lex->having_fix_field= 0;
|
2010-07-18 13:46:08 +02:00
|
|
|
if (fix_res)
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
2003-05-14 20:51:33 +02:00
|
|
|
}
|
|
|
|
else
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_ASSERT(FALSE);
|
2002-10-31 01:11:59 +01:00
|
|
|
}
|
2002-10-27 22:27:00 +01:00
|
|
|
}
|
2004-02-08 19:14:13 +01:00
|
|
|
|
2003-08-28 12:21:30 +02:00
|
|
|
DBUG_RETURN(RES_OK);
|
2002-10-27 22:27:00 +01:00
|
|
|
}
|
2002-09-03 08:50:36 +02:00
|
|
|
|
2003-11-28 11:18:13 +01:00
|
|
|
|
2003-05-14 20:51:33 +02:00
|
|
|
Item_subselect::trans_res
|
2003-11-02 16:27:35 +01:00
|
|
|
Item_in_subselect::row_value_transformer(JOIN *join)
|
2002-12-19 20:15:09 +01:00
|
|
|
{
|
2004-09-06 14:14:10 +02:00
|
|
|
SELECT_LEX *select_lex= join->select_lex;
|
2005-08-13 06:45:14 +02:00
|
|
|
uint cols_num= left_expr->cols();
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2002-12-19 20:15:09 +01:00
|
|
|
DBUG_ENTER("Item_in_subselect::row_value_transformer");
|
2002-12-31 17:39:16 +01:00
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
// psergey: duplicated_subselect_card_check
|
2010-02-19 22:55:57 +01:00
|
|
|
if (select_lex->item_list.elements != cols_num)
|
2003-10-23 22:54:21 +02:00
|
|
|
{
|
2010-02-19 22:55:57 +01:00
|
|
|
my_error(ER_OPERAND_COLUMNS, MYF(0), cols_num);
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
2003-10-23 22:54:21 +02:00
|
|
|
}
|
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
/*
|
|
|
|
Wrap the current IN predicate in an Item_in_optimizer. The actual
|
|
|
|
substitution in the Item tree takes place in Item_subselect::fix_fields.
|
|
|
|
*/
|
2003-05-14 20:51:33 +02:00
|
|
|
if (!substitution)
|
2002-12-19 20:15:09 +01:00
|
|
|
{
|
2003-05-14 20:51:33 +02:00
|
|
|
//first call for this unit
|
2006-12-14 23:51:37 +01:00
|
|
|
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
|
2005-03-10 13:01:22 +01:00
|
|
|
substitution= optimizer;
|
2003-05-14 20:51:33 +02:00
|
|
|
|
2008-02-13 20:27:12 +01:00
|
|
|
SELECT_LEX *current= thd->lex->current_select;
|
|
|
|
thd->lex->current_select= current->return_after_parsing();
|
2003-05-14 20:51:33 +02:00
|
|
|
//optimizer never use Item **ref => we can pass 0 as parameter
|
2005-07-01 06:05:42 +02:00
|
|
|
if (!optimizer || optimizer->fix_left(thd, 0))
|
2002-12-25 11:03:08 +01:00
|
|
|
{
|
2004-02-08 19:14:13 +01:00
|
|
|
thd->lex->current_select= current;
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
2002-12-25 11:03:08 +01:00
|
|
|
}
|
2004-02-12 02:10:26 +01:00
|
|
|
|
2005-02-08 23:50:45 +01:00
|
|
|
// we will refer to upper level cache array => we have to save it in PS
|
2004-02-12 02:10:26 +01:00
|
|
|
optimizer->keep_top_level_cache();
|
|
|
|
|
2004-02-08 19:14:13 +01:00
|
|
|
thd->lex->current_select= current;
|
2006-12-14 23:51:37 +01:00
|
|
|
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
|
2010-09-05 17:43:47 +02:00
|
|
|
//select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
|
2003-05-14 20:51:33 +02:00
|
|
|
}
|
|
|
|
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_RETURN(RES_OK);
|
2010-01-28 14:48:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Tranform a (possibly non-correlated) IN subquery into a correlated EXISTS.
|
|
|
|
|
|
|
|
@todo
|
|
|
|
The IF-ELSE below can be refactored so that there is no duplication of the
|
|
|
|
statements that create the new conditions. For this we have to invert the IF
|
|
|
|
and the FOR statements as this:
|
|
|
|
for (each left operand)
|
|
|
|
create the equi-join condition
|
|
|
|
if (is_having_used || !abort_on_null)
|
|
|
|
create the "is null" and is_not_null_test items
|
|
|
|
if (is_having_used)
|
|
|
|
add the equi-join and the null tests to HAVING
|
|
|
|
else
|
|
|
|
add the equi-join and the "is null" to WHERE
|
|
|
|
add the is_not_null_test to HAVING
|
|
|
|
*/
|
2010-07-18 14:59:24 +02:00
|
|
|
|
|
|
|
Item_subselect::trans_res
|
2010-09-05 17:43:47 +02:00
|
|
|
Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
|
|
|
|
Item **where_item,
|
|
|
|
Item **having_item)
|
2010-01-28 14:48:33 +01:00
|
|
|
{
|
|
|
|
SELECT_LEX *select_lex= join->select_lex;
|
|
|
|
uint cols_num= left_expr->cols();
|
2010-09-05 17:43:47 +02:00
|
|
|
/*
|
|
|
|
The non-transformed HAVING clause of 'join' may be stored differently in
|
|
|
|
JOIN::optimize:
|
|
|
|
this->tmp_having= this->having
|
|
|
|
this->having= 0;
|
|
|
|
*/
|
|
|
|
Item* join_having= join->having ? join->having : join->tmp_having;
|
|
|
|
bool is_having_used= (join_having || select_lex->with_sum_func ||
|
2010-01-28 14:48:33 +01:00
|
|
|
select_lex->group_list.first ||
|
|
|
|
!select_lex->table_list.elements);
|
|
|
|
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_ENTER("Item_in_subselect::create_row_in_to_exists_cond");
|
2010-07-18 14:59:24 +02:00
|
|
|
|
|
|
|
*where_item= NULL;
|
|
|
|
*having_item= NULL;
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2005-08-13 06:45:14 +02:00
|
|
|
if (is_having_used)
|
2004-02-08 19:14:13 +01:00
|
|
|
{
|
2005-08-13 06:45:14 +02:00
|
|
|
/*
|
|
|
|
(l1, l2, l3) IN (SELECT v1, v2, v3 ... HAVING having) =>
|
|
|
|
EXISTS (SELECT ... HAVING having and
|
|
|
|
(l1 = v1 or is null v1) and
|
|
|
|
(l2 = v2 or is null v2) and
|
|
|
|
(l3 = v3 or is null v3) and
|
|
|
|
is_not_null_test(v1) and
|
|
|
|
is_not_null_test(v2) and
|
|
|
|
is_not_null_test(v3))
|
|
|
|
where is_not_null_test used to register nulls in case if we have
|
|
|
|
not found matching to return correct NULL value
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
TODO: say here explicitly if the order of AND parts matters or not.
|
2005-08-13 06:45:14 +02:00
|
|
|
*/
|
|
|
|
Item *item_having_part2= 0;
|
|
|
|
for (uint i= 0; i < cols_num; i++)
|
2004-02-08 19:14:13 +01:00
|
|
|
{
|
2009-01-31 22:22:44 +01:00
|
|
|
DBUG_ASSERT((left_expr->fixed &&
|
2010-07-18 14:59:24 +02:00
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
select_lex->ref_pointer_array[i]->fixed) ||
|
2008-03-14 20:11:59 +01:00
|
|
|
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
|
|
|
|
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
|
|
|
|
Item_ref::OUTER_REF));
|
2005-01-24 14:56:57 +01:00
|
|
|
if (select_lex->ref_pointer_array[i]->
|
2006-12-14 23:51:37 +01:00
|
|
|
check_cols(left_expr->element_index(i)->cols()))
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
2005-08-13 06:45:14 +02:00
|
|
|
Item *item_eq=
|
|
|
|
new Item_func_eq(new
|
2006-08-24 18:56:28 +02:00
|
|
|
Item_ref(&select_lex->context,
|
|
|
|
(*optimizer->get_cache())->
|
|
|
|
addr(i),
|
|
|
|
(char *)"<no matter>",
|
|
|
|
(char *)in_left_expr_name),
|
2005-08-13 06:45:14 +02:00
|
|
|
new
|
2006-08-24 18:56:28 +02:00
|
|
|
Item_ref(&select_lex->context,
|
|
|
|
select_lex->ref_pointer_array + i,
|
|
|
|
(char *)"<no matter>",
|
|
|
|
(char *)"<list ref>")
|
2005-08-13 06:45:14 +02:00
|
|
|
);
|
|
|
|
Item *item_isnull=
|
|
|
|
new Item_func_isnull(new
|
2006-08-24 18:56:28 +02:00
|
|
|
Item_ref(&select_lex->context,
|
|
|
|
select_lex->ref_pointer_array+i,
|
|
|
|
(char *)"<no matter>",
|
|
|
|
(char *)"<list ref>")
|
2005-08-13 06:45:14 +02:00
|
|
|
);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
Item *col_item= new Item_cond_or(item_eq, item_isnull);
|
2007-01-29 15:13:18 +01:00
|
|
|
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
{
|
|
|
|
if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
}
|
2010-07-18 14:59:24 +02:00
|
|
|
*having_item= and_items(*having_item, col_item);
|
|
|
|
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
Item *item_nnull_test=
|
|
|
|
new Item_is_not_null_test(this,
|
|
|
|
new Item_ref(&select_lex->context,
|
|
|
|
select_lex->
|
|
|
|
ref_pointer_array + i,
|
|
|
|
(char *)"<no matter>",
|
|
|
|
(char *)"<list ref>"));
|
2007-01-29 15:13:18 +01:00
|
|
|
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
{
|
|
|
|
if (!(item_nnull_test=
|
|
|
|
new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
}
|
|
|
|
item_having_part2= and_items(item_having_part2, item_nnull_test);
|
2005-08-13 06:45:14 +02:00
|
|
|
item_having_part2->top_level_item();
|
2004-02-08 19:14:13 +01:00
|
|
|
}
|
2010-07-18 14:59:24 +02:00
|
|
|
*having_item= and_items(*having_item, item_having_part2);
|
|
|
|
(*having_item)->top_level_item();
|
2003-05-14 20:51:33 +02:00
|
|
|
}
|
2005-08-13 06:45:14 +02:00
|
|
|
else
|
2003-05-14 20:51:33 +02:00
|
|
|
{
|
2004-02-18 21:14:41 +01:00
|
|
|
/*
|
2005-08-13 06:45:14 +02:00
|
|
|
(l1, l2, l3) IN (SELECT v1, v2, v3 ... WHERE where) =>
|
|
|
|
EXISTS (SELECT ... WHERE where and
|
|
|
|
(l1 = v1 or is null v1) and
|
|
|
|
(l2 = v2 or is null v2) and
|
|
|
|
(l3 = v3 or is null v3)
|
|
|
|
HAVING is_not_null_test(v1) and
|
|
|
|
is_not_null_test(v2) and
|
|
|
|
is_not_null_test(v3))
|
|
|
|
where is_not_null_test register NULLs values but reject rows
|
|
|
|
|
|
|
|
in case when we do not need correct NULL, we have simplier construction:
|
|
|
|
EXISTS (SELECT ... WHERE where and
|
|
|
|
(l1 = v1) and
|
|
|
|
(l2 = v2) and
|
|
|
|
(l3 = v3)
|
2004-02-18 21:14:41 +01:00
|
|
|
*/
|
2005-08-13 06:45:14 +02:00
|
|
|
for (uint i= 0; i < cols_num; i++)
|
|
|
|
{
|
|
|
|
Item *item, *item_isnull;
|
2009-01-31 22:22:44 +01:00
|
|
|
DBUG_ASSERT((left_expr->fixed &&
|
2010-01-28 14:48:33 +01:00
|
|
|
select_lex->ref_pointer_array[i]->fixed) ||
|
2008-03-14 20:11:59 +01:00
|
|
|
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
|
|
|
|
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
|
|
|
|
Item_ref::OUTER_REF));
|
2005-08-13 06:45:14 +02:00
|
|
|
if (select_lex->ref_pointer_array[i]->
|
2006-12-14 23:51:37 +01:00
|
|
|
check_cols(left_expr->element_index(i)->cols()))
|
2005-08-13 06:45:14 +02:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
item=
|
|
|
|
new Item_func_eq(new
|
2005-08-13 10:15:17 +02:00
|
|
|
Item_direct_ref(&select_lex->context,
|
|
|
|
(*optimizer->get_cache())->
|
2005-08-13 06:45:14 +02:00
|
|
|
addr(i),
|
|
|
|
(char *)"<no matter>",
|
|
|
|
(char *)in_left_expr_name),
|
|
|
|
new
|
2005-08-13 10:15:17 +02:00
|
|
|
Item_direct_ref(&select_lex->context,
|
|
|
|
select_lex->
|
|
|
|
ref_pointer_array+i,
|
|
|
|
(char *)"<no matter>",
|
|
|
|
(char *)"<list ref>")
|
2005-08-13 06:45:14 +02:00
|
|
|
);
|
|
|
|
if (!abort_on_null)
|
|
|
|
{
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
Item *having_col_item=
|
|
|
|
new Item_is_not_null_test(this,
|
|
|
|
new
|
|
|
|
Item_ref(&select_lex->context,
|
|
|
|
select_lex->ref_pointer_array + i,
|
|
|
|
(char *)"<no matter>",
|
|
|
|
(char *)"<list ref>"));
|
|
|
|
|
|
|
|
|
2005-08-13 06:45:14 +02:00
|
|
|
item_isnull= new
|
|
|
|
Item_func_isnull(new
|
2005-08-13 10:15:17 +02:00
|
|
|
Item_direct_ref(&select_lex->context,
|
|
|
|
select_lex->
|
|
|
|
ref_pointer_array+i,
|
|
|
|
(char *)"<no matter>",
|
|
|
|
(char *)"<list ref>")
|
2005-08-13 06:45:14 +02:00
|
|
|
);
|
|
|
|
item= new Item_cond_or(item, item_isnull);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
/*
|
|
|
|
TODO: why we create the above for cases where the right part
|
|
|
|
cant be NULL?
|
|
|
|
*/
|
2007-01-29 15:13:18 +01:00
|
|
|
if (left_expr->element_index(i)->maybe_null)
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
{
|
|
|
|
if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
if (!(having_col_item=
|
|
|
|
new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
}
|
2010-07-18 14:59:24 +02:00
|
|
|
*having_item= and_items(*having_item, having_col_item);
|
2005-08-13 06:45:14 +02:00
|
|
|
}
|
2010-07-18 14:59:24 +02:00
|
|
|
*where_item= and_items(*where_item, item);
|
2005-08-13 06:45:14 +02:00
|
|
|
}
|
2010-07-18 14:59:24 +02:00
|
|
|
(*where_item)->fix_fields(thd, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DBUG_RETURN(RES_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Item_subselect::trans_res
|
2010-09-05 17:43:47 +02:00
|
|
|
Item_in_subselect::inject_row_in_to_exists_cond(JOIN * join,
|
|
|
|
Item *where_item,
|
|
|
|
Item *having_item)
|
2010-07-18 14:59:24 +02:00
|
|
|
{
|
|
|
|
SELECT_LEX *select_lex= join->select_lex;
|
2010-09-05 17:43:47 +02:00
|
|
|
/*
|
|
|
|
The non-transformed HAVING clause of 'join' may be stored differently in
|
|
|
|
JOIN::optimize:
|
|
|
|
this->tmp_having= this->having
|
|
|
|
this->having= 0;
|
|
|
|
*/
|
|
|
|
Item* join_having= join->having ? join->having : join->tmp_having;
|
|
|
|
bool is_having_used= (join_having || select_lex->with_sum_func ||
|
2010-07-18 14:59:24 +02:00
|
|
|
select_lex->group_list.first ||
|
|
|
|
!select_lex->table_list.elements);
|
|
|
|
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_ENTER("Item_in_subselect::inject_row_in_to_exists_cond");
|
2010-07-18 14:59:24 +02:00
|
|
|
|
|
|
|
if (!is_having_used)
|
|
|
|
{
|
2005-02-08 23:50:45 +01:00
|
|
|
/*
|
2004-02-18 21:14:41 +01:00
|
|
|
AND can't be changed during fix_fields()
|
2005-08-13 06:45:14 +02:00
|
|
|
we can assign select_lex->where here, and pass 0 as last
|
2004-02-18 21:14:41 +01:00
|
|
|
argument (reference) to fix_fields()
|
2005-02-08 23:50:45 +01:00
|
|
|
*/
|
2010-09-05 17:43:47 +02:00
|
|
|
thd->change_item_tree(&select_lex->where, and_items(join->conds, where_item));
|
|
|
|
join->conds= select_lex->where;
|
2005-08-13 06:45:14 +02:00
|
|
|
select_lex->where->top_level_item();
|
2010-07-18 14:59:24 +02:00
|
|
|
if (!join->conds->fixed && join->conds->fix_fields(thd, 0))
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
2002-12-19 20:15:09 +01:00
|
|
|
}
|
2010-07-18 14:59:24 +02:00
|
|
|
|
2005-08-13 06:45:14 +02:00
|
|
|
if (having_item)
|
2003-05-14 20:51:33 +02:00
|
|
|
{
|
2005-08-13 06:45:14 +02:00
|
|
|
bool res;
|
2010-09-05 17:43:47 +02:00
|
|
|
thd->change_item_tree(&select_lex->having,
|
|
|
|
and_items(join_having, having_item));
|
|
|
|
join->having= select_lex->having;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (having_item == select_lex->having)
|
|
|
|
having_item->name= (char*)in_having_cond;
|
2005-08-13 06:45:14 +02:00
|
|
|
select_lex->having->top_level_item();
|
2004-02-18 21:14:41 +01:00
|
|
|
/*
|
|
|
|
AND can't be changed during fix_fields()
|
|
|
|
we can assign select_lex->having here, and pass 0 as last
|
|
|
|
argument (reference) to fix_fields()
|
|
|
|
*/
|
2005-08-13 06:45:14 +02:00
|
|
|
select_lex->having_fix_field= 1;
|
2010-07-18 14:59:24 +02:00
|
|
|
if (!join->having->fixed)
|
|
|
|
res= join->having->fix_fields(thd, 0);
|
2005-08-13 06:45:14 +02:00
|
|
|
select_lex->having_fix_field= 0;
|
|
|
|
if (res)
|
2005-03-10 13:01:22 +01:00
|
|
|
DBUG_RETURN(RES_ERROR);
|
2003-05-14 20:51:33 +02:00
|
|
|
}
|
2004-02-08 19:14:13 +01:00
|
|
|
|
2003-08-28 12:21:30 +02:00
|
|
|
DBUG_RETURN(RES_OK);
|
2002-12-19 20:15:09 +01:00
|
|
|
}
|
|
|
|
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2003-05-14 20:51:33 +02:00
|
|
|
Item_subselect::trans_res
|
2003-07-02 00:45:22 +02:00
|
|
|
Item_in_subselect::select_transformer(JOIN *join)
|
2002-11-07 22:45:19 +01:00
|
|
|
{
|
2010-09-05 17:43:47 +02:00
|
|
|
return select_in_like_transformer(join);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Item_in_subselect::create_in_to_exists_cond(JOIN *join_arg)
|
|
|
|
{
|
|
|
|
Item_subselect::trans_res res;
|
|
|
|
|
|
|
|
DBUG_ASSERT(engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE ||
|
|
|
|
engine->engine_type() == subselect_engine::UNION_ENGINE);
|
|
|
|
/*
|
|
|
|
TIMOUR TODO: the call to init_cond_guards allocates and initializes an
|
|
|
|
array of booleans that may not be used later because we may choose
|
|
|
|
materialization.
|
|
|
|
The two calls below to create_XYZ_cond depend on this boolean array.
|
|
|
|
This dependency can be easily removed, and the call moved to a later
|
|
|
|
phase.
|
|
|
|
*/
|
|
|
|
init_cond_guards();
|
|
|
|
join_arg->select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
|
|
|
|
if (left_expr->cols() == 1)
|
|
|
|
res= create_single_in_to_exists_cond(join_arg,
|
|
|
|
&(join_arg->in_to_exists_where),
|
|
|
|
&(join_arg->in_to_exists_having));
|
|
|
|
else
|
|
|
|
res= create_row_in_to_exists_cond(join_arg,
|
|
|
|
&(join_arg->in_to_exists_where),
|
|
|
|
&(join_arg->in_to_exists_having));
|
|
|
|
return (res != RES_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Item_in_subselect::inject_in_to_exists_cond(JOIN * join_arg)
|
|
|
|
{
|
|
|
|
Item_subselect::trans_res res;
|
|
|
|
|
|
|
|
if (left_expr->cols() == 1)
|
|
|
|
res= inject_single_in_to_exists_cond(join_arg,
|
|
|
|
join_arg->in_to_exists_where,
|
|
|
|
join_arg->in_to_exists_having);
|
|
|
|
else
|
|
|
|
res= inject_row_in_to_exists_cond(join_arg,
|
|
|
|
join_arg->in_to_exists_where,
|
|
|
|
join_arg->in_to_exists_having);
|
|
|
|
|
|
|
|
return (res != RES_OK && res != RES_REDUCE);
|
2005-03-10 13:01:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
2005-03-10 13:01:22 +01:00
|
|
|
Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
|
2007-10-11 19:29:09 +02:00
|
|
|
transformation function.
|
2005-03-10 13:01:22 +01:00
|
|
|
|
|
|
|
To decide which transformation procedure (scalar or row) applicable here
|
|
|
|
we have to call fix_fields() for left expression to be able to call
|
|
|
|
cols() method on it. Also this method make arena management for
|
|
|
|
underlying transformation methods.
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@param join JOIN object of transforming subquery
|
|
|
|
@param func creator of condition function of subquery
|
|
|
|
|
|
|
|
@retval
|
2005-03-10 13:01:22 +01:00
|
|
|
RES_OK OK
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
|
|
|
RES_REDUCE OK, and current subquery was reduced during
|
|
|
|
transformation
|
|
|
|
@retval
|
2005-03-10 13:01:22 +01:00
|
|
|
RES_ERROR Error
|
|
|
|
*/
|
|
|
|
|
|
|
|
Item_subselect::trans_res
|
2010-09-05 17:43:47 +02:00
|
|
|
Item_in_subselect::select_in_like_transformer(JOIN *join)
|
2005-03-10 13:01:22 +01:00
|
|
|
{
|
2005-06-15 19:58:35 +02:00
|
|
|
Query_arena *arena, backup;
|
2008-02-13 20:27:12 +01:00
|
|
|
SELECT_LEX *current= thd->lex->current_select;
|
2005-03-10 13:01:22 +01:00
|
|
|
const char *save_where= thd->where;
|
|
|
|
Item_subselect::trans_res res= RES_ERROR;
|
|
|
|
bool result;
|
|
|
|
|
|
|
|
DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
|
2005-03-30 09:07:08 +02:00
|
|
|
|
2008-03-27 17:49:32 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
|
|
|
|
ORDER BY clause becomes meaningless thus we drop it here.
|
|
|
|
*/
|
|
|
|
SELECT_LEX *sl= current->master_unit()->first_select();
|
|
|
|
for (; sl; sl= sl->next_select())
|
|
|
|
{
|
|
|
|
if (sl->join)
|
|
|
|
sl->join->order= 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-10 13:01:22 +01:00
|
|
|
if (changed)
|
|
|
|
DBUG_RETURN(RES_OK);
|
|
|
|
|
|
|
|
thd->where= "IN/ALL/ANY subquery";
|
|
|
|
|
|
|
|
/*
|
|
|
|
In some optimisation cases we will not need this Item_in_optimizer
|
|
|
|
object, but we can't know it here, but here we need address correct
|
|
|
|
reference on left expresion.
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-02-15 22:53:06 +01:00
|
|
|
//psergey: he means degenerate cases like "... IN (SELECT 1)"
|
2005-03-10 13:01:22 +01:00
|
|
|
*/
|
|
|
|
if (!optimizer)
|
|
|
|
{
|
2005-09-02 15:21:19 +02:00
|
|
|
arena= thd->activate_stmt_arena_if_needed(&backup);
|
2005-03-10 13:01:22 +01:00
|
|
|
result= (!(optimizer= new Item_in_optimizer(left_expr, this)));
|
|
|
|
if (arena)
|
2005-09-02 15:21:19 +02:00
|
|
|
thd->restore_active_arena(arena, &backup);
|
2005-03-10 13:01:22 +01:00
|
|
|
if (result)
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2008-02-13 20:27:12 +01:00
|
|
|
thd->lex->current_select= current->return_after_parsing();
|
2005-03-10 13:01:22 +01:00
|
|
|
result= (!left_expr->fixed &&
|
2005-07-01 06:05:42 +02:00
|
|
|
left_expr->fix_fields(thd, optimizer->arguments()));
|
2005-03-10 13:01:22 +01:00
|
|
|
/* fix_fields can change reference to left_expr, we need reassign it */
|
|
|
|
left_expr= optimizer->arguments()[0];
|
|
|
|
|
|
|
|
thd->lex->current_select= current;
|
|
|
|
if (result)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Both transformers call fix_fields() only for Items created inside them,
|
|
|
|
and all that items do not make permanent changes in current item arena
|
|
|
|
which allow to us call them with changed arena (if we do not know nature
|
|
|
|
of Item, we have to call fix_fields() for it only with original arena to
|
|
|
|
avoid memory leack)
|
|
|
|
*/
|
2010-09-05 17:43:47 +02:00
|
|
|
arena= thd->activate_stmt_arena_if_needed(&backup);
|
2002-12-19 20:15:09 +01:00
|
|
|
if (left_expr->cols() == 1)
|
2010-09-05 17:43:47 +02:00
|
|
|
res= single_value_transformer(join);
|
2005-03-10 13:01:22 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* we do not support row operation for ALL/ANY/SOME */
|
|
|
|
if (func != &eq_creator)
|
|
|
|
{
|
2005-03-30 09:07:08 +02:00
|
|
|
if (arena)
|
2005-09-02 15:21:19 +02:00
|
|
|
thd->restore_active_arena(arena, &backup);
|
2005-03-10 13:01:22 +01:00
|
|
|
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
|
|
|
|
DBUG_RETURN(RES_ERROR);
|
|
|
|
}
|
|
|
|
res= row_value_transformer(join);
|
|
|
|
}
|
|
|
|
if (arena)
|
2005-09-02 15:21:19 +02:00
|
|
|
thd->restore_active_arena(arena, &backup);
|
2005-03-10 13:01:22 +01:00
|
|
|
err:
|
|
|
|
thd->where= save_where;
|
|
|
|
DBUG_RETURN(res);
|
2002-11-07 22:45:19 +01:00
|
|
|
}
|
|
|
|
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_in_subselect::print(String *str, enum_query_type query_type)
|
2003-10-16 14:54:47 +02:00
|
|
|
{
|
2010-01-28 14:48:33 +01:00
|
|
|
if (exec_method == IN_TO_EXISTS)
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN("<exists>"));
|
2003-10-16 14:54:47 +02:00
|
|
|
else
|
|
|
|
{
|
2008-02-22 11:30:33 +01:00
|
|
|
left_expr->print(str, query_type);
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" in "));
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
2008-02-22 11:30:33 +01:00
|
|
|
Item_subselect::print(str, query_type);
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-14 23:51:37 +01:00
|
|
|
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
|
2006-05-11 14:30:54 +02:00
|
|
|
{
|
2010-02-19 22:55:57 +01:00
|
|
|
uint outer_cols_num;
|
|
|
|
List<Item> *inner_cols;
|
2010-01-28 14:48:33 +01:00
|
|
|
|
|
|
|
if (exec_method == SEMI_JOIN)
|
|
|
|
return !( (*ref)= new Item_int(1));
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
|
|
|
Check if the outer and inner IN operands match in those cases when we
|
|
|
|
will not perform IN=>EXISTS transformation. Currently this is when we
|
|
|
|
use subquery materialization.
|
|
|
|
|
|
|
|
The condition below is true when this method was called recursively from
|
|
|
|
inside JOIN::prepare for the JOIN object created by the call chain
|
|
|
|
Item_subselect::fix_fields -> subselect_single_select_engine::prepare,
|
|
|
|
which creates a JOIN object for the subquery and calls JOIN::prepare for
|
|
|
|
the JOIN of the subquery.
|
|
|
|
Notice that in some cases, this doesn't happen, and the check_cols()
|
|
|
|
test for each Item happens later in
|
|
|
|
Item_in_subselect::row_value_in_to_exists_transformer.
|
|
|
|
The reason for this mess is that our JOIN::prepare phase works top-down
|
|
|
|
instead of bottom-up, so we first do name resoluton and semantic checks
|
|
|
|
for the outer selects, then for the inner.
|
|
|
|
*/
|
|
|
|
if (engine &&
|
|
|
|
engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE &&
|
|
|
|
((subselect_single_select_engine*)engine)->join)
|
|
|
|
{
|
|
|
|
outer_cols_num= left_expr->cols();
|
|
|
|
|
|
|
|
if (unit->is_union())
|
|
|
|
inner_cols= &(unit->types);
|
|
|
|
else
|
|
|
|
inner_cols= &(unit->first_select()->item_list);
|
|
|
|
if (outer_cols_num != inner_cols->elements)
|
|
|
|
{
|
|
|
|
my_error(ER_OPERAND_COLUMNS, MYF(0), outer_cols_num);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
if (outer_cols_num > 1)
|
|
|
|
{
|
|
|
|
List_iterator<Item> inner_col_it(*inner_cols);
|
|
|
|
Item *inner_col;
|
|
|
|
for (uint i= 0; i < outer_cols_num; i++)
|
|
|
|
{
|
|
|
|
inner_col= inner_col_it++;
|
|
|
|
if (inner_col->check_cols(left_expr->element_index(i)->cols()))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (thd_arg->lex->view_prepare_mode && left_expr && !left_expr->fixed &&
|
|
|
|
left_expr->fix_fields(thd_arg, &left_expr))
|
|
|
|
return TRUE;
|
|
|
|
if (Item_subselect::fix_fields(thd_arg, ref))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
fixed= TRUE;
|
2006-05-11 14:30:54 +02:00
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
return FALSE;
|
2006-05-11 14:30:54 +02:00
|
|
|
}
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
|
2010-02-12 00:59:58 +01:00
|
|
|
void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
|
|
|
{
|
|
|
|
left_expr->fix_after_pullout(new_parent, &left_expr);
|
|
|
|
Item_subselect::fix_after_pullout(new_parent, ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Item_in_subselect::update_used_tables()
|
|
|
|
{
|
|
|
|
Item_subselect::update_used_tables();
|
|
|
|
left_expr->update_used_tables();
|
|
|
|
used_tables_cache |= left_expr->used_tables();
|
|
|
|
}
|
2006-05-11 14:30:54 +02:00
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
/**
|
|
|
|
Try to create an engine to compute the subselect via materialization,
|
|
|
|
and if this fails, revert to execution via the IN=>EXISTS transformation.
|
|
|
|
|
|
|
|
@details
|
|
|
|
The purpose of this method is to hide the implementation details
|
|
|
|
of this Item's execution. The method creates a new engine for
|
|
|
|
materialized execution, and initializes the engine.
|
|
|
|
|
|
|
|
If this initialization fails
|
|
|
|
- either because it wasn't possible to create the needed temporary table
|
|
|
|
and its index,
|
|
|
|
- or because of a memory allocation error,
|
|
|
|
then we revert back to execution via the IN=>EXISTS tranformation.
|
|
|
|
|
|
|
|
The initialization of the new engine is divided in two parts - a permanent
|
|
|
|
one that lives across prepared statements, and one that is repeated for each
|
|
|
|
execution.
|
|
|
|
|
|
|
|
@returns
|
|
|
|
@retval TRUE memory allocation error occurred
|
|
|
|
@retval FALSE an execution method was chosen successfully
|
|
|
|
*/
|
|
|
|
|
2010-09-05 17:43:47 +02:00
|
|
|
bool Item_in_subselect::setup_mat_engine()
|
2010-01-28 14:48:33 +01:00
|
|
|
{
|
2010-07-16 12:52:02 +02:00
|
|
|
subselect_hash_sj_engine *mat_engine= NULL;
|
|
|
|
subselect_single_select_engine *select_engine;
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_ENTER("Item_in_subselect::setup_mat_engine");
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-07-16 12:52:02 +02:00
|
|
|
/*
|
|
|
|
The select_engine (that executes transformed IN=>EXISTS subselects) is
|
|
|
|
pre-created at parse time, and is stored in statment memory (preserved
|
|
|
|
across PS executions).
|
|
|
|
*/
|
|
|
|
DBUG_ASSERT(engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE);
|
|
|
|
select_engine= (subselect_single_select_engine*) engine;
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-07-16 12:52:02 +02:00
|
|
|
/* Create/initialize execution objects. */
|
|
|
|
if (!(mat_engine= new subselect_hash_sj_engine(thd, this, select_engine)))
|
|
|
|
DBUG_RETURN(TRUE);
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-07-16 12:52:02 +02:00
|
|
|
if (mat_engine->init(&select_engine->join->fields_list))
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_RETURN(TRUE);
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-07-16 12:52:02 +02:00
|
|
|
engine= mat_engine;
|
|
|
|
DBUG_RETURN(FALSE);
|
2010-01-28 14:48:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Initialize the cache of the left operand of the IN predicate.
|
|
|
|
|
|
|
|
@note This method has the same purpose as alloc_group_fields(),
|
|
|
|
but it takes a different kind of collection of items, and the
|
|
|
|
list we push to is dynamically allocated.
|
|
|
|
|
|
|
|
@retval TRUE if a memory allocation error occurred or the cache is
|
|
|
|
not applicable to the current query
|
|
|
|
@retval FALSE if success
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Item_in_subselect::init_left_expr_cache()
|
|
|
|
{
|
|
|
|
JOIN *outer_join;
|
|
|
|
|
|
|
|
outer_join= unit->outer_select()->join;
|
|
|
|
/*
|
|
|
|
An IN predicate might be evaluated in a query for which all tables have
|
|
|
|
been optimzied away.
|
|
|
|
*/
|
|
|
|
if (!outer_join || !outer_join->tables || !outer_join->tables_list)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (!(left_expr_cache= new List<Cached_item>))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
for (uint i= 0; i < left_expr->cols(); i++)
|
|
|
|
{
|
|
|
|
Cached_item *cur_item_cache= new_Cached_item(thd,
|
|
|
|
left_expr->element_index(i),
|
2010-07-06 17:16:24 +02:00
|
|
|
FALSE);
|
2010-01-28 14:48:33 +01:00
|
|
|
if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-05 17:43:47 +02:00
|
|
|
bool Item_in_subselect::init_cond_guards()
|
|
|
|
{
|
|
|
|
uint cols_num= left_expr->cols();
|
|
|
|
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
|
|
|
|
{
|
|
|
|
if (!(pushed_cond_guards= (bool*)thd->alloc(sizeof(bool) * cols_num)))
|
|
|
|
return TRUE;
|
|
|
|
for (uint i= 0; i < cols_num; i++)
|
|
|
|
pushed_cond_guards[i]= TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
/*
|
|
|
|
Callback to test if an IN predicate is expensive.
|
|
|
|
|
|
|
|
@details
|
|
|
|
IN predicates are considered expensive only if they will be executed via
|
|
|
|
materialization. The return value affects the behavior of
|
|
|
|
make_cond_for_table() in such a way that it is unchanged when we use
|
|
|
|
the IN=>EXISTS transformation to compute IN.
|
|
|
|
|
|
|
|
@retval TRUE if the predicate is expensive
|
|
|
|
@retval FALSE otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Item_in_subselect::is_expensive_processor(uchar *arg)
|
|
|
|
{
|
2010-09-05 17:43:47 +02:00
|
|
|
return TRUE; // exec_method == MATERIALIZATION;
|
2010-01-28 14:48:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-05-14 20:51:33 +02:00
|
|
|
Item_subselect::trans_res
|
2003-07-02 00:45:22 +02:00
|
|
|
Item_allany_subselect::select_transformer(JOIN *join)
|
2002-11-07 22:45:19 +01:00
|
|
|
{
|
2010-01-28 14:48:33 +01:00
|
|
|
DBUG_ENTER("Item_allany_subselect::select_transformer");
|
2010-01-17 15:51:10 +01:00
|
|
|
exec_method= IN_TO_EXISTS;
|
2004-11-18 17:10:07 +01:00
|
|
|
if (upper_item)
|
|
|
|
upper_item->show= 1;
|
2010-09-05 17:43:47 +02:00
|
|
|
DBUG_RETURN(select_in_like_transformer(join));
|
2002-11-07 22:45:19 +01:00
|
|
|
}
|
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void Item_allany_subselect::print(String *str, enum_query_type query_type)
|
2003-10-16 14:54:47 +02:00
|
|
|
{
|
2010-01-28 14:48:33 +01:00
|
|
|
if (exec_method == IN_TO_EXISTS)
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN("<exists>"));
|
2003-10-16 14:54:47 +02:00
|
|
|
else
|
|
|
|
{
|
2008-02-22 11:30:33 +01:00
|
|
|
left_expr->print(str, query_type);
|
2003-10-16 14:54:47 +02:00
|
|
|
str->append(' ');
|
2003-11-03 11:28:36 +01:00
|
|
|
str->append(func->symbol(all));
|
|
|
|
str->append(all ? " all " : " any ", 5);
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
2008-02-22 11:30:33 +01:00
|
|
|
Item_subselect::print(str, query_type);
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-09 22:23:56 +02:00
|
|
|
void subselect_engine::set_thd(THD *thd_arg)
|
|
|
|
{
|
|
|
|
thd= thd_arg;
|
|
|
|
if (result)
|
|
|
|
result->set_thd(thd_arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-24 14:26:21 +02:00
|
|
|
subselect_single_select_engine::
|
2003-10-02 21:19:41 +02:00
|
|
|
subselect_single_select_engine(st_select_lex *select,
|
2010-01-28 14:48:33 +01:00
|
|
|
select_result_interceptor *result_arg,
|
2006-12-14 23:51:37 +01:00
|
|
|
Item_subselect *item_arg)
|
|
|
|
:subselect_engine(item_arg, result_arg),
|
2010-01-28 14:48:33 +01:00
|
|
|
prepared(0), executed(0), select_lex(select), join(0)
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
2006-12-14 23:51:37 +01:00
|
|
|
select_lex->master_unit()->item= item_arg;
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
|
|
|
|
2010-03-29 16:04:35 +02:00
|
|
|
int subselect_single_select_engine::get_identifier()
|
|
|
|
{
|
|
|
|
return select_lex->select_number;
|
|
|
|
}
|
2004-02-08 19:14:13 +01:00
|
|
|
|
2003-12-30 11:08:19 +01:00
|
|
|
void subselect_single_select_engine::cleanup()
|
|
|
|
{
|
2004-02-08 19:14:13 +01:00
|
|
|
DBUG_ENTER("subselect_single_select_engine::cleanup");
|
2010-01-28 14:48:33 +01:00
|
|
|
prepared= executed= 0;
|
2004-02-12 02:10:26 +01:00
|
|
|
join= 0;
|
2005-01-26 14:27:45 +01:00
|
|
|
result->cleanup();
|
2004-02-08 19:14:13 +01:00
|
|
|
DBUG_VOID_RETURN;
|
2003-12-30 11:08:19 +01:00
|
|
|
}
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2004-02-08 19:14:13 +01:00
|
|
|
|
|
|
|
void subselect_union_engine::cleanup()
|
|
|
|
{
|
|
|
|
DBUG_ENTER("subselect_union_engine::cleanup");
|
|
|
|
unit->reinit_exec_mechanism();
|
2005-01-26 14:27:45 +01:00
|
|
|
result->cleanup();
|
2004-02-08 19:14:13 +01:00
|
|
|
DBUG_VOID_RETURN;
|
2003-12-30 11:08:19 +01:00
|
|
|
}
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2004-02-08 19:14:13 +01:00
|
|
|
|
2005-10-13 09:53:00 +02:00
|
|
|
bool subselect_union_engine::is_executed() const
|
|
|
|
{
|
|
|
|
return unit->executed;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
/*
|
|
|
|
Check if last execution of the subquery engine produced any rows
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
subselect_union_engine::no_rows()
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Check if last execution of the subquery engine produced any rows. The
|
|
|
|
return value is undefined if last execution ended in an error.
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
TRUE - Last subselect execution has produced no rows
|
|
|
|
FALSE - Otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool subselect_union_engine::no_rows()
|
|
|
|
{
|
|
|
|
/* Check if we got any rows when reading UNION result from temp. table: */
|
|
|
|
return test(!unit->fake_select_lex->join->send_records);
|
|
|
|
}
|
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2004-02-08 19:14:13 +01:00
|
|
|
void subselect_uniquesubquery_engine::cleanup()
|
|
|
|
{
|
|
|
|
DBUG_ENTER("subselect_uniquesubquery_engine::cleanup");
|
2010-02-19 22:55:57 +01:00
|
|
|
/* Tell handler we don't need the index anymore */
|
|
|
|
if (tab->table->file->inited)
|
|
|
|
tab->table->file->ha_index_end();
|
2004-02-08 19:14:13 +01:00
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-02 21:19:41 +02:00
|
|
|
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
|
2010-01-28 14:48:33 +01:00
|
|
|
select_result_interceptor *result_arg,
|
2003-11-28 11:18:13 +01:00
|
|
|
Item_subselect *item_arg)
|
|
|
|
:subselect_engine(item_arg, result_arg)
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
|
|
|
unit= u;
|
2003-11-28 11:18:13 +01:00
|
|
|
if (!result_arg) //out of memory
|
2003-10-02 21:19:41 +02:00
|
|
|
current_thd->fatal_error();
|
2003-11-28 11:18:13 +01:00
|
|
|
unit->item= item_arg;
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
|
|
|
|
2003-11-28 11:18:13 +01:00
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
/**
|
|
|
|
Create and prepare the JOIN object that represents the query execution
|
|
|
|
plan for the subquery.
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
@details
|
2010-01-28 14:48:33 +01:00
|
|
|
This method is called from Item_subselect::fix_fields. For prepared
|
|
|
|
statements it is called both during the PREPARE and EXECUTE phases in the
|
|
|
|
following ways:
|
|
|
|
- During PREPARE the optimizer needs some properties
|
|
|
|
(join->fields_list.elements) of the JOIN to proceed with preparation of
|
|
|
|
the remaining query (namely to complete ::fix_fields for the subselect
|
|
|
|
related classes. In the end of PREPARE the JOIN is deleted.
|
|
|
|
- When we EXECUTE the query, Item_subselect::fix_fields is called again, and
|
|
|
|
the JOIN object is re-created again, prepared and executed. In the end of
|
|
|
|
execution it is deleted.
|
|
|
|
In all cases the JOIN is created in runtime memory (not in the permanent
|
|
|
|
memory root).
|
|
|
|
|
|
|
|
@todo
|
|
|
|
Re-check what properties of 'join' are needed during prepare, and see if
|
|
|
|
we can avoid creating a JOIN during JOIN::prepare of the outer join.
|
|
|
|
|
|
|
|
@retval 0 if success
|
|
|
|
@retval 1 if error
|
|
|
|
*/
|
|
|
|
|
2002-09-03 08:50:36 +02:00
|
|
|
int subselect_single_select_engine::prepare()
|
|
|
|
{
|
2002-10-13 13:25:16 +02:00
|
|
|
if (prepared)
|
|
|
|
return 0;
|
2010-03-09 20:29:05 +01:00
|
|
|
if (select_lex->join)
|
|
|
|
{
|
|
|
|
select_lex->cleanup();
|
|
|
|
}
|
2003-12-10 21:46:14 +01:00
|
|
|
join= new JOIN(thd, select_lex->item_list,
|
|
|
|
select_lex->options | SELECT_NO_UNLOCK, result);
|
2003-10-02 21:19:41 +02:00
|
|
|
if (!join || !result)
|
|
|
|
{
|
2003-11-28 11:18:13 +01:00
|
|
|
thd->fatal_error(); //out of memory
|
2003-10-02 21:19:41 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2002-10-13 13:25:16 +02:00
|
|
|
prepared= 1;
|
2003-12-19 18:52:13 +01:00
|
|
|
SELECT_LEX *save_select= thd->lex->current_select;
|
|
|
|
thd->lex->current_select= select_lex;
|
2003-01-25 12:19:46 +01:00
|
|
|
if (join->prepare(&select_lex->ref_pointer_array,
|
|
|
|
(TABLE_LIST*) select_lex->table_list.first,
|
|
|
|
select_lex->with_wild,
|
2002-12-28 00:01:05 +01:00
|
|
|
select_lex->where,
|
2003-01-25 12:19:46 +01:00
|
|
|
select_lex->order_list.elements +
|
|
|
|
select_lex->group_list.elements,
|
2002-12-28 00:01:05 +01:00
|
|
|
(ORDER*) select_lex->order_list.first,
|
|
|
|
(ORDER*) select_lex->group_list.first,
|
|
|
|
select_lex->having,
|
2004-07-04 07:46:28 +02:00
|
|
|
(ORDER*) 0, select_lex,
|
2003-11-23 01:01:15 +01:00
|
|
|
select_lex->master_unit()))
|
2002-09-03 08:50:36 +02:00
|
|
|
return 1;
|
2003-12-19 18:52:13 +01:00
|
|
|
thd->lex->current_select= save_select;
|
2002-09-03 08:50:36 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int subselect_union_engine::prepare()
|
|
|
|
{
|
A fix and a test case for Bug#6513 "Test Suite: Values inserted by using
cursor is interpreted latin1 character and Bug#9819 "Cursors: Mysql Server
Crash while fetching from table with 5 million records."
A fix for a possible memory leak when fetching into an SP cursor
in a long loop.
The patch uses a common implementation of cursors in the binary protocol and
in stored procedures and implements materialized cursors.
For implementation details, see comments in sql_cursor.cc
include/my_sys.h:
- declaration for multi_alloc_root
libmysqld/Makefile.am:
- drop protocol_cursor.cc, add sql_cursor.cc (replaces the old
implementation of cursors with a new one)
mysql-test/r/ctype_ujis.result:
- test results fixed (a test case for Bug#6513)
mysql-test/r/sp-big.result:
- test results fixed (a test case for Bug#9819)
mysql-test/t/ctype_ujis.test:
Add a test case for Bug#6513 "Test Suite: Values inserted by using cursor is
interpreted latin1 character"
mysql-test/t/sp-big.test:
Add a restricted test case for Bug#9819 "Cursors: Mysql Server Crash
while fetching from table with 5 million records."
mysys/my_alloc.c:
- an implementation of multi_alloc_root; this is largely a copy-paste
from mulalloc.c, but the function is small and there is no easy way
to reuse the existing C function.
sql/Makefile.am:
- add sql_cursor.h, sql_cursor.cc (a new implementation of stored procedure
cursors) and drop protocol_cursor.cc (the old one)
sql/handler.cc:
- now TABLE object has its mem_root always initialized.
Adjust the implementation handler::ha_open
sql/item_subselect.cc:
- adjust to the changed declaration of st_select_lex_unit::prepare
sql/protocol.h:
- drop Protocol_cursor
sql/sp_head.cc:
- move juggling with Query_arena::free_list and Item::next to
sp_eval_func_item, as this is needed in 3 places already.
sql/sp_head.h:
- declare a no-op implementation for cleanup_stmt in sp_instr_cpush.
This method is needed for non-materializing cursors, which are yet not
used in stored procedures.
- declaration for sp_eval_func_item
sql/sp_rcontext.cc:
- reimplement sp_cursor using the new implementation of server side cursors.
- use sp_eval_func_item to assign values of SP variables from the
row fetched from a cursor. This should fix a possible memory leak in
the old implementation of sp_cursor::fetch
sql/sp_rcontext.h:
- reimplement sp_cursor using the new implementation of server side cursors.
sql/sql_class.cc:
- disable the functionality that closes transient cursors at commit/rollback;
transient cursors are not used in 5.0, instead we use materialized ones.
To be enabled in a later version.
sql/sql_class.h:
- adjust to the rename Cursor -> Server_side_cursor
- additional declarations of select_union used in materialized cursors
sql/sql_derived.cc:
- reuse bits of tmp table code in UNION, derived tables, and materialized
cursors
- cleanup comments
sql/sql_lex.h:
- declarations of auxiliary methods used by materialized cursors
- a cleanup in st_select_lex_unit interface
sql/sql_list.h:
- add an array operator new[] to class Sql_alloc
sql/sql_prepare.cc:
- split the tight coupling of cursors and prepared statements to reuse
the same implementation in stored procedures
- cleanups of error processing in Prepared_statement::{prepare,execute}
sql/sql_select.cc:
- move the implementation of sensitive (non-materializing) cursors to
sql_cursor.cc
- make temporary tables self-contained: the table, its record and fields
are allocated in TABLE::mem_root. This implementation is not clean
and resets thd->mem_root several times because of the way create_tmp_table
works (many additional things are done inside it).
- adjust to the changed declaration of st_select_lex_unit::prepare
sql/sql_select.h:
- move the declaration of sensitive (non-materializing) cursors to
sql_cursor.cc
sql/sql_union.cc:
- move pieces of st_select_unit::prepare to select_union and st_table
methods to be able to reuse code in the implementation of materialized
cursors
sql/sql_view.cc:
- adjust to the changed signature of st_select_lex_unit::prepare
sql/table.cc:
- implement auxiliary st_table methods for use with temporary tables
sql/table.h:
- add declarations for auxiliary methods of st_table used to work with
temporary tables
tests/mysql_client_test.c:
- if cursors are materialized, a parallel update of the table used
in the cursor may go through: update the test.
sql/sql_cursor.cc:
New BitKeeper file ``sql/sql_cursor.cc'' -- implementation of server side
cursors
sql/sql_cursor.h:
New BitKeeper file ``sql/sql_cursor.h'' - declarations for
server side cursors.
2005-09-22 00:11:21 +02:00
|
|
|
return unit->prepare(thd, result, SELECT_NO_UNLOCK);
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
|
|
|
|
2003-09-14 08:40:57 +02:00
|
|
|
int subselect_uniquesubquery_engine::prepare()
|
2003-07-07 17:40:19 +02:00
|
|
|
{
|
2010-01-28 14:48:33 +01:00
|
|
|
/* Should never be called. */
|
|
|
|
DBUG_ASSERT(FALSE);
|
2003-07-07 17:40:19 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Check if last execution of the subquery engine produced any rows
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
subselect_single_select_engine::no_rows()
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Check if last execution of the subquery engine produced any rows. The
|
|
|
|
return value is undefined if last execution ended in an error.
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
TRUE - Last subselect execution has produced no rows
|
|
|
|
FALSE - Otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool subselect_single_select_engine::no_rows()
|
|
|
|
{
|
|
|
|
return !item->assigned();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-07 17:16:17 +01:00
|
|
|
/*
|
|
|
|
makes storage for the output values for the subquery and calcuates
|
|
|
|
their data and column types and their nullability.
|
|
|
|
*/
|
|
|
|
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
|
2002-09-28 17:34:56 +02:00
|
|
|
{
|
2002-12-19 06:38:33 +01:00
|
|
|
Item *sel_item;
|
2003-11-23 01:01:15 +01:00
|
|
|
List_iterator_fast<Item> li(item_list);
|
2006-11-07 17:16:17 +01:00
|
|
|
res_type= STRING_RESULT;
|
2006-12-02 02:26:52 +01:00
|
|
|
res_field_type= MYSQL_TYPE_VAR_STRING;
|
2002-12-19 06:38:33 +01:00
|
|
|
for (uint i= 0; (sel_item= li++); i++)
|
|
|
|
{
|
|
|
|
item->max_length= sel_item->max_length;
|
|
|
|
res_type= sel_item->result_type();
|
2006-11-07 17:16:17 +01:00
|
|
|
res_field_type= sel_item->field_type();
|
2002-12-19 06:38:33 +01:00
|
|
|
item->decimals= sel_item->decimals;
|
2006-06-09 19:35:54 +02:00
|
|
|
item->unsigned_flag= sel_item->unsigned_flag;
|
2006-11-18 18:49:59 +01:00
|
|
|
maybe_null= sel_item->maybe_null;
|
2007-11-10 20:44:48 +01:00
|
|
|
if (!(row[i]= Item_cache::get_cache(sel_item)))
|
2006-11-07 17:16:17 +01:00
|
|
|
return;
|
2003-12-25 15:50:22 +01:00
|
|
|
row[i]->setup(sel_item);
|
2010-01-28 14:48:33 +01:00
|
|
|
//psergey-backport-timours: row[i]->store(sel_item);
|
2002-12-19 06:38:33 +01:00
|
|
|
}
|
2003-11-23 01:01:15 +01:00
|
|
|
if (item_list.elements > 1)
|
2002-12-19 06:38:33 +01:00
|
|
|
res_type= ROW_RESULT;
|
2002-09-28 17:34:56 +02:00
|
|
|
}
|
|
|
|
|
2002-12-19 06:38:33 +01:00
|
|
|
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
|
2002-09-28 17:34:56 +02:00
|
|
|
{
|
2002-12-19 06:38:33 +01:00
|
|
|
DBUG_ASSERT(row || select_lex->item_list.elements==1);
|
2006-11-07 17:16:17 +01:00
|
|
|
set_row(select_lex->item_list, row);
|
2003-07-30 11:15:25 +02:00
|
|
|
item->collation.set(row[0]->collation);
|
2002-12-27 20:19:25 +01:00
|
|
|
if (cols() != 1)
|
|
|
|
maybe_null= 0;
|
2002-12-19 06:38:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void subselect_union_engine::fix_length_and_dec(Item_cache **row)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(row || unit->first_select()->item_list.elements==1);
|
|
|
|
|
|
|
|
if (unit->first_select()->item_list.elements == 1)
|
2003-12-25 15:50:22 +01:00
|
|
|
{
|
2006-11-07 17:16:17 +01:00
|
|
|
set_row(unit->types, row);
|
2003-12-25 15:50:22 +01:00
|
|
|
item->collation.set(row[0]->collation);
|
|
|
|
}
|
2002-12-19 06:38:33 +01:00
|
|
|
else
|
|
|
|
{
|
2006-11-07 17:16:17 +01:00
|
|
|
bool maybe_null_saved= maybe_null;
|
|
|
|
set_row(unit->types, row);
|
|
|
|
maybe_null= maybe_null_saved;
|
2002-09-28 17:34:56 +02:00
|
|
|
}
|
|
|
|
}
|
2002-09-03 08:50:36 +02:00
|
|
|
|
2003-09-14 08:40:57 +02:00
|
|
|
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
|
2003-07-07 17:40:19 +02:00
|
|
|
{
|
|
|
|
//this never should be called
|
|
|
|
DBUG_ASSERT(0);
|
|
|
|
}
|
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
int init_read_record_seq(JOIN_TAB *tab);
|
|
|
|
int join_read_always_key_or_null(JOIN_TAB *tab);
|
|
|
|
int join_read_next_same_or_null(READ_RECORD *info);
|
|
|
|
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
int subselect_single_select_engine::exec()
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
|
|
|
DBUG_ENTER("subselect_single_select_engine::exec");
|
2004-09-10 01:22:44 +02:00
|
|
|
char const *save_where= thd->where;
|
|
|
|
SELECT_LEX *save_select= thd->lex->current_select;
|
|
|
|
thd->lex->current_select= select_lex;
|
2010-01-28 14:48:33 +01:00
|
|
|
if (!join->optimized)
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
2005-05-30 18:54:37 +02:00
|
|
|
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
|
|
|
|
|
|
|
unit->set_limit(unit->global_parameters);
|
2002-09-03 08:50:36 +02:00
|
|
|
if (join->optimize())
|
|
|
|
{
|
2004-09-10 01:22:44 +02:00
|
|
|
thd->where= save_where;
|
2002-09-03 08:50:36 +02:00
|
|
|
executed= 1;
|
2004-09-10 01:22:44 +02:00
|
|
|
thd->lex->current_select= save_select;
|
2004-06-23 12:29:05 +02:00
|
|
|
DBUG_RETURN(join->error ? join->error : 1);
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
2007-05-04 09:48:51 +02:00
|
|
|
if (!select_lex->uncacheable && thd->lex->describe &&
|
|
|
|
!(join->select_options & SELECT_DESCRIBE) &&
|
|
|
|
join->need_tmp && item->const_item())
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Force join->join_tmp creation, because this subquery will be replaced
|
|
|
|
by a simple select from the materialization temp table by optimize()
|
|
|
|
called by EXPLAIN and we need to preserve the initial query structure
|
|
|
|
so we can display it.
|
|
|
|
*/
|
|
|
|
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
|
|
|
|
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
|
|
|
|
if (join->init_save_join_tab())
|
2007-05-04 17:55:01 +02:00
|
|
|
DBUG_RETURN(1); /* purecov: inspected */
|
2007-05-04 09:48:51 +02:00
|
|
|
}
|
2003-07-07 17:40:19 +02:00
|
|
|
if (item->engine_changed)
|
|
|
|
{
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
2007-11-19 21:00:25 +01:00
|
|
|
if (select_lex->uncacheable &&
|
|
|
|
select_lex->uncacheable != UNCACHEABLE_EXPLAIN
|
|
|
|
&& executed)
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
|
|
|
if (join->reinit())
|
2002-11-24 20:10:52 +01:00
|
|
|
{
|
2004-09-10 01:22:44 +02:00
|
|
|
thd->where= save_where;
|
|
|
|
thd->lex->current_select= save_select;
|
2002-09-03 08:50:36 +02:00
|
|
|
DBUG_RETURN(1);
|
2002-11-24 20:10:52 +01:00
|
|
|
}
|
2002-12-06 20:55:53 +01:00
|
|
|
item->reset();
|
2002-09-03 08:50:36 +02:00
|
|
|
item->assigned((executed= 0));
|
|
|
|
}
|
|
|
|
if (!executed)
|
|
|
|
{
|
2004-11-18 17:10:07 +01:00
|
|
|
item->reset_value_registration();
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
JOIN_TAB *changed_tabs[MAX_TABLES];
|
|
|
|
JOIN_TAB **last_changed_tab= changed_tabs;
|
|
|
|
if (item->have_guarded_conds())
|
2006-10-31 18:51:09 +01:00
|
|
|
{
|
|
|
|
/*
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
For at least one of the pushed predicates the following is true:
|
2006-10-31 18:51:09 +01:00
|
|
|
We should not apply optimizations based on the condition that was
|
|
|
|
pushed down into the subquery. Those optimizations are ref[_or_null]
|
|
|
|
acceses. Change them to be full table scans.
|
|
|
|
*/
|
|
|
|
for (uint i=join->const_tables ; i < join->tables ; i++)
|
|
|
|
{
|
|
|
|
JOIN_TAB *tab=join->join_tab+i;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (tab && tab->keyuse)
|
2006-10-31 18:51:09 +01:00
|
|
|
{
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
for (uint i= 0; i < tab->ref.key_parts; i++)
|
|
|
|
{
|
|
|
|
bool *cond_guard= tab->ref.cond_guards[i];
|
|
|
|
if (cond_guard && !*cond_guard)
|
|
|
|
{
|
|
|
|
/* Change the access method to full table scan */
|
2007-05-12 04:37:32 +02:00
|
|
|
tab->save_read_first_record= tab->read_first_record;
|
|
|
|
tab->save_read_record= tab->read_record.read_record;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
tab->read_first_record= init_read_record_seq;
|
|
|
|
tab->read_record.record= tab->table->record[0];
|
|
|
|
tab->read_record.thd= join->thd;
|
|
|
|
tab->read_record.ref_length= tab->table->file->ref_length;
|
A fix and a test case for
Bug#41756 "Strange error messages about locks from InnoDB".
In JT_EQ_REF (join_read_key()) access method,
don't try to unlock rows in the handler, unless certain that
a) they were locked
b) they are not used.
Unlocking of rows is done by the logic of the nested join loop,
and is unaware of the possible caching that the access method may
have. This could lead to double unlocking, when a row
was unlocked first after reading into the cache, and then
when taken from cache, as well as to unlocking of rows which
were actually used (but taken from cache).
Delegate part of the unlocking logic to the access method,
and in JT_EQ_REF count how many times a record was actually
used in the join. Unlock it only if it's usage count is 0.
Implemented review comments.
mysql-test/r/bug41756.result:
Add result file (Bug#41756)
mysql-test/t/bug41756-master.opt:
Use --innodb-locks-unsafe-for-binlog, as in 5.0 just
using read_committed isolation is not sufficient to
reproduce the bug.
mysql-test/t/bug41756.test:
Add a test file (Bug#41756)
sql/item_subselect.cc:
Complete struct READ_RECORD initialization with a new
member to unlock records.
sql/records.cc:
Extend READ_RECORD API with a method to unlock read records.
sql/sql_select.cc:
In JT_EQ_REF (join_read_key()) access method,
don't try to unlock rows in the handler, unless certain that
a) they were locked
b) they are not used.
sql/sql_select.h:
Add members to TABLE_REF to count TABLE_REF buffer usage count.
sql/structs.h:
Update declarations.
2009-11-03 17:58:54 +01:00
|
|
|
tab->read_record.unlock_row= rr_unlock_row;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
*(last_changed_tab++)= tab;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-10-31 18:51:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-03 08:50:36 +02:00
|
|
|
join->exec();
|
2006-10-31 18:51:09 +01:00
|
|
|
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
/* Enable the optimizations back */
|
|
|
|
for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
|
2006-10-31 18:51:09 +01:00
|
|
|
{
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
JOIN_TAB *tab= *ptab;
|
|
|
|
tab->read_record.record= 0;
|
|
|
|
tab->read_record.ref_length= 0;
|
2007-05-12 04:37:32 +02:00
|
|
|
tab->read_first_record= tab->save_read_first_record;
|
|
|
|
tab->read_record.read_record= tab->save_read_record;
|
2006-10-31 18:51:09 +01:00
|
|
|
}
|
2002-09-03 08:50:36 +02:00
|
|
|
executed= 1;
|
2004-09-10 01:22:44 +02:00
|
|
|
thd->where= save_where;
|
|
|
|
thd->lex->current_select= save_select;
|
2003-01-30 21:15:44 +01:00
|
|
|
DBUG_RETURN(join->error||thd->is_fatal_error);
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
2004-09-10 01:22:44 +02:00
|
|
|
thd->where= save_where;
|
|
|
|
thd->lex->current_select= save_select;
|
2002-09-03 08:50:36 +02:00
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
int subselect_union_engine::exec()
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
2004-09-10 01:22:44 +02:00
|
|
|
char const *save_where= thd->where;
|
2002-11-24 20:10:52 +01:00
|
|
|
int res= unit->exec();
|
2004-09-10 01:22:44 +02:00
|
|
|
thd->where= save_where;
|
2002-11-24 20:10:52 +01:00
|
|
|
return res;
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
|
|
|
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
/*
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
Search for at least one row satisfying select condition
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
subselect_uniquesubquery_engine::scan_table()
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Scan the table using sequential access until we find at least one row
|
|
|
|
satisfying select condition.
|
|
|
|
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
The caller must set this->empty_result_set=FALSE before calling this
|
|
|
|
function. This function will set it to TRUE if it finds a matching row.
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
RETURN
|
|
|
|
FALSE - OK
|
|
|
|
TRUE - Error
|
|
|
|
*/
|
|
|
|
|
|
|
|
int subselect_uniquesubquery_engine::scan_table()
|
2003-07-07 17:40:19 +02:00
|
|
|
{
|
|
|
|
int error;
|
|
|
|
TABLE *table= tab->table;
|
2006-10-31 18:51:09 +01:00
|
|
|
DBUG_ENTER("subselect_uniquesubquery_engine::scan_table");
|
|
|
|
|
|
|
|
if (table->file->inited)
|
|
|
|
table->file->ha_index_end();
|
|
|
|
|
|
|
|
table->file->ha_rnd_init(1);
|
|
|
|
table->file->extra_opt(HA_EXTRA_CACHE,
|
|
|
|
current_thd->variables.read_buff_size);
|
|
|
|
table->null_row= 0;
|
|
|
|
for (;;)
|
2003-07-07 17:40:19 +02:00
|
|
|
{
|
This is based on the userstatv2 patch from Percona and OurDelta.
The original code comes, as far as I know, from Google (Mark Callaghan's team) with additional work from Percona, Ourdelta and Weldon Whipple.
This code provides the same functionallity, but with a lot of changes to make it faster and better fit the MariaDB infrastucture.
Added new status variables:
- Com_show_client_statistics, Com_show_index_statistics, Com_show_table_statistics, Com_show_user_statistics
- Access_denied_errors, Busy_time (clock time), Binlog_bytes_written, Cpu_time, Empty_queries, Rows_sent, Rows_read
Added new variable / startup option 'userstat' to control if user statistics should be enabled or not
Added my_getcputime(); Returns cpu time used by this thread.
New FLUSH commands:
- FLUSH SLOW QUERY LOG
- FLUSH TABLE_STATISTICS
- FLUSH INDEX_STATISTICS
- FLUSH USER_STATISTICS
- FLUSH CLIENT_STATISTICS
New SHOW commands:
- SHOW CLIENT_STATISTICS
- SHOW USER_STATISTICS
- SHOW TABLE_STATISTICS
- SHOW INDEX_STATISTICS
New Information schemas:
- CLIENT_STATISTICS
- USER_STATISTICS
- INDEX_STATISTICS
- TABLE_STATISTICS
Added support for all new flush commands to mysqladmin
Added handler::ha_... wrappers for all handler read calls to do statistics counting
- Changed all code to use new ha_... calls
- Count number of read rows, changed rows and rows read trough an index
Added counting of number of bytes sent to binary log (status variable Binlog_bytes_written)
Added counting of access denied errors (status variable Access_denied_erors)
Bugs fixed:
- Fixed bug in add_to_status() and add_diff_to_status() where longlong variables where threated as long
- CLOCK_GETTIME was not propely working on Linuxm
client/mysqladmin.cc:
Added support for all new flush commmands and some common combinations:
flush-slow-log
flush-table-statistics
flush-index-statistics
flush-user-statistics
flush-client-statistics
flush-all-status
flush-all-statistics
configure.in:
Added checking if clock_gettime needs the librt.
(Fixes Bug #37639 clock_gettime is never used/enabled in Linux/Unix)
include/my_sys.h:
Added my_getcputime()
include/mysql_com.h:
Added LIST_PROCESS_HOST_LEN & new REFRESH target defines
mysql-test/r/information_schema.result:
New information schema tables added
mysql-test/r/information_schema_all_engines.result:
New information schema tables added
mysql-test/r/information_schema_db.result:
New information schema tables added
mysql-test/r/log_slow.result:
Added testing that flosh slow query logs is accepted
mysql-test/r/status_user.result:
Basic testing of user, client, table and index statistics
mysql-test/t/log_slow.test:
Added testing that flosh slow query logs is accepted
mysql-test/t/status_user-master.opt:
Ensure that we get a fresh restart before running status_user.test
mysql-test/t/status_user.test:
Basic testing of user, client, table and index statistics
mysys/my_getsystime.c:
Added my_getcputime()
Returns cpu time used by this thread.
sql/authors.h:
Updated authors to have core and original MySQL developers first.
sql/event_data_objects.cc:
Updated call to mysql_reset_thd_for_next_command()
sql/event_db_repository.cc:
Changed to use new ha_... calls
sql/filesort.cc:
Changed to use new ha_... calls
sql/ha_partition.cc:
Changed to use new ha_... calls
Fixed comment syntax
sql/handler.cc:
Changed to use new ha_... calls
Reset table statistics
Added code to update global table and index status
Added counting of rows changed
sql/handler.h:
Added table and index statistics variables
Added function reset_statistics()
Added handler::ha_... wrappers for all handler read calls to do statistics counting
Protected all normal read calls to ensure we use the new calls in the server.
Made ha_partition a friend class so that partition code can call the old read functions
sql/item_subselect.cc:
Changed to use new ha_... calls
sql/lex.h:
Added keywords for new information schema tables and flush commands
sql/log.cc:
Added flush_slow_log()
Added counting of number of bytes sent to binary log
Removed not needed test of thd (It's used before, so it's safe to use)
Added THD object to MYSQL_BIN_LOG::write_cache() to simplify statistics counting
sql/log.h:
Added new parameter to write_cache()
Added flush_slow_log() functions.
sql/log_event.cc:
Updated call to mysql_reset_thd_for_next_command()
Changed to use new ha_... calls
sql/log_event_old.cc:
Updated call to mysql_reset_thd_for_next_command()
Changed to use new ha_... calls
sql/mysql_priv.h:
Updated call to mysql_reset_thd_for_next_command()
Added new statistics functions and variables needed by these.
sql/mysqld.cc:
Added new statistics variables and structures to handle these
Added new status variables:
- Com_show_client_statistics, Com_show_index_statistics, Com_show_table_statistics, Com_show_user_statistics
- Access_denied_errors, Busy_time (clock time), Binlog_bytes_written, Cpu_time, Empty_queries, Rows_set, Rows_read
Added new option 'userstat' to control if user statistics should be enabled or not
sql/opt_range.cc:
Changed to use new ha_... calls
sql/opt_range.h:
Changed to use new ha_... calls
sql/opt_sum.cc:
Changed to use new ha_... calls
sql/records.cc:
Changed to use new ha_... calls
sql/set_var.cc:
Added variable 'userstat'
sql/sp.cc:
Changed to use new ha_... calls
sql/sql_acl.cc:
Changed to use new ha_... calls
Added counting of access_denied_errors
sql/sql_base.cc:
Added call to statistics functions
sql/sql_class.cc:
Added usage of org_status_var, to store status variables at start of command
Added functions THD::update_stats(), THD::update_all_stats()
Fixed bug in add_to_status() and add_diff_to_status() where longlong variables where threated as long
sql/sql_class.h:
Added new status variables to status_var
Moved variables that was not ulong in status_var last.
Added variables to THD for storing temporary values during statistics counting
sql/sql_connect.cc:
Variables and functions to calculate user and client statistics
Added counting of access_denied_errors and lost_connections
sql/sql_cursor.cc:
Changed to use new ha_... calls
sql/sql_handler.cc:
Changed to use new ha_... calls
sql/sql_help.cc:
Changed to use new ha_... calls
sql/sql_insert.cc:
Changed to use new ha_... calls
sql/sql_lex.h:
Added SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, SQLCOM_SHOW_CLIENT_STATS
sql/sql_parse.cc:
Added handling of:
- SHOW CLIENT_STATISTICS
- SHOW USER_STATISTICS
- SHOW TABLE_STATISTICS
- SHOW INDEX_STATISTICS
Added handling of new FLUSH commands:
- FLUSH SLOW QUERY LOGS
- FLUSH TABLE_STATISTICS
- FLUSH INDEX_STATISTICS
- FLUSH USER_STATISTICS
- FLUSH CLIENT_STATISTICS
Added THD parameter to mysql_reset_thd_for_next_command()
Added initialization and calls to user statistics functions
Added increment of statistics variables empty_queries, rows_sent and access_denied_errors.
Added counting of cpu time per query
sql/sql_plugin.cc:
Changed to use new ha_... calls
sql/sql_prepare.cc:
Updated call to mysql_reset_thd_for_next_command()
sql/sql_select.cc:
Changed to use new ha_... calls
Indentation changes
sql/sql_servers.cc:
Changed to use new ha_... calls
sql/sql_show.cc:
Added counting of access denied errors
Added function for new information schema tables:
- CLIENT_STATISTICS
- USER_STATISTICS
- INDEX_STATISTICS
- TABLE_STATISTICS
Changed to use new ha_... calls
sql/sql_table.cc:
Changed to use new ha_... calls
sql/sql_udf.cc:
Changed to use new ha_... calls
sql/sql_update.cc:
Changed to use new ha_... calls
sql/sql_yacc.yy:
Add new show and flush commands
sql/structs.h:
Add name_length to KEY to avoid some strlen
Added cache_name to KEY for fast storage of keyvalue in cache
Added structs USER_STATS, TABLE_STATS, INDEX_STATS
Added function prototypes for statistics functions
sql/table.cc:
Store db+table+index name into keyinfo->cache_name
sql/table.h:
Added new information schema tables
sql/tztime.cc:
Changed to use new ha_... calls
2009-10-19 19:14:48 +02:00
|
|
|
error=table->file->ha_rnd_next(table->record[0]);
|
2010-02-19 22:55:57 +01:00
|
|
|
if (error) {
|
|
|
|
if (error == HA_ERR_RECORD_DELETED)
|
|
|
|
{
|
|
|
|
error= 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (error == HA_ERR_END_OF_FILE)
|
|
|
|
{
|
|
|
|
error= 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error= report_error(table, error);
|
|
|
|
break;
|
|
|
|
}
|
2006-10-31 18:51:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!cond || cond->val_int())
|
|
|
|
{
|
|
|
|
empty_result_set= FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
table->file->ha_rnd_end();
|
|
|
|
DBUG_RETURN(error != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Copy ref key and check for null parts in it
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
subselect_uniquesubquery_engine::copy_ref_key()
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Copy ref key and check for null parts in it.
|
2007-05-17 18:38:34 +02:00
|
|
|
Depending on the nullability and conversion problems this function
|
|
|
|
recognizes and processes the following states :
|
|
|
|
1. Partial match on top level. This means IN has a value of FALSE
|
|
|
|
regardless of the data in the subquery table.
|
|
|
|
Detected by finding a NULL in the left IN operand of a top level
|
|
|
|
expression.
|
|
|
|
We may actually skip reading the subquery, so return TRUE to skip
|
|
|
|
the table scan in subselect_uniquesubquery_engine::exec and make
|
|
|
|
the value of the IN predicate a NULL (that is equal to FALSE on
|
|
|
|
top level).
|
|
|
|
2. No exact match when IN is nested inside another predicate.
|
|
|
|
Detected by finding a NULL in the left IN operand when IN is not
|
|
|
|
a top level predicate.
|
|
|
|
We cannot have an exact match. But we must proceed further with a
|
|
|
|
table scan to find out if it's a partial match (and IN has a value
|
|
|
|
of NULL) or no match (and IN has a value of FALSE).
|
|
|
|
So we return FALSE to continue with the scan and see if there are
|
|
|
|
any record that would constitute a partial match (as we cannot
|
|
|
|
determine that from the index).
|
|
|
|
3. Error converting the left IN operand to the column type of the
|
|
|
|
right IN operand. This counts as no match (and IN has the value of
|
|
|
|
FALSE). We mark the subquery table cursor as having no more rows
|
|
|
|
(to ensure that the processing that follows will not find a match)
|
|
|
|
and return FALSE, so IN is not treated as returning NULL.
|
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
RETURN
|
2007-05-17 18:38:34 +02:00
|
|
|
FALSE - The value of the IN predicate is not known. Proceed to find the
|
|
|
|
value of the IN predicate using the determined values of
|
|
|
|
null_keypart and table->status.
|
|
|
|
TRUE - IN predicate has a value of NULL. Stop the processing right there
|
|
|
|
and return NULL to the outer predicates.
|
2006-10-31 18:51:09 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
bool subselect_uniquesubquery_engine::copy_ref_key()
|
|
|
|
{
|
|
|
|
DBUG_ENTER("subselect_uniquesubquery_engine::copy_ref_key");
|
|
|
|
|
|
|
|
for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
|
2003-07-07 17:40:19 +02:00
|
|
|
{
|
2006-10-31 18:51:09 +01:00
|
|
|
tab->ref.key_err= (*copy)->copy();
|
|
|
|
|
|
|
|
/*
|
|
|
|
When there is a NULL part in the key we don't need to make index
|
|
|
|
lookup for such key thus we don't need to copy whole key.
|
|
|
|
If we later should do a sequential scan return OK. Fail otherwise.
|
|
|
|
|
|
|
|
See also the comment for the subselect_uniquesubquery_engine::exec()
|
|
|
|
function.
|
|
|
|
*/
|
|
|
|
null_keypart= (*copy)->null_key;
|
2007-05-17 18:38:34 +02:00
|
|
|
if (null_keypart)
|
|
|
|
{
|
|
|
|
bool top_level= ((Item_in_subselect *) item)->is_top_level_item();
|
|
|
|
if (top_level)
|
|
|
|
{
|
|
|
|
/* Partial match on top level */
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No exact match when IN is nested inside another predicate */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
|
|
|
|
using the store_key::store_key_result enum because ref.key_err is a
|
|
|
|
boolean and we want to detect both TRUE and STORE_KEY_FATAL from the
|
|
|
|
space of the union of the values of [TRUE, FALSE] and
|
|
|
|
store_key::store_key_result.
|
|
|
|
TODO: fix the variable an return types.
|
|
|
|
*/
|
|
|
|
if (tab->ref.key_err & 1)
|
2004-08-12 16:31:23 +02:00
|
|
|
{
|
2007-05-17 18:38:34 +02:00
|
|
|
/*
|
|
|
|
Error converting the left IN operand to the column type of the right
|
|
|
|
IN operand.
|
|
|
|
*/
|
2006-10-31 18:51:09 +01:00
|
|
|
tab->table->status= STATUS_NOT_FOUND;
|
2007-05-17 18:38:34 +02:00
|
|
|
break;
|
2004-08-12 16:31:23 +02:00
|
|
|
}
|
2003-07-07 17:40:19 +02:00
|
|
|
}
|
2006-10-31 18:51:09 +01:00
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
2004-08-12 16:31:23 +02:00
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
|
|
|
@retval 1 A NULL was found in the outer reference, index lookup is
|
|
|
|
not applicable, the outer ref is unsusable as a lookup key,
|
|
|
|
use some other method to find a match.
|
|
|
|
@retval 0 The outer ref was copied into an index lookup key.
|
|
|
|
@retval -1 The outer ref cannot possibly match any row, IN is FALSE.
|
|
|
|
*/
|
|
|
|
/* TIMOUR: this method is a variant of copy_ref_key(), needs refactoring. */
|
|
|
|
|
|
|
|
int subselect_uniquesubquery_engine::copy_ref_key_simple()
|
|
|
|
{
|
|
|
|
for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
|
|
|
|
{
|
|
|
|
enum store_key::store_key_result store_res;
|
|
|
|
store_res= (*copy)->copy();
|
|
|
|
tab->ref.key_err= store_res;
|
|
|
|
|
|
|
|
/*
|
|
|
|
When there is a NULL part in the key we don't need to make index
|
|
|
|
lookup for such key thus we don't need to copy whole key.
|
|
|
|
If we later should do a sequential scan return OK. Fail otherwise.
|
|
|
|
|
|
|
|
See also the comment for the subselect_uniquesubquery_engine::exec()
|
|
|
|
function.
|
|
|
|
*/
|
|
|
|
null_keypart= (*copy)->null_key;
|
|
|
|
if (null_keypart)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
|
|
|
|
using the store_key::store_key_result enum because ref.key_err is a
|
|
|
|
boolean and we want to detect both TRUE and STORE_KEY_FATAL from the
|
|
|
|
space of the union of the values of [TRUE, FALSE] and
|
|
|
|
store_key::store_key_result.
|
|
|
|
TODO: fix the variable an return types.
|
|
|
|
*/
|
|
|
|
if (store_res == store_key::STORE_KEY_FATAL)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Error converting the left IN operand to the column type of the right
|
|
|
|
IN operand.
|
|
|
|
*/
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
/*
|
|
|
|
Execute subselect
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
subselect_uniquesubquery_engine::exec()
|
2004-08-12 16:31:23 +02:00
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
DESCRIPTION
|
|
|
|
Find rows corresponding to the ref key using index access.
|
|
|
|
If some part of the lookup key is NULL, then we're evaluating
|
|
|
|
NULL IN (SELECT ... )
|
|
|
|
This is a special case, we don't need to search for NULL in the table,
|
|
|
|
instead, the result value is
|
|
|
|
- NULL if select produces empty row set
|
|
|
|
- FALSE otherwise.
|
|
|
|
|
|
|
|
In some cases (IN subselect is a top level item, i.e. abort_on_null==TRUE)
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
the caller doesn't distinguish between NULL and FALSE result and we just
|
2006-10-31 18:51:09 +01:00
|
|
|
return FALSE.
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
Otherwise we make a full table scan to see if there is at least one
|
|
|
|
matching row.
|
|
|
|
|
|
|
|
The result of this function (info about whether a row was found) is
|
|
|
|
stored in this->empty_result_set.
|
2006-10-31 18:51:09 +01:00
|
|
|
NOTE
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
FALSE - ok
|
|
|
|
TRUE - an error occured while scanning
|
|
|
|
*/
|
2004-08-12 16:31:23 +02:00
|
|
|
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
int subselect_uniquesubquery_engine::exec()
|
2006-10-31 18:51:09 +01:00
|
|
|
{
|
|
|
|
DBUG_ENTER("subselect_uniquesubquery_engine::exec");
|
|
|
|
int error;
|
|
|
|
TABLE *table= tab->table;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
empty_result_set= TRUE;
|
2007-05-17 18:38:34 +02:00
|
|
|
table->status= 0;
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
/* TODO: change to use of 'full_scan' here? */
|
|
|
|
if (copy_ref_key())
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
TIMOUR: copy_ref_key() == 1 means NULL result, not error, why return 1?
|
|
|
|
Check who reiles on this result.
|
|
|
|
*/
|
2006-10-31 18:51:09 +01:00
|
|
|
DBUG_RETURN(1);
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
2007-05-17 18:38:34 +02:00
|
|
|
if (table->status)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
We know that there will be no rows even if we scan.
|
|
|
|
Can be set in copy_ref_key.
|
|
|
|
*/
|
|
|
|
((Item_in_subselect *) item)->value= 0;
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
if (null_keypart)
|
|
|
|
DBUG_RETURN(scan_table());
|
|
|
|
|
2004-08-12 16:31:23 +02:00
|
|
|
if (!table->file->inited)
|
2005-07-18 13:31:02 +02:00
|
|
|
table->file->ha_index_init(tab->ref.key, 0);
|
This is based on the userstatv2 patch from Percona and OurDelta.
The original code comes, as far as I know, from Google (Mark Callaghan's team) with additional work from Percona, Ourdelta and Weldon Whipple.
This code provides the same functionallity, but with a lot of changes to make it faster and better fit the MariaDB infrastucture.
Added new status variables:
- Com_show_client_statistics, Com_show_index_statistics, Com_show_table_statistics, Com_show_user_statistics
- Access_denied_errors, Busy_time (clock time), Binlog_bytes_written, Cpu_time, Empty_queries, Rows_sent, Rows_read
Added new variable / startup option 'userstat' to control if user statistics should be enabled or not
Added my_getcputime(); Returns cpu time used by this thread.
New FLUSH commands:
- FLUSH SLOW QUERY LOG
- FLUSH TABLE_STATISTICS
- FLUSH INDEX_STATISTICS
- FLUSH USER_STATISTICS
- FLUSH CLIENT_STATISTICS
New SHOW commands:
- SHOW CLIENT_STATISTICS
- SHOW USER_STATISTICS
- SHOW TABLE_STATISTICS
- SHOW INDEX_STATISTICS
New Information schemas:
- CLIENT_STATISTICS
- USER_STATISTICS
- INDEX_STATISTICS
- TABLE_STATISTICS
Added support for all new flush commands to mysqladmin
Added handler::ha_... wrappers for all handler read calls to do statistics counting
- Changed all code to use new ha_... calls
- Count number of read rows, changed rows and rows read trough an index
Added counting of number of bytes sent to binary log (status variable Binlog_bytes_written)
Added counting of access denied errors (status variable Access_denied_erors)
Bugs fixed:
- Fixed bug in add_to_status() and add_diff_to_status() where longlong variables where threated as long
- CLOCK_GETTIME was not propely working on Linuxm
client/mysqladmin.cc:
Added support for all new flush commmands and some common combinations:
flush-slow-log
flush-table-statistics
flush-index-statistics
flush-user-statistics
flush-client-statistics
flush-all-status
flush-all-statistics
configure.in:
Added checking if clock_gettime needs the librt.
(Fixes Bug #37639 clock_gettime is never used/enabled in Linux/Unix)
include/my_sys.h:
Added my_getcputime()
include/mysql_com.h:
Added LIST_PROCESS_HOST_LEN & new REFRESH target defines
mysql-test/r/information_schema.result:
New information schema tables added
mysql-test/r/information_schema_all_engines.result:
New information schema tables added
mysql-test/r/information_schema_db.result:
New information schema tables added
mysql-test/r/log_slow.result:
Added testing that flosh slow query logs is accepted
mysql-test/r/status_user.result:
Basic testing of user, client, table and index statistics
mysql-test/t/log_slow.test:
Added testing that flosh slow query logs is accepted
mysql-test/t/status_user-master.opt:
Ensure that we get a fresh restart before running status_user.test
mysql-test/t/status_user.test:
Basic testing of user, client, table and index statistics
mysys/my_getsystime.c:
Added my_getcputime()
Returns cpu time used by this thread.
sql/authors.h:
Updated authors to have core and original MySQL developers first.
sql/event_data_objects.cc:
Updated call to mysql_reset_thd_for_next_command()
sql/event_db_repository.cc:
Changed to use new ha_... calls
sql/filesort.cc:
Changed to use new ha_... calls
sql/ha_partition.cc:
Changed to use new ha_... calls
Fixed comment syntax
sql/handler.cc:
Changed to use new ha_... calls
Reset table statistics
Added code to update global table and index status
Added counting of rows changed
sql/handler.h:
Added table and index statistics variables
Added function reset_statistics()
Added handler::ha_... wrappers for all handler read calls to do statistics counting
Protected all normal read calls to ensure we use the new calls in the server.
Made ha_partition a friend class so that partition code can call the old read functions
sql/item_subselect.cc:
Changed to use new ha_... calls
sql/lex.h:
Added keywords for new information schema tables and flush commands
sql/log.cc:
Added flush_slow_log()
Added counting of number of bytes sent to binary log
Removed not needed test of thd (It's used before, so it's safe to use)
Added THD object to MYSQL_BIN_LOG::write_cache() to simplify statistics counting
sql/log.h:
Added new parameter to write_cache()
Added flush_slow_log() functions.
sql/log_event.cc:
Updated call to mysql_reset_thd_for_next_command()
Changed to use new ha_... calls
sql/log_event_old.cc:
Updated call to mysql_reset_thd_for_next_command()
Changed to use new ha_... calls
sql/mysql_priv.h:
Updated call to mysql_reset_thd_for_next_command()
Added new statistics functions and variables needed by these.
sql/mysqld.cc:
Added new statistics variables and structures to handle these
Added new status variables:
- Com_show_client_statistics, Com_show_index_statistics, Com_show_table_statistics, Com_show_user_statistics
- Access_denied_errors, Busy_time (clock time), Binlog_bytes_written, Cpu_time, Empty_queries, Rows_set, Rows_read
Added new option 'userstat' to control if user statistics should be enabled or not
sql/opt_range.cc:
Changed to use new ha_... calls
sql/opt_range.h:
Changed to use new ha_... calls
sql/opt_sum.cc:
Changed to use new ha_... calls
sql/records.cc:
Changed to use new ha_... calls
sql/set_var.cc:
Added variable 'userstat'
sql/sp.cc:
Changed to use new ha_... calls
sql/sql_acl.cc:
Changed to use new ha_... calls
Added counting of access_denied_errors
sql/sql_base.cc:
Added call to statistics functions
sql/sql_class.cc:
Added usage of org_status_var, to store status variables at start of command
Added functions THD::update_stats(), THD::update_all_stats()
Fixed bug in add_to_status() and add_diff_to_status() where longlong variables where threated as long
sql/sql_class.h:
Added new status variables to status_var
Moved variables that was not ulong in status_var last.
Added variables to THD for storing temporary values during statistics counting
sql/sql_connect.cc:
Variables and functions to calculate user and client statistics
Added counting of access_denied_errors and lost_connections
sql/sql_cursor.cc:
Changed to use new ha_... calls
sql/sql_handler.cc:
Changed to use new ha_... calls
sql/sql_help.cc:
Changed to use new ha_... calls
sql/sql_insert.cc:
Changed to use new ha_... calls
sql/sql_lex.h:
Added SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, SQLCOM_SHOW_CLIENT_STATS
sql/sql_parse.cc:
Added handling of:
- SHOW CLIENT_STATISTICS
- SHOW USER_STATISTICS
- SHOW TABLE_STATISTICS
- SHOW INDEX_STATISTICS
Added handling of new FLUSH commands:
- FLUSH SLOW QUERY LOGS
- FLUSH TABLE_STATISTICS
- FLUSH INDEX_STATISTICS
- FLUSH USER_STATISTICS
- FLUSH CLIENT_STATISTICS
Added THD parameter to mysql_reset_thd_for_next_command()
Added initialization and calls to user statistics functions
Added increment of statistics variables empty_queries, rows_sent and access_denied_errors.
Added counting of cpu time per query
sql/sql_plugin.cc:
Changed to use new ha_... calls
sql/sql_prepare.cc:
Updated call to mysql_reset_thd_for_next_command()
sql/sql_select.cc:
Changed to use new ha_... calls
Indentation changes
sql/sql_servers.cc:
Changed to use new ha_... calls
sql/sql_show.cc:
Added counting of access denied errors
Added function for new information schema tables:
- CLIENT_STATISTICS
- USER_STATISTICS
- INDEX_STATISTICS
- TABLE_STATISTICS
Changed to use new ha_... calls
sql/sql_table.cc:
Changed to use new ha_... calls
sql/sql_udf.cc:
Changed to use new ha_... calls
sql/sql_update.cc:
Changed to use new ha_... calls
sql/sql_yacc.yy:
Add new show and flush commands
sql/structs.h:
Add name_length to KEY to avoid some strlen
Added cache_name to KEY for fast storage of keyvalue in cache
Added structs USER_STATS, TABLE_STATS, INDEX_STATS
Added function prototypes for statistics functions
sql/table.cc:
Store db+table+index name into keyinfo->cache_name
sql/table.h:
Added new information schema tables
sql/tztime.cc:
Changed to use new ha_... calls
2009-10-19 19:14:48 +02:00
|
|
|
error= table->file->ha_index_read_map(table->record[0],
|
|
|
|
tab->ref.key_buff,
|
|
|
|
make_prev_keypart_map(tab->
|
|
|
|
ref.key_parts),
|
|
|
|
HA_READ_KEY_EXACT);
|
2004-10-07 13:13:42 +02:00
|
|
|
if (error &&
|
|
|
|
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
|
2004-08-12 16:31:23 +02:00
|
|
|
error= report_error(table, error);
|
2003-07-07 17:40:19 +02:00
|
|
|
else
|
|
|
|
{
|
2004-08-12 16:31:23 +02:00
|
|
|
error= 0;
|
|
|
|
table->null_row= 0;
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (!table->status && (!cond || cond->val_int()))
|
|
|
|
{
|
|
|
|
((Item_in_subselect *) item)->value= 1;
|
|
|
|
empty_result_set= FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
((Item_in_subselect *) item)->value= 0;
|
2003-07-07 17:40:19 +02:00
|
|
|
}
|
2004-08-12 16:31:23 +02:00
|
|
|
|
2003-09-29 11:39:38 +02:00
|
|
|
DBUG_RETURN(error != 0);
|
2003-07-07 23:08:00 +02:00
|
|
|
}
|
|
|
|
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
2010-03-09 11:14:06 +01:00
|
|
|
TIMOUR: write comment
|
2010-02-19 22:55:57 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
int subselect_uniquesubquery_engine::index_lookup()
|
|
|
|
{
|
|
|
|
DBUG_ENTER("subselect_uniquesubquery_engine::index_lookup");
|
|
|
|
int error;
|
|
|
|
TABLE *table= tab->table;
|
|
|
|
|
|
|
|
if (!table->file->inited)
|
|
|
|
table->file->ha_index_init(tab->ref.key, 0);
|
|
|
|
error= table->file->ha_index_read_map(table->record[0],
|
|
|
|
tab->ref.key_buff,
|
|
|
|
make_prev_keypart_map(tab->
|
|
|
|
ref.key_parts),
|
|
|
|
HA_READ_KEY_EXACT);
|
|
|
|
DBUG_PRINT("info", ("lookup result: %i", error));
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
2010-03-09 11:14:06 +01:00
|
|
|
/*
|
|
|
|
TIMOUR: I don't understand at all when do we need to call report_error.
|
|
|
|
In most places where we access an index, we don't do this. Why here?
|
|
|
|
*/
|
|
|
|
error= report_error(table, error);
|
|
|
|
DBUG_RETURN(error);
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
table->null_row= 0;
|
|
|
|
if (!error && (!cond || cond->val_int()))
|
|
|
|
((Item_in_subselect *) item)->value= 1;
|
|
|
|
else
|
|
|
|
((Item_in_subselect *) item)->value= 0;
|
|
|
|
|
|
|
|
DBUG_RETURN(0);
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2003-09-29 11:39:38 +02:00
|
|
|
subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
|
2003-07-07 23:08:00 +02:00
|
|
|
{
|
2003-09-29 11:39:38 +02:00
|
|
|
/* Tell handler we don't need the index anymore */
|
2010-01-28 14:48:33 +01:00
|
|
|
//psergey-merge-todo: the following was gone in 6.0:
|
|
|
|
//psergey-merge: don't need this after all: tab->table->file->ha_index_end();
|
2003-07-07 23:08:00 +02:00
|
|
|
}
|
|
|
|
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
/*
|
|
|
|
Index-lookup subselect 'engine' - run the subquery
|
|
|
|
|
|
|
|
SYNOPSIS
|
2010-01-28 14:48:33 +01:00
|
|
|
subselect_indexsubquery_engine:exec()
|
2006-10-31 18:51:09 +01:00
|
|
|
full_scan
|
|
|
|
|
|
|
|
DESCRIPTION
|
2006-10-31 19:30:40 +01:00
|
|
|
The engine is used to resolve subqueries in form
|
|
|
|
|
|
|
|
oe IN (SELECT key FROM tbl WHERE subq_where)
|
|
|
|
|
|
|
|
The value of the predicate is calculated as follows:
|
|
|
|
1. If oe IS NULL, this is a special case, do a full table scan on
|
|
|
|
table tbl and search for row that satisfies subq_where. If such
|
|
|
|
row is found, return NULL, otherwise return FALSE.
|
|
|
|
2. Make an index lookup via key=oe, search for a row that satisfies
|
|
|
|
subq_where. If found, return TRUE.
|
|
|
|
3. If check_null==TRUE, make another lookup via key=NULL, search for a
|
|
|
|
row that satisfies subq_where. If found, return NULL, otherwise
|
|
|
|
return FALSE.
|
|
|
|
|
|
|
|
TODO
|
|
|
|
The step #1 can be optimized further when the index has several key
|
|
|
|
parts. Consider a subquery:
|
|
|
|
|
|
|
|
(oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
|
|
|
|
|
|
|
|
and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
|
|
|
|
Current code will do a full table scan and obtain correct result. There
|
|
|
|
is a better option: instead of evaluating
|
|
|
|
|
|
|
|
SELECT keypart1, keypart2 FROM tbl WHERE subq_where (1)
|
|
|
|
|
|
|
|
and checking if it has produced any matching rows, evaluate
|
|
|
|
|
|
|
|
SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1 (2)
|
|
|
|
|
|
|
|
If this query produces a row, the result is NULL (as we're evaluating
|
|
|
|
"(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
|
|
|
|
i.e. NULL). If the query produces no rows, the result is FALSE.
|
2006-10-31 18:51:09 +01:00
|
|
|
|
2006-10-31 19:30:40 +01:00
|
|
|
We currently evaluate (1) by doing a full table scan. (2) can be
|
|
|
|
evaluated by doing a "ref" scan on "keypart1=const1", which can be much
|
|
|
|
cheaper. We can use index statistics to quickly check whether "ref" scan
|
|
|
|
will be cheaper than full table scan.
|
2006-10-31 18:51:09 +01:00
|
|
|
|
|
|
|
RETURN
|
|
|
|
0
|
|
|
|
1
|
|
|
|
*/
|
|
|
|
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
int subselect_indexsubquery_engine::exec()
|
2003-07-07 23:08:00 +02:00
|
|
|
{
|
2006-10-31 18:51:09 +01:00
|
|
|
DBUG_ENTER("subselect_indexsubquery_engine::exec");
|
2003-07-07 23:08:00 +02:00
|
|
|
int error;
|
2003-09-08 20:58:09 +02:00
|
|
|
bool null_finding= 0;
|
2003-07-07 23:08:00 +02:00
|
|
|
TABLE *table= tab->table;
|
2003-07-17 18:39:31 +02:00
|
|
|
|
2003-07-07 23:08:00 +02:00
|
|
|
((Item_in_subselect *) item)->value= 0;
|
2006-10-31 18:51:09 +01:00
|
|
|
empty_result_set= TRUE;
|
|
|
|
null_keypart= 0;
|
2007-11-10 20:44:48 +01:00
|
|
|
table->status= 0;
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2003-07-17 18:39:31 +02:00
|
|
|
if (check_null)
|
|
|
|
{
|
2003-09-29 11:39:38 +02:00
|
|
|
/* We need to check for NULL if there wasn't a matching value */
|
2004-01-31 07:04:16 +01:00
|
|
|
*tab->ref.null_ref_key= 0; // Search first for not null
|
2003-07-17 18:39:31 +02:00
|
|
|
((Item_in_subselect *) item)->was_null= 0;
|
|
|
|
}
|
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
/* Copy the ref key and check for nulls... */
|
|
|
|
if (copy_ref_key())
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
|
2007-11-10 20:44:48 +01:00
|
|
|
if (table->status)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
We know that there will be no rows even if we scan.
|
|
|
|
Can be set in copy_ref_key.
|
|
|
|
*/
|
|
|
|
((Item_in_subselect *) item)->value= 0;
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
2006-10-31 18:51:09 +01:00
|
|
|
if (null_keypart)
|
|
|
|
DBUG_RETURN(scan_table());
|
2004-08-12 16:31:23 +02:00
|
|
|
|
|
|
|
if (!table->file->inited)
|
2005-07-18 13:31:02 +02:00
|
|
|
table->file->ha_index_init(tab->ref.key, 1);
|
This is based on the userstatv2 patch from Percona and OurDelta.
The original code comes, as far as I know, from Google (Mark Callaghan's team) with additional work from Percona, Ourdelta and Weldon Whipple.
This code provides the same functionallity, but with a lot of changes to make it faster and better fit the MariaDB infrastucture.
Added new status variables:
- Com_show_client_statistics, Com_show_index_statistics, Com_show_table_statistics, Com_show_user_statistics
- Access_denied_errors, Busy_time (clock time), Binlog_bytes_written, Cpu_time, Empty_queries, Rows_sent, Rows_read
Added new variable / startup option 'userstat' to control if user statistics should be enabled or not
Added my_getcputime(); Returns cpu time used by this thread.
New FLUSH commands:
- FLUSH SLOW QUERY LOG
- FLUSH TABLE_STATISTICS
- FLUSH INDEX_STATISTICS
- FLUSH USER_STATISTICS
- FLUSH CLIENT_STATISTICS
New SHOW commands:
- SHOW CLIENT_STATISTICS
- SHOW USER_STATISTICS
- SHOW TABLE_STATISTICS
- SHOW INDEX_STATISTICS
New Information schemas:
- CLIENT_STATISTICS
- USER_STATISTICS
- INDEX_STATISTICS
- TABLE_STATISTICS
Added support for all new flush commands to mysqladmin
Added handler::ha_... wrappers for all handler read calls to do statistics counting
- Changed all code to use new ha_... calls
- Count number of read rows, changed rows and rows read trough an index
Added counting of number of bytes sent to binary log (status variable Binlog_bytes_written)
Added counting of access denied errors (status variable Access_denied_erors)
Bugs fixed:
- Fixed bug in add_to_status() and add_diff_to_status() where longlong variables where threated as long
- CLOCK_GETTIME was not propely working on Linuxm
client/mysqladmin.cc:
Added support for all new flush commmands and some common combinations:
flush-slow-log
flush-table-statistics
flush-index-statistics
flush-user-statistics
flush-client-statistics
flush-all-status
flush-all-statistics
configure.in:
Added checking if clock_gettime needs the librt.
(Fixes Bug #37639 clock_gettime is never used/enabled in Linux/Unix)
include/my_sys.h:
Added my_getcputime()
include/mysql_com.h:
Added LIST_PROCESS_HOST_LEN & new REFRESH target defines
mysql-test/r/information_schema.result:
New information schema tables added
mysql-test/r/information_schema_all_engines.result:
New information schema tables added
mysql-test/r/information_schema_db.result:
New information schema tables added
mysql-test/r/log_slow.result:
Added testing that flosh slow query logs is accepted
mysql-test/r/status_user.result:
Basic testing of user, client, table and index statistics
mysql-test/t/log_slow.test:
Added testing that flosh slow query logs is accepted
mysql-test/t/status_user-master.opt:
Ensure that we get a fresh restart before running status_user.test
mysql-test/t/status_user.test:
Basic testing of user, client, table and index statistics
mysys/my_getsystime.c:
Added my_getcputime()
Returns cpu time used by this thread.
sql/authors.h:
Updated authors to have core and original MySQL developers first.
sql/event_data_objects.cc:
Updated call to mysql_reset_thd_for_next_command()
sql/event_db_repository.cc:
Changed to use new ha_... calls
sql/filesort.cc:
Changed to use new ha_... calls
sql/ha_partition.cc:
Changed to use new ha_... calls
Fixed comment syntax
sql/handler.cc:
Changed to use new ha_... calls
Reset table statistics
Added code to update global table and index status
Added counting of rows changed
sql/handler.h:
Added table and index statistics variables
Added function reset_statistics()
Added handler::ha_... wrappers for all handler read calls to do statistics counting
Protected all normal read calls to ensure we use the new calls in the server.
Made ha_partition a friend class so that partition code can call the old read functions
sql/item_subselect.cc:
Changed to use new ha_... calls
sql/lex.h:
Added keywords for new information schema tables and flush commands
sql/log.cc:
Added flush_slow_log()
Added counting of number of bytes sent to binary log
Removed not needed test of thd (It's used before, so it's safe to use)
Added THD object to MYSQL_BIN_LOG::write_cache() to simplify statistics counting
sql/log.h:
Added new parameter to write_cache()
Added flush_slow_log() functions.
sql/log_event.cc:
Updated call to mysql_reset_thd_for_next_command()
Changed to use new ha_... calls
sql/log_event_old.cc:
Updated call to mysql_reset_thd_for_next_command()
Changed to use new ha_... calls
sql/mysql_priv.h:
Updated call to mysql_reset_thd_for_next_command()
Added new statistics functions and variables needed by these.
sql/mysqld.cc:
Added new statistics variables and structures to handle these
Added new status variables:
- Com_show_client_statistics, Com_show_index_statistics, Com_show_table_statistics, Com_show_user_statistics
- Access_denied_errors, Busy_time (clock time), Binlog_bytes_written, Cpu_time, Empty_queries, Rows_set, Rows_read
Added new option 'userstat' to control if user statistics should be enabled or not
sql/opt_range.cc:
Changed to use new ha_... calls
sql/opt_range.h:
Changed to use new ha_... calls
sql/opt_sum.cc:
Changed to use new ha_... calls
sql/records.cc:
Changed to use new ha_... calls
sql/set_var.cc:
Added variable 'userstat'
sql/sp.cc:
Changed to use new ha_... calls
sql/sql_acl.cc:
Changed to use new ha_... calls
Added counting of access_denied_errors
sql/sql_base.cc:
Added call to statistics functions
sql/sql_class.cc:
Added usage of org_status_var, to store status variables at start of command
Added functions THD::update_stats(), THD::update_all_stats()
Fixed bug in add_to_status() and add_diff_to_status() where longlong variables where threated as long
sql/sql_class.h:
Added new status variables to status_var
Moved variables that was not ulong in status_var last.
Added variables to THD for storing temporary values during statistics counting
sql/sql_connect.cc:
Variables and functions to calculate user and client statistics
Added counting of access_denied_errors and lost_connections
sql/sql_cursor.cc:
Changed to use new ha_... calls
sql/sql_handler.cc:
Changed to use new ha_... calls
sql/sql_help.cc:
Changed to use new ha_... calls
sql/sql_insert.cc:
Changed to use new ha_... calls
sql/sql_lex.h:
Added SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, SQLCOM_SHOW_CLIENT_STATS
sql/sql_parse.cc:
Added handling of:
- SHOW CLIENT_STATISTICS
- SHOW USER_STATISTICS
- SHOW TABLE_STATISTICS
- SHOW INDEX_STATISTICS
Added handling of new FLUSH commands:
- FLUSH SLOW QUERY LOGS
- FLUSH TABLE_STATISTICS
- FLUSH INDEX_STATISTICS
- FLUSH USER_STATISTICS
- FLUSH CLIENT_STATISTICS
Added THD parameter to mysql_reset_thd_for_next_command()
Added initialization and calls to user statistics functions
Added increment of statistics variables empty_queries, rows_sent and access_denied_errors.
Added counting of cpu time per query
sql/sql_plugin.cc:
Changed to use new ha_... calls
sql/sql_prepare.cc:
Updated call to mysql_reset_thd_for_next_command()
sql/sql_select.cc:
Changed to use new ha_... calls
Indentation changes
sql/sql_servers.cc:
Changed to use new ha_... calls
sql/sql_show.cc:
Added counting of access denied errors
Added function for new information schema tables:
- CLIENT_STATISTICS
- USER_STATISTICS
- INDEX_STATISTICS
- TABLE_STATISTICS
Changed to use new ha_... calls
sql/sql_table.cc:
Changed to use new ha_... calls
sql/sql_udf.cc:
Changed to use new ha_... calls
sql/sql_update.cc:
Changed to use new ha_... calls
sql/sql_yacc.yy:
Add new show and flush commands
sql/structs.h:
Add name_length to KEY to avoid some strlen
Added cache_name to KEY for fast storage of keyvalue in cache
Added structs USER_STATS, TABLE_STATS, INDEX_STATS
Added function prototypes for statistics functions
sql/table.cc:
Store db+table+index name into keyinfo->cache_name
sql/table.h:
Added new information schema tables
sql/tztime.cc:
Changed to use new ha_... calls
2009-10-19 19:14:48 +02:00
|
|
|
error= table->file->ha_index_read_map(table->record[0],
|
|
|
|
tab->ref.key_buff,
|
|
|
|
make_prev_keypart_map(tab->
|
|
|
|
ref.key_parts),
|
|
|
|
HA_READ_KEY_EXACT);
|
2004-10-07 13:13:42 +02:00
|
|
|
if (error &&
|
|
|
|
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
|
2004-08-12 16:31:23 +02:00
|
|
|
error= report_error(table, error);
|
2003-07-07 23:08:00 +02:00
|
|
|
else
|
|
|
|
{
|
2004-08-12 16:31:23 +02:00
|
|
|
for (;;)
|
2003-07-07 17:40:19 +02:00
|
|
|
{
|
2004-08-12 16:31:23 +02:00
|
|
|
error= 0;
|
|
|
|
table->null_row= 0;
|
|
|
|
if (!table->status)
|
2003-07-07 23:08:00 +02:00
|
|
|
{
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if ((!cond || cond->val_int()) && (!having || having->val_int()))
|
2004-08-12 16:31:23 +02:00
|
|
|
{
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
empty_result_set= FALSE;
|
2004-08-12 16:31:23 +02:00
|
|
|
if (null_finding)
|
|
|
|
((Item_in_subselect *) item)->was_null= 1;
|
|
|
|
else
|
|
|
|
((Item_in_subselect *) item)->value= 1;
|
|
|
|
break;
|
|
|
|
}
|
This is based on the userstatv2 patch from Percona and OurDelta.
The original code comes, as far as I know, from Google (Mark Callaghan's team) with additional work from Percona, Ourdelta and Weldon Whipple.
This code provides the same functionallity, but with a lot of changes to make it faster and better fit the MariaDB infrastucture.
Added new status variables:
- Com_show_client_statistics, Com_show_index_statistics, Com_show_table_statistics, Com_show_user_statistics
- Access_denied_errors, Busy_time (clock time), Binlog_bytes_written, Cpu_time, Empty_queries, Rows_sent, Rows_read
Added new variable / startup option 'userstat' to control if user statistics should be enabled or not
Added my_getcputime(); Returns cpu time used by this thread.
New FLUSH commands:
- FLUSH SLOW QUERY LOG
- FLUSH TABLE_STATISTICS
- FLUSH INDEX_STATISTICS
- FLUSH USER_STATISTICS
- FLUSH CLIENT_STATISTICS
New SHOW commands:
- SHOW CLIENT_STATISTICS
- SHOW USER_STATISTICS
- SHOW TABLE_STATISTICS
- SHOW INDEX_STATISTICS
New Information schemas:
- CLIENT_STATISTICS
- USER_STATISTICS
- INDEX_STATISTICS
- TABLE_STATISTICS
Added support for all new flush commands to mysqladmin
Added handler::ha_... wrappers for all handler read calls to do statistics counting
- Changed all code to use new ha_... calls
- Count number of read rows, changed rows and rows read trough an index
Added counting of number of bytes sent to binary log (status variable Binlog_bytes_written)
Added counting of access denied errors (status variable Access_denied_erors)
Bugs fixed:
- Fixed bug in add_to_status() and add_diff_to_status() where longlong variables where threated as long
- CLOCK_GETTIME was not propely working on Linuxm
client/mysqladmin.cc:
Added support for all new flush commmands and some common combinations:
flush-slow-log
flush-table-statistics
flush-index-statistics
flush-user-statistics
flush-client-statistics
flush-all-status
flush-all-statistics
configure.in:
Added checking if clock_gettime needs the librt.
(Fixes Bug #37639 clock_gettime is never used/enabled in Linux/Unix)
include/my_sys.h:
Added my_getcputime()
include/mysql_com.h:
Added LIST_PROCESS_HOST_LEN & new REFRESH target defines
mysql-test/r/information_schema.result:
New information schema tables added
mysql-test/r/information_schema_all_engines.result:
New information schema tables added
mysql-test/r/information_schema_db.result:
New information schema tables added
mysql-test/r/log_slow.result:
Added testing that flosh slow query logs is accepted
mysql-test/r/status_user.result:
Basic testing of user, client, table and index statistics
mysql-test/t/log_slow.test:
Added testing that flosh slow query logs is accepted
mysql-test/t/status_user-master.opt:
Ensure that we get a fresh restart before running status_user.test
mysql-test/t/status_user.test:
Basic testing of user, client, table and index statistics
mysys/my_getsystime.c:
Added my_getcputime()
Returns cpu time used by this thread.
sql/authors.h:
Updated authors to have core and original MySQL developers first.
sql/event_data_objects.cc:
Updated call to mysql_reset_thd_for_next_command()
sql/event_db_repository.cc:
Changed to use new ha_... calls
sql/filesort.cc:
Changed to use new ha_... calls
sql/ha_partition.cc:
Changed to use new ha_... calls
Fixed comment syntax
sql/handler.cc:
Changed to use new ha_... calls
Reset table statistics
Added code to update global table and index status
Added counting of rows changed
sql/handler.h:
Added table and index statistics variables
Added function reset_statistics()
Added handler::ha_... wrappers for all handler read calls to do statistics counting
Protected all normal read calls to ensure we use the new calls in the server.
Made ha_partition a friend class so that partition code can call the old read functions
sql/item_subselect.cc:
Changed to use new ha_... calls
sql/lex.h:
Added keywords for new information schema tables and flush commands
sql/log.cc:
Added flush_slow_log()
Added counting of number of bytes sent to binary log
Removed not needed test of thd (It's used before, so it's safe to use)
Added THD object to MYSQL_BIN_LOG::write_cache() to simplify statistics counting
sql/log.h:
Added new parameter to write_cache()
Added flush_slow_log() functions.
sql/log_event.cc:
Updated call to mysql_reset_thd_for_next_command()
Changed to use new ha_... calls
sql/log_event_old.cc:
Updated call to mysql_reset_thd_for_next_command()
Changed to use new ha_... calls
sql/mysql_priv.h:
Updated call to mysql_reset_thd_for_next_command()
Added new statistics functions and variables needed by these.
sql/mysqld.cc:
Added new statistics variables and structures to handle these
Added new status variables:
- Com_show_client_statistics, Com_show_index_statistics, Com_show_table_statistics, Com_show_user_statistics
- Access_denied_errors, Busy_time (clock time), Binlog_bytes_written, Cpu_time, Empty_queries, Rows_set, Rows_read
Added new option 'userstat' to control if user statistics should be enabled or not
sql/opt_range.cc:
Changed to use new ha_... calls
sql/opt_range.h:
Changed to use new ha_... calls
sql/opt_sum.cc:
Changed to use new ha_... calls
sql/records.cc:
Changed to use new ha_... calls
sql/set_var.cc:
Added variable 'userstat'
sql/sp.cc:
Changed to use new ha_... calls
sql/sql_acl.cc:
Changed to use new ha_... calls
Added counting of access_denied_errors
sql/sql_base.cc:
Added call to statistics functions
sql/sql_class.cc:
Added usage of org_status_var, to store status variables at start of command
Added functions THD::update_stats(), THD::update_all_stats()
Fixed bug in add_to_status() and add_diff_to_status() where longlong variables where threated as long
sql/sql_class.h:
Added new status variables to status_var
Moved variables that was not ulong in status_var last.
Added variables to THD for storing temporary values during statistics counting
sql/sql_connect.cc:
Variables and functions to calculate user and client statistics
Added counting of access_denied_errors and lost_connections
sql/sql_cursor.cc:
Changed to use new ha_... calls
sql/sql_handler.cc:
Changed to use new ha_... calls
sql/sql_help.cc:
Changed to use new ha_... calls
sql/sql_insert.cc:
Changed to use new ha_... calls
sql/sql_lex.h:
Added SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, SQLCOM_SHOW_CLIENT_STATS
sql/sql_parse.cc:
Added handling of:
- SHOW CLIENT_STATISTICS
- SHOW USER_STATISTICS
- SHOW TABLE_STATISTICS
- SHOW INDEX_STATISTICS
Added handling of new FLUSH commands:
- FLUSH SLOW QUERY LOGS
- FLUSH TABLE_STATISTICS
- FLUSH INDEX_STATISTICS
- FLUSH USER_STATISTICS
- FLUSH CLIENT_STATISTICS
Added THD parameter to mysql_reset_thd_for_next_command()
Added initialization and calls to user statistics functions
Added increment of statistics variables empty_queries, rows_sent and access_denied_errors.
Added counting of cpu time per query
sql/sql_plugin.cc:
Changed to use new ha_... calls
sql/sql_prepare.cc:
Updated call to mysql_reset_thd_for_next_command()
sql/sql_select.cc:
Changed to use new ha_... calls
Indentation changes
sql/sql_servers.cc:
Changed to use new ha_... calls
sql/sql_show.cc:
Added counting of access denied errors
Added function for new information schema tables:
- CLIENT_STATISTICS
- USER_STATISTICS
- INDEX_STATISTICS
- TABLE_STATISTICS
Changed to use new ha_... calls
sql/sql_table.cc:
Changed to use new ha_... calls
sql/sql_udf.cc:
Changed to use new ha_... calls
sql/sql_update.cc:
Changed to use new ha_... calls
sql/sql_yacc.yy:
Add new show and flush commands
sql/structs.h:
Add name_length to KEY to avoid some strlen
Added cache_name to KEY for fast storage of keyvalue in cache
Added structs USER_STATS, TABLE_STATS, INDEX_STATS
Added function prototypes for statistics functions
sql/table.cc:
Store db+table+index name into keyinfo->cache_name
sql/table.h:
Added new information schema tables
sql/tztime.cc:
Changed to use new ha_... calls
2009-10-19 19:14:48 +02:00
|
|
|
error= table->file->ha_index_next_same(table->record[0],
|
|
|
|
tab->ref.key_buff,
|
|
|
|
tab->ref.key_length);
|
2004-08-12 16:31:23 +02:00
|
|
|
if (error && error != HA_ERR_END_OF_FILE)
|
|
|
|
{
|
|
|
|
error= report_error(table, error);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!check_null || null_finding)
|
|
|
|
break; /* We don't need to check nulls */
|
|
|
|
*tab->ref.null_ref_key= 1;
|
|
|
|
null_finding= 1;
|
|
|
|
/* Check if there exists a row with a null value in the index */
|
|
|
|
if ((error= (safe_index_read(tab) == 1)))
|
|
|
|
break;
|
2003-07-07 23:08:00 +02:00
|
|
|
}
|
2003-07-07 17:40:19 +02:00
|
|
|
}
|
|
|
|
}
|
2003-09-29 11:39:38 +02:00
|
|
|
DBUG_RETURN(error != 0);
|
2003-07-07 17:40:19 +02:00
|
|
|
}
|
|
|
|
|
2003-09-29 11:39:38 +02:00
|
|
|
|
2002-09-03 08:50:36 +02:00
|
|
|
uint subselect_single_select_engine::cols()
|
|
|
|
{
|
2010-01-17 15:51:10 +01:00
|
|
|
//psergey-sj-backport: the following assert was gone in 6.0:
|
|
|
|
//DBUG_ASSERT(select_lex->join != 0); // should be called after fix_fields()
|
|
|
|
//return select_lex->join->fields_list.elements;
|
|
|
|
return select_lex->item_list.elements;
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2002-09-03 08:50:36 +02:00
|
|
|
uint subselect_union_engine::cols()
|
|
|
|
{
|
2005-01-24 13:25:44 +01:00
|
|
|
DBUG_ASSERT(unit->is_prepared()); // should be called after fix_fields()
|
|
|
|
return unit->types.elements;
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2003-11-17 19:53:40 +01:00
|
|
|
uint8 subselect_single_select_engine::uncacheable()
|
2003-01-28 13:48:12 +01:00
|
|
|
{
|
|
|
|
return select_lex->uncacheable;
|
|
|
|
}
|
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2003-11-17 19:53:40 +01:00
|
|
|
uint8 subselect_union_engine::uncacheable()
|
2003-01-28 13:48:12 +01:00
|
|
|
{
|
|
|
|
return unit->uncacheable;
|
|
|
|
}
|
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2002-11-28 18:29:26 +01:00
|
|
|
void subselect_single_select_engine::exclude()
|
|
|
|
{
|
|
|
|
select_lex->master_unit()->exclude_level();
|
|
|
|
}
|
|
|
|
|
|
|
|
void subselect_union_engine::exclude()
|
|
|
|
{
|
|
|
|
unit->exclude_level();
|
|
|
|
}
|
2003-07-07 17:40:19 +02:00
|
|
|
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2003-09-14 08:40:57 +02:00
|
|
|
void subselect_uniquesubquery_engine::exclude()
|
2003-07-07 17:40:19 +02:00
|
|
|
{
|
|
|
|
//this never should be called
|
|
|
|
DBUG_ASSERT(0);
|
|
|
|
}
|
2003-10-16 23:36:01 +02:00
|
|
|
|
|
|
|
|
|
|
|
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
|
|
|
|
{
|
|
|
|
table_map map= 0;
|
2005-06-01 15:35:09 +02:00
|
|
|
for (; table; table= table->next_leaf)
|
2003-10-16 23:36:01 +02:00
|
|
|
{
|
|
|
|
TABLE *tbl= table->table;
|
|
|
|
if (tbl && tbl->const_table)
|
|
|
|
map|= tbl->map;
|
|
|
|
}
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
table_map subselect_single_select_engine::upper_select_const_tables()
|
|
|
|
{
|
|
|
|
return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
|
2004-09-14 18:28:29 +02:00
|
|
|
leaf_tables);
|
2003-10-16 23:36:01 +02:00
|
|
|
}
|
|
|
|
|
2003-10-28 11:45:37 +01:00
|
|
|
|
2003-10-16 23:36:01 +02:00
|
|
|
table_map subselect_union_engine::upper_select_const_tables()
|
|
|
|
{
|
2004-09-14 18:28:29 +02:00
|
|
|
return calc_const_tables((TABLE_LIST *) unit->outer_select()->leaf_tables);
|
2003-10-16 23:36:01 +02:00
|
|
|
}
|
2003-10-28 11:45:37 +01:00
|
|
|
|
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void subselect_single_select_engine::print(String *str,
|
|
|
|
enum_query_type query_type)
|
2003-10-16 14:54:47 +02:00
|
|
|
{
|
2008-02-22 11:30:33 +01:00
|
|
|
select_lex->print(thd, str, query_type);
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void subselect_union_engine::print(String *str, enum_query_type query_type)
|
2003-10-16 14:54:47 +02:00
|
|
|
{
|
2008-02-22 11:30:33 +01:00
|
|
|
unit->print(str, query_type);
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void subselect_uniquesubquery_engine::print(String *str,
|
|
|
|
enum_query_type query_type)
|
2003-10-16 14:54:47 +02:00
|
|
|
{
|
2010-01-28 14:48:33 +01:00
|
|
|
char *table_name= tab->table->s->table_name.str;
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
|
2008-02-22 11:30:33 +01:00
|
|
|
tab->ref.items[0]->print(str, query_type);
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" in "));
|
2010-01-28 14:48:33 +01:00
|
|
|
if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Temporary tables' names change across runs, so they can't be used for
|
|
|
|
EXPLAIN EXTENDED.
|
|
|
|
*/
|
|
|
|
str->append(STRING_WITH_LEN("<temporary table>"));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
str->append(table_name, tab->table->s->table_name.length);
|
2003-10-19 13:22:17 +02:00
|
|
|
KEY *key_info= tab->table->key_info+ tab->ref.key;
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" on "));
|
2003-10-19 13:22:17 +02:00
|
|
|
str->append(key_info->name);
|
2003-10-16 14:54:47 +02:00
|
|
|
if (cond)
|
|
|
|
{
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" where "));
|
2008-02-22 11:30:33 +01:00
|
|
|
cond->print(str, query_type);
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
|
|
|
str->append(')');
|
|
|
|
}
|
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
/*
|
|
|
|
TODO:
|
|
|
|
The above ::print method should be changed as below. Do it after
|
|
|
|
all other tests pass.
|
|
|
|
|
|
|
|
void subselect_uniquesubquery_engine::print(String *str)
|
|
|
|
{
|
|
|
|
KEY *key_info= tab->table->key_info + tab->ref.key;
|
|
|
|
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
|
|
|
|
for (uint i= 0; i < key_info->key_parts; i++)
|
|
|
|
tab->ref.items[i]->print(str);
|
|
|
|
str->append(STRING_WITH_LEN(" in "));
|
|
|
|
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
|
|
|
|
str->append(STRING_WITH_LEN(" on "));
|
|
|
|
str->append(key_info->name);
|
|
|
|
if (cond)
|
|
|
|
{
|
|
|
|
str->append(STRING_WITH_LEN(" where "));
|
|
|
|
cond->print(str);
|
|
|
|
}
|
|
|
|
str->append(')');
|
|
|
|
}
|
|
|
|
*/
|
2003-10-16 14:54:47 +02:00
|
|
|
|
2008-02-22 11:30:33 +01:00
|
|
|
void subselect_indexsubquery_engine::print(String *str,
|
|
|
|
enum_query_type query_type)
|
2003-10-16 14:54:47 +02:00
|
|
|
{
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN("<index_lookup>("));
|
2008-02-22 11:30:33 +01:00
|
|
|
tab->ref.items[0]->print(str, query_type);
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" in "));
|
Table definition cache, part 2
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
Other noteworthy changes:
- In TABLE_SHARE the most common strings are now LEX_STRING's
- Better error message when table is not found
- Variable table_cache is now renamed 'table_open_cache'
- New variable 'table_definition_cache' that is the number of table defintions that will be cached
- strxnmov() calls are now fixed to avoid overflows
- strxnmov() will now always add one end \0 to result
- engine objects are now created with a TABLE_SHARE object instead of a TABLE object.
- After creating a field object one must call field->init(table) before using it
- For a busy system this change will give you:
- Less memory usage for table object
- Faster opening of tables (if it's has been in use or is in table definition cache)
- Allow you to cache many table definitions objects
- Faster drop of table
mysql-test/mysql-test-run.sh:
Fixed some problems with --gdb option
Test both with socket and tcp/ip port that all old servers are killed
mysql-test/r/flush_table.result:
More tests with lock table with 2 threads + flush table
mysql-test/r/information_schema.result:
Removed old (now wrong) result
mysql-test/r/innodb.result:
Better error messages (thanks to TDC patch)
mysql-test/r/merge.result:
Extra flush table test
mysql-test/r/ndb_bitfield.result:
Better error messages (thanks to TDC patch)
mysql-test/r/ndb_partition_error.result:
Better error messages (thanks to TDC patch)
mysql-test/r/query_cache.result:
Remove tables left from old tests
mysql-test/r/temp_table.result:
Test truncate with temporary tables
mysql-test/r/variables.result:
Table_cache -> Table_open_cache
mysql-test/t/flush_table.test:
More tests with lock table with 2 threads + flush table
mysql-test/t/merge.test:
Extra flush table test
mysql-test/t/multi_update.test:
Added 'sleep' to make test predictable
mysql-test/t/query_cache.test:
Remove tables left from old tests
mysql-test/t/temp_table.test:
Test truncate with temporary tables
mysql-test/t/variables.test:
Table_cache -> Table_open_cache
mysql-test/valgrind.supp:
Remove warning that may happens becasue threads dies in different order
mysys/hash.c:
Fixed wrong DBUG_PRINT
mysys/mf_dirname.c:
More DBUG
mysys/mf_pack.c:
Better comment
mysys/mf_tempdir.c:
More DBUG
Ensure that we call cleanup_dirname() on all temporary directory paths.
If we don't do this, we will get a failure when comparing temporary table
names as in some cases the temporary table name is run through convert_dirname())
mysys/my_alloc.c:
Indentation fix
sql/examples/ha_example.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_example.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/examples/ha_tina.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/field.cc:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Use s->db instead of s->table_cache_key
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/field.h:
Update for table definition cache:
- Field creation now takes TABLE_SHARE instead of TABLE as argument
(This is becasue field definitions are now cached in TABLE_SHARE)
When a field is created, one now must call field->init(TABLE) before using it
- Added Field::clone() to create a field in TABLE from a field in TABLE_SHARE
- make_field() takes TABLE_SHARE as argument instead of TABLE
- move_field() -> move_field_offset()
sql/ha_archive.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_archive.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_berkeley.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Changed name of argument create() to not hide internal 'table' variable.
table->s -> table_share
sql/ha_berkeley.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_blackhole.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_federated.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed comments
Remove index variable and replace with pointers (simple optimization)
move_field() -> move_field_offset()
Removed some strlen() calls
sql/ha_federated.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_heap.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Simplify delete_table() and create() as the given file names are now without extension
sql/ha_heap.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_innodb.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisam.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Remove not needed fn_format()
Fixed for new table->s structure
sql/ha_myisam.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_myisammrg.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Don't set 'is_view' for MERGE tables
Use new interface to find_temporary_table()
sql/ha_myisammrg.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Added flag HA_NO_COPY_ON_ALTER
sql/ha_ndbcluster.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Fixed wrong calls to strxnmov()
Give error HA_ERR_TABLE_DEF_CHANGED if table definition has changed
drop_table -> intern_drop_table()
table->s -> table_share
Move part_info to TABLE
Fixed comments & DBUG print's
New arguments to print_error()
sql/ha_ndbcluster.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
sql/ha_partition.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
We can't set up or use part_info when creating handler as there is not yet any table object
New ha_intialise() to work with TDC (Done by Mikael)
sql/ha_partition.h:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
Got set_part_info() from Mikael
sql/handler.cc:
We new use TABLE_SHARE instead of TABLE when creating engine handlers
ha_delete_table() now also takes database as an argument
handler::ha_open() now takes TABLE as argument
ha_open() now calls ha_allocate_read_write_set()
Simplify ha_allocate_read_write_set()
Remove ha_deallocate_read_write_set()
Use table_share (Cached by table definition cache)
sql/handler.h:
New table flag: HA_NO_COPY_ON_ALTER (used by merge tables)
Remove ha_deallocate_read_write_set()
get_new_handler() now takes TABLE_SHARE as argument
ha_delete_table() now gets database as argument
sql/item.cc:
table_name and db are now LEX_STRING objects
When creating fields, we have now have to call field->init(table)
move_field -> move_field_offset()
sql/item.h:
tmp_table_field_from_field_type() now takes an extra paramenter 'fixed_length' to allow one to force usage of CHAR
instead of BLOB
sql/item_cmpfunc.cc:
Fixed call to tmp_table_field_from_field_type()
sql/item_create.cc:
Assert if new not handled cast type
sql/item_func.cc:
When creating fields, we have now have to call field->init(table)
dummy_table used by 'sp' now needs a TABLE_SHARE object
sql/item_subselect.cc:
Trivial code cleanups
sql/item_sum.cc:
When creating fields, we have now have to call field->init(table)
sql/item_timefunc.cc:
Item_func_str_to_date::tmp_table_field() now replaced by call to
tmp_table_field_from_field_type() (see item_timefunc.h)
sql/item_timefunc.h:
Simply tmp_table_field()
sql/item_uniq.cc:
When creating fields, we have now have to call field->init(table)
sql/key.cc:
Added 'KEY' argument to 'find_ref_key' to simplify code
sql/lock.cc:
More debugging
Use create_table_def_key() to create key for table cache
Allocate TABLE_SHARE properly when creating name lock
Fix that locked_table_name doesn't test same table twice
sql/mysql_priv.h:
New functions for table definition cache
New interfaces to a lot of functions.
New faster interface to find_temporary_table() and close_temporary_table()
sql/mysqld.cc:
Added support for table definition cache of size 'table_def_size'
Fixed som calls to strnmov()
Changed name of 'table_cache' to 'table_open_cache'
sql/opt_range.cc:
Use new interfaces
Fixed warnings from valgrind
sql/parse_file.cc:
Safer calls to strxnmov()
Fixed typo
sql/set_var.cc:
Added variable 'table_definition_cache'
Variable table_cache renamed to 'table_open_cache'
sql/slave.cc:
Use new interface
sql/sp.cc:
Proper use of TABLE_SHARE
sql/sp_head.cc:
Remove compiler warnings
We have now to call field->init(table)
sql/sp_head.h:
Pointers to parsed strings are now const
sql/sql_acl.cc:
table_name is now a LEX_STRING
sql/sql_base.cc:
Main implementation of table definition cache
(The #ifdef's are there for the future when table definition cache will replace open table cache)
Now table definitions are cached indepndent of open tables, which will speed up things when a table is in use at once from several places
Views are not yet cached; For the moment we only cache if a table is a view or not.
Faster implementation of find_temorary_table()
Replace 'wait_for_refresh()' with the more general function 'wait_for_condition()'
Drop table is slightly faster as we can use the table definition cache to know the type of the table
sql/sql_cache.cc:
table_cache_key and table_name are now LEX_STRING
'sDBUG print fixes
sql/sql_class.cc:
table_cache_key is now a LEX_STRING
safer strxnmov()
sql/sql_class.h:
Added number of open table shares (table definitions)
sql/sql_db.cc:
safer strxnmov()
sql/sql_delete.cc:
Use new interface to find_temporary_table()
sql/sql_derived.cc:
table_name is now a LEX_STRING
sql/sql_handler.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_insert.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
sql/sql_lex.cc:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_lex.h:
Make parsed string a const (to quickly find out if anything is trying to change the query string)
sql/sql_load.cc:
Safer strxnmov()
sql/sql_parse.cc:
Better error if wrong DB name
sql/sql_partition.cc:
part_info moved to TABLE from TABLE_SHARE
Indentation changes
sql/sql_select.cc:
Indentation fixes
Call field->init(TABLE) for new created fields
Update create_tmp_table() to use TABLE_SHARE properly
sql/sql_select.h:
Call field->init(TABLE) for new created fields
sql/sql_show.cc:
table_name is now a LEX_STRING
part_info moved to TABLE
sql/sql_table.cc:
Use table definition cache to speed up delete of tables
Fixed calls to functions with new interfaces
Don't use 'share_not_to_be_used'
Instead of doing openfrm() when doing repair, we now have to call
get_table_share() followed by open_table_from_share().
Replace some fn_format() with faster unpack_filename().
Safer strxnmov()
part_info is now in TABLE
Added Mikaels patch for partition and ALTER TABLE
Instead of using 'TABLE_SHARE->is_view' use 'table_flags() & HA_NO_COPY_ON_ALTER
sql/sql_test.cc:
table_name and table_cache_key are now LEX_STRING's
sql/sql_trigger.cc:
TABLE_SHARE->db and TABLE_SHARE->table_name are now LEX_STRING's
safer strxnmov()
Removed compiler warnings
sql/sql_update.cc:
Call field->init(TABLE) after field is created
sql/sql_view.cc:
safer strxnmov()
Create common TABLE_SHARE object for views to allow us to cache if table is a view
sql/structs.h:
Added SHOW_TABLE_DEFINITIONS
sql/table.cc:
Creation and destruct of TABLE_SHARE objects that are common for many TABLE objects
The table opening process now works the following way:
- Create common TABLE_SHARE object
- Read the .frm file and unpack it into the TABLE_SHARE object
- Create a TABLE object based on the information in the TABLE_SHARE
object and open a handler to the table object
open_table_def() is written in such a way that it should be trival to add parsing of the .frm files in new formats
sql/table.h:
TABLE objects for the same database table now share a common TABLE_SHARE object
In TABLE_SHARE the most common strings are now LEX_STRING's
sql/unireg.cc:
Changed arguments to rea_create_table() to have same order as other functions
Call field->init(table) for new created fields
sql/unireg.h:
Added OPEN_VIEW
strings/strxnmov.c:
Change strxnmov() to always add end \0
This makes usage of strxnmov() safer as most of MySQL code assumes that strxnmov() will create a null terminated string
2005-11-23 21:45:02 +01:00
|
|
|
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
|
2003-10-19 13:22:17 +02:00
|
|
|
KEY *key_info= tab->table->key_info+ tab->ref.key;
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" on "));
|
2003-10-19 13:22:17 +02:00
|
|
|
str->append(key_info->name);
|
2003-10-16 14:54:47 +02:00
|
|
|
if (check_null)
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" checking NULL"));
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (cond)
|
2003-10-16 14:54:47 +02:00
|
|
|
{
|
2005-11-20 19:47:07 +01:00
|
|
|
str->append(STRING_WITH_LEN(" where "));
|
2008-02-22 11:30:33 +01:00
|
|
|
cond->print(str, query_type);
|
2003-10-16 14:54:47 +02:00
|
|
|
}
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
if (having)
|
|
|
|
{
|
|
|
|
str->append(STRING_WITH_LEN(" having "));
|
2008-02-22 11:30:33 +01:00
|
|
|
having->print(str, query_type);
|
BUG#24127: (a,b) IN (SELECT c,d ...) can produce wrong results if a and/or b are NULLs:
- Make the code produce correct result: use an array of triggers to turn on/off equalities for each
compared column. Also turn on/off optimizations based on those equalities.
- Make EXPLAIN output show "Full scan on NULL key" for tables for which we switch between
ref/unique_subquery/index_subquery and ALL access.
- index_subquery engine now has HAVING clause when it is needed, and it is
displayed in EXPLAIN EXTENDED
- Fix incorrect presense of "Using index" for index/unique-based subqueries (BUG#22930)
// bk trigger note: this commit refers to BUG#24127
mysql-test/r/ndb_subquery.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect2.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Updated test results (checked)
mysql-test/r/subselect3.result:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
mysql-test/t/subselect3.test:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Testcases
sql/item_cmpfunc.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- For row-based IN subqueries, use one flag per each column. Set the flags appropriately before
running the subquery.
sql/item_cmpfunc.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added Item_func_trig_cond::get_triv_var()
sql/item_subselect.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/item_subselect.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Item_subselect::exec() and subselect_*_engine::exec() don't have parameter
anymore - now Item_subselect owns the pushed down predicates guard flags.
- A correct set of conditional predicates is now pushed into row-based IN
subquery.
- select_indexsubquery_engine now has "HAVING clause" (needed for correct query
results), and it is shown in EXPLAIN EXTENDED
sql/mysql_priv.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/mysqld.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Added "in_having_cond" special Item name
sql/sql_lex.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
sql/sql_select.cc:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix subquery optimization code to match the changes in what kinds of
conditions are pushed down into subqueries
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
sql/sql_select.h:
BUG#24127: wrong result for (null,not-null) IN (SELECT a,b ...)
- Make "ref" analyzer be able to work with conditional equalities
- Fix wrong EXPLAIN output in some queries with subquery (BUG#22390)
2007-01-12 21:22:41 +01:00
|
|
|
}
|
2003-10-16 14:54:47 +02:00
|
|
|
str->append(')');
|
|
|
|
}
|
2004-05-07 22:06:11 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
change select_result object of engine.
|
2004-05-07 22:06:11 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@param si new subselect Item
|
|
|
|
@param res new select_result object
|
2004-05-07 22:06:11 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-20 03:04:37 +02:00
|
|
|
FALSE OK
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-20 03:04:37 +02:00
|
|
|
TRUE error
|
2004-05-07 22:06:11 +02:00
|
|
|
*/
|
|
|
|
|
2004-10-20 03:04:37 +02:00
|
|
|
bool subselect_single_select_engine::change_result(Item_subselect *si,
|
2010-01-28 14:48:33 +01:00
|
|
|
select_result_interceptor *res)
|
2004-05-07 22:06:11 +02:00
|
|
|
{
|
|
|
|
item= si;
|
|
|
|
result= res;
|
|
|
|
return select_lex->join->change_result(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
change select_result object of engine.
|
2004-05-07 22:06:11 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@param si new subselect Item
|
|
|
|
@param res new select_result object
|
2004-05-07 22:06:11 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-20 03:04:37 +02:00
|
|
|
FALSE OK
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-20 03:04:37 +02:00
|
|
|
TRUE error
|
2004-05-07 22:06:11 +02:00
|
|
|
*/
|
|
|
|
|
2004-10-20 03:04:37 +02:00
|
|
|
bool subselect_union_engine::change_result(Item_subselect *si,
|
2010-01-28 14:48:33 +01:00
|
|
|
select_result_interceptor *res)
|
2004-05-07 22:06:11 +02:00
|
|
|
{
|
|
|
|
item= si;
|
|
|
|
int rc= unit->change_result(res, result);
|
|
|
|
result= res;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
change select_result emulation, never should be called.
|
2004-05-07 22:06:11 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@param si new subselect Item
|
|
|
|
@param res new select_result object
|
2004-05-07 22:06:11 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-20 03:04:37 +02:00
|
|
|
FALSE OK
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-20 03:04:37 +02:00
|
|
|
TRUE error
|
2004-05-07 22:06:11 +02:00
|
|
|
*/
|
|
|
|
|
2004-10-20 03:04:37 +02:00
|
|
|
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si,
|
2010-01-28 14:48:33 +01:00
|
|
|
select_result_interceptor *res)
|
2004-05-07 22:06:11 +02:00
|
|
|
{
|
|
|
|
DBUG_ASSERT(0);
|
2004-10-20 03:04:37 +02:00
|
|
|
return TRUE;
|
2004-05-07 22:06:11 +02:00
|
|
|
}
|
2004-10-27 20:11:06 +02:00
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
Report about presence of tables in subquery.
|
2004-10-27 20:11:06 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-27 20:11:06 +02:00
|
|
|
TRUE there are not tables used in subquery
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-27 20:11:06 +02:00
|
|
|
FALSE there are some tables in subquery
|
|
|
|
*/
|
|
|
|
bool subselect_single_select_engine::no_tables()
|
|
|
|
{
|
|
|
|
return(select_lex->table_list.elements == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-12 03:57:23 +01:00
|
|
|
/*
|
|
|
|
Check statically whether the subquery can return NULL
|
|
|
|
|
|
|
|
SINOPSYS
|
|
|
|
subselect_single_select_engine::may_be_null()
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
FALSE can guarantee that the subquery never return NULL
|
|
|
|
TRUE otherwise
|
|
|
|
*/
|
|
|
|
bool subselect_single_select_engine::may_be_null()
|
|
|
|
{
|
|
|
|
return ((no_tables() && !join->conds && !join->having) ? maybe_null : 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
Report about presence of tables in subquery.
|
2004-10-27 20:11:06 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-27 20:11:06 +02:00
|
|
|
TRUE there are not tables used in subquery
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-27 20:11:06 +02:00
|
|
|
FALSE there are some tables in subquery
|
|
|
|
*/
|
|
|
|
bool subselect_union_engine::no_tables()
|
|
|
|
{
|
|
|
|
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
|
|
|
|
{
|
|
|
|
if (sl->table_list.elements)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
/**
|
|
|
|
Report about presence of tables in subquery.
|
2004-10-27 20:11:06 +02:00
|
|
|
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-27 20:11:06 +02:00
|
|
|
TRUE there are not tables used in subquery
|
2007-10-11 19:29:09 +02:00
|
|
|
@retval
|
2004-10-27 20:11:06 +02:00
|
|
|
FALSE there are some tables in subquery
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool subselect_uniquesubquery_engine::no_tables()
|
|
|
|
{
|
|
|
|
/* returning value is correct, but this method should never be called */
|
2010-02-19 22:55:57 +01:00
|
|
|
DBUG_ASSERT(FALSE);
|
2004-10-27 20:11:06 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2010-01-28 14:48:33 +01:00
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
WL#1110 - Implementation of class subselect_hash_sj_engine
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/**
|
|
|
|
Check if an IN predicate should be executed via partial matching using
|
|
|
|
only schema information.
|
|
|
|
|
|
|
|
@details
|
|
|
|
This test essentially has three results:
|
|
|
|
- partial matching is applicable, but cannot be executed due to a
|
|
|
|
limitation in the total number of indexes, as a result we can't
|
|
|
|
use subquery materialization at all.
|
|
|
|
- partial matching is either applicable or not, and this can be
|
|
|
|
determined by looking at 'this->max_keys'.
|
|
|
|
If max_keys > 1, then we need partial matching because there are
|
|
|
|
more indexes than just the one we use during materialization to
|
|
|
|
remove duplicates.
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
@note
|
|
|
|
TIMOUR: The schema-based analysis for partial matching can be done once for
|
|
|
|
prepared statement and remembered. It is done here to remove the need to
|
|
|
|
save/restore all related variables between each re-execution, thus making
|
|
|
|
the code simpler.
|
|
|
|
|
|
|
|
@retval PARTIAL_MATCH if a partial match should be used
|
|
|
|
@retval COMPLETE_MATCH if a complete match (index lookup) should be used
|
2010-02-19 22:55:57 +01:00
|
|
|
*/
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
subselect_hash_sj_engine::exec_strategy
|
|
|
|
subselect_hash_sj_engine::get_strategy_using_schema()
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
|
|
|
Item_in_subselect *item_in= (Item_in_subselect *) item;
|
|
|
|
|
|
|
|
if (item_in->is_top_level_item())
|
2010-03-09 11:14:06 +01:00
|
|
|
return COMPLETE_MATCH;
|
2010-02-19 22:55:57 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
List_iterator<Item> inner_col_it(*item_in->unit->get_unit_column_types());
|
|
|
|
Item *outer_col, *inner_col;
|
|
|
|
|
|
|
|
for (uint i= 0; i < item_in->left_expr->cols(); i++)
|
|
|
|
{
|
|
|
|
outer_col= item_in->left_expr->element_index(i);
|
|
|
|
inner_col= inner_col_it++;
|
|
|
|
|
|
|
|
if (!inner_col->maybe_null && !outer_col->maybe_null)
|
|
|
|
bitmap_set_bit(&non_null_key_parts, i);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bitmap_set_bit(&partial_match_key_parts, i);
|
|
|
|
++count_partial_match_columns;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If no column contains NULLs use regular hash index lookups. */
|
|
|
|
if (count_partial_match_columns)
|
2010-03-09 11:14:06 +01:00
|
|
|
return PARTIAL_MATCH;
|
|
|
|
return COMPLETE_MATCH;
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Test whether an IN predicate must be computed via partial matching
|
|
|
|
based on the NULL statistics for each column of a materialized subquery.
|
|
|
|
|
|
|
|
@details The procedure analyzes column NULL statistics, updates the
|
|
|
|
matching type of columns that cannot be NULL or that contain only NULLs.
|
|
|
|
Based on this, the procedure determines the final execution strategy for
|
|
|
|
the [NOT] IN predicate.
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
@retval PARTIAL_MATCH if a partial match should be used
|
|
|
|
@retval COMPLETE_MATCH if a complete match (index lookup) should be used
|
2010-02-19 22:55:57 +01:00
|
|
|
*/
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
subselect_hash_sj_engine::exec_strategy
|
|
|
|
subselect_hash_sj_engine::get_strategy_using_data()
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
|
|
|
Item_in_subselect *item_in= (Item_in_subselect *) item;
|
|
|
|
select_materialize_with_stats *result_sink=
|
|
|
|
(select_materialize_with_stats *) result;
|
|
|
|
Item *outer_col;
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
/*
|
|
|
|
If we already determined that a complete match is enough based on schema
|
|
|
|
information, nothing can be better.
|
|
|
|
*/
|
|
|
|
if (strategy == COMPLETE_MATCH)
|
|
|
|
return COMPLETE_MATCH;
|
2010-02-19 22:55:57 +01:00
|
|
|
|
|
|
|
for (uint i= 0; i < item_in->left_expr->cols(); i++)
|
|
|
|
{
|
|
|
|
if (!bitmap_is_set(&partial_match_key_parts, i))
|
|
|
|
continue;
|
|
|
|
outer_col= item_in->left_expr->element_index(i);
|
|
|
|
/*
|
|
|
|
If column 'i' doesn't contain NULLs, and the corresponding outer reference
|
|
|
|
cannot have a NULL value, then 'i' is a non-nullable column.
|
|
|
|
*/
|
|
|
|
if (result_sink->get_null_count_of_col(i) == 0 && !outer_col->maybe_null)
|
|
|
|
{
|
|
|
|
bitmap_clear_bit(&partial_match_key_parts, i);
|
|
|
|
bitmap_set_bit(&non_null_key_parts, i);
|
|
|
|
--count_partial_match_columns;
|
|
|
|
}
|
|
|
|
if (result_sink->get_null_count_of_col(i) ==
|
|
|
|
tmp_table->file->stats.records)
|
|
|
|
++count_null_only_columns;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If no column contains NULLs use regular hash index lookups. */
|
|
|
|
if (!count_partial_match_columns)
|
2010-03-09 11:14:06 +01:00
|
|
|
return COMPLETE_MATCH;
|
|
|
|
return PARTIAL_MATCH;
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
void
|
|
|
|
subselect_hash_sj_engine::choose_partial_match_strategy(
|
|
|
|
bool has_non_null_key, bool has_covering_null_row,
|
|
|
|
MY_BITMAP *partial_match_key_parts)
|
|
|
|
{
|
|
|
|
size_t pm_buff_size;
|
|
|
|
|
|
|
|
DBUG_ASSERT(strategy == PARTIAL_MATCH);
|
|
|
|
/*
|
|
|
|
Choose according to global optimizer switch. If only one of the switches is
|
|
|
|
'ON', then the remaining strategy is the only possible one. The only cases
|
|
|
|
when this will be overriden is when the total size of all buffers for the
|
|
|
|
merge strategy is bigger than the 'rowid_merge_buff_size' system variable,
|
|
|
|
or if there isn't enough physical memory to allocate the buffers.
|
|
|
|
*/
|
|
|
|
if (!optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) &&
|
|
|
|
optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN))
|
|
|
|
strategy= PARTIAL_MATCH_SCAN;
|
|
|
|
else if
|
|
|
|
( optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) &&
|
|
|
|
!optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN))
|
|
|
|
strategy= PARTIAL_MATCH_MERGE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
If both switches are ON, or both are OFF, we interpret that as "let the
|
|
|
|
optimizer decide". Perform a cost based choice between the two partial
|
|
|
|
matching strategies.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
TIMOUR: the above interpretation of the switch values could be changed to:
|
|
|
|
- if both are ON - let the optimizer decide,
|
|
|
|
- if both are OFF - do not use partial matching, therefore do not use
|
|
|
|
materialization in non-top-level predicates.
|
|
|
|
The problem with this is that we know for sure if we need partial matching
|
|
|
|
only after the subquery is materialized, and this is too late to revert to
|
|
|
|
the IN=>EXISTS strategy.
|
|
|
|
*/
|
|
|
|
if (strategy == PARTIAL_MATCH)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
TIMOUR: Currently we use a super simplistic measure. This will be
|
|
|
|
addressed in a separate task.
|
|
|
|
*/
|
|
|
|
if (tmp_table->file->stats.records < 100)
|
|
|
|
strategy= PARTIAL_MATCH_SCAN;
|
|
|
|
else
|
|
|
|
strategy= PARTIAL_MATCH_MERGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if there is enough memory for the rowid merge strategy. */
|
|
|
|
if (strategy == PARTIAL_MATCH_MERGE)
|
|
|
|
{
|
|
|
|
pm_buff_size= rowid_merge_buff_size(has_non_null_key,
|
|
|
|
has_covering_null_row,
|
|
|
|
partial_match_key_parts);
|
|
|
|
if (pm_buff_size > thd->variables.rowid_merge_buff_size)
|
|
|
|
strategy= PARTIAL_MATCH_SCAN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Compute the memory size of all buffers proportional to the number of rows
|
|
|
|
in tmp_table.
|
|
|
|
|
|
|
|
@details
|
|
|
|
If the result is bigger than thd->variables.rowid_merge_buff_size, partial
|
|
|
|
matching via merging is not applicable.
|
|
|
|
*/
|
|
|
|
|
|
|
|
size_t subselect_hash_sj_engine::rowid_merge_buff_size(
|
|
|
|
bool has_non_null_key, bool has_covering_null_row,
|
|
|
|
MY_BITMAP *partial_match_key_parts)
|
|
|
|
{
|
|
|
|
size_t buff_size; /* Total size of all buffers used by partial matching. */
|
|
|
|
ha_rows row_count= tmp_table->file->stats.records;
|
|
|
|
uint rowid_length= tmp_table->file->ref_length;
|
|
|
|
select_materialize_with_stats *result_sink=
|
|
|
|
(select_materialize_with_stats *) result;
|
|
|
|
|
|
|
|
/* Size of the subselect_rowid_merge_engine::row_num_to_rowid buffer. */
|
|
|
|
buff_size= row_count * rowid_length * sizeof(uchar);
|
|
|
|
|
|
|
|
if (has_non_null_key)
|
|
|
|
{
|
|
|
|
/* Add the size of Ordered_key::key_buff of the only non-NULL key. */
|
|
|
|
buff_size+= row_count * sizeof(rownum_t);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!has_covering_null_row)
|
|
|
|
{
|
|
|
|
for (uint i= 0; i < partial_match_key_parts->n_bits; i++)
|
|
|
|
{
|
|
|
|
if (!bitmap_is_set(partial_match_key_parts, i) ||
|
|
|
|
result_sink->get_null_count_of_col(i) == row_count)
|
|
|
|
continue; /* In these cases we wouldn't construct Ordered keys. */
|
|
|
|
|
|
|
|
/* Add the size of Ordered_key::key_buff */
|
|
|
|
buff_size+= (row_count - result_sink->get_null_count_of_col(i)) *
|
|
|
|
sizeof(rownum_t);
|
|
|
|
/* Add the size of Ordered_key::null_key */
|
|
|
|
buff_size+= bitmap_buffer_size(result_sink->get_max_null_of_col(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return buff_size;
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Initialize a MY_BITMAP with a buffer allocated on the current
|
|
|
|
memory root.
|
|
|
|
TIMOUR: move to bitmap C file?
|
|
|
|
*/
|
|
|
|
|
|
|
|
static my_bool
|
|
|
|
bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root)
|
|
|
|
{
|
|
|
|
my_bitmap_map *bitmap_buf;
|
|
|
|
|
|
|
|
if (!(bitmap_buf= (my_bitmap_map*) alloc_root(mem_root,
|
|
|
|
bitmap_buffer_size(n_bits))) ||
|
|
|
|
bitmap_init(map, bitmap_buf, n_bits, FALSE))
|
|
|
|
return TRUE;
|
|
|
|
bitmap_clear_all(map);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
/**
|
|
|
|
Create all structures needed for IN execution that can live between PS
|
|
|
|
reexecution.
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
@param tmp_columns the items that produce the data for the temp table
|
|
|
|
|
|
|
|
@details
|
2010-01-28 14:48:33 +01:00
|
|
|
- Create a temporary table to store the result of the IN subquery. The
|
|
|
|
temporary table has one hash index on all its columns.
|
|
|
|
- Create a new result sink that sends the result stream of the subquery to
|
|
|
|
the temporary table,
|
|
|
|
|
|
|
|
@notice:
|
|
|
|
Currently Item_subselect::init() already chooses and creates at parse
|
|
|
|
time an engine with a corresponding JOIN to execute the subquery.
|
|
|
|
|
|
|
|
@retval TRUE if error
|
|
|
|
@retval FALSE otherwise
|
|
|
|
*/
|
|
|
|
|
2010-07-16 12:52:02 +02:00
|
|
|
bool subselect_hash_sj_engine::init(List<Item> *tmp_columns)
|
2010-01-28 14:48:33 +01:00
|
|
|
{
|
2010-07-16 12:52:02 +02:00
|
|
|
select_union *result_sink;
|
2010-02-19 22:55:57 +01:00
|
|
|
/* Options to create_tmp_table. */
|
|
|
|
ulonglong tmp_create_options= thd->options | TMP_TABLE_ALL_COLUMNS;
|
|
|
|
/* | TMP_TABLE_FORCE_MYISAM; TIMOUR: force MYISAM */
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-07-16 12:52:02 +02:00
|
|
|
DBUG_ENTER("subselect_hash_sj_engine::init");
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
if (bitmap_init_memroot(&non_null_key_parts, tmp_columns->elements,
|
|
|
|
thd->mem_root) ||
|
|
|
|
bitmap_init_memroot(&partial_match_key_parts, tmp_columns->elements,
|
|
|
|
thd->mem_root))
|
|
|
|
DBUG_RETURN(TRUE);
|
2010-01-28 14:48:33 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Create and initialize a select result interceptor that stores the
|
|
|
|
result stream in a temporary table. The temporary table itself is
|
|
|
|
managed (created/filled/etc) internally by the interceptor.
|
|
|
|
*/
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
|
|
|
TIMOUR:
|
|
|
|
Select a more efficient result sink when we know there is no need to collect
|
|
|
|
data statistics.
|
|
|
|
|
|
|
|
if (strategy == COMPLETE_MATCH)
|
|
|
|
{
|
|
|
|
if (!(result= new select_union))
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
}
|
|
|
|
else if (strategy == PARTIAL_MATCH)
|
|
|
|
{
|
|
|
|
if (!(result= new select_materialize_with_stats))
|
2010-01-28 14:48:33 +01:00
|
|
|
DBUG_RETURN(TRUE);
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
*/
|
2010-07-16 12:52:02 +02:00
|
|
|
if (!(result_sink= new select_materialize_with_stats))
|
2010-02-19 22:55:57 +01:00
|
|
|
DBUG_RETURN(TRUE);
|
2010-07-16 12:52:02 +02:00
|
|
|
result_sink->get_tmp_table_param()->materialized_subquery= true;
|
|
|
|
if (result_sink->create_result_table(thd, tmp_columns, TRUE,
|
|
|
|
tmp_create_options,
|
|
|
|
"materialized subselect", TRUE))
|
2010-01-28 14:48:33 +01:00
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
|
2010-07-16 12:52:02 +02:00
|
|
|
tmp_table= result_sink->table;
|
|
|
|
result= result_sink;
|
2010-01-28 14:48:33 +01:00
|
|
|
|
|
|
|
/*
|
2010-02-19 22:55:57 +01:00
|
|
|
If the subquery has blobs, or the total key lenght is bigger than
|
|
|
|
some length, or the total number of key parts is more than the
|
|
|
|
allowed maximum (currently MAX_REF_PARTS == 16), then the created
|
|
|
|
index cannot be used for lookups and we can't use hash semi
|
|
|
|
join. If this is the case, delete the temporary table since it
|
|
|
|
will not be used, and tell the caller we failed to initialize the
|
|
|
|
engine.
|
2010-01-28 14:48:33 +01:00
|
|
|
*/
|
|
|
|
if (tmp_table->s->keys == 0)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(
|
|
|
|
tmp_table->s->uniques ||
|
|
|
|
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
|
|
|
|
tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
|
|
|
|
free_tmp_table(thd, tmp_table);
|
2010-02-19 22:55:57 +01:00
|
|
|
tmp_table= NULL;
|
2010-01-28 14:48:33 +01:00
|
|
|
delete result;
|
|
|
|
result= NULL;
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Make sure there is only one index on the temp table, and it doesn't have
|
|
|
|
the extra key part created when s->uniques > 0.
|
|
|
|
*/
|
2010-02-19 22:55:57 +01:00
|
|
|
DBUG_ASSERT(tmp_table->s->keys == 1 &&
|
|
|
|
((Item_in_subselect *) item)->left_expr->cols() ==
|
|
|
|
tmp_table->key_info->key_parts);
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
if (make_semi_join_conds() ||
|
|
|
|
/* A unique_engine is used both for complete and partial matching. */
|
|
|
|
!(lookup_engine= make_unique_engine()))
|
2010-02-19 22:55:57 +01:00
|
|
|
DBUG_RETURN(TRUE);
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-07-16 12:52:02 +02:00
|
|
|
/*
|
|
|
|
Repeat name resolution for 'cond' since cond is not part of any
|
|
|
|
clause of the query, and it is not 'fixed' during JOIN::prepare.
|
|
|
|
*/
|
|
|
|
if (semi_join_conds && !semi_join_conds->fixed &&
|
|
|
|
semi_join_conds->fix_fields(thd, (Item**)&semi_join_conds))
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
/* Let our engine reuse this query plan for materialization. */
|
|
|
|
materialize_join= materialize_engine->join;
|
|
|
|
materialize_join->change_result(result);
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
DBUG_RETURN(FALSE);
|
|
|
|
}
|
2010-01-28 14:48:33 +01:00
|
|
|
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
|
|
|
Create an artificial condition to post-filter those rows matched by index
|
|
|
|
lookups that cannot be distinguished by the index lookup procedure.
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
@notes
|
|
|
|
The need for post-filtering may occur e.g. because of
|
|
|
|
truncation. Prepared statements execution requires that fix_fields is
|
|
|
|
called for every execution. In order to call fix_fields we need to
|
|
|
|
create a Name_resolution_context and a corresponding TABLE_LIST for
|
|
|
|
the temporary table for the subquery, so that all column references
|
|
|
|
to the materialized subquery table can be resolved correctly.
|
|
|
|
|
|
|
|
@returns
|
|
|
|
@retval TRUE memory allocation error occurred
|
|
|
|
@retval FALSE the conditions were created and resolved (fixed)
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool subselect_hash_sj_engine::make_semi_join_conds()
|
|
|
|
{
|
2010-01-28 14:48:33 +01:00
|
|
|
/*
|
|
|
|
Table reference for tmp_table that is used to resolve column references
|
|
|
|
(Item_fields) to columns in tmp_table.
|
|
|
|
*/
|
|
|
|
TABLE_LIST *tmp_table_ref;
|
2010-02-19 22:55:57 +01:00
|
|
|
/* Name resolution context for all tmp_table columns created below. */
|
|
|
|
Name_resolution_context *context;
|
|
|
|
Item_in_subselect *item_in= (Item_in_subselect *) item;
|
|
|
|
|
|
|
|
DBUG_ENTER("subselect_hash_sj_engine::make_semi_join_conds");
|
|
|
|
DBUG_ASSERT(semi_join_conds == NULL);
|
|
|
|
|
|
|
|
if (!(semi_join_conds= new Item_cond_and))
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
if (!(tmp_table_ref= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST))))
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
|
|
|
|
tmp_table_ref->init_one_table("", "materialized subselect", TL_READ);
|
|
|
|
tmp_table_ref->table= tmp_table;
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
context= new Name_resolution_context;
|
2010-01-28 14:48:33 +01:00
|
|
|
context->init();
|
|
|
|
context->first_name_resolution_table=
|
|
|
|
context->last_name_resolution_table= tmp_table_ref;
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
for (uint i= 0; i < item_in->left_expr->cols(); i++)
|
2010-01-28 14:48:33 +01:00
|
|
|
{
|
|
|
|
Item_func_eq *eq_cond; /* New equi-join condition for the current column. */
|
|
|
|
/* Item for the corresponding field from the materialized temp table. */
|
|
|
|
Item_field *right_col_item;
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
if (!(right_col_item= new Item_field(thd, context, tmp_table->field[i])) ||
|
|
|
|
!(eq_cond= new Item_func_eq(item_in->left_expr->element_index(i),
|
|
|
|
right_col_item)) ||
|
|
|
|
(((Item_cond_and*)semi_join_conds)->add(eq_cond)))
|
2010-01-28 14:48:33 +01:00
|
|
|
{
|
2010-02-19 22:55:57 +01:00
|
|
|
delete semi_join_conds;
|
|
|
|
semi_join_conds= NULL;
|
2010-01-28 14:48:33 +01:00
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
}
|
|
|
|
}
|
2010-03-09 11:14:06 +01:00
|
|
|
if (semi_join_conds->fix_fields(thd, (Item**)&semi_join_conds))
|
2010-01-28 14:48:33 +01:00
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
|
|
|
|
DBUG_RETURN(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2010-02-19 22:55:57 +01:00
|
|
|
Create a new uniquesubquery engine for the execution of an IN predicate.
|
|
|
|
|
|
|
|
@details
|
|
|
|
Create and initialize a new JOIN_TAB, and Table_ref objects to perform
|
|
|
|
lookups into the indexed temporary table.
|
|
|
|
|
|
|
|
@retval A new subselect_hash_sj_engine object
|
|
|
|
@retval NULL if a memory allocation error occurs
|
|
|
|
*/
|
|
|
|
|
|
|
|
subselect_uniquesubquery_engine*
|
|
|
|
subselect_hash_sj_engine::make_unique_engine()
|
|
|
|
{
|
|
|
|
Item_in_subselect *item_in= (Item_in_subselect *) item;
|
2010-07-10 12:37:30 +02:00
|
|
|
Item_iterator_row it(item_in->left_expr);
|
2010-02-19 22:55:57 +01:00
|
|
|
/* The only index on the temporary table. */
|
|
|
|
KEY *tmp_key= tmp_table->key_info;
|
|
|
|
JOIN_TAB *tab;
|
|
|
|
|
|
|
|
DBUG_ENTER("subselect_hash_sj_engine::make_unique_engine");
|
|
|
|
|
|
|
|
/*
|
|
|
|
Create and initialize the JOIN_TAB that represents an index lookup
|
|
|
|
plan operator into the materialized subquery result. Notice that:
|
|
|
|
- this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
|
|
|
|
- here we initialize only those members that are used by
|
|
|
|
subselect_uniquesubquery_engine, so these objects are incomplete.
|
|
|
|
*/
|
|
|
|
if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
|
|
|
|
DBUG_RETURN(NULL);
|
|
|
|
|
2010-07-10 12:37:30 +02:00
|
|
|
tab->table= tmp_table;
|
|
|
|
tab->ref.tmp_table_index_lookup_init(thd, tmp_key, it, FALSE);
|
2010-02-19 22:55:57 +01:00
|
|
|
|
|
|
|
DBUG_RETURN(new subselect_uniquesubquery_engine(thd, tab, item,
|
|
|
|
semi_join_conds));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-16 12:52:02 +02:00
|
|
|
subselect_hash_sj_engine::~subselect_hash_sj_engine()
|
|
|
|
{
|
|
|
|
delete lookup_engine;
|
|
|
|
delete result;
|
|
|
|
if (tmp_table)
|
|
|
|
free_tmp_table(thd, tmp_table);
|
|
|
|
}
|
2010-01-28 14:48:33 +01:00
|
|
|
|
|
|
|
|
2010-07-16 12:52:02 +02:00
|
|
|
int subselect_hash_sj_engine::prepare()
|
2010-01-28 14:48:33 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
Create and optimize the JOIN that will be used to materialize
|
|
|
|
the subquery if not yet created.
|
|
|
|
*/
|
2010-07-16 12:52:02 +02:00
|
|
|
return materialize_engine->prepare();
|
2010-01-28 14:48:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Cleanup performed after each PS execution.
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
@details
|
2010-01-28 14:48:33 +01:00
|
|
|
Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void subselect_hash_sj_engine::cleanup()
|
|
|
|
{
|
2010-03-09 11:14:06 +01:00
|
|
|
enum_engine_type lookup_engine_type= lookup_engine->engine_type();
|
2010-01-28 14:48:33 +01:00
|
|
|
is_materialized= FALSE;
|
2010-03-09 11:14:06 +01:00
|
|
|
bitmap_clear_all(&non_null_key_parts);
|
|
|
|
bitmap_clear_all(&partial_match_key_parts);
|
|
|
|
count_partial_match_columns= 0;
|
|
|
|
count_null_only_columns= 0;
|
|
|
|
strategy= UNDEFINED;
|
2010-01-28 14:48:33 +01:00
|
|
|
materialize_engine->cleanup();
|
2010-07-16 12:52:02 +02:00
|
|
|
/*
|
|
|
|
Restore the original Item_in_subselect engine. This engine is created once
|
|
|
|
at parse time and stored across executions, while all other materialization
|
|
|
|
related engines are created and chosen for each execution.
|
|
|
|
*/
|
|
|
|
((Item_in_subselect *) item)->engine= materialize_engine;
|
2010-03-09 11:14:06 +01:00
|
|
|
if (lookup_engine_type == TABLE_SCAN_ENGINE ||
|
|
|
|
lookup_engine_type == ROWID_MERGE_ENGINE)
|
|
|
|
{
|
|
|
|
subselect_engine *inner_lookup_engine;
|
|
|
|
inner_lookup_engine=
|
|
|
|
((subselect_partial_match_engine*) lookup_engine)->lookup_engine;
|
|
|
|
/*
|
|
|
|
Partial match engines are recreated for each PS execution inside
|
|
|
|
subselect_hash_sj_engine::exec().
|
|
|
|
*/
|
|
|
|
delete lookup_engine;
|
|
|
|
lookup_engine= inner_lookup_engine;
|
|
|
|
}
|
|
|
|
DBUG_ASSERT(lookup_engine->engine_type() == UNIQUESUBQUERY_ENGINE);
|
|
|
|
lookup_engine->cleanup();
|
|
|
|
result->cleanup(); /* Resets the temp table as well. */
|
2010-07-16 12:52:02 +02:00
|
|
|
DBUG_ASSERT(tmp_table);
|
|
|
|
free_tmp_table(thd, tmp_table);
|
|
|
|
tmp_table= NULL;
|
2010-01-28 14:48:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Execute a subquery IN predicate via materialization.
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
@details
|
2010-01-28 14:48:33 +01:00
|
|
|
If needed materialize the subquery into a temporary table, then
|
|
|
|
copmpute the predicate via a lookup into this table.
|
|
|
|
|
|
|
|
@retval TRUE if error
|
|
|
|
@retval FALSE otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
int subselect_hash_sj_engine::exec()
|
|
|
|
{
|
|
|
|
Item_in_subselect *item_in= (Item_in_subselect *) item;
|
2010-02-19 22:55:57 +01:00
|
|
|
SELECT_LEX *save_select= thd->lex->current_select;
|
2010-03-09 11:14:06 +01:00
|
|
|
subselect_partial_match_engine *pm_engine= NULL;
|
2010-02-19 22:55:57 +01:00
|
|
|
int res= 0;
|
2010-01-28 14:48:33 +01:00
|
|
|
|
|
|
|
DBUG_ENTER("subselect_hash_sj_engine::exec");
|
|
|
|
|
|
|
|
/*
|
|
|
|
Optimize and materialize the subquery during the first execution of
|
|
|
|
the subquery predicate.
|
|
|
|
*/
|
2010-02-19 22:55:57 +01:00
|
|
|
thd->lex->current_select= materialize_engine->select_lex;
|
2010-07-16 12:52:02 +02:00
|
|
|
/* The subquery should be optimized, and materialized only once. */
|
|
|
|
DBUG_ASSERT(materialize_join->optimized && !is_materialized);
|
2010-02-19 22:55:57 +01:00
|
|
|
materialize_join->exec();
|
|
|
|
if ((res= test(materialize_join->error || thd->is_fatal_error)))
|
|
|
|
goto err;
|
2010-01-28 14:48:33 +01:00
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
|
|
|
TODO:
|
|
|
|
- Unlock all subquery tables as we don't need them. To implement this
|
|
|
|
we need to add new functionality to JOIN::join_free that can unlock
|
|
|
|
all tables in a subquery (and all its subqueries).
|
|
|
|
- The temp table used for grouping in the subquery can be freed
|
|
|
|
immediately after materialization (yet it's done together with
|
|
|
|
unlocking).
|
|
|
|
*/
|
|
|
|
is_materialized= TRUE;
|
|
|
|
/*
|
|
|
|
If the subquery returned no rows, the temporary table is empty, so we know
|
|
|
|
directly that the result of IN is FALSE. We first update the table
|
|
|
|
statistics, then we test if the temporary table for the query result is
|
|
|
|
empty.
|
|
|
|
*/
|
|
|
|
tmp_table->file->info(HA_STATUS_VARIABLE);
|
|
|
|
if (!tmp_table->file->stats.records)
|
|
|
|
{
|
|
|
|
item_in->value= FALSE;
|
|
|
|
/* The value of IN will not change during this execution. */
|
|
|
|
item_in->is_constant= TRUE;
|
|
|
|
item_in->set_first_execution();
|
|
|
|
/* TIMOUR: check if we need this: item_in->null_value= FALSE; */
|
|
|
|
DBUG_RETURN(FALSE);
|
|
|
|
}
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
/*
|
|
|
|
TIMOUR: The schema-based analysis for partial matching can be done once for
|
|
|
|
prepared statement and remembered. It is done here to remove the need to
|
|
|
|
save/restore all related variables between each re-execution, thus making
|
|
|
|
the code simpler.
|
|
|
|
*/
|
|
|
|
strategy= get_strategy_using_schema();
|
|
|
|
/* This call may discover that we don't need partial matching at all. */
|
|
|
|
strategy= get_strategy_using_data();
|
2010-02-19 22:55:57 +01:00
|
|
|
if (strategy == PARTIAL_MATCH)
|
|
|
|
{
|
2010-03-09 11:14:06 +01:00
|
|
|
uint count_pm_keys; /* Total number of keys needed for partial matching. */
|
|
|
|
MY_BITMAP *nn_key_parts; /* The key parts of the only non-NULL index. */
|
|
|
|
uint covering_null_row_width;
|
2010-02-19 22:55:57 +01:00
|
|
|
select_materialize_with_stats *result_sink=
|
|
|
|
(select_materialize_with_stats *) result;
|
|
|
|
|
|
|
|
nn_key_parts= (count_partial_match_columns < tmp_table->s->fields) ?
|
|
|
|
&non_null_key_parts : NULL;
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
if (result_sink->get_max_nulls_in_row() ==
|
|
|
|
tmp_table->s->fields -
|
|
|
|
(nn_key_parts ? bitmap_bits_set(nn_key_parts) : 0))
|
|
|
|
covering_null_row_width= result_sink->get_max_nulls_in_row();
|
|
|
|
else
|
|
|
|
covering_null_row_width= 0;
|
2010-02-19 22:55:57 +01:00
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
if (covering_null_row_width)
|
2010-02-19 22:55:57 +01:00
|
|
|
count_pm_keys= nn_key_parts ? 1 : 0;
|
|
|
|
else
|
|
|
|
count_pm_keys= count_partial_match_columns - count_null_only_columns +
|
|
|
|
(nn_key_parts ? 1 : 0);
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
choose_partial_match_strategy(test(nn_key_parts),
|
|
|
|
test(covering_null_row_width),
|
|
|
|
&partial_match_key_parts);
|
|
|
|
DBUG_ASSERT(strategy == PARTIAL_MATCH_MERGE ||
|
|
|
|
strategy == PARTIAL_MATCH_SCAN);
|
|
|
|
if (strategy == PARTIAL_MATCH_MERGE)
|
2010-01-28 14:48:33 +01:00
|
|
|
{
|
2010-03-09 11:14:06 +01:00
|
|
|
pm_engine=
|
|
|
|
new subselect_rowid_merge_engine((subselect_uniquesubquery_engine*)
|
|
|
|
lookup_engine, tmp_table,
|
|
|
|
count_pm_keys,
|
|
|
|
covering_null_row_width,
|
|
|
|
item, result,
|
|
|
|
semi_join_conds->argument_list());
|
|
|
|
if (!pm_engine ||
|
|
|
|
((subselect_rowid_merge_engine*) pm_engine)->
|
|
|
|
init(nn_key_parts, &partial_match_key_parts))
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
The call to init() would fail if there was not enough memory to allocate
|
|
|
|
all buffers for the rowid merge strategy. In this case revert to table
|
|
|
|
scanning which doesn't need any big buffers.
|
|
|
|
*/
|
|
|
|
delete pm_engine;
|
|
|
|
pm_engine= NULL;
|
|
|
|
strategy= PARTIAL_MATCH_SCAN;
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
if (strategy == PARTIAL_MATCH_SCAN)
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
2010-03-09 11:14:06 +01:00
|
|
|
if (!(pm_engine=
|
|
|
|
new subselect_table_scan_engine((subselect_uniquesubquery_engine*)
|
|
|
|
lookup_engine, tmp_table,
|
|
|
|
item, result,
|
|
|
|
semi_join_conds->argument_list(),
|
|
|
|
covering_null_row_width)))
|
|
|
|
{
|
|
|
|
/* This is an irrecoverable error. */
|
|
|
|
res= 1;
|
|
|
|
goto err;
|
|
|
|
}
|
2010-01-28 14:48:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
if (pm_engine)
|
|
|
|
lookup_engine= pm_engine;
|
2010-02-19 22:55:57 +01:00
|
|
|
item_in->change_engine(lookup_engine);
|
|
|
|
|
|
|
|
err:
|
|
|
|
thd->lex->current_select= save_select;
|
|
|
|
DBUG_RETURN(res);
|
2010-01-28 14:48:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Print the state of this engine into a string for debugging and views.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void subselect_hash_sj_engine::print(String *str, enum_query_type query_type)
|
|
|
|
{
|
|
|
|
str->append(STRING_WITH_LEN(" <materialize> ("));
|
|
|
|
materialize_engine->print(str, query_type);
|
|
|
|
str->append(STRING_WITH_LEN(" ), "));
|
2010-02-19 22:55:57 +01:00
|
|
|
|
|
|
|
if (lookup_engine)
|
|
|
|
lookup_engine->print(str, query_type);
|
2010-01-28 14:48:33 +01:00
|
|
|
else
|
|
|
|
str->append(STRING_WITH_LEN(
|
2010-02-22 16:16:55 +01:00
|
|
|
"<engine selected at execution time>"
|
2010-01-28 14:48:33 +01:00
|
|
|
));
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
|
|
|
|
void subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void subselect_hash_sj_engine::exclude()
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool subselect_hash_sj_engine::no_tables()
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(FALSE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool subselect_hash_sj_engine::change_result(Item_subselect *si,
|
|
|
|
select_result_interceptor *res)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(FALSE);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-22 16:16:55 +01:00
|
|
|
Ordered_key::Ordered_key(uint keyid_arg, TABLE *tbl_arg, Item *search_key_arg,
|
|
|
|
ha_rows null_count_arg, ha_rows min_null_row_arg,
|
|
|
|
ha_rows max_null_row_arg, uchar *row_num_to_rowid_arg)
|
|
|
|
: keyid(keyid_arg), tbl(tbl_arg), search_key(search_key_arg),
|
2010-02-19 22:55:57 +01:00
|
|
|
row_num_to_rowid(row_num_to_rowid_arg), null_count(null_count_arg)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(tbl->file->stats.records > null_count);
|
|
|
|
key_buff_elements= tbl->file->stats.records - null_count;
|
|
|
|
cur_key_idx= HA_POS_ERROR;
|
|
|
|
|
|
|
|
DBUG_ASSERT((null_count && min_null_row_arg && max_null_row_arg) ||
|
|
|
|
(!null_count && !min_null_row_arg && !max_null_row_arg));
|
|
|
|
if (null_count)
|
|
|
|
{
|
|
|
|
/* The counters are 1-based, for key access we need 0-based indexes. */
|
|
|
|
min_null_row= min_null_row_arg - 1;
|
|
|
|
max_null_row= max_null_row_arg - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
min_null_row= max_null_row= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ordered_key::~Ordered_key()
|
|
|
|
{
|
2010-03-09 11:14:06 +01:00
|
|
|
my_free((char*) key_buff, MYF(0));
|
|
|
|
bitmap_free(&null_key);
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Cleanup that needs to be done for each PS (re)execution.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void Ordered_key::cleanup()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Currently these keys are recreated for each PS re-execution, thus
|
|
|
|
there is nothing to cleanup, the whole object goes away after execution
|
|
|
|
is over. All handler related initialization/deinitialization is done by
|
|
|
|
the parent subselect_rowid_merge_engine object.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
|
|
|
Initialize a multi-column index.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Ordered_key::init(MY_BITMAP *columns_to_index)
|
|
|
|
{
|
|
|
|
THD *thd= tbl->in_use;
|
|
|
|
uint cur_key_col= 0;
|
|
|
|
Item_field *cur_tmp_field;
|
|
|
|
Item_func_lt *fn_less_than;
|
|
|
|
|
|
|
|
key_column_count= bitmap_bits_set(columns_to_index);
|
|
|
|
|
|
|
|
// TIMOUR: check for mem allocation err, revert to scan
|
|
|
|
|
|
|
|
key_columns= (Item_field**) thd->alloc(key_column_count *
|
|
|
|
sizeof(Item_field*));
|
|
|
|
compare_pred= (Item_func_lt**) thd->alloc(key_column_count *
|
|
|
|
sizeof(Item_func_lt*));
|
|
|
|
|
|
|
|
for (uint i= 0; i < columns_to_index->n_bits; i++)
|
|
|
|
{
|
|
|
|
if (!bitmap_is_set(columns_to_index, i))
|
|
|
|
continue;
|
|
|
|
cur_tmp_field= new Item_field(tbl->field[i]);
|
|
|
|
/* Create the predicate (tmp_column[i] < outer_ref[i]). */
|
|
|
|
fn_less_than= new Item_func_lt(cur_tmp_field,
|
|
|
|
search_key->element_index(i));
|
|
|
|
fn_less_than->fix_fields(thd, (Item**) &fn_less_than);
|
|
|
|
key_columns[cur_key_col]= cur_tmp_field;
|
|
|
|
compare_pred[cur_key_col]= fn_less_than;
|
|
|
|
++cur_key_col;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (alloc_keys_buffers())
|
|
|
|
{
|
|
|
|
/* TIMOUR revert to partial match via table scan. */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Initialize a single-column index.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Ordered_key::init(int col_idx)
|
|
|
|
{
|
|
|
|
THD *thd= tbl->in_use;
|
|
|
|
|
|
|
|
key_column_count= 1;
|
|
|
|
|
|
|
|
// TIMOUR: check for mem allocation err, revert to scan
|
|
|
|
|
|
|
|
key_columns= (Item_field**) thd->alloc(sizeof(Item_field*));
|
|
|
|
compare_pred= (Item_func_lt**) thd->alloc(sizeof(Item_func_lt*));
|
|
|
|
|
|
|
|
key_columns[0]= new Item_field(tbl->field[col_idx]);
|
|
|
|
/* Create the predicate (tmp_column[i] < outer_ref[i]). */
|
|
|
|
compare_pred[0]= new Item_func_lt(key_columns[0],
|
|
|
|
search_key->element_index(col_idx));
|
|
|
|
compare_pred[0]->fix_fields(thd, (Item**)&compare_pred[0]);
|
|
|
|
|
|
|
|
if (alloc_keys_buffers())
|
|
|
|
{
|
|
|
|
/* TIMOUR revert to partial match via table scan. */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
/*
|
|
|
|
Allocate the buffers for both the row number, and the NULL-bitmap indexes.
|
|
|
|
*/
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
bool Ordered_key::alloc_keys_buffers()
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(key_buff_elements > 0);
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
if (!(key_buff= (rownum_t*) my_malloc(key_buff_elements * sizeof(rownum_t),
|
|
|
|
MYF(MY_WME))))
|
2010-02-19 22:55:57 +01:00
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
TIMOUR: it is enough to create bitmaps with size
|
|
|
|
(max_null_row - min_null_row), and then use min_null_row as
|
|
|
|
lookup offset.
|
|
|
|
*/
|
2010-03-09 11:14:06 +01:00
|
|
|
/* Notice that max_null_row is max array index, we need count, so +1. */
|
|
|
|
if (bitmap_init(&null_key, NULL, max_null_row + 1, FALSE))
|
2010-02-19 22:55:57 +01:00
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
cur_key_idx= HA_POS_ERROR;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Quick sort comparison function that compares two rows of the same table
|
|
|
|
indentfied with their row numbers.
|
|
|
|
|
|
|
|
@retval -1
|
|
|
|
@retval 0
|
|
|
|
@retval +1
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
|
|
|
Ordered_key::cmp_keys_by_row_data(ha_rows a, ha_rows b)
|
|
|
|
{
|
|
|
|
uchar *rowid_a, *rowid_b;
|
|
|
|
int error, cmp_res;
|
|
|
|
/* The length in bytes of the rowids (positions) of tmp_table. */
|
|
|
|
uint rowid_length= tbl->file->ref_length;
|
|
|
|
|
|
|
|
if (a == b)
|
|
|
|
return 0;
|
|
|
|
/* Get the corresponding rowids. */
|
|
|
|
rowid_a= row_num_to_rowid + a * rowid_length;
|
|
|
|
rowid_b= row_num_to_rowid + b * rowid_length;
|
|
|
|
/* Fetch the rows for comparison. */
|
|
|
|
error= tbl->file->ha_rnd_pos(tbl->record[0], rowid_a);
|
|
|
|
DBUG_ASSERT(!error);
|
|
|
|
error= tbl->file->ha_rnd_pos(tbl->record[1], rowid_b);
|
|
|
|
DBUG_ASSERT(!error);
|
|
|
|
/*
|
|
|
|
Compare the two rows by the corresponding values of the indexed
|
|
|
|
columns.
|
|
|
|
*/
|
|
|
|
for (uint i= 0; i < key_column_count; i++)
|
|
|
|
{
|
|
|
|
Field *cur_field= key_columns[i]->field;
|
|
|
|
if ((cmp_res= cur_field->cmp_offset(tbl->s->rec_buff_length)))
|
|
|
|
return (cmp_res > 0 ? 1 : -1);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
Ordered_key::cmp_keys_by_row_data_and_rownum(Ordered_key *key,
|
|
|
|
rownum_t* a, rownum_t* b)
|
|
|
|
{
|
|
|
|
/* The result of comparing the two keys according to their row data. */
|
|
|
|
int cmp_row_res= key->cmp_keys_by_row_data(*a, *b);
|
|
|
|
if (cmp_row_res)
|
|
|
|
return cmp_row_res;
|
|
|
|
return (*a < *b) ? -1 : (*a > *b) ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Ordered_key::sort_keys()
|
|
|
|
{
|
|
|
|
my_qsort2(key_buff, key_buff_elements, sizeof(rownum_t),
|
|
|
|
(qsort2_cmp) &cmp_keys_by_row_data_and_rownum, (void*) this);
|
|
|
|
/* Invalidate the current row position. */
|
|
|
|
cur_key_idx= HA_POS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-22 16:16:55 +01:00
|
|
|
/*
|
2010-03-09 11:14:06 +01:00
|
|
|
The fraction of rows that do not contain NULL in the columns indexed by
|
|
|
|
this key.
|
|
|
|
|
2010-02-22 16:16:55 +01:00
|
|
|
@retval 1 if there are no NULLs
|
|
|
|
@retval 0 if only NULLs
|
|
|
|
*/
|
|
|
|
|
|
|
|
double Ordered_key::null_selectivity()
|
|
|
|
{
|
|
|
|
/* We should not be processing empty tables. */
|
|
|
|
DBUG_ASSERT(tbl->file->stats.records);
|
|
|
|
return (1 - (double) null_count / (double) tbl->file->stats.records);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
|
|
|
Compare the value(s) of the current key in 'search_key' with the
|
|
|
|
data of the current table record.
|
|
|
|
|
|
|
|
@notes The comparison result follows from the way compare_pred
|
|
|
|
is created in Ordered_key::init. Currently compare_pred compares
|
|
|
|
a field in of the current row with the corresponding Item that
|
|
|
|
contains the search key.
|
|
|
|
|
|
|
|
@param row_num Number of the row (not index in the key_buff array)
|
|
|
|
|
|
|
|
@retval -1 if (current row < search_key)
|
|
|
|
@retval 0 if (current row == search_key)
|
|
|
|
@retval +1 if (current row > search_key)
|
|
|
|
*/
|
|
|
|
|
|
|
|
int Ordered_key::cmp_key_with_search_key(rownum_t row_num)
|
|
|
|
{
|
|
|
|
/* The length in bytes of the rowids (positions) of tmp_table. */
|
|
|
|
uint rowid_length= tbl->file->ref_length;
|
|
|
|
uchar *cur_rowid= row_num_to_rowid + row_num * rowid_length;
|
|
|
|
int error, cmp_res;
|
|
|
|
|
|
|
|
error= tbl->file->ha_rnd_pos(tbl->record[0], cur_rowid);
|
|
|
|
DBUG_ASSERT(!error);
|
|
|
|
|
|
|
|
for (uint i= 0; i < key_column_count; i++)
|
|
|
|
{
|
|
|
|
cmp_res= compare_pred[i]->get_comparator()->compare();
|
|
|
|
/* Unlike Arg_comparator::compare_row() here there should be no NULLs. */
|
|
|
|
DBUG_ASSERT(!compare_pred[i]->null_value);
|
|
|
|
if (cmp_res)
|
|
|
|
return (cmp_res > 0 ? 1 : -1);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Find a key in a sorted array of keys via binary search.
|
|
|
|
|
|
|
|
see create_subq_in_equalities()
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Ordered_key::lookup()
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(key_buff_elements);
|
|
|
|
|
|
|
|
ha_rows lo= 0;
|
|
|
|
ha_rows hi= key_buff_elements - 1;
|
|
|
|
ha_rows mid;
|
|
|
|
int cmp_res;
|
|
|
|
|
|
|
|
while (lo <= hi)
|
|
|
|
{
|
|
|
|
mid= lo + (hi - lo) / 2;
|
|
|
|
cmp_res= cmp_key_with_search_key(key_buff[mid]);
|
|
|
|
/*
|
|
|
|
In order to find the minimum match, check if the pevious element is
|
|
|
|
equal or smaller than the found one. If equal, we need to search further
|
|
|
|
to the left.
|
|
|
|
*/
|
|
|
|
if (!cmp_res && mid > 0)
|
|
|
|
cmp_res= !cmp_key_with_search_key(key_buff[mid - 1]) ? 1 : 0;
|
|
|
|
|
|
|
|
if (cmp_res == -1)
|
|
|
|
{
|
|
|
|
/* row[mid] < search_key */
|
|
|
|
lo= mid + 1;
|
|
|
|
}
|
|
|
|
else if (cmp_res == 1)
|
|
|
|
{
|
|
|
|
/* row[mid] > search_key */
|
|
|
|
if (!mid)
|
|
|
|
goto not_found;
|
|
|
|
hi= mid - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* row[mid] == search_key */
|
|
|
|
cur_key_idx= mid;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
not_found:
|
|
|
|
cur_key_idx= HA_POS_ERROR;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Move the current index pointer to the next key with the same column
|
|
|
|
values as the current key. Since the index is sorted, all such keys
|
|
|
|
are contiguous.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool Ordered_key::next_same()
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(key_buff_elements);
|
|
|
|
|
|
|
|
if (cur_key_idx < key_buff_elements - 1)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
TIMOUR:
|
|
|
|
The below is quite inefficient, since as a result we will fetch every
|
|
|
|
row (except the last one) twice. There must be a more efficient way,
|
|
|
|
e.g. swapping record[0] and record[1], and reading only the new record.
|
|
|
|
*/
|
|
|
|
if (!cmp_keys_by_row_data(key_buff[cur_key_idx], key_buff[cur_key_idx + 1]))
|
|
|
|
{
|
|
|
|
++cur_key_idx;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-22 16:16:55 +01:00
|
|
|
void Ordered_key::print(String *str)
|
|
|
|
{
|
|
|
|
uint i;
|
|
|
|
str->append("{idx=");
|
|
|
|
str->qs_append(keyid);
|
|
|
|
str->append(", (");
|
|
|
|
for (i= 0; i < key_column_count - 1; i++)
|
|
|
|
{
|
|
|
|
str->append(key_columns[i]->field->field_name);
|
|
|
|
str->append(", ");
|
|
|
|
}
|
|
|
|
str->append(key_columns[i]->field->field_name);
|
|
|
|
str->append("), ");
|
|
|
|
|
|
|
|
str->append("null_bitmap: (bits=");
|
|
|
|
str->qs_append(null_key.n_bits);
|
|
|
|
str->append(", nulls= ");
|
|
|
|
str->qs_append((double)null_count);
|
|
|
|
str->append(", min_null= ");
|
|
|
|
str->qs_append((double)min_null_row);
|
|
|
|
str->append(", max_null= ");
|
|
|
|
str->qs_append((double)max_null_row);
|
|
|
|
str->append("), ");
|
|
|
|
|
|
|
|
str->append('}');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
subselect_partial_match_engine::subselect_partial_match_engine(
|
|
|
|
subselect_uniquesubquery_engine *engine_arg,
|
|
|
|
TABLE *tmp_table_arg, Item_subselect *item_arg,
|
|
|
|
select_result_interceptor *result_arg,
|
|
|
|
List<Item> *equi_join_conds_arg,
|
|
|
|
uint covering_null_row_width_arg)
|
|
|
|
:subselect_engine(item_arg, result_arg),
|
|
|
|
tmp_table(tmp_table_arg), lookup_engine(engine_arg),
|
|
|
|
equi_join_conds(equi_join_conds_arg),
|
|
|
|
covering_null_row_width(covering_null_row_width_arg)
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
int subselect_partial_match_engine::exec()
|
|
|
|
{
|
|
|
|
Item_in_subselect *item_in= (Item_in_subselect *) item;
|
|
|
|
int res;
|
|
|
|
|
|
|
|
/* Try to find a matching row by index lookup. */
|
|
|
|
res= lookup_engine->copy_ref_key_simple();
|
|
|
|
if (res == -1)
|
|
|
|
{
|
|
|
|
/* The result is FALSE based on the outer reference. */
|
|
|
|
item_in->value= 0;
|
|
|
|
item_in->null_value= 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (res == 0)
|
|
|
|
{
|
|
|
|
/* Search for a complete match. */
|
|
|
|
if ((res= lookup_engine->index_lookup()))
|
|
|
|
{
|
|
|
|
/* An error occured during lookup(). */
|
|
|
|
item_in->value= 0;
|
|
|
|
item_in->null_value= 0;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
else if (item_in->value)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
A complete match was found, the result of IN is TRUE.
|
|
|
|
Notice: (this->item == lookup_engine->item)
|
|
|
|
*/
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (covering_null_row_width == tmp_table->s->fields)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
If there is a NULL-only row that coveres all columns the result of IN
|
|
|
|
is UNKNOWN.
|
|
|
|
*/
|
|
|
|
item_in->value= 0;
|
|
|
|
/*
|
|
|
|
TIMOUR: which one is the right way to propagate an UNKNOWN result?
|
|
|
|
Should we also set empty_result_set= FALSE; ???
|
|
|
|
*/
|
|
|
|
//item_in->was_null= 1;
|
|
|
|
item_in->null_value= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
There is no complete match. Look for a partial match (UNKNOWN result), or
|
|
|
|
no match (FALSE).
|
|
|
|
*/
|
|
|
|
if (tmp_table->file->inited)
|
|
|
|
tmp_table->file->ha_index_end();
|
|
|
|
|
|
|
|
if (partial_match())
|
|
|
|
{
|
|
|
|
/* The result of IN is UNKNOWN. */
|
|
|
|
item_in->value= 0;
|
|
|
|
/*
|
|
|
|
TIMOUR: which one is the right way to propagate an UNKNOWN result?
|
|
|
|
Should we also set empty_result_set= FALSE; ???
|
|
|
|
*/
|
|
|
|
//item_in->was_null= 1;
|
|
|
|
item_in->null_value= 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* The result of IN is FALSE. */
|
|
|
|
item_in->value= 0;
|
|
|
|
/*
|
|
|
|
TIMOUR: which one is the right way to propagate an UNKNOWN result?
|
|
|
|
Should we also set empty_result_set= FALSE; ???
|
|
|
|
*/
|
|
|
|
//item_in->was_null= 0;
|
|
|
|
item_in->null_value= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void subselect_partial_match_engine::print(String *str,
|
|
|
|
enum_query_type query_type)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Should never be called as the actual engine cannot be known at query
|
|
|
|
optimization time.
|
|
|
|
*/
|
|
|
|
DBUG_ASSERT(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
|
|
|
@param non_null_key_parts
|
|
|
|
@param partial_match_key_parts A union of all single-column NULL key parts.
|
|
|
|
@param count_partial_match_columns Number of NULL keyparts (set bits above).
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
@retval FALSE the engine was initialized successfully
|
|
|
|
@retval TRUE there was some (memory allocation) error during initialization,
|
|
|
|
such errors should be interpreted as revert to other strategy
|
2010-02-19 22:55:57 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
bool
|
|
|
|
subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
|
|
|
|
MY_BITMAP *partial_match_key_parts)
|
|
|
|
{
|
|
|
|
/* The length in bytes of the rowids (positions) of tmp_table. */
|
|
|
|
uint rowid_length= tmp_table->file->ref_length;
|
|
|
|
ha_rows row_count= tmp_table->file->stats.records;
|
|
|
|
rownum_t cur_rownum= 0;
|
|
|
|
select_materialize_with_stats *result_sink=
|
|
|
|
(select_materialize_with_stats *) result;
|
2010-02-22 16:16:55 +01:00
|
|
|
uint cur_keyid= 0;
|
2010-02-19 22:55:57 +01:00
|
|
|
Item_in_subselect *item_in= (Item_in_subselect*) item;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
if (keys_count == 0)
|
|
|
|
{
|
|
|
|
/* There is nothing to initialize, we will only do regular lookups. */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
DBUG_ASSERT(!covering_null_row_width || (covering_null_row_width &&
|
|
|
|
keys_count == 1 &&
|
|
|
|
non_null_key_parts));
|
|
|
|
/*
|
|
|
|
Allocate buffers to hold the merged keys and the mapping between rowids and
|
|
|
|
row numbers.
|
|
|
|
*/
|
2010-02-19 22:55:57 +01:00
|
|
|
if (!(merge_keys= (Ordered_key**) thd->alloc(keys_count *
|
|
|
|
sizeof(Ordered_key*))) ||
|
2010-03-09 11:14:06 +01:00
|
|
|
!(row_num_to_rowid= (uchar*) my_malloc(row_count * rowid_length *
|
|
|
|
sizeof(uchar), MYF(MY_WME))))
|
2010-02-19 22:55:57 +01:00
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* Create the only non-NULL key if there is any. */
|
|
|
|
if (non_null_key_parts)
|
|
|
|
{
|
2010-02-22 16:16:55 +01:00
|
|
|
non_null_key= new Ordered_key(cur_keyid, tmp_table, item_in->left_expr,
|
2010-02-19 22:55:57 +01:00
|
|
|
0, 0, 0, row_num_to_rowid);
|
|
|
|
if (non_null_key->init(non_null_key_parts))
|
|
|
|
return TRUE;
|
2010-02-22 16:16:55 +01:00
|
|
|
merge_keys[cur_keyid]= non_null_key;
|
|
|
|
merge_keys[cur_keyid]->first();
|
|
|
|
++cur_keyid;
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
If there is a covering NULL row, the only key that is needed is the
|
2010-03-09 11:14:06 +01:00
|
|
|
only non-NULL key that is already created above. We create keys on
|
|
|
|
NULL-able columns only if there is no covering NULL row.
|
2010-02-19 22:55:57 +01:00
|
|
|
*/
|
2010-03-09 11:14:06 +01:00
|
|
|
if (!covering_null_row_width)
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
|
|
|
if (bitmap_init_memroot(&matching_keys, keys_count, thd->mem_root) ||
|
|
|
|
bitmap_init_memroot(&matching_outer_cols, keys_count, thd->mem_root) ||
|
|
|
|
bitmap_init_memroot(&null_only_columns, keys_count, thd->mem_root))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Create one single-column NULL-key for each column in
|
|
|
|
partial_match_key_parts.
|
|
|
|
*/
|
|
|
|
for (uint i= 0; i < partial_match_key_parts->n_bits; i++)
|
|
|
|
{
|
|
|
|
if (!bitmap_is_set(partial_match_key_parts, i))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (result_sink->get_null_count_of_col(i) == row_count)
|
2010-02-22 16:16:55 +01:00
|
|
|
bitmap_set_bit(&null_only_columns, cur_keyid);
|
2010-02-19 22:55:57 +01:00
|
|
|
else
|
|
|
|
{
|
2010-02-22 16:16:55 +01:00
|
|
|
merge_keys[cur_keyid]= new Ordered_key(
|
|
|
|
cur_keyid, tmp_table,
|
|
|
|
item_in->left_expr->element_index(i),
|
|
|
|
result_sink->get_null_count_of_col(i),
|
|
|
|
result_sink->get_min_null_of_col(i),
|
|
|
|
result_sink->get_max_null_of_col(i),
|
|
|
|
row_num_to_rowid);
|
|
|
|
if (merge_keys[cur_keyid]->init(i))
|
2010-02-19 22:55:57 +01:00
|
|
|
return TRUE;
|
2010-02-22 16:16:55 +01:00
|
|
|
merge_keys[cur_keyid]->first();
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
2010-02-22 16:16:55 +01:00
|
|
|
++cur_keyid;
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Populate the indexes with data from the temporary table. */
|
|
|
|
tmp_table->file->ha_rnd_init(1);
|
|
|
|
tmp_table->file->extra_opt(HA_EXTRA_CACHE,
|
|
|
|
current_thd->variables.read_buff_size);
|
|
|
|
tmp_table->null_row= 0;
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
error= tmp_table->file->ha_rnd_next(tmp_table->record[0]);
|
|
|
|
if (error == HA_ERR_RECORD_DELETED)
|
|
|
|
{
|
|
|
|
/* We get this for duplicate records that should not be in tmp_table. */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
This is a temp table that we fully own, there should be no other
|
|
|
|
cause to stop the iteration than EOF.
|
|
|
|
*/
|
|
|
|
DBUG_ASSERT(!error || error == HA_ERR_END_OF_FILE);
|
|
|
|
if (error == HA_ERR_END_OF_FILE)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(cur_rownum == tmp_table->file->stats.records);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Save the position of this record in the row_num -> rowid mapping.
|
|
|
|
*/
|
|
|
|
tmp_table->file->position(tmp_table->record[0]);
|
|
|
|
memcpy(row_num_to_rowid + cur_rownum * rowid_length,
|
|
|
|
tmp_table->file->ref, rowid_length);
|
|
|
|
|
|
|
|
/* Add the current row number to the corresponding keys. */
|
|
|
|
if (non_null_key)
|
|
|
|
{
|
|
|
|
/* By definition there are no NULLs in the non-NULL key. */
|
|
|
|
non_null_key->add_key(cur_rownum);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint i= (non_null_key ? 1 : 0); i < keys_count; i++)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Check if the first and only indexed column contains NULL in the curent
|
|
|
|
row, and add the row number to the corresponding key.
|
|
|
|
*/
|
|
|
|
if (tmp_table->field[merge_keys[i]->get_field_idx(0)]->is_null())
|
|
|
|
merge_keys[i]->set_null(cur_rownum);
|
|
|
|
else
|
|
|
|
merge_keys[i]->add_key(cur_rownum);
|
|
|
|
}
|
|
|
|
++cur_rownum;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp_table->file->ha_rnd_end();
|
|
|
|
|
2010-02-22 16:16:55 +01:00
|
|
|
/* Sort all the keys by their NULL selectivity. */
|
|
|
|
my_qsort(merge_keys, keys_count, sizeof(Ordered_key*),
|
|
|
|
(qsort_cmp) cmp_keys_by_null_selectivity);
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/* Sort the keys in each of the indexes. */
|
|
|
|
for (uint i= 0; i < keys_count; i++)
|
|
|
|
merge_keys[i]->sort_keys();
|
|
|
|
|
|
|
|
if (init_queue(&pq, keys_count, 0, FALSE,
|
2010-07-16 09:33:01 +02:00
|
|
|
subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL,
|
|
|
|
0, 0))
|
2010-02-19 22:55:57 +01:00
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
subselect_rowid_merge_engine::~subselect_rowid_merge_engine()
|
|
|
|
{
|
2010-03-09 11:14:06 +01:00
|
|
|
/* None of the resources below is allocated if there are no ordered keys. */
|
|
|
|
if (keys_count)
|
|
|
|
{
|
|
|
|
my_free((char*) row_num_to_rowid, MYF(0));
|
|
|
|
for (uint i= 0; i < keys_count; i++)
|
|
|
|
delete merge_keys[i];
|
|
|
|
delete_queue(&pq);
|
|
|
|
if (tmp_table->file->inited == handler::RND)
|
|
|
|
tmp_table->file->ha_rnd_end();
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void subselect_rowid_merge_engine::cleanup()
|
|
|
|
{
|
2010-02-22 16:16:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
2010-02-22 16:16:55 +01:00
|
|
|
Quick sort comparison function to compare keys in order of decreasing bitmap
|
|
|
|
selectivity, so that the most selective keys come first.
|
|
|
|
|
|
|
|
@param k1 first key to compare
|
|
|
|
@param k2 second key to compare
|
|
|
|
|
|
|
|
@retval 1 if k1 is less selective than k2
|
|
|
|
@retval 0 if k1 is equally selective as k2
|
|
|
|
@retval -1 if k1 is more selective than k2
|
2010-02-19 22:55:57 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
2010-02-22 16:16:55 +01:00
|
|
|
subselect_rowid_merge_engine::cmp_keys_by_null_selectivity(Ordered_key **k1,
|
|
|
|
Ordered_key **k2)
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
2010-02-22 16:16:55 +01:00
|
|
|
double k1_sel= (*k1)->null_selectivity();
|
|
|
|
double k2_sel= (*k2)->null_selectivity();
|
|
|
|
if (k1_sel < k2_sel)
|
2010-02-19 22:55:57 +01:00
|
|
|
return 1;
|
2010-02-22 16:16:55 +01:00
|
|
|
if (k1_sel > k2_sel)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
|
|
|
subselect_rowid_merge_engine::cmp_keys_by_cur_rownum(void *arg,
|
|
|
|
uchar *k1, uchar *k2)
|
|
|
|
{
|
|
|
|
rownum_t r1= ((Ordered_key*) k1)->current();
|
|
|
|
rownum_t r2= ((Ordered_key*) k2)->current();
|
|
|
|
|
|
|
|
return (r1 < r2) ? -1 : (r1 > r2) ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Check if certain table row contains a NULL in all columns for which there is
|
|
|
|
no match in the corresponding value index.
|
|
|
|
|
|
|
|
@retval TRUE if a NULL row exists
|
|
|
|
@retval FALSE otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool subselect_rowid_merge_engine::test_null_row(rownum_t row_num)
|
|
|
|
{
|
2010-02-22 16:16:55 +01:00
|
|
|
Ordered_key *cur_key;
|
|
|
|
uint cur_id;
|
2010-02-19 22:55:57 +01:00
|
|
|
for (uint i = 0; i < keys_count; i++)
|
|
|
|
{
|
2010-02-22 16:16:55 +01:00
|
|
|
cur_key= merge_keys[i];
|
|
|
|
cur_id= cur_key->get_keyid();
|
|
|
|
if (bitmap_is_set(&matching_keys, cur_id))
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
|
|
|
/*
|
2010-02-22 16:16:55 +01:00
|
|
|
The key 'i' (with id 'cur_keyid') already matches a value in row 'row_num',
|
|
|
|
thus we skip it as it can't possibly match a NULL.
|
2010-02-19 22:55:57 +01:00
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
}
|
2010-02-22 16:16:55 +01:00
|
|
|
if (!cur_key->is_null(row_num))
|
2010-02-19 22:55:57 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@retval TRUE there is a partial match (UNKNOWN)
|
|
|
|
@retval FALSE there is no match at all (FALSE)
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool subselect_rowid_merge_engine::partial_match()
|
|
|
|
{
|
|
|
|
Ordered_key *min_key; /* Key that contains the current minimum position. */
|
|
|
|
rownum_t min_row_num; /* Current row number of min_key. */
|
|
|
|
Ordered_key *cur_key;
|
|
|
|
rownum_t cur_row_num;
|
|
|
|
uint count_nulls_in_search_key= 0;
|
2010-03-09 11:14:06 +01:00
|
|
|
bool res= FALSE;
|
2010-02-19 22:55:57 +01:00
|
|
|
|
|
|
|
/* If there is a non-NULL key, it must be the first key in the keys array. */
|
|
|
|
DBUG_ASSERT(!non_null_key || (non_null_key && merge_keys[0] == non_null_key));
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
/* All data accesses during execution are via handler::ha_rnd_pos() */
|
|
|
|
tmp_table->file->ha_rnd_init(0);
|
|
|
|
|
2010-02-19 22:55:57 +01:00
|
|
|
/* Check if there is a match for the columns of the only non-NULL key. */
|
|
|
|
if (non_null_key && !non_null_key->lookup())
|
2010-03-09 11:14:06 +01:00
|
|
|
{
|
|
|
|
res= FALSE;
|
|
|
|
goto end;
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
If there is a NULL (sub)row that covers all NULL-able columns,
|
|
|
|
then there is a guranteed partial match, and we don't need to search
|
|
|
|
for the matching row.
|
|
|
|
*/
|
2010-03-09 11:14:06 +01:00
|
|
|
if (covering_null_row_width)
|
|
|
|
{
|
|
|
|
res= TRUE;
|
|
|
|
goto end;
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
|
|
|
|
if (non_null_key)
|
|
|
|
queue_insert(&pq, (uchar *) non_null_key);
|
|
|
|
/*
|
|
|
|
Do not add the non_null_key, since it was already processed above.
|
|
|
|
*/
|
|
|
|
bitmap_clear_all(&matching_outer_cols);
|
|
|
|
for (uint i= test(non_null_key); i < keys_count; i++)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(merge_keys[i]->get_column_count() == 1);
|
|
|
|
if (merge_keys[i]->get_search_key(0)->is_null())
|
|
|
|
{
|
|
|
|
++count_nulls_in_search_key;
|
2010-02-22 16:16:55 +01:00
|
|
|
bitmap_set_bit(&matching_outer_cols, merge_keys[i]->get_keyid());
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
else if (merge_keys[i]->lookup())
|
|
|
|
queue_insert(&pq, (uchar *) merge_keys[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
If the outer reference consists of only NULLs, or if it has NULLs in all
|
|
|
|
nullable columns, the result is UNKNOWN.
|
|
|
|
*/
|
|
|
|
if (count_nulls_in_search_key ==
|
|
|
|
((Item_in_subselect *) item)->left_expr->cols() -
|
|
|
|
(non_null_key ? non_null_key->get_column_count() : 0))
|
2010-03-09 11:14:06 +01:00
|
|
|
{
|
|
|
|
res= TRUE;
|
|
|
|
goto end;
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
If there is no NULL (sub)row that covers all NULL columns, and there is no
|
|
|
|
single match for any of the NULL columns, the result is FALSE.
|
|
|
|
*/
|
|
|
|
if (pq.elements - test(non_null_key) == 0)
|
2010-03-09 11:14:06 +01:00
|
|
|
{
|
|
|
|
res= FALSE;
|
|
|
|
goto end;
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
|
|
|
|
DBUG_ASSERT(pq.elements);
|
|
|
|
|
|
|
|
min_key= (Ordered_key*) queue_remove(&pq, 0);
|
|
|
|
min_row_num= min_key->current();
|
|
|
|
bitmap_copy(&matching_keys, &null_only_columns);
|
2010-02-22 16:16:55 +01:00
|
|
|
bitmap_set_bit(&matching_keys, min_key->get_keyid());
|
2010-02-19 22:55:57 +01:00
|
|
|
bitmap_union(&matching_keys, &matching_outer_cols);
|
|
|
|
if (min_key->next_same())
|
|
|
|
queue_insert(&pq, (uchar *) min_key);
|
|
|
|
|
|
|
|
if (pq.elements == 0)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Check the only matching row of the only key min_key for NULL matches
|
|
|
|
in the other columns.
|
|
|
|
*/
|
2010-03-09 11:14:06 +01:00
|
|
|
res= test_null_row(min_row_num);
|
|
|
|
goto end;
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
cur_key= (Ordered_key*) queue_remove(&pq, 0);
|
|
|
|
cur_row_num= cur_key->current();
|
|
|
|
|
|
|
|
if (cur_row_num == min_row_num)
|
2010-02-22 16:16:55 +01:00
|
|
|
bitmap_set_bit(&matching_keys, cur_key->get_keyid());
|
2010-02-19 22:55:57 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Follows from the correct use of priority queue. */
|
|
|
|
DBUG_ASSERT(cur_row_num > min_row_num);
|
|
|
|
if (test_null_row(min_row_num))
|
2010-03-09 11:14:06 +01:00
|
|
|
{
|
|
|
|
res= TRUE;
|
|
|
|
goto end;
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
min_key= cur_key;
|
|
|
|
min_row_num= cur_row_num;
|
|
|
|
bitmap_copy(&matching_keys, &null_only_columns);
|
2010-02-22 16:16:55 +01:00
|
|
|
bitmap_set_bit(&matching_keys, min_key->get_keyid());
|
2010-02-19 22:55:57 +01:00
|
|
|
bitmap_union(&matching_keys, &matching_outer_cols);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cur_key->next_same())
|
|
|
|
queue_insert(&pq, (uchar *) cur_key);
|
|
|
|
|
|
|
|
if (pq.elements == 0)
|
|
|
|
{
|
|
|
|
/* Check the last row of the last column in PQ for NULL matches. */
|
2010-03-09 11:14:06 +01:00
|
|
|
res= test_null_row(min_row_num);
|
|
|
|
goto end;
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
/* We should never get here - all branches must be handled explicitly above. */
|
2010-02-19 22:55:57 +01:00
|
|
|
DBUG_ASSERT(FALSE);
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
end:
|
|
|
|
tmp_table->file->ha_rnd_end();
|
|
|
|
return res;
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
subselect_table_scan_engine::subselect_table_scan_engine(
|
|
|
|
subselect_uniquesubquery_engine *engine_arg,
|
|
|
|
TABLE *tmp_table_arg,
|
|
|
|
Item_subselect *item_arg,
|
|
|
|
select_result_interceptor *result_arg,
|
|
|
|
List<Item> *equi_join_conds_arg,
|
|
|
|
uint covering_null_row_width_arg)
|
|
|
|
:subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg,
|
|
|
|
result_arg, equi_join_conds_arg,
|
|
|
|
covering_null_row_width_arg)
|
|
|
|
{}
|
2010-02-19 22:55:57 +01:00
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
TIMOUR:
|
|
|
|
This method is based on subselect_uniquesubquery_engine::scan_table().
|
|
|
|
Consider refactoring somehow, 80% of the code is the same.
|
|
|
|
|
|
|
|
for each row_i in tmp_table
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
2010-03-09 11:14:06 +01:00
|
|
|
count_matches= 0;
|
|
|
|
for each row element row_i[j]
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
2010-03-09 11:14:06 +01:00
|
|
|
if (outer_ref[j] is NULL || row_i[j] is NULL || outer_ref[j] == row_i[j])
|
|
|
|
++count_matches;
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
2010-03-09 11:14:06 +01:00
|
|
|
if (count_matches == outer_ref.elements)
|
|
|
|
return TRUE
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
2010-03-09 11:14:06 +01:00
|
|
|
return FALSE
|
|
|
|
*/
|
2010-02-19 22:55:57 +01:00
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
bool subselect_table_scan_engine::partial_match()
|
|
|
|
{
|
|
|
|
List_iterator_fast<Item> equality_it(*equi_join_conds);
|
|
|
|
Item *cur_eq;
|
|
|
|
uint count_matches;
|
|
|
|
int error;
|
|
|
|
bool res;
|
2010-02-19 22:55:57 +01:00
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
tmp_table->file->ha_rnd_init(1);
|
|
|
|
tmp_table->file->extra_opt(HA_EXTRA_CACHE,
|
|
|
|
current_thd->variables.read_buff_size);
|
2010-02-19 22:55:57 +01:00
|
|
|
/*
|
2010-03-09 11:14:06 +01:00
|
|
|
TIMOUR:
|
|
|
|
scan_table() also calls "table->null_row= 0;", why, do we need it?
|
2010-02-19 22:55:57 +01:00
|
|
|
*/
|
2010-03-09 11:14:06 +01:00
|
|
|
for (;;)
|
2010-02-19 22:55:57 +01:00
|
|
|
{
|
2010-03-09 11:14:06 +01:00
|
|
|
error= tmp_table->file->ha_rnd_next(tmp_table->record[0]);
|
|
|
|
if (error) {
|
|
|
|
if (error == HA_ERR_RECORD_DELETED)
|
|
|
|
{
|
|
|
|
error= 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (error == HA_ERR_END_OF_FILE)
|
|
|
|
{
|
|
|
|
error= 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error= report_error(tmp_table, error);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
equality_it.rewind();
|
|
|
|
count_matches= 0;
|
|
|
|
while ((cur_eq= equality_it++))
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(cur_eq->type() == Item::FUNC_ITEM &&
|
|
|
|
((Item_func*)cur_eq)->functype() == Item_func::EQ_FUNC);
|
|
|
|
if (!cur_eq->val_int() && !cur_eq->null_value)
|
|
|
|
break;
|
|
|
|
++count_matches;
|
|
|
|
}
|
|
|
|
if (count_matches == tmp_table->s->fields)
|
|
|
|
{
|
|
|
|
res= TRUE; /* Found a matching row. */
|
|
|
|
goto end;
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
res= FALSE;
|
|
|
|
end:
|
2010-02-19 22:55:57 +01:00
|
|
|
tmp_table->file->ha_rnd_end();
|
2010-03-09 11:14:06 +01:00
|
|
|
return res;
|
|
|
|
}
|
2010-02-19 22:55:57 +01:00
|
|
|
|
2010-03-09 11:14:06 +01:00
|
|
|
|
|
|
|
void subselect_table_scan_engine::cleanup()
|
|
|
|
{
|
2010-02-19 22:55:57 +01:00
|
|
|
}
|