MWL#17: Table elimination
Address review feedback: - Change from Wave-based approach (a-la const table detection) to building and walking functional dependency graph. - Change from piggy-backing on ref-access code and KEYUSE structures to using our own expression analyzer. sql/item.cc: MWL#17: Table elimination - Move from C-ish Field_processor_info to C++ ish and generic Field_enumerator sql/item.h: MWL#17: Table elimination - Move from C-ish Field_processor_info to C++ ish and generic Field_enumerator sql/sql_bitmap.h: MWL#17: Table elimination - Backport of Table_map_iterator from 6.0
This commit is contained in:
parent
5ecad03df9
commit
854bb82bd8
26
sql/item.cc
26
sql/item.cc
@ -1918,30 +1918,8 @@ void Item_field::reset_field(Field *f)
|
||||
|
||||
bool Item_field::check_column_usage_processor(uchar *arg)
|
||||
{
|
||||
Field_processor_info* info=(Field_processor_info*)arg;
|
||||
|
||||
if (field->table == info->table)
|
||||
{
|
||||
/* It is not ok to use columns that are not part of the key of interest: */
|
||||
if (!(field->part_of_key.is_set(info->keyno)))
|
||||
return TRUE;
|
||||
|
||||
/* Find which key part we're using and mark it in needed_key_parts */
|
||||
KEY *key= &field->table->key_info[info->keyno];
|
||||
for (uint part= 0; part < key->key_parts; part++)
|
||||
{
|
||||
if (field->field_index == key->key_part[part].field->field_index)
|
||||
{
|
||||
if (part == info->forbidden_part)
|
||||
return TRUE;
|
||||
info->needed_key_parts |= key_part_map(1) << part;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
info->used_tables |= this->used_tables();
|
||||
Field_enumerator *fe= (Field_enumerator*)arg;
|
||||
fe->see_field(field);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
10
sql/item.h
10
sql/item.h
@ -1017,7 +1017,7 @@ public:
|
||||
bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
|
||||
};
|
||||
|
||||
/* Data for Item::check_column_usage_processor */
|
||||
#if 0
|
||||
typedef struct
|
||||
{
|
||||
TABLE *table; /* Table of interest */
|
||||
@ -1028,7 +1028,15 @@ typedef struct
|
||||
/* [Set by processor] Parts of index of interest that expression refers to */
|
||||
uint needed_key_parts;
|
||||
} Field_processor_info;
|
||||
#endif
|
||||
|
||||
/* Data for Item::check_column_usage_processor */
|
||||
class Field_enumerator
|
||||
{
|
||||
public:
|
||||
virtual void see_field(Field *field)= 0;
|
||||
virtual ~Field_enumerator() {}; /* Shut up compiler warning */
|
||||
};
|
||||
|
||||
class sp_head;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -93,6 +93,34 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/* An iterator to quickly walk over bits in unlonglong bitmap. */
|
||||
class Table_map_iterator
|
||||
{
|
||||
ulonglong bmp;
|
||||
uint no;
|
||||
public:
|
||||
Table_map_iterator(ulonglong t) : bmp(t), no(0) {}
|
||||
int next_bit()
|
||||
{
|
||||
static const char last_bit[16]= {32, 0, 1, 0,
|
||||
2, 0, 1, 0,
|
||||
3, 0, 1, 0,
|
||||
2, 0, 1, 0};
|
||||
uint bit;
|
||||
while ((bit= last_bit[bmp & 0xF]) == 32)
|
||||
{
|
||||
no += 4;
|
||||
bmp= bmp >> 4;
|
||||
if (!bmp)
|
||||
return BITMAP_END;
|
||||
}
|
||||
bmp &= ~(1LL << bit);
|
||||
return no + bit;
|
||||
}
|
||||
int operator++(int) { return next_bit(); }
|
||||
enum { BITMAP_END= 64 };
|
||||
};
|
||||
|
||||
template <> class Bitmap<64>
|
||||
{
|
||||
ulonglong map;
|
||||
@ -136,5 +164,10 @@ public:
|
||||
my_bool operator==(const Bitmap<64>& map2) const { return map == map2.map; }
|
||||
char *print(char *buf) const { longlong2str(map,buf,16); return buf; }
|
||||
ulonglong to_ulonglong() const { return map; }
|
||||
class Iterator : public Table_map_iterator
|
||||
{
|
||||
public:
|
||||
Iterator(Bitmap<64> &bmp) : Table_map_iterator(bmp.map) {}
|
||||
};
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user