Replace item->marker= # with Item->marker= DEFINE
- Better, easier to read code (no used of 'random' constants). - All defines are now unique, so it is easier to find bugs if somethings goes wrong. Other things: - Created sub function of common code in Aggregator_distinct::setup() and Item_func_group_concat::setup() that set item->marker - More documentation - Folded a few long lines. - Allmost all changes in item.cc, sql_lex.cc and sql_window.cc are done with 'replace'.
This commit is contained in:
parent
860e754349
commit
e8a54a376a
42
sql/item.cc
42
sql/item.cc
@ -416,7 +416,7 @@ Item::Item(THD *thd):
|
||||
base_flags= item_base_t::FIXED;
|
||||
with_flags= item_with_t::NONE;
|
||||
null_value= 0;
|
||||
marker= 0;
|
||||
marker= MARKER_UNUSED;
|
||||
|
||||
/* Initially this item is not attached to any JOIN_TAB. */
|
||||
join_tab_idx= MAX_TABLES;
|
||||
@ -449,7 +449,7 @@ Item::Item():
|
||||
base_flags= item_base_t::FIXED;
|
||||
with_flags= item_with_t::NONE;
|
||||
null_value= 0;
|
||||
marker= 0;
|
||||
marker= MARKER_UNUSED;
|
||||
join_tab_idx= MAX_TABLES;
|
||||
}
|
||||
|
||||
@ -549,7 +549,7 @@ void Item::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item::cleanup");
|
||||
DBUG_PRINT("enter", ("this: %p", this));
|
||||
marker= 0;
|
||||
marker= MARKER_UNUSED;
|
||||
join_tab_idx= MAX_TABLES;
|
||||
if (orig_name)
|
||||
{
|
||||
@ -7361,10 +7361,10 @@ Item *Item_field::update_value_transformer(THD *thd, uchar *select_arg)
|
||||
extraction of a pushable condition. The criteria of pushability of
|
||||
a subformula is checked by the callback function 'checker' with one
|
||||
parameter arg. The subformulas that are not usable are marked with
|
||||
the flag NO_EXTRACTION_FL.
|
||||
the flag MARKER_NO_EXTRACTION.
|
||||
@note
|
||||
This method is called before any call of build_pushable_cond.
|
||||
The flag NO_EXTRACTION_FL set in a subformula allows to avoid building
|
||||
The flag MARKER_NO_EXTRACTION set in a subformula allows to avoid building
|
||||
clones for the subformulas that are not used in the pushable condition.
|
||||
@note
|
||||
This method is called for pushdown conditions into materialized
|
||||
@ -7388,14 +7388,14 @@ void Item::check_pushable_cond(Pushdown_checker checker, uchar *arg)
|
||||
while ((item=li++))
|
||||
{
|
||||
item->check_pushable_cond(checker, arg);
|
||||
if (item->get_extraction_flag() != NO_EXTRACTION_FL)
|
||||
if (item->get_extraction_flag() != MARKER_NO_EXTRACTION)
|
||||
count++;
|
||||
else if (!and_cond)
|
||||
break;
|
||||
}
|
||||
if ((and_cond && count == 0) || item)
|
||||
{
|
||||
set_extraction_flag(NO_EXTRACTION_FL);
|
||||
set_extraction_flag(MARKER_NO_EXTRACTION);
|
||||
if (and_cond)
|
||||
li.rewind();
|
||||
while ((item= li++))
|
||||
@ -7403,7 +7403,7 @@ void Item::check_pushable_cond(Pushdown_checker checker, uchar *arg)
|
||||
}
|
||||
}
|
||||
else if (!((this->*checker) (arg)))
|
||||
set_extraction_flag(NO_EXTRACTION_FL);
|
||||
set_extraction_flag(MARKER_NO_EXTRACTION);
|
||||
}
|
||||
|
||||
|
||||
@ -7420,7 +7420,7 @@ void Item::check_pushable_cond(Pushdown_checker checker, uchar *arg)
|
||||
@details
|
||||
This method finds out what condition that can be pushed down can be
|
||||
extracted from this condition. If such condition C exists the
|
||||
method builds the item for it. The method uses the flag NO_EXTRACTION_FL
|
||||
method builds the item for it. The method uses the flag MARKER_NO_EXTRACTION
|
||||
set by the preliminary call of the method check_pushable_cond() to figure
|
||||
out whether a subformula is pushable or not.
|
||||
In the case when this item is a multiple equality a checker method is
|
||||
@ -7455,7 +7455,7 @@ Item *Item::build_pushable_cond(THD *thd,
|
||||
bool is_multiple_equality= type() == Item::FUNC_ITEM &&
|
||||
((Item_func*) this)->functype() == Item_func::MULT_EQUAL_FUNC;
|
||||
|
||||
if (get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
if (get_extraction_flag() == MARKER_NO_EXTRACTION)
|
||||
return 0;
|
||||
|
||||
if (type() == Item::COND_ITEM)
|
||||
@ -7477,7 +7477,7 @@ Item *Item::build_pushable_cond(THD *thd,
|
||||
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
if (item->get_extraction_flag() == MARKER_NO_EXTRACTION)
|
||||
{
|
||||
if (!cond_and)
|
||||
return 0;
|
||||
@ -7533,7 +7533,7 @@ Item *Item::build_pushable_cond(THD *thd,
|
||||
return 0;
|
||||
return new_cond;
|
||||
}
|
||||
else if (get_extraction_flag() != NO_EXTRACTION_FL)
|
||||
else if (get_extraction_flag() != MARKER_NO_EXTRACTION)
|
||||
return build_clone(thd);
|
||||
return 0;
|
||||
}
|
||||
@ -7584,7 +7584,7 @@ Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg)
|
||||
return this;
|
||||
Item *item= get_field_item_for_having(thd, this, sel);
|
||||
if (item)
|
||||
item->marker|= SUBSTITUTION_FL;
|
||||
item->marker|= MARKER_SUBSTITUTION;
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -7592,9 +7592,9 @@ Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg)
|
||||
Item *Item_direct_view_ref::derived_field_transformer_for_having(THD *thd,
|
||||
uchar *arg)
|
||||
{
|
||||
if ((*ref)->marker & SUBSTITUTION_FL)
|
||||
if ((*ref)->marker & MARKER_SUBSTITUTION)
|
||||
{
|
||||
this->marker|= SUBSTITUTION_FL;
|
||||
this->marker|= MARKER_SUBSTITUTION;
|
||||
return this;
|
||||
}
|
||||
st_select_lex *sel= (st_select_lex *)arg;
|
||||
@ -7650,7 +7650,7 @@ Item *Item_field::derived_field_transformer_for_where(THD *thd, uchar *arg)
|
||||
{
|
||||
Item *producing_clone= producing_item->build_clone(thd);
|
||||
if (producing_clone)
|
||||
producing_clone->marker|= SUBSTITUTION_FL;
|
||||
producing_clone->marker|= MARKER_SUBSTITUTION;
|
||||
return producing_clone;
|
||||
}
|
||||
return this;
|
||||
@ -7659,7 +7659,7 @@ Item *Item_field::derived_field_transformer_for_where(THD *thd, uchar *arg)
|
||||
Item *Item_direct_view_ref::derived_field_transformer_for_where(THD *thd,
|
||||
uchar *arg)
|
||||
{
|
||||
if ((*ref)->marker & SUBSTITUTION_FL)
|
||||
if ((*ref)->marker & MARKER_SUBSTITUTION)
|
||||
return (*ref);
|
||||
if (item_equal)
|
||||
{
|
||||
@ -7681,7 +7681,7 @@ Item *Item_field::grouping_field_transformer_for_where(THD *thd, uchar *arg)
|
||||
Item *producing_clone=
|
||||
gr_field->corresponding_item->build_clone(thd);
|
||||
if (producing_clone)
|
||||
producing_clone->marker|= SUBSTITUTION_FL;
|
||||
producing_clone->marker|= MARKER_SUBSTITUTION;
|
||||
return producing_clone;
|
||||
}
|
||||
return this;
|
||||
@ -7692,9 +7692,9 @@ Item *
|
||||
Item_direct_view_ref::grouping_field_transformer_for_where(THD *thd,
|
||||
uchar *arg)
|
||||
{
|
||||
if ((*ref)->marker & SUBSTITUTION_FL)
|
||||
if ((*ref)->marker & MARKER_SUBSTITUTION)
|
||||
{
|
||||
this->marker|= SUBSTITUTION_FL;
|
||||
this->marker|= MARKER_SUBSTITUTION;
|
||||
return this;
|
||||
}
|
||||
if (!item_equal)
|
||||
@ -10734,7 +10734,7 @@ void Item::register_in(THD *thd)
|
||||
|
||||
bool Item::cleanup_excluding_immutables_processor (void *arg)
|
||||
{
|
||||
if (!(get_extraction_flag() == IMMUTABLE_FL))
|
||||
if (!(get_extraction_flag() == MARKER_IMMUTABLE))
|
||||
return cleanup_processor(arg);
|
||||
else
|
||||
{
|
||||
|
46
sql/item.h
46
sql/item.h
@ -153,14 +153,36 @@ bool mark_unsupported_function(const char *w1, const char *w2,
|
||||
#define SPLIT_SUM_SKIP_REGISTERED 1 /* Skip registered funcs */
|
||||
#define SPLIT_SUM_SELECT 2 /* SELECT item; Split all parts */
|
||||
|
||||
/*
|
||||
Values for item->marker for cond items in the WHERE clause as used
|
||||
by the optimizer.
|
||||
|
||||
#define NO_EXTRACTION_FL (1 << 6)
|
||||
#define FULL_EXTRACTION_FL (1 << 7)
|
||||
#define DELETION_FL (1 << 8)
|
||||
#define IMMUTABLE_FL (1 << 9)
|
||||
#define SUBSTITUTION_FL (1 << 10)
|
||||
#define EXTRACTION_MASK \
|
||||
(NO_EXTRACTION_FL | FULL_EXTRACTION_FL | DELETION_FL | IMMUTABLE_FL)
|
||||
Note that for Item_fields, the marker contains
|
||||
'select->cur_pos_in_select_list
|
||||
*/
|
||||
/* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */
|
||||
#define MARKER_UNDEF_POS -1
|
||||
#define MARKER_UNUSED 0
|
||||
#define MARKER_CHANGE_COND 1
|
||||
#define MARKER_PROCESSED 2
|
||||
#define MARKER_CHECK_ON_READ 3
|
||||
#define MARKER_NULL_KEY 4
|
||||
#define MARKER_FOUND_IN_ORDER 6
|
||||
|
||||
/* Used as bits in marker by Item::check_pushable_cond() */
|
||||
#define MARKER_NO_EXTRACTION (1 << 6)
|
||||
#define MARKER_FULL_EXTRACTION (1 << 7)
|
||||
#define MARKER_DELETION (1 << 8)
|
||||
#define MARKER_IMMUTABLE (1 << 9)
|
||||
#define MARKER_SUBSTITUTION (1 << 10)
|
||||
|
||||
/* Used as bits in marker by window functions */
|
||||
#define MARKER_SORTORDER_CHANGE (1 << 11)
|
||||
#define MARKER_PARTITION_CHANGE (1 << 12)
|
||||
#define MARKER_FRAME_CHANGE (1 << 13)
|
||||
#define MARKER_EXTRACTION_MASK \
|
||||
(MARKER_NO_EXTRACTION | MARKER_FULL_EXTRACTION | MARKER_DELETION | \
|
||||
MARKER_IMMUTABLE)
|
||||
|
||||
extern const char *item_empty_name;
|
||||
|
||||
@ -2616,17 +2638,17 @@ public:
|
||||
void register_in(THD *thd);
|
||||
|
||||
bool depends_only_on(table_map view_map)
|
||||
{ return marker & FULL_EXTRACTION_FL; }
|
||||
{ return marker & MARKER_FULL_EXTRACTION; }
|
||||
int get_extraction_flag()
|
||||
{ return marker & EXTRACTION_MASK; }
|
||||
{ return marker & MARKER_EXTRACTION_MASK; }
|
||||
void set_extraction_flag(int16 flags)
|
||||
{
|
||||
marker &= ~EXTRACTION_MASK;
|
||||
marker|= flags;
|
||||
marker &= ~MARKER_EXTRACTION_MASK;
|
||||
marker|= flags;
|
||||
}
|
||||
void clear_extraction_flag()
|
||||
{
|
||||
marker &= ~EXTRACTION_MASK;
|
||||
marker &= ~MARKER_EXTRACTION_MASK;
|
||||
}
|
||||
void check_pushable_cond(Pushdown_checker excl_dep_func, uchar *arg);
|
||||
bool pushable_cond_checker_for_derived(uchar *arg)
|
||||
|
@ -7549,7 +7549,7 @@ Item_equal::excl_dep_on_grouping_fields(st_select_lex *sel)
|
||||
{
|
||||
if (item->excl_dep_on_grouping_fields(sel))
|
||||
{
|
||||
set_extraction_flag(FULL_EXTRACTION_FL);
|
||||
set_extraction_flag(MARKER_FULL_EXTRACTION);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -7663,7 +7663,7 @@ bool Item_equal::create_pushable_equalities(THD *thd,
|
||||
if (!eq || equalities->push_back(eq, thd->mem_root))
|
||||
return true;
|
||||
if (!clone_const)
|
||||
right_item->set_extraction_flag(IMMUTABLE_FL);
|
||||
right_item->set_extraction_flag(MARKER_IMMUTABLE);
|
||||
}
|
||||
|
||||
while ((item=it++))
|
||||
|
@ -48,6 +48,25 @@ size_t Item_sum::ram_limitation(THD *thd)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Force create_tmp_table() to convert BIT columns to BIGINT.
|
||||
This is needed because BIT fields store parts of their data in table's
|
||||
null bits, and we don't have methods to compare two table records with
|
||||
bit fields.
|
||||
*/
|
||||
|
||||
static void store_bit_fields_as_bigint_in_tempory_table(List<Item> *list)
|
||||
{
|
||||
List_iterator_fast<Item> li(*list);
|
||||
Item *item;
|
||||
while ((item= li++))
|
||||
{
|
||||
if (item->type() == Item::FIELD_ITEM &&
|
||||
((Item_field*) item)->field->type() == FIELD_TYPE_BIT)
|
||||
item->marker= MARKER_NULL_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Prepare an aggregate function item for checking context conditions.
|
||||
|
||||
@ -781,24 +800,15 @@ bool Aggregator_distinct::setup(THD *thd)
|
||||
tmp_table_param->force_copy_fields= item_sum->has_force_copy_fields();
|
||||
DBUG_ASSERT(table == 0);
|
||||
/*
|
||||
Make create_tmp_table() convert BIT columns to BIGINT.
|
||||
This is needed because BIT fields store parts of their data in table's
|
||||
null bits, and we don't have methods to compare two table records, which
|
||||
is needed by Unique which is used when HEAP table is used.
|
||||
Convert bit fields to bigint's in temporary table.
|
||||
Needed by Unique which is used when HEAP table is used.
|
||||
*/
|
||||
{
|
||||
List_iterator_fast<Item> li(list);
|
||||
Item *item;
|
||||
while ((item= li++))
|
||||
{
|
||||
if (item->type() == Item::FIELD_ITEM &&
|
||||
((Item_field*)item)->field->type() == FIELD_TYPE_BIT)
|
||||
item->marker=4;
|
||||
}
|
||||
}
|
||||
store_bit_fields_as_bigint_in_tempory_table(&list);
|
||||
|
||||
if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
|
||||
0,
|
||||
(select_lex->options | thd->variables.option_bits),
|
||||
(select_lex->options |
|
||||
thd->variables.option_bits),
|
||||
HA_POS_ERROR, &empty_clex_str)))
|
||||
return TRUE;
|
||||
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
|
||||
@ -4343,20 +4353,13 @@ bool Item_func_group_concat::setup(THD *thd)
|
||||
if (order_or_distinct)
|
||||
{
|
||||
/*
|
||||
Force the create_tmp_table() to convert BIT columns to INT
|
||||
as we cannot compare two table records containing BIT fields
|
||||
Convert bit fields to bigint's in the temporary table.
|
||||
Needed as we cannot compare two table records containing BIT fields
|
||||
stored in the the tree used for distinct/order by.
|
||||
Moreover we don't even save in the tree record null bits
|
||||
where BIT fields store parts of their data.
|
||||
*/
|
||||
List_iterator_fast<Item> li(all_fields);
|
||||
Item *item;
|
||||
while ((item= li++))
|
||||
{
|
||||
if (item->type() == Item::FIELD_ITEM &&
|
||||
((Item_field*) item)->field->type() == FIELD_TYPE_BIT)
|
||||
item->marker= 4;
|
||||
}
|
||||
store_bit_fields_as_bigint_in_tempory_table(&all_fields);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -8794,21 +8794,21 @@ bool st_select_lex::collect_grouping_fields(THD *thd)
|
||||
condition over the grouping fields of this select. The method uses
|
||||
the call-back parameter checker to check whether a primary formula
|
||||
depends only on grouping fields.
|
||||
The subformulas that are not usable are marked with the flag NO_EXTRACTION_FL.
|
||||
The subformulas that are not usable are marked with the flag MARKER_NO_EXTRACTION.
|
||||
The subformulas that can be entierly extracted are marked with the flag
|
||||
FULL_EXTRACTION_FL.
|
||||
MARKER_FULL_EXTRACTION.
|
||||
@note
|
||||
This method is called before any call of extract_cond_for_grouping_fields.
|
||||
The flag NO_EXTRACTION_FL set in a subformula allows to avoid building clone
|
||||
The flag MARKER_NO_EXTRACTION set in a subformula allows to avoid building clone
|
||||
for the subformula when extracting the pushable condition.
|
||||
The flag FULL_EXTRACTION_FL allows to delete later all top level conjuncts
|
||||
The flag MARKER_FULL_EXTRACTION allows to delete later all top level conjuncts
|
||||
from cond.
|
||||
*/
|
||||
|
||||
void
|
||||
st_select_lex::check_cond_extraction_for_grouping_fields(THD *thd, Item *cond)
|
||||
{
|
||||
if (cond->get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
if (cond->get_extraction_flag() == MARKER_NO_EXTRACTION)
|
||||
return;
|
||||
cond->clear_extraction_flag();
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
@ -8819,26 +8819,26 @@ st_select_lex::check_cond_extraction_for_grouping_fields(THD *thd, Item *cond)
|
||||
|
||||
List<Item> *arg_list= ((Item_cond*) cond)->argument_list();
|
||||
List_iterator<Item> li(*arg_list);
|
||||
uint count= 0; // to count items not containing NO_EXTRACTION_FL
|
||||
uint count_full= 0; // to count items with FULL_EXTRACTION_FL
|
||||
uint count= 0; // to count items not containing MARKER_NO_EXTRACTION
|
||||
uint count_full= 0; // to count items with MARKER_FULL_EXTRACTION
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
check_cond_extraction_for_grouping_fields(thd, item);
|
||||
if (item->get_extraction_flag() != NO_EXTRACTION_FL)
|
||||
if (item->get_extraction_flag() != MARKER_NO_EXTRACTION)
|
||||
{
|
||||
count++;
|
||||
if (item->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
if (item->get_extraction_flag() == MARKER_FULL_EXTRACTION)
|
||||
count_full++;
|
||||
}
|
||||
else if (!and_cond)
|
||||
break;
|
||||
}
|
||||
if ((and_cond && count == 0) || item)
|
||||
cond->set_extraction_flag(NO_EXTRACTION_FL);
|
||||
cond->set_extraction_flag(MARKER_NO_EXTRACTION);
|
||||
if (count_full == arg_list->elements)
|
||||
{
|
||||
cond->set_extraction_flag(FULL_EXTRACTION_FL);
|
||||
cond->set_extraction_flag(MARKER_FULL_EXTRACTION);
|
||||
}
|
||||
if (cond->get_extraction_flag() != 0)
|
||||
{
|
||||
@ -8850,7 +8850,7 @@ st_select_lex::check_cond_extraction_for_grouping_fields(THD *thd, Item *cond)
|
||||
else
|
||||
{
|
||||
int fl= cond->excl_dep_on_grouping_fields(this) && !cond->is_expensive() ?
|
||||
FULL_EXTRACTION_FL : NO_EXTRACTION_FL;
|
||||
MARKER_FULL_EXTRACTION : MARKER_NO_EXTRACTION;
|
||||
cond->set_extraction_flag(fl);
|
||||
}
|
||||
}
|
||||
@ -8870,7 +8870,7 @@ st_select_lex::check_cond_extraction_for_grouping_fields(THD *thd, Item *cond)
|
||||
For the given condition cond this method finds out what condition depended
|
||||
only on the grouping fields can be extracted from cond. If such condition C
|
||||
exists the method builds the item for it.
|
||||
This method uses the flags NO_EXTRACTION_FL and FULL_EXTRACTION_FL set by the
|
||||
This method uses the flags MARKER_NO_EXTRACTION and MARKER_FULL_EXTRACTION set by the
|
||||
preliminary call of st_select_lex::check_cond_extraction_for_grouping_fields
|
||||
to figure out whether a subformula depends only on these fields or not.
|
||||
@note
|
||||
@ -8890,7 +8890,7 @@ st_select_lex::check_cond_extraction_for_grouping_fields(THD *thd, Item *cond)
|
||||
Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond,
|
||||
bool no_top_clones)
|
||||
{
|
||||
if (cond->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
if (cond->get_extraction_flag() == MARKER_FULL_EXTRACTION)
|
||||
{
|
||||
if (no_top_clones)
|
||||
return cond;
|
||||
@ -8914,7 +8914,7 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond,
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
if (item->get_extraction_flag() == MARKER_NO_EXTRACTION)
|
||||
{
|
||||
DBUG_ASSERT(cond_and);
|
||||
item->clear_extraction_flag();
|
||||
@ -10646,7 +10646,7 @@ void st_select_lex::pushdown_cond_into_where_clause(THD *thd, Item *cond,
|
||||
This will cause duplicate conditions in WHERE of dt.
|
||||
|
||||
To avoid repeatable pushdown such OR conditions as or1 describen
|
||||
above are marked with NO_EXTRACTION_FL.
|
||||
above are marked with MARKER_NO_EXTRACTION.
|
||||
|
||||
@note
|
||||
This method is called for pushdown into materialized
|
||||
@ -10664,12 +10664,12 @@ void mark_or_conds_to_avoid_pushdown(Item *cond)
|
||||
{
|
||||
if (item->type() == Item::COND_ITEM &&
|
||||
((Item_cond*) item)->functype() == Item_func::COND_OR_FUNC)
|
||||
item->set_extraction_flag(NO_EXTRACTION_FL);
|
||||
item->set_extraction_flag(MARKER_NO_EXTRACTION);
|
||||
}
|
||||
}
|
||||
else if (cond->type() == Item::COND_ITEM &&
|
||||
((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
|
||||
cond->set_extraction_flag(NO_EXTRACTION_FL);
|
||||
cond->set_extraction_flag(MARKER_NO_EXTRACTION);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -10683,16 +10683,16 @@ void mark_or_conds_to_avoid_pushdown(Item *cond)
|
||||
The method collects in attach_to_conds list conditions from cond
|
||||
that can be pushed from HAVING into WHERE.
|
||||
|
||||
Conditions that can be pushed were marked with FULL_EXTRACTION_FL in
|
||||
Conditions that can be pushed were marked with MARKER_FULL_EXTRACTION in
|
||||
check_cond_extraction_for_grouping_fields() method.
|
||||
Conditions that can't be pushed were marked with NO_EXTRACTION_FL.
|
||||
Conditions that can't be pushed were marked with MARKER_NO_EXTRACTION.
|
||||
Conditions which parts can be pushed weren't marked.
|
||||
|
||||
There are two types of conditions that can be pushed:
|
||||
1. Condition that can be simply moved from HAVING
|
||||
(if cond is marked with FULL_EXTRACTION_FL or
|
||||
(if cond is marked with MARKER_FULL_EXTRACTION or
|
||||
cond is an AND condition and some of its parts are marked with
|
||||
FULL_EXTRACTION_FL)
|
||||
MARKER_FULL_EXTRACTION)
|
||||
In this case condition is transformed and pushed into attach_to_conds
|
||||
list.
|
||||
2. Part of some other condition c1 that can't be entirely pushed
|
||||
@ -10731,14 +10731,14 @@ st_select_lex::build_pushable_cond_for_having_pushdown(THD *thd, Item *cond)
|
||||
List<Item> equalities;
|
||||
|
||||
/* Condition can't be pushed */
|
||||
if (cond->get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
if (cond->get_extraction_flag() == MARKER_NO_EXTRACTION)
|
||||
return false;
|
||||
|
||||
/**
|
||||
Condition can be pushed entirely.
|
||||
Transform its multiple equalities and add to attach_to_conds list.
|
||||
*/
|
||||
if (cond->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
if (cond->get_extraction_flag() == MARKER_FULL_EXTRACTION)
|
||||
{
|
||||
Item *result= cond->transform(thd,
|
||||
&Item::multiple_equality_transformer,
|
||||
@ -10789,9 +10789,9 @@ st_select_lex::build_pushable_cond_for_having_pushdown(THD *thd, Item *cond)
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
if (item->get_extraction_flag() == MARKER_NO_EXTRACTION)
|
||||
continue;
|
||||
else if (item->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
else if (item->get_extraction_flag() == MARKER_FULL_EXTRACTION)
|
||||
{
|
||||
Item *result= item->transform(thd,
|
||||
&Item::multiple_equality_transformer,
|
||||
@ -10924,13 +10924,13 @@ bool st_select_lex::collect_fields_equal_to_grouping(THD *thd)
|
||||
Item *remove_pushed_top_conjuncts_for_having(THD *thd, Item *cond)
|
||||
{
|
||||
/* Nothing to extract */
|
||||
if (cond->get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
if (cond->get_extraction_flag() == MARKER_NO_EXTRACTION)
|
||||
{
|
||||
cond->clear_extraction_flag();
|
||||
return cond;
|
||||
}
|
||||
/* cond can be pushed in WHERE entirely */
|
||||
if (cond->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
if (cond->get_extraction_flag() == MARKER_FULL_EXTRACTION)
|
||||
{
|
||||
cond->clear_extraction_flag();
|
||||
return 0;
|
||||
@ -10944,13 +10944,13 @@ Item *remove_pushed_top_conjuncts_for_having(THD *thd, Item *cond)
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->get_extraction_flag() == NO_EXTRACTION_FL)
|
||||
if (item->get_extraction_flag() == MARKER_NO_EXTRACTION)
|
||||
item->clear_extraction_flag();
|
||||
else if (item->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
else if (item->get_extraction_flag() == MARKER_FULL_EXTRACTION)
|
||||
{
|
||||
if (item->type() == Item::FUNC_ITEM &&
|
||||
((Item_func*) item)->functype() == Item_func::MULT_EQUAL_FUNC)
|
||||
item->set_extraction_flag(DELETION_FL);
|
||||
item->set_extraction_flag(MARKER_DELETION);
|
||||
else
|
||||
{
|
||||
item->clear_extraction_flag();
|
||||
@ -11019,7 +11019,7 @@ Item *remove_pushed_top_conjuncts_for_having(THD *thd, Item *cond)
|
||||
the condition is put into attach_to_conds as the only its element.
|
||||
4. Remove conditions from HAVING clause that can be entirely pushed
|
||||
into WHERE.
|
||||
Multiple equalities are not removed but marked with DELETION_FL flag.
|
||||
Multiple equalities are not removed but marked with MARKER_DELETION flag.
|
||||
They will be deleted later in substitite_for_best_equal_field() called
|
||||
for the HAVING condition.
|
||||
5. Unwrap fields wrapped in Item_ref wrappers contained in the condition
|
||||
@ -11073,7 +11073,7 @@ Item *st_select_lex::pushdown_from_having_into_where(THD *thd, Item *having)
|
||||
/*
|
||||
4. Remove conditions from HAVING clause that can be entirely pushed
|
||||
into WHERE.
|
||||
Multiple equalities are not removed but marked with DELETION_FL flag.
|
||||
Multiple equalities are not removed but marked with MARKER_DELETION flag.
|
||||
They will be deleted later in substitite_for_best_equal_field() called
|
||||
for the HAVING condition.
|
||||
*/
|
||||
|
@ -16252,7 +16252,7 @@ static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
|
||||
bool all_deleted= true;
|
||||
while ((item_equal= it++))
|
||||
{
|
||||
if (item_equal->get_extraction_flag() == DELETION_FL)
|
||||
if (item_equal->get_extraction_flag() == MARKER_DELETION)
|
||||
continue;
|
||||
all_deleted= false;
|
||||
eq_cond= eliminate_item_equal(thd, eq_cond, cond_equal->upper_levels,
|
||||
@ -16312,7 +16312,7 @@ static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
|
||||
cond_equal= item_equal->upper_levels;
|
||||
if (cond_equal && cond_equal->current_level.head() == item_equal)
|
||||
cond_equal= cond_equal->upper_levels;
|
||||
if (item_equal->get_extraction_flag() == DELETION_FL)
|
||||
if (item_equal->get_extraction_flag() == MARKER_DELETION)
|
||||
return 0;
|
||||
cond= eliminate_item_equal(thd, 0, cond_equal, item_equal);
|
||||
return cond ? cond : org_cond;
|
||||
@ -16482,7 +16482,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
|
||||
if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
|
||||
&& and_father != cond && !left_item->const_item())
|
||||
{
|
||||
cond->marker=1;
|
||||
cond->marker= MARKER_CHANGE_COND;
|
||||
COND_CMP *tmp2;
|
||||
/* Will work, even if malloc would fail */
|
||||
if ((tmp2= new (thd->mem_root) COND_CMP(and_father, func)))
|
||||
@ -16515,7 +16515,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
|
||||
{
|
||||
args[0]= args[1]; // For easy check
|
||||
thd->change_item_tree(args + 1, value);
|
||||
cond->marker=1;
|
||||
cond->marker= MARKER_CHANGE_COND;
|
||||
COND_CMP *tmp2;
|
||||
/* Will work, even if malloc would fail */
|
||||
if ((tmp2=new (thd->mem_root) COND_CMP(and_father, func)))
|
||||
@ -16557,7 +16557,7 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (and_father != cond && !cond->marker) // In a AND group
|
||||
else if (and_father != cond && cond->marker == MARKER_UNUSED) // In a AND group
|
||||
{
|
||||
if (cond->type() == Item::FUNC_ITEM &&
|
||||
(((Item_func*) cond)->functype() == Item_func::EQ_FUNC ||
|
||||
@ -18660,7 +18660,7 @@ TABLE *Create_tmp_table::start(THD *thd,
|
||||
- convert BIT fields to 64-bit long, needed because MEMORY tables
|
||||
can't index BIT fields.
|
||||
*/
|
||||
(*tmp->item)->marker=4; // Store null in key
|
||||
(*tmp->item)->marker= MARKER_NULL_KEY; // Store null in key
|
||||
if ((*tmp->item)->too_big_for_varchar())
|
||||
m_using_unique_constraint= true;
|
||||
}
|
||||
@ -18897,13 +18897,15 @@ bool Create_tmp_table::add_fields(THD *thd,
|
||||
!param->force_copy_fields &&
|
||||
(not_all_columns || m_group !=0),
|
||||
/*
|
||||
If item->marker == 4 then we force create_tmp_field
|
||||
to create a 64-bit longs for BIT fields because HEAP
|
||||
tables can't index BIT fields directly. We do the
|
||||
same for distinct, as we want the distinct index
|
||||
to be usable in this case too.
|
||||
If item->marker == MARKER_NULL_KEY then we
|
||||
force create_tmp_field to create a 64-bit
|
||||
longs for BIT fields because HEAP tables
|
||||
can't index BIT fields directly. We do the
|
||||
same for distinct, as we want the distinct
|
||||
index to be usable in this case too.
|
||||
*/
|
||||
item->marker == 4 || param->bit_fields_as_long,
|
||||
item->marker == MARKER_NULL_KEY ||
|
||||
param->bit_fields_as_long,
|
||||
param->force_copy_fields);
|
||||
if (!new_field)
|
||||
{
|
||||
@ -18943,7 +18945,7 @@ bool Create_tmp_table::add_fields(THD *thd,
|
||||
m_field_count[current_counter]++;
|
||||
m_uneven_bit[current_counter]+= (m_uneven_bit_length - uneven_delta);
|
||||
|
||||
if (item->marker == 4 && item->maybe_null())
|
||||
if (item->marker == MARKER_NULL_KEY && item->maybe_null())
|
||||
{
|
||||
m_group_null_items++;
|
||||
new_field->flags|= GROUP_FLAG;
|
||||
@ -23014,11 +23016,11 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
|
||||
table_count times, we mark each item that we have examined with the result
|
||||
of the test
|
||||
*/
|
||||
if ((cond->marker == 3 && !retain_ref_cond) ||
|
||||
if ((cond->marker == MARKER_CHECK_ON_READ && !retain_ref_cond) ||
|
||||
(cond->used_tables() & ~tables))
|
||||
return (COND*) 0; // Can't check this yet
|
||||
|
||||
if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
|
||||
if (cond->marker == MARKER_PROCESSED || cond->eq_cmp_result() == Item::COND_OK)
|
||||
{
|
||||
cond->set_join_tab_idx((uint8) join_tab_idx_arg);
|
||||
return cond; // Not boolean op
|
||||
@ -23032,13 +23034,13 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
|
||||
if (left_item->type() == Item::FIELD_ITEM && !retain_ref_cond &&
|
||||
test_if_ref(root_cond, (Item_field*) left_item,right_item))
|
||||
{
|
||||
cond->marker=3; // Checked when read
|
||||
cond->marker= MARKER_CHECK_ON_READ; // Checked when read
|
||||
return (COND*) 0;
|
||||
}
|
||||
if (right_item->type() == Item::FIELD_ITEM && !retain_ref_cond &&
|
||||
test_if_ref(root_cond, (Item_field*) right_item,left_item))
|
||||
{
|
||||
cond->marker=3; // Checked when read
|
||||
cond->marker= MARKER_CHECK_ON_READ; // Checked when read
|
||||
return (COND*) 0;
|
||||
}
|
||||
/*
|
||||
@ -23053,11 +23055,11 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
|
||||
(!retain_ref_cond ||
|
||||
!test_if_ref(root_cond, (Item_field*) left_item,right_item)))
|
||||
{
|
||||
cond->marker=3;
|
||||
cond->marker= MARKER_CHECK_ON_READ;
|
||||
return (COND*) 0;
|
||||
}
|
||||
}
|
||||
cond->marker=2;
|
||||
cond->marker= MARKER_PROCESSED;
|
||||
cond->set_join_tab_idx((uint8) join_tab_idx_arg);
|
||||
return cond;
|
||||
}
|
||||
@ -23155,9 +23157,10 @@ make_cond_after_sjm(THD *thd, Item *root_cond, Item *cond, table_map tables,
|
||||
of the test
|
||||
*/
|
||||
|
||||
if (cond->marker == 3 || (cond->used_tables() & ~(tables | sjm_tables)))
|
||||
if (cond->marker == MARKER_CHECK_ON_READ ||
|
||||
(cond->used_tables() & ~(tables | sjm_tables)))
|
||||
return (COND*) 0; // Can't check this yet
|
||||
if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
|
||||
if (cond->marker == MARKER_PROCESSED || cond->eq_cmp_result() == Item::COND_OK)
|
||||
return cond; // Not boolean op
|
||||
|
||||
/*
|
||||
@ -23171,17 +23174,17 @@ make_cond_after_sjm(THD *thd, Item *root_cond, Item *cond, table_map tables,
|
||||
if (left_item->type() == Item::FIELD_ITEM &&
|
||||
test_if_ref(root_cond, (Item_field*) left_item,right_item))
|
||||
{
|
||||
cond->marker=3; // Checked when read
|
||||
cond->marker= MARKER_CHECK_ON_READ;
|
||||
return (COND*) 0;
|
||||
}
|
||||
if (right_item->type() == Item::FIELD_ITEM &&
|
||||
test_if_ref(root_cond, (Item_field*) right_item,left_item))
|
||||
{
|
||||
cond->marker=3; // Checked when read
|
||||
cond->marker= MARKER_CHECK_ON_READ;
|
||||
return (COND*) 0;
|
||||
}
|
||||
}
|
||||
cond->marker=2;
|
||||
cond->marker= MARKER_PROCESSED;
|
||||
return cond;
|
||||
}
|
||||
|
||||
@ -25003,7 +25006,7 @@ setup_group(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
|
||||
if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
|
||||
all_fields, true, true, from_window_spec))
|
||||
return 1;
|
||||
(*ord->item)->marker= UNDEF_POS; /* Mark found */
|
||||
(*ord->item)->marker= MARKER_UNDEF_POS; /* Mark found */
|
||||
if ((*ord->item)->with_sum_func() && context_analysis_place == IN_GROUP_BY)
|
||||
{
|
||||
my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*ord->item)->full_name());
|
||||
@ -25039,6 +25042,9 @@ setup_group(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
|
||||
we throw an error. If there are no fields in the created list for a
|
||||
select list expression this means that all fields in it are used under
|
||||
aggregate functions.
|
||||
|
||||
Note that for items in the select list (fields), Item_field->markers
|
||||
contains the position of the field in the select list.
|
||||
*/
|
||||
Item *item;
|
||||
Item_field *field;
|
||||
@ -25049,7 +25055,8 @@ setup_group(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
|
||||
field= naf_it++;
|
||||
while (field && (item=li++))
|
||||
{
|
||||
if (item->type() != Item::SUM_FUNC_ITEM && item->marker >= 0 &&
|
||||
if (item->type() != Item::SUM_FUNC_ITEM &&
|
||||
item->marker != MARKER_UNDEF_POS &&
|
||||
!item->const_item() &&
|
||||
!(item->real_item()->type() == Item::FIELD_ITEM &&
|
||||
item->used_tables() & OUTER_REF_TABLE_BIT))
|
||||
@ -25146,7 +25153,7 @@ create_distinct_group(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
|
||||
*all_order_by_fields_used= 1;
|
||||
while ((item=li++))
|
||||
item->marker=0; /* Marker that field is not used */
|
||||
item->marker= MARKER_UNUSED; /* Marker that field is not used */
|
||||
|
||||
prev= &group; group=0;
|
||||
for (order=order_list ; order; order=order->next)
|
||||
@ -25158,7 +25165,7 @@ create_distinct_group(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
return 0;
|
||||
*prev=ord;
|
||||
prev= &ord->next;
|
||||
(*ord->item)->marker=1;
|
||||
(*ord->item)->marker= MARKER_FOUND_IN_ORDER;
|
||||
}
|
||||
else
|
||||
*all_order_by_fields_used= 0;
|
||||
@ -25167,7 +25174,8 @@ create_distinct_group(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
li.rewind();
|
||||
while ((item=li++))
|
||||
{
|
||||
if (!item->const_item() && !item->with_sum_func() && !item->marker)
|
||||
if (!item->const_item() && !item->with_sum_func() &&
|
||||
item->marker == MARKER_UNUSED)
|
||||
{
|
||||
/*
|
||||
Don't put duplicate columns from the SELECT list into the
|
||||
@ -29416,7 +29424,7 @@ AGGR_OP::end_send()
|
||||
|
||||
@details
|
||||
The function removes all top conjuncts marked with the flag
|
||||
FULL_EXTRACTION_FL from the condition 'cond'. The resulting
|
||||
MARKER_FULL_EXTRACTION from the condition 'cond'. The resulting
|
||||
formula is returned a the result of the function
|
||||
If 'cond' s marked with such flag the function returns 0.
|
||||
The function clear the extraction flags for the removed
|
||||
@ -29429,7 +29437,7 @@ AGGR_OP::end_send()
|
||||
|
||||
Item *remove_pushed_top_conjuncts(THD *thd, Item *cond)
|
||||
{
|
||||
if (cond->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
if (cond->get_extraction_flag() == MARKER_FULL_EXTRACTION)
|
||||
{
|
||||
cond->clear_extraction_flag();
|
||||
return 0;
|
||||
@ -29442,7 +29450,7 @@ Item *remove_pushed_top_conjuncts(THD *thd, Item *cond)
|
||||
Item *item;
|
||||
while ((item= li++))
|
||||
{
|
||||
if (item->get_extraction_flag() == FULL_EXTRACTION_FL)
|
||||
if (item->get_extraction_flag() == MARKER_FULL_EXTRACTION)
|
||||
{
|
||||
item->clear_extraction_flag();
|
||||
li.remove();
|
||||
|
@ -640,10 +640,6 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1,
|
||||
}
|
||||
|
||||
|
||||
#define SORTORDER_CHANGE_FLAG 1
|
||||
#define PARTITION_CHANGE_FLAG 2
|
||||
#define FRAME_CHANGE_FLAG 4
|
||||
|
||||
typedef int (*Item_window_func_cmp)(Item_window_func *f1,
|
||||
Item_window_func *f2,
|
||||
void *arg);
|
||||
@ -673,15 +669,15 @@ void order_window_funcs_by_window_specs(List<Item_window_func> *win_func_list)
|
||||
|
||||
List_iterator_fast<Item_window_func> it(*win_func_list);
|
||||
Item_window_func *prev= it++;
|
||||
prev->marker= SORTORDER_CHANGE_FLAG |
|
||||
PARTITION_CHANGE_FLAG |
|
||||
FRAME_CHANGE_FLAG;
|
||||
prev->marker= (MARKER_SORTORDER_CHANGE |
|
||||
MARKER_PARTITION_CHANGE |
|
||||
MARKER_FRAME_CHANGE);
|
||||
Item_window_func *curr;
|
||||
while ((curr= it++))
|
||||
{
|
||||
Window_spec *win_spec_prev= prev->window_spec;
|
||||
Window_spec *win_spec_curr= curr->window_spec;
|
||||
curr->marker= 0;
|
||||
curr->marker= MARKER_UNUSED;
|
||||
if (!(win_spec_prev->partition_list == win_spec_curr->partition_list &&
|
||||
win_spec_prev->order_list == win_spec_curr->order_list))
|
||||
{
|
||||
@ -693,17 +689,17 @@ void order_window_funcs_by_window_specs(List<Item_window_func> *win_func_list)
|
||||
cmp= compare_window_spec_joined_lists(win_spec_prev, win_spec_curr);
|
||||
if (!(CMP_LT_C <= cmp && cmp <= CMP_GT_C))
|
||||
{
|
||||
curr->marker= SORTORDER_CHANGE_FLAG |
|
||||
PARTITION_CHANGE_FLAG |
|
||||
FRAME_CHANGE_FLAG;
|
||||
curr->marker= (MARKER_SORTORDER_CHANGE |
|
||||
MARKER_PARTITION_CHANGE |
|
||||
MARKER_FRAME_CHANGE);
|
||||
}
|
||||
else if (win_spec_prev->partition_list != win_spec_curr->partition_list)
|
||||
{
|
||||
curr->marker|= PARTITION_CHANGE_FLAG | FRAME_CHANGE_FLAG;
|
||||
curr->marker|= MARKER_PARTITION_CHANGE | MARKER_FRAME_CHANGE;
|
||||
}
|
||||
}
|
||||
else if (win_spec_prev->window_frame != win_spec_curr->window_frame)
|
||||
curr->marker|= FRAME_CHANGE_FLAG;
|
||||
curr->marker|= MARKER_FRAME_CHANGE;
|
||||
|
||||
prev= curr;
|
||||
}
|
||||
@ -3038,11 +3034,11 @@ bool Window_funcs_sort::setup(THD *thd, SQL_SELECT *sel,
|
||||
return true;
|
||||
it++;
|
||||
win_func= it.peek();
|
||||
} while (win_func && !(win_func->marker & SORTORDER_CHANGE_FLAG));
|
||||
} while (win_func && !(win_func->marker & MARKER_SORTORDER_CHANGE));
|
||||
|
||||
/*
|
||||
The sort criteria must be taken from the last win_func in the group of
|
||||
adjacent win_funcs that do not have SORTORDER_CHANGE_FLAG. This is
|
||||
adjacent win_funcs that do not have MARKER_SORTORDER_CHANGE. This is
|
||||
because the sort order must be the most specific sorting criteria defined
|
||||
within the window function group. This ensures that we sort the table
|
||||
in a way that the result is valid for all window functions belonging to
|
||||
|
Loading…
x
Reference in New Issue
Block a user