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 */
33
32
#include <drizzled/item/sum.h>
34
33
#include <drizzled/field/decimal.h>
35
34
#include <drizzled/field/double.h>
36
#include <drizzled/field/int64.h>
35
#include <drizzled/field/int64_t.h>
37
36
#include <drizzled/field/date.h>
38
37
#include <drizzled/field/datetime.h>
509
508
uint32_t convert_blob_length)
513
511
switch (result_type()) {
514
512
case REAL_RESULT:
515
513
field= new Field_double(max_length, maybe_null, name, decimals, true);
519
field= new field::Int64(max_length, maybe_null, name, unsigned_flag);
516
field= new Field_int64_t(max_length, maybe_null, name, unsigned_flag);
522
518
case STRING_RESULT:
523
519
if (max_length/collation.collation->mbmaxlen <= 255 ||
524
520
convert_blob_length > Field_varstring::MAX_SIZE ||
525
521
!convert_blob_length)
527
522
return make_string_field(table);
530
table->setVariableWidth();
531
523
field= new Field_varstring(convert_blob_length, maybe_null,
532
name, collation.collation);
524
name, table->s, collation.collation);
535
526
case DECIMAL_RESULT:
536
527
field= new Field_decimal(max_length, maybe_null, name,
537
decimals, unsigned_flag);
528
decimals, unsigned_flag);
541
532
// This case should never be choosen
547
537
field->init(table);
806
797
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);
799
/* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
800
int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
801
max_length= my_decimal_precision_to_length(precision, decimals,
804
hybrid_type= DECIMAL_RESULT;
805
my_decimal_set_zero(dec_buffs);
970
962
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;
966
Preserving int8, int16, int32 field types gives ~10% performance boost
967
as the size of result tree becomes significantly smaller.
968
Another speed up we gain by using int64_t for intermediate
969
calculations. The range of int64 is enough to hold sum 2^32 distinct
970
integers each <= 2^32.
972
if (table_field_type == DRIZZLE_TYPE_LONG)
974
val.traits= Hybrid_type_traits_fast_decimal::instance();
977
table_field_type= DRIZZLE_TYPE_LONGLONG;
987
979
case DECIMAL_RESULT:
988
980
val.traits= Hybrid_type_traits_decimal::instance();
989
981
if (table_field_type != DRIZZLE_TYPE_LONGLONG)
990
982
table_field_type= DRIZZLE_TYPE_DECIMAL;
996
988
val.traits->fix_length_and_dec(this, args[0]);
1031
1023
field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
1032
1024
args[0]->decimals, args[0]->maybe_null);
1034
if (! (table= session->getInstanceTable(field_list)))
1026
if (! (table= create_virtual_tmp_table(session, field_list)))
1037
1029
/* XXX: check that the case of CHAR(0) works OK */
1038
tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
1030
tree_key_length= table->s->reclength - table->s->null_bytes;
1041
1033
Unique handles all unique elements in a tree until they can't fit
1055
1047
bool Item_sum_distinct::add()
1057
args[0]->save_in_field(table->getField(0), false);
1049
args[0]->save_in_field(table->field[0], false);
1058
1050
is_evaluated= false;
1059
if (!table->getField(0)->is_null())
1051
if (!table->field[0]->is_null())
1064
1056
'0' values are also stored in the tree. This doesn't matter
1065
1057
for SUM(DISTINCT), but is important for AVG(DISTINCT)
1067
return tree->unique_add(table->getField(0)->ptr);
1059
return tree->unique_add(table->field[0]->ptr);
1073
1065
bool Item_sum_distinct::unique_walk_function(void *element)
1075
memcpy(table->getField(0)->ptr, element, tree_key_length);
1067
memcpy(table->field[0]->ptr, element, tree_key_length);
1077
val.traits->add(&val, table->getField(0));
1069
val.traits->add(&val, table->field[0]);
1261
1253
The easiest way is to do this is to store both value in a string
1262
1254
and unpack on access.
1264
table->setVariableWidth();
1265
1256
field= new Field_varstring(((hybrid_type == DECIMAL_RESULT) ?
1266
1257
dec_bin_size : sizeof(double)) + sizeof(int64_t),
1267
0, name, &my_charset_bin);
1258
0, name, table->s, &my_charset_bin);
1269
1260
else if (hybrid_type == DECIMAL_RESULT)
1270
1261
field= new Field_decimal(max_length, maybe_null, name,
1441
1432
case INT_RESULT:
1442
1433
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,
1435
int precision= args[0]->decimal_precision()*2 + prec_increment;
1436
decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
1437
max_length= my_decimal_precision_to_length(precision, decimals,
1451
1442
case ROW_RESULT:
1476
1469
The easiest way is to do this is to store both value in a string
1477
1470
and unpack on access.
1479
table->setVariableWidth();
1480
field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, &my_charset_bin);
1472
field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, table->s, &my_charset_bin);
1483
1475
field= new Field_double(max_length, maybe_null, name, decimals, true);
1619
1611
assert(fixed == 1);
1620
1612
if (null_value)
1623
1614
switch (hybrid_type) {
1624
1615
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);
1619
String *res; res=val_str(&str_value);
1620
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
1621
&end_not_used, &err_not_used) : 0.0);
1632
1623
case INT_RESULT:
1633
1624
return (double) sum_int;
1634
1625
case DECIMAL_RESULT:
1757
1745
switch (hybrid_type) {
1758
1746
case STRING_RESULT:
1748
String *result=args[0]->val_str(&tmp_value);
1749
if (!args[0]->null_value &&
1750
(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);
1752
value.copy(*result);
1769
1757
case INT_RESULT:
1759
int64_t nr=args[0]->val_int();
1760
if (!args[0]->null_value && (null_value ||
1762
(uint64_t) nr < (uint64_t) sum_int) ||
1763
(!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
1770
case DECIMAL_RESULT:
1772
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1773
if (!args[0]->null_value &&
1774
(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);
1776
my_decimal2decimal(val, &sum_dec);
1793
1781
case REAL_RESULT:
1783
double nr= args[0]->val_real();
1784
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
1791
case ROW_RESULT:
1804
1793
// This case should never be choosen
1820
1809
switch (hybrid_type) {
1821
1810
case STRING_RESULT:
1812
String *result=args[0]->val_str(&tmp_value);
1813
if (!args[0]->null_value &&
1814
(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);
1816
value.copy(*result);
1832
1821
case INT_RESULT:
1823
int64_t nr=args[0]->val_int();
1824
if (!args[0]->null_value && (null_value ||
1826
(uint64_t) nr > (uint64_t) sum_int) ||
1827
(!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
1834
case DECIMAL_RESULT:
1836
my_decimal value_buff, *val= args[0]->val_decimal(&value_buff);
1837
if (!args[0]->null_value &&
1838
(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);
1840
my_decimal2decimal(val, &sum_dec);
1856
1845
case REAL_RESULT:
1847
double nr= args[0]->val_real();
1848
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
1855
case ROW_RESULT:
1867
1857
// This case should never be choosen
1957
1946
switch(hybrid_type) {
1958
1947
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)
1949
char buff[MAX_FIELD_WIDTH];
1950
String tmp(buff,sizeof(buff),result_field->charset()),*res;
1952
res=args[0]->val_str(&tmp);
1953
if (args[0]->null_value)
1955
result_field->set_null();
1956
result_field->reset();
1960
result_field->set_notnull();
1961
result_field->store(res->ptr(),res->length(),tmp.charset());
1967
int64_t nr=args[0]->val_int();
1971
if (args[0]->null_value)
1974
result_field->set_null();
1977
result_field->set_notnull();
1979
result_field->store(nr, unsigned_flag);
1984
double nr= args[0]->val_real();
1988
if (args[0]->null_value)
1991
result_field->set_null();
1994
result_field->set_notnull();
1996
result_field->store(nr);
1999
case DECIMAL_RESULT:
2001
my_decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
2005
if (args[0]->null_value)
1966
2006
result_field->set_null();
1967
result_field->reset();
1971
2008
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);
2011
We must store zero in the field as we will use the field value in
2014
if (!arg_dec) // Null
2015
arg_dec= &decimal_zero;
2016
result_field->store_decimal(arg_dec);
2030
2019
case ROW_RESULT:
2237
2226
if (!args[0]->null_value)
2239
result_field->val_str_internal(&tmp_value);
2228
result_field->val_str(&tmp_value);
2241
2230
if (result_field->is_null() ||
2242
2231
(cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
2503
2492
int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
2505
2494
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();
2495
Field **field = item->table->field;
2496
Field **field_end= field + item->table->s->fields;
2508
2497
uint32_t *lengths=item->field_lengths;
2509
2498
for (; field < field_end; ++field)
2608
2598
tmp_table_param->force_copy_fields= force_copy_fields;
2609
2599
assert(table == 0);
2611
if (!(table= create_tmp_table(session, tmp_table_param, list, (Order*) 0, 1,
2601
if (!(table= create_tmp_table(session, tmp_table_param, list, (order_st*) 0, 1,
2613
2603
(select_lex->options | session->options),
2614
2604
HA_POS_ERROR, (char*)"")))
2618
2606
table->cursor->extra(HA_EXTRA_NO_ROWS); // Don't update rows
2619
2607
table->no_rows=1;
2621
if (table->getShare()->db_type() == heap_engine)
2609
if (table->s->db_type() == heap_engine)
2624
2612
No blobs, otherwise it would have been MyISAM: set up a compare
2627
2615
qsort_cmp2 compare_key;
2629
Field **field= table->getFields();
2630
Field **field_end= field + table->getShare()->sizeFields();
2617
Field **field= table->field;
2618
Field **field_end= field + table->s->fields;
2631
2619
bool all_binary= true;
2633
2621
for (tree_key_length= 0; field < field_end; ++field)
2665
2653
uint32_t *length;
2666
2654
compare_key= (qsort_cmp2) composite_key_cmp;
2667
2655
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();
2656
field_lengths= (uint32_t*) session->alloc(table->s->fields * sizeof(uint32_t));
2657
for (tree_key_length= 0, length= field_lengths, field= table->field;
2670
2658
field < field_end; ++field, ++length)
2672
2660
*length= (*field)->pack_length();
2719
2707
if (always_null)
2721
2709
copy_fields(tmp_table_param);
2722
if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
2710
copy_funcs(tmp_table_param->items_to_copy);
2725
for (Field **field= table->getFields() ; *field ; field++)
2712
for (Field **field=table->field ; *field ; field++)
2727
2713
if ((*field)->is_real_null(0))
2729
2714
return 0; // Don't count NULL
2733
2716
is_evaluated= false;
2739
2722
bloat the tree without providing any valuable info. Besides,
2740
2723
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);
2725
return tree->unique_add(table->record[0] + table->s->null_bytes);
2744
if ((error= table->cursor->insertRecord(table->record[0])) &&
2727
if ((error= table->cursor->ha_write_row(table->record[0])) &&
2745
2728
table->cursor->is_fatal_error(error, HA_CHECK_DUP))
2829
2812
Field *field= item->get_tmp_table_field();
2831
uint32_t offset= field->offset(field->getTable()->record[0])-table->getShare()->null_bytes;
2814
uint32_t offset= field->offset(field->table->record[0])-table->s->null_bytes;
2832
2815
if((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2844
2827
const void* key2)
2846
2829
Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
2847
Order **order_item, **end;
2830
order_st **order_item, **end;
2848
2831
Table *table= grp_item->table;
2850
2833
for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
2865
2848
if (field && !item->const_item())
2868
uint32_t offset= (field->offset(field->getTable()->record[0]) -
2869
table->getShare()->null_bytes);
2851
uint32_t offset= (field->offset(field->table->record[0]) -
2852
table->s->null_bytes);
2870
2853
if ((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
2871
2854
return (*order_item)->asc ? res : -res;
2888
2871
Item_func_group_concat *item)
2890
2873
Table *table= item->table;
2891
String tmp((char *)table->getUpdateRecord(), table->getShare()->getRecordLength(),
2874
String tmp((char *)table->record[1], table->s->reclength,
2892
2875
default_charset_info);
2894
2877
String *result= &item->result;
2915
2898
because it contains both order and arg list fields.
2917
2900
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);
2901
uint32_t offset= (field->offset(field->table->record[0]) -
2902
table->s->null_bytes);
2903
assert(offset < table->s->reclength);
2904
res= field->val_str(&tmp, key + offset);
2924
2907
res= (*arg)->val_str(&tmp);
2988
2971
order - arg_count_order
2990
2973
if (!(args= (Item**) memory::sql_alloc(sizeof(Item*) * arg_count +
2991
sizeof(Order*)*arg_count_order)))
2974
sizeof(order_st*)*arg_count_order)))
2994
order= (Order**)(args + arg_count);
2977
order= (order_st**)(args + arg_count);
2996
2979
/* fill args items of show and sort */
2997
2980
List_iterator_fast<Item> li(*select_list);
3002
2985
if (arg_count_order)
3004
Order **order_ptr= order;
3005
for (Order *order_item= (Order*) order_list->first;
2987
order_st **order_ptr= order;
2988
for (order_st *order_item= (order_st*) order_list->first;
3006
2989
order_item != NULL;
3007
2990
order_item= order_item->next)
3050
3033
char warn_buff[DRIZZLE_ERRMSG_SIZE];
3051
snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3034
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3052
3035
warning->set_msg(current_session, warn_buff);
3080
3064
char warn_buff[DRIZZLE_ERRMSG_SIZE];
3081
snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3065
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3082
3066
warning->set_msg(session, warn_buff);
3137
3120
/* Filter out duplicate rows. */
3138
3121
uint32_t count= unique_filter->elements_in_tree();
3139
unique_filter->unique_add(table->record[0] + table->getShare()->null_bytes);
3122
unique_filter->unique_add(table->record[0] + table->s->null_bytes);
3140
3123
if (count == unique_filter->elements_in_tree())
3141
3124
row_eligible= false;
3144
3127
TREE_ELEMENT *el= 0; // Only for safety
3145
3128
if (row_eligible && tree)
3146
el= tree_insert(tree, table->record[0] + table->getShare()->null_bytes, 0,
3129
el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
3147
3130
tree->custom_arg);
3149
3132
If the row is not a duplicate (el->count == 1)
3153
3136
if (row_eligible && !warning_for_row &&
3154
3137
(!tree || (el->count == 1 && distinct && !arg_count_order)))
3155
dump_leaf_key(table->record[0] + table->getShare()->null_bytes, 1, this);
3138
dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
3272
3255
if (!(table= create_tmp_table(session, tmp_table_param, all_fields,
3273
(Order*) 0, 0, true,
3256
(order_st*) 0, 0, true,
3274
3257
(select_lex->options | session->options),
3275
3258
HA_POS_ERROR, (char*) "")))
3280
3260
table->cursor->extra(HA_EXTRA_NO_ROWS);
3281
3261
table->no_rows= 1;
3285
3265
Don't reserve space for NULLs: if any of gconcat arguments is NULL,
3286
3266
the row is not added to the result.
3288
uint32_t tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
3268
uint32_t tree_key_length= table->s->reclength - table->s->null_bytes;
3290
3270
if (arg_count_order)