Commit 36430f01 authored by Sergey Petrunya's avatar Sergey Petrunya

Merge fix for BUG#868908

parents d2e27452 ee24ec1e
...@@ -1729,6 +1729,29 @@ FROM t4 , t5 ...@@ -1729,6 +1729,29 @@ FROM t4 , t5
f1 f5 f1 f5
DROP TABLE t1, t2, t3, t4, t5; DROP TABLE t1, t2, t3, t4, t5;
# #
# BUG#868908: Crash in check_simple_equality() with semijoin + materialization + prepared statement
#
CREATE TABLE t1 ( a int );
CREATE TABLE t3 ( b int, c int) ;
CREATE TABLE t2 ( a int ) ;
CREATE TABLE t4 ( a int , c int) ;
PREPARE st1 FROM "
SELECT STRAIGHT_JOIN *
FROM t1
WHERE ( 3 ) IN (
SELECT t3.b
FROM t3
LEFT JOIN (
t2 STRAIGHT_JOIN t4 ON ( t4.c = t2.a )
) ON ( t4.a = t3.c )
);
";
EXECUTE st1;
a
EXECUTE st1;
a
DROP TABLE t1,t2,t3,t4;
#
# BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin # BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin
# #
CREATE TABLE t1 ( a INT, KEY(a) ); CREATE TABLE t1 ( a INT, KEY(a) );
......
...@@ -1765,6 +1765,29 @@ FROM t4 , t5 ...@@ -1765,6 +1765,29 @@ FROM t4 , t5
f1 f5 f1 f5
DROP TABLE t1, t2, t3, t4, t5; DROP TABLE t1, t2, t3, t4, t5;
# #
# BUG#868908: Crash in check_simple_equality() with semijoin + materialization + prepared statement
#
CREATE TABLE t1 ( a int );
CREATE TABLE t3 ( b int, c int) ;
CREATE TABLE t2 ( a int ) ;
CREATE TABLE t4 ( a int , c int) ;
PREPARE st1 FROM "
SELECT STRAIGHT_JOIN *
FROM t1
WHERE ( 3 ) IN (
SELECT t3.b
FROM t3
LEFT JOIN (
t2 STRAIGHT_JOIN t4 ON ( t4.c = t2.a )
) ON ( t4.a = t3.c )
);
";
EXECUTE st1;
a
EXECUTE st1;
a
DROP TABLE t1,t2,t3,t4;
#
# BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin # BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin
# #
CREATE TABLE t1 ( a INT, KEY(a) ); CREATE TABLE t1 ( a INT, KEY(a) );
......
...@@ -1427,6 +1427,29 @@ ON ( t2.f5 ) IN ( ...@@ -1427,6 +1427,29 @@ ON ( t2.f5 ) IN (
); );
DROP TABLE t1, t2, t3, t4, t5; DROP TABLE t1, t2, t3, t4, t5;
--echo #
--echo # BUG#868908: Crash in check_simple_equality() with semijoin + materialization + prepared statement
--echo #
CREATE TABLE t1 ( a int );
CREATE TABLE t3 ( b int, c int) ;
CREATE TABLE t2 ( a int ) ;
CREATE TABLE t4 ( a int , c int) ;
PREPARE st1 FROM "
SELECT STRAIGHT_JOIN *
FROM t1
WHERE ( 3 ) IN (
SELECT t3.b
FROM t3
LEFT JOIN (
t2 STRAIGHT_JOIN t4 ON ( t4.c = t2.a )
) ON ( t4.a = t3.c )
);
";
EXECUTE st1;
EXECUTE st1;
DROP TABLE t1,t2,t3,t4;
--echo # --echo #
--echo # BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin --echo # BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin
......
...@@ -1197,7 +1197,8 @@ Item_in_subselect::Item_in_subselect(Item * left_exp, ...@@ -1197,7 +1197,8 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
Item_exists_subselect(), Item_exists_subselect(),
left_expr_cache(0), first_execution(TRUE), in_strategy(SUBS_NOT_TRANSFORMED), left_expr_cache(0), first_execution(TRUE), in_strategy(SUBS_NOT_TRANSFORMED),
optimizer(0), pushed_cond_guards(NULL), emb_on_expr_nest(NULL), optimizer(0), pushed_cond_guards(NULL), emb_on_expr_nest(NULL),
is_jtbm_merged(FALSE), is_flattenable_semijoin(FALSE), is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
is_flattenable_semijoin(FALSE),
is_registered_semijoin(FALSE), is_registered_semijoin(FALSE),
upper_item(0) upper_item(0)
{ {
...@@ -4182,6 +4183,8 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id) ...@@ -4182,6 +4183,8 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
*/ */
if (tmp_table->s->keys == 0) if (tmp_table->s->keys == 0)
{ {
//fprintf(stderr, "Q: %s\n", current_thd->query());
DBUG_ASSERT(0);
DBUG_ASSERT( DBUG_ASSERT(
tmp_table->s->uniques || tmp_table->s->uniques ||
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() || tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
......
...@@ -449,6 +449,7 @@ class Item_in_subselect :public Item_exists_subselect ...@@ -449,6 +449,7 @@ class Item_in_subselect :public Item_exists_subselect
double jtbm_read_time; double jtbm_read_time;
double jtbm_record_count; double jtbm_record_count;
bool is_jtbm_merged; bool is_jtbm_merged;
bool is_jtbm_const_tab;
/* /*
TRUE<=>this is a flattenable semi-join, false overwise. TRUE<=>this is a flattenable semi-join, false overwise.
...@@ -490,7 +491,7 @@ class Item_in_subselect :public Item_exists_subselect ...@@ -490,7 +491,7 @@ class Item_in_subselect :public Item_exists_subselect
:Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE), :Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
abort_on_null(0), in_strategy(SUBS_NOT_TRANSFORMED), optimizer(0), abort_on_null(0), in_strategy(SUBS_NOT_TRANSFORMED), optimizer(0),
pushed_cond_guards(NULL), func(NULL), emb_on_expr_nest(NULL), pushed_cond_guards(NULL), func(NULL), emb_on_expr_nest(NULL),
is_jtbm_merged(FALSE), is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
upper_item(0) upper_item(0)
{} {}
void cleanup(); void cleanup();
......
...@@ -866,8 +866,10 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, ...@@ -866,8 +866,10 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
for (i=tables=lock_count=0 ; i < count ; i++) for (i=tables=lock_count=0 ; i < count ; i++)
{ {
TABLE *t= table_ptr[i]; TABLE *t= table_ptr[i];
if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE &&
t->s->tmp_table != INTERNAL_TMP_TABLE)
{ {
tables+= t->file->lock_count(); tables+= t->file->lock_count();
lock_count++; lock_count++;
...@@ -895,7 +897,9 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, ...@@ -895,7 +897,9 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
TABLE *table; TABLE *table;
enum thr_lock_type lock_type; enum thr_lock_type lock_type;
THR_LOCK_DATA **locks_start; THR_LOCK_DATA **locks_start;
if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) table= table_ptr[i];
if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE ||
table->s->tmp_table == INTERNAL_TMP_TABLE)
continue; continue;
lock_type= table->reginfo.lock_type; lock_type= table->reginfo.lock_type;
DBUG_ASSERT(lock_type != TL_WRITE_DEFAULT && lock_type != TL_READ_DEFAULT); DBUG_ASSERT(lock_type != TL_WRITE_DEFAULT && lock_type != TL_READ_DEFAULT);
......
...@@ -1266,10 +1266,9 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred) ...@@ -1266,10 +1266,9 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
List_iterator_fast<TABLE_LIST> si(subq_lex->leaf_tables); List_iterator_fast<TABLE_LIST> si(subq_lex->leaf_tables);
while ((tl= si++)) while ((tl= si++))
{ {
tl->table->tablenr= table_no; tl->set_tablenr(table_no);
tl->table->map= ((table_map)1) << table_no;
if (tl->is_jtbm()) if (tl->is_jtbm())
tl->jtbm_table_no= tl->table->tablenr; tl->jtbm_table_no= table_no;
SELECT_LEX *old_sl= tl->select_lex; SELECT_LEX *old_sl= tl->select_lex;
tl->select_lex= parent_join->select_lex; tl->select_lex= parent_join->select_lex;
for (TABLE_LIST *emb= tl->embedding; for (TABLE_LIST *emb= tl->embedding;
...@@ -1427,25 +1426,12 @@ static bool convert_subq_to_jtbm(JOIN *parent_join, ...@@ -1427,25 +1426,12 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
List<TABLE_LIST> *emb_join_list= &parent_lex->top_join_list; List<TABLE_LIST> *emb_join_list= &parent_lex->top_join_list;
TABLE_LIST *emb_tbl_nest= NULL; // will change when we learn to handle outer joins TABLE_LIST *emb_tbl_nest= NULL; // will change when we learn to handle outer joins
TABLE_LIST *tl; TABLE_LIST *tl;
double rows;
double read_time;
DBUG_ENTER("convert_subq_to_jtbm"); DBUG_ENTER("convert_subq_to_jtbm");
bool optimization_delayed= TRUE;
subq_pred->set_strategy(SUBS_MATERIALIZATION); subq_pred->set_strategy(SUBS_MATERIALIZATION);
if (subq_pred->optimize(&rows, &read_time))
DBUG_RETURN(TRUE);
subq_pred->jtbm_read_time= read_time;
subq_pred->jtbm_record_count=rows;
subq_pred->is_jtbm_merged= TRUE; subq_pred->is_jtbm_merged= TRUE;
if (subq_pred->engine->engine_type() != subselect_engine::HASH_SJ_ENGINE)
{
*remove_item= FALSE;
DBUG_RETURN(FALSE);
}
*remove_item= TRUE; *remove_item= TRUE;
TABLE_LIST *jtbm; TABLE_LIST *jtbm;
...@@ -1481,7 +1467,18 @@ static bool convert_subq_to_jtbm(JOIN *parent_join, ...@@ -1481,7 +1467,18 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
tl->next_local= jtbm; tl->next_local= jtbm;
/* A theory: no need to re-connect the next_global chain */ /* A theory: no need to re-connect the next_global chain */
if (optimization_delayed)
{
DBUG_ASSERT(parent_join->table_count < MAX_TABLES);
jtbm->jtbm_table_no= parent_join->table_count;
create_subquery_temptable_name(tbl_alias,
subq_pred->unit->first_select()->select_number);
jtbm->alias= tbl_alias;
parent_join->table_count++;
DBUG_RETURN(FALSE);
}
subselect_hash_sj_engine *hash_sj_engine= subselect_hash_sj_engine *hash_sj_engine=
((subselect_hash_sj_engine*)subq_pred->engine); ((subselect_hash_sj_engine*)subq_pred->engine);
jtbm->table= hash_sj_engine->tmp_table; jtbm->table= hash_sj_engine->tmp_table;
......
...@@ -3644,12 +3644,12 @@ bool st_select_lex::save_leaf_tables(THD *thd) ...@@ -3644,12 +3644,12 @@ bool st_select_lex::save_leaf_tables(THD *thd)
{ {
if (leaf_tables_exec.push_back(table)) if (leaf_tables_exec.push_back(table))
return 1; return 1;
table->tablenr_exec= table->table->tablenr; table->tablenr_exec= table->get_tablenr();
table->map_exec= table->table->map; table->map_exec= table->get_map();
if (join && (join->select_options & SELECT_DESCRIBE)) if (join && (join->select_options & SELECT_DESCRIBE))
table->maybe_null_exec= 0; table->maybe_null_exec= 0;
else else
table->maybe_null_exec= table->table->maybe_null; table->maybe_null_exec= table->table? table->table->maybe_null: 0;
} }
if (arena) if (arena)
thd->restore_active_arena(arena, &backup); thd->restore_active_arena(arena, &backup);
......
...@@ -798,13 +798,46 @@ bool JOIN::prepare_stage2() ...@@ -798,13 +798,46 @@ bool JOIN::prepare_stage2()
} }
/*
Create a dummy temporary table, useful only for the sake of having a
TABLE* object with map,tablenr and maybe_null properties.
This is used by non-mergeable semi-join materilization code to handle
degenerate cases where materialized subquery produced "Impossible WHERE"
and thus wasn't materialized.
*/
TABLE *create_dummy_tmp_table(THD *thd)
{
DBUG_ENTER("create_dummy_tmp_table");
TABLE *table;
TMP_TABLE_PARAM sjm_table_param;
sjm_table_param.init();
sjm_table_param.field_count= 1;
List<Item> sjm_table_cols;
Item *column_item= new Item_int(1);
sjm_table_cols.push_back(column_item);
if (!(table= create_tmp_table(thd, &sjm_table_param,
sjm_table_cols, (ORDER*) 0,
TRUE /* distinct */,
1, /*save_sum_fields*/
thd->options | TMP_TABLE_ALL_COLUMNS,
HA_POS_ERROR /*rows_limit */,
(char*)"dummy", TRUE /* Do not open */)))
{
DBUG_RETURN(NULL);
}
DBUG_RETURN(table);
}
void void
inject_jtbm_conds(JOIN *join, List<TABLE_LIST> *join_list, Item **join_where) setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list, Item **join_where)
{ {
TABLE_LIST *table; TABLE_LIST *table;
NESTED_JOIN *nested_join; NESTED_JOIN *nested_join;
List_iterator<TABLE_LIST> li(*join_list); List_iterator<TABLE_LIST> li(*join_list);
DBUG_ENTER("inject_jtbm_conds"); DBUG_ENTER("setup_jtbm_semi_joins");
while ((table= li++)) while ((table= li++))
...@@ -817,34 +850,60 @@ inject_jtbm_conds(JOIN *join, List<TABLE_LIST> *join_list, Item **join_where) ...@@ -817,34 +850,60 @@ inject_jtbm_conds(JOIN *join, List<TABLE_LIST> *join_list, Item **join_where)
double rows; double rows;
double read_time; double read_time;
//DBUG_ASSERT(subq_pred->test_set_strategy(SUBS_MATERIALIZATION));
subq_pred->optimize(&rows, &read_time); subq_pred->optimize(&rows, &read_time);
subq_pred->jtbm_read_time= read_time; subq_pred->jtbm_read_time= read_time;
subq_pred->jtbm_record_count=rows; subq_pred->jtbm_record_count=rows;
subq_pred->is_jtbm_merged= TRUE; subq_pred->is_jtbm_merged= TRUE;
JOIN *subq_join= subq_pred->unit->first_select()->join;
if (!subq_join->tables_list || !subq_join->table_count)
{
/*
This is an empty and constant table.
subselect_hash_sj_engine *hash_sj_engine= TODO: what if this is not empty but still constant?
((subselect_hash_sj_engine*)item->engine);
We'll need to check the equality but there's no materializatnion
table?
//repeat of convert_subq_to_jtbm:
table->table= hash_sj_engine->tmp_table; A: create an IN-equality from
table->table->pos_in_table_list= table; - left_expr
- right_expr. Q: how can right-expr exist in the context of
parent select? We don't have refs from outside to inside!
A: create/check in the context of the child select?
for injection, check how in->exists is performed.
*/
subq_pred->is_jtbm_const_tab= TRUE;
setup_table_map(table->table, table, table->jtbm_table_no); TABLE *dummy_table= create_dummy_tmp_table(join->thd);
table->table= dummy_table;
table->table->pos_in_table_list= table;
Item *sj_conds= hash_sj_engine->semi_join_conds; setup_table_map(table->table, table, table->jtbm_table_no);
}
else
{
DBUG_ASSERT(subq_pred->test_set_strategy(SUBS_MATERIALIZATION));
subq_pred->is_jtbm_const_tab= FALSE;
subselect_hash_sj_engine *hash_sj_engine=
((subselect_hash_sj_engine*)item->engine);
table->table= hash_sj_engine->tmp_table;
table->table->pos_in_table_list= table;
setup_table_map(table->table, table, table->jtbm_table_no);
Item *sj_conds= hash_sj_engine->semi_join_conds;
(*join_where)= and_items(*join_where, sj_conds); (*join_where)= and_items(*join_where, sj_conds);
if (!(*join_where)->fixed) if (!(*join_where)->fixed)
(*join_where)->fix_fields(join->thd, join_where); (*join_where)->fix_fields(join->thd, join_where);
//parent_join->select_lex->where= parent_join->conds; }
} }
if ((nested_join= table->nested_join)) if ((nested_join= table->nested_join))
{ {
inject_jtbm_conds(join, &nested_join->join_list, join_where); setup_jtbm_semi_joins(join, &nested_join->join_list, join_where);
} }
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -974,7 +1033,7 @@ JOIN::optimize() ...@@ -974,7 +1033,7 @@ JOIN::optimize()
thd->restore_active_arena(arena, &backup); thd->restore_active_arena(arena, &backup);
} }
inject_jtbm_conds(this, join_list, &conds); setup_jtbm_semi_joins(this, join_list, &conds);
conds= optimize_cond(this, conds, join_list, &cond_value, &cond_equal); conds= optimize_cond(this, conds, join_list, &cond_value, &cond_equal);
...@@ -3120,6 +3179,14 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, ...@@ -3120,6 +3179,14 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
set_position(join,const_count++,s,(KEYUSE*) 0); set_position(join,const_count++,s,(KEYUSE*) 0);
no_rows_const_tables |= table->map; no_rows_const_tables |= table->map;
} }
/* SJ-Materialization handling: */
if (table->pos_in_table_list->jtbm_subselect &&
table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab)
{
set_position(join,const_count++,s,(KEYUSE*) 0);
no_rows_const_tables |= table->map;
}
} }
stat_vector[i]=0; stat_vector[i]=0;
...@@ -9669,8 +9736,16 @@ void JOIN_TAB::cleanup() ...@@ -9669,8 +9736,16 @@ void JOIN_TAB::cleanup()
if (table->pos_in_table_list && if (table->pos_in_table_list &&
table->pos_in_table_list->jtbm_subselect) table->pos_in_table_list->jtbm_subselect)
{ {
end_read_record(&read_record); if (table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab)
table->pos_in_table_list->jtbm_subselect->cleanup(); {
free_tmp_table(join->thd, table);
table= NULL;
}
else
{
end_read_record(&read_record);
table->pos_in_table_list->jtbm_subselect->cleanup();
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /*
...@@ -11944,7 +12019,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top, ...@@ -11944,7 +12019,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top,
{ {
if (!table->prep_on_expr) if (!table->prep_on_expr)
table->prep_on_expr= table->on_expr; table->prep_on_expr= table->on_expr;
used_tables= table->table->map; used_tables= table->get_map();
if (conds) if (conds)
not_null_tables= conds->not_null_tables(); not_null_tables= conds->not_null_tables();
} }
...@@ -12001,7 +12076,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top, ...@@ -12001,7 +12076,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top,
table->embedding->on_expr_dep_tables|= table->on_expr->used_tables(); table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
} }
else else
table->dep_tables&= ~table->table->map; table->dep_tables&= ~table->get_map();
} }
if (prev_table) if (prev_table)
...@@ -12014,7 +12089,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top, ...@@ -12014,7 +12089,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top,
prev_table->dep_tables|= table->on_expr_dep_tables; prev_table->dep_tables|= table->on_expr_dep_tables;
table_map prev_used_tables= prev_table->nested_join ? table_map prev_used_tables= prev_table->nested_join ?
prev_table->nested_join->used_tables : prev_table->nested_join->used_tables :
prev_table->table->map; prev_table->get_map();
/* /*
If on expression contains only references to inner tables If on expression contains only references to inner tables
we still make the inner tables dependent on the outer tables. we still make the inner tables dependent on the outer tables.
...@@ -15577,6 +15652,12 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos) ...@@ -15577,6 +15652,12 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
/* Skip materialized derived tables/views. */ /* Skip materialized derived tables/views. */
DBUG_RETURN(0); DBUG_RETURN(0);
} }
else if (tab->table->pos_in_table_list->jtbm_subselect &&
tab->table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab)
{
/* Row will not be found */
DBUG_RETURN(-1);
}
else if (tab->type == JT_SYSTEM) else if (tab->type == JT_SYSTEM)
{ {
if ((error=join_read_system(tab))) if ((error=join_read_system(tab)))
......
...@@ -5922,6 +5922,8 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view) ...@@ -5922,6 +5922,8 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view)
int TABLE_LIST::fetch_number_of_rows() int TABLE_LIST::fetch_number_of_rows()
{ {
int error= 0; int error= 0;
if (jtbm_subselect)
return 0;
if (is_materialized_derived() && !fill_me) if (is_materialized_derived() && !fill_me)
{ {
......
...@@ -1377,6 +1377,26 @@ struct TABLE_LIST ...@@ -1377,6 +1377,26 @@ struct TABLE_LIST
select_union *derived_result; select_union *derived_result;
/* Stub used for materialized derived tables. */ /* Stub used for materialized derived tables. */
table_map map; /* ID bit of table (1,2,4,8,16...) */ table_map map; /* ID bit of table (1,2,4,8,16...) */
table_map get_map()
{
return jtbm_subselect? table_map(1) << jtbm_table_no : table->map;
}
uint get_tablenr()
{
return jtbm_subselect? jtbm_table_no : table->tablenr;
}
void set_tablenr(uint new_tablenr)
{
if (jtbm_subselect)
{
jtbm_table_no= new_tablenr;
}
if (table)
{
table->tablenr= new_tablenr;
table->map= table_map(1) << new_tablenr;
}
}
/* /*
Reference from aux_tables to local list entry of main select of Reference from aux_tables to local list entry of main select of
multi-delete statement: multi-delete statement:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment