1
/* Copyright (C) 2000-2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
21
Sum functions (COUNT, MIN...)
23
#include <drizzled/server_includes.h>
24
#include <drizzled/sql_select.h>
25
#include <drizzled/drizzled_error_messages.h>
28
Prepare an aggregate function item for checking context conditions.
30
The function initializes the members of the Item_sum object created
31
for a set function that are used to check validity of the set function
33
If the set function is not allowed in any subquery where it occurs
34
an error is reported immediately.
36
@param thd reference to the thread context info
39
This function is to be called for any item created for a set function
40
object when the traversal of trees built for expressions used in the query
41
is performed at the phase of context analysis. This function is to
42
be invoked at the descent of this traversal.
44
TRUE if an error is reported
49
bool Item_sum::init_sum_func_check(THD *thd)
51
if (!thd->lex->allow_sum_func)
53
my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
57
/* Set a reference to the nesting set function if there is any */
58
in_sum_func= thd->lex->in_sum_func;
59
/* Save a pointer to object to be used in items for nested set functions */
60
thd->lex->in_sum_func= this;
61
nest_level= thd->lex->current_select->nest_level;
66
max_sum_func_level= -1;
72
Check constraints imposed on a usage of a set function.
74
The method verifies whether context conditions imposed on a usage
75
of any set function are met for this occurrence.
76
It checks whether the set function occurs in the position where it
77
can be aggregated and, when it happens to occur in argument of another
78
set function, the method checks that these two functions are aggregated in
80
If the context conditions are not met the method reports an error.
81
If the set function is aggregated in some outer subquery the method
82
adds it to the chain of items for such set functions that is attached
83
to the the st_select_lex structure for this subquery.
85
A number of designated members of the object are used to check the
86
conditions. They are specified in the comment before the Item_sum
88
Additionally a bitmap variable called allow_sum_func is employed.
89
It is included into the thd->lex structure.
90
The bitmap contains 1 at n-th position if the set function happens
91
to occur under a construct of the n-th level subquery where usage
92
of set functions are allowed (i.e either in the SELECT list or
93
in the HAVING clause of the corresponding subquery)
96
SELECT SUM(t1.b) FROM t1 GROUP BY t1.a
97
HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
98
t1.a > (SELECT MIN(t2.d) FROM t2);
100
allow_sum_func will contain:
101
- for SUM(t1.b) - 1 at the first position
102
- for AVG(t1.b) - 1 at the first position, 0 at the second position
103
- for MIN(t2.d) - 1 at the first position, 1 at the second position.
105
@param thd reference to the thread context info
106
@param ref location of the pointer to this item in the embedding expression
109
This function is to be called for any item created for a set function
110
object when the traversal of trees built for expressions used in the query
111
is performed at the phase of context analysis. This function is to
112
be invoked at the ascent of this traversal.
115
TRUE if an error is reported
120
bool Item_sum::check_sum_func(THD *thd, Item **ref)
123
nesting_map allow_sum_func= thd->lex->allow_sum_func;
125
The value of max_arg_level is updated if an argument of the set function
126
contains a column reference resolved against a subquery whose level is
127
greater than the current value of max_arg_level.
128
max_arg_level cannot be greater than nest level.
129
nest level is always >= 0
131
if (nest_level == max_arg_level)
134
The function must be aggregated in the current subquery,
135
If it is there under a construct where it is not allowed
138
invalid= !(allow_sum_func & (1 << max_arg_level));
140
else if (max_arg_level >= 0 || !(allow_sum_func & (1 << nest_level)))
143
The set function can be aggregated only in outer subqueries.
144
Try to find a subquery where it can be aggregated;
145
If we fail to find such a subquery report an error.
147
if (register_sum_func(thd, ref))
149
invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
150
if (!invalid && false)
151
invalid= aggr_level < 0 && max_arg_level < nest_level;
153
if (!invalid && aggr_level < 0)
155
aggr_level= nest_level;
156
aggr_sel= thd->lex->current_select;
159
By this moment we either found a subquery where the set function is
160
to be aggregated and assigned a value that is >= 0 to aggr_level,
161
or set the value of 'invalid' to TRUE to report later an error.
164
Additionally we have to check whether possible nested set functions
165
are acceptable here: they are not, if the level of aggregation of
166
some of them is less than aggr_level.
169
invalid= aggr_level <= max_sum_func_level;
172
my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
180
If the set function is nested adjust the value of
181
max_sum_func_level for the nesting set function.
182
We take into account only enclosed set functions that are to be
183
aggregated on the same level or above of the nest level of
184
the enclosing set function.
185
But we must always pass up the max_sum_func_level because it is
186
the maximum nested level of all directly and indirectly enclosed
187
set functions. We must do that even for set functions that are
188
aggregated inside of their enclosing set function's nest level
189
because the enclosing function may contain another enclosing
190
function that is to be aggregated outside or on the same level
191
as its parent's nest level.
193
if (in_sum_func->nest_level >= aggr_level)
194
set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
195
set_if_bigger(in_sum_func->max_sum_func_level, max_sum_func_level);
199
Check that non-aggregated fields and sum functions aren't mixed in the
200
same select in the ONLY_FULL_GROUP_BY mode.
202
if (outer_fields.elements)
206
Here we compare the nesting level of the select to which an outer field
207
belongs to with the aggregation level of the sum function. All fields in
208
the outer_fields list are checked.
210
If the nesting level is equal to the aggregation level then the field is
211
aggregated by this sum function.
212
If the nesting level is less than the aggregation level then the field
213
belongs to an outer select. In this case if there is an embedding sum
214
function add current field to functions outer_fields list. If there is
215
no embedding function then the current field treated as non aggregated
216
and the select it belongs to is marked accordingly.
217
If the nesting level is greater than the aggregation level then it means
218
that this field was added by an inner sum function.
221
select avg ( <-- we are here, checking outer.f1
223
select sum(outer.f1 + inner.f1) from inner
227
In this case we check that no aggregate functions are used in the
228
select the field belongs to. If there are some then an error is
231
List_iterator<Item_field> of(outer_fields);
232
while ((field= of++))
234
SELECT_LEX *sel= field->cached_table->select_lex;
235
if (sel->nest_level < aggr_level)
240
Let upper function decide whether this field is a non
243
in_sum_func->outer_fields.push_back(field);
246
sel->full_group_by_flag|= NON_AGG_FIELD_USED;
248
if (sel->nest_level > aggr_level &&
249
(sel->full_group_by_flag & SUM_FUNC_USED) &&
250
!sel->group_list.elements)
252
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
253
ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
258
aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
259
update_used_tables();
260
thd->lex->in_sum_func= in_sum_func;
265
Attach a set function to the subquery where it must be aggregated.
267
The function looks for an outer subquery where the set function must be
268
aggregated. If it finds such a subquery then aggr_level is set to
269
the nest level of this subquery and the item for the set function
270
is added to the list of set functions used in nested subqueries
271
inner_sum_func_list defined for each subquery. When the item is placed
272
there the field 'ref_by' is set to ref.
275
Now we 'register' only set functions that are aggregated in outer
276
subqueries. Actually it makes sense to link all set function for
277
a subquery in one chain. It would simplify the process of 'splitting'
280
@param thd reference to the thread context info
281
@param ref location of the pointer to this item in the embedding expression
284
FALSE if the executes without failures (currently always)
289
bool Item_sum::register_sum_func(THD *thd, Item **ref)
292
nesting_map allow_sum_func= thd->lex->allow_sum_func;
293
for (sl= thd->lex->current_select->master_unit()->outer_select() ;
294
sl && sl->nest_level > max_arg_level;
295
sl= sl->master_unit()->outer_select() )
297
if (aggr_level < 0 && (allow_sum_func & (1 << sl->nest_level)))
299
/* Found the most nested subquery where the function can be aggregated */
300
aggr_level= sl->nest_level;
304
if (sl && (allow_sum_func & (1 << sl->nest_level)))
307
We reached the subquery of level max_arg_level and checked
308
that the function can be aggregated here.
309
The set function will be aggregated in this subquery.
311
aggr_level= sl->nest_level;
318
/* Add the object to the list of registered objects assigned to aggr_sel */
319
if (!aggr_sel->inner_sum_func_list)
323
next= aggr_sel->inner_sum_func_list->next;
324
aggr_sel->inner_sum_func_list->next= this;
326
aggr_sel->inner_sum_func_list= this;
327
aggr_sel->with_sum_func= 1;
330
Mark Item_subselect(s) as containing aggregate function all the way up
331
to aggregate function's calculation context.
332
Note that we must not mark the Item of calculation context itself
333
because with_sum_func on the calculation context st_select_lex is
336
with_sum_func being set for an Item means that this Item refers
337
(somewhere in it, e.g. one of its arguments if it's a function) directly
338
or through intermediate items to an aggregate function that is calculated
339
in a context "outside" of the Item (e.g. in the current or outer select).
341
with_sum_func being set for an st_select_lex means that this st_select_lex
342
has aggregate functions directly referenced (i.e. not through a sub-select).
344
for (sl= thd->lex->current_select;
345
sl && sl != aggr_sel && sl->master_unit()->item;
346
sl= sl->master_unit()->outer_select() )
347
sl->master_unit()->item->with_sum_func= 1;
349
thd->lex->current_select->mark_as_dependent(aggr_sel);
354
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
357
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
360
List_iterator_fast<Item> li(list);
369
list.empty(); // Fields are used
374
Constructor used in processing select with temporary tebles.
377
Item_sum::Item_sum(THD *thd, Item_sum *item):
378
Item_result_field(thd, item), arg_count(item->arg_count),
379
aggr_sel(item->aggr_sel),
380
nest_level(item->nest_level), aggr_level(item->aggr_level),
381
quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
382
forced_const(item->forced_const)
387
if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
389
memcpy(args, item->args, sizeof(Item*)*arg_count);
393
void Item_sum::mark_as_sum_func()
395
SELECT_LEX *cur_select= current_thd->lex->current_select;
396
cur_select->n_sum_items++;
397
cur_select->with_sum_func= 1;
402
void Item_sum::make_field(Send_field *tmp_field)
404
if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
406
((Item_field*) args[0])->field->make_field(tmp_field);
407
/* For expressions only col_name should be non-empty string. */
408
char *empty_string= (char*)"";
409
tmp_field->db_name= empty_string;
410
tmp_field->org_table_name= empty_string;
411
tmp_field->table_name= empty_string;
412
tmp_field->org_col_name= empty_string;
413
tmp_field->col_name= name;
415
tmp_field->flags&= ~NOT_NULL_FLAG;
418
init_make_field(tmp_field, field_type());
422
void Item_sum::print(String *str, enum_query_type query_type)
424
str->append(func_name());
425
for (uint32_t i=0 ; i < arg_count ; i++)
429
args[i]->print(str, query_type);
434
void Item_sum::fix_num_length_and_dec()
437
for (uint32_t i=0 ; i < arg_count ; i++)
438
set_if_bigger(decimals,args[i]->decimals);
439
max_length=float_length(decimals);
442
Item *Item_sum::get_tmp_table_item(THD *thd)
444
Item_sum* sum_item= (Item_sum *) copy_or_same(thd);
445
if (sum_item && sum_item->result_field) // If not a const sum func
447
Field *result_field_tmp= sum_item->result_field;
448
for (uint32_t i=0 ; i < sum_item->arg_count ; i++)
450
Item *arg= sum_item->args[i];
451
if (!arg->const_item())
453
if (arg->type() == Item::FIELD_ITEM)
454
((Item_field*) arg)->field= result_field_tmp++;
456
sum_item->args[i]= new Item_field(result_field_tmp++);
464
bool Item_sum::walk (Item_processor processor, bool walk_subquery,
465
unsigned char *argument)
469
Item **arg,**arg_end;
470
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
472
if ((*arg)->walk(processor, walk_subquery, argument))
476
return (this->*processor)(argument);
480
Field *Item_sum::create_tmp_field(bool group __attribute__((unused)),
482
uint32_t convert_blob_length)
485
switch (result_type()) {
487
field= new Field_double(max_length, maybe_null, name, decimals, true);
490
field= new Field_int64_t(max_length, maybe_null, name, unsigned_flag);
493
if (max_length/collation.collation->mbmaxlen <= 255 ||
494
convert_blob_length > Field_varstring::MAX_SIZE ||
495
!convert_blob_length)
496
return make_string_field(table);
497
field= new Field_varstring(convert_blob_length, maybe_null,
498
name, table->s, collation.collation);
501
field= new Field_new_decimal(max_length, maybe_null, name,
502
decimals, unsigned_flag);
506
// This case should never be choosen
516
void Item_sum::update_used_tables ()
520
used_tables_cache= 0;
521
for (uint32_t i=0 ; i < arg_count ; i++)
523
args[i]->update_used_tables();
524
used_tables_cache|= args[i]->used_tables();
527
used_tables_cache&= PSEUDO_TABLE_BITS;
529
/* the aggregate function is aggregated into its local context */
530
used_tables_cache |= (1 << aggr_sel->join->tables) - 1;
536
Item_sum_num::val_str(String *str)
538
return val_string_from_real(str);
542
my_decimal *Item_sum_num::val_decimal(my_decimal *decimal_value)
544
return val_decimal_from_real(decimal_value);
549
Item_sum_int::val_str(String *str)
551
return val_string_from_int(str);
555
my_decimal *Item_sum_int::val_decimal(my_decimal *decimal_value)
557
return val_decimal_from_int(decimal_value);
562
Item_sum_num::fix_fields(THD *thd, Item **ref)
566
if (init_sum_func_check(thd))
571
for (uint32_t i=0 ; i < arg_count ; i++)
573
if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
575
set_if_bigger(decimals, args[i]->decimals);
576
maybe_null |= args[i]->maybe_null;
579
max_length=float_length(decimals);
581
fix_length_and_dec();
583
if (check_sum_func(thd, ref))
591
Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
592
:Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
593
hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
594
was_values(item->was_values)
596
/* copy results from old value */
597
switch (hybrid_type) {
599
sum_int= item->sum_int;
602
my_decimal2decimal(&item->sum_dec, &sum_dec);
609
This can happen with ROLLUP. Note that the value is already
610
copied at function call.
617
collation.set(item->collation);
621
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
627
if (init_sum_func_check(thd))
630
// 'item' can be changed during fix_fields
631
if ((!item->fixed && item->fix_fields(thd, args)) ||
632
(item= args[0])->check_cols(1))
634
decimals=item->decimals;
636
switch (hybrid_type= item->result_type()) {
642
max_length= item->max_length;
643
my_decimal_set_zero(&sum_dec);
646
max_length= float_length(decimals);
650
max_length= item->max_length;
656
/* MIN/MAX can return NULL for empty set indepedent of the used column */
658
unsigned_flag=item->unsigned_flag;
659
collation.set(item->collation);
662
fix_length_and_dec();
663
item= item->real_item();
664
if (item->type() == Item::FIELD_ITEM)
665
hybrid_field_type= ((Item_field*) item)->field->type();
667
hybrid_field_type= Item::field_type();
669
if (check_sum_func(thd, ref))
676
Field *Item_sum_hybrid::create_tmp_field(bool group, Table *table,
677
uint32_t convert_blob_length)
680
if (args[0]->type() == Item::FIELD_ITEM)
682
field= ((Item_field*) args[0])->field;
684
if ((field= create_tmp_field_from_field(current_thd, field, name, table,
685
NULL, convert_blob_length)))
686
field->flags&= ~NOT_NULL_FLAG;
690
DATE/TIME fields have STRING_RESULT result types.
691
In order to preserve field type, it's needed to handle DATE/TIME
692
fields creations separately.
694
switch (args[0]->field_type()) {
695
case DRIZZLE_TYPE_NEWDATE:
696
field= new Field_newdate(maybe_null, name, collation.collation);
698
case DRIZZLE_TYPE_TIME:
699
field= new Field_time(maybe_null, name, collation.collation);
701
case DRIZZLE_TYPE_TIMESTAMP:
702
case DRIZZLE_TYPE_DATETIME:
703
field= new Field_datetime(maybe_null, name, collation.collation);
706
return Item_sum::create_tmp_field(group, table, convert_blob_length);
714
/***********************************************************************
715
** reset and add of sum_func
716
***********************************************************************/
720
check if the following assignments are really needed
722
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item)
723
:Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
724
curr_dec_buff(item->curr_dec_buff)
726
/* TODO: check if the following assignments are really needed */
727
if (hybrid_type == DECIMAL_RESULT)
729
my_decimal2decimal(item->dec_buffs, dec_buffs);
730
my_decimal2decimal(item->dec_buffs + 1, dec_buffs + 1);
736
Item *Item_sum_sum::copy_or_same(THD* thd)
738
return new (thd->mem_root) Item_sum_sum(thd, this);
742
void Item_sum_sum::clear()
745
if (hybrid_type == DECIMAL_RESULT)
748
my_decimal_set_zero(dec_buffs);
756
void Item_sum_sum::fix_length_and_dec()
758
maybe_null=null_value=1;
759
decimals= args[0]->decimals;
760
switch (args[0]->result_type()) {
763
hybrid_type= REAL_RESULT;
769
/* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
770
int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
771
max_length= my_decimal_precision_to_length(precision, decimals,
774
hybrid_type= DECIMAL_RESULT;
775
my_decimal_set_zero(dec_buffs);
786
bool Item_sum_sum::add()
788
if (hybrid_type == DECIMAL_RESULT)
790
my_decimal value, *val= args[0]->val_decimal(&value);
791
if (!args[0]->null_value)
793
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1),
794
val, dec_buffs + curr_dec_buff);
801
sum+= args[0]->val_real();
802
if (!args[0]->null_value)
809
int64_t Item_sum_sum::val_int()
812
if (hybrid_type == DECIMAL_RESULT)
815
my_decimal2int(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, unsigned_flag,
819
return (int64_t) rint(val_real());
823
double Item_sum_sum::val_real()
826
if (hybrid_type == DECIMAL_RESULT)
827
my_decimal2double(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, &sum);
832
String *Item_sum_sum::val_str(String *str)
834
if (hybrid_type == DECIMAL_RESULT)
835
return val_string_from_decimal(str);
836
return val_string_from_real(str);
840
my_decimal *Item_sum_sum::val_decimal(my_decimal *val)
842
if (hybrid_type == DECIMAL_RESULT)
843
return (dec_buffs + curr_dec_buff);
844
return val_decimal_from_real(val);
847
/***************************************************************************/
853
/* Declarations for auxilary C-callbacks */
855
static int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
857
return memcmp(key1, key2, *(uint32_t *) arg);
861
static int item_sum_distinct_walk(void *element,
862
element_count num_of_dups __attribute__((unused)),
865
return ((Item_sum_distinct*) (item))->unique_walk_function(element);
872
/* Item_sum_distinct */
874
Item_sum_distinct::Item_sum_distinct(Item *item_arg)
875
:Item_sum_num(item_arg), tree(0)
878
quick_group is an optimizer hint, which means that GROUP BY can be
879
handled with help of index on grouped columns.
880
By setting quick_group to zero we force creation of temporary table
887
Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
888
:Item_sum_num(thd, original), val(original->val), tree(0),
889
table_field_type(original->table_field_type)
896
Behaves like an Integer except to fix_length_and_dec().
897
Additionally div() converts val with this traits to a val with true
898
decimal traits along with conversion of integer value to decimal value.
899
This is to speedup SUM/AVG(DISTINCT) evaluation for 8-32 bit integer
902
struct Hybrid_type_traits_fast_decimal: public
903
Hybrid_type_traits_integer
905
virtual Item_result type() const { return DECIMAL_RESULT; }
906
virtual void fix_length_and_dec(Item *item, Item *arg) const
907
{ Hybrid_type_traits_decimal::instance()->fix_length_and_dec(item, arg); }
909
virtual void div(Hybrid_type *val, uint64_t u) const
911
int2my_decimal(E_DEC_FATAL_ERROR, val->integer, 0, val->dec_buf);
912
val->used_dec_buf_no= 0;
913
val->traits= Hybrid_type_traits_decimal::instance();
914
val->traits->div(val, u);
916
static const Hybrid_type_traits_fast_decimal *instance();
917
Hybrid_type_traits_fast_decimal() {};
920
static const Hybrid_type_traits_fast_decimal fast_decimal_traits_instance;
922
const Hybrid_type_traits_fast_decimal
923
*Hybrid_type_traits_fast_decimal::instance()
925
return &fast_decimal_traits_instance;
928
void Item_sum_distinct::fix_length_and_dec()
930
assert(args[0]->fixed);
932
table_field_type= args[0]->field_type();
934
/* Adjust tmp table type according to the chosen aggregation type */
935
switch (args[0]->result_type()) {
938
val.traits= Hybrid_type_traits::instance();
939
table_field_type= DRIZZLE_TYPE_DOUBLE;
943
Preserving int8, int16, int32 field types gives ~10% performance boost
944
as the size of result tree becomes significantly smaller.
945
Another speed up we gain by using int64_t for intermediate
946
calculations. The range of int64 is enough to hold sum 2^32 distinct
947
integers each <= 2^32.
949
if (table_field_type >= DRIZZLE_TYPE_TINY && table_field_type <= DRIZZLE_TYPE_LONG)
951
val.traits= Hybrid_type_traits_fast_decimal::instance();
954
table_field_type= DRIZZLE_TYPE_LONGLONG;
957
val.traits= Hybrid_type_traits_decimal::instance();
958
if (table_field_type != DRIZZLE_TYPE_LONGLONG)
959
table_field_type= DRIZZLE_TYPE_NEWDECIMAL;
965
val.traits->fix_length_and_dec(this, args[0]);
971
check that the case of CHAR(0) works OK
973
bool Item_sum_distinct::setup(THD *thd)
975
List<Create_field> field_list;
976
Create_field field_def; /* field definition */
977
/* It's legal to call setup() more than once when in a subquery */
982
Virtual table and the tree are created anew on each re-execution of
983
PS/SP. Hence all further allocations are performed in the runtime
986
if (field_list.push_back(&field_def))
989
null_value= maybe_null= 1;
992
assert(args[0]->fixed);
994
field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
995
args[0]->decimals, args[0]->maybe_null,
996
args[0]->unsigned_flag);
998
if (! (table= create_virtual_tmp_table(thd, field_list)))
1001
/* XXX: check that the case of CHAR(0) works OK */
1002
tree_key_length= table->s->reclength - table->s->null_bytes;
1005
Unique handles all unique elements in a tree until they can't fit
1006
in. Then the tree is dumped to the temporary file. We can use
1007
simple_raw_key_cmp because the table contains numbers only; decimals
1008
are converted to binary representation as well.
1010
tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length,
1011
thd->variables.max_heap_table_size);
1013
is_evaluated= false;
1018
bool Item_sum_distinct::add()
1020
args[0]->save_in_field(table->field[0], false);
1021
is_evaluated= false;
1022
if (!table->field[0]->is_null())
1027
'0' values are also stored in the tree. This doesn't matter
1028
for SUM(DISTINCT), but is important for AVG(DISTINCT)
1030
return tree->unique_add(table->field[0]->ptr);
1036
bool Item_sum_distinct::unique_walk_function(void *element)
1038
memcpy(table->field[0]->ptr, element, tree_key_length);
1040
val.traits->add(&val, table->field[0]);
1045
void Item_sum_distinct::clear()
1047
assert(tree != 0); /* we always have a tree */
1050
is_evaluated= false;
1054
void Item_sum_distinct::cleanup()
1056
Item_sum_num::cleanup();
1060
is_evaluated= false;
1063
Item_sum_distinct::~Item_sum_distinct()
1066
/* no need to free the table */
1070
void Item_sum_distinct::calculate_val_and_count()
1075
val.traits->set_zero(&val);
1077
We don't have a tree only if 'setup()' hasn't been called;
1078
this is the case of sql_select.cc:return_zero_rows.
1082
table->field[0]->set_notnull();
1083
tree->walk(item_sum_distinct_walk, (void*) this);
1090
double Item_sum_distinct::val_real()
1092
calculate_val_and_count();
1093
return val.traits->val_real(&val);
1097
my_decimal *Item_sum_distinct::val_decimal(my_decimal *to)
1099
calculate_val_and_count();
1102
return val.traits->val_decimal(&val, to);
1106
int64_t Item_sum_distinct::val_int()
1108
calculate_val_and_count();
1109
return val.traits->val_int(&val, unsigned_flag);
1113
String *Item_sum_distinct::val_str(String *str)
1115
calculate_val_and_count();
1118
return val.traits->val_str(&val, str, decimals);
1121
/* end of Item_sum_distinct */
1123
/* Item_sum_avg_distinct */
1126
Item_sum_avg_distinct::fix_length_and_dec()
1128
Item_sum_distinct::fix_length_and_dec();
1129
prec_increment= current_thd->variables.div_precincrement;
1131
AVG() will divide val by count. We need to reserve digits
1132
after decimal point as the result can be fractional.
1134
decimals= cmin(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
1139
Item_sum_avg_distinct::calculate_val_and_count()
1143
Item_sum_distinct::calculate_val_and_count();
1145
val.traits->div(&val, count);
1151
Item *Item_sum_count::copy_or_same(THD* thd)
1153
return new (thd->mem_root) Item_sum_count(thd, this);
1157
void Item_sum_count::clear()
1163
bool Item_sum_count::add()
1165
if (!args[0]->maybe_null || !args[0]->is_null())
1170
int64_t Item_sum_count::val_int()
1173
return (int64_t) count;
1177
void Item_sum_count::cleanup()
1180
Item_sum_int::cleanup();
1188
void Item_sum_avg::fix_length_and_dec()
1190
Item_sum_sum::fix_length_and_dec();
1191
maybe_null=null_value=1;
1192
prec_increment= current_thd->variables.div_precincrement;
1193
if (hybrid_type == DECIMAL_RESULT)
1195
int precision= args[0]->decimal_precision() + prec_increment;
1196
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1197
max_length= my_decimal_precision_to_length(precision, decimals,
1199
f_precision= cmin(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1200
f_scale= args[0]->decimals;
1201
dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
1204
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
1205
max_length= args[0]->max_length + prec_increment;
1210
Item *Item_sum_avg::copy_or_same(THD* thd)
1212
return new (thd->mem_root) Item_sum_avg(thd, this);
1216
Field *Item_sum_avg::create_tmp_field(bool group, Table *table,
1217
uint32_t convert_blob_len __attribute__((unused)))
1223
We must store both value and counter in the temporary table in one field.
1224
The easiest way is to do this is to store both value in a string
1225
and unpack on access.
1227
field= new Field_varstring(((hybrid_type == DECIMAL_RESULT) ?
1228
dec_bin_size : sizeof(double)) + sizeof(int64_t),
1229
0, name, table->s, &my_charset_bin);
1231
else if (hybrid_type == DECIMAL_RESULT)
1232
field= new Field_new_decimal(max_length, maybe_null, name,
1233
decimals, unsigned_flag);
1235
field= new Field_double(max_length, maybe_null, name, decimals, true);
1242
void Item_sum_avg::clear()
1244
Item_sum_sum::clear();
1249
bool Item_sum_avg::add()
1251
if (Item_sum_sum::add())
1253
if (!args[0]->null_value)
1258
double Item_sum_avg::val_real()
1266
return Item_sum_sum::val_real() / uint64_t2double(count);
1270
my_decimal *Item_sum_avg::val_decimal(my_decimal *val)
1272
my_decimal sum_buff, cnt;
1273
const my_decimal *sum_dec;
1282
For non-DECIMAL hybrid_type the division will be done in
1283
Item_sum_avg::val_real().
1285
if (hybrid_type != DECIMAL_RESULT)
1286
return val_decimal_from_real(val);
1288
sum_dec= dec_buffs + curr_dec_buff;
1289
int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &cnt);
1290
my_decimal_div(E_DEC_FATAL_ERROR, val, sum_dec, &cnt, prec_increment);
1295
String *Item_sum_avg::val_str(String *str)
1297
if (hybrid_type == DECIMAL_RESULT)
1298
return val_string_from_decimal(str);
1299
return val_string_from_real(str);
1307
double Item_sum_std::val_real()
1310
double nr= Item_sum_variance::val_real();
1315
Item *Item_sum_std::copy_or_same(THD* thd)
1317
return new (thd->mem_root) Item_sum_std(thd, this);
1327
Variance implementation for floating-point implementations, without
1328
catastrophic cancellation, from Knuth's _TAoCP_, 3rd ed, volume 2, pg232.
1329
This alters the value at m, s, and increments count.
1333
These two functions are used by the Item_sum_variance and the
1334
Item_variance_field classes, which are unrelated, and each need to calculate
1335
variance. The difference between the two classes is that the first is used
1336
for a mundane SELECT, while the latter is used in a GROUPing SELECT.
1338
static void variance_fp_recurrence_next(double *m, double *s, uint64_t *count, double nr)
1349
double m_kminusone= *m;
1350
*m= m_kminusone + (nr - m_kminusone) / (double) *count;
1351
*s= *s + (nr - m_kminusone) * (nr - *m);
1356
static double variance_fp_recurrence_result(double s, uint64_t count, bool is_sample_variance)
1361
if (is_sample_variance)
1362
return s / (count - 1);
1364
/* else, is a population variance */
1369
Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item):
1370
Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
1371
count(item->count), sample(item->sample),
1372
prec_increment(item->prec_increment)
1374
recurrence_m= item->recurrence_m;
1375
recurrence_s= item->recurrence_s;
1379
void Item_sum_variance::fix_length_and_dec()
1381
maybe_null= null_value= 1;
1382
prec_increment= current_thd->variables.div_precincrement;
1385
According to the SQL2003 standard (Part 2, Foundations; sec 10.9,
1386
aggregate function; paragraph 7h of Syntax Rules), "the declared
1387
type of the result is an implementation-defined aproximate numeric
1390
hybrid_type= REAL_RESULT;
1392
switch (args[0]->result_type()) {
1395
decimals= cmin(args[0]->decimals + 4, NOT_FIXED_DEC);
1398
case DECIMAL_RESULT:
1400
int precision= args[0]->decimal_precision()*2 + prec_increment;
1401
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1402
max_length= my_decimal_precision_to_length(precision, decimals,
1415
Item *Item_sum_variance::copy_or_same(THD* thd)
1417
return new (thd->mem_root) Item_sum_variance(thd, this);
1422
Create a new field to match the type of value we're expected to yield.
1423
If we're grouping, then we need some space to serialize variables into, to
1426
Field *Item_sum_variance::create_tmp_field(bool group, Table *table,
1427
uint32_t convert_blob_len __attribute__((unused)))
1433
We must store both value and counter in the temporary table in one field.
1434
The easiest way is to do this is to store both value in a string
1435
and unpack on access.
1437
field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, table->s, &my_charset_bin);
1440
field= new Field_double(max_length, maybe_null, name, decimals, true);
1449
void Item_sum_variance::clear()
1454
bool Item_sum_variance::add()
1457
Why use a temporary variable? We don't know if it is null until we
1458
evaluate it, which has the side-effect of setting null_value .
1460
double nr= args[0]->val_real();
1462
if (!args[0]->null_value)
1463
variance_fp_recurrence_next(&recurrence_m, &recurrence_s, &count, nr);
1467
double Item_sum_variance::val_real()
1472
'sample' is a 1/0 boolean value. If it is 1/true, id est this is a sample
1473
variance call, then we should set nullness when the count of the items
1474
is one or zero. If it's zero, i.e. a population variance, then we only
1475
set nullness when the count is zero.
1477
Another way to read it is that 'sample' is the numerical threshhold, at and
1478
below which a 'count' number of items is called NULL.
1480
assert((sample == 0) || (sample == 1));
1481
if (count <= sample)
1488
return variance_fp_recurrence_result(recurrence_s, count, sample);
1492
my_decimal *Item_sum_variance::val_decimal(my_decimal *dec_buf)
1495
return val_decimal_from_real(dec_buf);
1499
void Item_sum_variance::reset_field()
1502
unsigned char *res= result_field->ptr;
1504
nr= args[0]->val_real(); /* sets null_value as side-effect */
1506
if (args[0]->null_value)
1507
memset(res, 0, sizeof(double)*2+sizeof(int64_t));
1510
/* Serialize format is (double)m, (double)s, (int64_t)count */
1513
float8store(res, nr); /* recurrence variable m */
1515
float8store(res + sizeof(double), tmp_s);
1517
int8store(res + sizeof(double)*2, tmp_count);
1522
void Item_sum_variance::update_field()
1524
uint64_t field_count;
1525
unsigned char *res=result_field->ptr;
1527
double nr= args[0]->val_real(); /* sets null_value as side-effect */
1529
if (args[0]->null_value)
1532
/* Serialize format is (double)m, (double)s, (int64_t)count */
1533
double field_recurrence_m, field_recurrence_s;
1534
float8get(field_recurrence_m, res);
1535
float8get(field_recurrence_s, res + sizeof(double));
1536
field_count=sint8korr(res+sizeof(double)*2);
1538
variance_fp_recurrence_next(&field_recurrence_m, &field_recurrence_s, &field_count, nr);
1540
float8store(res, field_recurrence_m);
1541
float8store(res + sizeof(double), field_recurrence_s);
1542
res+= sizeof(double)*2;
1543
int8store(res,field_count);
1549
void Item_sum_hybrid::clear()
1551
switch (hybrid_type) {
1555
case DECIMAL_RESULT:
1556
my_decimal_set_zero(&sum_dec);
1567
double Item_sum_hybrid::val_real()
1572
switch (hybrid_type) {
1577
String *res; res=val_str(&str_value);
1578
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
1579
&end_not_used, &err_not_used) : 0.0);
1582
return (double) sum_int;
1583
case DECIMAL_RESULT:
1584
my_decimal2double(E_DEC_FATAL_ERROR, &sum_dec, &sum);
1590
// This case should never be choosen
1596
int64_t Item_sum_hybrid::val_int()
1601
switch (hybrid_type) {
1604
case DECIMAL_RESULT:
1607
my_decimal2int(E_DEC_FATAL_ERROR, &sum_dec, unsigned_flag, &result);
1611
return (int64_t) rint(Item_sum_hybrid::val_real());
1616
my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
1621
switch (hybrid_type) {
1623
string2my_decimal(E_DEC_FATAL_ERROR, &value, val);
1626
double2my_decimal(E_DEC_FATAL_ERROR, sum, val);
1628
case DECIMAL_RESULT:
1632
int2my_decimal(E_DEC_FATAL_ERROR, sum_int, unsigned_flag, val);
1636
// This case should never be choosen
1640
return val; // Keep compiler happy
1645
Item_sum_hybrid::val_str(String *str)
1650
switch (hybrid_type) {
1654
str->set_real(sum,decimals, &my_charset_bin);
1656
case DECIMAL_RESULT:
1657
my_decimal2string(E_DEC_FATAL_ERROR, &sum_dec, 0, 0, 0, str);
1660
str->set_int(sum_int, unsigned_flag, &my_charset_bin);
1664
// This case should never be choosen
1668
return str; // Keep compiler happy
1672
void Item_sum_hybrid::cleanup()
1674
Item_sum::cleanup();
1675
forced_const= false;
1678
by default it is TRUE to avoid TRUE reporting by
1679
Item_func_not_all/Item_func_nop_all if this item was never called.
1681
no_rows_in_result() set it to FALSE if was not results found.
1682
If some results found it will be left unchanged.
1688
void Item_sum_hybrid::no_rows_in_result()
1695
Item *Item_sum_min::copy_or_same(THD* thd)
1697
return new (thd->mem_root) Item_sum_min(thd, this);
1701
bool Item_sum_min::add()
1703
switch (hybrid_type) {
1706
String *result=args[0]->val_str(&tmp_value);
1707
if (!args[0]->null_value &&
1708
(null_value || sortcmp(&value,result,collation.collation) > 0))
1710
value.copy(*result);
1717
int64_t nr=args[0]->val_int();
1718
if (!args[0]->null_value && (null_value ||
1720
(uint64_t) nr < (uint64_t) sum_int) ||
1721
(!unsigned_flag && nr < sum_int)))
1728
case DECIMAL_RESULT:
1730
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1731
if (!args[0]->null_value &&
1732
(null_value || (my_decimal_cmp(&sum_dec, val) > 0)))
1734
my_decimal2decimal(val, &sum_dec);
1741
double nr= args[0]->val_real();
1742
if (!args[0]->null_value && (null_value || nr < sum))
1751
// This case should never be choosen
1759
Item *Item_sum_max::copy_or_same(THD* thd)
1761
return new (thd->mem_root) Item_sum_max(thd, this);
1765
bool Item_sum_max::add()
1767
switch (hybrid_type) {
1770
String *result=args[0]->val_str(&tmp_value);
1771
if (!args[0]->null_value &&
1772
(null_value || sortcmp(&value,result,collation.collation) < 0))
1774
value.copy(*result);
1781
int64_t nr=args[0]->val_int();
1782
if (!args[0]->null_value && (null_value ||
1784
(uint64_t) nr > (uint64_t) sum_int) ||
1785
(!unsigned_flag && nr > sum_int)))
1792
case DECIMAL_RESULT:
1794
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1795
if (!args[0]->null_value &&
1796
(null_value || (my_decimal_cmp(val, &sum_dec) > 0)))
1798
my_decimal2decimal(val, &sum_dec);
1805
double nr= args[0]->val_real();
1806
if (!args[0]->null_value && (null_value || nr > sum))
1815
// This case should never be choosen
1823
/* bit_or and bit_and */
1825
int64_t Item_sum_bit::val_int()
1828
return (int64_t) bits;
1832
void Item_sum_bit::clear()
1837
Item *Item_sum_or::copy_or_same(THD* thd)
1839
return new (thd->mem_root) Item_sum_or(thd, this);
1843
bool Item_sum_or::add()
1845
uint64_t value= (uint64_t) args[0]->val_int();
1846
if (!args[0]->null_value)
1851
Item *Item_sum_xor::copy_or_same(THD* thd)
1853
return new (thd->mem_root) Item_sum_xor(thd, this);
1857
bool Item_sum_xor::add()
1859
uint64_t value= (uint64_t) args[0]->val_int();
1860
if (!args[0]->null_value)
1865
Item *Item_sum_and::copy_or_same(THD* thd)
1867
return new (thd->mem_root) Item_sum_and(thd, this);
1871
bool Item_sum_and::add()
1873
uint64_t value= (uint64_t) args[0]->val_int();
1874
if (!args[0]->null_value)
1879
/************************************************************************
1880
** reset result of a Item_sum with is saved in a tmp_table
1881
*************************************************************************/
1883
void Item_sum_num::reset_field()
1885
double nr= args[0]->val_real();
1886
unsigned char *res=result_field->ptr;
1890
if (args[0]->null_value)
1893
result_field->set_null();
1896
result_field->set_notnull();
1898
float8store(res,nr);
1902
void Item_sum_hybrid::reset_field()
1904
switch(hybrid_type) {
1907
char buff[MAX_FIELD_WIDTH];
1908
String tmp(buff,sizeof(buff),result_field->charset()),*res;
1910
res=args[0]->val_str(&tmp);
1911
if (args[0]->null_value)
1913
result_field->set_null();
1914
result_field->reset();
1918
result_field->set_notnull();
1919
result_field->store(res->ptr(),res->length(),tmp.charset());
1925
int64_t nr=args[0]->val_int();
1929
if (args[0]->null_value)
1932
result_field->set_null();
1935
result_field->set_notnull();
1937
result_field->store(nr, unsigned_flag);
1942
double nr= args[0]->val_real();
1946
if (args[0]->null_value)
1949
result_field->set_null();
1952
result_field->set_notnull();
1954
result_field->store(nr);
1957
case DECIMAL_RESULT:
1959
my_decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
1963
if (args[0]->null_value)
1964
result_field->set_null();
1966
result_field->set_notnull();
1969
We must store zero in the field as we will use the field value in
1972
if (!arg_dec) // Null
1973
arg_dec= &decimal_zero;
1974
result_field->store_decimal(arg_dec);
1984
void Item_sum_sum::reset_field()
1986
if (hybrid_type == DECIMAL_RESULT)
1988
my_decimal value, *arg_val= args[0]->val_decimal(&value);
1989
if (!arg_val) // Null
1990
arg_val= &decimal_zero;
1991
result_field->store_decimal(arg_val);
1995
assert(hybrid_type == REAL_RESULT);
1996
double nr= args[0]->val_real(); // Nulls also return 0
1997
float8store(result_field->ptr, nr);
1999
if (args[0]->null_value)
2000
result_field->set_null();
2002
result_field->set_notnull();
2006
void Item_sum_count::reset_field()
2008
unsigned char *res=result_field->ptr;
2011
if (!args[0]->maybe_null || !args[0]->is_null())
2017
void Item_sum_avg::reset_field()
2019
unsigned char *res=result_field->ptr;
2020
if (hybrid_type == DECIMAL_RESULT)
2023
my_decimal value, *arg_dec= args[0]->val_decimal(&value);
2024
if (args[0]->null_value)
2026
arg_dec= &decimal_zero;
2031
my_decimal2binary(E_DEC_FATAL_ERROR, arg_dec, res, f_precision, f_scale);
2033
int8store(res, tmp);
2037
double nr= args[0]->val_real();
2039
if (args[0]->null_value)
2040
memset(res, 0, sizeof(double)+sizeof(int64_t));
2044
float8store(res,nr);
2045
res+=sizeof(double);
2052
void Item_sum_bit::reset_field()
2055
int8store(result_field->ptr, bits);
2058
void Item_sum_bit::update_field()
2060
unsigned char *res=result_field->ptr;
2061
bits= uint8korr(res);
2063
int8store(res, bits);
2068
calc next value and merge it with field_value.
2071
void Item_sum_sum::update_field()
2073
if (hybrid_type == DECIMAL_RESULT)
2075
my_decimal value, *arg_val= args[0]->val_decimal(&value);
2076
if (!args[0]->null_value)
2078
if (!result_field->is_null())
2080
my_decimal field_value,
2081
*field_val= result_field->val_decimal(&field_value);
2082
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, field_val);
2083
result_field->store_decimal(dec_buffs);
2087
result_field->store_decimal(arg_val);
2088
result_field->set_notnull();
2095
unsigned char *res=result_field->ptr;
2097
float8get(old_nr,res);
2098
nr= args[0]->val_real();
2099
if (!args[0]->null_value)
2102
result_field->set_notnull();
2104
float8store(res,old_nr);
2109
void Item_sum_count::update_field()
2112
unsigned char *res=result_field->ptr;
2115
if (!args[0]->maybe_null || !args[0]->is_null())
2121
void Item_sum_avg::update_field()
2123
int64_t field_count;
2124
unsigned char *res=result_field->ptr;
2125
if (hybrid_type == DECIMAL_RESULT)
2127
my_decimal value, *arg_val= args[0]->val_decimal(&value);
2128
if (!args[0]->null_value)
2130
binary2my_decimal(E_DEC_FATAL_ERROR, res,
2131
dec_buffs + 1, f_precision, f_scale);
2132
field_count= sint8korr(res + dec_bin_size);
2133
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, dec_buffs + 1);
2134
my_decimal2binary(E_DEC_FATAL_ERROR, dec_buffs,
2135
res, f_precision, f_scale);
2138
int8store(res, field_count);
2145
nr= args[0]->val_real();
2146
if (!args[0]->null_value)
2149
float8get(old_nr, res);
2150
field_count= sint8korr(res + sizeof(double));
2152
float8store(res,old_nr);
2153
res+= sizeof(double);
2155
int8store(res, field_count);
2161
void Item_sum_hybrid::update_field()
2163
switch (hybrid_type) {
2165
min_max_update_str_field();
2168
min_max_update_int_field();
2170
case DECIMAL_RESULT:
2171
min_max_update_decimal_field();
2174
min_max_update_real_field();
2180
Item_sum_hybrid::min_max_update_str_field()
2182
String *res_str=args[0]->val_str(&value);
2184
if (!args[0]->null_value)
2186
result_field->val_str(&tmp_value);
2188
if (result_field->is_null() ||
2189
(cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
2190
result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
2191
result_field->set_notnull();
2197
Item_sum_hybrid::min_max_update_real_field()
2201
old_nr=result_field->val_real();
2202
nr= args[0]->val_real();
2203
if (!args[0]->null_value)
2205
if (result_field->is_null(0) ||
2206
(cmp_sign > 0 ? old_nr > nr : old_nr < nr))
2208
result_field->set_notnull();
2210
else if (result_field->is_null(0))
2211
result_field->set_null();
2212
result_field->store(old_nr);
2217
Item_sum_hybrid::min_max_update_int_field()
2221
old_nr=result_field->val_int();
2222
nr=args[0]->val_int();
2223
if (!args[0]->null_value)
2225
if (result_field->is_null(0))
2229
bool res=(unsigned_flag ?
2230
(uint64_t) old_nr > (uint64_t) nr :
2232
/* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
2233
if ((cmp_sign > 0) ^ (!res))
2236
result_field->set_notnull();
2238
else if (result_field->is_null(0))
2239
result_field->set_null();
2240
result_field->store(old_nr, unsigned_flag);
2246
optimize: do not get result_field in case of args[0] is NULL
2249
Item_sum_hybrid::min_max_update_decimal_field()
2251
/* TODO: optimize: do not get result_field in case of args[0] is NULL */
2252
my_decimal old_val, nr_val;
2253
const my_decimal *old_nr= result_field->val_decimal(&old_val);
2254
const my_decimal *nr= args[0]->val_decimal(&nr_val);
2255
if (!args[0]->null_value)
2257
if (result_field->is_null(0))
2261
bool res= my_decimal_cmp(old_nr, nr) > 0;
2262
/* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
2263
if ((cmp_sign > 0) ^ (!res))
2266
result_field->set_notnull();
2268
else if (result_field->is_null(0))
2269
result_field->set_null();
2270
result_field->store_decimal(old_nr);
2274
Item_avg_field::Item_avg_field(Item_result res_type, Item_sum_avg *item)
2277
decimals=item->decimals;
2278
max_length= item->max_length;
2279
unsigned_flag= item->unsigned_flag;
2280
field=item->result_field;
2282
hybrid_type= res_type;
2283
prec_increment= item->prec_increment;
2284
if (hybrid_type == DECIMAL_RESULT)
2286
f_scale= item->f_scale;
2287
f_precision= item->f_precision;
2288
dec_bin_size= item->dec_bin_size;
2292
double Item_avg_field::val_real()
2294
// fix_fields() never calls for this Item
2299
if (hybrid_type == DECIMAL_RESULT)
2300
return val_real_from_decimal();
2302
float8get(nr,field->ptr);
2303
res= (field->ptr+sizeof(double));
2304
count= sint8korr(res);
2306
if ((null_value= !count))
2308
return nr/(double) count;
2312
int64_t Item_avg_field::val_int()
2314
return (int64_t) rint(val_real());
2318
my_decimal *Item_avg_field::val_decimal(my_decimal *dec_buf)
2320
// fix_fields() never calls for this Item
2321
if (hybrid_type == REAL_RESULT)
2322
return val_decimal_from_real(dec_buf);
2324
int64_t count= sint8korr(field->ptr + dec_bin_size);
2325
if ((null_value= !count))
2328
my_decimal dec_count, dec_field;
2329
binary2my_decimal(E_DEC_FATAL_ERROR,
2330
field->ptr, &dec_field, f_precision, f_scale);
2331
int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &dec_count);
2332
my_decimal_div(E_DEC_FATAL_ERROR, dec_buf,
2333
&dec_field, &dec_count, prec_increment);
2338
String *Item_avg_field::val_str(String *str)
2340
// fix_fields() never calls for this Item
2341
if (hybrid_type == DECIMAL_RESULT)
2342
return val_string_from_decimal(str);
2343
return val_string_from_real(str);
2347
Item_std_field::Item_std_field(Item_sum_std *item)
2348
: Item_variance_field(item)
2353
double Item_std_field::val_real()
2356
// fix_fields() never calls for this Item
2357
nr= Item_variance_field::val_real();
2363
my_decimal *Item_std_field::val_decimal(my_decimal *dec_buf)
2366
We can't call val_decimal_from_real() for DECIMAL_RESULT as
2367
Item_variance_field::val_real() would cause an infinite loop
2369
my_decimal tmp_dec, *dec;
2371
if (hybrid_type == REAL_RESULT)
2372
return val_decimal_from_real(dec_buf);
2374
dec= Item_variance_field::val_decimal(dec_buf);
2377
my_decimal2double(E_DEC_FATAL_ERROR, dec, &nr);
2380
double2my_decimal(E_DEC_FATAL_ERROR, nr, &tmp_dec);
2381
my_decimal_round(E_DEC_FATAL_ERROR, &tmp_dec, decimals, false, dec_buf);
2386
Item_variance_field::Item_variance_field(Item_sum_variance *item)
2389
decimals=item->decimals;
2390
max_length=item->max_length;
2391
unsigned_flag= item->unsigned_flag;
2392
field=item->result_field;
2394
sample= item->sample;
2395
prec_increment= item->prec_increment;
2396
if ((hybrid_type= item->hybrid_type) == DECIMAL_RESULT)
2398
f_scale0= item->f_scale0;
2399
f_precision0= item->f_precision0;
2400
dec_bin_size0= item->dec_bin_size0;
2401
f_scale1= item->f_scale1;
2402
f_precision1= item->f_precision1;
2403
dec_bin_size1= item->dec_bin_size1;
2408
double Item_variance_field::val_real()
2410
// fix_fields() never calls for this Item
2411
if (hybrid_type == DECIMAL_RESULT)
2412
return val_real_from_decimal();
2414
double recurrence_s;
2416
float8get(recurrence_s, (field->ptr + sizeof(double)));
2417
count=sint8korr(field->ptr+sizeof(double)*2);
2419
if ((null_value= (count <= sample)))
2422
return variance_fp_recurrence_result(recurrence_s, count, sample);
2426
/****************************************************************************
2427
** COUNT(DISTINCT ...)
2428
****************************************************************************/
2430
int simple_str_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
2432
Field *f= (Field*) arg;
2433
return f->cmp(key1, key2);
2437
Did not make this one static - at least gcc gets confused when
2438
I try to declare a static function as a friend. If you can figure
2439
out the syntax to make a static function a friend, make this one
2443
int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
2445
Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
2446
Field **field = item->table->field;
2447
Field **field_end= field + item->table->s->fields;
2448
uint32_t *lengths=item->field_lengths;
2449
for (; field < field_end; ++field)
2452
int len = *lengths++;
2453
int res = f->cmp(key1, key2);
2466
static int count_distinct_walk(void *elem __attribute__((unused)),
2467
element_count count __attribute__((unused)),
2470
(*((uint64_t*)arg))++;
2480
void Item_sum_count_distinct::cleanup()
2482
Item_sum_int::cleanup();
2484
/* Free objects only if we own them. */
2488
We need to delete the table and the tree in cleanup() as
2489
they were allocated in the runtime memroot. Using the runtime
2490
memroot reduces memory footprint for PS/SP and simplifies setup().
2494
is_evaluated= false;
2497
table->free_tmp_table(table->in_use);
2500
delete tmp_table_param;
2509
This is used by rollup to create a separate usable copy of
2513
void Item_sum_count_distinct::make_unique()
2517
force_copy_fields= 1;
2519
is_evaluated= false;
2525
Item_sum_count_distinct::~Item_sum_count_distinct()
2531
bool Item_sum_count_distinct::setup(THD *thd)
2534
SELECT_LEX *select_lex= thd->lex->current_select;
2537
Setup can be called twice for ROLLUP items. This is a bug.
2538
Please add assert(tree == 0) here when it's fixed.
2539
It's legal to call setup() more than once when in a subquery
2541
if (tree || table || tmp_table_param)
2544
if (!(tmp_table_param= new TMP_TABLE_PARAM))
2547
/* Create a table with an unique key over all parameters */
2548
for (uint32_t i=0; i < arg_count ; i++)
2551
if (list.push_back(item))
2552
return true; // End of memory
2553
if (item->const_item() && item->is_null())
2558
count_field_types(select_lex, tmp_table_param, list, 0);
2559
tmp_table_param->force_copy_fields= force_copy_fields;
2562
if (!(table= create_tmp_table(thd, tmp_table_param, list, (order_st*) 0, 1,
2564
(select_lex->options | thd->options),
2565
HA_POS_ERROR, (char*)"")))
2567
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
2570
if (table->s->db_type() == heap_hton)
2573
No blobs, otherwise it would have been MyISAM: set up a compare
2574
function and its arguments to use with Unique.
2576
qsort_cmp2 compare_key;
2578
Field **field= table->field;
2579
Field **field_end= field + table->s->fields;
2580
bool all_binary= true;
2582
for (tree_key_length= 0; field < field_end; ++field)
2585
enum enum_field_types f_type= f->type();
2586
tree_key_length+= f->pack_length();
2587
if (f_type == DRIZZLE_TYPE_VARCHAR)
2595
cmp_arg= (void*) &tree_key_length;
2596
compare_key= (qsort_cmp2) simple_raw_key_cmp;
2600
if (table->s->fields == 1)
2603
If we have only one field, which is the most common use of
2604
count(distinct), it is much faster to use a simpler key
2605
compare method that can take advantage of not having to worry
2608
compare_key= (qsort_cmp2) simple_str_key_cmp;
2609
cmp_arg= (void*) table->field[0];
2610
/* tree_key_length has been set already */
2615
compare_key= (qsort_cmp2) composite_key_cmp;
2616
cmp_arg= (void*) this;
2617
field_lengths= (uint32_t*) thd->alloc(table->s->fields * sizeof(uint32_t));
2618
for (tree_key_length= 0, length= field_lengths, field= table->field;
2619
field < field_end; ++field, ++length)
2621
*length= (*field)->pack_length();
2622
tree_key_length+= *length;
2627
tree= new Unique(compare_key, cmp_arg, tree_key_length,
2628
thd->variables.max_heap_table_size);
2630
The only time tree_key_length could be 0 is if someone does
2631
count(distinct) on a char(0) field - stupid thing to do,
2632
but this has to be handled - otherwise someone can crash
2633
the server with a DoS attack
2635
is_evaluated= false;
2643
Item *Item_sum_count_distinct::copy_or_same(THD* thd)
2645
return new (thd->mem_root) Item_sum_count_distinct(thd, this);
2649
void Item_sum_count_distinct::clear()
2651
/* tree and table can be both null only if always_null */
2652
is_evaluated= false;
2659
table->file->extra(HA_EXTRA_NO_CACHE);
2660
table->file->ha_delete_all_rows();
2661
table->file->extra(HA_EXTRA_WRITE_CACHE);
2665
bool Item_sum_count_distinct::add()
2670
copy_fields(tmp_table_param);
2671
copy_funcs(tmp_table_param->items_to_copy);
2673
for (Field **field=table->field ; *field ; field++)
2674
if ((*field)->is_real_null(0))
2675
return 0; // Don't count NULL
2677
is_evaluated= false;
2681
The first few bytes of record (at least one) are just markers
2682
for deleted and NULLs. We want to skip them since they will
2683
bloat the tree without providing any valuable info. Besides,
2684
key_length used to initialize the tree didn't include space for them.
2686
return tree->unique_add(table->record[0] + table->s->null_bytes);
2688
if ((error= table->file->ha_write_row(table->record[0])) &&
2689
table->file->is_fatal_error(error, HA_CHECK_DUP))
2695
int64_t Item_sum_count_distinct::val_int()
2699
if (!table) // Empty query
2706
if (tree->elements == 0)
2707
return (int64_t) tree->elements_in_tree(); // everything fits in memory
2709
tree->walk(count_distinct_walk, (void*) &count);
2711
return (int64_t) count;
2714
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2718
table->file->print_error(error, MYF(0));
2721
return table->file->stats.records;
2724
/*****************************************************************************
2725
GROUP_CONCAT function
2728
GROUP_CONCAT([DISTINCT] expr,... [order_st BY col [ASC|DESC],...]
2729
[SEPARATOR str_const])
2731
concat of values from "group by" operation
2734
Blobs doesn't work with DISTINCT or order_st BY
2735
*****************************************************************************/
2739
Compares the values for fields in expr list of GROUP_CONCAT.
2742
GROUP_CONCAT([DISTINCT] expr [,expr ...]
2743
[order_st BY {unsigned_integer | col_name | expr}
2744
[ASC | DESC] [,col_name ...]]
2745
[SEPARATOR str_val])
2748
@retval -1 : key1 < key2
2749
@retval 0 : key1 = key2
2750
@retval 1 : key1 > key2
2753
int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
2756
Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
2757
Table *table= item_func->table;
2759
for (uint32_t i= 0; i < item_func->arg_count_field; i++)
2761
Item *item= item_func->args[i];
2763
If field_item is a const item then either get_tp_table_field returns 0
2764
or it is an item over a const table.
2766
if (item->const_item())
2769
We have to use get_tmp_table_field() instead of
2770
real_item()->get_tmp_table_field() because we want the field in
2771
the temporary table, not the original field
2773
Field *field= item->get_tmp_table_field();
2775
uint32_t offset= field->offset(field->table->record[0])-table->s->null_bytes;
2776
if((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2784
function of sort for syntax: GROUP_CONCAT(expr,... order_st BY col,... )
2787
int group_concat_key_cmp_with_order(void* arg, const void* key1,
2790
Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
2791
order_st **order_item, **end;
2792
Table *table= grp_item->table;
2794
for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
2798
Item *item= *(*order_item)->item;
2800
We have to use get_tmp_table_field() instead of
2801
real_item()->get_tmp_table_field() because we want the field in
2802
the temporary table, not the original field
2804
Field *field= item->get_tmp_table_field();
2806
If item is a const item then either get_tp_table_field returns 0
2807
or it is an item over a const table.
2809
if (field && !item->const_item())
2812
uint32_t offset= (field->offset(field->table->record[0]) -
2813
table->s->null_bytes);
2814
if ((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2815
return (*order_item)->asc ? res : -res;
2819
We can't return 0 because in that case the tree class would remove this
2820
item as double value. This would cause problems for case-changes and
2821
if the returned values are not the same we do the sort on.
2828
Append data from current leaf to item->result.
2831
int dump_leaf_key(unsigned char* key, element_count count __attribute__((unused)),
2832
Item_func_group_concat *item)
2834
Table *table= item->table;
2835
String tmp((char *)table->record[1], table->s->reclength,
2836
default_charset_info);
2838
String *result= &item->result;
2839
Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
2840
uint32_t old_length= result->length();
2842
if (item->no_appended)
2843
item->no_appended= false;
2845
result->append(*item->separator);
2849
for (; arg < arg_end; arg++)
2852
if (! (*arg)->const_item())
2855
We have to use get_tmp_table_field() instead of
2856
real_item()->get_tmp_table_field() because we want the field in
2857
the temporary table, not the original field
2858
We also can't use table->field array to access the fields
2859
because it contains both order and arg list fields.
2861
Field *field= (*arg)->get_tmp_table_field();
2862
uint32_t offset= (field->offset(field->table->record[0]) -
2863
table->s->null_bytes);
2864
assert(offset < table->s->reclength);
2865
res= field->val_str(&tmp, key + offset);
2868
res= (*arg)->val_str(&tmp);
2870
result->append(*res);
2873
/* stop if length of result more than max_length */
2874
if (result->length() > item->max_length)
2876
int well_formed_error;
2877
const CHARSET_INFO * const cs= item->collation.collation;
2878
const char *ptr= result->ptr();
2879
uint32_t add_length;
2881
It's ok to use item->result.length() as the fourth argument
2882
as this is never used to limit the length of the data.
2883
Cut is done with the third argument.
2885
add_length= cs->cset->well_formed_len(cs,
2887
ptr + item->max_length,
2889
&well_formed_error);
2890
result->length(old_length + add_length);
2891
item->count_cut_values++;
2892
item->warning_for_row= true;
2900
Constructor of Item_func_group_concat.
2902
@param distinct_arg distinct
2903
@param select_list list of expression for show values
2904
@param order_list list of sort columns
2905
@param separator_arg string value of separator.
2908
Item_func_group_concat::
2909
Item_func_group_concat(Name_resolution_context *context_arg,
2910
bool distinct_arg, List<Item> *select_list,
2911
SQL_LIST *order_list, String *separator_arg)
2912
:tmp_table_param(0), warning(0),
2913
separator(separator_arg), tree(0), unique_filter(NULL), table(0),
2914
order(0), context(context_arg),
2915
arg_count_order(order_list ? order_list->elements : 0),
2916
arg_count_field(select_list->elements),
2917
count_cut_values(0),
2918
distinct(distinct_arg),
2919
warning_for_row(false),
2920
force_copy_fields(0), original(0)
2926
arg_count= arg_count_field + arg_count_order;
2929
We need to allocate:
2930
args - arg_count_field+arg_count_order
2931
(for possible order items in temporare tables)
2932
order - arg_count_order
2934
if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
2935
sizeof(order_st*)*arg_count_order)))
2938
order= (order_st**)(args + arg_count);
2940
/* fill args items of show and sort */
2941
List_iterator_fast<Item> li(*select_list);
2943
for (arg_ptr=args ; (item_select= li++) ; arg_ptr++)
2944
*arg_ptr= item_select;
2946
if (arg_count_order)
2948
order_st **order_ptr= order;
2949
for (order_st *order_item= (order_st*) order_list->first;
2951
order_item= order_item->next)
2953
(*order_ptr++)= order_item;
2954
*arg_ptr= *order_item->item;
2955
order_item->item= arg_ptr++;
2961
Item_func_group_concat::Item_func_group_concat(THD *thd,
2962
Item_func_group_concat *item)
2963
:Item_sum(thd, item),
2964
tmp_table_param(item->tmp_table_param),
2965
warning(item->warning),
2966
separator(item->separator),
2968
unique_filter(item->unique_filter),
2971
context(item->context),
2972
arg_count_order(item->arg_count_order),
2973
arg_count_field(item->arg_count_field),
2974
count_cut_values(item->count_cut_values),
2975
distinct(item->distinct),
2976
warning_for_row(item->warning_for_row),
2977
always_null(item->always_null),
2978
force_copy_fields(item->force_copy_fields),
2981
quick_group= item->quick_group;
2982
result.set_charset(collation.collation);
2987
void Item_func_group_concat::cleanup()
2989
Item_sum::cleanup();
2991
/* Adjust warning message to include total number of cut values */
2994
char warn_buff[DRIZZLE_ERRMSG_SIZE];
2995
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
2996
warning->set_msg(current_thd, warn_buff);
3001
Free table and tree if they belong to this item (if item have not pointer
3002
to original item from which was made copy => it own its objects )
3006
delete tmp_table_param;
3010
THD *thd= table->in_use;
3011
table->free_tmp_table(thd);
3020
delete unique_filter;
3021
unique_filter= NULL;
3025
char warn_buff[DRIZZLE_ERRMSG_SIZE];
3026
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3027
warning->set_msg(thd, warn_buff);
3031
assert(tree == 0 && warning == 0);
3037
Item *Item_func_group_concat::copy_or_same(THD* thd)
3039
return new (thd->mem_root) Item_func_group_concat(thd, this);
3043
void Item_func_group_concat::clear()
3048
warning_for_row= false;
3053
unique_filter->reset();
3054
/* No need to reset the table as we never call write_row */
3058
bool Item_func_group_concat::add()
3062
copy_fields(tmp_table_param);
3063
copy_funcs(tmp_table_param->items_to_copy);
3065
for (uint32_t i= 0; i < arg_count_field; i++)
3067
Item *show_item= args[i];
3068
if (!show_item->const_item())
3070
Field *f= show_item->get_tmp_table_field();
3071
if (f->is_null_in_record((const unsigned char*) table->record[0]))
3072
return 0; // Skip row if it contains null
3077
bool row_eligible= true;
3081
/* Filter out duplicate rows. */
3082
uint32_t count= unique_filter->elements_in_tree();
3083
unique_filter->unique_add(table->record[0] + table->s->null_bytes);
3084
if (count == unique_filter->elements_in_tree())
3085
row_eligible= false;
3088
TREE_ELEMENT *el= 0; // Only for safety
3089
if (row_eligible && tree)
3090
el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
3093
If the row is not a duplicate (el->count == 1)
3094
we can dump the row here in case of GROUP_CONCAT(DISTINCT...)
3095
instead of doing tree traverse later.
3097
if (row_eligible && !warning_for_row &&
3098
(!tree || (el->count == 1 && distinct && !arg_count_order)))
3099
dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3106
Item_func_group_concat::fix_fields(THD *thd, Item **ref)
3108
uint32_t i; /* for loop variable */
3111
if (init_sum_func_check(thd))
3117
Fix fields for select list and order_st clause
3120
for (i=0 ; i < arg_count ; i++)
3122
if ((!args[i]->fixed &&
3123
args[i]->fix_fields(thd, args + i)) ||
3124
args[i]->check_cols(1))
3128
if (agg_item_charsets(collation, func_name(),
3130
/* skip charset aggregation for order columns */
3131
arg_count - arg_count_order,
3132
MY_COLL_ALLOW_CONV, 1))
3135
result.set_charset(collation.collation);
3138
max_length= thd->variables.group_concat_max_len;
3141
if (separator->needs_conversion(separator->length(), separator->charset(),
3142
collation.collation, &offset))
3144
uint32_t buflen= collation.collation->mbmaxlen * separator->length();
3145
uint32_t errors, conv_length;
3147
String *new_separator;
3149
if (!(buf= (char*) thd->alloc(buflen)) ||
3150
!(new_separator= new(thd->mem_root)
3151
String(buf, buflen, collation.collation)))
3154
conv_length= copy_and_convert(buf, buflen, collation.collation,
3155
separator->ptr(), separator->length(),
3156
separator->charset(), &errors);
3157
new_separator->length(conv_length);
3158
separator= new_separator;
3161
if (check_sum_func(thd, ref))
3169
bool Item_func_group_concat::setup(THD *thd)
3172
SELECT_LEX *select_lex= thd->lex->current_select;
3175
Currently setup() can be called twice. Please add
3176
assertion here when this is fixed.
3181
if (!(tmp_table_param= new TMP_TABLE_PARAM))
3184
/* We'll convert all blobs to varchar fields in the temporary table */
3185
tmp_table_param->convert_blob_length= max_length *
3186
collation.collation->mbmaxlen;
3187
/* Push all not constant fields to the list and create a temp table */
3189
for (uint32_t i= 0; i < arg_count_field; i++)
3191
Item *item= args[i];
3192
if (list.push_back(item))
3194
if (item->const_item())
3196
if (item->is_null())
3204
List<Item> all_fields(list);
3206
Try to find every order_st expression in the list of GROUP_CONCAT
3207
arguments. If an expression is not found, prepend it to
3208
"all_fields". The resulting field list is used as input to create
3211
if (arg_count_order &&
3212
setup_order(thd, args, context->table_list, list, all_fields, *order))
3215
count_field_types(select_lex, tmp_table_param, all_fields, 0);
3216
tmp_table_param->force_copy_fields= force_copy_fields;
3218
if (arg_count_order > 0 || distinct)
3221
Currently we have to force conversion of BLOB values to VARCHAR's
3222
if we are to store them in TREE objects used for order_st BY and
3223
DISTINCT. This leads to truncation if the BLOB's size exceeds
3224
Field_varstring::MAX_SIZE.
3226
set_if_smaller(tmp_table_param->convert_blob_length,
3227
Field_varstring::MAX_SIZE);
3231
We have to create a temporary table to get descriptions of fields
3232
(types, sizes and so on).
3234
Note that in the table, we first have the order_st BY fields, then the
3237
if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
3238
(order_st*) 0, 0, true,
3239
(select_lex->options | thd->options),
3240
HA_POS_ERROR, (char*) "")))
3242
table->file->extra(HA_EXTRA_NO_ROWS);
3246
Need sorting or uniqueness: init tree and choose a function to sort.
3247
Don't reserve space for NULLs: if any of gconcat arguments is NULL,
3248
the row is not added to the result.
3250
uint32_t tree_key_length= table->s->reclength - table->s->null_bytes;
3252
if (arg_count_order)
3256
Create a tree for sorting. The tree is used to sort (according to the
3257
syntax of this function). If there is no order_st BY clause, we don't
3260
init_tree(tree, (uint) cmin(thd->variables.max_heap_table_size,
3261
thd->variables.sortbuff_size/16), 0,
3263
group_concat_key_cmp_with_order , 0, NULL, (void*) this);
3267
unique_filter= new Unique(group_concat_key_cmp_with_distinct,
3270
thd->variables.max_heap_table_size);
3276
/* This is used by rollup to create a separate usable copy of the function */
3278
void Item_func_group_concat::make_unique()
3283
force_copy_fields= 1;
3288
String* Item_func_group_concat::val_str(String* str __attribute__((unused)))
3293
if (no_appended && tree)
3294
/* Tree is used for sorting as in ORDER BY */
3295
tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
3297
if (count_cut_values && !warning)
3300
ER_CUT_VALUE_GROUP_CONCAT needs an argument, but this gets set in
3301
Item_func_group_concat::cleanup().
3304
warning= push_warning(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3305
ER_CUT_VALUE_GROUP_CONCAT,
3306
ER(ER_CUT_VALUE_GROUP_CONCAT));
3312
void Item_func_group_concat::print(String *str, enum_query_type query_type)
3314
str->append(STRING_WITH_LEN("group_concat("));
3316
str->append(STRING_WITH_LEN("distinct "));
3317
for (uint32_t i= 0; i < arg_count_field; i++)
3321
args[i]->print(str, query_type);
3323
if (arg_count_order)
3325
str->append(STRING_WITH_LEN(" order by "));
3326
for (uint32_t i= 0 ; i < arg_count_order ; i++)
3330
(*order[i]->item)->print(str, query_type);
3332
str->append(STRING_WITH_LEN(" ASC"));
3334
str->append(STRING_WITH_LEN(" DESC"));
3337
str->append(STRING_WITH_LEN(" separator \'"));
3338
str->append(*separator);
3339
str->append(STRING_WITH_LEN("\')"));
3343
Item_func_group_concat::~Item_func_group_concat()
3345
if (!original && unique_filter)
3346
delete unique_filter;