#include <item_sum.h>
Inheritance diagram for Item_sum_count_distinct:


Public Member Functions | |
| Item_sum_count_distinct (List< Item > &list) | |
| Item_sum_count_distinct (THD *thd, Item_sum_count_distinct *item) | |
| ~Item_sum_count_distinct () | |
| void | cleanup () |
| enum Sumfunctype | sum_func () const |
| void | clear () |
| bool | add () |
| longlong | val_int () |
| void | reset_field () |
| void | update_field () |
| const char * | func_name () const |
| bool | setup (THD *thd) |
| void | make_unique () |
| Item * | copy_or_same (THD *thd) |
| void | no_rows_in_result () |
Private Attributes | |
| TABLE * | table |
| uint32 * | field_lengths |
| TMP_TABLE_PARAM * | tmp_table_param |
| bool | force_copy_fields |
| Unique * | tree |
| Item_sum_count_distinct * | original |
| uint | tree_key_length |
| bool | always_null |
Friends | |
| int | composite_key_cmp (void *arg, byte *key1, byte *key2) |
| int | simple_str_key_cmp (void *arg, byte *key1, byte *key2) |
Definition at line 499 of file item_sum.h.
Definition at line 526 of file item_sum.h.
References Item_sum::quick_group.
Referenced by copy_or_same().
00527 :Item_sum_int(list), table(0), field_lengths(0), tmp_table_param(0), 00528 force_copy_fields(0), tree(0), original(0), always_null(FALSE) 00529 { quick_group= 0; }
Here is the caller graph for this function:

| Item_sum_count_distinct::Item_sum_count_distinct | ( | THD * | thd, | |
| Item_sum_count_distinct * | item | |||
| ) | [inline] |
Definition at line 530 of file item_sum.h.
00531 :Item_sum_int(thd, item), table(item->table), 00532 field_lengths(item->field_lengths), 00533 tmp_table_param(item->tmp_table_param), 00534 force_copy_fields(0), tree(item->tree), original(item), 00535 tree_key_length(item->tree_key_length), 00536 always_null(item->always_null) 00537 {}
| Item_sum_count_distinct::~Item_sum_count_distinct | ( | ) |
Definition at line 2503 of file item_sum.cc.
References cleanup().
02504 { 02505 cleanup(); 02506 }
Here is the call graph for this function:

