Commit 8e8bda7f authored by Monty's avatar Monty Committed by Sergei Golubchik

Optimize size of lex structures

LEX, st_select_lex, st_select_unit optimized for space:
- Use bit fields for bool variables
- Ensure that all bit fields are initialized (improves
  performance for init functions as all bit fields can be
  initalized with one memory access)
- Move members around in above structures to remove alignment
  gaps

Some savings:
LEX: 7032 -> 6880
THD: 25608 -> 25456
st_select_lex_unit: 2048 -> 2008

LEX::start():                    1321 -> 1245 instructions
st_select_lex_unit::init_query()  284 ->  214 instructions
st_select_lex::init_query():      766 ->  692 instructions
st_select_lex::init_select():     563 ->  540 instructions

Other things:
- Removed not used LEX::select_allow_into
- Fixed MDEV-25510 Assertion `sel->select_lock ==
   st_select_lex::select_lock_type::NONE' which was caused by this commit.
parent fa7d4abf
......@@ -2105,3 +2105,28 @@ ERROR HY000: Unknown data type: 'ACTION'
#
# End of 10.5 tests
#
#
# Start of 10.6 tests
#
#
# MDEV-25510 Assertion `sel->select_lock ==
# st_select_lex::select_lock_type::NONE' failed in Lex_select_lock::set_to
#
(SELECT x FROM t WINDOW w1 AS () FOR UPDATE) LIMIT 1;
ERROR 42S02: Table 'test.t' doesn't exist
create table t1 (x int);
insert into t1 values (1),(2);
explain extended (SELECT x FROM t1 WINDOW w1 as () FOR UPDATE) LIMIT 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1003 (select `test`.`t1`.`x` AS `x` from `test`.`t1` limit 1)
explain extended (SELECT x FROM t1 FOR UPDATE) LIMIT 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1003 (select `test`.`t1`.`x` AS `x` from `test`.`t1` limit 1)
drop table t1;
#
# End of 10.6 tests
#
......@@ -1883,3 +1883,24 @@ SELECT CAST(1 AS ACTION);
--echo #
--echo # End of 10.5 tests
--echo #
--echo #
--echo # Start of 10.6 tests
--echo #
--echo #
--echo # MDEV-25510 Assertion `sel->select_lock ==
--echo # st_select_lex::select_lock_type::NONE' failed in Lex_select_lock::set_to
--echo #
--error ER_NO_SUCH_TABLE
(SELECT x FROM t WINDOW w1 AS () FOR UPDATE) LIMIT 1;
create table t1 (x int);
insert into t1 values (1),(2);
explain extended (SELECT x FROM t1 WINDOW w1 as () FOR UPDATE) LIMIT 1;
explain extended (SELECT x FROM t1 FOR UPDATE) LIMIT 1;
drop table t1;
--echo #
--echo # End of 10.6 tests
--echo #
......@@ -1252,33 +1252,39 @@ void LEX::start(THD *thd_arg)
unit.slave= current_select= all_selects_list= &builtin_select;
sql_cache= LEX::SQL_CACHE_UNSPECIFIED;
describe= 0;
analyze_stmt= 0;
explain_json= false;
context_analysis_only= 0;
derived_tables= 0;
safe_to_cache_query= 1;
parsing_options.reset();
empty_field_list_on_rset= 0;
part_info= 0;
m_sql_cmd= NULL;
duplicates= DUP_ERROR;
ignore= 0;
spname= NULL;
spcont= NULL;
proc_list.first= 0;
escape_used= FALSE;
default_used= FALSE;
query_tables= 0;
reset_query_tables_list(FALSE);
clause_that_disallows_subselect= NULL;
selects_allow_into= FALSE;
selects_allow_procedure= FALSE;
use_only_table_context= FALSE;
parse_vcol_expr= FALSE;
check_exists= FALSE;
create_info.lex_start();
/* reset bool variables */
is_shutdown_wait_for_slaves= 0;
selects_allow_procedure= 0;
parse_vcol_expr= 0;
analyze_stmt= 0;
explain_json= 0;
local_file= 0;
check_exists= 0;
verbose= 0;
safe_to_cache_query= 1;
ignore= 0;
next_is_main= 0;
next_is_down= 0;
empty_field_list_on_rset= 0;
use_only_table_context= 0;
escape_used= 0;
default_used= 0;
is_lex_started= 1;
create_info.lex_start();
name= null_clex_str;
event_parse_data= NULL;
profile_options= PROFILE_NONE;
......@@ -1307,11 +1313,6 @@ void LEX::start(THD *thd_arg)
vers_conditions.empty();
period_conditions.empty();
is_lex_started= TRUE;
next_is_main= FALSE;
next_is_down= FALSE;
wild= 0;
exchange= 0;
......@@ -2898,25 +2899,30 @@ void st_select_lex_unit::init_query()
set_linkage(GLOBAL_OPTIONS_TYPE);
lim.clear();
union_distinct= 0;
prepared= optimized= optimized_2= executed= 0;
bag_set_op_optimized= 0;
optimize_started= 0;
item= 0;
union_result= 0;
table= 0;
fake_select_lex= 0;
saved_fake_select_lex= 0;
cleaned= 0;
item_list.empty();
describe= 0;
found_rows_for_union= 0;
derived= 0;
is_view= false;
with_clause= 0;
with_element= 0;
columns_are_renamed= false;
with_wrapped_tvc= false;
have_except_all_or_intersect_all= false;
/* reset all bit fields */
prepared= 0;
optimized= 0;
optimized_2= 0;
executed= 0;
cleaned= 0;
bag_set_op_optimized= 0;
optimize_started= 0;
have_except_all_or_intersect_all= 0;
with_wrapped_tvc= 0;
is_view= 0;
describe= 0;
columns_are_renamed= 0;
}
void st_select_lex::init_query()
......@@ -2930,13 +2936,37 @@ void st_select_lex::init_query()
leaf_tables.empty();
item_list.empty();
min_max_opt_list.empty();
limit_params.clear();
join= 0;
having= prep_having= where= prep_where= 0;
cond_pushed_into_where= cond_pushed_into_having= 0;
attach_to_conds.empty();
olap= UNSPECIFIED_OLAP_TYPE;
/* reset all bit fields */
is_item_list_lookup= 0;
have_merged_subqueries= 0;
is_set_query_expr_tail= 0;
with_sum_func= 0;
braces= 0;
automatic_brackets= 0;
having_fix_field= 0;
having_fix_field_for_pushed_cond= 0;
subquery_in_having= 0;
is_item_list_lookup= 0;
with_all_modifier= 0;
is_correlated= 0;
first_natural_join_processing= 1;
first_cond_optimization= 1;
no_wrap_view_item= 0;
exclude_from_table_unique_test= 0;
in_tvc= 0;
skip_locked= 0;
m_non_agg_field_used= 0;
m_agg_func_used= 0;
m_custom_agg_func_used= 0;
is_service_select= 0;
context.select_lex= this;
context.init();
cond_count= between_count= with_wild= 0;
......@@ -2949,29 +2979,18 @@ void st_select_lex::init_query()
n_child_sum_items= 0;
hidden_bit_fields= 0;
fields_in_window_functions= 0;
subquery_in_having= 0;
is_item_list_lookup= 0;
changed_elements= 0;
first_natural_join_processing= 1;
first_cond_optimization= 1;
is_service_select= 0;
parsing_place= NO_MATTER;
save_parsing_place= NO_MATTER;
context_analysis_place= NO_MATTER;
exclude_from_table_unique_test= no_wrap_view_item= FALSE;
nest_level= 0;
link_next= 0;
prep_leaf_list_state= UNINIT;
have_merged_subqueries= FALSE;
bzero((char*) expr_cache_may_be_used, sizeof(expr_cache_may_be_used));
select_list_tables= 0;
m_non_agg_field_used= false;
m_agg_func_used= false;
m_custom_agg_func_used= false;
window_specs.empty();
window_funcs.empty();
tvc= 0;
in_tvc= false;
versioned_tables= 0;
pushdown_select= 0;
}
......@@ -2986,6 +3005,8 @@ void st_select_lex::init_select()
type= 0;
db= null_clex_str;
having= 0;
table_join_options= 0;
select_lock= select_lock_type::NONE;
in_sum_expr= with_wild= 0;
options= 0;
ftfunc_list_alloc.empty();
......@@ -2994,20 +3015,23 @@ void st_select_lex::init_select()
order_list.empty();
/* Set limit and offset to default values */
limit_params.clear();
is_set_query_expr_tail= false;
select_lock= select_lock_type::NONE;
skip_locked= false;
/* Reset bit fields */
is_set_query_expr_tail= 0;
with_sum_func= 0;
with_all_modifier= 0;
is_correlated= 0;
in_tvc= 0;
skip_locked= 0;
m_non_agg_field_used= 0;
m_agg_func_used= 0;
m_custom_agg_func_used= 0;
cur_pos_in_select_list= UNDEF_POS;
cond_value= having_value= Item::COND_UNDEF;
inner_refs_list.empty();
insert_tables= 0;
merged_into= 0;
m_non_agg_field_used= false;
m_agg_func_used= false;
m_custom_agg_func_used= false;
name_visibility_map.clear_all();
with_dep= 0;
join= 0;
......@@ -3017,7 +3041,6 @@ void st_select_lex::init_select()
tvc= 0;
in_funcs.empty();
curr_tvc_name= 0;
in_tvc= false;
versioned_tables= 0;
nest_flags= 0;
}
......@@ -3937,8 +3960,9 @@ void Query_tables_list::destroy_query_tables_list()
LEX::LEX()
: explain(NULL), result(0), part_info(NULL), arena_for_set_stmt(0), mem_root_for_set_stmt(0),
json_table(NULL), option_type(OPT_DEFAULT), context_analysis_only(0), sphead(0),
default_used(0), is_lex_started(0), limit_rows_examined_cnt(ULONGLONG_MAX)
json_table(NULL), default_used(0), is_lex_started(0),
option_type(OPT_DEFAULT), context_analysis_only(0), sphead(0),
limit_rows_examined_cnt(ULONGLONG_MAX)
{
init_dynamic_array2(PSI_INSTRUMENT_ME, &plugins, sizeof(plugin_ref),
......@@ -9782,7 +9806,13 @@ void Lex_select_lock::set_to(SELECT_LEX *sel)
}
}
else
{
/*
select_lock can be FOR_UPDATE in case of
(SELECT x FROM t WINDOW w1 AS () FOR UPDATE) LIMIT 1
*/
sel->select_lock= st_select_lex::select_lock_type::NONE;
}
}
bool Lex_order_limit_lock::set_to(SELECT_LEX *sel)
......@@ -10272,7 +10302,6 @@ bool LEX::parsed_create_view(SELECT_LEX_UNIT *unit, int check)
bool LEX::select_finalize(st_select_lex_unit *expr)
{
sql_command= SQLCOM_SELECT;
selects_allow_into= TRUE;
selects_allow_procedure= TRUE;
if (set_main_unit(expr))
return true;
......
......@@ -727,12 +727,15 @@ class st_select_lex_node {
st_select_lex_node *next, **prev, /* neighbor list */
*master, *slave, /* vertical links */
*link_next, **link_prev; /* list of whole SELECT_LEX */
enum sub_select_type linkage;
void init_query_common();
public:
public:
ulonglong options;
uint8 uncacheable;
bool distinct:1;
bool no_table_names_allowed:1; /* used for global order by */
/*
result of this query can't be cached, bit field, can be :
UNCACHEABLE_DEPENDENT_GENERATED
......@@ -742,18 +745,12 @@ class st_select_lex_node {
UNCACHEABLE_EXPLAIN
UNCACHEABLE_PREPARE
*/
uint8 uncacheable;
private:
enum sub_select_type linkage;
public:
bool is_linkage_set() const
{
return linkage == UNION_TYPE || linkage == INTERSECT_TYPE || linkage == EXCEPT_TYPE;
}
enum sub_select_type get_linkage() { return linkage; }
bool distinct;
bool no_table_names_allowed; /* used for global order by */
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return (void*) alloc_root(mem_root, (uint) size); }
static void operator delete(void *ptr,size_t size) { TRASH_FREE(ptr, size); }
......@@ -859,7 +856,6 @@ class st_select_lex_unit: public st_select_lex_node {
TABLE_LIST result_table_list;
select_unit *union_result;
ulonglong found_rows_for_union;
bool saved_error;
bool prepare_join(THD *thd, SELECT_LEX *sl, select_result *result,
ulonglong additional_options,
......@@ -870,27 +866,51 @@ class st_select_lex_unit: public st_select_lex_node {
class Type_holder *holders, uint count);
public:
bool join_union_item_types(THD *thd, List<Item> &types, uint count);
public:
// Ensures that at least all members used during cleanup() are initialized.
st_select_lex_unit()
: union_result(NULL), table(NULL), result(NULL),
: union_result(NULL), table(NULL), result(NULL), fake_select_lex(NULL),
cleaned(false), bag_set_op_optimized(false),
have_except_all_or_intersect_all(false), fake_select_lex(NULL)
have_except_all_or_intersect_all(false)
{
}
TABLE *table; /* temporary table using for appending UNION results */
select_result *result;
st_select_lex *pre_last_parse;
bool prepared, // prepare phase already performed for UNION (unit)
optimized, // optimize phase already performed for UNION (unit)
optimized_2,
executed, // already executed
cleaned,
bag_set_op_optimized;
/*
Node on which we should return current_select pointer after parsing
subquery
*/
st_select_lex *return_to;
/* LIMIT clause runtime counters */
Select_limit_counters lim;
/* not NULL if unit used in subselect, point to subselect item */
Item_subselect *item;
/*
TABLE_LIST representing this union in the embedding select. Used for
derived tables/views handling.
*/
TABLE_LIST *derived;
/* With clause attached to this unit (if any) */
With_clause *with_clause;
/* With element where this unit is used as the specification (if any) */
With_element *with_element;
/* thread handler */
THD *thd;
/*
SELECT_LEX for hidden SELECT in union which process global
ORDER BY and LIMIT
*/
st_select_lex *fake_select_lex;
/**
SELECT_LEX that stores LIMIT and OFFSET for UNION ALL when noq
fake_select_lex is used.
*/
st_select_lex *saved_fake_select_lex;
bool optimize_started;
bool have_except_all_or_intersect_all;
/* pointer to the last node before last subsequence of UNION ALL */
st_select_lex *union_distinct;
Procedure *last_procedure; /* Pointer to procedure, if such exists */
// list of fields which points to temporary table for union
List<Item> item_list;
......@@ -902,12 +922,30 @@ class st_select_lex_unit: public st_select_lex_node {
any SELECT of this unit execution
*/
List<Item> types;
bool prepared:1; // prepare phase already performed for UNION (unit)
bool optimized:1; // optimize phase already performed for UNION (unit)
bool optimized_2:1;
bool executed:1; // already executed
bool cleaned:1;
bool bag_set_op_optimized:1;
bool optimize_started:1;
bool have_except_all_or_intersect_all:1;
/**
TRUE if the unit contained TVC at the top level that has been wrapped
into SELECT:
VALUES (v1) ... (vn) => SELECT * FROM (VALUES (v1) ... (vn)) as tvc
*/
bool with_wrapped_tvc;
bool with_wrapped_tvc:1;
bool is_view:1;
bool describe:1; /* union exec() called for EXPLAIN */
bool columns_are_renamed:1;
protected:
/* This is bool, not bit, as it's used and set in many places */
bool saved_error;
public:
/**
Pointer to 'last' select, or pointer to select where we stored
global parameters for union.
......@@ -930,41 +968,6 @@ class st_select_lex_unit: public st_select_lex_node {
return saved_fake_select_lex;
return first_select();
};
//node on which we should return current_select pointer after parsing subquery
st_select_lex *return_to;
/* LIMIT clause runtime counters */
Select_limit_counters lim;
/* not NULL if unit used in subselect, point to subselect item */
Item_subselect *item;
/*
TABLE_LIST representing this union in the embedding select. Used for
derived tables/views handling.
*/
TABLE_LIST *derived;
bool is_view;
/* With clause attached to this unit (if any) */
With_clause *with_clause;
/* With element where this unit is used as the specification (if any) */
With_element *with_element;
/* thread handler */
THD *thd;
/*
SELECT_LEX for hidden SELECT in union which process global
ORDER BY and LIMIT
*/
st_select_lex *fake_select_lex;
/**
SELECT_LEX that stores LIMIT and OFFSET for UNION ALL when noq
fake_select_lex is used.
*/
st_select_lex *saved_fake_select_lex;
/* pointer to the last node before last subsequence of UNION ALL */
st_select_lex *union_distinct;
bool describe; /* union exec() called for EXPLAIN */
Procedure *last_procedure; /* Pointer to procedure, if such exists */
bool columns_are_renamed;
void init_query();
st_select_lex* outer_select();
......@@ -1098,18 +1101,10 @@ class st_select_lex: public st_select_lex_node
while select3->first_nested points to select2 and
select1->first_nested points to select1.
*/
st_select_lex *first_nested;
uint8 nest_flags;
Name_resolution_context context;
LEX_CSTRING db;
Item *where, *having; /* WHERE & HAVING clauses */
Item *prep_where; /* saved WHERE clause for prepared statement processing */
Item *prep_having;/* saved HAVING clause for prepared statement processing */
Item *cond_pushed_into_where; /* condition pushed into the select's WHERE */
Item *cond_pushed_into_having; /* condition pushed into the select's HAVING */
List<Item> attach_to_conds;
/* Saved values of the WHERE and HAVING clauses*/
Item::cond_result cond_value, having_value;
/*
Point to the LEX in which it was created, used in view subquery detection.
......@@ -1118,22 +1113,53 @@ class st_select_lex: public st_select_lex_node
instead of global (from THD) references where it is possible.
*/
LEX *parent_lex;
enum olap_type olap;
/* FROM clause - points to the beginning of the TABLE_LIST::next_local list */
SQL_I_List<TABLE_LIST> table_list;
st_select_lex *first_nested;
Item *where, *having; /* WHERE & HAVING clauses */
Item *prep_where; /* saved WHERE clause for prepared statement processing */
Item *prep_having;/* saved HAVING clause for prepared statement processing */
Item *cond_pushed_into_where; /* condition pushed into WHERE */
Item *cond_pushed_into_having; /* condition pushed into HAVING */
/*
GROUP BY clause.
This list may be mutated during optimization (by remove_const()),
so for prepared statements, we keep a copy of the ORDER.next pointers in
group_list_ptrs, and re-establish the original list before each execution.
nest_levels are local to the query or VIEW,
and that view merge procedure does not re-calculate them.
So we also have to remember unit against which we count levels.
*/
SQL_I_List<ORDER> group_list;
Group_list_ptrs *group_list_ptrs;
SELECT_LEX_UNIT *nest_level_base;
Item_sum *inner_sum_func_list; /* list of sum func in nested selects */
/*
This is a copy of the original JOIN USING list that comes from
the parser. The parser :
1. Sets the natural_join of the second TABLE_LIST in the join
and the st_select_lex::prev_join_using.
2. Makes a parent TABLE_LIST and sets its is_natural_join/
join_using_fields members.
3. Uses the wrapper TABLE_LIST as a table in the upper level.
We cannot assign directly to join_using_fields in the parser because
at stage (1.) the parent TABLE_LIST is not constructed yet and
the assignment will override the JOIN USING fields of the lower level
joins on the right.
*/
List<String> *prev_join_using;
JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */
TABLE_LIST *embedding; /* table embedding to the above list */
table_value_constr *tvc;
List<Item> item_list; /* list of fields & expressions */
List<Item> pre_fix; /* above list before fix_fields */
bool is_item_list_lookup;
/* The interface employed to execute the select query by a foreign engine */
select_handler *select_h;
/* The object used to organize execution of the query by a foreign engine */
select_handler *pushdown_select;
List<TABLE_LIST> *join_list; /* list for the currently parsed join */
st_select_lex *merged_into; /* select which this select is merged into */
/* (not 0 only for views/derived tables) */
const char *type; /* type of select for EXPLAIN */
/* List of references to fields referenced from inner selects */
List<Item_outer_ref> inner_refs_list;
List<Item> attach_to_conds;
/* Saved values of the WHERE and HAVING clauses*/
Item::cond_result cond_value, having_value;
/*
Usually it is pointer to ftfunc_list_alloc, but in union used to create
fake select_lex for calling mysql_select under results of union
......@@ -1145,10 +1171,7 @@ class st_select_lex: public st_select_lex_node
have been applied. Used to rollback those optimizations if it's needed.
*/
List<Item_sum> min_max_opt_list;
JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */
List<TABLE_LIST> top_join_list; /* join list of the top level */
List<TABLE_LIST> *join_list; /* list for the currently parsed join */
TABLE_LIST *embedding; /* table embedding to the above list */
List<TABLE_LIST> sj_nests; /* Semi-join nests within this join */
/*
Beginning of the list of leaves in a FROM clause, where the leaves
......@@ -1169,38 +1192,82 @@ class st_select_lex: public st_select_lex_node
can be transformed into IN-subselect defined with TVC.
*/
List<Item_func_in> in_funcs;
/*
Number of current derived table made with TVC during the
transformation of IN-predicate into IN-subquery for this
st_select_lex.
*/
uint curr_tvc_name;
/*
Needed to correctly generate 'PRIMARY' or 'SIMPLE' for select_type column
of EXPLAIN
*/
bool have_merged_subqueries;
List<TABLE_LIST> leaf_tables;
List<TABLE_LIST> leaf_tables_exec;
List<TABLE_LIST> leaf_tables_prep;
enum leaf_list_state {UNINIT, READY, SAVED};
enum leaf_list_state prep_leaf_list_state;
uint insert_tables;
st_select_lex *merged_into; /* select which this select is merged into */
/* (not 0 only for views/derived tables) */
const char *type; /* type of select for EXPLAIN */
/* current index hint kind. used in filling up index_hints */
enum index_hint_type current_index_hint_type;
/*
FROM clause - points to the beginning of the TABLE_LIST::next_local list.
*/
SQL_I_List<TABLE_LIST> table_list;
/*
GROUP BY clause.
This list may be mutated during optimization (by remove_const()),
so for prepared statements, we keep a copy of the ORDER.next pointers in
group_list_ptrs, and re-establish the original list before each execution.
*/
SQL_I_List<ORDER> group_list;
Group_list_ptrs *group_list_ptrs;
List<Item> item_list; /* list of fields & expressions */
List<Item> pre_fix; /* above list before fix_fields */
SQL_I_List<ORDER> order_list; /* ORDER clause */
SQL_I_List<ORDER> gorder_list;
Lex_select_limit limit_params; /* LIMIT clause parameters */
bool is_set_query_expr_tail;
/* Structure to store fields that are used in the GROUP BY of this select */
List<Field_pair> grouping_tmp_fields;
List<udf_func> udf_list; /* udf function calls stack */
List<Index_hint> *index_hints; /* list of USE/FORCE/IGNORE INDEX */
List<List_item> save_many_values;
List<Item> *save_insert_list;
bool is_item_list_lookup:1;
/*
Needed to correctly generate 'PRIMARY' or 'SIMPLE' for select_type column
of EXPLAIN
*/
bool have_merged_subqueries:1;
bool is_set_query_expr_tail:1;
bool with_sum_func:1; /* sum function indicator */
bool braces:1; /* SELECT ... UNION (SELECT ... ) <- this braces */
bool automatic_brackets:1; /* dummy select for INTERSECT precedence */
/* TRUE when having fix field called in processing of this SELECT */
bool having_fix_field:1;
/*
TRUE when fix field is called for a new condition pushed into the
HAVING clause of this SELECT
*/
bool having_fix_field_for_pushed_cond:1;
/*
there are subquery in HAVING clause => we can't close tables before
query processing end even if we use temporary table
*/
bool subquery_in_having:1;
/* TRUE <=> this SELECT is correlated w.r.t. some ancestor select */
bool with_all_modifier:1; /* used for selects in union */
bool is_correlated:1;
bool first_natural_join_processing:1;
bool first_cond_optimization:1;
/* do not wrap view fields with Item_ref */
bool no_wrap_view_item:1;
/* exclude this select from check of unique_table() */
bool exclude_from_table_unique_test:1;
bool in_tvc:1;
bool skip_locked:1;
bool m_non_agg_field_used:1;
bool m_agg_func_used:1;
bool m_custom_agg_func_used:1;
/* the select is "service-select" and can not have tables */
bool is_service_select:1;
/// Array of pointers to top elements of all_fields list
Ref_ptr_array ref_pointer_array;
ulong table_join_options;
/*
number of items in select_list and HAVING clause used to get number
......@@ -1208,9 +1275,9 @@ class st_select_lex: public st_select_lex_node
list during split_sum_func
*/
uint select_n_having_items;
uint cond_count; /* number of sargable Items in where/having/on */
uint between_count; /* number of between predicates in where/having/on */
uint max_equal_elems; /* maximal number of elements in multiple equalities */
uint cond_count; /* number of sargable Items in where/having/on */
uint between_count; /* number of between predicates in where/having/on */
uint max_equal_elems; /* max number of elements in multiple equalities */
/*
Number of fields used in select list or where clause of current select
and all inner subselects.
......@@ -1219,8 +1286,8 @@ class st_select_lex: public st_select_lex_node
/* reserved for exists 2 in */
uint select_n_reserved;
/*
it counts the number of bit fields in the SELECT list. These are used when DISTINCT is
converted to a GROUP BY involving BIT fields.
it counts the number of bit fields in the SELECT list. These are used when
DISTINCT is converted to a GROUP BY involving BIT fields.
*/
uint hidden_bit_fields;
/*
......@@ -1230,53 +1297,42 @@ class st_select_lex: public st_select_lex_node
2) Fields in the PARTITION BY clause
3) Fields in the ORDER BY clause
*/
/*
Number of current derived table made with TVC during the
transformation of IN-predicate into IN-subquery for this
st_select_lex.
*/
uint curr_tvc_name;
uint fields_in_window_functions;
uint insert_tables;
enum_parsing_place parsing_place; /* where we are parsing expression */
enum_parsing_place save_parsing_place;
enum_parsing_place context_analysis_place; /* where we are in prepare */
bool with_sum_func; /* sum function indicator */
enum leaf_list_state {UNINIT, READY, SAVED};
enum leaf_list_state prep_leaf_list_state;
enum olap_type olap;
/* SELECT [FOR UPDATE/LOCK IN SHARE MODE] [SKIP LOCKED] */
enum select_lock_type {NONE, IN_SHARE_MODE, FOR_UPDATE};
enum select_lock_type select_lock;
uint in_sum_expr;
uint select_number; /* number of select (used for EXPLAIN) */
/*
nest_levels are local to the query or VIEW,
and that view merge procedure does not re-calculate them.
So we also have to remember unit against which we count levels.
*/
SELECT_LEX_UNIT *nest_level_base;
int nest_level; /* nesting level of select */
Item_sum *inner_sum_func_list; /* list of sum func in nested selects */
uint with_wild; /* item list contain '*' */
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
bool automatic_brackets; /* dummy select for INTERSECT precedence */
/* TRUE when having fix field called in processing of this SELECT */
bool having_fix_field;
/*
TRUE when fix field is called for a new condition pushed into the
HAVING clause of this SELECT
*/
bool having_fix_field_for_pushed_cond;
/* List of references to fields referenced from inner selects */
List<Item_outer_ref> inner_refs_list;
uint with_wild; /* item list contain '*' ; Counter */
/* Number of Item_sum-derived objects in this SELECT */
uint n_sum_items;
/* Number of Item_sum-derived objects in children and descendant SELECTs */
uint n_child_sum_items;
uint versioned_tables; /* For versioning */
int nest_level; /* nesting level of select */
/* index in the select list of the expression currently being fixed */
int cur_pos_in_select_list;
/*
This array is used to note whether we have any candidates for
expression caching in the corresponding clauses
*/
bool expr_cache_may_be_used[PARSING_PLACE_SIZE];
/*
there are subquery in HAVING clause => we can't close tables before
query processing end even if we use temporary table
*/
bool subquery_in_having;
/* TRUE <=> this SELECT is correlated w.r.t. some ancestor select */
bool with_all_modifier; /* used for selects in union */
bool is_correlated;
uint8 nest_flags;
/*
This variable is required to ensure proper work of subqueries and
stored procedures. Generally, one should use the states of
......@@ -1290,39 +1346,6 @@ class st_select_lex: public st_select_lex_node
case of an error during prepare the PS is not created.
*/
uint8 changed_elements; // see TOUCHED_SEL_*
/* TODO: add foloowing first_* to bitmap above */
bool first_natural_join_processing;
bool first_cond_optimization;
/* do not wrap view fields with Item_ref */
bool no_wrap_view_item;
/* exclude this select from check of unique_table() */
bool exclude_from_table_unique_test;
/* the select is "service-select" and can not have tables*/
bool is_service_select;
/* index in the select list of the expression currently being fixed */
int cur_pos_in_select_list;
/* SELECT [FOR UPDATE/LOCK IN SHARE MODE] [SKIP LOCKED] */
enum select_lock_type {NONE, IN_SHARE_MODE, FOR_UPDATE};
enum select_lock_type select_lock;
bool skip_locked;
List<udf_func> udf_list; /* udf function calls stack */
/*
This is a copy of the original JOIN USING list that comes from
the parser. The parser :
1. Sets the natural_join of the second TABLE_LIST in the join
and the st_select_lex::prev_join_using.
2. Makes a parent TABLE_LIST and sets its is_natural_join/
join_using_fields members.
3. Uses the wrapper TABLE_LIST as a table in the upper level.
We cannot assign directly to join_using_fields in the parser because
at stage (1.) the parent TABLE_LIST is not constructed yet and
the assignment will override the JOIN USING fields of the lower level
joins on the right.
*/
List<String> *prev_join_using;
/**
The set of those tables whose fields are referenced in the select list of
......@@ -1332,28 +1355,17 @@ class st_select_lex: public st_select_lex_node
/* namp of nesting SELECT visibility (for aggregate functions check) */
nesting_map name_visibility_map;
table_map with_dep;
/* the structure to store fields that are used in the GROUP BY of this select */
List<Field_pair> grouping_tmp_fields;
index_clause_map current_index_hint_clause;
/* it is for correct printing SELECT options */
thr_lock_type lock_type;
List<List_item> save_many_values;
List<Item> *save_insert_list;
table_value_constr *tvc;
bool in_tvc;
/* The object used to organize execution of the query by a foreign engine */
select_handler *pushdown_select;
/** System Versioning */
public:
uint versioned_tables;
int vers_setup_conds(THD *thd, TABLE_LIST *tables);
/* push new Item_field into item_list */
bool vers_push_field(THD *thd, TABLE_LIST *table, const LEX_CSTRING field_name);
bool vers_push_field(THD *thd, TABLE_LIST *table,
const LEX_CSTRING field_name);
int period_setup_conds(THD *thd, TABLE_LIST *table);
void init_query();
......@@ -1492,7 +1504,7 @@ class st_select_lex: public st_select_lex_node
return hints;
}
void clear_index_hints(void) { index_hints= NULL; }
inline void clear_index_hints(void) { index_hints= NULL; }
bool is_part_of_union() { return master_unit()->is_unit_op(); }
bool is_top_level_node()
{
......@@ -1596,18 +1608,6 @@ class st_select_lex: public st_select_lex_node
linkage == INTERSECT_TYPE;
}
private:
bool m_non_agg_field_used;
bool m_agg_func_used;
bool m_custom_agg_func_used;
/* current index hint kind. used in filling up index_hints */
enum index_hint_type current_index_hint_type;
index_clause_map current_index_hint_clause;
/* a list of USE/FORCE/IGNORE INDEX */
List<Index_hint> *index_hints;
public:
inline void add_where_field(st_select_lex *sel)
{
DBUG_ASSERT(this != sel);
......@@ -2815,8 +2815,8 @@ class Lex_input_stream
size_t m_buf_length;
/** Echo the parsed stream to the pre-processed buffer. */
bool m_echo;
bool m_echo_saved;
bool m_echo:1;
bool m_echo_saved:1;
/** Pre-processed buffer. */
char *m_cpp_buf;
......@@ -2866,17 +2866,17 @@ class Lex_input_stream
const char *found_semicolon;
/** SQL_MODE = IGNORE_SPACE. */
bool ignore_space;
bool ignore_space:1;
/**
TRUE if we're parsing a prepared statement: in this mode
we should allow placeholders.
*/
bool stmt_prepare_mode;
bool stmt_prepare_mode:1;
/**
TRUE if we should allow multi-statements.
*/
bool multi_statements;
bool multi_statements:1;
/** Current line number. */
uint yylineno;
......@@ -3236,8 +3236,6 @@ struct LEX: public Query_tables_list
/** SELECT of CREATE VIEW statement */
LEX_STRING create_view_select;
uint current_select_number; // valid for statment LEX (not view)
/** Start of 'ON table', in trigger statements. */
const char* raw_trg_on_table_name_begin;
/** End of 'ON table', in trigger statements. */
......@@ -3335,7 +3333,50 @@ struct LEX: public Query_tables_list
/* The following is used by KILL */
killed_state kill_signal;
killed_type kill_type;
bool is_shutdown_wait_for_slaves;
uint current_select_number; // valid for statment LEX (not view)
/*
The following bool variables should not be bit fields as they are not
reset for every query
*/
bool autocommit; // Often used, better as bool
bool sp_lex_in_use; // Keep track on lex usage in SPs for error handling
/* Bit fields, reset for every query */
bool is_shutdown_wait_for_slaves:1;
bool selects_allow_procedure:1;
/*
A special command "PARSE_VCOL_EXPR" is defined for the parser
to translate a defining expression of a virtual column into an
Item object.
The following flag is used to prevent other applications to use
this command.
*/
bool parse_vcol_expr:1;
bool analyze_stmt:1; /* TRUE<=> this is "ANALYZE $stmt" */
bool explain_json:1;
bool local_file:1;
bool check_exists:1;
bool verbose:1, no_write_to_binlog:1;
bool safe_to_cache_query:1;
bool ignore:1;
bool next_is_main:1; // use "main" SELECT_LEX for nrxt allocation;
bool next_is_down:1; // use "main" SELECT_LEX for nrxt allocation;
/*
field_list was created for view and should be removed before PS/SP
rexecuton
*/
bool empty_field_list_on_rset:1;
/**
During name resolution search only in the table list given by
Name_resolution_context::first_name_resolution_table and
Name_resolution_context::last_name_resolution_table
(see Item_field::fix_fields()).
*/
bool use_only_table_context:1;
bool escape_used:1;
bool default_used:1; /* using default() function */
bool is_lex_started:1; /* If lex_start() did run. For debugging. */
/*
This variable is used in post-parse stage to declare that sum-functions,
or functions which have sense only if GROUP BY is present, are allowed.
......@@ -3356,16 +3397,6 @@ struct LEX: public Query_tables_list
clause name to get an error.
*/
const char *clause_that_disallows_subselect;
bool selects_allow_into;
bool selects_allow_procedure;
/*
A special command "PARSE_VCOL_EXPR" is defined for the parser
to translate a defining expression of a virtual column into an
Item object.
The following flag is used to prevent other applications to use
this command.
*/
bool parse_vcol_expr;
enum enum_duplicates duplicates;
enum enum_tx_isolation tx_isolation;
......@@ -3379,23 +3410,32 @@ struct LEX: public Query_tables_list
enum enum_var_type option_type;
enum enum_drop_mode drop_mode;
uint profile_query_id;
uint profile_options;
enum backup_stages backup_stage;
enum Foreign_key::fk_match_opt fk_match_option;
enum_fk_option fk_update_opt;
enum_fk_option fk_delete_opt;
enum enum_yes_no_unknown tx_chain, tx_release;
st_parsing_options parsing_options;
/*
In sql_cache we store SQL_CACHE flag as specified by user to be
able to restore SELECT statement from internal structures.
*/
enum e_sql_cache { SQL_CACHE_UNSPECIFIED, SQL_NO_CACHE, SQL_CACHE };
e_sql_cache sql_cache;
uint slave_thd_opt, start_transaction_opt;
uint profile_query_id;
uint profile_options;
int nest_level;
/*
In LEX representing update which were transformed to multi-update
stores total number of tables. For LEX representing multi-delete
holds number of tables from which we will delete records.
*/
uint table_count;
uint8 describe;
bool analyze_stmt; /* TRUE<=> this is "ANALYZE $stmt" */
bool explain_json;
/*
A flag that indicates what kinds of derived tables are present in the
query (0 if no derived tables, otherwise a combination of flags
......@@ -3403,36 +3443,18 @@ struct LEX: public Query_tables_list
*/
uint8 derived_tables;
uint8 context_analysis_only;
bool local_file;
bool check_exists;
bool autocommit;
bool verbose, no_write_to_binlog;
enum enum_yes_no_unknown tx_chain, tx_release;
bool safe_to_cache_query;
bool ignore;
bool next_is_main; // use "main" SELECT_LEX for nrxt allocation;
bool next_is_down; // use "main" SELECT_LEX for nrxt allocation;
st_parsing_options parsing_options;
uint8 lex_options; // see OPTION_LEX_*
/*
In sql_cache we store SQL_CACHE flag as specified by user to be
able to restore SELECT statement from internal structures.
*/
enum e_sql_cache { SQL_CACHE_UNSPECIFIED, SQL_NO_CACHE, SQL_CACHE };
e_sql_cache sql_cache;
Alter_info alter_info;
Lex_prepared_stmt prepared_stmt;
/*
For CREATE TABLE statement last element of table list which is not
part of SELECT or LIKE part (i.e. either element for table we are
creating or last of tables referenced by foreign keys).
*/
TABLE_LIST *create_last_non_select_table;
Lex_prepared_stmt prepared_stmt;
sp_head *sphead;
sp_name *spname;
bool sp_lex_in_use; // Keep track on lex usage in SPs for error handling
sp_pcontext *spcont;
......@@ -3440,11 +3462,6 @@ struct LEX: public Query_tables_list
Event_parse_data *event_parse_data;
/*
field_list was created for view and should be removed before PS/SP
rexecuton
*/
bool empty_field_list_on_rset;
/* Characterstics of trigger being created */
st_trg_chistics trg_chistics;
/*
......@@ -3494,23 +3511,12 @@ struct LEX: public Query_tables_list
*/
engine_option_value *option_list_last;
/**
During name resolution search only in the table list given by
Name_resolution_context::first_name_resolution_table and
Name_resolution_context::last_name_resolution_table
(see Item_field::fix_fields()).
*/
bool use_only_table_context;
/*
Reference to a struct that contains information in various commands
to add/create/drop/change table spaces.
*/
st_alter_tablespace *alter_tablespace_info;
bool escape_used;
bool default_used; /* using default() function */
bool is_lex_started; /* If lex_start() did run. For debugging. */
/*
The set of those tables whose fields are referenced in all subqueries
......
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