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>
38
36
#include <drizzled/field/datetime.h>
40
#include "drizzled/internal/m_string.h"
49
38
extern my_decimal decimal_zero;
50
extern plugin::StorageEngine *heap_engine;
53
41
Prepare an aggregate function item for checking context conditions.
268
256
in_sum_func->outer_fields.push_back(field);
272
sel->full_group_by_flag.set(NON_AGG_FIELD_USED);
259
sel->full_group_by_flag|= NON_AGG_FIELD_USED;
275
261
if (sel->nest_level > aggr_level &&
276
(sel->full_group_by_flag.test(SUM_FUNC_USED)) &&
277
! sel->group_list.elements)
262
(sel->full_group_by_flag & SUM_FUNC_USED) &&
263
!sel->group_list.elements)
279
265
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
280
266
ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
381
367
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
382
368
forced_const(false)
384
if ((args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
370
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
387
373
List_iterator_fast<Item> li(list);
509
495
uint32_t convert_blob_length)
513
498
switch (result_type()) {
514
499
case REAL_RESULT:
515
500
field= new Field_double(max_length, maybe_null, name, decimals, true);
519
field= new field::Int64(max_length, maybe_null, name, unsigned_flag);
503
field= new Field_int64_t(max_length, maybe_null, name, unsigned_flag);
522
505
case STRING_RESULT:
523
506
if (max_length/collation.collation->mbmaxlen <= 255 ||
524
507
convert_blob_length > Field_varstring::MAX_SIZE ||
525
508
!convert_blob_length)
527
509
return make_string_field(table);
530
table->setVariableWidth();
531
510
field= new Field_varstring(convert_blob_length, maybe_null,
532
name, collation.collation);
511
name, table->s, collation.collation);
535
513
case DECIMAL_RESULT:
536
field= new Field_decimal(max_length, maybe_null, name,
537
decimals, unsigned_flag);
514
field= new Field_new_decimal(max_length, maybe_null, name,
515
decimals, unsigned_flag);
541
519
// This case should never be choosen
547
524
field->init(table);
806
784
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);
786
/* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
787
int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
788
max_length= my_decimal_precision_to_length(precision, decimals,
791
hybrid_type= DECIMAL_RESULT;
792
my_decimal_set_zero(dec_buffs);
970
957
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;
961
Preserving int8, int16, int32 field types gives ~10% performance boost
962
as the size of result tree becomes significantly smaller.
963
Another speed up we gain by using int64_t for intermediate
964
calculations. The range of int64 is enough to hold sum 2^32 distinct
965
integers each <= 2^32.
967
if (table_field_type == DRIZZLE_TYPE_LONG)
969
val.traits= Hybrid_type_traits_fast_decimal::instance();
972
table_field_type= DRIZZLE_TYPE_LONGLONG;
987
974
case DECIMAL_RESULT:
988
975
val.traits= Hybrid_type_traits_decimal::instance();
989
976
if (table_field_type != DRIZZLE_TYPE_LONGLONG)
990
table_field_type= DRIZZLE_TYPE_DECIMAL;
977
table_field_type= DRIZZLE_TYPE_NEWDECIMAL;
996
983
val.traits->fix_length_and_dec(this, args[0]);
1010
997
bool Item_sum_distinct::setup(Session *session)
1012
List<CreateField> field_list;
1013
CreateField field_def; /* field definition */
999
List<Create_field> field_list;
1000
Create_field field_def; /* field definition */
1014
1001
/* It's legal to call setup() more than once when in a subquery */
1029
1016
assert(args[0]->fixed);
1031
1018
field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
1032
args[0]->decimals, args[0]->maybe_null);
1019
args[0]->decimals, args[0]->maybe_null,
1020
args[0]->unsigned_flag);
1034
if (! (table= session->getInstanceTable(field_list)))
1022
if (! (table= create_virtual_tmp_table(session, field_list)))
1037
1025
/* XXX: check that the case of CHAR(0) works OK */
1038
tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
1026
tree_key_length= table->s->reclength - table->s->null_bytes;
1041
1029
Unique handles all unique elements in a tree until they can't fit
1055
1043
bool Item_sum_distinct::add()
1057
args[0]->save_in_field(table->getField(0), false);
1045
args[0]->save_in_field(table->field[0], false);
1058
1046
is_evaluated= false;
1059
if (!table->getField(0)->is_null())
1047
if (!table->field[0]->is_null())
1064
1052
'0' values are also stored in the tree. This doesn't matter
1065
1053
for SUM(DISTINCT), but is important for AVG(DISTINCT)
1067
return tree->unique_add(table->getField(0)->ptr);
1055
return tree->unique_add(table->field[0]->ptr);
1073
1061
bool Item_sum_distinct::unique_walk_function(void *element)
1075
memcpy(table->getField(0)->ptr, element, tree_key_length);
1063
memcpy(table->field[0]->ptr, element, tree_key_length);
1077
val.traits->add(&val, table->getField(0));
1065
val.traits->add(&val, table->field[0]);
1168
1156
AVG() will divide val by count. We need to reserve digits
1169
1157
after decimal point as the result can be fractional.
1171
decimals= min(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
1159
decimals= cmin(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
1230
1218
if (hybrid_type == DECIMAL_RESULT)
1232
1220
int precision= args[0]->decimal_precision() + prec_increment;
1233
decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1221
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1234
1222
max_length= my_decimal_precision_to_length(precision, decimals,
1235
1223
unsigned_flag);
1236
f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1224
f_precision= cmin(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
1237
1225
f_scale= args[0]->decimals;
1238
1226
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);
1229
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
1242
1230
max_length= args[0]->max_length + prec_increment;
1261
1249
The easiest way is to do this is to store both value in a string
1262
1250
and unpack on access.
1264
table->setVariableWidth();
1265
1252
field= new Field_varstring(((hybrid_type == DECIMAL_RESULT) ?
1266
1253
dec_bin_size : sizeof(double)) + sizeof(int64_t),
1267
0, name, &my_charset_bin);
1254
0, name, table->s, &my_charset_bin);
1269
1256
else if (hybrid_type == DECIMAL_RESULT)
1270
field= new Field_decimal(max_length, maybe_null, name,
1271
decimals, unsigned_flag);
1257
field= new Field_new_decimal(max_length, maybe_null, name,
1258
decimals, unsigned_flag);
1273
1260
field= new Field_double(max_length, maybe_null, name, decimals, true);
1436
1423
switch (args[0]->result_type()) {
1437
1424
case REAL_RESULT:
1438
1425
case STRING_RESULT:
1439
decimals= min(args[0]->decimals + 4, (int)NOT_FIXED_DEC);
1426
decimals= cmin(args[0]->decimals + 4, NOT_FIXED_DEC);
1441
1428
case INT_RESULT:
1442
1429
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,
1431
int precision= args[0]->decimal_precision()*2 + prec_increment;
1432
decimals= cmin(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1433
max_length= my_decimal_precision_to_length(precision, decimals,
1451
1438
case ROW_RESULT:
1476
1465
The easiest way is to do this is to store both value in a string
1477
1466
and unpack on access.
1479
table->setVariableWidth();
1480
field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, &my_charset_bin);
1468
field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, table->s, &my_charset_bin);
1483
1471
field= new Field_double(max_length, maybe_null, name, decimals, true);
1619
1607
assert(fixed == 1);
1620
1608
if (null_value)
1623
1610
switch (hybrid_type) {
1624
1611
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);
1615
String *res; res=val_str(&str_value);
1616
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
1617
&end_not_used, &err_not_used) : 0.0);
1632
1619
case INT_RESULT:
1633
1620
return (double) sum_int;
1634
1621
case DECIMAL_RESULT:
1757
1741
switch (hybrid_type) {
1758
1742
case STRING_RESULT:
1744
String *result=args[0]->val_str(&tmp_value);
1745
if (!args[0]->null_value &&
1746
(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);
1748
value.copy(*result);
1769
1753
case INT_RESULT:
1755
int64_t nr=args[0]->val_int();
1756
if (!args[0]->null_value && (null_value ||
1758
(uint64_t) nr < (uint64_t) sum_int) ||
1759
(!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
1766
case DECIMAL_RESULT:
1768
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1769
if (!args[0]->null_value &&
1770
(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);
1772
my_decimal2decimal(val, &sum_dec);
1793
1777
case REAL_RESULT:
1779
double nr= args[0]->val_real();
1780
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
1787
case ROW_RESULT:
1804
1789
// This case should never be choosen
1820
1805
switch (hybrid_type) {
1821
1806
case STRING_RESULT:
1808
String *result=args[0]->val_str(&tmp_value);
1809
if (!args[0]->null_value &&
1810
(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);
1812
value.copy(*result);
1832
1817
case INT_RESULT:
1819
int64_t nr=args[0]->val_int();
1820
if (!args[0]->null_value && (null_value ||
1822
(uint64_t) nr > (uint64_t) sum_int) ||
1823
(!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
1830
case DECIMAL_RESULT:
1832
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1833
if (!args[0]->null_value &&
1834
(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);
1836
my_decimal2decimal(val, &sum_dec);
1856
1841
case REAL_RESULT:
1843
double nr= args[0]->val_real();
1844
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
1851
case ROW_RESULT:
1867
1853
// This case should never be choosen
1957
1942
switch(hybrid_type) {
1958
1943
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)
1945
char buff[MAX_FIELD_WIDTH];
1946
String tmp(buff,sizeof(buff),result_field->charset()),*res;
1948
res=args[0]->val_str(&tmp);
1949
if (args[0]->null_value)
1951
result_field->set_null();
1952
result_field->reset();
1956
result_field->set_notnull();
1957
result_field->store(res->ptr(),res->length(),tmp.charset());
1963
int64_t nr=args[0]->val_int();
1967
if (args[0]->null_value)
1970
result_field->set_null();
1973
result_field->set_notnull();
1975
result_field->store(nr, unsigned_flag);
1980
double nr= args[0]->val_real();
1984
if (args[0]->null_value)
1987
result_field->set_null();
1990
result_field->set_notnull();
1992
result_field->store(nr);
1995
case DECIMAL_RESULT:
1997
my_decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
2001
if (args[0]->null_value)
1966
2002
result_field->set_null();
1967
result_field->reset();
1971
2004
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);
2007
We must store zero in the field as we will use the field value in
2010
if (!arg_dec) // Null
2011
arg_dec= &decimal_zero;
2012
result_field->store_decimal(arg_dec);
2030
2015
case ROW_RESULT:
2237
2222
if (!args[0]->null_value)
2239
result_field->val_str_internal(&tmp_value);
2224
result_field->val_str(&tmp_value);
2241
2226
if (result_field->is_null() ||
2242
2227
(cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
2503
2488
int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
2505
2490
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();
2491
Field **field = item->table->field;
2492
Field **field_end= field + item->table->s->fields;
2508
2493
uint32_t *lengths=item->field_lengths;
2509
2494
for (; field < field_end; ++field)
2608
2604
tmp_table_param->force_copy_fields= force_copy_fields;
2609
2605
assert(table == 0);
2611
if (!(table= create_tmp_table(session, tmp_table_param, list, (Order*) 0, 1,
2607
if (!(table= create_tmp_table(session, tmp_table_param, list, (order_st*) 0, 1,
2613
2609
(select_lex->options | session->options),
2614
2610
HA_POS_ERROR, (char*)"")))
2618
table->cursor->extra(HA_EXTRA_NO_ROWS); // Don't update rows
2612
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
2619
2613
table->no_rows=1;
2621
if (table->getShare()->db_type() == heap_engine)
2615
if (table->s->db_type() == heap_engine)
2624
2618
No blobs, otherwise it would have been MyISAM: set up a compare
2627
2621
qsort_cmp2 compare_key;
2629
Field **field= table->getFields();
2630
Field **field_end= field + table->getShare()->sizeFields();
2623
Field **field= table->field;
2624
Field **field_end= field + table->s->fields;
2631
2625
bool all_binary= true;
2633
2627
for (tree_key_length= 0; field < field_end; ++field)
2665
2659
uint32_t *length;
2666
2660
compare_key= (qsort_cmp2) composite_key_cmp;
2667
2661
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();
2662
field_lengths= (uint32_t*) session->alloc(table->s->fields * sizeof(uint32_t));
2663
for (tree_key_length= 0, length= field_lengths, field= table->field;
2670
2664
field < field_end; ++field, ++length)
2672
2666
*length= (*field)->pack_length();
2708
2702
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);
2704
table->file->extra(HA_EXTRA_NO_CACHE);
2705
table->file->ha_delete_all_rows();
2706
table->file->extra(HA_EXTRA_WRITE_CACHE);
2719
2713
if (always_null)
2721
2715
copy_fields(tmp_table_param);
2722
if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
2716
copy_funcs(tmp_table_param->items_to_copy);
2725
for (Field **field= table->getFields() ; *field ; field++)
2718
for (Field **field=table->field ; *field ; field++)
2727
2719
if ((*field)->is_real_null(0))
2729
2720
return 0; // Don't count NULL
2733
2722
is_evaluated= false;
2739
2728
bloat the tree without providing any valuable info. Besides,
2740
2729
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);
2731
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))
2733
if ((error= table->file->ha_write_row(table->record[0])) &&
2734
table->file->is_fatal_error(error, HA_CHECK_DUP))
2767
2756
return (int64_t) count;
2770
error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2759
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2774
table->print_error(error, MYF(0));
2763
table->file->print_error(error, MYF(0));
2777
return table->cursor->stats.records;
2766
return table->file->stats.records;
2780
2769
/*****************************************************************************
2829
2818
Field *field= item->get_tmp_table_field();
2831
uint32_t offset= field->offset(field->getTable()->record[0])-table->getShare()->null_bytes;
2820
uint32_t offset= field->offset(field->table->record[0])-table->s->null_bytes;
2832
2821
if((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2840
function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
2829
function of sort for syntax: GROUP_CONCAT(expr,... order_st BY col,... )
2843
2832
int group_concat_key_cmp_with_order(void* arg, const void* key1,
2844
2833
const void* key2)
2846
2835
Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
2847
Order **order_item, **end;
2836
order_st **order_item, **end;
2848
2837
Table *table= grp_item->table;
2850
2839
for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
2865
2854
if (field && !item->const_item())
2868
uint32_t offset= (field->offset(field->getTable()->record[0]) -
2869
table->getShare()->null_bytes);
2857
uint32_t offset= (field->offset(field->table->record[0]) -
2858
table->s->null_bytes);
2870
2859
if ((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2871
2860
return (*order_item)->asc ? res : -res;
2884
2873
Append data from current leaf to item->result.
2887
int dump_leaf_key(unsigned char* key, uint32_t ,
2876
int dump_leaf_key(unsigned char* key, element_count ,
2888
2877
Item_func_group_concat *item)
2890
2879
Table *table= item->table;
2891
String tmp((char *)table->getUpdateRecord(), table->getShare()->getRecordLength(),
2880
String tmp((char *)table->record[1], table->s->reclength,
2892
2881
default_charset_info);
2894
2883
String *result= &item->result;
2915
2904
because it contains both order and arg list fields.
2917
2906
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);
2907
uint32_t offset= (field->offset(field->table->record[0]) -
2908
table->s->null_bytes);
2909
assert(offset < table->s->reclength);
2910
res= field->val_str(&tmp, key + offset);
2924
2913
res= (*arg)->val_str(&tmp);
2966
2955
bool distinct_arg, List<Item> *select_list,
2967
2956
SQL_LIST *order_list, String *separator_arg)
2968
2957
:tmp_table_param(0), warning(0),
2969
separator(separator_arg), tree(NULL), unique_filter(NULL), table(0),
2958
separator(separator_arg), tree(0), unique_filter(NULL), table(0),
2970
2959
order(0), context(context_arg),
2971
2960
arg_count_order(order_list ? order_list->elements : 0),
2972
2961
arg_count_field(select_list->elements),
2987
2976
(for possible order items in temporare tables)
2988
2977
order - arg_count_order
2990
if (!(args= (Item**) memory::sql_alloc(sizeof(Item*) * arg_count +
2991
sizeof(Order*)*arg_count_order)))
2979
if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count +
2980
sizeof(order_st*)*arg_count_order)))
2994
order= (Order**)(args + arg_count);
2983
order= (order_st**)(args + arg_count);
2996
2985
/* fill args items of show and sort */
2997
2986
List_iterator_fast<Item> li(*select_list);
3002
2991
if (arg_count_order)
3004
Order **order_ptr= order;
3005
for (Order *order_item= (Order*) order_list->first;
2993
order_st **order_ptr= order;
2994
for (order_st *order_item= (order_st*) order_list->first;
3006
2995
order_item != NULL;
3007
2996
order_item= order_item->next)
3050
3039
char warn_buff[DRIZZLE_ERRMSG_SIZE];
3051
snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3040
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3052
3041
warning->set_msg(current_session, warn_buff);
3080
3070
char warn_buff[DRIZZLE_ERRMSG_SIZE];
3081
snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3071
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3082
3072
warning->set_msg(session, warn_buff);
3137
3126
/* Filter out duplicate rows. */
3138
3127
uint32_t count= unique_filter->elements_in_tree();
3139
unique_filter->unique_add(table->record[0] + table->getShare()->null_bytes);
3128
unique_filter->unique_add(table->record[0] + table->s->null_bytes);
3140
3129
if (count == unique_filter->elements_in_tree())
3141
3130
row_eligible= false;
3144
3133
TREE_ELEMENT *el= 0; // Only for safety
3145
3134
if (row_eligible && tree)
3146
el= tree_insert(tree, table->record[0] + table->getShare()->null_bytes, 0,
3135
el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
3147
3136
tree->custom_arg);
3149
3138
If the row is not a duplicate (el->count == 1)
3153
3142
if (row_eligible && !warning_for_row &&
3154
3143
(!tree || (el->count == 1 && distinct && !arg_count_order)))
3155
dump_leaf_key(table->record[0] + table->getShare()->null_bytes, 1, this);
3144
dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3194
3183
max_length= (size_t)session->variables.group_concat_max_len;
3186
if (separator->needs_conversion(separator->length(), separator->charset(),
3187
collation.collation, &offset))
3189
uint32_t buflen= collation.collation->mbmaxlen * separator->length();
3190
uint32_t errors, conv_length;
3192
String *new_separator;
3194
if (!(buf= (char*) session->alloc(buflen)) ||
3195
!(new_separator= new(session->mem_root)
3196
String(buf, buflen, collation.collation)))
3199
conv_length= copy_and_convert(buf, buflen, collation.collation,
3200
separator->ptr(), separator->length(),
3201
separator->charset(), &errors);
3202
new_separator->length(conv_length);
3203
separator= new_separator;
3196
3206
if (check_sum_func(session, ref))
3256
3266
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
3267
if we are to store them in TREE objects used for order_st BY and
3258
3268
DISTINCT. This leads to truncation if the BLOB's size exceeds
3259
3269
Field_varstring::MAX_SIZE.
3266
3276
We have to create a temporary table to get descriptions of fields
3267
3277
(types, sizes and so on).
3269
Note that in the table, we first have the ORDER BY fields, then the
3279
Note that in the table, we first have the order_st BY fields, then the
3272
3282
if (!(table= create_tmp_table(session, tmp_table_param, all_fields,
3273
(Order*) 0, 0, true,
3283
(order_st*) 0, 0, true,
3274
3284
(select_lex->options | session->options),
3275
3285
HA_POS_ERROR, (char*) "")))
3280
table->cursor->extra(HA_EXTRA_NO_ROWS);
3287
table->file->extra(HA_EXTRA_NO_ROWS);
3281
3288
table->no_rows= 1;
3285
3292
Don't reserve space for NULLs: if any of gconcat arguments is NULL,
3286
3293
the row is not added to the result.
3288
uint32_t tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
3295
uint32_t tree_key_length= table->s->reclength - table->s->null_bytes;
3290
3297
if (arg_count_order)
3292
3299
tree= &tree_base;
3294
3301
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
3302
syntax of this function). If there is no order_st BY clause, we don't
3296
3303
create this tree.
3298
init_tree(tree, (uint32_t) min(session->variables.max_heap_table_size,
3299
(uint64_t)(session->variables.sortbuff_size/16)),
3305
init_tree(tree, (uint32_t) cmin(session->variables.max_heap_table_size,
3306
session->variables.sortbuff_size/16), 0,
3301
3307
tree_key_length,
3302
group_concat_key_cmp_with_order , false, NULL, (void*) this);
3308
group_concat_key_cmp_with_order , 0, NULL, (void*) this);
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
3333
String* Item_func_group_concat::val_str(String* )