| bool Item_sum_count_distinct::add | ( | ) | [virtual] |
Implements Item_sum.
Definition at line 2643 of file item_sum.cc.
References always_null, copy_fields(), copy_funcs(), error, FALSE, st_table::field, st_table::file, HA_CHECK_DUP, handler::ha_write_row(), handler::is_fatal_error(), st_table_share::null_bytes, st_table::record, st_table::s, table, tmp_table_param, tree, and TRUE.
02644 { 02645 int error; 02646 if (always_null) 02647 return 0; 02648 copy_fields(tmp_table_param); 02649 copy_funcs(tmp_table_param->items_to_copy); 02650 02651 for (Field **field=table->field ; *field ; field++) 02652 if ((*field)->is_real_null(0)) 02653 return 0; // Don't count NULL 02654 02655 if (tree) 02656 { 02657 /* 02658 The first few bytes of record (at least one) are just markers 02659 for deleted and NULLs. We want to skip them since they will 02660 bloat the tree without providing any valuable info. Besides, 02661 key_length used to initialize the tree didn't include space for them. 02662 */ 02663 return tree->unique_add(table->record[0] + table->s->null_bytes); 02664 } 02665 if ((error= table->file->ha_write_row(table->record[0])) && 02666 table->file->is_fatal_error(error, HA_CHECK_DUP)) 02667 return TRUE; 02668 return FALSE; 02669 }
Here is the call graph for this function:

| C_MODE_END void Item_sum_count_distinct::cleanup | ( | ) | [virtual] |
Reimplemented from Item_result_field.
Definition at line 2462 of file item_sum.cc.
References always_null, Item_result_field::cleanup(), DBUG_ENTER, DBUG_VOID_RETURN, FALSE, free_tmp_table(), st_table::in_use, original, table, tmp_table_param, and tree.
Referenced by ~Item_sum_count_distinct().
02463 { 02464 DBUG_ENTER("Item_sum_count_distinct::cleanup"); 02465 Item_sum_int::cleanup(); 02466 02467 /* Free objects only if we own them. */ 02468 if (!original) 02469 { 02470 /* 02471 We need to delete the table and the tree in cleanup() as 02472 they were allocated in the runtime memroot. Using the runtime 02473 memroot reduces memory footprint for PS/SP and simplifies setup(). 02474 */ 02475 delete tree; 02476 tree= 0; 02477 if (table) 02478 { 02479 free_tmp_table(table->in_use, table); 02480 table= 0; 02481 } 02482 delete tmp_table_param; 02483 tmp_table_param= 0; 02484 } 02485 always_null= FALSE; 02486 DBUG_VOID_RETURN; 02487 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void Item_sum_count_distinct::clear | ( | ) | [virtual] |
Implements Item_sum.
Definition at line 2630 of file item_sum.cc.
References handler::delete_all_rows(), handler::extra(), st_table::file, HA_EXTRA_NO_CACHE, HA_EXTRA_WRITE_CACHE, table, and tree.
02631 { 02632 /* tree and table can be both null only if always_null */ 02633 if (tree) 02634 tree->reset(); 02635 else if (table) 02636 { 02637 table->file->extra(HA_EXTRA_NO_CACHE); 02638 table->file->delete_all_rows(); 02639 table->file->extra(HA_EXTRA_WRITE_CACHE); 02640 } 02641 }
Here is the call graph for this function:

| Item * Item_sum_count_distinct::copy_or_same | ( | THD * | thd | ) | [virtual] |
Reimplemented from Item.
Definition at line 2624 of file item_sum.cc.
References Item_sum_count_distinct().
02625 { 02626 return new (thd->mem_root) Item_sum_count_distinct(thd, this); 02627 }
Here is the call graph for this function:

| const char* Item_sum_count_distinct::func_name | ( | ) | const [inline, virtual] |
| void Item_sum_count_distinct::make_unique | ( | ) | [virtual] |
Reimplemented from Item_sum.
Definition at line 2492 of file item_sum.cc.
References always_null, FALSE, force_copy_fields, original, table, tmp_table_param, and tree.
02493 { 02494 table=0; 02495 original= 0; 02496 force_copy_fields= 1; 02497 tree= 0; 02498 tmp_table_param= 0; 02499 always_null= FALSE; 02500 }
| void Item_sum_count_distinct::no_rows_in_result | ( | ) | [inline, virtual] |
| void Item_sum_count_distinct::reset_field | ( | ) | [inline, virtual] |
| bool Item_sum_count_distinct::setup | ( | THD * | thd | ) | [virtual] |
Reimplemented from Item_sum.
Definition at line 2509 of file item_sum.cc.
References always_null, Item_sum::arg_count, Item_sum::args, composite_key_cmp, count_field_types(), create_tmp_table(), st_table_share::db_type, DBUG_ASSERT, handler::extra(), f, FALSE, st_table::field, field_lengths, st_table_share::fields, st_table::file, force_copy_fields, HA_EXTRA_NO_ROWS, HA_POS_ERROR, heap_hton, list(), MYSQL_TYPE_STRING, MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VARCHAR, st_table::no_rows, st_table::s, simple_raw_key_cmp(), simple_str_key_cmp, table, tmp_table_param, tree, tree_key_length, TRUE, and Item_sum::type().
02510 { 02511 List<Item> list; 02512 SELECT_LEX *select_lex= thd->lex->current_select; 02513 02514 /* 02515 Setup can be called twice for ROLLUP items. This is a bug. 02516 Please add DBUG_ASSERT(tree == 0) here when it's fixed. 02517 */ 02518 if (tree || table || tmp_table_param) 02519 return FALSE; 02520 02521 if (!(tmp_table_param= new TMP_TABLE_PARAM)) 02522 return TRUE; 02523 02524 /* Create a table with an unique key over all parameters */ 02525 for (uint i=0; i < arg_count ; i++) 02526 { 02527 Item *item=args[i]; 02528 if (list.push_back(item)) 02529 return TRUE; // End of memory 02530 if (item->const_item()) 02531 { 02532 (void) item->val_int(); 02533 if (item->null_value) 02534 always_null=1; 02535 } 02536 } 02537 if (always_null) 02538 return FALSE; 02539 count_field_types(tmp_table_param,list,0); 02540 tmp_table_param->force_copy_fields= force_copy_fields; 02541 DBUG_ASSERT(table == 0); 02542 if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1, 02543 0, 02544 (select_lex->options | thd->options), 02545 HA_POS_ERROR, (char*)""))) 02546 return TRUE; 02547 table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows 02548 table->no_rows=1; 02549 02550 if (table->s->db_type == &heap_hton) 02551 { 02552 /* 02553 No blobs, otherwise it would have been MyISAM: set up a compare 02554 function and its arguments to use with Unique. 02555 */ 02556 qsort_cmp2 compare_key; 02557 void* cmp_arg; 02558 Field **field= table->field; 02559 Field **field_end= field + table->s->fields; 02560 bool all_binary= TRUE; 02561 02562 for (tree_key_length= 0; field < field_end; ++field) 02563 { 02564 Field *f= *field; 02565 enum enum_field_types type= f->type(); 02566 tree_key_length+= f->pack_length(); 02567 if ((type == MYSQL_TYPE_VARCHAR) || 02568 !f->binary() && (type == MYSQL_TYPE_STRING || 02569 type == MYSQL_TYPE_VAR_STRING)) 02570 { 02571 all_binary= FALSE; 02572 break; 02573 } 02574 } 02575 if (all_binary) 02576 { 02577 cmp_arg= (void*) &tree_key_length; 02578 compare_key= (qsort_cmp2) simple_raw_key_cmp; 02579 } 02580 else 02581 { 02582 if (table->s->fields == 1) 02583 { 02584 /* 02585 If we have only one field, which is the most common use of 02586 count(distinct), it is much faster to use a simpler key 02587 compare method that can take advantage of not having to worry 02588 about other fields. 02589 */ 02590 compare_key= (qsort_cmp2) simple_str_key_cmp; 02591 cmp_arg= (void*) table->field[0]; 02592 /* tree_key_length has been set already */ 02593 } 02594 else 02595 { 02596 uint32 *length; 02597 compare_key= (qsort_cmp2) composite_key_cmp; 02598 cmp_arg= (void*) this; 02599 field_lengths= (uint32*) thd->alloc(table->s->fields * sizeof(uint32)); 02600 for (tree_key_length= 0, length= field_lengths, field= table->field; 02601 field < field_end; ++field, ++length) 02602 { 02603 *length= (*field)->pack_length(); 02604 tree_key_length+= *length; 02605 } 02606 } 02607 } 02608 DBUG_ASSERT(tree == 0); 02609 tree= new Unique(compare_key, cmp_arg, tree_key_length, 02610 thd->variables.max_heap_table_size); 02611 /* 02612 The only time tree_key_length could be 0 is if someone does 02613 count(distinct) on a char(0) field - stupid thing to do, 02614 but this has to be handled - otherwise someone can crash 02615 the server with a DoS attack 02616 */ 02617 if (! tree) 02618 return TRUE; 02619 } 02620 return FALSE; 02621 }
Here is the call graph for this function:

| enum Sumfunctype Item_sum_count_distinct::sum_func | ( | ) | const [inline, virtual] |
Implements Item_sum.
Definition at line 542 of file item_sum.h.
References Item_sum::COUNT_DISTINCT_FUNC.
00542 { return COUNT_DISTINCT_FUNC; }
| void Item_sum_count_distinct::update_field | ( | ) | [inline, virtual] |
| longlong Item_sum_count_distinct::val_int | ( | ) | [virtual] |
Reimplemented from Item_sum_num.
Definition at line 2672 of file item_sum.cc.
References count, count_distinct_walk(), DBUG_ASSERT, st_table::file, Item::fixed, HA_STATUS_NO_LOCK, HA_STATUS_VARIABLE, handler::info(), LL, ha_statistics::records, handler::stats, table, and tree.
02673 { 02674 DBUG_ASSERT(fixed == 1); 02675 if (!table) // Empty query 02676 return LL(0); 02677 if (tree) 02678 { 02679 ulonglong count; 02680 02681 if (tree->elements == 0) 02682 return (longlong) tree->elements_in_tree(); // everything fits in memory 02683 count= 0; 02684 tree->walk(count_distinct_walk, (void*) &count); 02685 return (longlong) count; 02686 } 02687 table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); 02688 return table->file->stats.records; 02689 }
Here is the call graph for this function:

Definition at line 2431 of file item_sum.cc.
Referenced by setup().
02432 { 02433 Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg; 02434 Field **field = item->table->field; 02435 Field **field_end= field + item->table->s->fields; 02436 uint32 *lengths=item->field_lengths; 02437 for (; field < field_end; ++field) 02438 { 02439 Field* f = *field; 02440 int len = *lengths++; 02441 int res = f->cmp((char *) key1, (char *) key2); 02442 if (res) 02443 return res; 02444 key1 += len; 02445 key2 += len; 02446 } 02447 return 0; 02448 }
bool Item_sum_count_distinct::always_null [private] |
Definition at line 519 of file item_sum.h.
Referenced by add(), cleanup(), make_unique(), and setup().
uint32* Item_sum_count_distinct::field_lengths [private] |
TABLE* Item_sum_count_distinct::table [private] |
Definition at line 501 of file item_sum.h.
Referenced by add(), cleanup(), clear(), composite_key_cmp(), make_unique(), setup(), and val_int().
TMP_TABLE_PARAM* Item_sum_count_distinct::tmp_table_param [private] |
Definition at line 503 of file item_sum.h.
Referenced by add(), cleanup(), make_unique(), and setup().
Unique* Item_sum_count_distinct::tree [private] |
Definition at line 510 of file item_sum.h.
Referenced by add(), cleanup(), clear(), make_unique(), setup(), and val_int().
uint Item_sum_count_distinct::tree_key_length [private] |
1.4.7

