MDEV-16697: Fix difference between 32bit/windows and 64bit systems in allowed select nest level
This commit is contained in:
parent
89a87e8e42
commit
54b2e1c1be
@ -986,7 +986,6 @@ typedef unsigned long my_off_t;
|
|||||||
TODO Convert these to use Bitmap class.
|
TODO Convert these to use Bitmap class.
|
||||||
*/
|
*/
|
||||||
typedef ulonglong table_map; /* Used for table bits in join */
|
typedef ulonglong table_map; /* Used for table bits in join */
|
||||||
typedef ulong nesting_map; /* Used for flags of nesting constructs */
|
|
||||||
|
|
||||||
/* often used type names - opaque declarations */
|
/* often used type names - opaque declarations */
|
||||||
typedef const struct charset_info_st CHARSET_INFO;
|
typedef const struct charset_info_st CHARSET_INFO;
|
||||||
|
@ -1680,3 +1680,24 @@ SELECT without VERSIONING FROM t1
|
|||||||
SELECT without WITHOUT FROM t1
|
SELECT without WITHOUT FROM t1
|
||||||
DROP PROCEDURE p2;
|
DROP PROCEDURE p2;
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
|
#
|
||||||
|
# MDEV-16697: Fix difference between 32bit/windows and 64bit
|
||||||
|
# systems in allowed select nest level
|
||||||
|
#
|
||||||
|
SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
1
|
||||||
|
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT
|
||||||
|
1
|
||||||
|
End of 10.3 tests
|
||||||
|
@ -1443,3 +1443,20 @@ CALL p2('without');
|
|||||||
|
|
||||||
DROP PROCEDURE p2;
|
DROP PROCEDURE p2;
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-16697: Fix difference between 32bit/windows and 64bit
|
||||||
|
--echo # systems in allowed select nest level
|
||||||
|
--echo #
|
||||||
|
SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT
|
||||||
|
1
|
||||||
|
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
|
||||||
|
--echo End of 10.3 tests
|
||||||
|
@ -1983,8 +1983,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
|
|||||||
print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
|
print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
|
||||||
|
|
||||||
save_allow_sum_func= thd->lex->allow_sum_func;
|
save_allow_sum_func= thd->lex->allow_sum_func;
|
||||||
thd->lex->allow_sum_func|=
|
thd->lex->allow_sum_func.set_bit(thd->lex->current_select->nest_level);
|
||||||
(nesting_map)1 << thd->lex->current_select->nest_level;
|
|
||||||
/*
|
/*
|
||||||
Item_sum_(max|min) can't substitute other item => we can use 0 as
|
Item_sum_(max|min) can't substitute other item => we can use 0 as
|
||||||
reference, also Item_sum_(max|min) can't be fixed after creation, so
|
reference, also Item_sum_(max|min) can't be fixed after creation, so
|
||||||
|
@ -72,14 +72,15 @@ size_t Item_sum::ram_limitation(THD *thd)
|
|||||||
bool Item_sum::init_sum_func_check(THD *thd)
|
bool Item_sum::init_sum_func_check(THD *thd)
|
||||||
{
|
{
|
||||||
SELECT_LEX *curr_sel= thd->lex->current_select;
|
SELECT_LEX *curr_sel= thd->lex->current_select;
|
||||||
if (curr_sel && !curr_sel->name_visibility_map)
|
if (curr_sel && curr_sel->name_visibility_map.is_clear_all())
|
||||||
{
|
{
|
||||||
for (SELECT_LEX *sl= curr_sel; sl; sl= sl->context.outer_select())
|
for (SELECT_LEX *sl= curr_sel; sl; sl= sl->context.outer_select())
|
||||||
{
|
{
|
||||||
curr_sel->name_visibility_map|= (1 << sl-> nest_level);
|
curr_sel->name_visibility_map.set_bit(sl->nest_level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!curr_sel || !(thd->lex->allow_sum_func & curr_sel->name_visibility_map))
|
if (!curr_sel ||
|
||||||
|
!(thd->lex->allow_sum_func.is_overlapping(curr_sel->name_visibility_map)))
|
||||||
{
|
{
|
||||||
my_message(ER_INVALID_GROUP_FUNC_USE, ER_THD(thd, ER_INVALID_GROUP_FUNC_USE),
|
my_message(ER_INVALID_GROUP_FUNC_USE, ER_THD(thd, ER_INVALID_GROUP_FUNC_USE),
|
||||||
MYF(0));
|
MYF(0));
|
||||||
@ -155,10 +156,11 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
|||||||
bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||||
{
|
{
|
||||||
SELECT_LEX *curr_sel= thd->lex->current_select;
|
SELECT_LEX *curr_sel= thd->lex->current_select;
|
||||||
nesting_map allow_sum_func= (thd->lex->allow_sum_func &
|
nesting_map allow_sum_func(thd->lex->allow_sum_func);
|
||||||
curr_sel->name_visibility_map);
|
allow_sum_func.intersect(curr_sel->name_visibility_map);
|
||||||
bool invalid= FALSE;
|
bool invalid= FALSE;
|
||||||
DBUG_ASSERT(curr_sel->name_visibility_map); // should be set already
|
// should be set already
|
||||||
|
DBUG_ASSERT(!curr_sel->name_visibility_map.is_clear_all());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Window functions can not be used as arguments to sum functions.
|
Window functions can not be used as arguments to sum functions.
|
||||||
@ -189,10 +191,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
|||||||
If it is there under a construct where it is not allowed
|
If it is there under a construct where it is not allowed
|
||||||
we report an error.
|
we report an error.
|
||||||
*/
|
*/
|
||||||
invalid= !(allow_sum_func & ((nesting_map)1 << max_arg_level));
|
invalid= !(allow_sum_func.is_set(max_arg_level));
|
||||||
}
|
}
|
||||||
else if (max_arg_level >= 0 ||
|
else if (max_arg_level >= 0 ||
|
||||||
!(allow_sum_func & ((nesting_map)1 << nest_level)))
|
!(allow_sum_func.is_set(nest_level)))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
The set function can be aggregated only in outer subqueries.
|
The set function can be aggregated only in outer subqueries.
|
||||||
@ -202,7 +204,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
|||||||
if (register_sum_func(thd, ref))
|
if (register_sum_func(thd, ref))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
invalid= aggr_level < 0 &&
|
invalid= aggr_level < 0 &&
|
||||||
!(allow_sum_func & ((nesting_map)1 << nest_level));
|
!(allow_sum_func.is_set(nest_level));
|
||||||
if (!invalid && thd->variables.sql_mode & MODE_ANSI)
|
if (!invalid && thd->variables.sql_mode & MODE_ANSI)
|
||||||
invalid= aggr_level < 0 && max_arg_level < nest_level;
|
invalid= aggr_level < 0 && max_arg_level < nest_level;
|
||||||
}
|
}
|
||||||
@ -354,14 +356,14 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
|
|||||||
sl= sl->context.outer_select())
|
sl= sl->context.outer_select())
|
||||||
{
|
{
|
||||||
if (aggr_level < 0 &&
|
if (aggr_level < 0 &&
|
||||||
(allow_sum_func & ((nesting_map)1 << sl->nest_level)))
|
(allow_sum_func.is_set(sl->nest_level)))
|
||||||
{
|
{
|
||||||
/* Found the most nested subquery where the function can be aggregated */
|
/* Found the most nested subquery where the function can be aggregated */
|
||||||
aggr_level= sl->nest_level;
|
aggr_level= sl->nest_level;
|
||||||
aggr_sel= sl;
|
aggr_sel= sl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sl && (allow_sum_func & ((nesting_map)1 << sl->nest_level)))
|
if (sl && (allow_sum_func.is_set(sl->nest_level)))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We reached the subquery of level max_arg_level and checked
|
We reached the subquery of level max_arg_level and checked
|
||||||
|
@ -7372,8 +7372,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
|
|||||||
thd->column_usage= column_usage;
|
thd->column_usage= column_usage;
|
||||||
DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
|
DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
|
||||||
if (allow_sum_func)
|
if (allow_sum_func)
|
||||||
thd->lex->allow_sum_func|=
|
thd->lex->allow_sum_func.set_bit(thd->lex->current_select->nest_level);
|
||||||
(nesting_map)1 << thd->lex->current_select->nest_level;
|
|
||||||
thd->where= THD::DEFAULT_WHERE;
|
thd->where= THD::DEFAULT_WHERE;
|
||||||
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
|
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
|
||||||
thd->lex->current_select->is_item_list_lookup= 0;
|
thd->lex->current_select->is_item_list_lookup= 0;
|
||||||
|
@ -84,7 +84,7 @@
|
|||||||
#define MAX_FIELDS 4096 /* Limit in the .frm file */
|
#define MAX_FIELDS 4096 /* Limit in the .frm file */
|
||||||
#define MAX_PARTITIONS 8192
|
#define MAX_PARTITIONS 8192
|
||||||
|
|
||||||
#define MAX_SELECT_NESTING (sizeof(nesting_map)*8-1)
|
#define MAX_SELECT_NESTING (SELECT_NESTING_MAP_SIZE - 1)
|
||||||
|
|
||||||
#define MAX_SORT_MEMORY 2048*1024
|
#define MAX_SORT_MEMORY 2048*1024
|
||||||
#define MIN_SORT_MEMORY 1024
|
#define MIN_SORT_MEMORY 1024
|
||||||
|
@ -936,7 +936,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
|
|||||||
List<Item> all_fields;
|
List<Item> all_fields;
|
||||||
|
|
||||||
*delete_while_scanning= true;
|
*delete_while_scanning= true;
|
||||||
thd->lex->allow_sum_func= 0;
|
thd->lex->allow_sum_func.clear_all();
|
||||||
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
||||||
&thd->lex->select_lex.top_join_list,
|
&thd->lex->select_lex.top_join_list,
|
||||||
table_list,
|
table_list,
|
||||||
|
@ -734,7 +734,7 @@ void LEX::start(THD *thd_arg)
|
|||||||
profile_options= PROFILE_NONE;
|
profile_options= PROFILE_NONE;
|
||||||
nest_level=0 ;
|
nest_level=0 ;
|
||||||
select_lex.nest_level_base= &unit;
|
select_lex.nest_level_base= &unit;
|
||||||
allow_sum_func= 0;
|
allow_sum_func.clear_all();
|
||||||
in_sum_func= NULL;
|
in_sum_func= NULL;
|
||||||
|
|
||||||
used_tables= 0;
|
used_tables= 0;
|
||||||
@ -2335,7 +2335,7 @@ void st_select_lex::init_select()
|
|||||||
m_non_agg_field_used= false;
|
m_non_agg_field_used= false;
|
||||||
m_agg_func_used= false;
|
m_agg_func_used= false;
|
||||||
m_custom_agg_func_used= false;
|
m_custom_agg_func_used= false;
|
||||||
name_visibility_map= 0;
|
name_visibility_map.clear_all();
|
||||||
with_dep= 0;
|
with_dep= 0;
|
||||||
join= 0;
|
join= 0;
|
||||||
lock_type= TL_READ_DEFAULT;
|
lock_type= TL_READ_DEFAULT;
|
||||||
|
@ -33,6 +33,10 @@
|
|||||||
#include "sql_tvc.h"
|
#include "sql_tvc.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
|
||||||
|
/* Used for flags of nesting constructs */
|
||||||
|
#define SELECT_NESTING_MAP_SIZE 64
|
||||||
|
typedef Bitmap<SELECT_NESTING_MAP_SIZE> nesting_map;
|
||||||
|
|
||||||
/* YACC and LEX Definitions */
|
/* YACC and LEX Definitions */
|
||||||
|
|
||||||
|
|
||||||
|
@ -857,7 +857,7 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
|
|||||||
const bool save_agg_field= thd->lex->current_select->non_agg_field_used();
|
const bool save_agg_field= thd->lex->current_select->non_agg_field_used();
|
||||||
const bool save_agg_func= thd->lex->current_select->agg_func_used();
|
const bool save_agg_func= thd->lex->current_select->agg_func_used();
|
||||||
const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func;
|
const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func;
|
||||||
thd->lex->allow_sum_func= 0;
|
thd->lex->allow_sum_func.clear_all();
|
||||||
|
|
||||||
if (likely(!(error= func_expr->fix_fields_if_needed(thd, (Item**)&func_expr))))
|
if (likely(!(error= func_expr->fix_fields_if_needed(thd, (Item**)&func_expr))))
|
||||||
func_expr->walk(&Item::post_fix_fields_part_expr_processor, 0, NULL);
|
func_expr->walk(&Item::post_fix_fields_part_expr_processor, 0, NULL);
|
||||||
|
@ -3041,7 +3041,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
|
|||||||
lex->result->cleanup();
|
lex->result->cleanup();
|
||||||
lex->result->set_thd(thd);
|
lex->result->set_thd(thd);
|
||||||
}
|
}
|
||||||
lex->allow_sum_func= 0;
|
lex->allow_sum_func.clear_all();
|
||||||
lex->in_sum_func= NULL;
|
lex->in_sum_func= NULL;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -645,7 +645,7 @@ setup_without_group(THD *thd, Ref_ptr_array ref_pointer_array,
|
|||||||
const bool saved_non_agg_field_used= select->non_agg_field_used();
|
const bool saved_non_agg_field_used= select->non_agg_field_used();
|
||||||
DBUG_ENTER("setup_without_group");
|
DBUG_ENTER("setup_without_group");
|
||||||
|
|
||||||
thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level);
|
thd->lex->allow_sum_func.clear_bit(select->nest_level);
|
||||||
res= setup_conds(thd, tables, leaves, conds);
|
res= setup_conds(thd, tables, leaves, conds);
|
||||||
if (thd->lex->current_select->first_cond_optimization)
|
if (thd->lex->current_select->first_cond_optimization)
|
||||||
{
|
{
|
||||||
@ -658,18 +658,18 @@ setup_without_group(THD *thd, Ref_ptr_array ref_pointer_array,
|
|||||||
/* it's not wrong to have non-aggregated columns in a WHERE */
|
/* it's not wrong to have non-aggregated columns in a WHERE */
|
||||||
select->set_non_agg_field_used(saved_non_agg_field_used);
|
select->set_non_agg_field_used(saved_non_agg_field_used);
|
||||||
|
|
||||||
thd->lex->allow_sum_func|= (nesting_map)1 << select->nest_level;
|
thd->lex->allow_sum_func.set_bit(select->nest_level);
|
||||||
|
|
||||||
save_place= thd->lex->current_select->context_analysis_place;
|
save_place= thd->lex->current_select->context_analysis_place;
|
||||||
thd->lex->current_select->context_analysis_place= IN_ORDER_BY;
|
thd->lex->current_select->context_analysis_place= IN_ORDER_BY;
|
||||||
res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
|
res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
|
||||||
order);
|
order);
|
||||||
thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level);
|
thd->lex->allow_sum_func.clear_bit(select->nest_level);
|
||||||
thd->lex->current_select->context_analysis_place= IN_GROUP_BY;
|
thd->lex->current_select->context_analysis_place= IN_GROUP_BY;
|
||||||
res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
|
res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
|
||||||
group, hidden_group_fields);
|
group, hidden_group_fields);
|
||||||
thd->lex->current_select->context_analysis_place= save_place;
|
thd->lex->current_select->context_analysis_place= save_place;
|
||||||
thd->lex->allow_sum_func|= (nesting_map)1 << select->nest_level;
|
thd->lex->allow_sum_func.set_bit(select->nest_level);
|
||||||
res= res || setup_windows(thd, ref_pointer_array, tables, fields, all_fields,
|
res= res || setup_windows(thd, ref_pointer_array, tables, fields, all_fields,
|
||||||
win_specs, win_funcs);
|
win_specs, win_funcs);
|
||||||
thd->lex->allow_sum_func= save_allow_sum_func;
|
thd->lex->allow_sum_func= save_allow_sum_func;
|
||||||
@ -1117,7 +1117,7 @@ JOIN::prepare(TABLE_LIST *tables_init,
|
|||||||
select_lex->master_unit()->global_parameters())
|
select_lex->master_unit()->global_parameters())
|
||||||
{
|
{
|
||||||
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
|
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
|
||||||
thd->lex->allow_sum_func|= (nesting_map)1 << select_lex->nest_level;
|
thd->lex->allow_sum_func.set_bit(select_lex->nest_level);
|
||||||
thd->where= "order clause";
|
thd->where= "order clause";
|
||||||
for (ORDER *order= select_lex->order_list.first; order; order= order->next)
|
for (ORDER *order= select_lex->order_list.first; order; order= order->next)
|
||||||
{
|
{
|
||||||
@ -1135,7 +1135,7 @@ JOIN::prepare(TABLE_LIST *tables_init,
|
|||||||
{
|
{
|
||||||
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
|
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
|
||||||
thd->where="having clause";
|
thd->where="having clause";
|
||||||
thd->lex->allow_sum_func|= (nesting_map)1 << select_lex_arg->nest_level;
|
thd->lex->allow_sum_func.set_bit(select_lex_arg->nest_level);
|
||||||
select_lex->having_fix_field= 1;
|
select_lex->having_fix_field= 1;
|
||||||
/*
|
/*
|
||||||
Wrap alone field in HAVING clause in case it will be outer field
|
Wrap alone field in HAVING clause in case it will be outer field
|
||||||
|
@ -1255,7 +1255,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
|||||||
table_list->register_want_access(SELECT_ACL);
|
table_list->register_want_access(SELECT_ACL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
thd->lex->allow_sum_func= 0;
|
thd->lex->allow_sum_func.clear_all();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We do not call DT_MERGE_FOR_INSERT because it has no sense for simple
|
We do not call DT_MERGE_FOR_INSERT because it has no sense for simple
|
||||||
|
Loading…
x
Reference in New Issue
Block a user