21
21
Sum functions (COUNT, MIN...)
23
#include <drizzled/server_includes.h>
26
24
#include <drizzled/sql_select.h>
27
#include <drizzled/error.h>
28
#include <drizzled/hybrid_type_traits.h>
29
#include <drizzled/hybrid_type_traits_integer.h>
30
#include <drizzled/hybrid_type_traits_decimal.h>
31
#include <drizzled/sql_base.h>
33
#include <drizzled/item/sum.h>
34
#include <drizzled/field/decimal.h>
35
#include <drizzled/field/double.h>
36
#include <drizzled/field/int64_t.h>
37
#include <drizzled/field/date.h>
38
#include <drizzled/field/datetime.h>
40
#include "drizzled/internal/m_string.h"
49
extern my_decimal decimal_zero;
50
extern plugin::StorageEngine *heap_engine;
25
#include <drizzled/drizzled_error_messages.h>
53
28
Prepare an aggregate function item for checking context conditions.
58
33
If the set function is not allowed in any subquery where it occurs
59
34
an error is reported immediately.
61
@param session reference to the thread context info
36
@param thd reference to the thread context info
64
39
This function is to be called for any item created for a set function
74
bool Item_sum::init_sum_func_check(Session *session)
49
bool Item_sum::init_sum_func_check(THD *thd)
76
if (!session->lex->allow_sum_func)
51
if (!thd->lex->allow_sum_func)
78
53
my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
82
57
/* Set a reference to the nesting set function if there is any */
83
in_sum_func= session->lex->in_sum_func;
58
in_sum_func= thd->lex->in_sum_func;
84
59
/* Save a pointer to object to be used in items for nested set functions */
85
session->lex->in_sum_func= this;
86
nest_level= session->lex->current_select->nest_level;
60
thd->lex->in_sum_func= this;
61
nest_level= thd->lex->current_select->nest_level;
105
80
If the context conditions are not met the method reports an error.
106
81
If the set function is aggregated in some outer subquery the method
107
82
adds it to the chain of items for such set functions that is attached
108
to the the Select_Lex structure for this subquery.
83
to the the st_select_lex structure for this subquery.
110
85
A number of designated members of the object are used to check the
111
86
conditions. They are specified in the comment before the Item_sum
112
87
class declaration.
113
88
Additionally a bitmap variable called allow_sum_func is employed.
114
It is included into the session->lex structure.
89
It is included into the thd->lex structure.
115
90
The bitmap contains 1 at n-th position if the set function happens
116
91
to occur under a construct of the n-th level subquery where usage
117
92
of set functions are allowed (i.e either in the SELECT list or
122
97
HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
123
98
t1.a > (SELECT MIN(t2.d) FROM t2);
125
allow_sum_func will contain:
126
- for SUM(t1.b) - 1 at the first position
100
allow_sum_func will contain:
101
- for SUM(t1.b) - 1 at the first position
127
102
- for AVG(t1.b) - 1 at the first position, 0 at the second position
128
103
- for MIN(t2.d) - 1 at the first position, 1 at the second position.
130
@param session reference to the thread context info
105
@param thd reference to the thread context info
131
106
@param ref location of the pointer to this item in the embedding expression
145
bool Item_sum::check_sum_func(Session *session, Item **ref)
120
bool Item_sum::check_sum_func(THD *thd, Item **ref)
147
122
bool invalid= false;
148
nesting_map allow_sum_func= session->lex->allow_sum_func;
123
nesting_map allow_sum_func= thd->lex->allow_sum_func;
150
125
The value of max_arg_level is updated if an argument of the set function
151
126
contains a column reference resolved against a subquery whose level is
152
127
greater than the current value of max_arg_level.
153
128
max_arg_level cannot be greater than nest level.
154
nest level is always >= 0
129
nest level is always >= 0
156
131
if (nest_level == max_arg_level)
159
The function must be aggregated in the current subquery,
160
If it is there under a construct where it is not allowed
134
The function must be aggregated in the current subquery,
135
If it is there under a construct where it is not allowed
163
138
invalid= !(allow_sum_func & (1 << max_arg_level));
165
140
else if (max_arg_level >= 0 || !(allow_sum_func & (1 << nest_level)))
169
144
Try to find a subquery where it can be aggregated;
170
145
If we fail to find such a subquery report an error.
172
if (register_sum_func(session, ref))
147
if (register_sum_func(thd, ref))
174
149
invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
175
150
if (!invalid && false)
178
153
if (!invalid && aggr_level < 0)
180
155
aggr_level= nest_level;
181
aggr_sel= session->lex->current_select;
156
aggr_sel= thd->lex->current_select;
184
159
By this moment we either found a subquery where the set function is
185
160
to be aggregated and assigned a value that is >= 0 to aggr_level,
186
or set the value of 'invalid' to TRUE to report later an error.
161
or set the value of 'invalid' to TRUE to report later an error.
189
164
Additionally we have to check whether possible nested set functions
190
165
are acceptable here: they are not, if the level of aggregation of
191
166
some of them is less than aggr_level.
194
169
invalid= aggr_level <= max_sum_func_level;
197
172
my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
205
180
If the set function is nested adjust the value of
206
181
max_sum_func_level for the nesting set function.
207
We take into account only enclosed set functions that are to be
208
aggregated on the same level or above of the nest level of
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
209
184
the enclosing set function.
210
185
But we must always pass up the max_sum_func_level because it is
211
186
the maximum nested level of all directly and indirectly enclosed
268
243
in_sum_func->outer_fields.push_back(field);
272
sel->full_group_by_flag.set(NON_AGG_FIELD_USED);
246
sel->full_group_by_flag|= NON_AGG_FIELD_USED;
275
248
if (sel->nest_level > aggr_level &&
276
(sel->full_group_by_flag.test(SUM_FUNC_USED)) &&
277
! sel->group_list.elements)
249
(sel->full_group_by_flag & SUM_FUNC_USED) &&
250
!sel->group_list.elements)
279
252
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
280
253
ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
295
268
aggregated. If it finds such a subquery then aggr_level is set to
296
269
the nest level of this subquery and the item for the set function
297
270
is added to the list of set functions used in nested subqueries
298
inner_sum_func_list defined for each subquery. When the item is placed
271
inner_sum_func_list defined for each subquery. When the item is placed
299
272
there the field 'ref_by' is set to ref.
304
277
a subquery in one chain. It would simplify the process of 'splitting'
305
278
for set functions.
307
@param session reference to the thread context info
280
@param thd reference to the thread context info
308
281
@param ref location of the pointer to this item in the embedding expression
311
284
FALSE if the executes without failures (currently always)
316
bool Item_sum::register_sum_func(Session *session, Item **ref)
289
bool Item_sum::register_sum_func(THD *thd, Item **ref)
319
nesting_map allow_sum_func= session->lex->allow_sum_func;
320
for (sl= session->lex->current_select->master_unit()->outer_select() ;
292
nesting_map allow_sum_func= thd->lex->allow_sum_func;
293
for (sl= thd->lex->current_select->master_unit()->outer_select() ;
321
294
sl && sl->nest_level > max_arg_level;
322
295
sl= sl->master_unit()->outer_select() )
331
304
if (sl && (allow_sum_func & (1 << sl->nest_level)))
334
307
We reached the subquery of level max_arg_level and checked
335
that the function can be aggregated here.
308
that the function can be aggregated here.
336
309
The set function will be aggregated in this subquery.
338
311
aggr_level= sl->nest_level;
353
326
aggr_sel->inner_sum_func_list= this;
354
327
aggr_sel->with_sum_func= 1;
357
330
Mark Item_subselect(s) as containing aggregate function all the way up
358
331
to aggregate function's calculation context.
359
332
Note that we must not mark the Item of calculation context itself
360
because with_sum_func on the calculation context Select_Lex is
333
because with_sum_func on the calculation context st_select_lex is
361
334
already set above.
363
with_sum_func being set for an Item means that this Item refers
336
with_sum_func being set for an Item means that this Item refers
364
337
(somewhere in it, e.g. one of its arguments if it's a function) directly
365
338
or through intermediate items to an aggregate function that is calculated
366
339
in a context "outside" of the Item (e.g. in the current or outer select).
368
with_sum_func being set for an Select_Lex means that this Select_Lex
341
with_sum_func being set for an st_select_lex means that this st_select_lex
369
342
has aggregate functions directly referenced (i.e. not through a sub-select).
371
for (sl= session->lex->current_select;
344
for (sl= thd->lex->current_select;
372
345
sl && sl != aggr_sel && sl->master_unit()->item;
373
346
sl= sl->master_unit()->outer_select() )
374
347
sl->master_unit()->item->with_sum_func= 1;
376
session->lex->current_select->mark_as_dependent(aggr_sel);
349
thd->lex->current_select->mark_as_dependent(aggr_sel);
381
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
354
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
382
355
forced_const(false)
384
if ((args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
357
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
387
360
List_iterator_fast<Item> li(list);
401
374
Constructor used in processing select with temporary tebles.
404
Item_sum::Item_sum(Session *session, Item_sum *item):
405
Item_result_field(session, item), arg_count(item->arg_count),
377
Item_sum::Item_sum(THD *thd, Item_sum *item):
378
Item_result_field(thd, item), arg_count(item->arg_count),
406
379
aggr_sel(item->aggr_sel),
407
380
nest_level(item->nest_level), aggr_level(item->aggr_level),
408
381
quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
409
forced_const(item->forced_const)
382
forced_const(item->forced_const)
411
384
if (arg_count <= 2)
414
if (!(args= (Item**) session->alloc(sizeof(Item*)*arg_count)))
387
if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
416
389
memcpy(args, item->args, sizeof(Item*)*arg_count);
420
393
void Item_sum::mark_as_sum_func()
422
Select_Lex *cur_select= current_session->lex->current_select;
395
SELECT_LEX *cur_select= current_thd->lex->current_select;
423
396
cur_select->n_sum_items++;
424
397
cur_select->with_sum_func= 1;
425
398
with_sum_func= 1;
429
void Item_sum::make_field(SendField *tmp_field)
402
void Item_sum::make_field(Send_field *tmp_field)
431
404
if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
466
439
max_length=float_length(decimals);
469
Item *Item_sum::get_tmp_table_item(Session *session)
442
Item *Item_sum::get_tmp_table_item(THD *thd)
471
Item_sum* sum_item= (Item_sum *) copy_or_same(session);
444
Item_sum* sum_item= (Item_sum *) copy_or_same(thd);
472
445
if (sum_item && sum_item->result_field) // If not a const sum func
474
447
Field *result_field_tmp= sum_item->result_field;
522
495
!convert_blob_length)
523
496
return make_string_field(table);
524
497
field= new Field_varstring(convert_blob_length, maybe_null,
525
name, table->getMutableShare(), collation.collation);
498
name, table->s, collation.collation);
527
500
case DECIMAL_RESULT:
528
field= new Field_decimal(max_length, maybe_null, name,
501
field= new Field_new_decimal(max_length, maybe_null, name,
529
502
decimals, unsigned_flag);
596
Item_sum_num::fix_fields(Session *session, Item **ref)
562
Item_sum_num::fix_fields(THD *thd, Item **ref)
598
564
assert(fixed == 0);
600
if (init_sum_func_check(session))
566
if (init_sum_func_check(thd))
605
571
for (uint32_t i=0 ; i < arg_count ; i++)
607
if (args[i]->fix_fields(session, args + i) || args[i]->check_cols(1))
573
if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
609
575
set_if_bigger(decimals, args[i]->decimals);
610
576
maybe_null |= args[i]->maybe_null;
625
Item_sum_hybrid::Item_sum_hybrid(Session *session, Item_sum_hybrid *item)
626
:Item_sum(session, item), value(item->value), hybrid_type(item->hybrid_type),
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),
627
593
hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
628
594
was_values(item->was_values)
655
Item_sum_hybrid::fix_fields(Session *session, Item **ref)
621
Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
657
623
assert(fixed == 0);
659
625
Item *item= args[0];
661
if (init_sum_func_check(session))
627
if (init_sum_func_check(thd))
664
630
// 'item' can be changed during fix_fields
665
if ((!item->fixed && item->fix_fields(session, args)) ||
631
if ((!item->fixed && item->fix_fields(thd, args)) ||
666
632
(item= args[0])->check_cols(1))
668
634
decimals=item->decimals;
714
680
if (args[0]->type() == Item::FIELD_ITEM)
716
682
field= ((Item_field*) args[0])->field;
718
if ((field= create_tmp_field_from_field(current_session, field, name, table,
684
if ((field= create_tmp_field_from_field(current_thd, field, name, table,
719
685
NULL, convert_blob_length)))
720
686
field->flags&= ~NOT_NULL_FLAG;
726
692
fields creations separately.
728
694
switch (args[0]->field_type()) {
729
case DRIZZLE_TYPE_DATE:
730
field= new Field_date(maybe_null, name, collation.collation);
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);
732
701
case DRIZZLE_TYPE_TIMESTAMP:
733
702
case DRIZZLE_TYPE_DATETIME:
751
720
check if the following assignments are really needed
753
Item_sum_sum::Item_sum_sum(Session *session, Item_sum_sum *item)
754
:Item_sum_num(session, item), hybrid_type(item->hybrid_type),
722
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item)
723
:Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
755
724
curr_dec_buff(item->curr_dec_buff)
757
726
/* TODO: check if the following assignments are really needed */
767
Item *Item_sum_sum::copy_or_same(Session* session)
736
Item *Item_sum_sum::copy_or_same(THD* thd)
769
return new (session->mem_root) Item_sum_sum(session, this);
738
return new (thd->mem_root) Item_sum_sum(thd, this);
888
861
static int item_sum_distinct_walk(void *element,
862
element_count num_of_dups __attribute__((unused)),
892
865
return ((Item_sum_distinct*) (item))->unique_walk_function(element);
895
872
/* Item_sum_distinct */
897
874
Item_sum_distinct::Item_sum_distinct(Item *item_arg)
910
Item_sum_distinct::Item_sum_distinct(Session *session, Item_sum_distinct *original)
911
:Item_sum_num(session, original), val(original->val), tree(0),
887
Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
888
:Item_sum_num(thd, original), val(original->val), tree(0),
912
889
table_field_type(original->table_field_type)
948
925
return &fast_decimal_traits_instance;
952
928
void Item_sum_distinct::fix_length_and_dec()
954
930
assert(args[0]->fixed);
956
null_value= maybe_null= true;
957
932
table_field_type= args[0]->field_type();
959
934
/* Adjust tmp table type according to the chosen aggregation type */
994
enum Item_result Item_sum_distinct::result_type () const
996
return val.traits->type();
1002
971
check that the case of CHAR(0) works OK
1004
bool Item_sum_distinct::setup(Session *session)
973
bool Item_sum_distinct::setup(THD *thd)
1006
List<CreateField> field_list;
1007
CreateField field_def; /* field definition */
975
List<Create_field> field_list;
976
Create_field field_def; /* field definition */
1008
977
/* It's legal to call setup() more than once when in a subquery */
1023
992
assert(args[0]->fixed);
1025
994
field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
1026
args[0]->decimals, args[0]->maybe_null);
995
args[0]->decimals, args[0]->maybe_null,
996
args[0]->unsigned_flag);
1028
if (! (table= session->create_virtual_tmp_table(field_list)))
998
if (! (table= create_virtual_tmp_table(thd, field_list)))
1031
1001
/* XXX: check that the case of CHAR(0) works OK */
1032
tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
1002
tree_key_length= table->s->reclength - table->s->null_bytes;
1035
1005
Unique handles all unique elements in a tree until they can't fit
1037
1007
simple_raw_key_cmp because the table contains numbers only; decimals
1038
1008
are converted to binary representation as well.
1040
tree= new Unique(simple_raw_key_cmp, &tree_key_length,
1042
(size_t)session->variables.max_heap_table_size);
1010
tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length,
1011
thd->variables.max_heap_table_size);
1044
1013
is_evaluated= false;
1045
1014
return(tree == 0);
1049
1018
bool Item_sum_distinct::add()
1051
args[0]->save_in_field(table->getField(0), false);
1020
args[0]->save_in_field(table->field[0], false);
1052
1021
is_evaluated= false;
1053
if (!table->getField(0)->is_null())
1022
if (!table->field[0]->is_null())
1058
1027
'0' values are also stored in the tree. This doesn't matter
1059
1028
for SUM(DISTINCT), but is important for AVG(DISTINCT)
1061
return tree->unique_add(table->getField(0)->ptr);
1030
return tree->unique_add(table->field[0]->ptr);
1067
1036
bool Item_sum_distinct::unique_walk_function(void *element)
1069
memcpy(table->getField(0)->ptr, element, tree_key_length);
1038
memcpy(table->field[0]->ptr, element, tree_key_length);
1071
val.traits->add(&val, table->getField(0));
1040
val.traits->add(&val, table->field[0]);
1157
1126
Item_sum_avg_distinct::fix_length_and_dec()
1159
1128
Item_sum_distinct::fix_length_and_dec();
1160
prec_increment= current_session->variables.div_precincrement;
1129
prec_increment= current_thd->variables.div_precincrement;
1162
1131
AVG() will divide val by count. We need to reserve digits
1163
1132
after decimal point as the result can be fractional.
1165
decimals= min(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
1134
decimals= cmin(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
1182
Item *Item_sum_count::copy_or_same(Session* session)
1151
Item *Item_sum_count::copy_or_same(THD* thd)
1184
return new (session->mem_root) Item_sum_count(session, this);
1153
return new (thd->mem_root) Item_sum_count(thd, this);
1221
1190
Item_sum_sum::fix_length_and_dec();
1222
1191
maybe_null=null_value=1;
1223
prec_increment= current_session->variables.div_precincrement;
1192
prec_increment= current_thd->variables.div_precincrement;
1224
1193
if (hybrid_type == DECIMAL_RESULT)
1226
1195
int precision= args[0]->decimal_precision() + prec_increment;
1227
decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1196
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1228
1197
max_length= my_decimal_precision_to_length(precision, decimals,
1229
1198
unsigned_flag);
1230
f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1199
f_precision= cmin(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1231
1200
f_scale= args[0]->decimals;
1232
1201
dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
1235
decimals= min(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
1204
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
1236
1205
max_length= args[0]->max_length + prec_increment;
1241
Item *Item_sum_avg::copy_or_same(Session* session)
1210
Item *Item_sum_avg::copy_or_same(THD* thd)
1243
return new (session->mem_root) Item_sum_avg(session, this);
1212
return new (thd->mem_root) Item_sum_avg(thd, this);
1247
1216
Field *Item_sum_avg::create_tmp_field(bool group, Table *table,
1217
uint32_t convert_blob_len __attribute__((unused)))
1258
1227
field= new Field_varstring(((hybrid_type == DECIMAL_RESULT) ?
1259
1228
dec_bin_size : sizeof(double)) + sizeof(int64_t),
1260
0, name, table->getMutableShare(), &my_charset_bin);
1229
0, name, table->s, &my_charset_bin);
1262
1231
else if (hybrid_type == DECIMAL_RESULT)
1263
field= new Field_decimal(max_length, maybe_null, name,
1264
decimals, unsigned_flag);
1232
field= new Field_new_decimal(max_length, maybe_null, name,
1233
decimals, unsigned_flag);
1266
1235
field= new Field_double(max_length, maybe_null, name, decimals, true);
1301
int64_t Item_sum_avg::val_int()
1303
return (int64_t) rint(val_real());
1307
1270
my_decimal *Item_sum_avg::val_decimal(my_decimal *val)
1309
1272
my_decimal sum_buff, cnt;
1349
1312
return sqrt(nr);
1352
Item *Item_sum_std::copy_or_same(Session* session)
1315
Item *Item_sum_std::copy_or_same(THD* thd)
1354
return new (session->mem_root) Item_sum_std(session, this);
1317
return new (thd->mem_root) Item_sum_std(thd, this);
1406
Item_sum_variance::Item_sum_variance(Session *session, Item_sum_variance *item):
1407
Item_sum_num(session, item), hybrid_type(item->hybrid_type),
1369
Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item):
1370
Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
1408
1371
count(item->count), sample(item->sample),
1409
1372
prec_increment(item->prec_increment)
1416
1379
void Item_sum_variance::fix_length_and_dec()
1418
1381
maybe_null= null_value= 1;
1419
prec_increment= current_session->variables.div_precincrement;
1382
prec_increment= current_thd->variables.div_precincrement;
1422
1385
According to the SQL2003 standard (Part 2, Foundations; sec 10.9,
1423
aggregate function; paragraph 7h of Syntax Rules), "the declared
1386
aggregate function; paragraph 7h of Syntax Rules), "the declared
1424
1387
type of the result is an implementation-defined aproximate numeric
1429
1392
switch (args[0]->result_type()) {
1430
1393
case REAL_RESULT:
1431
1394
case STRING_RESULT:
1432
decimals= min(args[0]->decimals + 4, (int)NOT_FIXED_DEC);
1395
decimals= cmin(args[0]->decimals + 4, NOT_FIXED_DEC);
1434
1397
case INT_RESULT:
1435
1398
case DECIMAL_RESULT:
1437
1400
int precision= args[0]->decimal_precision()*2 + prec_increment;
1438
decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1401
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1439
1402
max_length= my_decimal_precision_to_length(precision, decimals,
1440
1403
unsigned_flag);
1452
Item *Item_sum_variance::copy_or_same(Session* session)
1415
Item *Item_sum_variance::copy_or_same(THD* thd)
1454
return new (session->mem_root) Item_sum_variance(session, this);
1417
return new (thd->mem_root) Item_sum_variance(thd, this);
1471
1434
The easiest way is to do this is to store both value in a string
1472
1435
and unpack on access.
1474
field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, table->getMutableShare(), &my_charset_bin);
1437
field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, table->s, &my_charset_bin);
1477
1440
field= new Field_double(max_length, maybe_null, name, decimals, true);
1486
1449
void Item_sum_variance::clear()
1491
1454
bool Item_sum_variance::add()
1494
1457
Why use a temporary variable? We don't know if it is null until we
1495
1458
evaluate it, which has the side-effect of setting null_value .
1497
1460
double nr= args[0]->val_real();
1499
1462
if (!args[0]->null_value)
1500
1463
variance_fp_recurrence_next(&recurrence_m, &recurrence_s, &count, nr);
1739
Item *Item_sum_min::copy_or_same(Session* session)
1695
Item *Item_sum_min::copy_or_same(THD* thd)
1741
return new (session->mem_root) Item_sum_min(session, this);
1697
return new (thd->mem_root) Item_sum_min(thd, this);
1803
Item *Item_sum_max::copy_or_same(Session* session)
1759
Item *Item_sum_max::copy_or_same(THD* thd)
1805
return new (session->mem_root) Item_sum_max(session, this);
1761
return new (thd->mem_root) Item_sum_max(thd, this);
1878
1834
bits= reset_bits;
1881
Item *Item_sum_or::copy_or_same(Session* session)
1837
Item *Item_sum_or::copy_or_same(THD* thd)
1883
return new (session->mem_root) Item_sum_or(session, this);
1839
return new (thd->mem_root) Item_sum_or(thd, this);
1895
Item *Item_sum_xor::copy_or_same(Session* session)
1851
Item *Item_sum_xor::copy_or_same(THD* thd)
1897
return new (session->mem_root) Item_sum_xor(session, this);
1853
return new (thd->mem_root) Item_sum_xor(thd, this);
1909
Item *Item_sum_and::copy_or_same(Session* session)
1865
Item *Item_sum_and::copy_or_same(THD* thd)
1911
return new (session->mem_root) Item_sum_and(session, this);
1867
return new (thd->mem_root) Item_sum_and(thd, this);
2452
int64_t Item_variance_field::val_int()
2454
/* can't be fix_fields()ed */
2455
return (int64_t) rint(val_real());
2459
2408
double Item_variance_field::val_real()
2461
2410
// fix_fields() never calls for this Item
2494
2443
int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
2496
2445
Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
2497
Field **field = item->table->getFields();
2498
Field **field_end= field + item->table->getShare()->sizeFields();
2446
Field **field = item->table->field;
2447
Field **field_end= field + item->table->s->fields;
2499
2448
uint32_t *lengths=item->field_lengths;
2500
2449
for (; field < field_end; ++field)
2513
static int count_distinct_walk(void *,
2466
static int count_distinct_walk(void *elem __attribute__((unused)),
2467
element_count count __attribute__((unused)),
2517
2470
(*((uint64_t*)arg))++;
2521
2480
void Item_sum_count_distinct::cleanup()
2523
2482
Item_sum_int::cleanup();
2571
bool Item_sum_count_distinct::setup(Session *session)
2531
bool Item_sum_count_distinct::setup(THD *thd)
2573
2533
List<Item> list;
2574
Select_Lex *select_lex= session->lex->current_select;
2534
SELECT_LEX *select_lex= thd->lex->current_select;
2577
2537
Setup can be called twice for ROLLUP items. This is a bug.
2599
2559
tmp_table_param->force_copy_fields= force_copy_fields;
2600
2560
assert(table == 0);
2602
if (!(table= create_tmp_table(session, tmp_table_param, list, (order_st*) 0, 1,
2562
if (!(table= create_tmp_table(thd, tmp_table_param, list, (order_st*) 0, 1,
2604
(select_lex->options | session->options),
2564
(select_lex->options | thd->options),
2605
2565
HA_POS_ERROR, (char*)"")))
2609
table->cursor->extra(HA_EXTRA_NO_ROWS); // Don't update rows
2567
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
2610
2568
table->no_rows=1;
2612
if (table->getShare()->db_type() == heap_engine)
2570
if (table->s->db_type() == heap_hton)
2615
2573
No blobs, otherwise it would have been MyISAM: set up a compare
2618
2576
qsort_cmp2 compare_key;
2620
Field **field= table->getFields();
2621
Field **field_end= field + table->getShare()->sizeFields();
2578
Field **field= table->field;
2579
Field **field_end= field + table->s->fields;
2622
2580
bool all_binary= true;
2624
2582
for (tree_key_length= 0; field < field_end; ++field)
2656
2614
uint32_t *length;
2657
2615
compare_key= (qsort_cmp2) composite_key_cmp;
2658
2616
cmp_arg= (void*) this;
2659
field_lengths= (uint32_t*) session->alloc(table->getShare()->sizeFields() * sizeof(uint32_t));
2660
for (tree_key_length= 0, length= field_lengths, field= table->getFields();
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;
2661
2619
field < field_end; ++field, ++length)
2663
2621
*length= (*field)->pack_length();
2668
2626
assert(tree == 0);
2669
2627
tree= new Unique(compare_key, cmp_arg, tree_key_length,
2670
(size_t)session->variables.max_heap_table_size);
2628
thd->variables.max_heap_table_size);
2672
2630
The only time tree_key_length could be 0 is if someone does
2673
2631
count(distinct) on a char(0) field - stupid thing to do,
2685
Item *Item_sum_count_distinct::copy_or_same(Session* session)
2643
Item *Item_sum_count_distinct::copy_or_same(THD* thd)
2687
return new (session->mem_root) Item_sum_count_distinct(session, this);
2645
return new (thd->mem_root) Item_sum_count_distinct(thd, this);
2699
2657
else if (table)
2701
table->cursor->extra(HA_EXTRA_NO_CACHE);
2702
table->cursor->ha_delete_all_rows();
2703
table->cursor->extra(HA_EXTRA_WRITE_CACHE);
2659
table->file->extra(HA_EXTRA_NO_CACHE);
2660
table->file->ha_delete_all_rows();
2661
table->file->extra(HA_EXTRA_WRITE_CACHE);
2712
2670
copy_fields(tmp_table_param);
2713
2671
copy_funcs(tmp_table_param->items_to_copy);
2715
for (Field **field= table->getFields() ; *field ; field++)
2673
for (Field **field=table->field ; *field ; field++)
2717
2674
if ((*field)->is_real_null(0))
2719
2675
return 0; // Don't count NULL
2723
2677
is_evaluated= false;
2729
2683
bloat the tree without providing any valuable info. Besides,
2730
2684
key_length used to initialize the tree didn't include space for them.
2732
return tree->unique_add(table->record[0] + table->getShare()->null_bytes);
2686
return tree->unique_add(table->record[0] + table->s->null_bytes);
2734
if ((error= table->cursor->insertRecord(table->record[0])) &&
2735
table->cursor->is_fatal_error(error, HA_CHECK_DUP))
2688
if ((error= table->file->ha_write_row(table->record[0])) &&
2689
table->file->is_fatal_error(error, HA_CHECK_DUP))
2757
2711
return (int64_t) count;
2760
error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2714
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2764
table->print_error(error, MYF(0));
2718
table->file->print_error(error, MYF(0));
2767
return table->cursor->stats.records;
2721
return table->file->stats.records;
2770
2724
/*****************************************************************************
2781
2735
*****************************************************************************/
2785
2739
Compares the values for fields in expr list of GROUP_CONCAT.
2788
2742
GROUP_CONCAT([DISTINCT] expr [,expr ...]
2789
2743
[order_st BY {unsigned_integer | col_name | expr}
2790
2744
[ASC | DESC] [,col_name ...]]
2791
2745
[SEPARATOR str_val])
2794
@retval -1 : key1 < key2
2748
@retval -1 : key1 < key2
2795
2749
@retval 0 : key1 = key2
2796
@retval 1 : key1 > key2
2750
@retval 1 : key1 > key2
2799
int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
2753
int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
2800
2754
const void* key2)
2802
2756
Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
2805
2759
for (uint32_t i= 0; i < item_func->arg_count_field; i++)
2807
2761
Item *item= item_func->args[i];
2809
2763
If field_item is a const item then either get_tp_table_field returns 0
2810
or it is an item over a const table.
2764
or it is an item over a const table.
2812
2766
if (item->const_item())
2819
2773
Field *field= item->get_tmp_table_field();
2821
uint32_t offset= field->offset(field->getTable()->record[0])-table->getShare()->null_bytes;
2775
uint32_t offset= field->offset(field->table->record[0])-table->s->null_bytes;
2822
2776
if((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2830
function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
2784
function of sort for syntax: GROUP_CONCAT(expr,... order_st BY col,... )
2833
int group_concat_key_cmp_with_order(void* arg, const void* key1,
2787
int group_concat_key_cmp_with_order(void* arg, const void* key1,
2834
2788
const void* key2)
2836
2790
Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
2848
2802
the temporary table, not the original field
2850
2804
Field *field= item->get_tmp_table_field();
2852
2806
If item is a const item then either get_tp_table_field returns 0
2853
or it is an item over a const table.
2807
or it is an item over a const table.
2855
2809
if (field && !item->const_item())
2858
uint32_t offset= (field->offset(field->getTable()->record[0]) -
2859
table->getShare()->null_bytes);
2812
uint32_t offset= (field->offset(field->table->record[0]) -
2813
table->s->null_bytes);
2860
2814
if ((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2861
2815
return (*order_item)->asc ? res : -res;
2874
2828
Append data from current leaf to item->result.
2877
int dump_leaf_key(unsigned char* key, uint32_t ,
2831
int dump_leaf_key(unsigned char* key, element_count count __attribute__((unused)),
2878
2832
Item_func_group_concat *item)
2880
2834
Table *table= item->table;
2881
String tmp((char *)table->getUpdateRecord(), table->getShare()->getRecordLength(),
2835
String tmp((char *)table->record[1], table->s->reclength,
2882
2836
default_charset_info);
2884
2838
String *result= &item->result;
2905
2859
because it contains both order and arg list fields.
2907
2861
Field *field= (*arg)->get_tmp_table_field();
2908
uint32_t offset= (field->offset(field->getTable()->record[0]) -
2909
table->getShare()->null_bytes);
2910
assert(offset < table->getShare()->getRecordLength());
2862
uint32_t offset= (field->offset(field->table->record[0]) -
2863
table->s->null_bytes);
2864
assert(offset < table->s->reclength);
2911
2865
res= field->val_str(&tmp, key + offset);
2956
2910
bool distinct_arg, List<Item> *select_list,
2957
2911
SQL_LIST *order_list, String *separator_arg)
2958
2912
:tmp_table_param(0), warning(0),
2959
separator(separator_arg), tree(NULL), unique_filter(NULL), table(0),
2913
separator(separator_arg), tree(0), unique_filter(NULL), table(0),
2960
2914
order(0), context(context_arg),
2961
2915
arg_count_order(order_list ? order_list->elements : 0),
2962
2916
arg_count_field(select_list->elements),
2977
2931
(for possible order items in temporare tables)
2978
2932
order - arg_count_order
2980
if (!(args= (Item**) memory::sql_alloc(sizeof(Item*) * arg_count +
2934
if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
2981
2935
sizeof(order_st*)*arg_count_order)))
3007
Item_func_group_concat::Item_func_group_concat(Session *session,
2961
Item_func_group_concat::Item_func_group_concat(THD *thd,
3008
2962
Item_func_group_concat *item)
3009
:Item_sum(session, item),
2963
:Item_sum(thd, item),
3010
2964
tmp_table_param(item->tmp_table_param),
3011
2965
warning(item->warning),
3012
2966
separator(item->separator),
3040
2994
char warn_buff[DRIZZLE_ERRMSG_SIZE];
3041
snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3042
warning->set_msg(current_session, warn_buff);
2995
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
2996
warning->set_msg(current_thd, warn_buff);
3070
3025
char warn_buff[DRIZZLE_ERRMSG_SIZE];
3071
snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3072
warning->set_msg(session, warn_buff);
3026
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3027
warning->set_msg(thd, warn_buff);
3082
Item *Item_func_group_concat::copy_or_same(Session* session)
3037
Item *Item_func_group_concat::copy_or_same(THD* thd)
3084
return new (session->mem_root) Item_func_group_concat(session, this);
3039
return new (thd->mem_root) Item_func_group_concat(thd, this);
3121
3076
null_value= false;
3122
3077
bool row_eligible= true;
3126
3081
/* Filter out duplicate rows. */
3127
3082
uint32_t count= unique_filter->elements_in_tree();
3128
unique_filter->unique_add(table->record[0] + table->getShare()->null_bytes);
3083
unique_filter->unique_add(table->record[0] + table->s->null_bytes);
3129
3084
if (count == unique_filter->elements_in_tree())
3130
3085
row_eligible= false;
3133
3088
TREE_ELEMENT *el= 0; // Only for safety
3134
3089
if (row_eligible && tree)
3135
el= tree_insert(tree, table->record[0] + table->getShare()->null_bytes, 0,
3090
el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
3136
3091
tree->custom_arg);
3138
3093
If the row is not a duplicate (el->count == 1)
3142
3097
if (row_eligible && !warning_for_row &&
3143
3098
(!tree || (el->count == 1 && distinct && !arg_count_order)))
3144
dump_leaf_key(table->record[0] + table->getShare()->null_bytes, 1, this);
3099
dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3151
Item_func_group_concat::fix_fields(Session *session, Item **ref)
3106
Item_func_group_concat::fix_fields(THD *thd, Item **ref)
3153
3108
uint32_t i; /* for loop variable */
3154
3109
assert(fixed == 0);
3156
if (init_sum_func_check(session))
3111
if (init_sum_func_check(thd))
3180
3135
result.set_charset(collation.collation);
3181
3136
result_field= 0;
3183
max_length= (size_t)session->variables.group_concat_max_len;
3185
if (check_sum_func(session, ref))
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))
3193
bool Item_func_group_concat::setup(Session *session)
3169
bool Item_func_group_concat::setup(THD *thd)
3195
3171
List<Item> list;
3196
Select_Lex *select_lex= session->lex->current_select;
3172
SELECT_LEX *select_lex= thd->lex->current_select;
3199
3175
Currently setup() can be called twice. Please add
3233
3209
tmp table columns.
3235
3211
if (arg_count_order &&
3236
setup_order(session, args, context->table_list, list, all_fields, *order))
3212
setup_order(thd, args, context->table_list, list, all_fields, *order))
3239
3215
count_field_types(select_lex, tmp_table_param, all_fields, 0);
3245
3221
Currently we have to force conversion of BLOB values to VARCHAR's
3246
if we are to store them in TREE objects used for ORDER BY and
3222
if we are to store them in TREE objects used for order_st BY and
3247
3223
DISTINCT. This leads to truncation if the BLOB's size exceeds
3248
3224
Field_varstring::MAX_SIZE.
3250
set_if_smaller(tmp_table_param->convert_blob_length,
3226
set_if_smaller(tmp_table_param->convert_blob_length,
3251
3227
Field_varstring::MAX_SIZE);
3255
3231
We have to create a temporary table to get descriptions of fields
3256
3232
(types, sizes and so on).
3258
Note that in the table, we first have the ORDER BY fields, then the
3234
Note that in the table, we first have the order_st BY fields, then the
3261
if (!(table= create_tmp_table(session, tmp_table_param, all_fields,
3237
if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
3262
3238
(order_st*) 0, 0, true,
3263
(select_lex->options | session->options),
3239
(select_lex->options | thd->options),
3264
3240
HA_POS_ERROR, (char*) "")))
3269
table->cursor->extra(HA_EXTRA_NO_ROWS);
3242
table->file->extra(HA_EXTRA_NO_ROWS);
3270
3243
table->no_rows= 1;
3274
3247
Don't reserve space for NULLs: if any of gconcat arguments is NULL,
3275
3248
the row is not added to the result.
3277
uint32_t tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
3250
uint32_t tree_key_length= table->s->reclength - table->s->null_bytes;
3279
3252
if (arg_count_order)
3281
3254
tree= &tree_base;
3283
3256
Create a tree for sorting. The tree is used to sort (according to the
3284
syntax of this function). If there is no ORDER BY clause, we don't
3257
syntax of this function). If there is no order_st BY clause, we don't
3285
3258
create this tree.
3287
init_tree(tree, (uint32_t) min(session->variables.max_heap_table_size,
3288
(uint64_t)(session->variables.sortbuff_size/16)),
3291
group_concat_key_cmp_with_order , false, NULL, (void*) this);
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);
3295
3267
unique_filter= new Unique(group_concat_key_cmp_with_distinct,
3297
3269
tree_key_length,
3298
(size_t)session->variables.max_heap_table_size);
3270
thd->variables.max_heap_table_size);
3315
double Item_func_group_concat::val_real()
3317
String *res; res=val_str(&str_value);
3318
return res ? internal::my_atof(res->c_ptr()) : 0.0;
3321
int64_t Item_func_group_concat::val_int()
3326
if (!(res= val_str(&str_value)))
3328
end_ptr= (char*) res->ptr()+ res->length();
3329
return internal::my_strtoll10(res->ptr(), &end_ptr, &error);
3332
String* Item_func_group_concat::val_str(String* )
3288
String* Item_func_group_concat::val_str(String* str __attribute__((unused)))
3334
3290
assert(fixed == 1);
3335
3291
if (null_value)