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.
|
||||
*/
|
||||
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 */
|
||||
typedef const struct charset_info_st CHARSET_INFO;
|
||||
|
@ -1680,3 +1680,24 @@ SELECT without VERSIONING FROM t1
|
||||
SELECT without WITHOUT FROM t1
|
||||
DROP PROCEDURE p2;
|
||||
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 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););
|
||||
|
||||
save_allow_sum_func= thd->lex->allow_sum_func;
|
||||
thd->lex->allow_sum_func|=
|
||||
(nesting_map)1 << thd->lex->current_select->nest_level;
|
||||
thd->lex->allow_sum_func.set_bit(thd->lex->current_select->nest_level);
|
||||
/*
|
||||
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
|
||||
|
@ -72,14 +72,15 @@ size_t Item_sum::ram_limitation(THD *thd)
|
||||
bool Item_sum::init_sum_func_check(THD *thd)
|
||||
{
|
||||
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())
|
||||
{
|
||||
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),
|
||||
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)
|
||||
{
|
||||
SELECT_LEX *curr_sel= thd->lex->current_select;
|
||||
nesting_map allow_sum_func= (thd->lex->allow_sum_func &
|
||||
curr_sel->name_visibility_map);
|
||||
nesting_map allow_sum_func(thd->lex->allow_sum_func);
|
||||
allow_sum_func.intersect(curr_sel->name_visibility_map);
|
||||
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.
|
||||
@ -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
|
||||
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 ||
|
||||
!(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.
|
||||
@ -202,7 +204,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||
if (register_sum_func(thd, ref))
|
||||
return TRUE;
|
||||
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)
|
||||
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())
|
||||
{
|
||||
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 */
|
||||
aggr_level= sl->nest_level;
|
||||
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
|
||||
|
@ -7372,8 +7372,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
thd->column_usage= column_usage;
|
||||
DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
|
||||
if (allow_sum_func)
|
||||
thd->lex->allow_sum_func|=
|
||||
(nesting_map)1 << thd->lex->current_select->nest_level;
|
||||
thd->lex->allow_sum_func.set_bit(thd->lex->current_select->nest_level);
|
||||
thd->where= THD::DEFAULT_WHERE;
|
||||
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
|
||||
thd->lex->current_select->is_item_list_lookup= 0;
|
||||
|
@ -84,7 +84,7 @@
|
||||
#define MAX_FIELDS 4096 /* Limit in the .frm file */
|
||||
#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 MIN_SORT_MEMORY 1024
|
||||
|
@ -936,7 +936,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
|
||||
List<Item> all_fields;
|
||||
|
||||
*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,
|
||||
&thd->lex->select_lex.top_join_list,
|
||||
table_list,
|
||||
|
@ -734,7 +734,7 @@ void LEX::start(THD *thd_arg)
|
||||
profile_options= PROFILE_NONE;
|
||||
nest_level=0 ;
|
||||
select_lex.nest_level_base= &unit;
|
||||
allow_sum_func= 0;
|
||||
allow_sum_func.clear_all();
|
||||
in_sum_func= NULL;
|
||||
|
||||
used_tables= 0;
|
||||
@ -2335,7 +2335,7 @@ void st_select_lex::init_select()
|
||||
m_non_agg_field_used= false;
|
||||
m_agg_func_used= false;
|
||||
m_custom_agg_func_used= false;
|
||||
name_visibility_map= 0;
|
||||
name_visibility_map.clear_all();
|
||||
with_dep= 0;
|
||||
join= 0;
|
||||
lock_type= TL_READ_DEFAULT;
|
||||
|
@ -33,6 +33,10 @@
|
||||
#include "sql_tvc.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 */
|
||||
|
||||
|
||||
|
@ -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_func= thd->lex->current_select->agg_func_used();
|
||||
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))))
|
||||
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->set_thd(thd);
|
||||
}
|
||||
lex->allow_sum_func= 0;
|
||||
lex->allow_sum_func.clear_all();
|
||||
lex->in_sum_func= NULL;
|
||||
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();
|
||||
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);
|
||||
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 */
|
||||
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;
|
||||
thd->lex->current_select->context_analysis_place= IN_ORDER_BY;
|
||||
res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
|
||||
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;
|
||||
res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
|
||||
group, hidden_group_fields);
|
||||
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,
|
||||
win_specs, win_funcs);
|
||||
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())
|
||||
{
|
||||
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";
|
||||
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;
|
||||
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;
|
||||
/*
|
||||
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);
|
||||
#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
|
||||
|
Loading…
x
Reference in New Issue
Block a user