00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00023 #include <config.h>
00024 #include <cstdio>
00025 #include <math.h>
00026 #include <drizzled/sql_select.h>
00027 #include <drizzled/error.h>
00028 #include <drizzled/hybrid_type_traits.h>
00029 #include <drizzled/hybrid_type_traits_integer.h>
00030 #include <drizzled/hybrid_type_traits_decimal.h>
00031 #include <drizzled/sql_base.h>
00032 #include <drizzled/session.h>
00033 #include <drizzled/item/sum.h>
00034 #include <drizzled/field/decimal.h>
00035 #include <drizzled/field/double.h>
00036 #include <drizzled/field/int64.h>
00037 #include <drizzled/field/date.h>
00038 #include <drizzled/field/datetime.h>
00039 #include <drizzled/unique.h>
00040 #include <drizzled/type/decimal.h>
00041 #include <drizzled/internal/m_string.h>
00042 #include <drizzled/item/subselect.h>
00043 #include <drizzled/sql_lex.h>
00044
00045 #include <algorithm>
00046
00047 using namespace std;
00048
00049 namespace drizzled {
00050
00051 extern plugin::StorageEngine *heap_engine;
00052
00075 bool Item_sum::init_sum_func_check(Session *session)
00076 {
00077 if (!session->lex().allow_sum_func)
00078 {
00079 my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
00080 MYF(0));
00081 return true;
00082 }
00083
00084 in_sum_func= session->lex().in_sum_func;
00085
00086 session->lex().in_sum_func= this;
00087 nest_level= session->lex().current_select->nest_level;
00088 ref_by= 0;
00089 aggr_level= -1;
00090 aggr_sel= NULL;
00091 max_arg_level= -1;
00092 max_sum_func_level= -1;
00093 outer_fields.clear();
00094 return false;
00095 }
00096
00146 bool Item_sum::check_sum_func(Session *session, Item **ref)
00147 {
00148 bool invalid= false;
00149 nesting_map allow_sum_func= session->lex().allow_sum_func;
00150
00151
00152
00153
00154
00155
00156
00157 if (nest_level == max_arg_level)
00158 {
00159
00160
00161
00162
00163
00164 invalid= !(allow_sum_func & (1 << max_arg_level));
00165 }
00166 else if (max_arg_level >= 0 || !(allow_sum_func & (1 << nest_level)))
00167 {
00168
00169
00170
00171
00172
00173 if (register_sum_func(session, ref))
00174 return true;
00175 invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
00176 if (!invalid && false)
00177 invalid= aggr_level < 0 && max_arg_level < nest_level;
00178 }
00179 if (!invalid && aggr_level < 0)
00180 {
00181 aggr_level= nest_level;
00182 aggr_sel= session->lex().current_select;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 if (!invalid)
00195 invalid= aggr_level <= max_sum_func_level;
00196 if (invalid)
00197 {
00198 my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
00199 MYF(0));
00200 return true;
00201 }
00202
00203 if (in_sum_func)
00204 {
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 if (in_sum_func->nest_level >= aggr_level)
00220 set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
00221 set_if_bigger(in_sum_func->max_sum_func_level, max_sum_func_level);
00222 }
00223
00224
00225
00226
00227
00228 if (outer_fields.size())
00229 {
00230 Item_field *field;
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 List<Item_field>::iterator of(outer_fields.begin());
00258 while ((field= of++))
00259 {
00260 Select_Lex *sel= field->cached_table->select_lex;
00261 if (sel->nest_level < aggr_level)
00262 {
00263 if (in_sum_func)
00264 {
00265
00266
00267
00268
00269 in_sum_func->outer_fields.push_back(field);
00270 }
00271 else
00272 {
00273 sel->full_group_by_flag.set(NON_AGG_FIELD_USED);
00274 }
00275 }
00276 if (sel->nest_level > aggr_level &&
00277 (sel->full_group_by_flag.test(SUM_FUNC_USED)) &&
00278 ! sel->group_list.elements)
00279 {
00280 my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
00281 ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
00282 return true;
00283 }
00284 }
00285 }
00286 aggr_sel->full_group_by_flag.set(SUM_FUNC_USED);
00287 update_used_tables();
00288 session->lex().in_sum_func= in_sum_func;
00289 return false;
00290 }
00291
00317 bool Item_sum::register_sum_func(Session *session, Item **ref)
00318 {
00319 Select_Lex *sl;
00320 nesting_map allow_sum_func= session->lex().allow_sum_func;
00321 for (sl= session->lex().current_select->master_unit()->outer_select() ;
00322 sl && sl->nest_level > max_arg_level;
00323 sl= sl->master_unit()->outer_select() )
00324 {
00325 if (aggr_level < 0 && (allow_sum_func & (1 << sl->nest_level)))
00326 {
00327
00328 aggr_level= sl->nest_level;
00329 aggr_sel= sl;
00330 }
00331 }
00332 if (sl && (allow_sum_func & (1 << sl->nest_level)))
00333 {
00334
00335
00336
00337
00338
00339 aggr_level= sl->nest_level;
00340 aggr_sel= sl;
00341
00342 }
00343 if (aggr_level >= 0)
00344 {
00345 ref_by= ref;
00346
00347 if (!aggr_sel->inner_sum_func_list)
00348 next= this;
00349 else
00350 {
00351 next= aggr_sel->inner_sum_func_list->next;
00352 aggr_sel->inner_sum_func_list->next= this;
00353 }
00354 aggr_sel->inner_sum_func_list= this;
00355 aggr_sel->with_sum_func= 1;
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 for (sl= session->lex().current_select;
00373 sl && sl != aggr_sel && sl->master_unit()->item;
00374 sl= sl->master_unit()->outer_select() )
00375 sl->master_unit()->item->with_sum_func= 1;
00376 }
00377 session->lex().current_select->mark_as_dependent(aggr_sel);
00378 return false;
00379 }
00380
00381
00382 Item_sum::Item_sum(List<Item> &list) :arg_count(list.size()),
00383 forced_const(false)
00384 {
00385 if ((args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
00386 {
00387 uint32_t i=0;
00388 List<Item>::iterator li(list.begin());
00389 Item *item;
00390
00391 while ((item=li++))
00392 {
00393 args[i++]= item;
00394 }
00395 }
00396 mark_as_sum_func();
00397 list.clear();
00398 }
00399
00400
00405 Item_sum::Item_sum(Session *session, Item_sum *item):
00406 Item_result_field(session, item), arg_count(item->arg_count),
00407 aggr_sel(item->aggr_sel),
00408 nest_level(item->nest_level), aggr_level(item->aggr_level),
00409 quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
00410 forced_const(item->forced_const)
00411 {
00412 if (arg_count <= 2)
00413 args=tmp_args;
00414 else
00415 if (!(args= (Item**) session->getMemRoot()->allocate(sizeof(Item*)*arg_count)))
00416 return;
00417 memcpy(args, item->args, sizeof(Item*)*arg_count);
00418 }
00419
00420
00421 void Item_sum::mark_as_sum_func()
00422 {
00423 Select_Lex *cur_select= getSession().lex().current_select;
00424 cur_select->n_sum_items++;
00425 cur_select->with_sum_func= 1;
00426 with_sum_func= 1;
00427 }
00428
00429
00430 void Item_sum::make_field(SendField *tmp_field)
00431 {
00432 if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
00433 {
00434 ((Item_field*) args[0])->field->make_field(tmp_field);
00435
00436 char *empty_string= (char*)"";
00437 tmp_field->db_name= empty_string;
00438 tmp_field->org_table_name= empty_string;
00439 tmp_field->table_name= empty_string;
00440 tmp_field->org_col_name= empty_string;
00441 tmp_field->col_name= name;
00442 if (maybe_null)
00443 tmp_field->flags&= ~NOT_NULL_FLAG;
00444 }
00445 else
00446 init_make_field(tmp_field, field_type());
00447 }
00448
00449
00450 void Item_sum::print(String *str)
00451 {
00452 str->append(func_name());
00453 for (uint32_t i=0 ; i < arg_count ; i++)
00454 {
00455 if (i)
00456 str->append(',');
00457 args[i]->print(str);
00458 }
00459 str->append(')');
00460 }
00461
00462 void Item_sum::fix_num_length_and_dec()
00463 {
00464 decimals=0;
00465 for (uint32_t i=0 ; i < arg_count ; i++)
00466 set_if_bigger(decimals,args[i]->decimals);
00467 max_length=float_length(decimals);
00468 }
00469
00470 Item *Item_sum::get_tmp_table_item(Session *session)
00471 {
00472 Item_sum* sum_item= (Item_sum *) copy_or_same(session);
00473 if (sum_item && sum_item->result_field)
00474 {
00475 Field *result_field_tmp= sum_item->result_field;
00476 for (uint32_t i=0 ; i < sum_item->arg_count ; i++)
00477 {
00478 Item *arg= sum_item->args[i];
00479 if (!arg->const_item())
00480 {
00481 if (arg->type() == Item::FIELD_ITEM)
00482 ((Item_field*) arg)->field= result_field_tmp++;
00483 else
00484 sum_item->args[i]= new Item_field(result_field_tmp++);
00485 }
00486 }
00487 }
00488 return sum_item;
00489 }
00490
00491
00492 bool Item_sum::walk (Item_processor processor, bool walk_subquery,
00493 unsigned char *argument)
00494 {
00495 if (arg_count)
00496 {
00497 Item **arg,**arg_end;
00498 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
00499 {
00500 if ((*arg)->walk(processor, walk_subquery, argument))
00501 return 1;
00502 }
00503 }
00504 return (this->*processor)(argument);
00505 }
00506
00507
00508 Field *Item_sum::create_tmp_field(bool ,
00509 Table *table,
00510 uint32_t convert_blob_length)
00511 {
00512 Field *field= NULL;
00513
00514 switch (result_type()) {
00515 case REAL_RESULT:
00516 field= new Field_double(max_length, maybe_null, name, decimals, true);
00517 break;
00518
00519 case INT_RESULT:
00520 field= new field::Int64(max_length, maybe_null, name, unsigned_flag);
00521 break;
00522
00523 case STRING_RESULT:
00524 if (max_length/collation.collation->mbmaxlen <= 255 ||
00525 convert_blob_length > Field_varstring::MAX_SIZE ||
00526 !convert_blob_length)
00527 {
00528 return make_string_field(table);
00529 }
00530
00531 table->setVariableWidth();
00532 field= new Field_varstring(convert_blob_length, maybe_null,
00533 name, collation.collation);
00534 break;
00535
00536 case DECIMAL_RESULT:
00537 field= new Field_decimal(max_length, maybe_null, name,
00538 decimals, unsigned_flag);
00539 break;
00540
00541 case ROW_RESULT:
00542
00543 assert(0);
00544 return 0;
00545 }
00546
00547 if (field)
00548 field->init(table);
00549
00550 return field;
00551 }
00552
00553
00554 void Item_sum::update_used_tables ()
00555 {
00556 if (!forced_const)
00557 {
00558 used_tables_cache= 0;
00559 for (uint32_t i=0 ; i < arg_count ; i++)
00560 {
00561 args[i]->update_used_tables();
00562 used_tables_cache|= args[i]->used_tables();
00563 }
00564
00565 used_tables_cache&= PSEUDO_TABLE_BITS;
00566
00567
00568 used_tables_cache |= (1 << aggr_sel->join->tables) - 1;
00569 }
00570 }
00571
00572
00573 String *
00574 Item_sum_num::val_str(String *str)
00575 {
00576 return val_string_from_real(str);
00577 }
00578
00579
00580 int64_t Item_sum_num::val_int()
00581 {
00582 assert(fixed == 1);
00583 return (int64_t) rint(val_real());
00584 }
00585
00586
00587 type::Decimal *Item_sum_num::val_decimal(type::Decimal *decimal_value)
00588 {
00589 return val_decimal_from_real(decimal_value);
00590 }
00591
00592
00593 String *
00594 Item_sum_int::val_str(String *str)
00595 {
00596 return val_string_from_int(str);
00597 }
00598
00599
00600 type::Decimal *Item_sum_int::val_decimal(type::Decimal *decimal_value)
00601 {
00602 return val_decimal_from_int(decimal_value);
00603 }
00604
00605
00606 bool
00607 Item_sum_num::fix_fields(Session *session, Item **ref)
00608 {
00609 assert(fixed == 0);
00610
00611 if (init_sum_func_check(session))
00612 return true;
00613
00614 decimals=0;
00615 maybe_null=0;
00616 for (uint32_t i=0 ; i < arg_count ; i++)
00617 {
00618 if (args[i]->fix_fields(session, args + i) || args[i]->check_cols(1))
00619 return true;
00620 set_if_bigger(decimals, args[i]->decimals);
00621 maybe_null |= args[i]->maybe_null;
00622 }
00623 result_field=0;
00624 max_length=float_length(decimals);
00625 null_value=1;
00626 fix_length_and_dec();
00627
00628 if (check_sum_func(session, ref))
00629 return true;
00630
00631 fixed= 1;
00632 return false;
00633 }
00634
00635
00636 Item_sum_hybrid::Item_sum_hybrid(Session *session, Item_sum_hybrid *item)
00637 :Item_sum(session, item), value(item->value), hybrid_type(item->hybrid_type),
00638 hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
00639 was_values(item->was_values)
00640 {
00641
00642 switch (hybrid_type) {
00643 case INT_RESULT:
00644 sum_int= item->sum_int;
00645 break;
00646 case DECIMAL_RESULT:
00647 class_decimal2decimal(&item->sum_dec, &sum_dec);
00648 break;
00649 case REAL_RESULT:
00650 sum= item->sum;
00651 break;
00652 case STRING_RESULT:
00653
00654
00655
00656
00657 break;
00658 case ROW_RESULT:
00659 assert(0);
00660 }
00661 collation.set(item->collation);
00662 }
00663
00664 bool
00665 Item_sum_hybrid::fix_fields(Session *session, Item **ref)
00666 {
00667 assert(fixed == 0);
00668
00669 Item *item= args[0];
00670
00671 if (init_sum_func_check(session))
00672 return true;
00673
00674
00675 if ((!item->fixed && item->fix_fields(session, args)) ||
00676 (item= args[0])->check_cols(1))
00677 return true;
00678 decimals=item->decimals;
00679
00680 switch (hybrid_type= item->result_type()) {
00681 case INT_RESULT:
00682 max_length= 20;
00683 sum_int= 0;
00684 break;
00685 case DECIMAL_RESULT:
00686 max_length= item->max_length;
00687 sum_dec.set_zero();
00688 break;
00689 case REAL_RESULT:
00690 max_length= float_length(decimals);
00691 sum= 0.0;
00692 break;
00693 case STRING_RESULT:
00694 max_length= item->max_length;
00695 break;
00696 case ROW_RESULT:
00697 assert(0);
00698 };
00699
00700 maybe_null= 1;
00701 unsigned_flag=item->unsigned_flag;
00702 collation.set(item->collation);
00703 result_field=0;
00704 null_value=1;
00705 fix_length_and_dec();
00706 item= item->real_item();
00707 if (item->type() == Item::FIELD_ITEM)
00708 hybrid_field_type= ((Item_field*) item)->field->type();
00709 else
00710 hybrid_field_type= Item::field_type();
00711
00712 if (check_sum_func(session, ref))
00713 return true;
00714
00715 fixed= 1;
00716 return false;
00717 }
00718
00719 Field *Item_sum_hybrid::create_tmp_field(bool group, Table *table,
00720 uint32_t convert_blob_length)
00721 {
00722 Field *field;
00723 if (args[0]->type() == Item::FIELD_ITEM)
00724 {
00725 field= ((Item_field*) args[0])->field;
00726
00727 if ((field= create_tmp_field_from_field(&getSession(), field, name, table,
00728 NULL, convert_blob_length)))
00729 field->flags&= ~NOT_NULL_FLAG;
00730 return field;
00731 }
00732
00733
00734
00735
00736
00737 switch (args[0]->field_type()) {
00738 case DRIZZLE_TYPE_DATE:
00739 field= new Field_date(maybe_null, name);
00740 break;
00741 case DRIZZLE_TYPE_TIMESTAMP:
00742 case DRIZZLE_TYPE_DATETIME:
00743 field= new Field_datetime(maybe_null, name);
00744 break;
00745 default:
00746 return Item_sum::create_tmp_field(group, table, convert_blob_length);
00747 }
00748
00749 if (field)
00750 field->init(table);
00751
00752 return field;
00753 }
00754
00755
00756
00757
00758
00759
00764 Item_sum_sum::Item_sum_sum(Session *session, Item_sum_sum *item)
00765 :Item_sum_num(session, item), hybrid_type(item->hybrid_type),
00766 curr_dec_buff(item->curr_dec_buff)
00767 {
00768
00769 if (hybrid_type == DECIMAL_RESULT)
00770 {
00771 class_decimal2decimal(item->dec_buffs, dec_buffs);
00772 class_decimal2decimal(item->dec_buffs + 1, dec_buffs + 1);
00773 }
00774 else
00775 sum= item->sum;
00776 }
00777
00778 Item *Item_sum_sum::copy_or_same(Session* session)
00779 {
00780 return new (session->mem_root) Item_sum_sum(session, this);
00781 }
00782
00783
00784 void Item_sum_sum::clear()
00785 {
00786 null_value=1;
00787 if (hybrid_type == DECIMAL_RESULT)
00788 {
00789 curr_dec_buff= 0;
00790 dec_buffs->set_zero();
00791 }
00792 else
00793 sum= 0.0;
00794 return;
00795 }
00796
00797
00798 void Item_sum_sum::fix_length_and_dec()
00799 {
00800 maybe_null=null_value=1;
00801 decimals= args[0]->decimals;
00802 switch (args[0]->result_type()) {
00803 case REAL_RESULT:
00804 case STRING_RESULT:
00805 hybrid_type= REAL_RESULT;
00806 sum= 0.0;
00807 break;
00808 case INT_RESULT:
00809 case DECIMAL_RESULT:
00810 {
00811
00812 int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
00813 max_length= class_decimal_precision_to_length(precision, decimals,
00814 unsigned_flag);
00815 curr_dec_buff= 0;
00816 hybrid_type= DECIMAL_RESULT;
00817 dec_buffs->set_zero();
00818 break;
00819 }
00820 case ROW_RESULT:
00821 assert(0);
00822 }
00823 }
00824
00825
00826 bool Item_sum_sum::add()
00827 {
00828 if (hybrid_type == DECIMAL_RESULT)
00829 {
00830 type::Decimal value, *val= args[0]->val_decimal(&value);
00831 if (!args[0]->null_value)
00832 {
00833 class_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1),
00834 val, dec_buffs + curr_dec_buff);
00835 curr_dec_buff^= 1;
00836 null_value= 0;
00837 }
00838 }
00839 else
00840 {
00841 sum+= args[0]->val_real();
00842 if (!args[0]->null_value)
00843 null_value= 0;
00844 }
00845 return(0);
00846 }
00847
00848
00849 int64_t Item_sum_sum::val_int()
00850 {
00851 assert(fixed == 1);
00852 if (hybrid_type == DECIMAL_RESULT)
00853 {
00854 int64_t result;
00855 (dec_buffs + curr_dec_buff)->val_int32(E_DEC_FATAL_ERROR, unsigned_flag, &result);
00856 return result;
00857 }
00858 return (int64_t) rint(val_real());
00859 }
00860
00861
00862 double Item_sum_sum::val_real()
00863 {
00864 assert(fixed == 1);
00865 if (hybrid_type == DECIMAL_RESULT)
00866 class_decimal2double(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, &sum);
00867 return sum;
00868 }
00869
00870
00871 String *Item_sum_sum::val_str(String *str)
00872 {
00873 if (hybrid_type == DECIMAL_RESULT)
00874 return val_string_from_decimal(str);
00875 return val_string_from_real(str);
00876 }
00877
00878
00879 type::Decimal *Item_sum_sum::val_decimal(type::Decimal *val)
00880 {
00881 if (hybrid_type == DECIMAL_RESULT)
00882 return (dec_buffs + curr_dec_buff);
00883 return val_decimal_from_real(val);
00884 }
00885
00886
00887
00888
00889
00890 static int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
00891 {
00892 return memcmp(key1, key2, *(uint32_t *) arg);
00893 }
00894
00895
00896 static int item_sum_distinct_walk(void *element,
00897 uint32_t ,
00898 void *item)
00899 {
00900 return ((Item_sum_distinct*) (item))->unique_walk_function(element);
00901 }
00902
00903
00904
00905 Item_sum_distinct::Item_sum_distinct(Item *item_arg)
00906 :Item_sum_num(item_arg), tree(0)
00907 {
00908
00909
00910
00911
00912
00913
00914 quick_group= 0;
00915 }
00916
00917
00918 Item_sum_distinct::Item_sum_distinct(Session *session, Item_sum_distinct *original)
00919 :Item_sum_num(session, original), val(original->val), tree(0),
00920 table_field_type(original->table_field_type)
00921 {
00922 quick_group= 0;
00923 }
00924
00925
00933 struct Hybrid_type_traits_fast_decimal: public
00934 Hybrid_type_traits_integer
00935 {
00936 virtual Item_result type() const { return DECIMAL_RESULT; }
00937 virtual void fix_length_and_dec(Item *item, Item *arg) const
00938 { Hybrid_type_traits_decimal::instance()->fix_length_and_dec(item, arg); }
00939
00940 virtual void div(Hybrid_type *val, uint64_t u) const
00941 {
00942 int2_class_decimal(E_DEC_FATAL_ERROR, val->integer, 0, val->dec_buf);
00943 val->used_dec_buf_no= 0;
00944 val->traits= Hybrid_type_traits_decimal::instance();
00945 val->traits->div(val, u);
00946 }
00947 static const Hybrid_type_traits_fast_decimal *instance();
00948 Hybrid_type_traits_fast_decimal() {};
00949 };
00950
00951 static const Hybrid_type_traits_fast_decimal fast_decimal_traits_instance;
00952
00953 const Hybrid_type_traits_fast_decimal
00954 *Hybrid_type_traits_fast_decimal::instance()
00955 {
00956 return &fast_decimal_traits_instance;
00957 }
00958
00959
00960 void Item_sum_distinct::fix_length_and_dec()
00961 {
00962 assert(args[0]->fixed);
00963
00964 null_value= maybe_null= true;
00965 table_field_type= args[0]->field_type();
00966
00967
00968 switch (args[0]->result_type()) {
00969 case STRING_RESULT:
00970 case REAL_RESULT:
00971 val.traits= Hybrid_type_traits::instance();
00972 table_field_type= DRIZZLE_TYPE_DOUBLE;
00973 break;
00974 case INT_RESULT:
00975
00976
00977
00978
00979
00980
00981
00982 if (table_field_type == DRIZZLE_TYPE_LONG)
00983 {
00984 val.traits= Hybrid_type_traits_fast_decimal::instance();
00985 break;
00986 }
00987 table_field_type= DRIZZLE_TYPE_LONGLONG;
00988
00989 case DECIMAL_RESULT:
00990 val.traits= Hybrid_type_traits_decimal::instance();
00991 if (table_field_type != DRIZZLE_TYPE_LONGLONG)
00992 table_field_type= DRIZZLE_TYPE_DECIMAL;
00993 break;
00994 case ROW_RESULT:
00995 assert(0);
00996 }
00997
00998 val.traits->fix_length_and_dec(this, args[0]);
00999 }
01000
01001
01002 enum Item_result Item_sum_distinct::result_type () const
01003 {
01004 return val.traits->type();
01005 }
01006
01007
01012 bool Item_sum_distinct::setup(Session *session)
01013 {
01014 List<CreateField> field_list;
01015 CreateField field_def;
01016
01017 if (tree)
01018 return(false);
01019
01020
01021
01022
01023
01024
01025 if (field_list.push_back(&field_def))
01026 return(true);
01027
01028 null_value= maybe_null= 1;
01029 quick_group= 0;
01030
01031 assert(args[0]->fixed);
01032
01033 field_def.init_for_tmp_table(table_field_type, args[0]->max_length,
01034 args[0]->decimals, args[0]->maybe_null);
01035
01036 if (! (table= session->getInstanceTable(field_list)))
01037 return(true);
01038
01039
01040 tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
01041
01042
01043
01044
01045
01046
01047
01048 tree= new Unique(simple_raw_key_cmp, &tree_key_length,
01049 tree_key_length,
01050 (size_t)session->variables.max_heap_table_size);
01051
01052 is_evaluated= false;
01053 return(tree == 0);
01054 }
01055
01056
01057 bool Item_sum_distinct::add()
01058 {
01059 args[0]->save_in_field(table->getField(0), false);
01060 is_evaluated= false;
01061 if (!table->getField(0)->is_null())
01062 {
01063 assert(tree);
01064 null_value= 0;
01065
01066
01067
01068
01069 return tree->unique_add(table->getField(0)->ptr);
01070 }
01071 return 0;
01072 }
01073
01074
01075 bool Item_sum_distinct::unique_walk_function(void *element)
01076 {
01077 memcpy(table->getField(0)->ptr, element, tree_key_length);
01078 ++count;
01079 val.traits->add(&val, table->getField(0));
01080 return 0;
01081 }
01082
01083
01084 void Item_sum_distinct::clear()
01085 {
01086 assert(tree != 0);
01087 null_value= 1;
01088 tree->reset();
01089 is_evaluated= false;
01090 return;
01091 }
01092
01093 void Item_sum_distinct::cleanup()
01094 {
01095 Item_sum_num::cleanup();
01096 delete tree;
01097 tree= 0;
01098 table= 0;
01099 is_evaluated= false;
01100 }
01101
01102 Item_sum_distinct::~Item_sum_distinct()
01103 {
01104 delete tree;
01105
01106 }
01107
01108
01109 void Item_sum_distinct::calculate_val_and_count()
01110 {
01111 if (!is_evaluated)
01112 {
01113 count= 0;
01114 val.traits->set_zero(&val);
01115
01116
01117
01118
01119 if (tree)
01120 {
01121 table->getField(0)->set_notnull();
01122 tree->walk(item_sum_distinct_walk, (void*) this);
01123 }
01124 is_evaluated= true;
01125 }
01126 }
01127
01128
01129 double Item_sum_distinct::val_real()
01130 {
01131 calculate_val_and_count();
01132 return val.traits->val_real(&val);
01133 }
01134
01135
01136 type::Decimal *Item_sum_distinct::val_decimal(type::Decimal *to)
01137 {
01138 calculate_val_and_count();
01139 if (null_value)
01140 return 0;
01141 return val.traits->val_decimal(&val, to);
01142 }
01143
01144
01145 int64_t Item_sum_distinct::val_int()
01146 {
01147 calculate_val_and_count();
01148 return val.traits->val_int(&val, unsigned_flag);
01149 }
01150
01151
01152 String *Item_sum_distinct::val_str(String *str)
01153 {
01154 calculate_val_and_count();
01155 if (null_value)
01156 return 0;
01157 return val.traits->val_str(&val, str, decimals);
01158 }
01159
01160
01161
01162
01163
01164 void
01165 Item_sum_avg_distinct::fix_length_and_dec()
01166 {
01167 Item_sum_distinct::fix_length_and_dec();
01168 prec_increment= getSession().variables.div_precincrement;
01169
01170
01171
01172
01173 decimals= min(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
01174 }
01175
01176
01177 void
01178 Item_sum_avg_distinct::calculate_val_and_count()
01179 {
01180 if (!is_evaluated)
01181 {
01182 Item_sum_distinct::calculate_val_and_count();
01183 if (count)
01184 val.traits->div(&val, count);
01185 is_evaluated= true;
01186 }
01187 }
01188
01189
01190 Item *Item_sum_count::copy_or_same(Session* session)
01191 {
01192 return new (session->mem_root) Item_sum_count(session, this);
01193 }
01194
01195
01196 void Item_sum_count::clear()
01197 {
01198 count= 0;
01199 }
01200
01201
01202 bool Item_sum_count::add()
01203 {
01204 if (!args[0]->maybe_null || !args[0]->is_null())
01205 count++;
01206 return 0;
01207 }
01208
01209 int64_t Item_sum_count::val_int()
01210 {
01211 assert(fixed == 1);
01212 return (int64_t) count;
01213 }
01214
01215
01216 void Item_sum_count::cleanup()
01217 {
01218 count= 0;
01219 Item_sum_int::cleanup();
01220 return;
01221 }
01222
01223
01224
01225
01226
01227 void Item_sum_avg::fix_length_and_dec()
01228 {
01229 Item_sum_sum::fix_length_and_dec();
01230 maybe_null=null_value=1;
01231 prec_increment= getSession().variables.div_precincrement;
01232
01233 if (hybrid_type == DECIMAL_RESULT)
01234 {
01235 int precision= args[0]->decimal_precision() + prec_increment;
01236 decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
01237 max_length= class_decimal_precision_to_length(precision, decimals,
01238 unsigned_flag);
01239 f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
01240 f_scale= args[0]->decimals;
01241 dec_bin_size= class_decimal_get_binary_size(f_precision, f_scale);
01242 }
01243 else {
01244 decimals= min(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
01245 max_length= args[0]->max_length + prec_increment;
01246 }
01247 }
01248
01249
01250 Item *Item_sum_avg::copy_or_same(Session* session)
01251 {
01252 return new (session->mem_root) Item_sum_avg(session, this);
01253 }
01254
01255
01256 Field *Item_sum_avg::create_tmp_field(bool group, Table *table,
01257 uint32_t )
01258 {
01259 Field *field;
01260 if (group)
01261 {
01262
01263
01264
01265
01266
01267 table->setVariableWidth();
01268 field= new Field_varstring(((hybrid_type == DECIMAL_RESULT) ?
01269 dec_bin_size : sizeof(double)) + sizeof(int64_t),
01270 0, name, &my_charset_bin);
01271 }
01272 else if (hybrid_type == DECIMAL_RESULT)
01273 field= new Field_decimal(max_length, maybe_null, name,
01274 decimals, unsigned_flag);
01275 else
01276 field= new Field_double(max_length, maybe_null, name, decimals, true);
01277 if (field)
01278 field->init(table);
01279 return field;
01280 }
01281
01282
01283 void Item_sum_avg::clear()
01284 {
01285 Item_sum_sum::clear();
01286 count=0;
01287 }
01288
01289
01290 bool Item_sum_avg::add()
01291 {
01292 if (Item_sum_sum::add())
01293 return true;
01294 if (!args[0]->null_value)
01295 count++;
01296 return false;
01297 }
01298
01299 double Item_sum_avg::val_real()
01300 {
01301 assert(fixed == 1);
01302 if (!count)
01303 {
01304 null_value=1;
01305 return 0.0;
01306 }
01307 return Item_sum_sum::val_real() / uint64_t2double(count);
01308 }
01309
01310
01311 int64_t Item_sum_avg::val_int()
01312 {
01313 return (int64_t) rint(val_real());
01314 }
01315
01316
01317 type::Decimal *Item_sum_avg::val_decimal(type::Decimal *val)
01318 {
01319 type::Decimal sum_buff, cnt;
01320 const type::Decimal *sum_dec;
01321 assert(fixed == 1);
01322 if (!count)
01323 {
01324 null_value=1;
01325 return NULL;
01326 }
01327
01328
01329
01330
01331
01332 if (hybrid_type != DECIMAL_RESULT)
01333 return val_decimal_from_real(val);
01334
01335 sum_dec= dec_buffs + curr_dec_buff;
01336 int2_class_decimal(E_DEC_FATAL_ERROR, count, 0, &cnt);
01337 class_decimal_div(E_DEC_FATAL_ERROR, val, sum_dec, &cnt, prec_increment);
01338 return val;
01339 }
01340
01341
01342 String *Item_sum_avg::val_str(String *str)
01343 {
01344 if (hybrid_type == DECIMAL_RESULT)
01345 return val_string_from_decimal(str);
01346 return val_string_from_real(str);
01347 }
01348
01349
01350
01351
01352
01353
01354 double Item_sum_std::val_real()
01355 {
01356 assert(fixed == 1);
01357 double nr= Item_sum_variance::val_real();
01358 assert(nr >= 0.0);
01359 return sqrt(nr);
01360 }
01361
01362 Item *Item_sum_std::copy_or_same(Session* session)
01363 {
01364 return new (session->mem_root) Item_sum_std(session, this);
01365 }
01366
01367
01368
01369
01370
01371
01372
01379
01380
01381
01382
01383
01384
01385 static void variance_fp_recurrence_next(double *m, double *s, uint64_t *count, double nr)
01386 {
01387 *count += 1;
01388
01389 if (*count == 1)
01390 {
01391 *m= nr;
01392 *s= 0;
01393 }
01394 else
01395 {
01396 double m_kminusone= *m;
01397 *m= m_kminusone + (nr - m_kminusone) / (double) *count;
01398 *s= *s + (nr - m_kminusone) * (nr - *m);
01399 }
01400 }
01401
01402
01403 static double variance_fp_recurrence_result(double s, uint64_t count, bool is_sample_variance)
01404 {
01405 if (count == 1)
01406 return 0.0;
01407
01408 if (is_sample_variance)
01409 return s / (count - 1);
01410
01411
01412 return s / count;
01413 }
01414
01415
01416 Item_sum_variance::Item_sum_variance(Session *session, Item_sum_variance *item):
01417 Item_sum_num(session, item), hybrid_type(item->hybrid_type),
01418 count(item->count), sample(item->sample),
01419 prec_increment(item->prec_increment)
01420 {
01421 recurrence_m= item->recurrence_m;
01422 recurrence_s= item->recurrence_s;
01423 }
01424
01425
01426 void Item_sum_variance::fix_length_and_dec()
01427 {
01428 maybe_null= null_value= 1;
01429 prec_increment= getSession().variables.div_precincrement;
01430
01431
01432
01433
01434
01435
01436
01437 hybrid_type= REAL_RESULT;
01438
01439 switch (args[0]->result_type()) {
01440 case REAL_RESULT:
01441 case STRING_RESULT:
01442 decimals= min(args[0]->decimals + 4, (int)NOT_FIXED_DEC);
01443 break;
01444 case INT_RESULT:
01445 case DECIMAL_RESULT:
01446 {
01447 int precision= args[0]->decimal_precision()*2 + prec_increment;
01448 decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
01449 max_length= class_decimal_precision_to_length(precision, decimals,
01450 unsigned_flag);
01451
01452 break;
01453 }
01454 case ROW_RESULT:
01455 assert(0);
01456 }
01457 }
01458
01459
01460 Item *Item_sum_variance::copy_or_same(Session* session)
01461 {
01462 return new (session->mem_root) Item_sum_variance(session, this);
01463 }
01464
01465
01471 Field *Item_sum_variance::create_tmp_field(bool group, Table *table,
01472 uint32_t )
01473 {
01474 Field *field;
01475 if (group)
01476 {
01477
01478
01479
01480
01481
01482 table->setVariableWidth();
01483 field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, &my_charset_bin);
01484 }
01485 else
01486 field= new Field_double(max_length, maybe_null, name, decimals, true);
01487
01488 if (field != NULL)
01489 field->init(table);
01490
01491 return field;
01492 }
01493
01494
01495 void Item_sum_variance::clear()
01496 {
01497 count= 0;
01498 }
01499
01500 bool Item_sum_variance::add()
01501 {
01502
01503
01504
01505
01506 double nr= args[0]->val_real();
01507
01508 if (!args[0]->null_value)
01509 variance_fp_recurrence_next(&recurrence_m, &recurrence_s, &count, nr);
01510 return 0;
01511 }
01512
01513 double Item_sum_variance::val_real()
01514 {
01515 assert(fixed == 1);
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 assert((sample == 0) || (sample == 1));
01527 if (count <= sample)
01528 {
01529 null_value=1;
01530 return 0.0;
01531 }
01532
01533 null_value=0;
01534 return variance_fp_recurrence_result(recurrence_s, count, sample);
01535 }
01536
01537
01538 int64_t Item_sum_variance::val_int()
01539 {
01540
01541 return (int64_t) rint(val_real());
01542 }
01543
01544
01545 type::Decimal *Item_sum_variance::val_decimal(type::Decimal *dec_buf)
01546 {
01547 assert(fixed == 1);
01548 return val_decimal_from_real(dec_buf);
01549 }
01550
01551
01552 void Item_sum_variance::reset_field()
01553 {
01554 double nr;
01555 unsigned char *res= result_field->ptr;
01556
01557 nr= args[0]->val_real();
01558
01559 if (args[0]->null_value)
01560 memset(res, 0, sizeof(double)*2+sizeof(int64_t));
01561 else
01562 {
01563
01564 uint64_t tmp_count;
01565 double tmp_s;
01566 float8store(res, nr);
01567 tmp_s= 0.0;
01568 float8store(res + sizeof(double), tmp_s);
01569 tmp_count= 1;
01570 int8store(res + sizeof(double)*2, tmp_count);
01571 }
01572 }
01573
01574
01575 void Item_sum_variance::update_field()
01576 {
01577 uint64_t field_count;
01578 unsigned char *res=result_field->ptr;
01579
01580 double nr= args[0]->val_real();
01581
01582 if (args[0]->null_value)
01583 return;
01584
01585
01586 double field_recurrence_m, field_recurrence_s;
01587 float8get(field_recurrence_m, res);
01588 float8get(field_recurrence_s, res + sizeof(double));
01589 field_count=sint8korr(res+sizeof(double)*2);
01590
01591 variance_fp_recurrence_next(&field_recurrence_m, &field_recurrence_s, &field_count, nr);
01592
01593 float8store(res, field_recurrence_m);
01594 float8store(res + sizeof(double), field_recurrence_s);
01595 res+= sizeof(double)*2;
01596 int8store(res,field_count);
01597 }
01598
01599
01600
01601
01602 void Item_sum_hybrid::clear()
01603 {
01604 switch (hybrid_type) {
01605 case INT_RESULT:
01606 sum_int= 0;
01607 break;
01608 case DECIMAL_RESULT:
01609 sum_dec.set_zero();
01610 break;
01611 case REAL_RESULT:
01612 sum= 0.0;
01613 break;
01614 default:
01615 value.length(0);
01616 }
01617 null_value= 1;
01618 }
01619
01620 double Item_sum_hybrid::val_real()
01621 {
01622 assert(fixed == 1);
01623 if (null_value)
01624 return 0.0;
01625
01626 switch (hybrid_type) {
01627 case STRING_RESULT:
01628 {
01629 char *end_not_used;
01630 int err_not_used;
01631 String *res; res=val_str(&str_value);
01632 return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
01633 &end_not_used, &err_not_used) : 0.0);
01634 }
01635 case INT_RESULT:
01636 return (double) sum_int;
01637 case DECIMAL_RESULT:
01638 class_decimal2double(E_DEC_FATAL_ERROR, &sum_dec, &sum);
01639 return sum;
01640 case REAL_RESULT:
01641 return sum;
01642 case ROW_RESULT:
01643
01644 break;
01645 }
01646
01647 assert(0);
01648 return 0;
01649 }
01650
01651 int64_t Item_sum_hybrid::val_int()
01652 {
01653 assert(fixed == 1);
01654 if (null_value)
01655 return 0;
01656 switch (hybrid_type) {
01657 case INT_RESULT:
01658 return sum_int;
01659 case DECIMAL_RESULT:
01660 {
01661 int64_t result;
01662 sum_dec.val_int32(E_DEC_FATAL_ERROR, unsigned_flag, &result);
01663 return sum_int;
01664 }
01665 default:
01666 return (int64_t) rint(Item_sum_hybrid::val_real());
01667 }
01668 }
01669
01670
01671 type::Decimal *Item_sum_hybrid::val_decimal(type::Decimal *val)
01672 {
01673 assert(fixed == 1);
01674 if (null_value)
01675 return 0;
01676
01677 switch (hybrid_type) {
01678 case STRING_RESULT:
01679 val->store(E_DEC_FATAL_ERROR, &value);
01680 break;
01681 case REAL_RESULT:
01682 double2_class_decimal(E_DEC_FATAL_ERROR, sum, val);
01683 break;
01684 case DECIMAL_RESULT:
01685 val= &sum_dec;
01686 break;
01687 case INT_RESULT:
01688 int2_class_decimal(E_DEC_FATAL_ERROR, sum_int, unsigned_flag, val);
01689 break;
01690 case ROW_RESULT:
01691
01692 assert(0);
01693 break;
01694 }
01695
01696 return val;
01697 }
01698
01699
01700 String *
01701 Item_sum_hybrid::val_str(String *str)
01702 {
01703 assert(fixed == 1);
01704 if (null_value)
01705 return 0;
01706
01707 switch (hybrid_type) {
01708 case STRING_RESULT:
01709 return &value;
01710 case REAL_RESULT:
01711 str->set_real(sum,decimals, &my_charset_bin);
01712 break;
01713 case DECIMAL_RESULT:
01714 class_decimal2string(&sum_dec, 0, str);
01715 return str;
01716 case INT_RESULT:
01717 str->set_int(sum_int, unsigned_flag, &my_charset_bin);
01718 break;
01719 case ROW_RESULT:
01720 default:
01721
01722 break;
01723 }
01724
01725 return str;
01726 }
01727
01728
01729 void Item_sum_hybrid::cleanup()
01730 {
01731 Item_sum::cleanup();
01732 forced_const= false;
01733
01734
01735
01736
01737
01738
01739
01740
01741 was_values= true;
01742 return;
01743 }
01744
01745 void Item_sum_hybrid::no_rows_in_result()
01746 {
01747 was_values= false;
01748 clear();
01749 }
01750
01751
01752 Item *Item_sum_min::copy_or_same(Session* session)
01753 {
01754 return new (session->mem_root) Item_sum_min(session, this);
01755 }
01756
01757
01758 bool Item_sum_min::add()
01759 {
01760 switch (hybrid_type) {
01761 case STRING_RESULT:
01762 {
01763 String *result=args[0]->val_str(&tmp_value);
01764 if (!args[0]->null_value &&
01765 (null_value || sortcmp(&value,result,collation.collation) > 0))
01766 {
01767 value.copy(*result);
01768 null_value=0;
01769 }
01770 }
01771 break;
01772 case INT_RESULT:
01773 {
01774 int64_t nr=args[0]->val_int();
01775 if (!args[0]->null_value && (null_value ||
01776 (unsigned_flag &&
01777 (uint64_t) nr < (uint64_t) sum_int) ||
01778 (!unsigned_flag && nr < sum_int)))
01779 {
01780 sum_int=nr;
01781 null_value=0;
01782 }
01783 }
01784 break;
01785 case DECIMAL_RESULT:
01786 {
01787 type::Decimal value_buff, *val= args[0]->val_decimal(&value_buff);
01788 if (!args[0]->null_value &&
01789 (null_value || (class_decimal_cmp(&sum_dec, val) > 0)))
01790 {
01791 class_decimal2decimal(val, &sum_dec);
01792 null_value= 0;
01793 }
01794 }
01795 break;
01796 case REAL_RESULT:
01797 {
01798 double nr= args[0]->val_real();
01799 if (!args[0]->null_value && (null_value || nr < sum))
01800 {
01801 sum=nr;
01802 null_value=0;
01803 }
01804 }
01805 break;
01806 case ROW_RESULT:
01807
01808 assert(0);
01809 break;
01810 }
01811 return 0;
01812 }
01813
01814
01815 Item *Item_sum_max::copy_or_same(Session* session)
01816 {
01817 return new (session->mem_root) Item_sum_max(session, this);
01818 }
01819
01820
01821 bool Item_sum_max::add()
01822 {
01823 switch (hybrid_type) {
01824 case STRING_RESULT:
01825 {
01826 String *result=args[0]->val_str(&tmp_value);
01827 if (!args[0]->null_value &&
01828 (null_value || sortcmp(&value,result,collation.collation) < 0))
01829 {
01830 value.copy(*result);
01831 null_value=0;
01832 }
01833 }
01834 break;
01835 case INT_RESULT:
01836 {
01837 int64_t nr=args[0]->val_int();
01838 if (!args[0]->null_value && (null_value ||
01839 (unsigned_flag &&
01840 (uint64_t) nr > (uint64_t) sum_int) ||
01841 (!unsigned_flag && nr > sum_int)))
01842 {
01843 sum_int=nr;
01844 null_value=0;
01845 }
01846 }
01847 break;
01848 case DECIMAL_RESULT:
01849 {
01850 type::Decimal value_buff, *val= args[0]->val_decimal(&value_buff);
01851 if (!args[0]->null_value &&
01852 (null_value || (class_decimal_cmp(val, &sum_dec) > 0)))
01853 {
01854 class_decimal2decimal(val, &sum_dec);
01855 null_value= 0;
01856 }
01857 }
01858 break;
01859 case REAL_RESULT:
01860 {
01861 double nr= args[0]->val_real();
01862 if (!args[0]->null_value && (null_value || nr > sum))
01863 {
01864 sum=nr;
01865 null_value=0;
01866 }
01867 }
01868 break;
01869 case ROW_RESULT:
01870
01871 assert(0);
01872 break;
01873 }
01874
01875 return 0;
01876 }
01877
01878
01879
01880
01881 int64_t Item_sum_bit::val_int()
01882 {
01883 assert(fixed == 1);
01884 return (int64_t) bits;
01885 }
01886
01887
01888 void Item_sum_bit::clear()
01889 {
01890 bits= reset_bits;
01891 }
01892
01893 Item *Item_sum_or::copy_or_same(Session* session)
01894 {
01895 return new (session->mem_root) Item_sum_or(session, this);
01896 }
01897
01898
01899 bool Item_sum_or::add()
01900 {
01901 uint64_t value= (uint64_t) args[0]->val_int();
01902 if (!args[0]->null_value)
01903 bits|=value;
01904 return 0;
01905 }
01906
01907 Item *Item_sum_xor::copy_or_same(Session* session)
01908 {
01909 return new (session->mem_root) Item_sum_xor(session, this);
01910 }
01911
01912
01913 bool Item_sum_xor::add()
01914 {
01915 uint64_t value= (uint64_t) args[0]->val_int();
01916 if (!args[0]->null_value)
01917 bits^=value;
01918 return 0;
01919 }
01920
01921 Item *Item_sum_and::copy_or_same(Session* session)
01922 {
01923 return new (session->mem_root) Item_sum_and(session, this);
01924 }
01925
01926
01927 bool Item_sum_and::add()
01928 {
01929 uint64_t value= (uint64_t) args[0]->val_int();
01930 if (!args[0]->null_value)
01931 bits&=value;
01932 return 0;
01933 }
01934
01935
01936
01937
01938
01939 void Item_sum_num::reset_field()
01940 {
01941 double nr= args[0]->val_real();
01942 unsigned char *res=result_field->ptr;
01943
01944 if (maybe_null)
01945 {
01946 if (args[0]->null_value)
01947 {
01948 nr=0.0;
01949 result_field->set_null();
01950 }
01951 else
01952 result_field->set_notnull();
01953 }
01954 float8store(res,nr);
01955 }
01956
01957
01958 void Item_sum_hybrid::reset_field()
01959 {
01960 switch(hybrid_type) {
01961 case STRING_RESULT:
01962 {
01963 char buff[MAX_FIELD_WIDTH];
01964 String tmp(buff,sizeof(buff),result_field->charset()),*res;
01965
01966 res=args[0]->val_str(&tmp);
01967 if (args[0]->null_value)
01968 {
01969 result_field->set_null();
01970 result_field->reset();
01971 }
01972 else
01973 {
01974 result_field->set_notnull();
01975 result_field->store(res->ptr(),res->length(),tmp.charset());
01976 }
01977 break;
01978 }
01979 case INT_RESULT:
01980 {
01981 int64_t nr=args[0]->val_int();
01982
01983 if (maybe_null)
01984 {
01985 if (args[0]->null_value)
01986 {
01987 nr=0;
01988 result_field->set_null();
01989 }
01990 else
01991 result_field->set_notnull();
01992 }
01993 result_field->store(nr, unsigned_flag);
01994 break;
01995 }
01996 case REAL_RESULT:
01997 {
01998 double nr= args[0]->val_real();
01999
02000 if (maybe_null)
02001 {
02002 if (args[0]->null_value)
02003 {
02004 nr=0.0;
02005 result_field->set_null();
02006 }
02007 else
02008 result_field->set_notnull();
02009 }
02010 result_field->store(nr);
02011 break;
02012 }
02013 case DECIMAL_RESULT:
02014 {
02015 type::Decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
02016
02017 if (maybe_null)
02018 {
02019 if (args[0]->null_value)
02020 result_field->set_null();
02021 else
02022 result_field->set_notnull();
02023 }
02024
02025
02026
02027
02028 if (!arg_dec)
02029 arg_dec= &decimal_zero;
02030 result_field->store_decimal(arg_dec);
02031 break;
02032 }
02033 case ROW_RESULT:
02034 assert(0);
02035 }
02036 }
02037
02038
02039 void Item_sum_sum::reset_field()
02040 {
02041 if (hybrid_type == DECIMAL_RESULT)
02042 {
02043 type::Decimal value, *arg_val= args[0]->val_decimal(&value);
02044 if (!arg_val)
02045 arg_val= &decimal_zero;
02046 result_field->store_decimal(arg_val);
02047 }
02048 else
02049 {
02050 assert(hybrid_type == REAL_RESULT);
02051 double nr= args[0]->val_real();
02052 float8store(result_field->ptr, nr);
02053 }
02054 if (args[0]->null_value)
02055 result_field->set_null();
02056 else
02057 result_field->set_notnull();
02058 }
02059
02060
02061 void Item_sum_count::reset_field()
02062 {
02063 unsigned char *res=result_field->ptr;
02064 int64_t nr=0;
02065
02066 if (!args[0]->maybe_null || !args[0]->is_null())
02067 nr=1;
02068 int8store(res,nr);
02069 }
02070
02071
02072 void Item_sum_avg::reset_field()
02073 {
02074 unsigned char *res=result_field->ptr;
02075 if (hybrid_type == DECIMAL_RESULT)
02076 {
02077 int64_t tmp;
02078 type::Decimal value, *arg_dec= args[0]->val_decimal(&value);
02079 if (args[0]->null_value)
02080 {
02081 arg_dec= &decimal_zero;
02082 tmp= 0;
02083 }
02084 else
02085 tmp= 1;
02086 arg_dec->val_binary(E_DEC_FATAL_ERROR, res, f_precision, f_scale);
02087 res+= dec_bin_size;
02088 int8store(res, tmp);
02089 }
02090 else
02091 {
02092 double nr= args[0]->val_real();
02093
02094 if (args[0]->null_value)
02095 memset(res, 0, sizeof(double)+sizeof(int64_t));
02096 else
02097 {
02098 int64_t tmp= 1;
02099 float8store(res,nr);
02100 res+=sizeof(double);
02101 int8store(res,tmp);
02102 }
02103 }
02104 }
02105
02106
02107 void Item_sum_bit::reset_field()
02108 {
02109 reset();
02110 int8store(result_field->ptr, bits);
02111 }
02112
02113 void Item_sum_bit::update_field()
02114 {
02115 unsigned char *res=result_field->ptr;
02116 bits= uint8korr(res);
02117 add();
02118 int8store(res, bits);
02119 }
02120
02121
02126 void Item_sum_sum::update_field()
02127 {
02128 if (hybrid_type == DECIMAL_RESULT)
02129 {
02130 type::Decimal value, *arg_val= args[0]->val_decimal(&value);
02131 if (!args[0]->null_value)
02132 {
02133 if (!result_field->is_null())
02134 {
02135 type::Decimal field_value,
02136 *field_val= result_field->val_decimal(&field_value);
02137 class_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, field_val);
02138 result_field->store_decimal(dec_buffs);
02139 }
02140 else
02141 {
02142 result_field->store_decimal(arg_val);
02143 result_field->set_notnull();
02144 }
02145 }
02146 }
02147 else
02148 {
02149 double old_nr,nr;
02150 unsigned char *res=result_field->ptr;
02151
02152 float8get(old_nr,res);
02153 nr= args[0]->val_real();
02154 if (!args[0]->null_value)
02155 {
02156 old_nr+=nr;
02157 result_field->set_notnull();
02158 }
02159 float8store(res,old_nr);
02160 }
02161 }
02162
02163
02164 void Item_sum_count::update_field()
02165 {
02166 int64_t nr;
02167 unsigned char *res=result_field->ptr;
02168
02169 nr=sint8korr(res);
02170 if (!args[0]->maybe_null || !args[0]->is_null())
02171 nr++;
02172 int8store(res,nr);
02173 }
02174
02175
02176 void Item_sum_avg::update_field()
02177 {
02178 int64_t field_count;
02179 unsigned char *res=result_field->ptr;
02180 if (hybrid_type == DECIMAL_RESULT)
02181 {
02182 type::Decimal value, *arg_val= args[0]->val_decimal(&value);
02183 if (!args[0]->null_value)
02184 {
02185 binary2_class_decimal(E_DEC_FATAL_ERROR, res,
02186 dec_buffs + 1, f_precision, f_scale);
02187 field_count= sint8korr(res + dec_bin_size);
02188 class_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, dec_buffs + 1);
02189 dec_buffs->val_binary(E_DEC_FATAL_ERROR, res, f_precision, f_scale);
02190 res+= dec_bin_size;
02191 field_count++;
02192 int8store(res, field_count);
02193 }
02194 }
02195 else
02196 {
02197 double nr;
02198
02199 nr= args[0]->val_real();
02200 if (!args[0]->null_value)
02201 {
02202 double old_nr;
02203 float8get(old_nr, res);
02204 field_count= sint8korr(res + sizeof(double));
02205 old_nr+= nr;
02206 float8store(res,old_nr);
02207 res+= sizeof(double);
02208 field_count++;
02209 int8store(res, field_count);
02210 }
02211 }
02212 }
02213
02214
02215 void Item_sum_hybrid::update_field()
02216 {
02217 switch (hybrid_type) {
02218 case STRING_RESULT:
02219 min_max_update_str_field();
02220 break;
02221 case INT_RESULT:
02222 min_max_update_int_field();
02223 break;
02224 case DECIMAL_RESULT:
02225 min_max_update_decimal_field();
02226 break;
02227 case REAL_RESULT:
02228 case ROW_RESULT:
02229 min_max_update_real_field();
02230 }
02231 }
02232
02233
02234 void
02235 Item_sum_hybrid::min_max_update_str_field()
02236 {
02237 String *res_str=args[0]->val_str(&value);
02238
02239 if (!args[0]->null_value)
02240 {
02241 result_field->val_str_internal(&tmp_value);
02242
02243 if (result_field->is_null() ||
02244 (cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
02245 result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
02246 result_field->set_notnull();
02247 }
02248 }
02249
02250
02251 void
02252 Item_sum_hybrid::min_max_update_real_field()
02253 {
02254 double nr,old_nr;
02255
02256 old_nr=result_field->val_real();
02257 nr= args[0]->val_real();
02258 if (!args[0]->null_value)
02259 {
02260 if (result_field->is_null(0) ||
02261 (cmp_sign > 0 ? old_nr > nr : old_nr < nr))
02262 old_nr=nr;
02263 result_field->set_notnull();
02264 }
02265 else if (result_field->is_null(0))
02266 result_field->set_null();
02267 result_field->store(old_nr);
02268 }
02269
02270
02271 void
02272 Item_sum_hybrid::min_max_update_int_field()
02273 {
02274 int64_t nr,old_nr;
02275
02276 old_nr=result_field->val_int();
02277 nr=args[0]->val_int();
02278 if (!args[0]->null_value)
02279 {
02280 if (result_field->is_null(0))
02281 old_nr=nr;
02282 else
02283 {
02284 bool res=(unsigned_flag ?
02285 (uint64_t) old_nr > (uint64_t) nr :
02286 old_nr > nr);
02287
02288 if ((cmp_sign > 0) ^ (!res))
02289 old_nr=nr;
02290 }
02291 result_field->set_notnull();
02292 }
02293 else if (result_field->is_null(0))
02294 result_field->set_null();
02295 result_field->store(old_nr, unsigned_flag);
02296 }
02297
02298
02303 void
02304 Item_sum_hybrid::min_max_update_decimal_field()
02305 {
02306
02307 type::Decimal old_val, nr_val;
02308 const type::Decimal *old_nr= result_field->val_decimal(&old_val);
02309 const type::Decimal *nr= args[0]->val_decimal(&nr_val);
02310 if (!args[0]->null_value)
02311 {
02312 if (result_field->is_null(0))
02313 old_nr=nr;
02314 else
02315 {
02316 bool res= class_decimal_cmp(old_nr, nr) > 0;
02317
02318 if ((cmp_sign > 0) ^ (!res))
02319 old_nr=nr;
02320 }
02321 result_field->set_notnull();
02322 }
02323 else if (result_field->is_null(0))
02324 result_field->set_null();
02325 result_field->store_decimal(old_nr);
02326 }
02327
02328
02329 Item_avg_field::Item_avg_field(Item_result res_type, Item_sum_avg *item)
02330 {
02331 name=item->name;
02332 decimals=item->decimals;
02333 max_length= item->max_length;
02334 unsigned_flag= item->unsigned_flag;
02335 field=item->result_field;
02336 maybe_null=1;
02337 hybrid_type= res_type;
02338 prec_increment= item->prec_increment;
02339 if (hybrid_type == DECIMAL_RESULT)
02340 {
02341 f_scale= item->f_scale;
02342 f_precision= item->f_precision;
02343 dec_bin_size= item->dec_bin_size;
02344 }
02345 }
02346
02347 double Item_avg_field::val_real()
02348 {
02349
02350 double nr;
02351 int64_t count;
02352 unsigned char *res;
02353
02354 if (hybrid_type == DECIMAL_RESULT)
02355 return val_real_from_decimal();
02356
02357 float8get(nr,field->ptr);
02358 res= (field->ptr+sizeof(double));
02359 count= sint8korr(res);
02360
02361 if ((null_value= !count))
02362 return 0.0;
02363 return nr/(double) count;
02364 }
02365
02366
02367 int64_t Item_avg_field::val_int()
02368 {
02369 return (int64_t) rint(val_real());
02370 }
02371
02372
02373 type::Decimal *Item_avg_field::val_decimal(type::Decimal *dec_buf)
02374 {
02375
02376 if (hybrid_type == REAL_RESULT)
02377 return val_decimal_from_real(dec_buf);
02378
02379 int64_t count= sint8korr(field->ptr + dec_bin_size);
02380 if ((null_value= !count))
02381 return 0;
02382
02383 type::Decimal dec_count, dec_field;
02384 binary2_class_decimal(E_DEC_FATAL_ERROR,
02385 field->ptr, &dec_field, f_precision, f_scale);
02386 int2_class_decimal(E_DEC_FATAL_ERROR, count, 0, &dec_count);
02387 class_decimal_div(E_DEC_FATAL_ERROR, dec_buf,
02388 &dec_field, &dec_count, prec_increment);
02389 return dec_buf;
02390 }
02391
02392
02393 String *Item_avg_field::val_str(String *str)
02394 {
02395
02396 if (hybrid_type == DECIMAL_RESULT)
02397 return val_string_from_decimal(str);
02398 return val_string_from_real(str);
02399 }
02400
02401
02402 Item_std_field::Item_std_field(Item_sum_std *item)
02403 : Item_variance_field(item)
02404 {
02405 }
02406
02407
02408 double Item_std_field::val_real()
02409 {
02410 double nr;
02411
02412 nr= Item_variance_field::val_real();
02413 assert(nr >= 0.0);
02414 return sqrt(nr);
02415 }
02416
02417
02418 type::Decimal *Item_std_field::val_decimal(type::Decimal *dec_buf)
02419 {
02420
02421
02422
02423
02424 type::Decimal tmp_dec, *dec;
02425 double nr;
02426 if (hybrid_type == REAL_RESULT)
02427 return val_decimal_from_real(dec_buf);
02428
02429 dec= Item_variance_field::val_decimal(dec_buf);
02430 if (!dec)
02431 return 0;
02432 class_decimal2double(E_DEC_FATAL_ERROR, dec, &nr);
02433 assert(nr >= 0.0);
02434 nr= sqrt(nr);
02435 double2_class_decimal(E_DEC_FATAL_ERROR, nr, &tmp_dec);
02436 class_decimal_round(E_DEC_FATAL_ERROR, &tmp_dec, decimals, false, dec_buf);
02437 return dec_buf;
02438 }
02439
02440
02441 Item_variance_field::Item_variance_field(Item_sum_variance *item)
02442 {
02443 name=item->name;
02444 decimals=item->decimals;
02445 max_length=item->max_length;
02446 unsigned_flag= item->unsigned_flag;
02447 field=item->result_field;
02448 maybe_null=1;
02449 sample= item->sample;
02450 prec_increment= item->prec_increment;
02451 if ((hybrid_type= item->hybrid_type) == DECIMAL_RESULT)
02452 {
02453 f_scale0= item->f_scale0;
02454 f_precision0= item->f_precision0;
02455 dec_bin_size0= item->dec_bin_size0;
02456 f_scale1= item->f_scale1;
02457 f_precision1= item->f_precision1;
02458 dec_bin_size1= item->dec_bin_size1;
02459 }
02460 }
02461
02462
02463 int64_t Item_variance_field::val_int()
02464 {
02465
02466 return (int64_t) rint(val_real());
02467 }
02468
02469
02470 double Item_variance_field::val_real()
02471 {
02472
02473 if (hybrid_type == DECIMAL_RESULT)
02474 return val_real_from_decimal();
02475
02476 double recurrence_s;
02477 uint64_t count;
02478 float8get(recurrence_s, (field->ptr + sizeof(double)));
02479 count=sint8korr(field->ptr+sizeof(double)*2);
02480
02481 if ((null_value= (count <= sample)))
02482 return 0.0;
02483
02484 return variance_fp_recurrence_result(recurrence_s, count, sample);
02485 }
02486
02487
02488
02489
02490
02491
02492 int simple_str_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
02493 {
02494 Field *f= (Field*) arg;
02495 return f->cmp(key1, key2);
02496 }
02497
02505 int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
02506 {
02507 Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
02508 Field **field = item->table->getFields();
02509 Field **field_end= field + item->table->getShare()->sizeFields();
02510 uint32_t *lengths=item->field_lengths;
02511 for (; field < field_end; ++field)
02512 {
02513 Field* f = *field;
02514 int len = *lengths++;
02515 int res = f->cmp(key1, key2);
02516 if (res)
02517 return res;
02518 key1 += len;
02519 key2 += len;
02520 }
02521 return 0;
02522 }
02523
02524 static int count_distinct_walk(void *,
02525 uint32_t ,
02526 void *arg)
02527 {
02528 (*((uint64_t*)arg))++;
02529 return 0;
02530 }
02531
02532 void Item_sum_count_distinct::cleanup()
02533 {
02534 Item_sum_int::cleanup();
02535
02536
02537 if (!original)
02538 {
02539
02540
02541
02542
02543
02544 delete tree;
02545 tree= 0;
02546 is_evaluated= false;
02547 if (table)
02548 {
02549 table= 0;
02550 }
02551 delete tmp_table_param;
02552 tmp_table_param= 0;
02553 }
02554 always_null= false;
02555 return;
02556 }
02557
02558
02564 void Item_sum_count_distinct::make_unique()
02565 {
02566 table=0;
02567 original= 0;
02568 force_copy_fields= 1;
02569 tree= 0;
02570 is_evaluated= false;
02571 tmp_table_param= 0;
02572 always_null= false;
02573 }
02574
02575
02576 Item_sum_count_distinct::~Item_sum_count_distinct()
02577 {
02578 cleanup();
02579 }
02580
02581
02582 bool Item_sum_count_distinct::setup(Session *session)
02583 {
02584 List<Item> list;
02585 Select_Lex *select_lex= session->lex().current_select;
02586
02587
02588
02589
02590
02591
02592 if (tree || table || tmp_table_param)
02593 return false;
02594
02595 if (!(tmp_table_param= new Tmp_Table_Param))
02596 return true;
02597
02598
02599 for (uint32_t i=0; i < arg_count ; i++)
02600 {
02601 Item *item=args[i];
02602 if (list.push_back(item))
02603 return true;
02604 if (item->const_item() && item->is_null())
02605 always_null= 1;
02606 }
02607 if (always_null)
02608 return false;
02609 count_field_types(select_lex, tmp_table_param, list, 0);
02610 tmp_table_param->force_copy_fields= force_copy_fields;
02611 assert(table == 0);
02612
02613 if (!(table= create_tmp_table(session, tmp_table_param, list, (Order*) 0, 1,
02614 0,
02615 (select_lex->options | session->options),
02616 HA_POS_ERROR, (char*)"")))
02617 {
02618 return true;
02619 }
02620 table->cursor->extra(HA_EXTRA_NO_ROWS);
02621 table->no_rows=1;
02622
02623 if (table->getShare()->db_type() == heap_engine)
02624 {
02625
02626
02627
02628
02629 qsort_cmp2 compare_key;
02630 void* cmp_arg;
02631 Field **field= table->getFields();
02632 Field **field_end= field + table->getShare()->sizeFields();
02633 bool all_binary= true;
02634
02635 for (tree_key_length= 0; field < field_end; ++field)
02636 {
02637 Field *f= *field;
02638 enum enum_field_types f_type= f->type();
02639 tree_key_length+= f->pack_length();
02640 if (f_type == DRIZZLE_TYPE_VARCHAR)
02641 {
02642 all_binary= false;
02643 break;
02644 }
02645 }
02646 if (all_binary)
02647 {
02648 cmp_arg= (void*) &tree_key_length;
02649 compare_key= (qsort_cmp2) simple_raw_key_cmp;
02650 }
02651 else
02652 {
02653 if (table->getShare()->sizeFields() == 1)
02654 {
02655
02656
02657
02658
02659
02660
02661 compare_key= (qsort_cmp2) simple_str_key_cmp;
02662 cmp_arg= (void*) table->getField(0);
02663
02664 }
02665 else
02666 {
02667 uint32_t *length;
02668 compare_key= (qsort_cmp2) composite_key_cmp;
02669 cmp_arg= (void*) this;
02670 field_lengths= (uint32_t*) session->getMemRoot()->allocate(table->getShare()->sizeFields() * sizeof(uint32_t));
02671 for (tree_key_length= 0, length= field_lengths, field= table->getFields();
02672 field < field_end; ++field, ++length)
02673 {
02674 *length= (*field)->pack_length();
02675 tree_key_length+= *length;
02676 }
02677 }
02678 }
02679 assert(tree == 0);
02680 tree= new Unique(compare_key, cmp_arg, tree_key_length,
02681 (size_t)session->variables.max_heap_table_size);
02682
02683
02684
02685
02686
02687
02688 is_evaluated= false;
02689 if (! tree)
02690 return true;
02691 }
02692 return false;
02693 }
02694
02695
02696 Item *Item_sum_count_distinct::copy_or_same(Session* session)
02697 {
02698 return new (session->mem_root) Item_sum_count_distinct(session, this);
02699 }
02700
02701
02702 void Item_sum_count_distinct::clear()
02703 {
02704
02705 is_evaluated= false;
02706 if (tree)
02707 {
02708 tree->reset();
02709 }
02710 else if (table)
02711 {
02712 table->cursor->extra(HA_EXTRA_NO_CACHE);
02713 table->cursor->ha_delete_all_rows();
02714 table->cursor->extra(HA_EXTRA_WRITE_CACHE);
02715 }
02716 }
02717
02718 bool Item_sum_count_distinct::add()
02719 {
02720 int error;
02721 if (always_null)
02722 return 0;
02723 copy_fields(tmp_table_param);
02724 if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
02725 return true;
02726
02727 for (Field **field= table->getFields() ; *field ; field++)
02728 {
02729 if ((*field)->is_real_null(0))
02730 {
02731 return 0;
02732 }
02733 }
02734
02735 is_evaluated= false;
02736 if (tree)
02737 {
02738
02739
02740
02741
02742
02743
02744 return tree->unique_add(table->record[0] + table->getShare()->null_bytes);
02745 }
02746 if ((error= table->cursor->insertRecord(table->record[0])) &&
02747 table->cursor->is_fatal_error(error, HA_CHECK_DUP))
02748 return true;
02749 return false;
02750 }
02751
02752
02753 int64_t Item_sum_count_distinct::val_int()
02754 {
02755 int error;
02756 assert(fixed == 1);
02757 if (!table)
02758 return 0L;
02759 if (tree)
02760 {
02761 if (is_evaluated)
02762 return count;
02763
02764 if (tree->elements == 0)
02765 return (int64_t) tree->elements_in_tree();
02766 count= 0;
02767 tree->walk(count_distinct_walk, (void*) &count);
02768 is_evaluated= true;
02769 return (int64_t) count;
02770 }
02771
02772 error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
02773
02774 if(error)
02775 {
02776 table->print_error(error, MYF(0));
02777 }
02778
02779 return table->cursor->stats.records;
02780 }
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02811 int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
02812 const void* key2)
02813 {
02814 Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
02815 Table *table= item_func->table;
02816
02817 for (uint32_t i= 0; i < item_func->arg_count_field; i++)
02818 {
02819 Item *item= item_func->args[i];
02820
02821
02822
02823
02824 if (item->const_item())
02825 continue;
02826
02827
02828
02829
02830
02831 Field *field= item->get_tmp_table_field();
02832 int res;
02833 uint32_t offset= field->offset(field->getTable()->record[0])-table->getShare()->null_bytes;
02834 if((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
02835 return res;
02836 }
02837 return 0;
02838 }
02839
02840
02845 int group_concat_key_cmp_with_order(void* arg, const void* key1,
02846 const void* key2)
02847 {
02848 Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
02849 Order **order_item, **end;
02850 Table *table= grp_item->table;
02851
02852 for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
02853 order_item < end;
02854 order_item++)
02855 {
02856 Item *item= *(*order_item)->item;
02857
02858
02859
02860
02861
02862 Field *field= item->get_tmp_table_field();
02863
02864
02865
02866
02867 if (field && !item->const_item())
02868 {
02869 int res;
02870 uint32_t offset= (field->offset(field->getTable()->record[0]) -
02871 table->getShare()->null_bytes);
02872 if ((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
02873 return (*order_item)->asc ? res : -res;
02874 }
02875 }
02876
02877
02878
02879
02880
02881 return 1;
02882 }
02883
02884
02889 int dump_leaf_key(unsigned char* key, uint32_t ,
02890 Item_func_group_concat *item)
02891 {
02892 Table *table= item->table;
02893 String tmp((char *)table->getUpdateRecord(), table->getShare()->getRecordLength(),
02894 default_charset_info);
02895 String tmp2;
02896 String *result= &item->result;
02897 Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
02898 uint32_t old_length= result->length();
02899
02900 if (item->no_appended)
02901 item->no_appended= false;
02902 else
02903 result->append(*item->separator);
02904
02905 tmp.length(0);
02906
02907 for (; arg < arg_end; arg++)
02908 {
02909 String *res;
02910 if (! (*arg)->const_item())
02911 {
02912
02913
02914
02915
02916
02917
02918
02919 Field *field= (*arg)->get_tmp_table_field();
02920 uint32_t offset= (field->offset(field->getTable()->record[0]) -
02921 table->getShare()->null_bytes);
02922 assert(offset < table->getShare()->getRecordLength());
02923 res= field->val_str_internal(&tmp, key + offset);
02924 }
02925 else
02926 res= (*arg)->val_str(&tmp);
02927 if (res)
02928 result->append(*res);
02929 }
02930
02931
02932 if (result->length() > item->max_length)
02933 {
02934 int well_formed_error;
02935 const CHARSET_INFO * const cs= item->collation.collation;
02936 const char *ptr= result->ptr();
02937 uint32_t add_length;
02938
02939
02940
02941
02942
02943 add_length= cs->cset->well_formed_len(cs,
02944 ptr + old_length,
02945 ptr + item->max_length,
02946 result->length(),
02947 &well_formed_error);
02948 result->length(old_length + add_length);
02949 item->count_cut_values++;
02950 item->warning_for_row= true;
02951 return 1;
02952 }
02953 return 0;
02954 }
02955
02956
02966 Item_func_group_concat::
02967 Item_func_group_concat(Name_resolution_context *context_arg,
02968 bool distinct_arg, List<Item> *select_list,
02969 SQL_LIST *order_list, String *separator_arg)
02970 :tmp_table_param(0), warning(0),
02971 separator(separator_arg), tree(NULL), unique_filter(NULL), table(0),
02972 order(0), context(context_arg),
02973 arg_count_order(order_list ? order_list->elements : 0),
02974 arg_count_field(select_list->size()),
02975 count_cut_values(0),
02976 distinct(distinct_arg),
02977 warning_for_row(false),
02978 force_copy_fields(0), original(0)
02979 {
02980 Item *item_select;
02981 Item **arg_ptr;
02982
02983 quick_group= false;
02984 arg_count= arg_count_field + arg_count_order;
02985
02986
02987
02988
02989
02990
02991
02992 if (!(args= (Item**) memory::sql_alloc(sizeof(Item*) * arg_count +
02993 sizeof(Order*)*arg_count_order)))
02994 return;
02995
02996 order= (Order**)(args + arg_count);
02997
02998
02999 List<Item>::iterator li(select_list->begin());
03000
03001 for (arg_ptr=args ; (item_select= li++) ; arg_ptr++)
03002 *arg_ptr= item_select;
03003
03004 if (arg_count_order)
03005 {
03006 Order **order_ptr= order;
03007 for (Order *order_item= (Order*) order_list->first;
03008 order_item != NULL;
03009 order_item= order_item->next)
03010 {
03011 (*order_ptr++)= order_item;
03012 *arg_ptr= *order_item->item;
03013 order_item->item= arg_ptr++;
03014 }
03015 }
03016 }
03017
03018
03019 Item_func_group_concat::Item_func_group_concat(Session *session,
03020 Item_func_group_concat *item)
03021 :Item_sum(session, item),
03022 tmp_table_param(item->tmp_table_param),
03023 warning(item->warning),
03024 separator(item->separator),
03025 tree(item->tree),
03026 unique_filter(item->unique_filter),
03027 table(item->table),
03028 order(item->order),
03029 context(item->context),
03030 arg_count_order(item->arg_count_order),
03031 arg_count_field(item->arg_count_field),
03032 count_cut_values(item->count_cut_values),
03033 distinct(item->distinct),
03034 warning_for_row(item->warning_for_row),
03035 always_null(item->always_null),
03036 force_copy_fields(item->force_copy_fields),
03037 original(item)
03038 {
03039 quick_group= item->quick_group;
03040 result.set_charset(collation.collation);
03041 }
03042
03043
03044
03045 void Item_func_group_concat::cleanup()
03046 {
03047 Item_sum::cleanup();
03048
03049
03050 if (warning)
03051 {
03052 char warn_buff[DRIZZLE_ERRMSG_SIZE];
03053 snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
03054 warning->set_msg(&getSession(), warn_buff);
03055 warning= 0;
03056 }
03057
03058
03059
03060
03061
03062 if (!original)
03063 {
03064 delete tmp_table_param;
03065 tmp_table_param= 0;
03066 if (table)
03067 {
03068 Session *session= table->in_use;
03069 table= 0;
03070 if (tree)
03071 {
03072 delete_tree(tree);
03073 tree= 0;
03074 }
03075 if (unique_filter)
03076 {
03077 delete unique_filter;
03078 unique_filter= NULL;
03079 }
03080 if (warning)
03081 {
03082 char warn_buff[DRIZZLE_ERRMSG_SIZE];
03083 snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
03084 warning->set_msg(session, warn_buff);
03085 warning= 0;
03086 }
03087 }
03088 assert(tree == 0 && warning == 0);
03089 }
03090 return;
03091 }
03092
03093
03094 Item *Item_func_group_concat::copy_or_same(Session* session)
03095 {
03096 return new (session->mem_root) Item_func_group_concat(session, this);
03097 }
03098
03099
03100 void Item_func_group_concat::clear()
03101 {
03102 result.length(0);
03103 result.copy();
03104 null_value= true;
03105 warning_for_row= false;
03106 no_appended= true;
03107 if (tree)
03108 reset_tree(tree);
03109 if (distinct)
03110 unique_filter->reset();
03111
03112 }
03113
03114
03115 bool Item_func_group_concat::add()
03116 {
03117 if (always_null)
03118 return 0;
03119 copy_fields(tmp_table_param);
03120 if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
03121 return true;
03122
03123 for (uint32_t i= 0; i < arg_count_field; i++)
03124 {
03125 Item *show_item= args[i];
03126 if (!show_item->const_item())
03127 {
03128 Field *f= show_item->get_tmp_table_field();
03129 if (f->is_null_in_record((const unsigned char*) table->record[0]))
03130 return 0;
03131 }
03132 }
03133
03134 null_value= false;
03135 bool row_eligible= true;
03136
03137 if (distinct)
03138 {
03139
03140 uint32_t count= unique_filter->elements_in_tree();
03141 unique_filter->unique_add(table->record[0] + table->getShare()->null_bytes);
03142 if (count == unique_filter->elements_in_tree())
03143 row_eligible= false;
03144 }
03145
03146 TREE_ELEMENT *el= 0;
03147 if (row_eligible && tree)
03148 el= tree_insert(tree, table->record[0] + table->getShare()->null_bytes, 0,
03149 tree->custom_arg);
03150
03151
03152
03153
03154
03155 if (row_eligible && !warning_for_row &&
03156 (!tree || (el->count == 1 && distinct && !arg_count_order)))
03157 dump_leaf_key(table->record[0] + table->getShare()->null_bytes, 1, this);
03158
03159 return 0;
03160 }
03161
03162
03163 bool
03164 Item_func_group_concat::fix_fields(Session *session, Item **ref)
03165 {
03166 uint32_t i;
03167 assert(fixed == 0);
03168
03169 if (init_sum_func_check(session))
03170 return true;
03171
03172 maybe_null= 1;
03173
03174
03175
03176
03177
03178 for (i=0 ; i < arg_count ; i++)
03179 {
03180 if ((!args[i]->fixed &&
03181 args[i]->fix_fields(session, args + i)) ||
03182 args[i]->check_cols(1))
03183 return true;
03184 }
03185
03186 if (agg_item_charsets(collation, func_name(),
03187 args,
03188
03189 arg_count - arg_count_order,
03190 MY_COLL_ALLOW_CONV, 1))
03191 return 1;
03192
03193 result.set_charset(collation.collation);
03194 result_field= 0;
03195 null_value= 1;
03196 max_length= (size_t)session->variables.group_concat_max_len;
03197
03198 if (check_sum_func(session, ref))
03199 return true;
03200
03201 fixed= 1;
03202 return false;
03203 }
03204
03205
03206 bool Item_func_group_concat::setup(Session *session)
03207 {
03208 List<Item> list;
03209 Select_Lex *select_lex= session->lex().current_select;
03210
03211
03212
03213
03214
03215 if (table || tree)
03216 return(false);
03217
03218 if (!(tmp_table_param= new Tmp_Table_Param))
03219 return(true);
03220
03221
03222 tmp_table_param->convert_blob_length= max_length *
03223 collation.collation->mbmaxlen;
03224
03225 always_null= 0;
03226 for (uint32_t i= 0; i < arg_count_field; i++)
03227 {
03228 Item *item= args[i];
03229 if (list.push_back(item))
03230 return(true);
03231 if (item->const_item())
03232 {
03233 if (item->is_null())
03234 {
03235 always_null= 1;
03236 return(false);
03237 }
03238 }
03239 }
03240
03241 List<Item> all_fields(list);
03242
03243
03244
03245
03246
03247
03248 if (arg_count_order &&
03249 setup_order(session, args, context->table_list, list, all_fields, *order))
03250 return(true);
03251
03252 count_field_types(select_lex, tmp_table_param, all_fields, 0);
03253 tmp_table_param->force_copy_fields= force_copy_fields;
03254 assert(table == 0);
03255 if (arg_count_order > 0 || distinct)
03256 {
03257
03258
03259
03260
03261
03262
03263 set_if_smaller(tmp_table_param->convert_blob_length,
03264 Field_varstring::MAX_SIZE);
03265 }
03266
03267
03268
03269
03270
03271
03272
03273
03274 if (!(table= create_tmp_table(session, tmp_table_param, all_fields,
03275 (Order*) 0, 0, true,
03276 (select_lex->options | session->options),
03277 HA_POS_ERROR, (char*) "")))
03278 {
03279 return(true);
03280 }
03281
03282 table->cursor->extra(HA_EXTRA_NO_ROWS);
03283 table->no_rows= 1;
03284
03285
03286
03287
03288
03289
03290 uint32_t tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
03291
03292 if (arg_count_order)
03293 {
03294 tree= &tree_base;
03295
03296
03297
03298
03299
03300 init_tree(tree, (uint32_t) min(session->variables.max_heap_table_size,
03301 (uint64_t)(session->variables.sortbuff_size/16)),
03302 0,
03303 tree_key_length,
03304 group_concat_key_cmp_with_order , false, NULL, (void*) this);
03305 }
03306
03307 if (distinct)
03308 unique_filter= new Unique(group_concat_key_cmp_with_distinct,
03309 (void*)this,
03310 tree_key_length,
03311 (size_t)session->variables.max_heap_table_size);
03312
03313 return(false);
03314 }
03315
03316
03317
03318
03319 void Item_func_group_concat::make_unique()
03320 {
03321 tmp_table_param= 0;
03322 table=0;
03323 original= 0;
03324 force_copy_fields= 1;
03325 tree= 0;
03326 }
03327
03328 double Item_func_group_concat::val_real()
03329 {
03330 String *res; res=val_str(&str_value);
03331 return res ? internal::my_atof(res->c_ptr()) : 0.0;
03332 }
03333
03334 int64_t Item_func_group_concat::val_int()
03335 {
03336 String *res;
03337 char *end_ptr;
03338 int error;
03339 if (!(res= val_str(&str_value)))
03340 return (int64_t) 0;
03341 end_ptr= (char*) res->ptr()+ res->length();
03342 return internal::my_strtoll10(res->ptr(), &end_ptr, &error);
03343 }
03344
03345 String* Item_func_group_concat::val_str(String* )
03346 {
03347 assert(fixed == 1);
03348 if (null_value)
03349 return 0;
03350 if (no_appended && tree)
03351
03352 tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
03353 left_root_right);
03354 if (count_cut_values && !warning)
03355 {
03356
03357
03358
03359
03360 assert(table);
03361 warning= push_warning(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
03362 ER_CUT_VALUE_GROUP_CONCAT,
03363 ER(ER_CUT_VALUE_GROUP_CONCAT));
03364 }
03365 return &result;
03366 }
03367
03368
03369 void Item_func_group_concat::print(String *str)
03370 {
03371 str->append(STRING_WITH_LEN("group_concat("));
03372 if (distinct)
03373 str->append(STRING_WITH_LEN("distinct "));
03374 for (uint32_t i= 0; i < arg_count_field; i++)
03375 {
03376 if (i)
03377 str->append(',');
03378 args[i]->print(str);
03379 }
03380 if (arg_count_order)
03381 {
03382 str->append(STRING_WITH_LEN(" order by "));
03383 for (uint32_t i= 0 ; i < arg_count_order ; i++)
03384 {
03385 if (i)
03386 str->append(',');
03387 (*order[i]->item)->print(str);
03388 if (order[i]->asc)
03389 str->append(STRING_WITH_LEN(" ASC"));
03390 else
03391 str->append(STRING_WITH_LEN(" DESC"));
03392 }
03393 }
03394 str->append(STRING_WITH_LEN(" separator \'"));
03395 str->append(*separator);
03396 str->append(STRING_WITH_LEN("\')"));
03397 }
03398
03399
03400 Item_func_group_concat::~Item_func_group_concat()
03401 {
03402 if (!original && unique_filter)
03403 delete unique_filter;
03404 }
03405
03406 }