summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <wax@kishkin.ru>2003-06-03 17:07:46 +0600
committerunknown <wax@kishkin.ru>2003-06-03 17:07:46 +0600
commit284a6abeea27640bf7a726c06c90c5af9db09cf7 (patch)
treef843ad0e54bde2b08179141dbc0431f17a5aefd6 /sql
parent27d95e9687e840c98235a89ff7aea880bb905f44 (diff)
parentfbd157fa5754c5c1dac01ad824531aeb434426d7 (diff)
downloadmariadb-git-284a6abeea27640bf7a726c06c90c5af9db09cf7.tar.gz
Merge kishkin.ru:/home/wax/mysql-4n into kishkin.ru:/home/wax/mysql-4g
sql/field.cc: Auto merged sql/field.h: Auto merged sql/item_sum.cc: Auto merged sql/item_sum.h: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc2
-rw-r--r--sql/field.h1
-rw-r--r--sql/item_sum.cc102
-rw-r--r--sql/item_sum.h29
4 files changed, 82 insertions, 52 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 044684b2675..04859dd22e0 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -183,7 +183,7 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
field_name(field_name_arg),
query_id(0),key_start(0),part_of_key(0),part_of_sortkey(0),
unireg_check(unireg_check_arg),
- field_length(length_arg),null_bit(null_bit_arg)
+ field_length(length_arg),null_bit(null_bit_arg),abs_offset(0)
{
flags=null_ptr ? 0: NOT_NULL_FLAG;
comment.str= (char*) "";
diff --git a/sql/field.h b/sql/field.h
index 4456eb36731..21f2ab4b6e9 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -62,6 +62,7 @@ public:
uint32 field_length; // Length of field
uint16 flags;
uchar null_bit; // Bit used to test null bit
+ uint abs_offset; // use only in group_concat
Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg,
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index fa8bf7e6e0f..e5be3809230 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1351,27 +1351,28 @@ String *Item_sum_udf_str::val_str(String *str)
GROUP_CONCAT(DISTINCT expr,...)
*/
-static int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
- byte* key2)
+int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
+ byte* key2)
{
Item_func_group_concat* item= (Item_func_group_concat*)arg;
+
for (uint i= 0; i < item->arg_count_field; i++)
{
- Item *field_item= item->expr[i];
+ Item *field_item= item->args[i];
Field *field= field_item->tmp_table_field();
if (field)
{
- uint offset= field->offset();
+ uint offset= field->abs_offset;
int res= field->key_cmp(key1 + offset, key2 + offset);
/*
if key1 and key2 is not equal than field->key_cmp return offset. This
- function must return value 1 for this case.
+ function must return value 1 for this case.
*/
if (res)
return 1;
}
- }
+ }
return 0;
}
@@ -1381,9 +1382,10 @@ static int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
GROUP_CONCAT(expr,... ORDER BY col,... )
*/
-static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
+int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
{
Item_func_group_concat* item= (Item_func_group_concat*)arg;
+
for (uint i=0; i < item->arg_count_order; i++)
{
ORDER *order_item= item->order[i];
@@ -1391,14 +1393,14 @@ static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
Field *field= item->tmp_table_field();
if (field)
{
- uint offset= field->offset();
+ uint offset= field->abs_offset;
bool dir= order_item->asc;
int res= field->key_cmp(key1 + offset, key2 + offset);
if (res)
return dir ? res : -res;
}
- }
+ }
/*
We can't return 0 because tree class remove this item as double value.
*/
@@ -1411,9 +1413,8 @@ static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
*/
-static int group_concat_key_cmp_with_distinct_and_order(void* arg,
- byte* key1,
- byte* key2)
+int group_concat_key_cmp_with_distinct_and_order(void* arg,byte* key1,
+ byte* key2)
{
if (!group_concat_key_cmp_with_distinct(arg,key1,key2))
return 0;
@@ -1426,24 +1427,23 @@ static int group_concat_key_cmp_with_distinct_and_order(void* arg,
item is pointer to Item_func_group_concat
*/
-static int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
+int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
Item_func_group_concat *group_concat_item)
{
char buff[MAX_FIELD_WIDTH];
String tmp((char *)&buff,sizeof(buff),default_charset_info);
String tmp2((char *)&buff,sizeof(buff),default_charset_info);
-
+
tmp.length(0);
for (uint i= 0; i < group_concat_item->arg_show_fields; i++)
{
- Item *show_item= group_concat_item->expr[i];
+ Item *show_item= group_concat_item->args[i];
if (!show_item->const_item())
{
Field *f= show_item->tmp_table_field();
- uint offset= f->offset();
char *sv= f->ptr;
- f->ptr= (char *)key + offset;
+ f->ptr= (char *)key + f->abs_offset;
String *res= f->val_str(&tmp,&tmp2);
group_concat_item->result.append(*res);
f->ptr= sv;
@@ -1493,9 +1493,14 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
List<Item> *is_select,
SQL_LIST *is_order,
String *is_separator)
- :Item_sum(), tmp_table_param(0), warning_available(false),
- separator(is_separator), tree(&tree_base), table(0),
- count_cut_values(0), tree_mode(0), distinct(is_distinct)
+ :Item_sum(), tmp_table_param(0), max_elements_in_tree(0), warning(0),
+ warning_available(0), key_length(0), rec_offset(0),
+ tree_mode(0), distinct(is_distinct), warning_for_row(0),
+ separator(is_separator), tree(&tree_base), table(0),
+ order(0), tables_list(0), group_concat_max_len(0),
+ show_elements(0), arg_count_order(0), arg_count_field(0),
+ arg_show_fields(0), count_cut_values(0)
+
{
original= 0;
quick_group= 0;
@@ -1511,16 +1516,12 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
We need to allocate:
args - arg_count+arg_count_order (for possible order items in temporare
tables)
- expr - arg_count_field
order - arg_count_order
*/
- args= (Item**) sql_alloc(sizeof(Item*)*(arg_count+arg_count_order+
- arg_count_field)+
+ args= (Item**) sql_alloc(sizeof(Item*)*(arg_count+arg_count_order)+
sizeof(ORDER*)*arg_count_order);
if (!args)
- return; // thd->fatal is set
- expr= args;
- expr+= arg_count+arg_count_order;
+ return;
/* fill args items of show and sort */
int i= 0;
@@ -1528,12 +1529,12 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
Item *item_select;
for ( ; (item_select= li++) ; i++)
- args[i]= expr[i]= item_select;
+ args[i]= item_select;
if (arg_count_order)
{
i= 0;
- order= (ORDER**)(expr + arg_count_field);
+ order= (ORDER**)(args + arg_count + arg_count_order);
for (ORDER *order_item= (ORDER*) is_order->first;
order_item != NULL;
order_item= order_item->next)
@@ -1588,13 +1589,15 @@ void Item_func_group_concat::reset()
bool Item_func_group_concat::add()
{
+ if (always_null)
+ return 0;
copy_fields(tmp_table_param);
copy_funcs(tmp_table_param->items_to_copy);
bool record_is_null= TRUE;
for (uint i= 0; i < arg_show_fields; i++)
{
- Item *show_item= expr[i];
+ Item *show_item= args[i];
if (!show_item->const_item())
{
Field *f= show_item->tmp_table_field();
@@ -1610,13 +1613,13 @@ bool Item_func_group_concat::add()
null_value= FALSE;
if (tree_mode)
{
- if (!tree_insert(tree, table->record[0], 0,tree->custom_arg))
+ if (!tree_insert(tree, table->record[0] + rec_offset, 0, tree->custom_arg))
return 1;
}
else
{
if (result.length() <= group_concat_max_len && !warning_for_row)
- dump_leaf_key(table->record[0],1,
+ dump_leaf_key(table->record[0] + rec_offset, 1,
(Item_func_group_concat*)this);
}
return 0;
@@ -1649,12 +1652,6 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 1;
maybe_null |= args[i]->maybe_null;
}
- for (i= 0 ; i < arg_count_field ; i++)
- {
- if (expr[i]->fix_fields(thd, tables, expr + i) || expr[i]->check_cols(1))
- return 1;
- maybe_null |= expr[i]->maybe_null;
- }
/*
Fix fields for order clause in function:
GROUP_CONCAT(expr,... ORDER BY col,... )
@@ -1688,6 +1685,7 @@ bool Item_func_group_concat::setup(THD *thd)
/*
all not constant fields are push to list and create temp table
*/
+ always_null= 0;
for (uint i= 0; i < arg_count; i++)
{
Item *item= args[i];
@@ -1700,6 +1698,8 @@ bool Item_func_group_concat::setup(THD *thd)
always_null= 1;
}
}
+ if (always_null)
+ return 0;
List<Item> all_fields(list);
if (arg_count_order)
@@ -1719,12 +1719,25 @@ bool Item_func_group_concat::setup(THD *thd)
return 1;
table->file->extra(HA_EXTRA_NO_ROWS);
table->no_rows= 1;
- qsort_cmp2 compare_key;
-
- tree_mode= distinct || arg_count_order;
+
+
+ Field** field, **field_end;
+ field_end = (field = table->field) + table->fields;
+ uint offset = 0;
+ for (key_length = 0; field < field_end; ++field)
+ {
+ uint32 length= (*field)->pack_length();
+ (*field)->abs_offset= offset;
+ offset+= length;
+ key_length += length;
+ }
+ rec_offset = table->reclength - key_length;
+
/*
choise function of sort
*/
+ tree_mode= distinct || arg_count_order;
+ qsort_cmp2 compare_key;
if (tree_mode)
{
if (arg_count_order)
@@ -1748,9 +1761,9 @@ bool Item_func_group_concat::setup(THD *thd)
*/
init_tree(tree, min(thd->variables.max_heap_table_size,
thd->variables.sortbuff_size/16), 0,
- table->reclength, compare_key, 0, NULL, (void*) this);
- max_elements_in_tree= ((table->reclength) ?
- thd->variables.max_heap_table_size/table->reclength : 1);
+ key_length, compare_key, 0, NULL, (void*) this);
+ max_elements_in_tree= ((key_length) ?
+ thd->variables.max_heap_table_size/key_length : 1);
};
item_thd= thd;
@@ -1791,3 +1804,6 @@ String* Item_func_group_concat::val_str(String* str)
}
return &result;
}
+
+
+
diff --git a/sql/item_sum.h b/sql/item_sum.h
index f996f980fff..7deec8de564 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -642,13 +642,28 @@ class Item_func_group_concat : public Item_sum
uint max_elements_in_tree;
MYSQL_ERROR *warning;
bool warning_available;
+ uint key_length;
+ int rec_offset;
+ bool tree_mode;
+ bool distinct;
+ bool warning_for_row;
+ bool always_null;
+
+ friend int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
+ byte* key2);
+ friend int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2);
+ friend int group_concat_key_cmp_with_distinct_and_order(void* arg,
+ byte* key1,
+ byte* key2);
+ friend int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
+ Item_func_group_concat *group_concat_item);
+
public:
String result;
String *separator;
TREE tree_base;
TREE *tree;
TABLE *table;
- Item **expr;
ORDER **order;
TABLE_LIST *tables_list;
ulong group_concat_max_len;
@@ -657,9 +672,6 @@ class Item_func_group_concat : public Item_sum
uint arg_count_field;
uint arg_show_fields;
uint count_cut_values;
- bool tree_mode, distinct;
- bool warning_for_row;
- bool always_null;
/*
Following is 0 normal object and pointer to original one for copy
(to correctly free resources)
@@ -675,10 +687,14 @@ class Item_func_group_concat : public Item_sum
max_elements_in_tree(item.max_elements_in_tree),
warning(item.warning),
warning_available(item.warning_available),
+ key_length(item.key_length),
+ rec_offset(item.rec_offset),
+ tree_mode(0),
+ distinct(item.distinct),
+ warning_for_row(item.warning_for_row),
separator(item.separator),
tree(item.tree),
table(item.table),
- expr(item.expr),
order(item.order),
tables_list(item.tables_list),
group_concat_max_len(item.group_concat_max_len),
@@ -687,9 +703,6 @@ class Item_func_group_concat : public Item_sum
arg_count_field(item.arg_count_field),
arg_show_fields(item.arg_show_fields),
count_cut_values(item.count_cut_values),
- tree_mode(0),
- distinct(item.distinct),
- warning_for_row(item.warning_for_row),
original(&item)
{
quick_group = 0;