Browse Source

MDEV-16697: Fix difference between 32bit/windows and 64bit systems in allowed select nest level

pull/933/head
Oleksandr Byelkin 7 years ago
parent
commit
54b2e1c1be
  1. 1
      include/my_global.h
  2. 21
      mysql-test/main/parser.result
  3. 17
      mysql-test/main/parser.test
  4. 3
      sql/item_subselect.cc
  5. 24
      sql/item_sum.cc
  6. 3
      sql/sql_base.cc
  7. 2
      sql/sql_const.h
  8. 2
      sql/sql_delete.cc
  9. 4
      sql/sql_lex.cc
  10. 4
      sql/sql_lex.h
  11. 2
      sql/sql_partition.cc
  12. 2
      sql/sql_prepare.cc
  13. 12
      sql/sql_select.cc
  14. 2
      sql/sql_update.cc

1
include/my_global.h

@ -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;

21
mysql-test/main/parser.result

@ -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

17
mysql-test/main/parser.test

@ -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

3
sql/item_subselect.cc

@ -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

24
sql/item_sum.cc

@ -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

3
sql/sql_base.cc

@ -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;

2
sql/sql_const.h

@ -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

2
sql/sql_delete.cc

@ -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,

4
sql/sql_lex.cc

@ -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;

4
sql/sql_lex.h

@ -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 */

2
sql/sql_partition.cc

@ -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);

2
sql/sql_prepare.cc

@ -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;
}

12
sql/sql_select.cc

@ -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

2
sql/sql_update.cc

@ -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…
Cancel
Save