12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
21
21
Sum functions (COUNT, MIN...)
23
#include <drizzled/server_includes.h>
26
24
#include <drizzled/sql_select.h>
27
25
#include <drizzled/error.h>
28
26
#include <drizzled/hybrid_type_traits.h>
33
31
#include <drizzled/item/sum.h>
34
32
#include <drizzled/field/decimal.h>
35
33
#include <drizzled/field/double.h>
36
#include <drizzled/field/int64.h>
34
#include <drizzled/field/int64_t.h>
37
35
#include <drizzled/field/date.h>
36
#include <drizzled/field/timetype.h>
38
37
#include <drizzled/field/datetime.h>
40
#include "drizzled/internal/m_string.h"
41
#if defined(CMATH_NAMESPACE)
42
using namespace CMATH_NAMESPACE;
49
45
extern my_decimal decimal_zero;
50
extern plugin::StorageEngine *heap_engine;
53
48
Prepare an aggregate function item for checking context conditions.
105
100
If the context conditions are not met the method reports an error.
106
101
If the set function is aggregated in some outer subquery the method
107
102
adds it to the chain of items for such set functions that is attached
108
to the the Select_Lex structure for this subquery.
103
to the the st_select_lex structure for this subquery.
110
105
A number of designated members of the object are used to check the
111
106
conditions. They are specified in the comment before the Item_sum
268
263
in_sum_func->outer_fields.push_back(field);
272
sel->full_group_by_flag.set(NON_AGG_FIELD_USED);
266
sel->full_group_by_flag|= NON_AGG_FIELD_USED;
275
268
if (sel->nest_level > aggr_level &&
276
(sel->full_group_by_flag.test(SUM_FUNC_USED)) &&
277
! sel->group_list.elements)
269
(sel->full_group_by_flag & SUM_FUNC_USED) &&
270
!sel->group_list.elements)
279
272
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
280
273
ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
316
309
bool Item_sum::register_sum_func(Session *session, Item **ref)
319
312
nesting_map allow_sum_func= session->lex->allow_sum_func;
320
313
for (sl= session->lex->current_select->master_unit()->outer_select() ;
321
314
sl && sl->nest_level > max_arg_level;
357
350
Mark Item_subselect(s) as containing aggregate function all the way up
358
351
to aggregate function's calculation context.
359
352
Note that we must not mark the Item of calculation context itself
360
because with_sum_func on the calculation context Select_Lex is
353
because with_sum_func on the calculation context st_select_lex is
361
354
already set above.
363
356
with_sum_func being set for an Item means that this Item refers
365
358
or through intermediate items to an aggregate function that is calculated
366
359
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
361
with_sum_func being set for an st_select_lex means that this st_select_lex
369
362
has aggregate functions directly referenced (i.e. not through a sub-select).
371
364
for (sl= session->lex->current_select;
381
374
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
382
375
forced_const(false)
384
if ((args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
377
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
387
380
List_iterator_fast<Item> li(list);
420
413
void Item_sum::mark_as_sum_func()
422
Select_Lex *cur_select= current_session->lex->current_select;
415
SELECT_LEX *cur_select= current_session->lex->current_select;
423
416
cur_select->n_sum_items++;
424
417
cur_select->with_sum_func= 1;
425
418
with_sum_func= 1;
429
void Item_sum::make_field(SendField *tmp_field)
422
void Item_sum::make_field(Send_field *tmp_field)
431
424
if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
507
Field *Item_sum::create_tmp_field(bool ,
500
Field *Item_sum::create_tmp_field(bool group __attribute__((unused)),
509
502
uint32_t convert_blob_length)
513
505
switch (result_type()) {
514
506
case REAL_RESULT:
515
507
field= new Field_double(max_length, maybe_null, name, decimals, true);
519
field= new field::Int64(max_length, maybe_null, name, unsigned_flag);
510
field= new Field_int64_t(max_length, maybe_null, name, unsigned_flag);
522
512
case STRING_RESULT:
523
513
if (max_length/collation.collation->mbmaxlen <= 255 ||
524
514
convert_blob_length > Field_varstring::MAX_SIZE ||
525
515
!convert_blob_length)
527
516
return make_string_field(table);
530
table->setVariableWidth();
531
517
field= new Field_varstring(convert_blob_length, maybe_null,
532
name, collation.collation);
518
name, table->s, collation.collation);
535
520
case DECIMAL_RESULT:
536
field= new Field_decimal(max_length, maybe_null, name,
537
decimals, unsigned_flag);
521
field= new Field_new_decimal(max_length, maybe_null, name,
522
decimals, unsigned_flag);
541
526
// This case should never be choosen
547
531
field->init(table);
737
722
case DRIZZLE_TYPE_DATE:
738
723
field= new Field_date(maybe_null, name, collation.collation);
725
case DRIZZLE_TYPE_TIME:
726
field= new Field_time(maybe_null, name, collation.collation);
740
728
case DRIZZLE_TYPE_TIMESTAMP:
741
729
case DRIZZLE_TYPE_DATETIME:
742
730
field= new Field_datetime(maybe_null, name, collation.collation);
806
794
case DECIMAL_RESULT:
808
/* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
809
int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
810
max_length= my_decimal_precision_to_length(precision, decimals,
813
hybrid_type= DECIMAL_RESULT;
814
my_decimal_set_zero(dec_buffs);
796
/* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
797
int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
798
max_length= my_decimal_precision_to_length(precision, decimals,
801
hybrid_type= DECIMAL_RESULT;
802
my_decimal_set_zero(dec_buffs);
894
888
static int item_sum_distinct_walk(void *element,
889
element_count num_of_dups __attribute__((unused)),
898
892
return ((Item_sum_distinct*) (item))->unique_walk_function(element);
901
899
/* Item_sum_distinct */
903
901
Item_sum_distinct::Item_sum_distinct(Item *item_arg)
970
967
table_field_type= DRIZZLE_TYPE_DOUBLE;
974
Preserving int8, int16, int32 field types gives ~10% performance boost
975
as the size of result tree becomes significantly smaller.
976
Another speed up we gain by using int64_t for intermediate
977
calculations. The range of int64 is enough to hold sum 2^32 distinct
978
integers each <= 2^32.
980
if (table_field_type == DRIZZLE_TYPE_LONG)
982
val.traits= Hybrid_type_traits_fast_decimal::instance();
985
table_field_type= DRIZZLE_TYPE_LONGLONG;
971
Preserving int8, int16, int32 field types gives ~10% performance boost
972
as the size of result tree becomes significantly smaller.
973
Another speed up we gain by using int64_t for intermediate
974
calculations. The range of int64 is enough to hold sum 2^32 distinct
975
integers each <= 2^32.
977
if (table_field_type == DRIZZLE_TYPE_LONG)
979
val.traits= Hybrid_type_traits_fast_decimal::instance();
982
table_field_type= DRIZZLE_TYPE_LONGLONG;
987
984
case DECIMAL_RESULT:
988
985
val.traits= Hybrid_type_traits_decimal::instance();
989
986
if (table_field_type != DRIZZLE_TYPE_LONGLONG)
990
table_field_type= DRIZZLE_TYPE_DECIMAL;
987
table_field_type= DRIZZLE_TYPE_NEWDECIMAL;
996
993
val.traits->fix_length_and_dec(this, args[0]);
1010
1007
bool Item_sum_distinct::setup(Session *session)
1012
List<CreateField> field_list;
1013
CreateField field_def; /* field definition */
1009
List<Create_field> field_list;
1010
Create_field field_def; /* field definition */
1014
1011
/* It's legal to call setup() more than once when in a subquery */
1029
1026
assert(args[0]->fixed);
1031
1028
field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
1032
args[0]->decimals, args[0]->maybe_null);
1029
args[0]->decimals, args[0]->maybe_null,
1030
args[0]->unsigned_flag);
1034
if (! (table= session->getInstanceTable(field_list)))
1032
if (! (table= create_virtual_tmp_table(session, field_list)))
1037
1035
/* XXX: check that the case of CHAR(0) works OK */
1038
tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
1036
tree_key_length= table->s->reclength - table->s->null_bytes;
1041
1039
Unique handles all unique elements in a tree until they can't fit
1043
1041
simple_raw_key_cmp because the table contains numbers only; decimals
1044
1042
are converted to binary representation as well.
1046
tree= new Unique(simple_raw_key_cmp, &tree_key_length,
1048
(size_t)session->variables.max_heap_table_size);
1044
tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length,
1045
session->variables.max_heap_table_size);
1050
1047
is_evaluated= false;
1051
1048
return(tree == 0);
1055
1052
bool Item_sum_distinct::add()
1057
args[0]->save_in_field(table->getField(0), false);
1054
args[0]->save_in_field(table->field[0], false);
1058
1055
is_evaluated= false;
1059
if (!table->getField(0)->is_null())
1056
if (!table->field[0]->is_null())
1064
1061
'0' values are also stored in the tree. This doesn't matter
1065
1062
for SUM(DISTINCT), but is important for AVG(DISTINCT)
1067
return tree->unique_add(table->getField(0)->ptr);
1064
return tree->unique_add(table->field[0]->ptr);
1073
1070
bool Item_sum_distinct::unique_walk_function(void *element)
1075
memcpy(table->getField(0)->ptr, element, tree_key_length);
1072
memcpy(table->field[0]->ptr, element, tree_key_length);
1077
val.traits->add(&val, table->getField(0));
1074
val.traits->add(&val, table->field[0]);
1168
1165
AVG() will divide val by count. We need to reserve digits
1169
1166
after decimal point as the result can be fractional.
1171
decimals= min(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
1168
decimals= cmin(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
1230
1227
if (hybrid_type == DECIMAL_RESULT)
1232
1229
int precision= args[0]->decimal_precision() + prec_increment;
1233
decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1230
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1234
1231
max_length= my_decimal_precision_to_length(precision, decimals,
1235
1232
unsigned_flag);
1236
f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1233
f_precision= cmin(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1237
1234
f_scale= args[0]->decimals;
1238
1235
dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
1241
decimals= min(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
1238
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
1242
1239
max_length= args[0]->max_length + prec_increment;
1261
1258
The easiest way is to do this is to store both value in a string
1262
1259
and unpack on access.
1264
table->setVariableWidth();
1265
1261
field= new Field_varstring(((hybrid_type == DECIMAL_RESULT) ?
1266
1262
dec_bin_size : sizeof(double)) + sizeof(int64_t),
1267
0, name, &my_charset_bin);
1263
0, name, table->s, &my_charset_bin);
1269
1265
else if (hybrid_type == DECIMAL_RESULT)
1270
field= new Field_decimal(max_length, maybe_null, name,
1271
decimals, unsigned_flag);
1266
field= new Field_new_decimal(max_length, maybe_null, name,
1267
decimals, unsigned_flag);
1273
1269
field= new Field_double(max_length, maybe_null, name, decimals, true);
1436
1432
switch (args[0]->result_type()) {
1437
1433
case REAL_RESULT:
1438
1434
case STRING_RESULT:
1439
decimals= min(args[0]->decimals + 4, (int)NOT_FIXED_DEC);
1435
decimals= cmin(args[0]->decimals + 4, NOT_FIXED_DEC);
1441
1437
case INT_RESULT:
1442
1438
case DECIMAL_RESULT:
1444
int precision= args[0]->decimal_precision()*2 + prec_increment;
1445
decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1446
max_length= my_decimal_precision_to_length(precision, decimals,
1440
int precision= args[0]->decimal_precision()*2 + prec_increment;
1441
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1442
max_length= my_decimal_precision_to_length(precision, decimals,
1451
1447
case ROW_RESULT:
1476
1474
The easiest way is to do this is to store both value in a string
1477
1475
and unpack on access.
1479
table->setVariableWidth();
1480
field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, &my_charset_bin);
1477
field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, table->s, &my_charset_bin);
1483
1480
field= new Field_double(max_length, maybe_null, name, decimals, true);
1619
1616
assert(fixed == 1);
1620
1617
if (null_value)
1623
1619
switch (hybrid_type) {
1624
1620
case STRING_RESULT:
1628
String *res; res=val_str(&str_value);
1629
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
1630
&end_not_used, &err_not_used) : 0.0);
1624
String *res; res=val_str(&str_value);
1625
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
1626
&end_not_used, &err_not_used) : 0.0);
1632
1628
case INT_RESULT:
1633
1629
return (double) sum_int;
1634
1630
case DECIMAL_RESULT:
1757
1750
switch (hybrid_type) {
1758
1751
case STRING_RESULT:
1753
String *result=args[0]->val_str(&tmp_value);
1754
if (!args[0]->null_value &&
1755
(null_value || sortcmp(&value,result,collation.collation) > 0))
1760
String *result=args[0]->val_str(&tmp_value);
1761
if (!args[0]->null_value &&
1762
(null_value || sortcmp(&value,result,collation.collation) > 0))
1764
value.copy(*result);
1757
value.copy(*result);
1769
1762
case INT_RESULT:
1764
int64_t nr=args[0]->val_int();
1765
if (!args[0]->null_value && (null_value ||
1767
(uint64_t) nr < (uint64_t) sum_int) ||
1768
(!unsigned_flag && nr < sum_int)))
1771
int64_t nr=args[0]->val_int();
1772
if (!args[0]->null_value && (null_value ||
1774
(uint64_t) nr < (uint64_t) sum_int) ||
1775
(!unsigned_flag && nr < sum_int)))
1782
1775
case DECIMAL_RESULT:
1777
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1778
if (!args[0]->null_value &&
1779
(null_value || (my_decimal_cmp(&sum_dec, val) > 0)))
1784
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1785
if (!args[0]->null_value &&
1786
(null_value || (my_decimal_cmp(&sum_dec, val) > 0)))
1788
my_decimal2decimal(val, &sum_dec);
1781
my_decimal2decimal(val, &sum_dec);
1793
1786
case REAL_RESULT:
1788
double nr= args[0]->val_real();
1789
if (!args[0]->null_value && (null_value || nr < sum))
1795
double nr= args[0]->val_real();
1796
if (!args[0]->null_value && (null_value || nr < sum))
1803
1796
case ROW_RESULT:
1804
1798
// This case should never be choosen
1820
1814
switch (hybrid_type) {
1821
1815
case STRING_RESULT:
1817
String *result=args[0]->val_str(&tmp_value);
1818
if (!args[0]->null_value &&
1819
(null_value || sortcmp(&value,result,collation.collation) < 0))
1823
String *result=args[0]->val_str(&tmp_value);
1824
if (!args[0]->null_value &&
1825
(null_value || sortcmp(&value,result,collation.collation) < 0))
1827
value.copy(*result);
1821
value.copy(*result);
1832
1826
case INT_RESULT:
1828
int64_t nr=args[0]->val_int();
1829
if (!args[0]->null_value && (null_value ||
1831
(uint64_t) nr > (uint64_t) sum_int) ||
1832
(!unsigned_flag && nr > sum_int)))
1834
int64_t nr=args[0]->val_int();
1835
if (!args[0]->null_value && (null_value ||
1837
(uint64_t) nr > (uint64_t) sum_int) ||
1838
(!unsigned_flag && nr > sum_int)))
1845
1839
case DECIMAL_RESULT:
1841
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1842
if (!args[0]->null_value &&
1843
(null_value || (my_decimal_cmp(val, &sum_dec) > 0)))
1847
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1848
if (!args[0]->null_value &&
1849
(null_value || (my_decimal_cmp(val, &sum_dec) > 0)))
1851
my_decimal2decimal(val, &sum_dec);
1845
my_decimal2decimal(val, &sum_dec);
1856
1850
case REAL_RESULT:
1852
double nr= args[0]->val_real();
1853
if (!args[0]->null_value && (null_value || nr > sum))
1858
double nr= args[0]->val_real();
1859
if (!args[0]->null_value && (null_value || nr > sum))
1866
1860
case ROW_RESULT:
1867
1862
// This case should never be choosen
1957
1951
switch(hybrid_type) {
1958
1952
case STRING_RESULT:
1960
char buff[MAX_FIELD_WIDTH];
1961
String tmp(buff,sizeof(buff),result_field->charset()),*res;
1963
res=args[0]->val_str(&tmp);
1964
if (args[0]->null_value)
1954
char buff[MAX_FIELD_WIDTH];
1955
String tmp(buff,sizeof(buff),result_field->charset()),*res;
1957
res=args[0]->val_str(&tmp);
1958
if (args[0]->null_value)
1960
result_field->set_null();
1961
result_field->reset();
1965
result_field->set_notnull();
1966
result_field->store(res->ptr(),res->length(),tmp.charset());
1972
int64_t nr=args[0]->val_int();
1976
if (args[0]->null_value)
1979
result_field->set_null();
1982
result_field->set_notnull();
1984
result_field->store(nr, unsigned_flag);
1989
double nr= args[0]->val_real();
1993
if (args[0]->null_value)
1996
result_field->set_null();
1999
result_field->set_notnull();
2001
result_field->store(nr);
2004
case DECIMAL_RESULT:
2006
my_decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
2010
if (args[0]->null_value)
1966
2011
result_field->set_null();
1967
result_field->reset();
1971
2013
result_field->set_notnull();
1972
result_field->store(res->ptr(),res->length(),tmp.charset());
1978
int64_t nr=args[0]->val_int();
1982
if (args[0]->null_value)
1985
result_field->set_null();
1988
result_field->set_notnull();
1990
result_field->store(nr, unsigned_flag);
1995
double nr= args[0]->val_real();
1999
if (args[0]->null_value)
2002
result_field->set_null();
2005
result_field->set_notnull();
2007
result_field->store(nr);
2010
case DECIMAL_RESULT:
2012
my_decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
2016
if (args[0]->null_value)
2017
result_field->set_null();
2019
result_field->set_notnull();
2022
We must store zero in the field as we will use the field value in
2025
if (!arg_dec) // Null
2026
arg_dec= &decimal_zero;
2027
result_field->store_decimal(arg_dec);
2016
We must store zero in the field as we will use the field value in
2019
if (!arg_dec) // Null
2020
arg_dec= &decimal_zero;
2021
result_field->store_decimal(arg_dec);
2030
2024
case ROW_RESULT:
2237
2231
if (!args[0]->null_value)
2239
result_field->val_str_internal(&tmp_value);
2233
result_field->val_str(&tmp_value);
2241
2235
if (result_field->is_null() ||
2242
2236
(cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
2503
2497
int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
2505
2499
Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
2506
Field **field = item->table->getFields();
2507
Field **field_end= field + item->table->getShare()->sizeFields();
2500
Field **field = item->table->field;
2501
Field **field_end= field + item->table->s->fields;
2508
2502
uint32_t *lengths=item->field_lengths;
2509
2503
for (; field < field_end; ++field)
2522
static int count_distinct_walk(void *,
2520
static int count_distinct_walk(void *elem __attribute__((unused)),
2521
element_count count __attribute__((unused)),
2526
2524
(*((uint64_t*)arg))++;
2530
2534
void Item_sum_count_distinct::cleanup()
2532
2536
Item_sum_int::cleanup();
2608
2613
tmp_table_param->force_copy_fields= force_copy_fields;
2609
2614
assert(table == 0);
2611
if (!(table= create_tmp_table(session, tmp_table_param, list, (Order*) 0, 1,
2616
if (!(table= create_tmp_table(session, tmp_table_param, list, (order_st*) 0, 1,
2613
2618
(select_lex->options | session->options),
2614
2619
HA_POS_ERROR, (char*)"")))
2618
table->cursor->extra(HA_EXTRA_NO_ROWS); // Don't update rows
2621
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
2619
2622
table->no_rows=1;
2621
if (table->getShare()->db_type() == heap_engine)
2624
if (table->s->db_type() == heap_hton)
2624
2627
No blobs, otherwise it would have been MyISAM: set up a compare
2627
2630
qsort_cmp2 compare_key;
2629
Field **field= table->getFields();
2630
Field **field_end= field + table->getShare()->sizeFields();
2632
Field **field= table->field;
2633
Field **field_end= field + table->s->fields;
2631
2634
bool all_binary= true;
2633
2636
for (tree_key_length= 0; field < field_end; ++field)
2665
2668
uint32_t *length;
2666
2669
compare_key= (qsort_cmp2) composite_key_cmp;
2667
2670
cmp_arg= (void*) this;
2668
field_lengths= (uint32_t*) session->alloc(table->getShare()->sizeFields() * sizeof(uint32_t));
2669
for (tree_key_length= 0, length= field_lengths, field= table->getFields();
2671
field_lengths= (uint32_t*) session->alloc(table->s->fields * sizeof(uint32_t));
2672
for (tree_key_length= 0, length= field_lengths, field= table->field;
2670
2673
field < field_end; ++field, ++length)
2672
2675
*length= (*field)->pack_length();
2677
2680
assert(tree == 0);
2678
2681
tree= new Unique(compare_key, cmp_arg, tree_key_length,
2679
(size_t)session->variables.max_heap_table_size);
2682
session->variables.max_heap_table_size);
2681
2684
The only time tree_key_length could be 0 is if someone does
2682
2685
count(distinct) on a char(0) field - stupid thing to do,
2708
2711
else if (table)
2710
table->cursor->extra(HA_EXTRA_NO_CACHE);
2711
table->cursor->ha_delete_all_rows();
2712
table->cursor->extra(HA_EXTRA_WRITE_CACHE);
2713
table->file->extra(HA_EXTRA_NO_CACHE);
2714
table->file->ha_delete_all_rows();
2715
table->file->extra(HA_EXTRA_WRITE_CACHE);
2719
2722
if (always_null)
2721
2724
copy_fields(tmp_table_param);
2722
if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
2725
copy_funcs(tmp_table_param->items_to_copy);
2725
for (Field **field= table->getFields() ; *field ; field++)
2727
for (Field **field=table->field ; *field ; field++)
2727
2728
if ((*field)->is_real_null(0))
2729
2729
return 0; // Don't count NULL
2733
2731
is_evaluated= false;
2739
2737
bloat the tree without providing any valuable info. Besides,
2740
2738
key_length used to initialize the tree didn't include space for them.
2742
return tree->unique_add(table->record[0] + table->getShare()->null_bytes);
2740
return tree->unique_add(table->record[0] + table->s->null_bytes);
2744
if ((error= table->cursor->insertRecord(table->record[0])) &&
2745
table->cursor->is_fatal_error(error, HA_CHECK_DUP))
2742
if ((error= table->file->ha_write_row(table->record[0])) &&
2743
table->file->is_fatal_error(error, HA_CHECK_DUP))
2767
2765
return (int64_t) count;
2770
error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2768
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2774
table->print_error(error, MYF(0));
2772
table->file->print_error(error, MYF(0));
2777
return table->cursor->stats.records;
2775
return table->file->stats.records;
2780
2778
/*****************************************************************************
2829
2827
Field *field= item->get_tmp_table_field();
2831
uint32_t offset= field->offset(field->getTable()->record[0])-table->getShare()->null_bytes;
2829
uint32_t offset= field->offset(field->table->record[0])-table->s->null_bytes;
2832
2830
if((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2840
function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
2838
function of sort for syntax: GROUP_CONCAT(expr,... order_st BY col,... )
2843
2841
int group_concat_key_cmp_with_order(void* arg, const void* key1,
2844
2842
const void* key2)
2846
2844
Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
2847
Order **order_item, **end;
2845
order_st **order_item, **end;
2848
2846
Table *table= grp_item->table;
2850
2848
for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
2865
2863
if (field && !item->const_item())
2868
uint32_t offset= (field->offset(field->getTable()->record[0]) -
2869
table->getShare()->null_bytes);
2866
uint32_t offset= (field->offset(field->table->record[0]) -
2867
table->s->null_bytes);
2870
2868
if ((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2871
2869
return (*order_item)->asc ? res : -res;
2884
2882
Append data from current leaf to item->result.
2887
int dump_leaf_key(unsigned char* key, uint32_t ,
2885
int dump_leaf_key(unsigned char* key, element_count count __attribute__((unused)),
2888
2886
Item_func_group_concat *item)
2890
2888
Table *table= item->table;
2891
String tmp((char *)table->getUpdateRecord(), table->getShare()->getRecordLength(),
2889
String tmp((char *)table->record[1], table->s->reclength,
2892
2890
default_charset_info);
2894
2892
String *result= &item->result;
2915
2913
because it contains both order and arg list fields.
2917
2915
Field *field= (*arg)->get_tmp_table_field();
2918
uint32_t offset= (field->offset(field->getTable()->record[0]) -
2919
table->getShare()->null_bytes);
2920
assert(offset < table->getShare()->getRecordLength());
2921
res= field->val_str_internal(&tmp, key + offset);
2916
uint32_t offset= (field->offset(field->table->record[0]) -
2917
table->s->null_bytes);
2918
assert(offset < table->s->reclength);
2919
res= field->val_str(&tmp, key + offset);
2924
2922
res= (*arg)->val_str(&tmp);
2966
2964
bool distinct_arg, List<Item> *select_list,
2967
2965
SQL_LIST *order_list, String *separator_arg)
2968
2966
:tmp_table_param(0), warning(0),
2969
separator(separator_arg), tree(NULL), unique_filter(NULL), table(0),
2967
separator(separator_arg), tree(0), unique_filter(NULL), table(0),
2970
2968
order(0), context(context_arg),
2971
2969
arg_count_order(order_list ? order_list->elements : 0),
2972
2970
arg_count_field(select_list->elements),
2987
2985
(for possible order items in temporare tables)
2988
2986
order - arg_count_order
2990
if (!(args= (Item**) memory::sql_alloc(sizeof(Item*) * arg_count +
2991
sizeof(Order*)*arg_count_order)))
2988
if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
2989
sizeof(order_st*)*arg_count_order)))
2994
order= (Order**)(args + arg_count);
2992
order= (order_st**)(args + arg_count);
2996
2994
/* fill args items of show and sort */
2997
2995
List_iterator_fast<Item> li(*select_list);
3002
3000
if (arg_count_order)
3004
Order **order_ptr= order;
3005
for (Order *order_item= (Order*) order_list->first;
3002
order_st **order_ptr= order;
3003
for (order_st *order_item= (order_st*) order_list->first;
3006
3004
order_item != NULL;
3007
3005
order_item= order_item->next)
3050
3048
char warn_buff[DRIZZLE_ERRMSG_SIZE];
3051
snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3049
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3052
3050
warning->set_msg(current_session, warn_buff);
3080
3079
char warn_buff[DRIZZLE_ERRMSG_SIZE];
3081
snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3080
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3082
3081
warning->set_msg(session, warn_buff);
3137
3135
/* Filter out duplicate rows. */
3138
3136
uint32_t count= unique_filter->elements_in_tree();
3139
unique_filter->unique_add(table->record[0] + table->getShare()->null_bytes);
3137
unique_filter->unique_add(table->record[0] + table->s->null_bytes);
3140
3138
if (count == unique_filter->elements_in_tree())
3141
3139
row_eligible= false;
3144
3142
TREE_ELEMENT *el= 0; // Only for safety
3145
3143
if (row_eligible && tree)
3146
el= tree_insert(tree, table->record[0] + table->getShare()->null_bytes, 0,
3144
el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
3147
3145
tree->custom_arg);
3149
3147
If the row is not a duplicate (el->count == 1)
3153
3151
if (row_eligible && !warning_for_row &&
3154
3152
(!tree || (el->count == 1 && distinct && !arg_count_order)))
3155
dump_leaf_key(table->record[0] + table->getShare()->null_bytes, 1, this);
3153
dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3191
3189
result.set_charset(collation.collation);
3192
3190
result_field= 0;
3194
max_length= (size_t)session->variables.group_concat_max_len;
3192
max_length= session->variables.group_concat_max_len;
3195
if (separator->needs_conversion(separator->length(), separator->charset(),
3196
collation.collation, &offset))
3198
uint32_t buflen= collation.collation->mbmaxlen * separator->length();
3199
uint32_t errors, conv_length;
3201
String *new_separator;
3203
if (!(buf= (char*) session->alloc(buflen)) ||
3204
!(new_separator= new(session->mem_root)
3205
String(buf, buflen, collation.collation)))
3208
conv_length= copy_and_convert(buf, buflen, collation.collation,
3209
separator->ptr(), separator->length(),
3210
separator->charset(), &errors);
3211
new_separator->length(conv_length);
3212
separator= new_separator;
3196
3215
if (check_sum_func(session, ref))
3256
3275
Currently we have to force conversion of BLOB values to VARCHAR's
3257
if we are to store them in TREE objects used for ORDER BY and
3276
if we are to store them in TREE objects used for order_st BY and
3258
3277
DISTINCT. This leads to truncation if the BLOB's size exceeds
3259
3278
Field_varstring::MAX_SIZE.
3266
3285
We have to create a temporary table to get descriptions of fields
3267
3286
(types, sizes and so on).
3269
Note that in the table, we first have the ORDER BY fields, then the
3288
Note that in the table, we first have the order_st BY fields, then the
3272
3291
if (!(table= create_tmp_table(session, tmp_table_param, all_fields,
3273
(Order*) 0, 0, true,
3292
(order_st*) 0, 0, true,
3274
3293
(select_lex->options | session->options),
3275
3294
HA_POS_ERROR, (char*) "")))
3280
table->cursor->extra(HA_EXTRA_NO_ROWS);
3296
table->file->extra(HA_EXTRA_NO_ROWS);
3281
3297
table->no_rows= 1;
3285
3301
Don't reserve space for NULLs: if any of gconcat arguments is NULL,
3286
3302
the row is not added to the result.
3288
uint32_t tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
3304
uint32_t tree_key_length= table->s->reclength - table->s->null_bytes;
3290
3306
if (arg_count_order)
3292
3308
tree= &tree_base;
3294
3310
Create a tree for sorting. The tree is used to sort (according to the
3295
syntax of this function). If there is no ORDER BY clause, we don't
3311
syntax of this function). If there is no order_st BY clause, we don't
3296
3312
create this tree.
3298
init_tree(tree, (uint32_t) min(session->variables.max_heap_table_size,
3299
(uint64_t)(session->variables.sortbuff_size/16)),
3314
init_tree(tree, (uint) cmin(session->variables.max_heap_table_size,
3315
session->variables.sortbuff_size/16), 0,
3301
3316
tree_key_length,
3302
group_concat_key_cmp_with_order , false, NULL, (void*) this);
3317
group_concat_key_cmp_with_order , 0, NULL, (void*) this);
3306
3321
unique_filter= new Unique(group_concat_key_cmp_with_distinct,
3308
3323
tree_key_length,
3309
(size_t)session->variables.max_heap_table_size);
3324
session->variables.max_heap_table_size);
3326
double Item_func_group_concat::val_real()
3328
String *res; res=val_str(&str_value);
3329
return res ? internal::my_atof(res->c_ptr()) : 0.0;
3332
int64_t Item_func_group_concat::val_int()
3337
if (!(res= val_str(&str_value)))
3339
end_ptr= (char*) res->ptr()+ res->length();
3340
return internal::my_strtoll10(res->ptr(), &end_ptr, &error);
3343
String* Item_func_group_concat::val_str(String* )
3342
String* Item_func_group_concat::val_str(String* str __attribute__((unused)))
3345
3344
assert(fixed == 1);
3346
3345
if (null_value)