2017-07-18 14:59:10 +02:00
|
|
|
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
|
2020-08-10 17:40:57 +02:00
|
|
|
Copyright (c) 2010, 2020, MariaDB Corporation.
|
2001-08-02 05:29:50 +02:00
|
|
|
|
|
|
|
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.
|
2001-08-02 05:29:50 +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
|
2019-05-11 20:29:06 +02:00
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
2001-08-02 05:29:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
UNION of select's
|
|
|
|
UNION's were introduced by Monty and Sinisa <sinisa@mysql.com>
|
|
|
|
*/
|
|
|
|
|
2017-06-18 05:42:16 +02:00
|
|
|
#include "mariadb.h"
|
2010-03-31 16:05:33 +02:00
|
|
|
#include "sql_priv.h"
|
|
|
|
#include "unireg.h"
|
|
|
|
#include "sql_union.h"
|
2001-08-02 05:29:50 +02:00
|
|
|
#include "sql_select.h"
|
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
|
|
|
#include "sql_cursor.h"
|
2010-03-31 16:05:33 +02:00
|
|
|
#include "sql_base.h" // fill_record
|
|
|
|
#include "filesort.h" // filesort_free_buffers
|
2016-05-09 22:39:10 +02:00
|
|
|
#include "sql_view.h"
|
|
|
|
#include "sql_cte.h"
|
2001-08-02 05:29:50 +02:00
|
|
|
|
2004-10-20 03:04:37 +02:00
|
|
|
bool mysql_union(THD *thd, LEX *lex, select_result *result,
|
2005-01-03 20:04:33 +01:00
|
|
|
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
|
|
|
DBUG_ENTER("mysql_union");
|
2004-10-20 03:04:37 +02:00
|
|
|
bool res;
|
2018-04-18 14:29:48 +02:00
|
|
|
if (!(res= unit->prepare(unit->derived, result, SELECT_NO_UNLOCK |
|
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
|
|
|
setup_tables_done_option)))
|
2002-09-03 08:50:36 +02:00
|
|
|
res= unit->exec();
|
2010-07-27 14:42:36 +02:00
|
|
|
res|= unit->cleanup();
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(res);
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
** store records in temporary table for UNION
|
|
|
|
***************************************************************************/
|
|
|
|
|
2017-03-14 11:52:00 +01:00
|
|
|
int select_unit::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
|
|
|
unit= u;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-03-14 11:52:00 +01:00
|
|
|
/**
|
|
|
|
This called by SELECT_LEX_UNIT::exec when select changed
|
|
|
|
*/
|
2003-04-08 02:54:02 +02:00
|
|
|
|
2017-03-14 11:52:00 +01:00
|
|
|
void select_unit::change_select()
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
2017-03-14 11:52:00 +01:00
|
|
|
uint current_select_number= thd->lex->current_select->select_number;
|
|
|
|
DBUG_ENTER("select_unit::change_select");
|
|
|
|
DBUG_PRINT("enter", ("select in unit change: %u -> %u",
|
|
|
|
curr_sel, current_select_number));
|
|
|
|
DBUG_ASSERT(curr_sel != current_select_number);
|
|
|
|
curr_sel= current_select_number;
|
|
|
|
/* New SELECT processing starts */
|
|
|
|
DBUG_ASSERT(table->file->inited == 0);
|
2018-05-22 19:08:39 +02:00
|
|
|
step= thd->lex->current_select->get_linkage();
|
2018-01-05 21:48:09 +01:00
|
|
|
switch (step)
|
2017-03-14 11:52:00 +01:00
|
|
|
{
|
|
|
|
case INTERSECT_TYPE:
|
2019-08-24 15:42:35 +02:00
|
|
|
prev_step= curr_step;
|
2017-03-14 11:52:00 +01:00
|
|
|
curr_step= current_select_number;
|
2018-01-05 21:48:09 +01:00
|
|
|
break;
|
2017-03-14 11:52:00 +01:00
|
|
|
case EXCEPT_TYPE:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
step= UNION_TYPE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
2019-08-24 15:42:35 +02:00
|
|
|
|
2017-03-14 11:52:00 +01:00
|
|
|
/**
|
|
|
|
Fill temporary tables for UNION/EXCEPT/INTERSECT
|
|
|
|
|
|
|
|
@Note
|
|
|
|
UNION:
|
|
|
|
just add records to the table (with 'counter' field first if INTERSECT
|
|
|
|
present in the sequence).
|
|
|
|
EXCEPT:
|
|
|
|
looks for the record in the table (with 'counter' field first if
|
|
|
|
INTERSECT present in the sequence) and delete it if found
|
2019-08-24 15:42:35 +02:00
|
|
|
INTERSECT:
|
2017-03-14 11:52:00 +01:00
|
|
|
looks for the same record with 'counter' field of previous operation,
|
|
|
|
put as a 'counter' number of the current SELECT.
|
|
|
|
We scan the table and remove all records which marked with not last
|
|
|
|
'counter' after processing all records in send_eof and only if it last
|
|
|
|
SELECT of sequence of INTERSECTS.
|
|
|
|
|
|
|
|
@param values List of record items to process.
|
|
|
|
|
|
|
|
@retval 0 - OK
|
|
|
|
@retval -1 - duplicate
|
|
|
|
@retval 1 - error
|
|
|
|
*/
|
|
|
|
int select_unit::send_data(List<Item> &values)
|
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
int rc= 0;
|
2017-03-14 11:52:00 +01:00
|
|
|
int not_reported_error= 0;
|
2019-09-30 17:20:28 +02:00
|
|
|
|
2012-02-25 01:50:22 +01:00
|
|
|
if (table->no_rows_with_nulls)
|
|
|
|
table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT;
|
2019-08-24 15:42:35 +02:00
|
|
|
|
|
|
|
fill_record(thd, table, table->field + addon_cnt, values, true, false);
|
|
|
|
/* set up initial values for records to be written */
|
|
|
|
if (addon_cnt && step == UNION_TYPE)
|
2017-03-14 11:52:00 +01:00
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
DBUG_ASSERT(addon_cnt == 1);
|
|
|
|
table->field[0]->store((longlong) curr_step, 1);
|
2017-03-14 11:52:00 +01:00
|
|
|
}
|
2019-08-24 15:42:35 +02:00
|
|
|
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(thd->is_error()))
|
2017-03-14 11:52:00 +01:00
|
|
|
{
|
|
|
|
rc= 1;
|
2019-08-24 15:42:35 +02:00
|
|
|
if (unlikely(not_reported_error))
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(rc);
|
|
|
|
table->file->print_error(not_reported_error, MYF(0));
|
|
|
|
}
|
|
|
|
return rc;
|
2017-03-14 11:52:00 +01:00
|
|
|
}
|
2012-02-25 01:50:22 +01:00
|
|
|
if (table->no_rows_with_nulls)
|
|
|
|
{
|
|
|
|
table->null_catch_flags&= ~CHECK_ROW_FOR_NULLS_TO_REJECT;
|
|
|
|
if (table->null_catch_flags)
|
2017-03-14 11:52:00 +01:00
|
|
|
{
|
|
|
|
rc= 0;
|
2019-08-24 15:42:35 +02:00
|
|
|
if (unlikely(not_reported_error))
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(rc);
|
|
|
|
table->file->print_error(not_reported_error, MYF(0));
|
|
|
|
}
|
|
|
|
return rc;
|
2017-03-14 11:52:00 +01:00
|
|
|
}
|
2012-02-25 01:50:22 +01:00
|
|
|
}
|
2005-02-24 22:33:42 +01:00
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
/* select_unit::change_select() change step & Co correctly for each SELECT */
|
|
|
|
int find_res;
|
2017-03-14 11:52:00 +01:00
|
|
|
switch (step)
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
case UNION_TYPE:
|
|
|
|
rc= write_record();
|
|
|
|
/* no reaction with conversion */
|
|
|
|
if (rc == -2)
|
|
|
|
rc= 0;
|
|
|
|
break;
|
2017-03-14 11:52:00 +01:00
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
case EXCEPT_TYPE:
|
|
|
|
/*
|
|
|
|
The temporary table uses very first index or constrain for
|
|
|
|
checking unique constrain.
|
|
|
|
*/
|
|
|
|
if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
|
|
|
|
rc= delete_record();
|
|
|
|
else
|
|
|
|
rc= not_reported_error= (find_res != 1);
|
|
|
|
break;
|
|
|
|
case INTERSECT_TYPE:
|
|
|
|
/*
|
|
|
|
The temporary table uses very first index or constrain for
|
|
|
|
checking unique constrain.
|
|
|
|
*/
|
|
|
|
if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
|
2017-03-14 11:52:00 +01:00
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
DBUG_ASSERT(!table->triggers);
|
|
|
|
if (table->field[0]->val_int() == prev_step)
|
2017-03-14 11:52:00 +01:00
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
not_reported_error= update_counter(table->field[0], curr_step);
|
2017-03-14 11:52:00 +01:00
|
|
|
rc= MY_TEST(not_reported_error);
|
|
|
|
DBUG_ASSERT(rc != HA_ERR_RECORD_IS_THE_SAME);
|
|
|
|
}
|
|
|
|
}
|
2019-08-24 15:42:35 +02:00
|
|
|
else
|
|
|
|
rc= not_reported_error= (find_res != 1);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DBUG_ASSERT(0);
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
2017-03-14 11:52:00 +01:00
|
|
|
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(not_reported_error))
|
2017-03-14 11:52:00 +01:00
|
|
|
{
|
|
|
|
DBUG_ASSERT(rc);
|
|
|
|
table->file->print_error(not_reported_error, MYF(0));
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool select_unit::send_eof()
|
|
|
|
{
|
|
|
|
if (step != INTERSECT_TYPE ||
|
|
|
|
(thd->lex->current_select->next_select() &&
|
2018-05-22 19:08:39 +02:00
|
|
|
thd->lex->current_select->next_select()->get_linkage() == INTERSECT_TYPE))
|
2017-03-14 11:52:00 +01:00
|
|
|
{
|
|
|
|
/*
|
2019-08-24 15:42:35 +02:00
|
|
|
it is not INTERSECT or next SELECT in the sequence is INTERSECT so no
|
2017-03-14 11:52:00 +01:00
|
|
|
need filtering (the last INTERSECT in this sequence of intersects will
|
|
|
|
filter).
|
|
|
|
*/
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
It is last select in the sequence of INTERSECTs so we should filter out
|
|
|
|
all records except marked with actual counter.
|
|
|
|
|
|
|
|
TODO: as optimization for simple case this could be moved to
|
|
|
|
'fake_select' WHERE condition
|
|
|
|
*/
|
|
|
|
int error;
|
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
if (table->file->ha_rnd_init_with_error(1))
|
2017-03-14 11:52:00 +01:00
|
|
|
return 1;
|
|
|
|
do
|
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
error= table->file->ha_rnd_next(table->record[0]);
|
|
|
|
if (unlikely(error))
|
2017-03-14 11:52:00 +01:00
|
|
|
{
|
|
|
|
if (error == HA_ERR_END_OF_FILE)
|
|
|
|
{
|
|
|
|
error= 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (table->field[0]->val_int() != curr_step)
|
2019-08-24 15:42:35 +02:00
|
|
|
error= delete_record();
|
|
|
|
} while (!error);
|
|
|
|
table->file->ha_rnd_end();
|
2017-03-14 11:52:00 +01:00
|
|
|
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(error))
|
2017-03-14 11:52:00 +01:00
|
|
|
table->file->print_error(error, MYF(0));
|
|
|
|
|
|
|
|
return(MY_TEST(error));
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
|
|
|
|
2016-08-30 07:45:17 +02:00
|
|
|
|
2016-05-09 22:39:10 +02:00
|
|
|
int select_union_recursive::send_data(List<Item> &values)
|
|
|
|
{
|
2017-03-14 11:52:00 +01:00
|
|
|
int rc= select_unit::send_data(values);
|
2016-05-09 22:39:10 +02:00
|
|
|
|
2017-11-13 13:04:21 +01:00
|
|
|
if (rc == 0 &&
|
|
|
|
write_err != HA_ERR_FOUND_DUPP_KEY &&
|
2017-04-26 19:10:36 +02:00
|
|
|
write_err != HA_ERR_FOUND_DUPP_UNIQUE)
|
2016-05-09 22:39:10 +02:00
|
|
|
{
|
|
|
|
int err;
|
2020-01-27 21:50:16 +01:00
|
|
|
DBUG_ASSERT(incr_table->s->reclength == table->s->reclength ||
|
|
|
|
incr_table->s->reclength == table->s->reclength - MARIA_UNIQUE_HASH_LENGTH);
|
2016-05-09 22:39:10 +02:00
|
|
|
if ((err= incr_table->file->ha_write_tmp_row(table->record[0])))
|
|
|
|
{
|
|
|
|
bool is_duplicate;
|
|
|
|
rc= create_internal_tmp_table_from_heap(thd, incr_table,
|
|
|
|
tmp_table_param.start_recinfo,
|
|
|
|
&tmp_table_param.recinfo,
|
|
|
|
err, 1, &is_duplicate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2003-04-08 02:54:02 +02:00
|
|
|
|
2017-03-14 11:52:00 +01:00
|
|
|
bool select_unit::flush()
|
2001-08-02 05:29:50 +02:00
|
|
|
{
|
2002-09-03 08:50:36 +02:00
|
|
|
int error;
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely((error=table->file->extra(HA_EXTRA_NO_CACHE))))
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
2004-10-20 03:04:37 +02:00
|
|
|
table->file->print_error(error, MYF(0));
|
2002-09-03 08:50:36 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-03-14 11:52:00 +01:00
|
|
|
|
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
|
|
|
/*
|
|
|
|
Create a temporary table to store the result of select_union.
|
|
|
|
|
|
|
|
SYNOPSIS
|
2017-03-14 11:52:00 +01:00
|
|
|
select_unit::create_result_table()
|
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
|
|
|
thd thread handle
|
|
|
|
column_types a list of items used to define columns of the
|
|
|
|
temporary table
|
|
|
|
is_union_distinct if set, the temporary table will eliminate
|
|
|
|
duplicates on insert
|
|
|
|
options create options
|
2010-02-17 22:59:41 +01:00
|
|
|
table_alias name of the temporary table
|
|
|
|
bit_fields_as_long convert bit fields to ulonglong
|
2010-05-26 22:18:18 +02:00
|
|
|
create_table whether to physically create result table
|
2013-09-06 13:59:19 +02:00
|
|
|
keep_row_order keep rows in order as they were inserted
|
2017-03-14 11:52:00 +01:00
|
|
|
hidden number of hidden fields (for INTERSECT)
|
2019-08-24 15:42:35 +02:00
|
|
|
plus one for `ALL`
|
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
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Create a temporary table that is used to store the result of a UNION,
|
|
|
|
derived table, or a materialized cursor.
|
|
|
|
|
|
|
|
RETURN VALUE
|
|
|
|
0 The table has been created successfully.
|
|
|
|
1 create_tmp_table failed.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool
|
2017-03-14 11:52:00 +01:00
|
|
|
select_unit::create_result_table(THD *thd_arg, List<Item> *column_types,
|
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
|
|
|
bool is_union_distinct, ulonglong options,
|
2018-01-07 17:03:44 +01:00
|
|
|
const LEX_CSTRING *alias,
|
2013-09-06 13:59:19 +02:00
|
|
|
bool bit_fields_as_long, bool create_table,
|
2017-03-14 11:52:00 +01:00
|
|
|
bool keep_row_order,
|
|
|
|
uint hidden)
|
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
|
|
|
{
|
|
|
|
DBUG_ASSERT(table == 0);
|
|
|
|
tmp_table_param.init();
|
|
|
|
tmp_table_param.field_count= column_types->elements;
|
2010-02-17 22:59:41 +01:00
|
|
|
tmp_table_param.bit_fields_as_long= bit_fields_as_long;
|
2017-03-14 11:52:00 +01:00
|
|
|
tmp_table_param.hidden_field_count= hidden;
|
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
|
|
|
|
2006-12-14 23:51:37 +01:00
|
|
|
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
|
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
|
|
|
(ORDER*) 0, is_union_distinct, 1,
|
2011-10-19 21:45:18 +02:00
|
|
|
options, HA_POS_ERROR, alias,
|
2013-09-06 13:59:19 +02:00
|
|
|
!create_table, keep_row_order)))
|
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 TRUE;
|
2011-06-05 04:56:06 +02:00
|
|
|
|
2011-05-25 17:31:13 +02:00
|
|
|
table->keys_in_use_for_query.clear_all();
|
|
|
|
for (uint i=0; i < table->s->fields; i++)
|
2019-08-14 18:27:00 +02:00
|
|
|
table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG);
|
2011-05-25 17:31:13 +02:00
|
|
|
|
2010-05-26 22:18:18 +02:00
|
|
|
if (create_table)
|
|
|
|
{
|
|
|
|
table->file->extra(HA_EXTRA_WRITE_CACHE);
|
|
|
|
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
|
|
|
}
|
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 FALSE;
|
|
|
|
}
|
|
|
|
|
2016-05-09 22:39:10 +02:00
|
|
|
bool
|
|
|
|
select_union_recursive::create_result_table(THD *thd_arg,
|
|
|
|
List<Item> *column_types,
|
|
|
|
bool is_union_distinct,
|
|
|
|
ulonglong options,
|
2018-01-07 17:03:44 +01:00
|
|
|
const LEX_CSTRING *alias,
|
2016-05-09 22:39:10 +02:00
|
|
|
bool bit_fields_as_long,
|
|
|
|
bool create_table,
|
2017-03-14 11:52:00 +01:00
|
|
|
bool keep_row_order,
|
|
|
|
uint hidden)
|
2016-05-09 22:39:10 +02:00
|
|
|
{
|
2017-03-14 11:52:00 +01:00
|
|
|
if (select_unit::create_result_table(thd_arg, column_types,
|
|
|
|
is_union_distinct, options,
|
2018-01-07 17:03:44 +01:00
|
|
|
&empty_clex_str, bit_fields_as_long,
|
2017-03-14 11:52:00 +01:00
|
|
|
create_table, keep_row_order,
|
|
|
|
hidden))
|
2016-05-09 22:39:10 +02:00
|
|
|
return true;
|
|
|
|
|
2020-12-16 18:11:11 +01:00
|
|
|
incr_table_param.init();
|
|
|
|
incr_table_param.field_count= column_types->elements;
|
|
|
|
incr_table_param.bit_fields_as_long= bit_fields_as_long;
|
|
|
|
if (! (incr_table= create_tmp_table(thd_arg, &incr_table_param, *column_types,
|
2016-05-09 22:39:10 +02:00
|
|
|
(ORDER*) 0, false, 1,
|
2018-01-07 17:03:44 +01:00
|
|
|
options, HA_POS_ERROR, &empty_clex_str,
|
2018-04-16 16:19:19 +02:00
|
|
|
true, keep_row_order)))
|
2016-05-09 22:39:10 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
incr_table->keys_in_use_for_query.clear_all();
|
|
|
|
for (uint i=0; i < table->s->fields; i++)
|
2019-08-14 18:27:00 +02:00
|
|
|
incr_table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG);
|
2016-05-09 22:39:10 +02:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2003-04-08 02:54:02 +02:00
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
/*
|
|
|
|
@brief
|
|
|
|
Write a record
|
|
|
|
|
|
|
|
@retval
|
|
|
|
-2 conversion happened
|
|
|
|
-1 found a duplicate key
|
|
|
|
0 no error
|
|
|
|
1 if an error is reported
|
|
|
|
*/
|
|
|
|
|
|
|
|
int select_unit::write_record()
|
|
|
|
{
|
|
|
|
if (unlikely((write_err= table->file->ha_write_tmp_row(table->record[0]))))
|
|
|
|
{
|
|
|
|
if (write_err == HA_ERR_FOUND_DUPP_KEY)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Inform upper level that we found a duplicate key, that should not
|
|
|
|
be counted as part of limit
|
|
|
|
*/
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
bool is_duplicate= false;
|
|
|
|
/* create_internal_tmp_table_from_heap will generate error if needed */
|
|
|
|
if (table->file->is_fatal_error(write_err, HA_CHECK_DUP))
|
|
|
|
{
|
|
|
|
if (!create_internal_tmp_table_from_heap(thd, table,
|
|
|
|
tmp_table_param.start_recinfo,
|
|
|
|
&tmp_table_param.recinfo,
|
|
|
|
write_err, 1, &is_duplicate))
|
|
|
|
{
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (is_duplicate)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@brief
|
|
|
|
Update counter for a record
|
|
|
|
|
|
|
|
@retval
|
|
|
|
0 no error
|
|
|
|
-1 error occurred
|
|
|
|
*/
|
|
|
|
|
|
|
|
int select_unit::update_counter(Field* counter, longlong value)
|
|
|
|
{
|
|
|
|
store_record(table, record[1]);
|
|
|
|
counter->store(value, 0);
|
|
|
|
int error= table->file->ha_update_tmp_row(table->record[1],
|
|
|
|
table->record[0]);
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@brief
|
|
|
|
Try to disable index
|
|
|
|
|
|
|
|
@retval
|
|
|
|
true index is disabled this time
|
|
|
|
false this time did not disable the index
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool select_unit_ext::disable_index_if_needed(SELECT_LEX *curr_sl)
|
|
|
|
{
|
|
|
|
if (is_index_enabled &&
|
|
|
|
(curr_sl == curr_sl->master_unit()->union_distinct ||
|
|
|
|
!curr_sl->next_select()) )
|
|
|
|
{
|
|
|
|
is_index_enabled= false;
|
|
|
|
if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
|
|
|
|
return false;
|
|
|
|
table->no_keyread=1;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
@brief
|
|
|
|
Unfold a record
|
|
|
|
|
|
|
|
@retval
|
|
|
|
0 no error
|
|
|
|
-1 conversion happened
|
|
|
|
*/
|
|
|
|
|
2019-08-30 08:47:12 +02:00
|
|
|
int select_unit_ext::unfold_record(ha_rows cnt)
|
2019-08-24 15:42:35 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
DBUG_ASSERT(cnt > 0);
|
|
|
|
int error= 0;
|
|
|
|
bool is_convertion_happened= false;
|
|
|
|
while (--cnt)
|
|
|
|
{
|
|
|
|
error= write_record();
|
|
|
|
if (error == -2)
|
|
|
|
{
|
|
|
|
is_convertion_happened= true;
|
|
|
|
error= -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (is_convertion_happened)
|
|
|
|
return -1;
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
@brief
|
|
|
|
Delete a record
|
|
|
|
|
|
|
|
@retval
|
|
|
|
0 no error
|
|
|
|
1 if an error is reported
|
|
|
|
*/
|
|
|
|
|
|
|
|
int select_unit::delete_record()
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(!table->triggers);
|
|
|
|
table->status|= STATUS_DELETED;
|
|
|
|
int not_reported_error= table->file->ha_delete_tmp_row(table->record[0]);
|
|
|
|
return MY_TEST(not_reported_error);
|
|
|
|
}
|
|
|
|
|
2010-07-16 13:02:15 +02:00
|
|
|
/**
|
2016-03-22 20:51:59 +01:00
|
|
|
Reset and empty the temporary table that stores the materialized query
|
|
|
|
result.
|
2010-07-16 13:02:15 +02:00
|
|
|
|
|
|
|
@note The cleanup performed here is exactly the same as for the two temp
|
|
|
|
tables of JOIN - exec_tmp_table_[1 | 2].
|
|
|
|
*/
|
|
|
|
|
2017-03-14 11:52:00 +01:00
|
|
|
void select_unit::cleanup()
|
2010-07-16 13:02:15 +02:00
|
|
|
{
|
|
|
|
table->file->extra(HA_EXTRA_RESET_STATE);
|
|
|
|
table->file->ha_delete_all_rows();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
/*
|
|
|
|
@brief
|
|
|
|
Set up value needed by send_data() and send_eof()
|
|
|
|
|
|
|
|
@detail
|
|
|
|
- For EXCEPT we will decrease the counter by one
|
|
|
|
and INTERSECT / UNION we increase the counter.
|
|
|
|
|
|
|
|
- For INTERSECT we will modify the second extra field (intersect counter)
|
|
|
|
and for EXCEPT / UNION we modify the first (duplicate counter)
|
|
|
|
*/
|
|
|
|
|
|
|
|
void select_unit_ext::change_select()
|
|
|
|
{
|
|
|
|
select_unit::change_select();
|
|
|
|
switch(step){
|
|
|
|
case UNION_TYPE:
|
|
|
|
increment= 1;
|
|
|
|
curr_op_type= UNION_DISTINCT;
|
|
|
|
break;
|
|
|
|
case EXCEPT_TYPE:
|
|
|
|
increment= -1;
|
|
|
|
curr_op_type= EXCEPT_DISTINCT;
|
|
|
|
break;
|
|
|
|
case INTERSECT_TYPE:
|
|
|
|
increment= 1;
|
|
|
|
curr_op_type= INTERSECT_DISTINCT;
|
|
|
|
break;
|
|
|
|
default: DBUG_ASSERT(0);
|
|
|
|
}
|
|
|
|
if (!thd->lex->current_select->distinct)
|
|
|
|
/* change type from DISTINCT to ALL */
|
|
|
|
curr_op_type= (set_op_type)(curr_op_type + 1);
|
|
|
|
|
|
|
|
duplicate_cnt= table->field[addon_cnt - 1];
|
|
|
|
if (addon_cnt == 2)
|
|
|
|
additional_cnt= table->field[addon_cnt - 2];
|
|
|
|
else
|
|
|
|
additional_cnt= NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@brief
|
|
|
|
Fill temporary tables for operations need extra fields
|
|
|
|
|
|
|
|
@detail
|
|
|
|
- If this operation is not distinct, we try to find it and increase the
|
|
|
|
counter by "increment" setted in select_unit_ext::change_select().
|
|
|
|
|
|
|
|
- If it is distinct, for UNION we write this record; for INTERSECT we
|
|
|
|
try to find it and increase the intersect counter if found; for EXCEPT
|
|
|
|
we try to find it and delete that record if found.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int select_unit_ext::send_data(List<Item> &values)
|
|
|
|
{
|
|
|
|
int rc= 0;
|
|
|
|
int not_reported_error= 0;
|
|
|
|
int find_res;
|
2019-09-30 17:20:28 +02:00
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
if (table->no_rows_with_nulls)
|
|
|
|
table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT;
|
|
|
|
|
|
|
|
fill_record(thd, table, table->field + addon_cnt, values, true, false);
|
|
|
|
/* set up initial values for records to be written */
|
|
|
|
if ( step == UNION_TYPE )
|
|
|
|
{
|
|
|
|
/* set duplicate counter to 1 */
|
|
|
|
duplicate_cnt->store((longlong) 1, 1);
|
|
|
|
/* set the other counter to 0 */
|
|
|
|
if (curr_op_type == INTERSECT_ALL)
|
|
|
|
additional_cnt->store((longlong) 0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unlikely(thd->is_error()))
|
|
|
|
{
|
|
|
|
rc= 1;
|
|
|
|
if (unlikely(not_reported_error))
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(rc);
|
|
|
|
table->file->print_error(not_reported_error, MYF(0));
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
if (table->no_rows_with_nulls)
|
|
|
|
{
|
|
|
|
table->null_catch_flags&= ~CHECK_ROW_FOR_NULLS_TO_REJECT;
|
|
|
|
if (table->null_catch_flags)
|
|
|
|
{
|
|
|
|
if (unlikely(not_reported_error))
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(rc);
|
|
|
|
table->file->print_error(not_reported_error, MYF(0));
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(curr_op_type)
|
|
|
|
{
|
|
|
|
case UNION_ALL:
|
|
|
|
if (!is_index_enabled ||
|
|
|
|
(find_res= table->file->find_unique_row(table->record[0], 0)))
|
|
|
|
{
|
|
|
|
rc= write_record();
|
|
|
|
/* no reaction with conversion */
|
|
|
|
if (rc == -2)
|
|
|
|
rc= 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
longlong cnt= duplicate_cnt->val_int() + increment;
|
|
|
|
not_reported_error= update_counter(duplicate_cnt, cnt);
|
|
|
|
DBUG_ASSERT(!table->triggers);
|
|
|
|
rc= MY_TEST(not_reported_error);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EXCEPT_ALL:
|
|
|
|
if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
|
|
|
|
{
|
|
|
|
longlong cnt= duplicate_cnt->val_int() + increment;
|
|
|
|
if (cnt == 0)
|
|
|
|
rc= delete_record();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
not_reported_error= update_counter(duplicate_cnt, cnt);
|
|
|
|
DBUG_ASSERT(!table->triggers);
|
|
|
|
rc= MY_TEST(not_reported_error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case INTERSECT_ALL:
|
|
|
|
if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
|
|
|
|
{
|
|
|
|
longlong cnt= duplicate_cnt->val_int() + increment;
|
|
|
|
if (cnt <= additional_cnt->val_int())
|
|
|
|
{
|
|
|
|
not_reported_error= update_counter(duplicate_cnt, cnt);
|
|
|
|
DBUG_ASSERT(!table->triggers);
|
|
|
|
rc= MY_TEST(not_reported_error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case UNION_DISTINCT:
|
|
|
|
rc= write_record();
|
|
|
|
/* no reaction with conversion */
|
|
|
|
if (rc == -2)
|
|
|
|
rc= 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EXCEPT_DISTINCT:
|
|
|
|
if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
|
|
|
|
rc= delete_record();
|
|
|
|
else
|
|
|
|
rc= not_reported_error= (find_res != 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case INTERSECT_DISTINCT:
|
|
|
|
if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
|
|
|
|
{
|
|
|
|
if (additional_cnt->val_int() == prev_step)
|
|
|
|
{
|
|
|
|
not_reported_error= update_counter(additional_cnt, curr_step);
|
|
|
|
rc= MY_TEST(not_reported_error);
|
|
|
|
DBUG_ASSERT(rc != HA_ERR_RECORD_IS_THE_SAME);
|
|
|
|
}
|
|
|
|
else if (additional_cnt->val_int() != curr_step)
|
|
|
|
rc= delete_record();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rc= not_reported_error= (find_res != 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DBUG_ASSERT(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unlikely(not_reported_error))
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(rc);
|
|
|
|
table->file->print_error(not_reported_error, MYF(0));
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@brief
|
|
|
|
Do post-operation after a operator
|
|
|
|
|
|
|
|
@detail
|
|
|
|
We need to scan in these cases:
|
|
|
|
- If this operation is DISTINCT and next is ALL,
|
|
|
|
duplicate counter needs to be set to 1.
|
|
|
|
- If this operation is INTERSECT ALL and counter needs to be updated.
|
|
|
|
- If next operation is INTERSECT ALL,
|
|
|
|
set up the second extra field (called "intersect_counter") to 0.
|
|
|
|
this extra field counts records in the second operand.
|
|
|
|
|
|
|
|
If this operation is equal to "union_distinct" or is the last operation,
|
|
|
|
we'll disable index. Then if this operation is ALL we'll unfold records.
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool select_unit_ext::send_eof()
|
|
|
|
{
|
|
|
|
int error= 0;
|
|
|
|
SELECT_LEX *curr_sl= thd->lex->current_select;
|
|
|
|
SELECT_LEX *next_sl= curr_sl->next_select();
|
|
|
|
bool is_next_distinct= next_sl && next_sl->distinct;
|
|
|
|
bool is_next_intersect_all=
|
|
|
|
next_sl &&
|
|
|
|
next_sl->get_linkage() == INTERSECT_TYPE &&
|
|
|
|
!next_sl->distinct;
|
|
|
|
bool need_unfold= (disable_index_if_needed(curr_sl) &&
|
|
|
|
!curr_sl->distinct);
|
|
|
|
|
|
|
|
if (((curr_sl->distinct && !is_next_distinct) ||
|
|
|
|
curr_op_type == INTERSECT_ALL ||
|
|
|
|
is_next_intersect_all) &&
|
|
|
|
!need_unfold)
|
|
|
|
{
|
|
|
|
if (!next_sl)
|
|
|
|
DBUG_ASSERT(curr_op_type != INTERSECT_ALL);
|
|
|
|
bool need_update_row;
|
|
|
|
if (unlikely(table->file->ha_rnd_init_with_error(1)))
|
|
|
|
return 1;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
need_update_row= false;
|
|
|
|
if (unlikely(error= table->file->ha_rnd_next(table->record[0])))
|
|
|
|
{
|
|
|
|
if (error == HA_ERR_END_OF_FILE)
|
|
|
|
{
|
|
|
|
error= 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
store_record(table, record[1]);
|
|
|
|
|
|
|
|
if (curr_sl->distinct && !is_next_distinct)
|
|
|
|
{
|
|
|
|
/* set duplicate counter to 1 if next operation is ALL */
|
|
|
|
duplicate_cnt->store(1, 0);
|
|
|
|
need_update_row= true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_next_intersect_all)
|
|
|
|
{
|
|
|
|
longlong d_cnt_val= duplicate_cnt->val_int();
|
|
|
|
if (d_cnt_val == 0)
|
|
|
|
error= delete_record();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (curr_op_type == INTERSECT_ALL)
|
|
|
|
{
|
|
|
|
longlong a_cnt_val= additional_cnt->val_int();
|
|
|
|
if (a_cnt_val < d_cnt_val)
|
|
|
|
d_cnt_val= a_cnt_val;
|
|
|
|
}
|
|
|
|
additional_cnt->store(d_cnt_val, 0);
|
|
|
|
duplicate_cnt->store((longlong)0, 0);
|
|
|
|
need_update_row= true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (need_update_row)
|
|
|
|
error= table->file->ha_update_tmp_row(table->record[1],
|
|
|
|
table->record[0]);
|
|
|
|
} while (likely(!error));
|
|
|
|
table->file->ha_rnd_end();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* unfold */
|
|
|
|
else if (need_unfold)
|
|
|
|
{
|
|
|
|
/* unfold if is ALL operation */
|
2019-08-30 08:47:12 +02:00
|
|
|
ha_rows dup_cnt;
|
2019-08-24 15:42:35 +02:00
|
|
|
if (unlikely(table->file->ha_rnd_init_with_error(1)))
|
|
|
|
return 1;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (unlikely(error= table->file->ha_rnd_next(table->record[0])))
|
|
|
|
{
|
|
|
|
if (error == HA_ERR_END_OF_FILE)
|
|
|
|
{
|
|
|
|
error= 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2019-08-30 08:47:12 +02:00
|
|
|
dup_cnt= (ha_rows)duplicate_cnt->val_int();
|
2019-08-24 15:42:35 +02:00
|
|
|
/* delete record if not exist in the second operand */
|
|
|
|
if (dup_cnt == 0)
|
|
|
|
{
|
|
|
|
error= delete_record();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (curr_op_type == INTERSECT_ALL)
|
|
|
|
{
|
2019-09-01 07:44:58 +02:00
|
|
|
ha_rows add_cnt= (ha_rows)additional_cnt->val_int();
|
2019-08-24 15:42:35 +02:00
|
|
|
if (dup_cnt > add_cnt && add_cnt > 0)
|
2019-08-30 08:47:12 +02:00
|
|
|
dup_cnt= (ha_rows)add_cnt;
|
2019-08-24 15:42:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dup_cnt == 1)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
duplicate_cnt->store((longlong)1, 0);
|
|
|
|
if (additional_cnt)
|
|
|
|
additional_cnt->store((longlong)0, 0);
|
|
|
|
error= table->file->ha_update_tmp_row(table->record[1],
|
|
|
|
table->record[0]);
|
|
|
|
if (unlikely(error))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (unfold_record(dup_cnt) == -1)
|
|
|
|
{
|
|
|
|
/* restart the scan */
|
|
|
|
if (unlikely(table->file->ha_rnd_init_with_error(1)))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
duplicate_cnt= table->field[addon_cnt - 1];
|
|
|
|
if (addon_cnt == 2)
|
|
|
|
additional_cnt= table->field[addon_cnt - 2];
|
|
|
|
else
|
|
|
|
additional_cnt= NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} while (likely(!error));
|
|
|
|
table->file->ha_rnd_end();
|
|
|
|
}
|
|
|
|
|
2020-11-25 05:05:54 +01:00
|
|
|
/* Clean up table buffers for the next set operation from pipeline */
|
|
|
|
if (next_sl)
|
|
|
|
restore_record(table,s->default_values);
|
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
if (unlikely(error))
|
|
|
|
table->file->print_error(error, MYF(0));
|
|
|
|
|
|
|
|
return (MY_TEST(error));
|
|
|
|
}
|
|
|
|
|
2016-05-09 22:39:10 +02:00
|
|
|
void select_union_recursive::cleanup()
|
|
|
|
{
|
2016-05-19 21:07:53 +02:00
|
|
|
if (table)
|
|
|
|
{
|
2017-03-14 11:52:00 +01:00
|
|
|
select_unit::cleanup();
|
2016-05-19 21:07:53 +02:00
|
|
|
free_tmp_table(thd, table);
|
|
|
|
}
|
2016-05-09 22:39:10 +02:00
|
|
|
|
2016-05-19 21:07:53 +02:00
|
|
|
if (incr_table)
|
|
|
|
{
|
2018-04-16 16:19:19 +02:00
|
|
|
if (incr_table->is_created())
|
|
|
|
{
|
|
|
|
incr_table->file->extra(HA_EXTRA_RESET_STATE);
|
|
|
|
incr_table->file->ha_delete_all_rows();
|
|
|
|
}
|
2016-05-19 21:07:53 +02:00
|
|
|
free_tmp_table(thd, incr_table);
|
|
|
|
}
|
2016-05-09 22:39:10 +02:00
|
|
|
|
2020-12-16 18:11:11 +01:00
|
|
|
List_iterator<TABLE_LIST> it(rec_table_refs);
|
|
|
|
TABLE_LIST *tbl;
|
|
|
|
while ((tbl= it++))
|
2016-05-09 22:39:10 +02:00
|
|
|
{
|
2020-12-16 18:11:11 +01:00
|
|
|
TABLE *tab= tbl->table;
|
2016-07-27 07:58:33 +02:00
|
|
|
if (tab->is_created())
|
|
|
|
{
|
|
|
|
tab->file->extra(HA_EXTRA_RESET_STATE);
|
|
|
|
tab->file->ha_delete_all_rows();
|
|
|
|
}
|
2020-12-16 18:11:11 +01:00
|
|
|
/*
|
2017-01-28 23:52:19 +01:00
|
|
|
The table will be closed later in close_thread_tables(),
|
|
|
|
because it might be used in the statements like
|
|
|
|
ANALYZE WITH r AS (...) SELECT * from r
|
2020-12-16 18:11:11 +01:00
|
|
|
where r is defined through recursion.
|
2017-01-28 23:52:19 +01:00
|
|
|
*/
|
|
|
|
tab->next= thd->rec_tables;
|
|
|
|
thd->rec_tables= tab;
|
2020-12-16 18:11:11 +01:00
|
|
|
tbl->derived_result= 0;
|
2016-05-09 22:39:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-14 18:36:50 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Replace the current result with new_result and prepare it.
|
|
|
|
|
|
|
|
@param new_result New result pointer
|
|
|
|
|
|
|
|
@retval FALSE Success
|
|
|
|
@retval TRUE Error
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool select_union_direct::change_result(select_result *new_result)
|
|
|
|
{
|
|
|
|
result= new_result;
|
2018-05-17 07:42:53 +02:00
|
|
|
return (result->prepare(unit->types, unit) || result->prepare2(NULL));
|
2014-10-14 18:36:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool select_union_direct::postponed_prepare(List<Item> &types)
|
|
|
|
{
|
|
|
|
if (result != NULL)
|
2018-05-17 07:42:53 +02:00
|
|
|
return (result->prepare(types, unit) || result->prepare2(NULL));
|
2014-10-14 18:36:50 +02:00
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool select_union_direct::send_result_set_metadata(List<Item> &list, uint flags)
|
|
|
|
{
|
|
|
|
if (done_send_result_set_metadata)
|
|
|
|
return false;
|
|
|
|
done_send_result_set_metadata= true;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Set global offset and limit to be used in send_data(). These can
|
|
|
|
be variables in prepared statements or stored programs, so they
|
|
|
|
must be reevaluated for each execution.
|
|
|
|
*/
|
|
|
|
offset= unit->global_parameters()->get_offset();
|
|
|
|
limit= unit->global_parameters()->get_limit();
|
|
|
|
if (limit + offset >= limit)
|
|
|
|
limit+= offset;
|
|
|
|
else
|
|
|
|
limit= HA_POS_ERROR; /* purecov: inspected */
|
|
|
|
|
|
|
|
return result->send_result_set_metadata(unit->types, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int select_union_direct::send_data(List<Item> &items)
|
|
|
|
{
|
|
|
|
if (!limit)
|
|
|
|
return false;
|
|
|
|
limit--;
|
|
|
|
if (offset)
|
|
|
|
{
|
|
|
|
offset--;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-10-17 21:59:28 +02:00
|
|
|
send_records++;
|
2014-10-14 18:36:50 +02:00
|
|
|
fill_record(thd, table, table->field, items, true, false);
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(thd->is_error()))
|
2014-10-14 18:36:50 +02:00
|
|
|
return true; /* purecov: inspected */
|
|
|
|
|
|
|
|
return result->send_data(unit->item_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool select_union_direct::initialize_tables (JOIN *join)
|
|
|
|
{
|
|
|
|
if (done_initialize_tables)
|
|
|
|
return false;
|
|
|
|
done_initialize_tables= true;
|
|
|
|
|
|
|
|
return result->initialize_tables(join);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool select_union_direct::send_eof()
|
|
|
|
{
|
|
|
|
// Reset for each SELECT_LEX, so accumulate here
|
|
|
|
limit_found_rows+= thd->limit_found_rows;
|
|
|
|
|
|
|
|
if (unit->thd->lex->current_select == last_select_lex)
|
|
|
|
{
|
|
|
|
thd->limit_found_rows= limit_found_rows;
|
|
|
|
|
|
|
|
// Reset and make ready for re-execution
|
|
|
|
done_send_result_set_metadata= false;
|
|
|
|
done_initialize_tables= false;
|
|
|
|
|
|
|
|
return result->send_eof();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-06 23:08:21 +02:00
|
|
|
/*
|
|
|
|
initialization procedures before fake_select_lex preparation()
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
st_select_lex_unit::init_prepare_fake_select_lex()
|
|
|
|
thd - thread handler
|
2013-12-12 22:55:33 +01:00
|
|
|
first_execution - TRUE at the first execution of the union
|
2004-05-06 23:08:21 +02:00
|
|
|
|
|
|
|
RETURN
|
|
|
|
options of SELECT
|
|
|
|
*/
|
|
|
|
|
2005-05-30 18:54:37 +02:00
|
|
|
void
|
2013-12-12 22:55:33 +01:00
|
|
|
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg,
|
|
|
|
bool first_execution)
|
2004-05-06 23:08:21 +02:00
|
|
|
{
|
2006-12-14 23:51:37 +01:00
|
|
|
thd_arg->lex->current_select= fake_select_lex;
|
2010-06-10 22:45:22 +02:00
|
|
|
fake_select_lex->table_list.link_in_list(&result_table_list,
|
|
|
|
&result_table_list.next_local);
|
2007-05-15 02:06:05 +02:00
|
|
|
fake_select_lex->context.table_list=
|
|
|
|
fake_select_lex->context.first_name_resolution_table=
|
2007-02-19 13:39:37 +01:00
|
|
|
fake_select_lex->get_table_list();
|
2013-12-12 22:55:33 +01:00
|
|
|
/*
|
|
|
|
The flag fake_select_lex->first_execution indicates whether this is
|
|
|
|
called at the first execution of the statement, while first_execution
|
|
|
|
shows whether this is called at the first execution of the union that
|
|
|
|
may form just a subselect.
|
2019-02-27 15:53:25 +01:00
|
|
|
*/
|
|
|
|
if ((fake_select_lex->changed_elements & TOUCHED_SEL_COND) &&
|
|
|
|
first_execution)
|
2007-05-15 02:06:05 +02:00
|
|
|
{
|
2014-10-14 18:36:50 +02:00
|
|
|
for (ORDER *order= global_parameters()->order_list.first;
|
2007-05-15 02:06:05 +02:00
|
|
|
order;
|
|
|
|
order= order->next)
|
|
|
|
order->item= &order->item_ptr;
|
|
|
|
}
|
2014-10-14 18:36:50 +02:00
|
|
|
for (ORDER *order= global_parameters()->order_list.first;
|
2005-07-01 06:05:42 +02:00
|
|
|
order;
|
|
|
|
order=order->next)
|
|
|
|
{
|
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
|
|
|
(*order->item)->walk(&Item::change_context_processor, 0,
|
2016-06-26 22:42:48 +02:00
|
|
|
&fake_select_lex->context);
|
2010-09-05 17:43:47 +02:00
|
|
|
(*order->item)->walk(&Item::set_fake_select_as_master_processor, 0,
|
2016-06-26 22:42:48 +02:00
|
|
|
fake_select_lex);
|
2005-07-01 06:05:42 +02:00
|
|
|
}
|
2004-05-06 23:08:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-04-26 07:49:41 +02:00
|
|
|
bool st_select_lex_unit::prepare_join(THD *thd_arg, SELECT_LEX *sl,
|
|
|
|
select_result *tmp_result,
|
2019-12-30 12:56:19 +01:00
|
|
|
ulonglong additional_options,
|
2017-04-26 07:49:41 +02:00
|
|
|
bool is_union_select)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("st_select_lex_unit::prepare_join");
|
2018-01-14 16:03:35 +01:00
|
|
|
TABLE_LIST *derived= sl->master_unit()->derived;
|
2017-04-26 07:49:41 +02:00
|
|
|
bool can_skip_order_by;
|
|
|
|
sl->options|= SELECT_NO_UNLOCK;
|
|
|
|
JOIN *join= new JOIN(thd_arg, sl->item_list,
|
|
|
|
(sl->options | thd_arg->variables.option_bits |
|
|
|
|
additional_options),
|
|
|
|
tmp_result);
|
|
|
|
if (!join)
|
|
|
|
DBUG_RETURN(true);
|
|
|
|
|
|
|
|
thd_arg->lex->current_select= sl;
|
|
|
|
|
2020-12-19 12:59:37 +01:00
|
|
|
can_skip_order_by= is_union_select && !(sl->braces &&
|
|
|
|
sl->limit_params.explicit_limit);
|
2017-04-26 07:49:41 +02:00
|
|
|
|
|
|
|
saved_error= join->prepare(sl->table_list.first,
|
2018-01-14 16:03:35 +01:00
|
|
|
(derived && derived->merged ? NULL : sl->where),
|
2017-04-26 07:49:41 +02:00
|
|
|
(can_skip_order_by ? 0 :
|
|
|
|
sl->order_list.elements) +
|
|
|
|
sl->group_list.elements,
|
|
|
|
can_skip_order_by ?
|
|
|
|
NULL : sl->order_list.first,
|
|
|
|
can_skip_order_by,
|
|
|
|
sl->group_list.first,
|
|
|
|
sl->having,
|
|
|
|
(is_union_select ? NULL :
|
|
|
|
thd_arg->lex->proc_list.first),
|
|
|
|
sl, this);
|
|
|
|
|
|
|
|
last_procedure= join->procedure;
|
|
|
|
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(saved_error || (saved_error= thd_arg->is_fatal_error)))
|
2017-04-26 07:49:41 +02:00
|
|
|
DBUG_RETURN(true);
|
|
|
|
/*
|
|
|
|
Remove all references from the select_lex_units to the subqueries that
|
|
|
|
are inside the ORDER BY clause.
|
|
|
|
*/
|
|
|
|
if (can_skip_order_by)
|
|
|
|
{
|
|
|
|
for (ORDER *ord= (ORDER *)sl->order_list.first; ord; ord= ord->next)
|
|
|
|
{
|
|
|
|
(*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DBUG_RETURN(false);
|
|
|
|
}
|
2016-05-09 22:39:10 +02:00
|
|
|
|
|
|
|
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
/**
|
|
|
|
Aggregate data type handlers for the "count" leftmost UNION parts.
|
|
|
|
*/
|
|
|
|
bool st_select_lex_unit::join_union_type_handlers(THD *thd_arg,
|
|
|
|
Type_holder *holders,
|
|
|
|
uint count)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("st_select_lex_unit::join_union_type_handlers");
|
|
|
|
SELECT_LEX *first_sl= first_select(), *sl= first_sl;
|
|
|
|
for (uint i= 0; i < count ; sl= sl->next_select(), i++)
|
|
|
|
{
|
|
|
|
Item *item;
|
|
|
|
List_iterator_fast<Item> it(sl->item_list);
|
|
|
|
for (uint pos= 0; (item= it++); pos++)
|
|
|
|
{
|
|
|
|
const Type_handler *item_type_handler= item->real_type_handler();
|
|
|
|
if (sl == first_sl)
|
|
|
|
holders[pos].set_handler(item_type_handler);
|
|
|
|
else
|
|
|
|
{
|
2017-11-05 19:22:01 +01:00
|
|
|
DBUG_ASSERT(first_sl->item_list.elements == sl->item_list.elements);
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
if (holders[pos].aggregate_for_result(item_type_handler))
|
|
|
|
{
|
|
|
|
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
|
|
|
|
holders[pos].type_handler()->name().ptr(),
|
|
|
|
item_type_handler->name().ptr(),
|
|
|
|
"UNION");
|
|
|
|
DBUG_RETURN(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DBUG_RETURN(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Aggregate data type attributes for the "count" leftmost UNION parts.
|
|
|
|
*/
|
|
|
|
bool st_select_lex_unit::join_union_type_attributes(THD *thd_arg,
|
|
|
|
Type_holder *holders,
|
|
|
|
uint count)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("st_select_lex_unit::join_union_type_attributes");
|
|
|
|
SELECT_LEX *sl, *first_sl= first_select();
|
|
|
|
uint item_pos;
|
|
|
|
for (uint pos= 0; pos < first_sl->item_list.elements; pos++)
|
|
|
|
{
|
|
|
|
if (holders[pos].alloc_arguments(thd_arg, count))
|
|
|
|
DBUG_RETURN(true);
|
|
|
|
}
|
|
|
|
for (item_pos= 0, sl= first_sl ;
|
|
|
|
item_pos < count;
|
|
|
|
sl= sl->next_select(), item_pos++)
|
|
|
|
{
|
|
|
|
Item *item_tmp;
|
|
|
|
List_iterator_fast<Item> itx(sl->item_list);
|
|
|
|
for (uint holder_pos= 0 ; (item_tmp= itx++); holder_pos++)
|
|
|
|
{
|
2017-08-25 10:25:48 +02:00
|
|
|
/*
|
|
|
|
If the outer query has a GROUP BY clause, an outer reference to this
|
|
|
|
query block may have been wrapped in a Item_outer_ref, which has not
|
|
|
|
been fixed yet. An Item_type_holder must be created based on a fixed
|
|
|
|
Item, so use the inner Item instead.
|
|
|
|
*/
|
2018-06-05 09:56:19 +02:00
|
|
|
DBUG_ASSERT(item_tmp->is_fixed() ||
|
2017-08-25 10:25:48 +02:00
|
|
|
(item_tmp->type() == Item::REF_ITEM &&
|
|
|
|
((Item_ref *)(item_tmp))->ref_type() ==
|
|
|
|
Item_ref::OUTER_REF));
|
2018-06-05 09:56:19 +02:00
|
|
|
if (!item_tmp->is_fixed())
|
2017-08-25 10:25:48 +02:00
|
|
|
item_tmp= item_tmp->real_item();
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
holders[holder_pos].add_argument(item_tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (uint pos= 0; pos < first_sl->item_list.elements; pos++)
|
|
|
|
{
|
|
|
|
if (holders[pos].aggregate_attributes(thd_arg))
|
|
|
|
DBUG_RETURN(true);
|
|
|
|
}
|
|
|
|
DBUG_RETURN(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Join data types for the leftmost "count" UNION parts
|
|
|
|
and store corresponding Item_type_holder's into "types".
|
|
|
|
*/
|
|
|
|
bool st_select_lex_unit::join_union_item_types(THD *thd_arg,
|
|
|
|
List<Item> &types,
|
|
|
|
uint count)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("st_select_lex_unit::join_union_select_list_types");
|
|
|
|
SELECT_LEX *first_sl= first_select();
|
|
|
|
Type_holder *holders;
|
|
|
|
|
|
|
|
if (!(holders= new (thd_arg->mem_root)
|
|
|
|
Type_holder[first_sl->item_list.elements]) ||
|
|
|
|
join_union_type_handlers(thd_arg, holders, count) ||
|
|
|
|
join_union_type_attributes(thd_arg, holders, count))
|
|
|
|
DBUG_RETURN(true);
|
|
|
|
|
2018-05-14 23:38:17 +02:00
|
|
|
bool is_recursive= with_element && with_element->is_recursive;
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
types.empty();
|
|
|
|
List_iterator_fast<Item> it(first_sl->item_list);
|
|
|
|
Item *item_tmp;
|
|
|
|
for (uint pos= 0; (item_tmp= it++); pos++)
|
|
|
|
{
|
2018-05-14 23:38:17 +02:00
|
|
|
/*
|
|
|
|
SQL standard requires forced nullability only for
|
|
|
|
recursive columns. However type aggregation in our
|
|
|
|
implementation so far does not differentiate between
|
|
|
|
recursive and non-recursive columns of a recursive CTE.
|
|
|
|
TODO: this should be fixed.
|
|
|
|
*/
|
|
|
|
bool pos_maybe_null= is_recursive ? true : holders[pos].get_maybe_null();
|
|
|
|
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
/* Error's in 'new' will be detected after loop */
|
|
|
|
types.push_back(new (thd_arg->mem_root)
|
|
|
|
Item_type_holder(thd_arg,
|
2017-10-23 14:12:37 +02:00
|
|
|
item_tmp,
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
holders[pos].type_handler(),
|
|
|
|
&holders[pos]/*Type_all_attributes*/,
|
2018-05-14 23:38:17 +02:00
|
|
|
pos_maybe_null));
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
}
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(thd_arg->is_fatal_error))
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
DBUG_RETURN(true); // out of memory
|
|
|
|
DBUG_RETURN(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
bool init_item_int(THD* thd, Item_int* &item)
|
|
|
|
{
|
|
|
|
if (!item)
|
|
|
|
{
|
|
|
|
Query_arena *arena, backup_arena;
|
|
|
|
arena= thd->activate_stmt_arena_if_needed(&backup_arena);
|
|
|
|
|
|
|
|
item= new (thd->mem_root) Item_int(thd, 0);
|
|
|
|
|
|
|
|
if (arena)
|
|
|
|
thd->restore_active_arena(arena, &backup_arena);
|
|
|
|
|
|
|
|
if (!item)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->value= 0;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-18 14:29:48 +02:00
|
|
|
bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
|
|
|
|
select_result *sel_result,
|
2019-12-30 12:56:19 +01:00
|
|
|
ulonglong additional_options)
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
2018-04-18 14:29:48 +02:00
|
|
|
SELECT_LEX *lex_select_save= thd->lex->current_select;
|
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
|
|
|
SELECT_LEX *sl, *first_sl= first_select();
|
2016-05-09 22:39:10 +02:00
|
|
|
bool is_recursive= with_element && with_element->is_recursive;
|
2016-05-24 20:29:52 +02:00
|
|
|
bool is_rec_result_table_created= false;
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
uint union_part_count= 0;
|
2003-11-23 01:01:15 +01:00
|
|
|
select_result *tmp_result;
|
2007-04-23 13:16:49 +02:00
|
|
|
bool is_union_select;
|
2019-08-24 15:42:35 +02:00
|
|
|
bool have_except= false, have_intersect= false,
|
|
|
|
have_except_all_or_intersect_all= false;
|
2014-10-14 18:36:50 +02:00
|
|
|
bool instantiate_tmp_table= false;
|
2019-09-20 18:03:38 +02:00
|
|
|
bool single_tvc= !first_sl->next_select() && first_sl->tvc;
|
|
|
|
bool single_tvc_wo_order= single_tvc && !first_sl->order_list.elements;
|
2002-10-13 13:25:16 +02:00
|
|
|
DBUG_ENTER("st_select_lex_unit::prepare");
|
2016-09-19 19:07:17 +02:00
|
|
|
DBUG_ASSERT(thd == current_thd);
|
2002-10-13 13:25:16 +02:00
|
|
|
|
2018-05-18 07:56:27 +02:00
|
|
|
if (is_recursive && (sl= first_sl->next_select()))
|
|
|
|
{
|
|
|
|
SELECT_LEX *next_sl;
|
|
|
|
for ( ; ; sl= next_sl)
|
|
|
|
{
|
|
|
|
next_sl= sl->next_select();
|
|
|
|
if (!next_sl)
|
|
|
|
break;
|
|
|
|
if (next_sl->with_all_modifier != sl->with_all_modifier)
|
|
|
|
{
|
|
|
|
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
|
|
|
|
"mix of ALL and DISTINCT UNION operations in recursive CTE spec");
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-19 19:07:17 +02:00
|
|
|
describe= additional_options & SELECT_DESCRIBE;
|
2004-05-06 19:40:21 +02:00
|
|
|
|
2014-10-14 18:36:50 +02:00
|
|
|
/*
|
|
|
|
Save fake_select_lex in case we don't need it for anything but
|
|
|
|
global parameters.
|
|
|
|
*/
|
|
|
|
if (saved_fake_select_lex == NULL) // Don't overwrite on PS second prepare
|
|
|
|
saved_fake_select_lex= fake_select_lex;
|
|
|
|
|
2003-10-27 00:01:27 +01:00
|
|
|
/*
|
|
|
|
result object should be reassigned even if preparing already done for
|
|
|
|
max/min subquery (ALL/ANY optimization)
|
|
|
|
*/
|
|
|
|
result= sel_result;
|
2019-08-24 15:42:35 +02:00
|
|
|
|
2002-10-13 13:25:16 +02:00
|
|
|
if (prepared)
|
2004-05-06 19:40:21 +02:00
|
|
|
{
|
|
|
|
if (describe)
|
|
|
|
{
|
|
|
|
/* fast reinit for EXPLAIN */
|
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
|
|
|
for (sl= first_sl; sl; sl= sl->next_select())
|
2004-05-06 19:40:21 +02:00
|
|
|
{
|
2017-08-29 02:32:39 +02:00
|
|
|
if (sl->tvc)
|
2004-05-06 19:40:21 +02:00
|
|
|
{
|
2017-08-29 02:32:39 +02:00
|
|
|
sl->tvc->result= result;
|
|
|
|
if (result->prepare(sl->item_list, this))
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
sl->tvc->select_options|= SELECT_DESCRIBE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sl->join->result= result;
|
2021-03-28 20:09:51 +02:00
|
|
|
lim.clear();
|
2017-08-29 02:32:39 +02:00
|
|
|
if (!sl->join->procedure &&
|
|
|
|
result->prepare(sl->join->fields_list, this))
|
|
|
|
{
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
}
|
|
|
|
sl->join->select_options|= SELECT_DESCRIBE;
|
|
|
|
sl->join->reinit();
|
2004-05-06 19:40:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(FALSE);
|
2004-05-06 19:40:21 +02:00
|
|
|
}
|
2002-10-13 13:25:16 +02:00
|
|
|
prepared= 1;
|
2006-12-14 23:51:37 +01:00
|
|
|
saved_error= FALSE;
|
2003-04-21 20:03:32 +02:00
|
|
|
|
2018-04-18 14:29:48 +02:00
|
|
|
thd->lex->current_select= sl= first_sl;
|
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
|
|
|
found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
|
2017-08-29 02:32:39 +02:00
|
|
|
is_union_select= is_unit_op() || fake_select_lex || single_tvc;
|
2003-11-23 01:01:15 +01:00
|
|
|
|
2020-08-04 11:06:01 +02:00
|
|
|
/*
|
|
|
|
If we are reading UNION output and the UNION is in the
|
|
|
|
IN/ANY/ALL/EXISTS subquery, then ORDER BY is redundant and hence should
|
|
|
|
be removed.
|
|
|
|
Example:
|
|
|
|
select ... col IN (select col2 FROM t1 union select col3 from t2 ORDER BY 1)
|
|
|
|
|
|
|
|
(as for ORDER BY ... LIMIT, it currently not supported inside
|
|
|
|
IN/ALL/ANY subqueries)
|
|
|
|
(For non-UNION this removal of ORDER BY clause is done in
|
|
|
|
check_and_do_in_subquery_rewrites())
|
|
|
|
*/
|
2020-08-10 17:40:57 +02:00
|
|
|
if (item && is_unit_op() &&
|
2020-08-04 11:06:01 +02:00
|
|
|
(item->is_in_predicate() || item->is_exists_predicate()))
|
|
|
|
{
|
|
|
|
global_parameters()->order_list.first= NULL;
|
|
|
|
global_parameters()->order_list.elements= 0;
|
|
|
|
}
|
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
/* will only optimize once */
|
|
|
|
if (!bag_set_op_optimized && !is_recursive)
|
|
|
|
{
|
|
|
|
optimize_bag_operation(false);
|
|
|
|
}
|
|
|
|
|
2017-03-14 11:52:00 +01:00
|
|
|
for (SELECT_LEX *s= first_sl; s; s= s->next_select())
|
|
|
|
{
|
|
|
|
switch (s->linkage)
|
|
|
|
{
|
|
|
|
case INTERSECT_TYPE:
|
|
|
|
have_intersect= TRUE;
|
2019-08-24 15:42:35 +02:00
|
|
|
if (!s->distinct){
|
|
|
|
have_except_all_or_intersect_all= true;
|
|
|
|
}
|
2017-03-14 11:52:00 +01:00
|
|
|
break;
|
|
|
|
case EXCEPT_TYPE:
|
|
|
|
have_except= TRUE;
|
2019-08-24 15:42:35 +02:00
|
|
|
if (!s->distinct){
|
|
|
|
have_except_all_or_intersect_all= TRUE;
|
|
|
|
}
|
2017-03-14 11:52:00 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-08-10 17:40:57 +02:00
|
|
|
|
2002-05-08 22:14:40 +02:00
|
|
|
/* Global option */
|
2003-11-23 01:01:15 +01:00
|
|
|
|
2016-06-06 19:01:16 +02:00
|
|
|
if (is_union_select || is_recursive)
|
2001-08-02 05:29:50 +02:00
|
|
|
{
|
2019-09-20 18:03:38 +02:00
|
|
|
if ((single_tvc_wo_order && !fake_select_lex) ||
|
|
|
|
(is_unit_op() && !union_needs_tmp_table() &&
|
|
|
|
!have_except && !have_intersect && !single_tvc))
|
2014-10-14 18:36:50 +02:00
|
|
|
{
|
|
|
|
SELECT_LEX *last= first_select();
|
|
|
|
while (last->next_select())
|
|
|
|
last= last->next_select();
|
2015-04-22 11:29:56 +02:00
|
|
|
if (!(tmp_result= union_result=
|
2018-04-18 14:29:48 +02:00
|
|
|
new (thd->mem_root) select_union_direct(thd, sel_result,
|
2015-04-22 11:29:56 +02:00
|
|
|
last)))
|
2014-10-14 18:36:50 +02:00
|
|
|
goto err; /* purecov: inspected */
|
|
|
|
fake_select_lex= NULL;
|
|
|
|
instantiate_tmp_table= false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-05-09 22:39:10 +02:00
|
|
|
if (!is_recursive)
|
2019-09-24 10:41:38 +02:00
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
/*
|
|
|
|
class "select_unit_ext" handles query contains EXCEPT ALL and / or
|
|
|
|
INTERSECT ALL. Others are handled by class "select_unit"
|
|
|
|
If have EXCEPT ALL or INTERSECT ALL in the query. First operand
|
|
|
|
should be UNION ALL
|
|
|
|
*/
|
|
|
|
if (have_except_all_or_intersect_all)
|
|
|
|
{
|
|
|
|
union_result= new (thd->mem_root) select_unit_ext(thd);
|
|
|
|
first_sl->distinct= false;
|
|
|
|
}
|
|
|
|
else
|
2019-09-24 10:41:38 +02:00
|
|
|
union_result= new (thd->mem_root) select_unit(thd);
|
|
|
|
}
|
2016-05-09 22:39:10 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
with_element->rec_result=
|
2018-04-18 14:29:48 +02:00
|
|
|
new (thd->mem_root) select_union_recursive(thd);
|
2016-05-09 22:39:10 +02:00
|
|
|
union_result= with_element->rec_result;
|
2018-05-18 00:47:17 +02:00
|
|
|
if (fake_select_lex)
|
|
|
|
{
|
|
|
|
if (fake_select_lex->order_list.first ||
|
2020-12-19 12:59:37 +01:00
|
|
|
fake_select_lex->limit_params.explicit_limit)
|
2018-05-18 00:47:17 +02:00
|
|
|
{
|
|
|
|
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
|
|
|
|
"global ORDER_BY/LIMIT in recursive CTE spec");
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
fake_select_lex->cleanup();
|
|
|
|
fake_select_lex= NULL;
|
|
|
|
}
|
2016-05-09 22:39:10 +02:00
|
|
|
}
|
|
|
|
if (!(tmp_result= union_result))
|
2014-10-14 18:36:50 +02:00
|
|
|
goto err; /* purecov: inspected */
|
|
|
|
instantiate_tmp_table= true;
|
|
|
|
}
|
2003-01-29 18:42:39 +01:00
|
|
|
}
|
|
|
|
else
|
2003-11-23 01:01:15 +01:00
|
|
|
tmp_result= sel_result;
|
2001-09-17 14:40:03 +02:00
|
|
|
|
2005-07-01 06:05:42 +02:00
|
|
|
sl->context.resolve_in_select_list= TRUE;
|
2017-04-26 07:49:41 +02:00
|
|
|
|
|
|
|
if (!is_union_select && !is_recursive)
|
|
|
|
{
|
2017-06-29 14:32:17 +02:00
|
|
|
if (sl->tvc)
|
|
|
|
{
|
2018-04-18 14:29:48 +02:00
|
|
|
if (sl->tvc->prepare(thd, sl, tmp_result, this))
|
2017-06-29 14:32:17 +02:00
|
|
|
goto err;
|
|
|
|
}
|
2019-11-25 14:01:43 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (prepare_join(thd, first_sl, tmp_result, additional_options,
|
2017-04-26 07:49:41 +02:00
|
|
|
is_union_select))
|
2019-11-25 14:01:43 +01:00
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (derived_arg && derived_arg->table &&
|
|
|
|
derived_arg->derived_type == VIEW_ALGORITHM_MERGE &&
|
|
|
|
derived_arg->table->versioned())
|
|
|
|
{
|
|
|
|
/* Got versioning conditions (see vers_setup_conds()), need to update
|
|
|
|
derived_arg. */
|
|
|
|
derived_arg->where= first_sl->where;
|
|
|
|
}
|
|
|
|
}
|
2017-04-26 07:49:41 +02:00
|
|
|
types= first_sl->item_list;
|
|
|
|
goto cont;
|
|
|
|
}
|
2019-05-19 20:55:37 +02:00
|
|
|
|
|
|
|
if (sl->tvc && sl->order_list.elements &&
|
|
|
|
!sl->tvc->to_be_wrapped_as_with_tail())
|
|
|
|
{
|
2019-09-20 18:03:38 +02:00
|
|
|
SELECT_LEX_UNIT *unit= sl->master_unit();
|
2019-05-19 20:55:37 +02:00
|
|
|
if (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)
|
|
|
|
{
|
2019-09-20 18:03:38 +02:00
|
|
|
unit->fake_select_lex= 0;
|
|
|
|
unit->saved_fake_select_lex= 0;
|
2019-05-19 20:55:37 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-20 18:03:38 +02:00
|
|
|
if (!unit->first_select()->next_select())
|
|
|
|
{
|
|
|
|
if (!unit->fake_select_lex)
|
2020-12-19 12:59:37 +01:00
|
|
|
{
|
2019-09-20 18:03:38 +02:00
|
|
|
Query_arena *arena, backup_arena;
|
|
|
|
arena= thd->activate_stmt_arena_if_needed(&backup_arena);
|
|
|
|
bool rc= unit->add_fake_select_lex(thd);
|
|
|
|
if (arena)
|
|
|
|
thd->restore_active_arena(arena, &backup_arena);
|
|
|
|
if (rc)
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
SELECT_LEX *fake= unit->fake_select_lex;
|
|
|
|
fake->order_list= sl->order_list;
|
2020-12-19 12:59:37 +01:00
|
|
|
fake->limit_params= sl->limit_params;
|
2019-09-20 18:03:38 +02:00
|
|
|
sl->order_list.empty();
|
2020-12-19 12:59:37 +01:00
|
|
|
sl->limit_params.clear();
|
2019-09-20 18:03:38 +02:00
|
|
|
if (describe)
|
|
|
|
fake->options|= SELECT_DESCRIBE;
|
|
|
|
}
|
2020-12-19 12:59:37 +01:00
|
|
|
else if (!sl->limit_params.explicit_limit)
|
2019-09-20 18:03:38 +02:00
|
|
|
sl->order_list.empty();
|
2019-05-19 20:55:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
for (;sl; sl= sl->next_select(), union_part_count++)
|
2017-04-26 07:49:41 +02:00
|
|
|
{
|
2017-06-29 14:32:17 +02:00
|
|
|
if (sl->tvc)
|
|
|
|
{
|
2019-05-08 09:08:09 +02:00
|
|
|
if (sl->tvc->to_be_wrapped_as_with_tail() &&
|
|
|
|
!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW))
|
|
|
|
|
|
|
|
{
|
|
|
|
st_select_lex *wrapper_sl= wrap_tvc_with_tail(thd, sl);
|
|
|
|
if (!wrapper_sl)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (sl == first_sl)
|
|
|
|
first_sl= wrapper_sl;
|
|
|
|
sl= wrapper_sl;
|
|
|
|
|
|
|
|
if (prepare_join(thd, sl, tmp_result, additional_options,
|
|
|
|
is_union_select))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
else if (sl->tvc->prepare(thd, sl, tmp_result, this))
|
2019-09-20 18:03:38 +02:00
|
|
|
goto err;
|
2017-06-29 14:32:17 +02:00
|
|
|
}
|
2018-04-18 14:29:48 +02:00
|
|
|
else if (prepare_join(thd, sl, tmp_result, additional_options,
|
2017-06-29 14:32:17 +02:00
|
|
|
is_union_select))
|
2017-04-26 07:49:41 +02:00
|
|
|
goto err;
|
|
|
|
|
2005-01-03 20:04:33 +01:00
|
|
|
/*
|
|
|
|
setup_tables_done_option should be set only for very first SELECT,
|
|
|
|
because it protect from secont setup_tables call for select-like non
|
|
|
|
select commands (DELETE/INSERT/...) and they use only very first
|
|
|
|
SELECT (for union it can be only INSERT ... SELECT).
|
|
|
|
*/
|
|
|
|
additional_options&= ~OPTION_SETUP_TABLES_DONE;
|
2014-11-15 22:18:33 +01:00
|
|
|
|
2005-07-30 03:53:35 +02:00
|
|
|
/*
|
|
|
|
Use items list of underlaid select for derived tables to preserve
|
|
|
|
information about fields lengths and exact types
|
|
|
|
*/
|
2017-04-26 07:49:41 +02:00
|
|
|
if (sl == first_sl)
|
2003-11-23 01:01:15 +01:00
|
|
|
{
|
2018-03-13 01:53:48 +01:00
|
|
|
if (with_element)
|
2016-05-09 22:39:10 +02:00
|
|
|
{
|
2020-01-27 21:50:16 +01:00
|
|
|
if (with_element->process_columns_of_derived_unit(thd, this))
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
goto err;
|
2016-05-09 22:39:10 +02:00
|
|
|
if (check_duplicate_names(thd, sl->item_list, 0))
|
|
|
|
goto err;
|
|
|
|
}
|
2003-11-23 01:01:15 +01:00
|
|
|
}
|
2017-11-05 19:22:01 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (first_sl->item_list.elements != sl->item_list.elements)
|
|
|
|
{
|
|
|
|
my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
|
2018-04-18 14:29:48 +02:00
|
|
|
ER_THD(thd, ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),
|
2017-11-05 19:22:01 +01:00
|
|
|
MYF(0));
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
2016-05-24 20:29:52 +02:00
|
|
|
if (is_recursive)
|
2016-05-09 22:39:10 +02:00
|
|
|
{
|
2016-05-24 20:29:52 +02:00
|
|
|
if (!with_element->is_anchor(sl))
|
|
|
|
sl->uncacheable|= UNCACHEABLE_UNITED;
|
2018-04-24 13:19:44 +02:00
|
|
|
if (!is_rec_result_table_created &&
|
|
|
|
(!sl->next_select() ||
|
|
|
|
sl->next_select() == with_element->first_recursive))
|
2016-05-24 20:29:52 +02:00
|
|
|
{
|
|
|
|
ulonglong create_options;
|
2018-04-18 14:29:48 +02:00
|
|
|
create_options= (first_sl->options | thd->variables.option_bits |
|
2016-05-24 20:29:52 +02:00
|
|
|
TMP_TABLE_ALL_COLUMNS);
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
// Join data types for all non-recursive parts of a recursive UNION
|
|
|
|
if (join_union_item_types(thd, types, union_part_count + 1))
|
|
|
|
goto err;
|
2016-05-24 20:29:52 +02:00
|
|
|
if (union_result->create_result_table(thd, &types,
|
2019-08-30 08:47:12 +02:00
|
|
|
MY_TEST(union_distinct),
|
2018-04-18 14:29:48 +02:00
|
|
|
create_options,
|
|
|
|
&derived_arg->alias, false,
|
2017-03-14 11:52:00 +01:00
|
|
|
instantiate_tmp_table, false,
|
|
|
|
0))
|
2016-05-24 20:29:52 +02:00
|
|
|
goto err;
|
2019-08-24 15:42:35 +02:00
|
|
|
if (have_except_all_or_intersect_all)
|
|
|
|
{
|
|
|
|
union_result->init();
|
|
|
|
}
|
2018-04-18 14:29:48 +02:00
|
|
|
if (!derived_arg->table)
|
2018-12-02 00:06:04 +01:00
|
|
|
{
|
2020-12-16 18:11:11 +01:00
|
|
|
bool res= false;
|
|
|
|
|
2020-12-23 19:28:02 +01:00
|
|
|
if ((!derived_arg->is_with_table_recursive_reference() ||
|
|
|
|
!derived_arg->derived_result) &&
|
|
|
|
!(derived_arg->derived_result=
|
|
|
|
new (thd->mem_root) select_unit(thd)))
|
2020-12-16 18:11:11 +01:00
|
|
|
goto err; // out of memory
|
|
|
|
thd->create_tmp_table_for_derived= TRUE;
|
2020-12-23 19:28:02 +01:00
|
|
|
|
|
|
|
res= derived_arg->derived_result->create_result_table(thd,
|
2020-12-16 18:11:11 +01:00
|
|
|
&types,
|
|
|
|
FALSE,
|
|
|
|
create_options,
|
2020-12-23 19:28:02 +01:00
|
|
|
&derived_arg->alias,
|
|
|
|
FALSE, FALSE,
|
|
|
|
FALSE, 0);
|
2020-12-16 18:11:11 +01:00
|
|
|
thd->create_tmp_table_for_derived= FALSE;
|
|
|
|
if (res)
|
|
|
|
goto err;
|
2020-12-23 19:28:02 +01:00
|
|
|
derived_arg->derived_result->set_unit(this);
|
|
|
|
derived_arg->table= derived_arg->derived_result->table;
|
|
|
|
if (derived_arg->is_with_table_recursive_reference())
|
2020-12-16 18:11:11 +01:00
|
|
|
{
|
2020-12-23 19:28:02 +01:00
|
|
|
/* Here 'derived_arg' is the primary recursive table reference */
|
|
|
|
derived_arg->with->rec_result->
|
|
|
|
rec_table_refs.push_back(derived_arg);
|
2020-12-16 18:11:11 +01:00
|
|
|
}
|
2018-12-02 00:06:04 +01:00
|
|
|
}
|
2016-05-24 20:29:52 +02:00
|
|
|
with_element->mark_as_with_prepared_anchor();
|
|
|
|
is_rec_result_table_created= true;
|
|
|
|
}
|
|
|
|
}
|
2001-08-02 05:29:50 +02:00
|
|
|
}
|
2019-08-24 15:42:35 +02:00
|
|
|
|
MDEV-12775 Reuse data type aggregation code for hybrid functions and UNION
Introducing a new class Type_holder (used internally in sql_union.cc),
to reuse exactly the same data type attribute aggregation Type_handler API
for hybrid functions and UNION.
This fixes a number of bugs in UNION:
- MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
- MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
- MDEV-12594 UNION between fixed length double columns does not always preserve scale
- MDEV-12595 UNION converts INT to BIGINT
- MDEV-12599 UNION is not symmetric when mixing INT and CHAR
Details:
- sql_union.cc: Reusing attribute aggregation for UNION.
Adding new methods:
* st_select_lex_unit::join_union_type_handlers()
* st_select_lex_unit::join_union_type_attributes()
* st_select_lex_unit::join_union_item_types()
Removing the old join_types()-based code.
- Changing Type_handler::Item_hybrid_func_fix_attributes()
to accept "name", Type_handler_hybrid_field_type, Type_all_attributes
as three separate parameters instead of a single Item_hybrid_func parameter,
to make it possible to pass both Item_hybrid_func and Type_holder.
- Moving the former special GEOMETRY and ENUM/SET attribute aggregation code
from Item_type_holder::join_types() to
* Type_handler_typelib::Item_hybrid_func_fix_attributes().
* Type_handler_geometry::Item_hybrid_func_fix_attrubutes().
This makes GEOMETRY/ENUM/SET symmetric with all other data types
(from the UNION point of view).
Removing Item_type_holder::join_types() and Item_type_holder::get_full_info().
- Adding new methods into Type_all_attributes:
* Type_all_attributes::set_geometry_type() and
Item_hybrid_func::set_geometry_type().
* Adding Type_all_attributes::get_typelib().
* Adding Type_all_attributes::set_typelib().
- Adding Type_handler_typelib as a common parent for
Type_handler_enum and Type_handler_set, to avoid code duplication: they have
already had two common methods, and we're adding one more shared method.
- Adding Type_all_attributes::set_maybe_null(), as some type handlers
may want to set maybe_null (e.g. Type_handler_geometry) during data type
attribute aggregation.
- Changing Type_geometry_attributes() to accept Type_handler
and Type_all_attributes as two separate parameters, instead
of a single Item parameter, to make it possible to pass Type_holder.
- Adding Item_args::add_argument().
- Moving Item_args::alloc_arguments() from "protected" to "public".
- Moving Item_type_holder::Item_type_holder() from item.cc to item.h, as
now it's very simple.
Btw, this constructor should probably be eventually removed.
It's now used only in sql_show.cc, which could be modified to use
Item_return_decimal (for symmetry with Item_return_xxx created for all
other data types). Or, another option: remove all Item_return_xxx and
use Item_type_holder for all data types instead.
- storage/tokudb/mysql-test/tokudb/r/type_float.result
Recording new results (MDEV-12594).
- mysql-test/r/cte_recursive.result
Recording new results (MDEV-9497)
- mysql-test/r/subselect*.result
Recording new results (MDEV-12595)
- mysql-test/r/metadata.result
Recording new results (MDEV-9495)
- mysql-test/r/temp_table.result
Recording new results (MDEV-12594)
- mysql-test/r/type_float.result
Recording new results (MDEV-12594)
2017-05-10 13:29:48 +02:00
|
|
|
// In case of a non-recursive UNION, join data types for all UNION parts.
|
|
|
|
if (!is_recursive && join_union_item_types(thd, types, union_part_count))
|
|
|
|
goto err;
|
2003-03-06 16:02:10 +01:00
|
|
|
|
2017-04-26 07:49:41 +02:00
|
|
|
cont:
|
2014-10-14 18:36:50 +02:00
|
|
|
/*
|
|
|
|
If the query is using select_union_direct, we have postponed
|
|
|
|
preparation of the underlying select_result until column types
|
|
|
|
are known.
|
|
|
|
*/
|
|
|
|
if (union_result != NULL && union_result->postponed_prepare(types))
|
|
|
|
DBUG_RETURN(true);
|
|
|
|
|
2007-04-23 13:16:49 +02:00
|
|
|
if (is_union_select)
|
2003-01-29 18:42:39 +01:00
|
|
|
{
|
2004-10-18 14:56:25 +02:00
|
|
|
/*
|
2004-10-19 08:45:33 +02:00
|
|
|
Check that it was possible to aggregate
|
|
|
|
all collations together for UNION.
|
2004-10-18 14:56:25 +02:00
|
|
|
*/
|
|
|
|
List_iterator_fast<Item> tp(types);
|
|
|
|
Item *type;
|
2005-08-12 12:54:42 +02:00
|
|
|
ulonglong create_options;
|
2011-05-19 23:53:16 +02:00
|
|
|
uint save_tablenr= 0;
|
|
|
|
table_map save_map= 0;
|
2011-08-17 07:48:35 +02:00
|
|
|
uint save_maybe_null= 0;
|
2004-10-29 18:26:52 +02:00
|
|
|
|
2004-10-18 14:56:25 +02:00
|
|
|
while ((type= tp++))
|
|
|
|
{
|
2019-04-23 11:45:28 +02:00
|
|
|
/*
|
|
|
|
Test if the aggregated data type is OK for a UNION element.
|
|
|
|
E.g. in case of string data, DERIVATION_NONE is not allowed.
|
|
|
|
*/
|
|
|
|
if (type->type_handler()->union_element_finalize(type))
|
2004-10-18 14:56:25 +02:00
|
|
|
goto err;
|
|
|
|
}
|
2005-08-06 23:08:28 +02:00
|
|
|
|
2009-12-22 16:52:15 +01:00
|
|
|
/*
|
|
|
|
Disable the usage of fulltext searches in the last union branch.
|
|
|
|
This is a temporary 5.x limitation because of the way the fulltext
|
|
|
|
search functions are handled by the optimizer.
|
|
|
|
This is manifestation of the more general problems of "taking away"
|
|
|
|
parts of a SELECT statement post-fix_fields(). This is generally not
|
|
|
|
doable since various flags are collected in various places (e.g.
|
|
|
|
SELECT_LEX) that carry information about the presence of certain
|
|
|
|
expressions or constructs in the parts of the query.
|
|
|
|
When part of the query is taken away it's not clear how to "divide"
|
|
|
|
the meaning of these accumulated flags and what to carry over to the
|
|
|
|
recipient query (SELECT_LEX).
|
|
|
|
*/
|
2014-10-14 18:36:50 +02:00
|
|
|
if (global_parameters()->ftfunc_list->elements &&
|
|
|
|
global_parameters()->order_list.elements &&
|
|
|
|
global_parameters() != fake_select_lex)
|
2009-12-22 16:52:15 +01:00
|
|
|
{
|
|
|
|
ORDER *ord;
|
|
|
|
Item_func::Functype ft= Item_func::FT_FUNC;
|
2014-10-14 18:36:50 +02:00
|
|
|
for (ord= global_parameters()->order_list.first; ord; ord= ord->next)
|
2016-06-26 22:42:48 +02:00
|
|
|
if ((*ord->item)->walk (&Item::find_function_processor, FALSE, &ft))
|
2009-12-22 16:52:15 +01:00
|
|
|
{
|
|
|
|
my_error (ER_CANT_USE_OPTION_HERE, MYF(0), "MATCH()");
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-18 14:29:48 +02:00
|
|
|
create_options= (first_sl->options | thd->variables.option_bits |
|
2005-08-12 12:54:42 +02:00
|
|
|
TMP_TABLE_ALL_COLUMNS);
|
2005-08-06 23:08:28 +02:00
|
|
|
/*
|
|
|
|
Force the temporary table to be a MyISAM table if we're going to use
|
|
|
|
fullext functions (MATCH ... AGAINST .. IN BOOLEAN MODE) when reading
|
2005-08-07 23:03:45 +02:00
|
|
|
from it (this should be removed in 5.2 when fulltext search is moved
|
|
|
|
out of MyISAM).
|
2005-08-06 23:08:28 +02:00
|
|
|
*/
|
2014-10-14 18:36:50 +02:00
|
|
|
if (global_parameters()->ftfunc_list->elements)
|
2005-08-06 23:08:28 +02:00
|
|
|
create_options= create_options | TMP_TABLE_FORCE_MYISAM;
|
2004-10-18 14:56:25 +02:00
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
/* extra field counter */
|
|
|
|
uint hidden= 0;
|
|
|
|
Item_int *addon_fields[2]= {0};
|
2017-03-14 11:52:00 +01:00
|
|
|
if (!is_recursive)
|
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
if (have_except_all_or_intersect_all)
|
2017-03-14 11:52:00 +01:00
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
/* add duplicate_count */
|
|
|
|
++hidden;
|
|
|
|
}
|
|
|
|
/* add intersect_count */
|
|
|
|
if (have_intersect)
|
|
|
|
++hidden;
|
2017-03-14 11:52:00 +01:00
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
for(uint i= 0; i< hidden; i++)
|
|
|
|
{
|
|
|
|
init_item_int(thd, addon_fields[i]);
|
|
|
|
types.push_front(addon_fields[i]);
|
|
|
|
addon_fields[i]->name.str= i ? "__CNT_1" : "__CNT_2";
|
|
|
|
addon_fields[i]->name.length= 7;
|
2017-03-14 11:52:00 +01:00
|
|
|
}
|
|
|
|
bool error=
|
|
|
|
union_result->create_result_table(thd, &types,
|
2019-08-30 08:47:12 +02:00
|
|
|
MY_TEST(union_distinct) ||
|
|
|
|
have_except_all_or_intersect_all ||
|
|
|
|
have_intersect,
|
2018-01-07 17:03:44 +01:00
|
|
|
create_options, &empty_clex_str, false,
|
2017-03-14 11:52:00 +01:00
|
|
|
instantiate_tmp_table, false,
|
|
|
|
hidden);
|
2019-08-24 15:42:35 +02:00
|
|
|
union_result->addon_cnt= hidden;
|
|
|
|
for (uint i= 0; i < hidden; i++)
|
2017-03-14 11:52:00 +01:00
|
|
|
types.pop();
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(error))
|
2017-03-14 11:52:00 +01:00
|
|
|
goto err;
|
|
|
|
}
|
2019-08-24 15:42:35 +02:00
|
|
|
|
2010-05-26 22:18:18 +02:00
|
|
|
if (fake_select_lex && !fake_select_lex->first_cond_optimization)
|
|
|
|
{
|
|
|
|
save_tablenr= result_table_list.tablenr_exec;
|
|
|
|
save_map= result_table_list.map_exec;
|
2011-08-17 07:48:35 +02:00
|
|
|
save_maybe_null= result_table_list.maybe_null_exec;
|
2010-05-26 22:18:18 +02:00
|
|
|
}
|
2003-11-23 01:01:15 +01:00
|
|
|
bzero((char*) &result_table_list, sizeof(result_table_list));
|
2018-01-07 17:03:44 +01:00
|
|
|
result_table_list.db.str= (char*) "";
|
|
|
|
result_table_list.db.length= 0;
|
|
|
|
result_table_list.table_name.str= result_table_list.alias.str= "union";
|
|
|
|
result_table_list.table_name.length= result_table_list.alias.length= sizeof("union")-1;
|
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
|
|
|
result_table_list.table= table= union_result->table;
|
2010-05-26 22:18:18 +02:00
|
|
|
if (fake_select_lex && !fake_select_lex->first_cond_optimization)
|
|
|
|
{
|
|
|
|
result_table_list.tablenr_exec= save_tablenr;
|
|
|
|
result_table_list.map_exec= save_map;
|
2011-08-17 07:48:35 +02:00
|
|
|
result_table_list.maybe_null_exec= save_maybe_null;
|
2010-05-26 22:18:18 +02:00
|
|
|
}
|
2003-01-29 18:42:39 +01:00
|
|
|
|
2018-04-18 14:29:48 +02:00
|
|
|
thd->lex->current_select= lex_select_save;
|
2004-05-06 23:32:44 +02:00
|
|
|
if (!item_list.elements)
|
2003-01-29 18:42:39 +01:00
|
|
|
{
|
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
|
|
|
Query_arena *arena, backup_arena;
|
2004-09-09 05:59:26 +02:00
|
|
|
|
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
|
|
|
arena= thd->activate_stmt_arena_if_needed(&backup_arena);
|
|
|
|
|
2006-12-14 23:51:37 +01:00
|
|
|
saved_error= table->fill_item_list(&item_list);
|
2019-08-24 15:42:35 +02:00
|
|
|
for (uint i= 0; i < hidden; i++)
|
|
|
|
item_list.pop();
|
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
|
|
|
|
|
|
|
if (arena)
|
|
|
|
thd->restore_active_arena(arena, &backup_arena);
|
|
|
|
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(saved_error))
|
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
|
|
|
goto err;
|
|
|
|
|
2017-06-16 16:24:36 +02:00
|
|
|
if (fake_select_lex != NULL &&
|
|
|
|
(thd->stmt_arena->is_stmt_prepare() ||
|
|
|
|
(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)))
|
2004-05-06 23:08:21 +02:00
|
|
|
{
|
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
|
|
|
/* Validate the global parameters of this union */
|
|
|
|
|
2013-12-12 22:55:33 +01:00
|
|
|
init_prepare_fake_select_lex(thd, TRUE);
|
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
|
|
|
/* Should be done only once (the only item_list per statement) */
|
2004-05-20 01:02:49 +02:00
|
|
|
DBUG_ASSERT(fake_select_lex->join == 0);
|
2009-12-22 10:35:56 +01:00
|
|
|
if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->variables.option_bits,
|
2004-05-06 23:08:21 +02:00
|
|
|
result)))
|
|
|
|
{
|
|
|
|
fake_select_lex->table_list.empty();
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(TRUE);
|
2004-05-06 23:08:21 +02:00
|
|
|
}
|
2011-07-11 11:20:19 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
Fake st_select_lex should have item list for correct ref_array
|
|
|
|
allocation.
|
|
|
|
*/
|
2004-05-06 23:08:21 +02:00
|
|
|
fake_select_lex->item_list= item_list;
|
|
|
|
|
2018-04-18 14:29:48 +02:00
|
|
|
thd->lex->current_select= fake_select_lex;
|
2011-07-11 11:20:19 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
We need to add up n_sum_items in order to make the correct
|
|
|
|
allocation in setup_ref_array().
|
|
|
|
*/
|
2014-10-14 18:36:50 +02:00
|
|
|
fake_select_lex->n_child_sum_items+= global_parameters()->n_sum_items;
|
2004-05-06 23:08:21 +02:00
|
|
|
}
|
2003-01-29 18:42:39 +01:00
|
|
|
}
|
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
|
|
|
else
|
2004-10-22 12:47:35 +02:00
|
|
|
{
|
|
|
|
/*
|
2004-10-29 18:26:52 +02:00
|
|
|
We're in execution of a prepared statement or stored procedure:
|
|
|
|
reset field items to point at fields from the created temporary table.
|
2004-10-22 12:47:35 +02:00
|
|
|
*/
|
2019-08-24 15:42:35 +02:00
|
|
|
table->reset_item_list(&item_list, hidden);
|
2004-10-22 12:47:35 +02:00
|
|
|
}
|
2019-03-07 11:30:06 +01:00
|
|
|
if (fake_select_lex != NULL &&
|
|
|
|
(thd->stmt_arena->is_stmt_prepare() ||
|
|
|
|
(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)))
|
|
|
|
{
|
|
|
|
if (!fake_select_lex->join &&
|
|
|
|
!(fake_select_lex->join=
|
|
|
|
new JOIN(thd, item_list, thd->variables.option_bits, result)))
|
|
|
|
{
|
|
|
|
fake_select_lex->table_list.empty();
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
}
|
|
|
|
saved_error= fake_select_lex->join->
|
2019-09-22 23:23:28 +02:00
|
|
|
prepare(fake_select_lex->table_list.first, 0,
|
2019-03-15 20:00:28 +01:00
|
|
|
global_parameters()->order_list.elements, // og_num
|
|
|
|
global_parameters()->order_list.first, // order
|
|
|
|
false, NULL, NULL, NULL, fake_select_lex, this);
|
2019-03-07 11:30:06 +01:00
|
|
|
fake_select_lex->table_list.empty();
|
|
|
|
}
|
2003-01-29 18:42:39 +01:00
|
|
|
}
|
2003-11-23 01:01:15 +01:00
|
|
|
|
2018-04-18 14:29:48 +02:00
|
|
|
thd->lex->current_select= lex_select_save;
|
2003-01-29 18:42:39 +01:00
|
|
|
|
2018-04-18 14:29:48 +02:00
|
|
|
DBUG_RETURN(saved_error || thd->is_fatal_error);
|
2003-11-23 01:01:15 +01:00
|
|
|
|
2002-09-26 22:08:22 +02:00
|
|
|
err:
|
2018-04-18 14:29:48 +02:00
|
|
|
thd->lex->current_select= lex_select_save;
|
2010-11-10 15:48:29 +01:00
|
|
|
(void) cleanup();
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(TRUE);
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
|
|
|
|
2003-03-18 10:17:48 +01:00
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
/**
|
|
|
|
@brief
|
|
|
|
Optimize a sequence of set operations
|
|
|
|
|
|
|
|
@param first_sl first select of the level now under processing
|
|
|
|
|
|
|
|
@details
|
|
|
|
The method optimizes with the following rules:
|
|
|
|
- (1)If a subsequence of INTERSECT contains at least one INTERSECT DISTINCT
|
|
|
|
or this subsequence is followed by UNION/EXCEPT DISTINCT then all
|
|
|
|
elements in the subsequence can changed for INTERSECT DISTINCT
|
|
|
|
- (2)If previous set operation is DISTINCT then EXCEPT ALL can be replaced
|
|
|
|
for EXCEPT DISTINCT
|
|
|
|
- (3)If UNION DISTINCT / EXCEPT DISTINCT follows a subsequence of UNION ALL
|
|
|
|
then all set operations of this subsequence can be replaced for
|
|
|
|
UNION DISTINCT
|
|
|
|
|
|
|
|
For derived table it will look up outer select, and do optimize based on
|
|
|
|
outer select.
|
|
|
|
|
|
|
|
Variable "union_distinct" will be updated in the end.
|
|
|
|
Not compatible with Oracle Mode.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void st_select_lex_unit::optimize_bag_operation(bool is_outer_distinct)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
skip run optimize for:
|
|
|
|
ORACLE MODE
|
|
|
|
CREATE VIEW
|
|
|
|
PREPARE ... FROM
|
|
|
|
recursive
|
|
|
|
*/
|
|
|
|
if ((thd->variables.sql_mode & MODE_ORACLE) ||
|
|
|
|
(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) ||
|
|
|
|
(fake_select_lex != NULL && thd->stmt_arena->is_stmt_prepare()) ||
|
|
|
|
(with_element && with_element->is_recursive ))
|
|
|
|
return;
|
|
|
|
DBUG_ASSERT(!bag_set_op_optimized);
|
|
|
|
|
|
|
|
SELECT_LEX *sl;
|
|
|
|
/* INTERSECT subsequence can occur only at the very beginning */
|
|
|
|
/* The first select with linkage == INTERSECT_TYPE */
|
|
|
|
SELECT_LEX *intersect_start= NULL;
|
|
|
|
/* The first select after the INTERSECT subsequence */
|
|
|
|
SELECT_LEX *intersect_end= NULL;
|
|
|
|
/*
|
|
|
|
Will point to the last node before UNION ALL subsequence.
|
|
|
|
Index can be disable there.
|
|
|
|
*/
|
|
|
|
SELECT_LEX *disable_index= NULL;
|
|
|
|
/*
|
|
|
|
True if there is a select with:
|
|
|
|
linkage == INTERSECT_TYPE && distinct==true
|
|
|
|
*/
|
|
|
|
bool any_intersect_distinct= false;
|
|
|
|
SELECT_LEX *prev_sl= first_select();
|
|
|
|
|
|
|
|
/* process INTERSECT subsequence in the begining */
|
|
|
|
for (sl= prev_sl->next_select(); sl; prev_sl= sl, sl= sl->next_select())
|
|
|
|
{
|
|
|
|
if (sl->linkage != INTERSECT_TYPE)
|
|
|
|
{
|
|
|
|
intersect_end= sl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!intersect_start)
|
|
|
|
intersect_start= sl;
|
|
|
|
if (sl->distinct)
|
|
|
|
{
|
|
|
|
any_intersect_distinct= true;
|
|
|
|
disable_index= sl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if subquery only contains INTERSECT and outer is UNION DISTINCT*/
|
|
|
|
if (!sl && is_outer_distinct)
|
|
|
|
any_intersect_distinct= true;
|
|
|
|
|
|
|
|
/* The first select of the current UNION ALL subsequence */
|
|
|
|
SELECT_LEX *union_all_start= NULL;
|
|
|
|
for ( ; sl; prev_sl= sl, sl= sl->next_select())
|
|
|
|
{
|
|
|
|
DBUG_ASSERT (sl->linkage != INTERSECT_TYPE);
|
|
|
|
if (!sl->distinct)
|
|
|
|
{
|
|
|
|
if (sl->linkage == UNION_TYPE)
|
|
|
|
{
|
|
|
|
if (!union_all_start)
|
|
|
|
{
|
|
|
|
union_all_start= sl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DBUG_ASSERT (sl->linkage == EXCEPT_TYPE);
|
|
|
|
union_all_start= NULL;
|
|
|
|
if (prev_sl->distinct && prev_sl->is_set_op())
|
|
|
|
{
|
|
|
|
sl->distinct= true;
|
|
|
|
disable_index= sl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ /* sl->distinct == true */
|
|
|
|
for (SELECT_LEX *si= union_all_start; si && si != sl; si= si->next_select())
|
|
|
|
{
|
|
|
|
si->distinct= true;
|
|
|
|
}
|
|
|
|
union_all_start= NULL;
|
|
|
|
disable_index= sl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_outer_distinct)
|
|
|
|
{
|
|
|
|
for (SELECT_LEX *si= union_all_start; si && si != sl; si= si->next_select())
|
|
|
|
{
|
|
|
|
si->distinct= true;
|
|
|
|
}
|
|
|
|
union_all_start= NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (any_intersect_distinct ||
|
|
|
|
(intersect_end != NULL && intersect_end->distinct))
|
|
|
|
{
|
|
|
|
for (sl= intersect_start; sl && sl != intersect_end; sl= sl->next_select())
|
|
|
|
{
|
|
|
|
sl->distinct= true;
|
|
|
|
if (disable_index && disable_index->linkage == INTERSECT_TYPE)
|
|
|
|
disable_index= sl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
if disable_index points to a INTERSECT, based on rule 1 we can set it
|
|
|
|
to the last INTERSECT node.
|
|
|
|
*/
|
|
|
|
if (disable_index && disable_index->linkage == INTERSECT_TYPE &&
|
|
|
|
intersect_end && intersect_end->distinct)
|
|
|
|
disable_index= intersect_end;
|
|
|
|
/* union_distinct controls when to disable index */
|
|
|
|
union_distinct= disable_index;
|
|
|
|
|
|
|
|
/* recursive call this function for whole lex tree */
|
|
|
|
for(sl= first_select(); sl; sl= sl->next_select())
|
|
|
|
{
|
|
|
|
if (sl->is_unit_nest() &&
|
|
|
|
sl->first_inner_unit() &&
|
|
|
|
!sl->first_inner_unit()->bag_set_op_optimized)
|
|
|
|
sl->first_inner_unit()->optimize_bag_operation(sl->distinct);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* mark as optimized */
|
|
|
|
bag_set_op_optimized= true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-26 22:18:18 +02:00
|
|
|
/**
|
|
|
|
Run optimization phase.
|
|
|
|
|
2019-08-24 15:42:35 +02:00
|
|
|
@return false unit successfully passed optimization phase.
|
2010-05-26 22:18:18 +02:00
|
|
|
@return TRUE an error occur.
|
|
|
|
*/
|
|
|
|
bool st_select_lex_unit::optimize()
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
2003-12-19 18:52:13 +01:00
|
|
|
SELECT_LEX *lex_select_save= thd->lex->current_select;
|
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
|
|
|
SELECT_LEX *select_cursor=first_select();
|
2010-05-26 22:18:18 +02:00
|
|
|
DBUG_ENTER("st_select_lex_unit::optimize");
|
2003-04-08 02:54:02 +02:00
|
|
|
|
2010-05-26 22:18:18 +02:00
|
|
|
if (optimized && !uncacheable && !describe)
|
2019-08-24 15:42:35 +02:00
|
|
|
DBUG_RETURN(false);
|
2010-05-26 22:18:18 +02:00
|
|
|
|
2016-07-27 07:58:33 +02:00
|
|
|
if (with_element && with_element->is_recursive && optimize_started)
|
2019-08-24 15:42:35 +02:00
|
|
|
DBUG_RETURN(false);
|
2016-07-27 07:58:33 +02:00
|
|
|
optimize_started= true;
|
|
|
|
|
2004-05-06 19:40:21 +02:00
|
|
|
if (uncacheable || !item || !item->assigned() || describe)
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
2004-11-18 17:10:07 +01:00
|
|
|
if (item)
|
|
|
|
item->reset_value_registration();
|
2004-05-21 09:31:28 +02:00
|
|
|
if (optimized && item)
|
2002-11-28 18:29:26 +01:00
|
|
|
{
|
2004-05-21 09:31:28 +02:00
|
|
|
if (item->assigned())
|
|
|
|
{
|
|
|
|
item->assigned(0); // We will reinit & rexecute unit
|
|
|
|
item->reset();
|
2017-11-10 11:22:51 +01:00
|
|
|
}
|
|
|
|
if (table->is_created())
|
|
|
|
{
|
|
|
|
table->file->ha_delete_all_rows();
|
|
|
|
table->file->info(HA_STATUS_VARIABLE);
|
2004-05-21 09:31:28 +02:00
|
|
|
}
|
|
|
|
/* re-enabling indexes for next subselect iteration */
|
2019-08-24 15:42:35 +02:00
|
|
|
if ((union_result->force_enable_index_if_needed() || union_distinct))
|
2006-11-30 02:40:42 +01:00
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
if(table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
|
|
|
|
DBUG_ASSERT(0);
|
|
|
|
else
|
|
|
|
table->no_keyread= 0;
|
2006-11-30 02:40:42 +01:00
|
|
|
}
|
2002-11-28 18:29:26 +01:00
|
|
|
}
|
2003-03-06 16:02:10 +01:00
|
|
|
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
2002-09-03 08:50:36 +02:00
|
|
|
{
|
2017-06-29 14:32:17 +02:00
|
|
|
if (sl->tvc)
|
2017-08-29 02:32:39 +02:00
|
|
|
{
|
|
|
|
sl->tvc->select_options=
|
2019-09-26 09:49:50 +02:00
|
|
|
(lim.is_unlimited() || sl->braces) ?
|
2017-08-29 02:32:39 +02:00
|
|
|
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
2017-11-14 06:47:58 +01:00
|
|
|
if (sl->tvc->optimize(thd))
|
|
|
|
{
|
|
|
|
thd->lex->current_select= lex_select_save;
|
|
|
|
DBUG_RETURN(TRUE);
|
|
|
|
}
|
2018-08-19 07:57:20 +02:00
|
|
|
if (derived)
|
|
|
|
sl->increase_derived_records(sl->tvc->get_records());
|
2017-06-29 14:32:17 +02:00
|
|
|
continue;
|
2017-08-29 02:32:39 +02:00
|
|
|
}
|
2003-12-19 18:52:13 +01:00
|
|
|
thd->lex->current_select= sl;
|
2003-05-14 20:51:33 +02:00
|
|
|
|
2003-02-13 16:56:01 +01:00
|
|
|
if (optimized)
|
2006-12-14 23:51:37 +01:00
|
|
|
saved_error= sl->join->reinit();
|
2003-02-13 16:56:01 +01:00
|
|
|
else
|
2010-05-26 22:18:18 +02:00
|
|
|
{
|
|
|
|
set_limit(sl);
|
2014-10-14 18:36:50 +02:00
|
|
|
if (sl == global_parameters() || describe)
|
2010-05-26 22:18:18 +02:00
|
|
|
{
|
2019-09-26 09:49:50 +02:00
|
|
|
lim.remove_offset();
|
2010-05-26 22:18:18 +02:00
|
|
|
/*
|
|
|
|
We can't use LIMIT at this stage if we are using ORDER BY for the
|
|
|
|
whole query
|
|
|
|
*/
|
|
|
|
if (sl->order_list.first || describe)
|
2019-09-26 09:49:50 +02:00
|
|
|
lim.set_unlimited();
|
2010-05-26 22:18:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
|
|
|
|
we don't calculate found_rows() per union part.
|
|
|
|
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
|
|
|
|
*/
|
2017-08-29 02:32:39 +02:00
|
|
|
sl->join->select_options=
|
2019-09-26 09:49:50 +02:00
|
|
|
(lim.is_unlimited() || sl->braces) ?
|
2010-05-26 22:18:18 +02:00
|
|
|
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
|
|
|
|
|
|
|
saved_error= sl->join->optimize();
|
|
|
|
}
|
|
|
|
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(saved_error))
|
2010-05-26 22:18:18 +02:00
|
|
|
{
|
|
|
|
thd->lex->current_select= lex_select_save;
|
|
|
|
DBUG_RETURN(saved_error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
optimized= 1;
|
|
|
|
|
|
|
|
thd->lex->current_select= lex_select_save;
|
|
|
|
DBUG_RETURN(saved_error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool st_select_lex_unit::exec()
|
|
|
|
{
|
|
|
|
SELECT_LEX *lex_select_save= thd->lex->current_select;
|
|
|
|
SELECT_LEX *select_cursor=first_select();
|
|
|
|
ulonglong add_rows=0;
|
|
|
|
ha_rows examined_rows= 0;
|
2013-12-12 22:55:33 +01:00
|
|
|
bool first_execution= !executed;
|
2010-05-26 22:18:18 +02:00
|
|
|
DBUG_ENTER("st_select_lex_unit::exec");
|
2013-06-27 14:41:12 +02:00
|
|
|
bool was_executed= executed;
|
2010-05-26 22:18:18 +02:00
|
|
|
|
2016-06-26 06:38:40 +02:00
|
|
|
if (executed && !uncacheable && !describe)
|
2010-05-26 22:18:18 +02:00
|
|
|
DBUG_RETURN(FALSE);
|
|
|
|
executed= 1;
|
2017-04-20 22:09:31 +02:00
|
|
|
if (!(uncacheable & ~UNCACHEABLE_EXPLAIN) && item &&
|
|
|
|
!item->with_recursive_reference)
|
2012-08-25 08:15:57 +02:00
|
|
|
item->make_const();
|
2010-05-26 22:18:18 +02:00
|
|
|
|
|
|
|
saved_error= optimize();
|
2013-10-16 10:13:51 +02:00
|
|
|
|
|
|
|
create_explain_query_if_not_exists(thd->lex, thd->mem_root);
|
2010-05-26 22:18:18 +02:00
|
|
|
|
2013-10-16 10:13:51 +02:00
|
|
|
if (!saved_error && !was_executed)
|
2013-10-05 07:58:22 +02:00
|
|
|
save_union_explain(thd->lex->explain);
|
2010-05-26 22:18:18 +02:00
|
|
|
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(saved_error))
|
2014-02-13 20:21:57 +01:00
|
|
|
DBUG_RETURN(saved_error);
|
2010-05-26 22:18:18 +02:00
|
|
|
|
2017-11-13 10:02:59 +01:00
|
|
|
if (union_result)
|
2018-02-22 19:08:49 +01:00
|
|
|
{
|
2017-11-13 10:02:59 +01:00
|
|
|
union_result->init();
|
2018-02-22 19:08:49 +01:00
|
|
|
if (uncacheable & UNCACHEABLE_DEPENDENT &&
|
|
|
|
union_result->table && union_result->table->is_created())
|
|
|
|
{
|
|
|
|
union_result->table->file->ha_delete_all_rows();
|
|
|
|
union_result->table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL);
|
|
|
|
}
|
|
|
|
}
|
2017-11-13 10:02:59 +01:00
|
|
|
|
2010-05-26 22:18:18 +02:00
|
|
|
if (uncacheable || !item || !item->assigned() || describe)
|
|
|
|
{
|
2016-05-12 22:23:12 +02:00
|
|
|
if (!fake_select_lex && !(with_element && with_element->is_recursive))
|
2014-10-19 18:50:50 +02:00
|
|
|
union_result->cleanup();
|
2010-05-26 22:18:18 +02:00
|
|
|
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
|
|
|
{
|
|
|
|
ha_rows records_at_start= 0;
|
|
|
|
thd->lex->current_select= sl;
|
2017-03-14 11:52:00 +01:00
|
|
|
if (union_result)
|
|
|
|
union_result->change_select();
|
2014-10-14 18:36:50 +02:00
|
|
|
if (fake_select_lex)
|
|
|
|
{
|
2018-05-22 19:08:39 +02:00
|
|
|
if (sl != thd->lex->first_select_lex())
|
2014-10-14 18:36:50 +02:00
|
|
|
fake_select_lex->uncacheable|= sl->uncacheable;
|
|
|
|
else
|
|
|
|
fake_select_lex->uncacheable= 0;
|
|
|
|
}
|
2010-05-26 22:18:18 +02:00
|
|
|
|
2003-02-13 16:56:01 +01:00
|
|
|
{
|
2005-05-30 18:54:37 +02:00
|
|
|
set_limit(sl);
|
2014-10-14 18:36:50 +02:00
|
|
|
if (sl == global_parameters() || describe)
|
2003-09-14 21:12:55 +02:00
|
|
|
{
|
2019-09-26 09:49:50 +02:00
|
|
|
lim.remove_offset();
|
2003-09-14 21:12:55 +02:00
|
|
|
/*
|
|
|
|
We can't use LIMIT at this stage if we are using ORDER BY for the
|
|
|
|
whole query
|
|
|
|
*/
|
2004-05-06 19:40:21 +02:00
|
|
|
if (sl->order_list.first || describe)
|
2019-09-26 09:49:50 +02:00
|
|
|
lim.set_unlimited();
|
2005-05-30 18:54:37 +02:00
|
|
|
}
|
2003-08-29 12:44:35 +02:00
|
|
|
|
2005-03-02 17:00:48 +01:00
|
|
|
/*
|
|
|
|
When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
|
|
|
|
we don't calculate found_rows() per union part.
|
|
|
|
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
|
|
|
|
*/
|
2017-08-29 02:32:39 +02:00
|
|
|
if (sl->tvc)
|
|
|
|
{
|
|
|
|
sl->tvc->select_options=
|
2019-09-26 09:49:50 +02:00
|
|
|
(lim.is_unlimited() || sl->braces) ?
|
2017-08-29 02:32:39 +02:00
|
|
|
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
2017-11-14 06:47:58 +01:00
|
|
|
saved_error= sl->tvc->optimize(thd);
|
2017-08-29 02:32:39 +02:00
|
|
|
}
|
|
|
|
else
|
2017-06-30 12:54:33 +02:00
|
|
|
{
|
2019-08-24 15:42:35 +02:00
|
|
|
sl->join->select_options=
|
2019-09-26 09:49:50 +02:00
|
|
|
(lim.is_unlimited() || sl->braces) ?
|
2017-06-30 12:54:33 +02:00
|
|
|
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
|
|
|
saved_error= sl->join->optimize();
|
|
|
|
}
|
2003-02-13 16:56:01 +01:00
|
|
|
}
|
2018-04-04 11:16:12 +02:00
|
|
|
if (likely(!saved_error))
|
2002-10-26 19:18:37 +02:00
|
|
|
{
|
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
|
|
|
records_at_start= table->file->stats.records;
|
2017-06-29 14:32:17 +02:00
|
|
|
if (sl->tvc)
|
2017-08-29 02:32:39 +02:00
|
|
|
sl->tvc->exec(sl);
|
2017-06-30 12:54:33 +02:00
|
|
|
else
|
|
|
|
sl->join->exec();
|
2019-09-01 07:44:58 +02:00
|
|
|
if (sl == union_distinct && !have_except_all_or_intersect_all &&
|
|
|
|
!(with_element && with_element->is_recursive))
|
2004-05-15 15:13:08 +02:00
|
|
|
{
|
2014-10-14 18:36:50 +02:00
|
|
|
// This is UNION DISTINCT, so there should be a fake_select_lex
|
|
|
|
DBUG_ASSERT(fake_select_lex != NULL);
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL)))
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(TRUE);
|
2004-05-15 15:13:08 +02:00
|
|
|
table->no_keyread=1;
|
|
|
|
}
|
2017-06-30 12:54:33 +02:00
|
|
|
if (!sl->tvc)
|
|
|
|
saved_error= sl->join->error;
|
2018-04-04 11:16:12 +02:00
|
|
|
if (likely(!saved_error))
|
2003-02-13 16:56:01 +01:00
|
|
|
{
|
fixes for test failures
and small collateral changes
mysql-test/lib/My/Test.pm:
somehow with "print" we get truncated writes sometimes
mysql-test/suite/perfschema/r/digest_table_full.result:
md5 hashes of statement digests differ, because yacc token codes are different in mariadb
mysql-test/suite/perfschema/r/dml_handler.result:
host table is not ported over yet
mysql-test/suite/perfschema/r/information_schema.result:
host table is not ported over yet
mysql-test/suite/perfschema/r/nesting.result:
this differs, because we don't rewrite general log queries, and multi-statement
packets are logged as a one entry. this result file is identical to what mysql-5.6.5
produces with the --log-raw option.
mysql-test/suite/perfschema/r/relaylog.result:
MariaDB modifies the binlog index file directly, while MySQL 5.6 has a feature "crash-safe binlog index" and modifies a special "crash-safe" shadow copy of the index file and then moves it over. That's why this test shows "NONE" index file writes in MySQL and "MANY" in MariaDB.
mysql-test/suite/perfschema/r/server_init.result:
MariaDB initializes the "manager" resources from the "manager" thread, and starts this thread only when --flush-time is not 0. MySQL 5.6 initializes "manager" resources unconditionally on server startup.
mysql-test/suite/perfschema/r/stage_mdl_global.result:
this differs, because MariaDB disables query cache when query_cache_size=0. MySQL does not
do that, and this causes useless mutex locks and waits.
mysql-test/suite/perfschema/r/statement_digest.result:
md5 hashes of statement digests differ, because yacc token codes are different in mariadb
mysql-test/suite/perfschema/r/statement_digest_consumers.result:
md5 hashes of statement digests differ, because yacc token codes are different in mariadb
mysql-test/suite/perfschema/r/statement_digest_long_query.result:
md5 hashes of statement digests differ, because yacc token codes are different in mariadb
mysql-test/suite/rpl/r/rpl_mixed_drop_create_temp_table.result:
will be updated to match 5.6 when alfranio.correia@oracle.com-20110512172919-c1b5kmum4h52g0ni and anders.song@greatopensource.com-20110105052107-zoab0bsf5a6xxk2y are merged
mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result:
will be updated to match 5.6 when anders.song@greatopensource.com-20110105052107-zoab0bsf5a6xxk2y is merged
2012-09-27 20:09:46 +02:00
|
|
|
examined_rows+= thd->get_examined_row_count();
|
|
|
|
thd->set_examined_row_count(0);
|
2005-01-18 22:13:29 +01:00
|
|
|
if (union_result->flush())
|
|
|
|
{
|
|
|
|
thd->lex->current_select= lex_select_save;
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
2003-02-13 16:56:01 +01:00
|
|
|
}
|
2002-10-26 19:18:37 +02:00
|
|
|
}
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(saved_error))
|
2002-09-26 22:08:22 +02:00
|
|
|
{
|
2003-12-19 18:52:13 +01:00
|
|
|
thd->lex->current_select= lex_select_save;
|
2006-12-14 23:51:37 +01:00
|
|
|
DBUG_RETURN(saved_error);
|
2002-09-26 22:08:22 +02:00
|
|
|
}
|
2014-10-14 18:36:50 +02:00
|
|
|
if (fake_select_lex != NULL)
|
2006-09-28 15:41:37 +02:00
|
|
|
{
|
2014-10-14 18:36:50 +02:00
|
|
|
/* Needed for the following test and for records_at_start in next loop */
|
|
|
|
int error= table->file->info(HA_STATUS_VARIABLE);
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(error))
|
2014-10-14 18:36:50 +02:00
|
|
|
{
|
|
|
|
table->file->print_error(error, MYF(0));
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
2006-09-28 15:41:37 +02:00
|
|
|
}
|
2019-09-26 09:49:50 +02:00
|
|
|
if (found_rows_for_union && !sl->braces &&
|
|
|
|
!lim.is_unlimited())
|
2003-08-23 20:21:02 +02:00
|
|
|
{
|
|
|
|
/*
|
2003-08-29 12:44:35 +02:00
|
|
|
This is a union without braces. Remember the number of rows that
|
|
|
|
could also have been part of the result set.
|
2003-08-23 20:21:02 +02:00
|
|
|
We get this from the difference of between total number of possible
|
|
|
|
rows and actual rows added to the temporary table.
|
|
|
|
*/
|
2003-09-13 18:56:58 +02:00
|
|
|
add_rows+= (ulonglong) (thd->limit_found_rows - (ulonglong)
|
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
|
|
|
((table->file->stats.records - records_at_start)));
|
2003-08-23 20:21:02 +02:00
|
|
|
}
|
2012-03-11 13:39:20 +01:00
|
|
|
if (thd->killed == ABORT_QUERY)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Stop execution of the remaining queries in the UNIONS, and produce
|
|
|
|
the current result.
|
|
|
|
*/
|
2013-06-15 17:32:08 +02:00
|
|
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
2012-03-11 13:39:20 +01:00
|
|
|
ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT,
|
2015-07-06 19:24:14 +02:00
|
|
|
ER_THD(thd, ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT),
|
2012-03-11 13:39:20 +01:00
|
|
|
thd->accessed_rows_and_keys,
|
|
|
|
thd->lex->limit_rows_examined->val_uint());
|
2013-01-10 23:22:14 +01:00
|
|
|
thd->reset_killed();
|
2012-03-11 13:39:20 +01:00
|
|
|
break;
|
|
|
|
}
|
2002-09-03 08:50:36 +02:00
|
|
|
}
|
2001-08-02 05:29:50 +02:00
|
|
|
}
|
2001-08-14 19:33:49 +02:00
|
|
|
|
2012-06-07 19:19:22 +02:00
|
|
|
DBUG_EXECUTE_IF("show_explain_probe_union_read",
|
|
|
|
dbug_serve_apcs(thd, 1););
|
2001-08-02 05:29:50 +02:00
|
|
|
{
|
2002-09-03 08:50:36 +02:00
|
|
|
List<Item_func_match> empty_list;
|
|
|
|
empty_list.empty();
|
2012-03-11 13:39:20 +01:00
|
|
|
/*
|
|
|
|
Disable LIMIT ROWS EXAMINED in order to produce the possibly incomplete
|
|
|
|
result of the UNION without interruption due to exceeding the limit.
|
|
|
|
*/
|
|
|
|
thd->lex->limit_rows_examined_cnt= ULONGLONG_MAX;
|
2001-08-02 05:29:50 +02:00
|
|
|
|
2018-04-04 11:16:12 +02:00
|
|
|
// Check if EOM
|
|
|
|
if (fake_select_lex != NULL && likely(!thd->is_fatal_error))
|
2001-10-19 16:43:30 +02:00
|
|
|
{
|
2014-10-14 18:36:50 +02:00
|
|
|
/* Send result to 'result' */
|
|
|
|
saved_error= true;
|
|
|
|
|
|
|
|
set_limit(global_parameters());
|
2013-12-12 22:55:33 +01:00
|
|
|
init_prepare_fake_select_lex(thd, first_execution);
|
2003-07-05 16:21:39 +02:00
|
|
|
JOIN *join= fake_select_lex->join;
|
2014-10-14 18:36:50 +02:00
|
|
|
saved_error= false;
|
2003-07-05 16:21:39 +02:00
|
|
|
if (!join)
|
|
|
|
{
|
|
|
|
/*
|
2004-05-05 20:24:21 +02:00
|
|
|
allocate JOIN for fake select only once (prevent
|
2003-07-05 16:21:39 +02:00
|
|
|
mysql_select automatic allocation)
|
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with the results of the UNION. Making this call for
every subquery execution caused O(#enumerated-rows-in-the-outer-query)
memory allocations.
- Instead, call join->reinit() and join->exec(), and
= disable constant table detection for such joins,
= provide special handling for table-less constant subqueries.
sql/sql_select.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_select.h:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_union.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with UNION results.
- Instead, call join->reinit() and join->exec().
- Provide special handling for table-less constant subqueries.
2007-07-31 13:19:06 +02:00
|
|
|
TODO: The above is nonsense. mysql_select() will not allocate the
|
|
|
|
join if one already exists. There must be some other reason why we
|
|
|
|
don't let it allocate the join. Perhaps this is because we need
|
|
|
|
some special parameter values passed to join constructor?
|
2003-07-05 16:21:39 +02:00
|
|
|
*/
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(!(fake_select_lex->join=
|
|
|
|
new JOIN(thd, item_list, fake_select_lex->options,
|
|
|
|
result))))
|
2004-05-03 12:58:01 +02:00
|
|
|
{
|
|
|
|
fake_select_lex->table_list.empty();
|
2012-03-11 13:39:20 +01:00
|
|
|
goto err;
|
2004-05-03 12:58:01 +02:00
|
|
|
}
|
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with the results of the UNION. Making this call for
every subquery execution caused O(#enumerated-rows-in-the-outer-query)
memory allocations.
- Instead, call join->reinit() and join->exec(), and
= disable constant table detection for such joins,
= provide special handling for table-less constant subqueries.
sql/sql_select.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_select.h:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_union.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with UNION results.
- Instead, call join->reinit() and join->exec().
- Provide special handling for table-less constant subqueries.
2007-07-31 13:19:06 +02:00
|
|
|
fake_select_lex->join->no_const_tables= TRUE;
|
2004-03-25 21:11:22 +01:00
|
|
|
|
2011-07-11 11:20:19 +02:00
|
|
|
/*
|
|
|
|
Fake st_select_lex should have item list for correct ref_array
|
|
|
|
allocation.
|
|
|
|
*/
|
|
|
|
fake_select_lex->item_list= item_list;
|
|
|
|
|
|
|
|
/*
|
|
|
|
We need to add up n_sum_items in order to make the correct
|
|
|
|
allocation in setup_ref_array().
|
|
|
|
Don't add more sum_items if we have already done JOIN::prepare
|
|
|
|
for this (with a different join object)
|
|
|
|
*/
|
2016-05-08 22:04:41 +02:00
|
|
|
if (fake_select_lex->ref_pointer_array.is_null())
|
2014-10-14 18:36:50 +02:00
|
|
|
fake_select_lex->n_child_sum_items+= global_parameters()->n_sum_items;
|
2013-06-26 23:00:22 +02:00
|
|
|
|
2013-10-16 10:13:51 +02:00
|
|
|
if (!was_executed)
|
2013-10-05 07:58:22 +02:00
|
|
|
save_union_explain_part2(thd->lex->explain);
|
2011-07-11 11:20:19 +02:00
|
|
|
|
2019-09-22 23:23:28 +02:00
|
|
|
saved_error= mysql_select(thd, &result_table_list,
|
|
|
|
item_list, NULL,
|
2014-10-14 18:36:50 +02:00
|
|
|
global_parameters()->order_list.elements,
|
|
|
|
global_parameters()->order_list.first,
|
2019-09-22 23:23:28 +02:00
|
|
|
NULL, NULL, NULL,
|
|
|
|
fake_select_lex->options | SELECT_NO_UNLOCK,
|
|
|
|
result, this, fake_select_lex);
|
2003-07-05 16:21:39 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with the results of the UNION. Making this call for
every subquery execution caused O(#enumerated-rows-in-the-outer-query)
memory allocations.
- Instead, call join->reinit() and join->exec(), and
= disable constant table detection for such joins,
= provide special handling for table-less constant subqueries.
sql/sql_select.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_select.h:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_union.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with UNION results.
- Instead, call join->reinit() and join->exec().
- Provide special handling for table-less constant subqueries.
2007-07-31 13:19:06 +02:00
|
|
|
if (describe)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
In EXPLAIN command, constant subqueries that do not use any
|
|
|
|
tables are executed two times:
|
|
|
|
- 1st time is a real evaluation to get the subquery value
|
|
|
|
- 2nd time is to produce EXPLAIN output rows.
|
|
|
|
1st execution sets certain members (e.g. select_result) to perform
|
|
|
|
subquery execution rather than EXPLAIN line production. In order
|
|
|
|
to reset them back, we re-do all of the actions (yes it is ugly):
|
2015-04-12 03:48:42 +02:00
|
|
|
*/ // psergey-todo: is the above really necessary anymore??
|
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with the results of the UNION. Making this call for
every subquery execution caused O(#enumerated-rows-in-the-outer-query)
memory allocations.
- Instead, call join->reinit() and join->exec(), and
= disable constant table detection for such joins,
= provide special handling for table-less constant subqueries.
sql/sql_select.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_select.h:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_union.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with UNION results.
- Instead, call join->reinit() and join->exec().
- Provide special handling for table-less constant subqueries.
2007-07-31 13:19:06 +02:00
|
|
|
join->init(thd, item_list, fake_select_lex->options, result);
|
2019-09-22 23:23:28 +02:00
|
|
|
saved_error= mysql_select(thd, &result_table_list, item_list, NULL,
|
2014-10-14 18:36:50 +02:00
|
|
|
global_parameters()->order_list.elements,
|
|
|
|
global_parameters()->order_list.first,
|
2019-09-22 23:23:28 +02:00
|
|
|
NULL, NULL, NULL,
|
|
|
|
fake_select_lex->options | SELECT_NO_UNLOCK,
|
|
|
|
result, this, fake_select_lex);
|
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with the results of the UNION. Making this call for
every subquery execution caused O(#enumerated-rows-in-the-outer-query)
memory allocations.
- Instead, call join->reinit() and join->exec(), and
= disable constant table detection for such joins,
= provide special handling for table-less constant subqueries.
sql/sql_select.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_select.h:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_union.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with UNION results.
- Instead, call join->reinit() and join->exec().
- Provide special handling for table-less constant subqueries.
2007-07-31 13:19:06 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-07-06 19:24:14 +02:00
|
|
|
join->join_examined_rows= 0;
|
2007-07-31 14:15:56 +02:00
|
|
|
saved_error= join->reinit();
|
|
|
|
join->exec();
|
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with the results of the UNION. Making this call for
every subquery execution caused O(#enumerated-rows-in-the-outer-query)
memory allocations.
- Instead, call join->reinit() and join->exec(), and
= disable constant table detection for such joins,
= provide special handling for table-less constant subqueries.
sql/sql_select.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_select.h:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't mark tables as constant if JOIN::no_const_tables flag is set
sql/sql_union.cc:
BUG#29582: huge memory consumption with union, subselect, joins:
- Don't call mysql_select() several times for the select that enumerates
a temporary table with UNION results.
- Instead, call join->reinit() and join->exec().
- Provide special handling for table-less constant subqueries.
2007-07-31 13:19:06 +02:00
|
|
|
}
|
2003-07-05 16:21:39 +02:00
|
|
|
}
|
2004-05-03 12:58:01 +02:00
|
|
|
|
|
|
|
fake_select_lex->table_list.empty();
|
2018-04-04 11:16:12 +02:00
|
|
|
if (likely(!saved_error))
|
2004-10-05 13:47:10 +02:00
|
|
|
{
|
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
|
|
|
thd->limit_found_rows = (ulonglong)table->file->stats.records + add_rows;
|
fixes for test failures
and small collateral changes
mysql-test/lib/My/Test.pm:
somehow with "print" we get truncated writes sometimes
mysql-test/suite/perfschema/r/digest_table_full.result:
md5 hashes of statement digests differ, because yacc token codes are different in mariadb
mysql-test/suite/perfschema/r/dml_handler.result:
host table is not ported over yet
mysql-test/suite/perfschema/r/information_schema.result:
host table is not ported over yet
mysql-test/suite/perfschema/r/nesting.result:
this differs, because we don't rewrite general log queries, and multi-statement
packets are logged as a one entry. this result file is identical to what mysql-5.6.5
produces with the --log-raw option.
mysql-test/suite/perfschema/r/relaylog.result:
MariaDB modifies the binlog index file directly, while MySQL 5.6 has a feature "crash-safe binlog index" and modifies a special "crash-safe" shadow copy of the index file and then moves it over. That's why this test shows "NONE" index file writes in MySQL and "MANY" in MariaDB.
mysql-test/suite/perfschema/r/server_init.result:
MariaDB initializes the "manager" resources from the "manager" thread, and starts this thread only when --flush-time is not 0. MySQL 5.6 initializes "manager" resources unconditionally on server startup.
mysql-test/suite/perfschema/r/stage_mdl_global.result:
this differs, because MariaDB disables query cache when query_cache_size=0. MySQL does not
do that, and this causes useless mutex locks and waits.
mysql-test/suite/perfschema/r/statement_digest.result:
md5 hashes of statement digests differ, because yacc token codes are different in mariadb
mysql-test/suite/perfschema/r/statement_digest_consumers.result:
md5 hashes of statement digests differ, because yacc token codes are different in mariadb
mysql-test/suite/perfschema/r/statement_digest_long_query.result:
md5 hashes of statement digests differ, because yacc token codes are different in mariadb
mysql-test/suite/rpl/r/rpl_mixed_drop_create_temp_table.result:
will be updated to match 5.6 when alfranio.correia@oracle.com-20110512172919-c1b5kmum4h52g0ni and anders.song@greatopensource.com-20110105052107-zoab0bsf5a6xxk2y are merged
mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result:
will be updated to match 5.6 when anders.song@greatopensource.com-20110105052107-zoab0bsf5a6xxk2y is merged
2012-09-27 20:09:46 +02:00
|
|
|
thd->inc_examined_row_count(examined_rows);
|
2004-10-05 13:47:10 +02:00
|
|
|
}
|
2003-04-08 02:54:02 +02:00
|
|
|
/*
|
|
|
|
Mark for slow query log if any of the union parts didn't use
|
|
|
|
indexes efficiently
|
|
|
|
*/
|
2001-10-19 16:43:30 +02:00
|
|
|
}
|
2001-08-02 05:29:50 +02:00
|
|
|
}
|
2003-12-19 18:52:13 +01:00
|
|
|
thd->lex->current_select= lex_select_save;
|
2012-03-11 13:39:20 +01:00
|
|
|
err:
|
|
|
|
thd->lex->set_limit_rows_examined();
|
2006-12-14 23:51:37 +01:00
|
|
|
DBUG_RETURN(saved_error);
|
2001-08-02 05:29:50 +02:00
|
|
|
}
|
|
|
|
|
2003-04-08 02:54:02 +02:00
|
|
|
|
2016-08-30 07:45:17 +02:00
|
|
|
/**
|
|
|
|
@brief
|
|
|
|
Execute the union of the specification of a recursive with table
|
|
|
|
|
|
|
|
@details
|
|
|
|
The method is performed only for the units that are specifications
|
|
|
|
if recursive with table T. If the specification contains an anchor
|
|
|
|
part then the first call of this method executes only this part
|
|
|
|
while the following calls execute the recursive part. If there are
|
|
|
|
no anchors each call executes the whole unit.
|
|
|
|
Before the excution the method cleans up the temporary table
|
|
|
|
to where the new rows of the recursive table are sent.
|
|
|
|
After the execution the unit these rows are copied to the
|
|
|
|
temporary tables created for recursive references of T.
|
|
|
|
If the specification if T is restricted (standards compliant)
|
|
|
|
then these temporary tables are cleaned up before new rows
|
|
|
|
are copied into them.
|
|
|
|
|
|
|
|
@retval
|
|
|
|
false on success
|
|
|
|
true on failure
|
|
|
|
*/
|
|
|
|
|
2016-08-11 00:51:40 +02:00
|
|
|
bool st_select_lex_unit::exec_recursive()
|
2016-05-09 22:39:10 +02:00
|
|
|
{
|
|
|
|
st_select_lex *lex_select_save= thd->lex->current_select;
|
2016-06-26 06:38:40 +02:00
|
|
|
st_select_lex *start= with_element->first_recursive;
|
2016-05-09 22:39:10 +02:00
|
|
|
TABLE *incr_table= with_element->rec_result->incr_table;
|
2016-06-26 06:38:40 +02:00
|
|
|
st_select_lex *end= NULL;
|
|
|
|
bool is_unrestricted= with_element->is_unrestricted();
|
2020-12-16 18:11:11 +01:00
|
|
|
List_iterator_fast<TABLE_LIST> li(with_element->rec_result->rec_table_refs);
|
2017-01-04 23:33:24 +01:00
|
|
|
TMP_TABLE_PARAM *tmp_table_param= &with_element->rec_result->tmp_table_param;
|
2016-06-26 06:38:40 +02:00
|
|
|
ha_rows examined_rows= 0;
|
|
|
|
bool was_executed= executed;
|
2020-12-16 18:11:11 +01:00
|
|
|
TABLE_LIST *rec_tbl;
|
2016-05-09 22:39:10 +02:00
|
|
|
|
2016-05-24 20:29:52 +02:00
|
|
|
DBUG_ENTER("st_select_lex_unit::exec_recursive");
|
|
|
|
|
2016-06-26 06:38:40 +02:00
|
|
|
executed= 1;
|
|
|
|
create_explain_query_if_not_exists(thd->lex, thd->mem_root);
|
|
|
|
if (!was_executed)
|
|
|
|
save_union_explain(thd->lex->explain);
|
2016-05-09 22:39:10 +02:00
|
|
|
|
2016-06-26 06:38:40 +02:00
|
|
|
if (with_element->level == 0)
|
|
|
|
{
|
2018-04-16 16:19:19 +02:00
|
|
|
if (!incr_table->is_created() &&
|
|
|
|
instantiate_tmp_table(incr_table,
|
|
|
|
tmp_table_param->keyinfo,
|
|
|
|
tmp_table_param->start_recinfo,
|
|
|
|
&tmp_table_param->recinfo,
|
|
|
|
0))
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
incr_table->file->extra(HA_EXTRA_WRITE_CACHE);
|
|
|
|
incr_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
2016-06-26 06:38:40 +02:00
|
|
|
start= first_select();
|
|
|
|
if (with_element->with_anchor)
|
|
|
|
end= with_element->first_recursive;
|
|
|
|
}
|
2018-04-04 11:16:12 +02:00
|
|
|
else if (unlikely((saved_error= incr_table->file->ha_delete_all_rows())))
|
2018-04-16 16:19:19 +02:00
|
|
|
goto err;
|
|
|
|
|
2016-06-26 06:38:40 +02:00
|
|
|
for (st_select_lex *sl= start ; sl != end; sl= sl->next_select())
|
|
|
|
{
|
2018-02-22 19:08:49 +01:00
|
|
|
if (with_element->level)
|
|
|
|
{
|
|
|
|
for (TABLE_LIST *derived= with_element->derived_with_rec_ref.first;
|
|
|
|
derived;
|
|
|
|
derived= derived->next_with_rec_ref)
|
|
|
|
{
|
|
|
|
if (derived->is_materialized_derived())
|
|
|
|
{
|
|
|
|
if (derived->table->is_created())
|
|
|
|
derived->table->file->ha_delete_all_rows();
|
|
|
|
derived->table->reginfo.join_tab->preread_init_done= false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-06-26 06:38:40 +02:00
|
|
|
thd->lex->current_select= sl;
|
2018-09-18 08:15:56 +02:00
|
|
|
set_limit(sl);
|
2017-08-29 02:32:39 +02:00
|
|
|
if (sl->tvc)
|
|
|
|
sl->tvc->exec(sl);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sl->join->exec();
|
|
|
|
saved_error= sl->join->error;
|
|
|
|
}
|
2018-04-04 11:16:12 +02:00
|
|
|
if (likely(!saved_error))
|
2016-05-09 22:39:10 +02:00
|
|
|
{
|
2016-06-26 06:38:40 +02:00
|
|
|
examined_rows+= thd->get_examined_row_count();
|
|
|
|
thd->set_examined_row_count(0);
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(union_result->flush()))
|
2016-06-26 06:38:40 +02:00
|
|
|
{
|
|
|
|
thd->lex->current_select= lex_select_save;
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
2016-05-09 22:39:10 +02:00
|
|
|
}
|
2018-04-04 11:16:12 +02:00
|
|
|
if (unlikely(saved_error))
|
2016-05-09 22:39:10 +02:00
|
|
|
{
|
2016-06-26 06:38:40 +02:00
|
|
|
thd->lex->current_select= lex_select_save;
|
|
|
|
goto err;
|
|
|
|
|
2016-05-09 22:39:10 +02:00
|
|
|
}
|
2016-06-26 06:38:40 +02:00
|
|
|
}
|
2016-06-06 19:01:16 +02:00
|
|
|
|
2016-06-26 06:38:40 +02:00
|
|
|
thd->inc_examined_row_count(examined_rows);
|
2016-05-09 22:39:10 +02:00
|
|
|
|
2016-06-26 06:38:40 +02:00
|
|
|
incr_table->file->info(HA_STATUS_VARIABLE);
|
2017-03-27 23:41:17 +02:00
|
|
|
if (with_element->level && incr_table->file->stats.records == 0)
|
2016-06-26 06:38:40 +02:00
|
|
|
with_element->set_as_stabilized();
|
|
|
|
else
|
|
|
|
with_element->level++;
|
|
|
|
|
2020-12-16 18:11:11 +01:00
|
|
|
while ((rec_tbl= li++))
|
2016-06-06 19:01:16 +02:00
|
|
|
{
|
2020-12-16 18:11:11 +01:00
|
|
|
TABLE *rec_table= rec_tbl->table;
|
2016-06-26 06:38:40 +02:00
|
|
|
saved_error=
|
2017-01-04 23:33:24 +01:00
|
|
|
incr_table->insert_all_rows_into_tmp_table(thd, rec_table,
|
|
|
|
tmp_table_param,
|
|
|
|
!is_unrestricted);
|
2016-08-27 01:09:22 +02:00
|
|
|
if (!with_element->rec_result->first_rec_table_to_update)
|
|
|
|
with_element->rec_result->first_rec_table_to_update= rec_table;
|
2017-04-23 08:45:38 +02:00
|
|
|
if (with_element->level == 1 && rec_table->reginfo.join_tab)
|
2018-02-22 19:08:49 +01:00
|
|
|
rec_table->reginfo.join_tab->preread_init_done= true;
|
2016-06-06 19:01:16 +02:00
|
|
|
}
|
2017-04-20 22:09:31 +02:00
|
|
|
for (Item_subselect *sq= with_element->sq_with_rec_ref.first;
|
|
|
|
sq;
|
|
|
|
sq= sq->next_with_rec_ref)
|
|
|
|
{
|
2018-01-06 18:32:47 +01:00
|
|
|
sq->reset();
|
2017-04-20 22:09:31 +02:00
|
|
|
sq->engine->force_reexecution();
|
|
|
|
}
|
2016-05-09 22:39:10 +02:00
|
|
|
|
|
|
|
thd->lex->current_select= lex_select_save;
|
|
|
|
err:
|
|
|
|
thd->lex->set_limit_rows_examined();
|
2016-06-26 06:38:40 +02:00
|
|
|
DBUG_RETURN(saved_error);
|
2016-05-09 22:39:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-20 03:04:37 +02:00
|
|
|
bool st_select_lex_unit::cleanup()
|
2001-08-02 05:29:50 +02:00
|
|
|
{
|
2018-02-06 18:14:05 +01:00
|
|
|
bool error= 0;
|
2003-03-18 10:17:48 +01:00
|
|
|
DBUG_ENTER("st_select_lex_unit::cleanup");
|
2003-01-25 01:25:52 +01:00
|
|
|
|
2004-02-10 01:18:22 +01:00
|
|
|
if (cleaned)
|
|
|
|
{
|
2004-10-20 03:04:37 +02:00
|
|
|
DBUG_RETURN(FALSE);
|
2004-02-10 01:18:22 +01:00
|
|
|
}
|
2020-11-11 01:02:30 +01:00
|
|
|
if (with_element && with_element->is_recursive && union_result)
|
2018-09-08 05:10:04 +02:00
|
|
|
{
|
|
|
|
select_union_recursive *result= with_element->rec_result;
|
|
|
|
if (++result->cleanup_count == with_element->rec_outer_references)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Perform cleanup for with_element and for all with elements
|
|
|
|
mutually recursive with it.
|
|
|
|
*/
|
|
|
|
cleaned= 1;
|
|
|
|
with_element->get_next_mutually_recursive()->spec->cleanup();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Just increment by 1 cleanup_count for with_element and
|
|
|
|
for all with elements mutually recursive with it.
|
|
|
|
*/
|
|
|
|
With_element *with_elem= with_element;
|
|
|
|
while ((with_elem= with_elem->get_next_mutually_recursive()) !=
|
|
|
|
with_element)
|
|
|
|
with_elem->rec_result->cleanup_count++;
|
|
|
|
DBUG_RETURN(FALSE);
|
|
|
|
}
|
|
|
|
}
|
2019-09-21 00:59:54 +02:00
|
|
|
columns_are_renamed= false;
|
2004-03-23 13:26:54 +01:00
|
|
|
cleaned= 1;
|
2004-02-10 01:18:22 +01:00
|
|
|
|
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
|
|
|
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
error|= sl->cleanup();
|
2016-08-27 01:09:22 +02:00
|
|
|
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
if (fake_select_lex)
|
2001-08-02 05:29:50 +02:00
|
|
|
{
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
error|= fake_select_lex->cleanup();
|
2009-05-15 09:03:34 +02:00
|
|
|
/*
|
|
|
|
There are two cases when we should clean order items:
|
|
|
|
1. UNION with SELECTs which all enclosed into braces
|
|
|
|
in this case global_parameters == fake_select_lex
|
|
|
|
2. UNION where last SELECT is not enclosed into braces
|
|
|
|
in this case global_parameters == 'last select'
|
|
|
|
So we should use global_parameters->order_list for
|
|
|
|
proper order list clean up.
|
|
|
|
Note: global_parameters and fake_select_lex are always
|
|
|
|
initialized for UNION
|
|
|
|
*/
|
2014-10-14 18:36:50 +02:00
|
|
|
DBUG_ASSERT(global_parameters());
|
|
|
|
if (global_parameters()->order_list.elements)
|
2007-03-09 22:29:02 +01:00
|
|
|
{
|
|
|
|
ORDER *ord;
|
2014-10-14 18:36:50 +02:00
|
|
|
for (ord= global_parameters()->order_list.first; ord; ord= ord->next)
|
2009-12-22 16:52:15 +01:00
|
|
|
(*ord->item)->walk (&Item::cleanup_processor, 0, 0);
|
2007-03-09 22:29:02 +01:00
|
|
|
}
|
2003-07-05 16:21:39 +02:00
|
|
|
}
|
2004-07-16 00:15:55 +02:00
|
|
|
|
2016-05-09 22:39:10 +02:00
|
|
|
if (with_element && with_element->is_recursive)
|
2016-08-27 01:09:22 +02:00
|
|
|
{
|
2018-09-08 05:10:04 +02:00
|
|
|
if (union_result)
|
2016-08-27 01:09:22 +02:00
|
|
|
{
|
|
|
|
((select_union_recursive *) union_result)->cleanup();
|
|
|
|
delete union_result;
|
|
|
|
union_result= 0;
|
|
|
|
}
|
2016-05-09 22:39:10 +02:00
|
|
|
with_element->mark_as_cleaned();
|
2016-08-27 01:09:22 +02:00
|
|
|
}
|
|
|
|
else
|
2016-05-08 22:04:41 +02:00
|
|
|
{
|
2016-08-27 01:09:22 +02:00
|
|
|
if (union_result)
|
|
|
|
{
|
|
|
|
delete union_result;
|
|
|
|
union_result=0; // Safety
|
|
|
|
if (table)
|
|
|
|
free_tmp_table(thd, table);
|
|
|
|
table= 0; // Safety
|
|
|
|
}
|
2016-05-08 22:04:41 +02:00
|
|
|
}
|
|
|
|
|
2003-01-25 01:25:52 +01:00
|
|
|
DBUG_RETURN(error);
|
2001-08-02 05:29:50 +02:00
|
|
|
}
|
2004-02-08 19:14:13 +01:00
|
|
|
|
|
|
|
|
|
|
|
void st_select_lex_unit::reinit_exec_mechanism()
|
|
|
|
{
|
2017-08-04 06:19:19 +02:00
|
|
|
prepared= optimized= optimized_2= executed= 0;
|
2016-07-27 07:58:33 +02:00
|
|
|
optimize_started= 0;
|
2016-06-07 20:06:54 +02:00
|
|
|
if (with_element && with_element->is_recursive)
|
2016-08-27 01:09:22 +02:00
|
|
|
with_element->reset_recursive_for_exec();
|
2004-02-08 19:14:13 +01:00
|
|
|
}
|
2004-05-07 22:06:11 +02:00
|
|
|
|
|
|
|
|
2014-10-14 18:36:50 +02:00
|
|
|
/**
|
|
|
|
Change the select_result object used to return the final result of
|
|
|
|
the unit, replacing occurences of old_result with new_result.
|
2004-05-07 22:06:11 +02:00
|
|
|
|
2014-10-14 18:36:50 +02:00
|
|
|
@param new_result New select_result object
|
|
|
|
@param old_result Old select_result object
|
2004-05-07 22:06:11 +02:00
|
|
|
|
2014-10-14 18:36:50 +02:00
|
|
|
@retval false Success
|
|
|
|
@retval true Error
|
2004-05-07 22:06:11 +02:00
|
|
|
*/
|
|
|
|
|
2010-01-28 14:48:33 +01:00
|
|
|
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
|
|
|
|
select_result_interceptor *old_result)
|
2004-05-07 22:06:11 +02:00
|
|
|
{
|
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
|
|
|
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
2004-05-07 22:06:11 +02:00
|
|
|
{
|
2014-10-14 18:36:50 +02:00
|
|
|
if (sl->join)
|
|
|
|
if (sl->join->change_result(new_result, old_result))
|
|
|
|
return true; /* purecov: inspected */
|
2004-05-07 22:06:11 +02:00
|
|
|
}
|
2014-10-14 18:36:50 +02:00
|
|
|
/*
|
|
|
|
If there were a fake_select_lex->join, we would have to change the
|
|
|
|
result of that also, but change_result() is called before such an
|
|
|
|
object is created.
|
|
|
|
*/
|
|
|
|
DBUG_ASSERT(fake_select_lex == NULL || fake_select_lex->join == NULL);
|
|
|
|
return false;
|
2004-05-07 22:06:11 +02:00
|
|
|
}
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
|
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
|
|
|
/*
|
|
|
|
Get column type information for this unit.
|
|
|
|
|
|
|
|
SYNOPSIS
|
2016-11-21 19:33:06 +01:00
|
|
|
st_select_lex_unit::get_column_types()
|
|
|
|
@param for_cursor if true return the list the fields
|
|
|
|
retrieved by the cursor
|
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
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
For a single-select the column types are taken
|
|
|
|
from the list of selected items. For a union this function
|
|
|
|
assumes that st_select_lex_unit::prepare has been called
|
|
|
|
and returns the type holders that were created for unioned
|
|
|
|
column types of all selects.
|
|
|
|
|
|
|
|
NOTES
|
|
|
|
The implementation of this function should be in sync with
|
|
|
|
st_select_lex_unit::prepare()
|
|
|
|
*/
|
|
|
|
|
2016-11-21 19:33:06 +01:00
|
|
|
List<Item> *st_select_lex_unit::get_column_types(bool for_cursor)
|
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
|
|
|
{
|
2006-09-07 16:44:18 +02:00
|
|
|
SELECT_LEX *sl= first_select();
|
2018-04-22 02:20:20 +02:00
|
|
|
bool is_procedure= !sl->tvc && sl->join->procedure ;
|
2006-09-07 16:44:18 +02:00
|
|
|
|
|
|
|
if (is_procedure)
|
|
|
|
{
|
|
|
|
/* Types for "SELECT * FROM t1 procedure analyse()"
|
|
|
|
are generated during execute */
|
|
|
|
return &sl->join->procedure_fields_list;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2017-03-14 11:52:00 +01:00
|
|
|
if (is_unit_op())
|
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
|
|
|
{
|
|
|
|
DBUG_ASSERT(prepared);
|
|
|
|
/* Types are generated during prepare */
|
|
|
|
return &types;
|
|
|
|
}
|
2006-09-07 16:44:18 +02:00
|
|
|
|
2016-11-21 19:33:06 +01:00
|
|
|
return for_cursor ? sl->join->fields : &sl->item_list;
|
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
|
|
|
}
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
|
2016-03-16 19:49:17 +01:00
|
|
|
|
|
|
|
static void cleanup_order(ORDER *order)
|
|
|
|
{
|
|
|
|
for (; order; order= order->next)
|
|
|
|
order->counter_used= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
bool st_select_lex::cleanup()
|
|
|
|
{
|
|
|
|
bool error= FALSE;
|
|
|
|
DBUG_ENTER("st_select_lex::cleanup()");
|
|
|
|
|
2020-08-11 16:37:48 +02:00
|
|
|
DBUG_PRINT("info", ("select: %p (%u) JOIN %p",
|
|
|
|
this, select_number, join));
|
2016-03-16 19:49:17 +01:00
|
|
|
cleanup_order(order_list.first);
|
|
|
|
cleanup_order(group_list.first);
|
2018-05-15 12:10:19 +02:00
|
|
|
cleanup_ftfuncs(this);
|
2016-03-16 19:49:17 +01:00
|
|
|
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
if (join)
|
|
|
|
{
|
2020-11-11 01:02:30 +01:00
|
|
|
List_iterator<TABLE_LIST> ti(leaf_tables);
|
|
|
|
TABLE_LIST *tbl;
|
|
|
|
while ((tbl= ti++))
|
|
|
|
{
|
|
|
|
if (tbl->is_recursive_with_table() &&
|
|
|
|
!tbl->is_with_table_recursive_reference())
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
If query is killed before open_and_process_table() for tbl
|
|
|
|
is called then 'with' is already set, but 'derived' is not.
|
|
|
|
*/
|
|
|
|
st_select_lex_unit *unit= tbl->with->spec;
|
|
|
|
error|= (bool) error | (uint) unit->cleanup();
|
|
|
|
}
|
|
|
|
}
|
2005-06-29 10:50:29 +02:00
|
|
|
DBUG_ASSERT((st_select_lex*)join->select_lex == this);
|
2005-07-04 02:42:33 +02:00
|
|
|
error= join->destroy();
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
delete join;
|
|
|
|
join= 0;
|
|
|
|
}
|
2020-11-17 23:28:30 +01:00
|
|
|
leaf_tables.empty();
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
|
|
|
|
lex_unit= lex_unit->next_unit())
|
|
|
|
{
|
2020-11-11 01:02:30 +01:00
|
|
|
if (lex_unit->with_element && lex_unit->with_element->is_recursive)
|
|
|
|
continue;
|
2005-07-04 02:42:33 +02:00
|
|
|
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
}
|
2007-04-15 06:31:34 +02:00
|
|
|
inner_refs_list.empty();
|
2012-02-14 15:52:56 +01:00
|
|
|
exclude_from_table_unique_test= FALSE;
|
2018-05-14 22:14:03 +02:00
|
|
|
hidden_bit_fields= 0;
|
- don't call JOIN::join_free(1) twice for every join in JOIN::cleanup().
The reason it happened was that both, JOIN::cleanup() and JOIN::join_free(),
went over all nested joins and called cleanup/join_free for them.
For that:
- split recursive and non-recursive parts of JOIN::cleanup() and
JOIN::join_free()
- rename JOIN::cleanup to JOIN::destroy, as it actually destroys its
argument
- move the recursive part of JOIN::cleanup to st_select_lex::cleanup
- move the non-recursive part of JOIN::join_free to the introduced
method JOIN::cleanup().
sql/sql_lex.h:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup()
sql/sql_select.cc:
- remove two unused arguments from return_zero_rows
- split JOIN::join_free and JOIN::cleanup to recursive and non-recursive
parts.
- note, the assert in JOIN::join_free _does_ fail in having.test.
We have two options: a) propagate `full' flag to the nested joins.
We did it before, and this patch didn't change it. If so, we
can end up cleaning up an uncacheable JOIN (that is, the join that
we might need again).
b) evaluate own 'full' flag on every level. In this case, we might
end up with tables freed in mysql_unlock_read_tables, but not
cleaned up properly, and this may be even worse. The test suite
passes with both approaches, but not with the assert.
sql/sql_select.h:
- declarations for JOIN::cleanup() and JOIN::join_free()
sql/sql_union.cc:
Add st_select_lex::cleanup, a counterpart of st_select_lex_unit::cleanup():
move the recursive part of JOIN::cleanup to it.
2005-06-24 20:48:12 +02:00
|
|
|
DBUG_RETURN(error);
|
|
|
|
}
|
|
|
|
|
2005-10-13 09:53:00 +02:00
|
|
|
|
|
|
|
void st_select_lex::cleanup_all_joins(bool full)
|
|
|
|
{
|
|
|
|
SELECT_LEX_UNIT *unit;
|
|
|
|
SELECT_LEX *sl;
|
2015-06-25 22:18:48 +02:00
|
|
|
DBUG_ENTER("st_select_lex::cleanup_all_joins");
|
2005-10-13 09:53:00 +02:00
|
|
|
|
|
|
|
if (join)
|
|
|
|
join->cleanup(full);
|
|
|
|
|
|
|
|
for (unit= first_inner_unit(); unit; unit= unit->next_unit())
|
2020-11-11 01:02:30 +01:00
|
|
|
{
|
|
|
|
if (unit->with_element && unit->with_element->is_recursive)
|
|
|
|
continue;
|
2005-10-13 09:53:00 +02:00
|
|
|
for (sl= unit->first_select(); sl; sl= sl->next_select())
|
|
|
|
sl->cleanup_all_joins(full);
|
2020-11-11 01:02:30 +01:00
|
|
|
}
|
2015-06-25 22:18:48 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2005-10-13 09:53:00 +02:00
|
|
|
}
|
2011-05-27 09:03:55 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Set exclude_from_table_unique_test for selects of this unit and all
|
|
|
|
underlying selects.
|
|
|
|
|
|
|
|
@note used to exclude materialized derived tables (views) from unique
|
|
|
|
table check.
|
|
|
|
*/
|
|
|
|
|
2011-05-30 20:40:46 +02:00
|
|
|
void st_select_lex_unit::set_unique_exclude()
|
2011-05-27 09:03:55 +02:00
|
|
|
{
|
|
|
|
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
|
|
|
{
|
|
|
|
sl->exclude_from_table_unique_test= TRUE;
|
|
|
|
for (SELECT_LEX_UNIT *unit= sl->first_inner_unit();
|
|
|
|
unit;
|
|
|
|
unit= unit->next_unit())
|
|
|
|
{
|
2011-05-30 20:40:46 +02:00
|
|
|
unit->set_unique_exclude();
|
2011-05-27 09:03:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-04-30 17:35:50 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
@brief
|
|
|
|
Check if the derived table is guaranteed to have distinct rows because of
|
|
|
|
UNION operations used to populate it.
|
|
|
|
|
|
|
|
@detail
|
|
|
|
UNION operation removes duplicate rows from its output. That is, a query like
|
|
|
|
|
|
|
|
select * from t1 UNION select * from t2
|
|
|
|
|
|
|
|
will not produce duplicate rows in its output, even if table t1 (and/or t2)
|
|
|
|
contain duplicate rows. EXCEPT and INTERSECT operations also have this
|
|
|
|
property.
|
|
|
|
|
|
|
|
On the other hand, UNION ALL operation doesn't remove duplicates. (The SQL
|
|
|
|
standard also defines EXCEPT ALL and INTERSECT ALL, but we don't support
|
|
|
|
them).
|
|
|
|
|
|
|
|
st_select_lex_unit computes its value left to right. That is, if there is
|
|
|
|
a st_select_lex_unit object describing
|
|
|
|
|
|
|
|
(select #1) OP1 (select #2) OP2 (select #3)
|
|
|
|
|
|
|
|
then ((select #1) OP1 (select #2)) is computed first, and OP2 is computed
|
|
|
|
second.
|
|
|
|
|
|
|
|
How can one tell if st_select_lex_unit is guaranteed to have distinct
|
|
|
|
output rows? This depends on whether the last operation was duplicate-
|
|
|
|
removing or not:
|
|
|
|
- UNION ALL is not duplicate-removing
|
|
|
|
- all other operations are duplicate-removing
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool st_select_lex_unit::check_distinct_in_union()
|
|
|
|
{
|
|
|
|
if (union_distinct && !union_distinct->next_select())
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|