optimized single value subselect (to be used as row) (SCRUM)
sql/item.h: optimized single value subselect (to be used as row) sql/item_subselect.cc: optimized single value subselect (to be used as row) sql/item_subselect.h: optimized single value subselect (to be used as row) sql/sql_class.cc: optimized single value subselect (to be used as row)
This commit is contained in:
parent
c7182a999c
commit
ea4f406baf
101
sql/item.h
101
sql/item.h
@ -31,12 +31,12 @@ public:
|
||||
static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
|
||||
static void operator delete(void *ptr,size_t size) {} /*lint -e715 */
|
||||
|
||||
enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM,
|
||||
INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM,
|
||||
COPY_STR_ITEM,FIELD_AVG_ITEM, DEFAULT_ITEM,
|
||||
PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM,
|
||||
FIELD_VARIANCE_ITEM,CONST_ITEM,
|
||||
SUBSELECT_ITEM, ROW_ITEM};
|
||||
enum Type {FIELD_ITEM, FUNC_ITEM, SUM_FUNC_ITEM, STRING_ITEM,
|
||||
INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM,
|
||||
COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_ITEM,
|
||||
PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
|
||||
FIELD_VARIANCE_ITEM, CONST_ITEM,
|
||||
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM};
|
||||
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
||||
|
||||
String str_value; /* used to store value */
|
||||
@ -381,7 +381,8 @@ public:
|
||||
name=(char*) str_value.ptr();
|
||||
decimals=NOT_FIXED_DEC;
|
||||
}
|
||||
Item_string(const char *name_par,const char *str,uint length,CHARSET_INFO *cs)
|
||||
Item_string(const char *name_par, const char *str, uint length,
|
||||
CHARSET_INFO *cs)
|
||||
{
|
||||
str_value.set(str,length,cs);
|
||||
max_length=length;
|
||||
@ -392,11 +393,13 @@ public:
|
||||
enum Type type() const { return STRING_ITEM; }
|
||||
double val()
|
||||
{
|
||||
return my_strntod(str_value.charset(),str_value.ptr(),str_value.length(),(char**)NULL);
|
||||
return my_strntod(str_value.charset(), str_value.ptr(),
|
||||
str_value.length(), (char**) 0);
|
||||
}
|
||||
longlong val_int()
|
||||
{
|
||||
return my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),(char**) 0,10);
|
||||
return my_strntoll(str_value.charset(), str_value.ptr(),
|
||||
str_value.length(), (char**) 0, 10);
|
||||
}
|
||||
String *val_str(String*) { return (String*) &str_value; }
|
||||
int save_in_field(Field *field, bool no_conversions);
|
||||
@ -706,6 +709,86 @@ public:
|
||||
bool cmp(void);
|
||||
};
|
||||
|
||||
class Item_cache: public Item
|
||||
{
|
||||
public:
|
||||
virtual void store(Item *)= 0;
|
||||
void set_len_n_dec(uint32 max_len, uint8 dec)
|
||||
{
|
||||
max_length= max_len;
|
||||
decimals= dec;
|
||||
}
|
||||
enum Type type() const { return CACHE_ITEM; }
|
||||
};
|
||||
|
||||
class Item_cache_int: public Item_cache
|
||||
{
|
||||
longlong value;
|
||||
public:
|
||||
Item_cache_int() { fixed= 1; null_value= 1; }
|
||||
|
||||
void store(Item *item)
|
||||
{
|
||||
value= item->val_int_result();
|
||||
null_value= item->null_value;
|
||||
}
|
||||
double val() { return (double) value; }
|
||||
longlong val_int() { return value; }
|
||||
String* val_str(String *str) { str->set(value, thd_charset()); return str; }
|
||||
enum Item_result result_type() const { return INT_RESULT; }
|
||||
};
|
||||
|
||||
class Item_cache_real: public Item_cache
|
||||
{
|
||||
double value;
|
||||
public:
|
||||
Item_cache_real() { fixed= 1; null_value= 1; }
|
||||
|
||||
void store(Item *item)
|
||||
{
|
||||
value= item->val_result();
|
||||
null_value= item->null_value;
|
||||
}
|
||||
double val() { return value; }
|
||||
longlong val_int() { return (longlong) (value+(value > 0 ? 0.5 : -0.5)); }
|
||||
String* val_str(String *str)
|
||||
{
|
||||
str->set(value, decimals, thd_charset());
|
||||
return str;
|
||||
}
|
||||
enum Item_result result_type() const { return REAL_RESULT; }
|
||||
};
|
||||
|
||||
class Item_cache_str: public Item_cache
|
||||
{
|
||||
char buffer[80];
|
||||
String *value;
|
||||
public:
|
||||
Item_cache_str() { fixed= 1; null_value= 1; }
|
||||
|
||||
void store(Item *item)
|
||||
{
|
||||
str_value.set(buffer, sizeof(buffer), item->charset());
|
||||
value= item->str_result(&str_value);
|
||||
// TODO remove if str_value charset have no side effect for now
|
||||
str_value.set_charset(value->charset());
|
||||
null_value= item->null_value;
|
||||
}
|
||||
double val()
|
||||
{
|
||||
return my_strntod(value->charset(), value->ptr(),
|
||||
value->length(), (char**)0);
|
||||
}
|
||||
longlong val_int()
|
||||
{
|
||||
return my_strntoll(value->charset(), value->ptr(),
|
||||
value->length(), (char**) 0, 10);
|
||||
}
|
||||
String* val_str(String *) { return value; }
|
||||
enum Item_result result_type() const { return STRING_RESULT; }
|
||||
CHARSET_INFO *charset() const { return value->charset(); };
|
||||
};
|
||||
|
||||
extern Item_buff *new_Item_buff(Item *item);
|
||||
extern Item_result item_cmp_type(Item_result a,Item_result b);
|
||||
extern Item *resolve_const_item(Item *item,Item *cmp_item);
|
||||
|
@ -124,7 +124,7 @@ inline table_map Item_subselect::used_tables() const
|
||||
|
||||
Item_singleval_subselect::Item_singleval_subselect(THD *thd,
|
||||
st_select_lex *select_lex):
|
||||
Item_subselect()
|
||||
Item_subselect(), value(0)
|
||||
{
|
||||
DBUG_ENTER("Item_singleval_subselect::Item_singleval_subselect");
|
||||
init(thd, select_lex, new select_singleval_subselect(this));
|
||||
@ -133,10 +133,43 @@ Item_singleval_subselect::Item_singleval_subselect(THD *thd,
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void Item_singleval_subselect::reset()
|
||||
{
|
||||
null_value= 1;
|
||||
if (value)
|
||||
value->null_value= 1;
|
||||
}
|
||||
|
||||
void Item_singleval_subselect::store(Item *item)
|
||||
{
|
||||
value->store(item);
|
||||
}
|
||||
|
||||
enum Item_result Item_singleval_subselect::result_type() const
|
||||
{
|
||||
return engine->type();
|
||||
}
|
||||
|
||||
void Item_singleval_subselect::fix_length_and_dec()
|
||||
{
|
||||
engine->fix_length_and_dec();
|
||||
res_type= engine->type();
|
||||
switch (engine->type())
|
||||
{
|
||||
case INT_RESULT:
|
||||
value= new Item_cache_int();
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
value= new Item_cache_real();
|
||||
break;
|
||||
case STRING_RESULT:
|
||||
value= new Item_cache_str();
|
||||
break;
|
||||
default:
|
||||
// should never be in real life
|
||||
DBUG_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
value->set_len_n_dec(max_length, decimals);
|
||||
}
|
||||
|
||||
Item::Type Item_subselect::type() const
|
||||
@ -146,32 +179,44 @@ Item::Type Item_subselect::type() const
|
||||
|
||||
double Item_singleval_subselect::val ()
|
||||
{
|
||||
if (engine->exec())
|
||||
if (!engine->exec() && !value->null_value)
|
||||
{
|
||||
null_value= 0;
|
||||
return value->val();
|
||||
}
|
||||
else
|
||||
{
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
return real_value;
|
||||
}
|
||||
|
||||
longlong Item_singleval_subselect::val_int ()
|
||||
{
|
||||
if (engine->exec())
|
||||
if (!engine->exec() && !value->null_value)
|
||||
{
|
||||
null_value= 0;
|
||||
return value->val_int();
|
||||
}
|
||||
else
|
||||
{
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
return int_value;
|
||||
}
|
||||
|
||||
String *Item_singleval_subselect::val_str (String *str)
|
||||
{
|
||||
if (engine->exec() || null_value)
|
||||
if (!engine->exec() && !value->null_value)
|
||||
{
|
||||
null_value= 0;
|
||||
return value->val_str(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
return &string_value;
|
||||
}
|
||||
|
||||
Item_exists_subselect::Item_exists_subselect(THD *thd,
|
||||
|
@ -90,44 +90,28 @@ public:
|
||||
|
||||
/* single value subselect */
|
||||
|
||||
class Item_cache;
|
||||
class Item_singleval_subselect :public Item_subselect
|
||||
{
|
||||
protected:
|
||||
longlong int_value; /* Here stored integer value of this item */
|
||||
double real_value; /* Here stored real value of this item */
|
||||
/*
|
||||
Here stored string value of this item.
|
||||
(str_value used only as temporary buffer, because it can be changed
|
||||
by Item::save_field)
|
||||
*/
|
||||
String string_value;
|
||||
enum Item_result res_type; /* type of results */
|
||||
Item_cache *value;
|
||||
|
||||
public:
|
||||
Item_singleval_subselect(THD *thd, st_select_lex *select_lex);
|
||||
Item_singleval_subselect(Item_singleval_subselect *item):
|
||||
Item_subselect(item)
|
||||
{
|
||||
int_value= item->int_value;
|
||||
real_value= item->real_value;
|
||||
string_value.set(item->string_value, 0, item->string_value.length());
|
||||
value= item->value;
|
||||
max_length= item->max_length;
|
||||
decimals= item->decimals;
|
||||
res_type= item->res_type;
|
||||
}
|
||||
virtual void reset()
|
||||
{
|
||||
null_value= 1;
|
||||
int_value= 0;
|
||||
real_value= 0;
|
||||
max_length= 4;
|
||||
res_type= STRING_RESULT;
|
||||
}
|
||||
double val ();
|
||||
void reset();
|
||||
void store(Item* item);
|
||||
double val();
|
||||
longlong val_int ();
|
||||
String *val_str (String *);
|
||||
Item *new_item() { return new Item_singleval_subselect(this); }
|
||||
enum Item_result result_type() const { return res_type; }
|
||||
enum Item_result result_type() const;
|
||||
void fix_length_and_dec();
|
||||
|
||||
friend class select_singleval_subselect;
|
||||
@ -149,7 +133,7 @@ public:
|
||||
}
|
||||
Item_exists_subselect(): Item_subselect() {}
|
||||
|
||||
virtual void reset()
|
||||
void reset()
|
||||
{
|
||||
value= 0;
|
||||
}
|
||||
|
@ -932,31 +932,7 @@ bool select_singleval_subselect::send_data(List<Item> &items)
|
||||
}
|
||||
List_iterator_fast<Item> li(items);
|
||||
Item *val_item= li++; // Only one (single value subselect)
|
||||
/*
|
||||
Following val() call have to be first, because function AVG() & STD()
|
||||
calculate value on it & determinate "is it NULL?".
|
||||
*/
|
||||
it->real_value= val_item->val_result();
|
||||
if ((it->null_value= val_item->null_value))
|
||||
{
|
||||
it->reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
it->max_length= val_item->max_length;
|
||||
it->decimals= val_item->decimals;
|
||||
it->set_charset(val_item->charset());
|
||||
it->int_value= val_item->val_int_result();
|
||||
String *s= val_item->str_result(&it->string_value);
|
||||
if (s != &it->string_value)
|
||||
{
|
||||
it->string_value.set(*s, 0, s->length());
|
||||
}
|
||||
// TODO: remove when correct charset handling appeared for Item
|
||||
it->str_value.set(*s, 0, s->length()); // store charset
|
||||
|
||||
it->res_type= val_item->result_type();
|
||||
}
|
||||
it->store(val_item);
|
||||
it->assigned(1);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user