mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
merged 5.0-main -> 5.0-bugteam
This commit is contained in:
commit
702ae189a3
10 changed files with 441 additions and 25 deletions
|
@ -99,3 +99,37 @@ kill query
|
|||
ERROR 70100: Query execution was interrupted
|
||||
unlock tables;
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
a int(11) unsigned default NULL,
|
||||
b varchar(255) default NULL,
|
||||
UNIQUE KEY a (a),
|
||||
KEY b (b)
|
||||
);
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
|
||||
CREATE TABLE t2 SELECT * FROM t1;
|
||||
CREATE TABLE t3 SELECT * FROM t1;
|
||||
# test altering of columns that multiupdate doesn't use
|
||||
# normal mode
|
||||
# PS mode
|
||||
# test altering of columns that multiupdate uses
|
||||
# normal mode
|
||||
# PS mode
|
||||
DROP TABLE t1, t2, t3;
|
||||
CREATE TABLE t1( a INT, b INT );
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
|
||||
# 1. test regular tables
|
||||
# 1.1. test altering of columns that multiupdate doesn't use
|
||||
# 1.1.1. normal mode
|
||||
# 1.1.2. PS mode
|
||||
# 1.2. test altering of columns that multiupdate uses
|
||||
# 1.2.1. normal mode
|
||||
# 1.2.2. PS mode
|
||||
ALTER TABLE t1 ADD COLUMN a INT;
|
||||
# 2. test UNIONs
|
||||
# 2.1. test altering of columns that multiupdate doesn't use
|
||||
# 2.1.1. normal mode
|
||||
# 2.1.2. PS mode
|
||||
# 2.2. test altering of columns that multiupdate uses
|
||||
# 2.2.1. normal mode
|
||||
# 2.2.2. PS mode
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -281,4 +281,325 @@ unlock tables;
|
|||
connection default;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #38691: segfault/abort in ``UPDATE ...JOIN'' while
|
||||
# ``FLUSH TABLES WITH READ LOCK''
|
||||
#
|
||||
|
||||
--connection default
|
||||
CREATE TABLE t1 (
|
||||
a int(11) unsigned default NULL,
|
||||
b varchar(255) default NULL,
|
||||
UNIQUE KEY a (a),
|
||||
KEY b (b)
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
|
||||
CREATE TABLE t2 SELECT * FROM t1;
|
||||
CREATE TABLE t3 SELECT * FROM t1;
|
||||
|
||||
--echo # test altering of columns that multiupdate doesn't use
|
||||
|
||||
--echo # normal mode
|
||||
|
||||
--disable_query_log
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
--dec $i
|
||||
|
||||
--connection writer
|
||||
send UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a)
|
||||
SET a = NULL WHERE t1.b <> t2.b;
|
||||
|
||||
--connection locker
|
||||
ALTER TABLE t2 ADD COLUMN (c INT);
|
||||
ALTER TABLE t2 DROP COLUMN c;
|
||||
|
||||
--connection writer
|
||||
--reap
|
||||
}
|
||||
|
||||
--echo # PS mode
|
||||
|
||||
--connection writer
|
||||
PREPARE stmt FROM 'UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a)
|
||||
SET a = NULL WHERE t1.b <> t2.b';
|
||||
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
--dec $i
|
||||
|
||||
--connection writer
|
||||
--send EXECUTE stmt
|
||||
|
||||
--connection locker
|
||||
ALTER TABLE t2 ADD COLUMN (c INT);
|
||||
ALTER TABLE t2 DROP COLUMN c;
|
||||
|
||||
--connection writer
|
||||
--reap
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
|
||||
--echo # test altering of columns that multiupdate uses
|
||||
|
||||
--echo # normal mode
|
||||
|
||||
--connection default
|
||||
|
||||
--disable_query_log
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
dec $i;
|
||||
|
||||
--connection locker
|
||||
--error 0,1060
|
||||
ALTER TABLE t2 ADD COLUMN a int(11) unsigned default NULL;
|
||||
UPDATE t2 SET a=b;
|
||||
|
||||
--connection writer
|
||||
--send UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a) SET a = NULL WHERE t1.b <> t2.b
|
||||
|
||||
--connection locker
|
||||
--error 0,1091
|
||||
ALTER TABLE t2 DROP COLUMN a;
|
||||
|
||||
--connection writer
|
||||
--error 0,1054
|
||||
--reap
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
--echo # PS mode
|
||||
|
||||
--disable_query_log
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
dec $i;
|
||||
|
||||
--connection locker
|
||||
--error 0,1060
|
||||
ALTER TABLE t2 ADD COLUMN a int(11) unsigned default NULL;
|
||||
UPDATE t2 SET a=b;
|
||||
|
||||
--connection writer
|
||||
PREPARE stmt FROM 'UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a) SET a = NULL WHERE t1.b <> t2.b';
|
||||
--send EXECUTE stmt
|
||||
|
||||
--connection locker
|
||||
--error 0,1091
|
||||
ALTER TABLE t2 DROP COLUMN a;
|
||||
|
||||
--connection writer
|
||||
--error 0,1054
|
||||
--reap
|
||||
|
||||
}
|
||||
--enable_query_log
|
||||
--connection default
|
||||
DROP TABLE t1, t2, t3;
|
||||
|
||||
#
|
||||
# Bug#38499: flush tables and multitable table update with derived table cause
|
||||
# crash
|
||||
#
|
||||
|
||||
CREATE TABLE t1( a INT, b INT );
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
|
||||
|
||||
--echo # 1. test regular tables
|
||||
--echo # 1.1. test altering of columns that multiupdate doesn't use
|
||||
--echo # 1.1.1. normal mode
|
||||
|
||||
--disable_query_log
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
--dec $i
|
||||
|
||||
--connection writer
|
||||
send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
|
||||
|
||||
--connection locker
|
||||
ALTER TABLE t1 ADD COLUMN (c INT);
|
||||
ALTER TABLE t1 DROP COLUMN c;
|
||||
|
||||
--connection writer
|
||||
--reap
|
||||
}
|
||||
|
||||
--echo # 1.1.2. PS mode
|
||||
|
||||
--connection writer
|
||||
PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0';
|
||||
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
--dec $i
|
||||
|
||||
--connection writer
|
||||
--send EXECUTE stmt
|
||||
|
||||
--connection locker
|
||||
ALTER TABLE t1 ADD COLUMN (c INT);
|
||||
ALTER TABLE t1 DROP COLUMN c;
|
||||
|
||||
--connection writer
|
||||
--reap
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
--echo # 1.2. test altering of columns that multiupdate uses
|
||||
--echo # 1.2.1. normal mode
|
||||
|
||||
--connection default
|
||||
|
||||
--disable_query_log
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
dec $i;
|
||||
|
||||
--connection locker
|
||||
--error 0,1060
|
||||
ALTER TABLE t1 ADD COLUMN a int(11) unsigned default NULL;
|
||||
UPDATE t1 SET a=b;
|
||||
|
||||
--connection writer
|
||||
--send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
|
||||
|
||||
--connection locker
|
||||
--error 0,1091
|
||||
ALTER TABLE t1 DROP COLUMN a;
|
||||
|
||||
--connection writer
|
||||
--error 0,1054 # unknown column error
|
||||
--reap
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
--echo # 1.2.2. PS mode
|
||||
|
||||
--disable_query_log
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
dec $i;
|
||||
|
||||
--connection locker
|
||||
--error 0,1060
|
||||
ALTER TABLE t1 ADD COLUMN a INT;
|
||||
UPDATE t1 SET a=b;
|
||||
|
||||
--connection writer
|
||||
PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0';
|
||||
--send EXECUTE stmt
|
||||
|
||||
--connection locker
|
||||
--error 0,1091
|
||||
ALTER TABLE t1 DROP COLUMN a;
|
||||
|
||||
--connection writer
|
||||
--error 0,1054 # Unknown column 'a' in 'field list'
|
||||
--reap
|
||||
}
|
||||
--enable_query_log
|
||||
--connection default
|
||||
ALTER TABLE t1 ADD COLUMN a INT;
|
||||
|
||||
--echo # 2. test UNIONs
|
||||
--echo # 2.1. test altering of columns that multiupdate doesn't use
|
||||
--echo # 2.1.1. normal mode
|
||||
|
||||
--disable_query_log
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
--dec $i
|
||||
|
||||
--connection writer
|
||||
send UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0;
|
||||
|
||||
--connection locker
|
||||
ALTER TABLE t1 ADD COLUMN (c INT);
|
||||
ALTER TABLE t1 DROP COLUMN c;
|
||||
|
||||
--connection writer
|
||||
--reap
|
||||
}
|
||||
|
||||
--echo # 2.1.2. PS mode
|
||||
|
||||
--connection writer
|
||||
PREPARE stmt FROM 'UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0';
|
||||
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
--dec $i
|
||||
|
||||
--connection writer
|
||||
--send EXECUTE stmt
|
||||
|
||||
--connection locker
|
||||
ALTER TABLE t1 ADD COLUMN (c INT);
|
||||
ALTER TABLE t1 DROP COLUMN c;
|
||||
|
||||
--connection writer
|
||||
--reap
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
--echo # 2.2. test altering of columns that multiupdate uses
|
||||
--echo # 2.2.1. normal mode
|
||||
|
||||
--connection default
|
||||
|
||||
--disable_query_log
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
dec $i;
|
||||
|
||||
--connection locker
|
||||
--error 0,1060
|
||||
ALTER TABLE t1 ADD COLUMN a int(11) unsigned default NULL;
|
||||
UPDATE t1 SET a=b;
|
||||
|
||||
--connection writer
|
||||
--send UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0;
|
||||
|
||||
--connection locker
|
||||
--error 0,1091
|
||||
ALTER TABLE t1 DROP COLUMN a;
|
||||
|
||||
--connection writer
|
||||
--error 0,1054 # Unknown column 'a' in 'field list'
|
||||
--reap
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
--echo # 2.2.2. PS mode
|
||||
|
||||
--disable_query_log
|
||||
let $i = 100;
|
||||
while ($i) {
|
||||
dec $i;
|
||||
|
||||
--connection locker
|
||||
--error 0,1060
|
||||
ALTER TABLE t1 ADD COLUMN a INT;
|
||||
UPDATE t1 SET a=b;
|
||||
|
||||
--connection writer
|
||||
PREPARE stmt FROM 'UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0';
|
||||
--send EXECUTE stmt
|
||||
|
||||
--connection locker
|
||||
--error 0,1091
|
||||
ALTER TABLE t1 DROP COLUMN a;
|
||||
|
||||
--connection writer
|
||||
--error 0,1054 # Unknown column 'a' in 'field list'
|
||||
--reap
|
||||
}
|
||||
--enable_query_log
|
||||
--connection default
|
||||
DROP TABLE t1;
|
||||
|
||||
# End of 5.0 tests
|
||||
|
|
10
sql/item.cc
10
sql/item.cc
|
@ -1758,14 +1758,16 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg,
|
|||
We need to copy db_name, table_name and field_name because they must
|
||||
be allocated in the statement memory, not in table memory (the table
|
||||
structure can go away and pop up again between subsequent executions
|
||||
of a prepared statement).
|
||||
of a prepared statement or after the close_tables_for_reopen() call
|
||||
in mysql_multi_update_prepare()).
|
||||
*/
|
||||
if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
|
||||
{
|
||||
if (db_name)
|
||||
orig_db_name= thd->strdup(db_name);
|
||||
orig_table_name= thd->strdup(table_name);
|
||||
orig_field_name= thd->strdup(field_name);
|
||||
if (table_name)
|
||||
orig_table_name= thd->strdup(table_name);
|
||||
if (field_name)
|
||||
orig_field_name= thd->strdup(field_name);
|
||||
/*
|
||||
We don't restore 'name' in cleanup because it's not changed
|
||||
during execution. Still we need it to point to persistent
|
||||
|
|
|
@ -3617,8 +3617,21 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
|||
{
|
||||
/* This is a base table. */
|
||||
DBUG_ASSERT(nj_col->view_field == NULL);
|
||||
DBUG_ASSERT(nj_col->table_ref->table == nj_col->table_field->table);
|
||||
found_field= nj_col->table_field;
|
||||
/*
|
||||
This fix_fields is not necessary (initially this item is fixed by
|
||||
the Item_field constructor; after reopen_tables the Item_func_eq
|
||||
calls fix_fields on that item), it's just a check during table
|
||||
reopening for columns that was dropped by the concurrent connection.
|
||||
*/
|
||||
if (!nj_col->table_field->fixed &&
|
||||
nj_col->table_field->fix_fields(thd, (Item **)&nj_col->table_field))
|
||||
{
|
||||
DBUG_PRINT("info", ("column '%s' was dropped by the concurrent connection",
|
||||
nj_col->table_field->name));
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
DBUG_ASSERT(nj_col->table_ref->table == nj_col->table_field->field->table);
|
||||
found_field= nj_col->table_field->field;
|
||||
update_field_dependencies(thd, found_field, nj_col->table_ref->table);
|
||||
}
|
||||
|
||||
|
@ -4450,7 +4463,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
|||
const char *field_name_1;
|
||||
/* true if field_name_1 is a member of using_fields */
|
||||
bool is_using_column_1;
|
||||
if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1)))
|
||||
if (!(nj_col_1= it_1.get_or_create_column_ref(thd, leaf_1)))
|
||||
goto err;
|
||||
field_name_1= nj_col_1->name();
|
||||
is_using_column_1= using_fields &&
|
||||
|
@ -4471,7 +4484,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
|||
{
|
||||
Natural_join_column *cur_nj_col_2;
|
||||
const char *cur_field_name_2;
|
||||
if (!(cur_nj_col_2= it_2.get_or_create_column_ref(leaf_2)))
|
||||
if (!(cur_nj_col_2= it_2.get_or_create_column_ref(thd, leaf_2)))
|
||||
goto err;
|
||||
cur_field_name_2= cur_nj_col_2->name();
|
||||
DBUG_PRINT ("info", ("cur_field_name_2=%s.%s",
|
||||
|
@ -4957,15 +4970,24 @@ static bool setup_natural_join_row_types(THD *thd,
|
|||
TABLE_LIST *left_neighbor;
|
||||
/* Table reference to the right of the current. */
|
||||
TABLE_LIST *right_neighbor= NULL;
|
||||
bool save_first_natural_join_processing=
|
||||
context->select_lex->first_natural_join_processing;
|
||||
|
||||
context->select_lex->first_natural_join_processing= FALSE;
|
||||
|
||||
/* Note that tables in the list are in reversed order */
|
||||
for (left_neighbor= table_ref_it++; left_neighbor ; )
|
||||
{
|
||||
table_ref= left_neighbor;
|
||||
left_neighbor= table_ref_it++;
|
||||
/* For stored procedures do not redo work if already done. */
|
||||
if (context->select_lex->first_execution)
|
||||
/*
|
||||
Do not redo work if already done:
|
||||
1) for stored procedures,
|
||||
2) for multitable update after lock failure and table reopening.
|
||||
*/
|
||||
if (save_first_natural_join_processing)
|
||||
{
|
||||
context->select_lex->first_natural_join_processing= FALSE;
|
||||
if (store_top_level_join_columns(thd, table_ref,
|
||||
left_neighbor, right_neighbor))
|
||||
return TRUE;
|
||||
|
|
|
@ -1205,6 +1205,7 @@ void st_select_lex::init_query()
|
|||
subquery_in_having= explicit_limit= 0;
|
||||
is_item_list_lookup= 0;
|
||||
first_execution= 1;
|
||||
first_natural_join_processing= 1;
|
||||
first_cond_optimization= 1;
|
||||
parsing_place= NO_MATTER;
|
||||
exclude_from_table_unique_test= no_wrap_view_item= FALSE;
|
||||
|
|
|
@ -586,6 +586,7 @@ public:
|
|||
case of an error during prepare the PS is not created.
|
||||
*/
|
||||
bool first_execution;
|
||||
bool first_natural_join_processing;
|
||||
bool first_cond_optimization;
|
||||
/* do not wrap view fields with Item_ref */
|
||||
bool no_wrap_view_item;
|
||||
|
|
|
@ -399,7 +399,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||
}
|
||||
else
|
||||
{
|
||||
DBUG_ASSERT(!thd->stmt_arena->is_conventional());
|
||||
/*
|
||||
We're in execution of a prepared statement or stored procedure:
|
||||
reset field items to point at fields from the created temporary table.
|
||||
|
|
|
@ -852,11 +852,14 @@ reopen_tables:
|
|||
}
|
||||
|
||||
/* now lock and fill tables */
|
||||
if (lock_tables(thd, table_list, table_count, &need_reopen))
|
||||
if (!thd->stmt_arena->is_stmt_prepare() &&
|
||||
lock_tables(thd, table_list, table_count, &need_reopen))
|
||||
{
|
||||
if (!need_reopen)
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
DBUG_PRINT("info", ("lock_tables failed, reopening"));
|
||||
|
||||
/*
|
||||
We have to reopen tables since some of them were altered or dropped
|
||||
during lock_tables() or something was done with their triggers.
|
||||
|
@ -872,6 +875,34 @@ reopen_tables:
|
|||
for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
|
||||
tbl->cleanup_items();
|
||||
|
||||
/*
|
||||
To not to hog memory (as a result of the
|
||||
unit->reinit_exec_mechanism() call below):
|
||||
*/
|
||||
lex->unit.cleanup();
|
||||
|
||||
for (SELECT_LEX *sl= lex->all_selects_list;
|
||||
sl;
|
||||
sl= sl->next_select_in_list())
|
||||
{
|
||||
SELECT_LEX_UNIT *unit= sl->master_unit();
|
||||
unit->reinit_exec_mechanism(); // reset unit->prepared flags
|
||||
/*
|
||||
Reset 'clean' flag back to force normal execution of
|
||||
unit->cleanup() in Prepared_statement::cleanup_stmt()
|
||||
(call to lex->unit.cleanup() above sets this flag to TRUE).
|
||||
*/
|
||||
unit->unclean();
|
||||
}
|
||||
|
||||
/*
|
||||
Also we need to cleanup Natural_join_column::table_field items.
|
||||
To not to traverse a join tree we will cleanup whole
|
||||
thd->free_list (in PS execution mode that list may not contain
|
||||
items from 'fields' list, so the cleanup above is necessary to.
|
||||
*/
|
||||
cleanup_items(thd->free_list);
|
||||
|
||||
close_tables_for_reopen(thd, &table_list);
|
||||
goto reopen_tables;
|
||||
}
|
||||
|
|
24
sql/table.cc
24
sql/table.cc
|
@ -2191,7 +2191,7 @@ TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
|
|||
}
|
||||
|
||||
/*
|
||||
cleunup items belonged to view fields translation table
|
||||
cleanup items belonged to view fields translation table
|
||||
|
||||
SYNOPSIS
|
||||
TABLE_LIST::cleanup_items()
|
||||
|
@ -2637,10 +2637,10 @@ Natural_join_column::Natural_join_column(Field_translator *field_param,
|
|||
}
|
||||
|
||||
|
||||
Natural_join_column::Natural_join_column(Field *field_param,
|
||||
Natural_join_column::Natural_join_column(Item_field *field_param,
|
||||
TABLE_LIST *tab)
|
||||
{
|
||||
DBUG_ASSERT(tab->table == field_param->table);
|
||||
DBUG_ASSERT(tab->table == field_param->field->table);
|
||||
table_field= field_param;
|
||||
view_field= NULL;
|
||||
table_ref= tab;
|
||||
|
@ -2668,7 +2668,7 @@ Item *Natural_join_column::create_item(THD *thd)
|
|||
return create_view_field(thd, table_ref, &view_field->item,
|
||||
view_field->name);
|
||||
}
|
||||
return new Item_field(thd, &thd->lex->current_select->context, table_field);
|
||||
return table_field;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2679,7 +2679,7 @@ Field *Natural_join_column::field()
|
|||
DBUG_ASSERT(table_field == NULL);
|
||||
return NULL;
|
||||
}
|
||||
return table_field;
|
||||
return table_field->field;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2811,7 +2811,7 @@ void Field_iterator_natural_join::next()
|
|||
cur_column_ref= column_ref_it++;
|
||||
DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field ||
|
||||
cur_column_ref->table_ref->table ==
|
||||
cur_column_ref->table_field->table);
|
||||
cur_column_ref->table_field->field->table);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2975,7 +2975,7 @@ GRANT_INFO *Field_iterator_table_ref::grant()
|
|||
*/
|
||||
|
||||
Natural_join_column *
|
||||
Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref)
|
||||
Field_iterator_table_ref::get_or_create_column_ref(THD *thd, TABLE_LIST *parent_table_ref)
|
||||
{
|
||||
Natural_join_column *nj_col;
|
||||
bool is_created= TRUE;
|
||||
|
@ -2988,7 +2988,11 @@ Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref)
|
|||
{
|
||||
/* The field belongs to a stored table. */
|
||||
Field *tmp_field= table_field_it.field();
|
||||
nj_col= new Natural_join_column(tmp_field, table_ref);
|
||||
Item_field *tmp_item=
|
||||
new Item_field(thd, &thd->lex->current_select->context, tmp_field);
|
||||
if (!tmp_item)
|
||||
return NULL;
|
||||
nj_col= new Natural_join_column(tmp_item, table_ref);
|
||||
field_count= table_ref->table->s->fields;
|
||||
}
|
||||
else if (field_it == &view_field_it)
|
||||
|
@ -3012,7 +3016,7 @@ Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref)
|
|||
DBUG_ASSERT(nj_col);
|
||||
}
|
||||
DBUG_ASSERT(!nj_col->table_field ||
|
||||
nj_col->table_ref->table == nj_col->table_field->table);
|
||||
nj_col->table_ref->table == nj_col->table_field->field->table);
|
||||
|
||||
/*
|
||||
If the natural join column was just created add it to the list of
|
||||
|
@ -3077,7 +3081,7 @@ Field_iterator_table_ref::get_natural_column_ref()
|
|||
nj_col= natural_join_it.column_ref();
|
||||
DBUG_ASSERT(nj_col &&
|
||||
(!nj_col->table_field ||
|
||||
nj_col->table_ref->table == nj_col->table_field->table));
|
||||
nj_col->table_ref->table == nj_col->table_field->field->table));
|
||||
return nj_col;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
class Item; /* Needed by ORDER */
|
||||
class Item_subselect;
|
||||
class Item_field;
|
||||
class GRANT_TABLE;
|
||||
class st_select_lex_unit;
|
||||
class st_select_lex;
|
||||
|
@ -469,7 +470,7 @@ class Natural_join_column: public Sql_alloc
|
|||
{
|
||||
public:
|
||||
Field_translator *view_field; /* Column reference of merge view. */
|
||||
Field *table_field; /* Column reference of table or temp view. */
|
||||
Item_field *table_field; /* Column reference of table or temp view. */
|
||||
TABLE_LIST *table_ref; /* Original base table/view reference. */
|
||||
/*
|
||||
True if a common join column of two NATURAL/USING join operands. Notice
|
||||
|
@ -481,7 +482,7 @@ public:
|
|||
bool is_common;
|
||||
public:
|
||||
Natural_join_column(Field_translator *field_param, TABLE_LIST *tab);
|
||||
Natural_join_column(Field *field_param, TABLE_LIST *tab);
|
||||
Natural_join_column(Item_field *field_param, TABLE_LIST *tab);
|
||||
const char *name();
|
||||
Item *create_item(THD *thd);
|
||||
Field *field();
|
||||
|
@ -899,7 +900,7 @@ public:
|
|||
GRANT_INFO *grant();
|
||||
Item *create_item(THD *thd) { return field_it->create_item(thd); }
|
||||
Field *field() { return field_it->field(); }
|
||||
Natural_join_column *get_or_create_column_ref(TABLE_LIST *parent_table_ref);
|
||||
Natural_join_column *get_or_create_column_ref(THD *thd, TABLE_LIST *parent_table_ref);
|
||||
Natural_join_column *get_natural_column_ref();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue