diff options
author | unknown <wax@kishkin.ru> | 2003-06-03 17:07:46 +0600 |
---|---|---|
committer | unknown <wax@kishkin.ru> | 2003-06-03 17:07:46 +0600 |
commit | 284a6abeea27640bf7a726c06c90c5af9db09cf7 (patch) | |
tree | f843ad0e54bde2b08179141dbc0431f17a5aefd6 /sql | |
parent | 27d95e9687e840c98235a89ff7aea880bb905f44 (diff) | |
parent | fbd157fa5754c5c1dac01ad824531aeb434426d7 (diff) | |
download | mariadb-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.cc | 2 | ||||
-rw-r--r-- | sql/field.h | 1 | ||||
-rw-r--r-- | sql/item_sum.cc | 102 | ||||
-rw-r--r-- | sql/item_sum.h | 29 |
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; |