1 #ifndef ITEM_SUM_INCLUDED 2 #define ITEM_SUM_INCLUDED 3 /* Copyright (c) 2000, 2013 Oracle and/or its affiliates. 4 Copyright (c) 2008, 2013 Monty Program Ab. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; version 2 of the License. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ 18 19 20 /* classes for sum functions */ 21 22 #ifdef USE_PRAGMA_INTERFACE 23 #pragma interface /* gcc class implementation */ 24 #endif 25 26 #include <my_tree.h> 27 #include "sql_udf.h" /* udf_handler */ 28 29 class Item_sum; 30 class Aggregator_distinct; 31 class Aggregator_simple; 32 33 /** 34 The abstract base class for the Aggregator_* classes. 35 It implements the data collection functions (setup/add/clear) 36 as either pass-through to the real functionality or 37 as collectors into an Unique (for distinct) structure. 38 39 Note that update_field/reset_field are not in that 40 class, because they're simply not called when 41 GROUP BY/DISTINCT can be handled with help of index on grouped 42 fields (quick_group = 0); 43 */ 44 45 class Aggregator : public Sql_alloc 46 { 47 friend class Item_sum; 48 friend class Item_sum_sum; 49 friend class Item_sum_count; 50 friend class Item_sum_avg; 51 52 /* 53 All members are protected as this class is not usable outside of an 54 Item_sum descendant. 55 */ 56 protected: 57 /* the aggregate function class to act on */ 58 Item_sum *item_sum; 59 60 public: Aggregator(Item_sum * arg)61 Aggregator (Item_sum *arg): item_sum(arg) {} ~Aggregator()62 virtual ~Aggregator () {} /* Keep gcc happy */ 63 64 enum Aggregator_type { SIMPLE_AGGREGATOR, DISTINCT_AGGREGATOR }; 65 virtual Aggregator_type Aggrtype() = 0; 66 67 /** 68 Called before adding the first row. 69 Allocates and sets up the internal aggregation structures used, 70 e.g. the Unique instance used to calculate distinct. 71 */ 72 virtual bool setup(THD *) = 0; 73 74 /** 75 Called when we need to wipe out all the data from the aggregator : 76 all the values acumulated and all the state. 77 Cleans up the internal structures and resets them to their initial state. 78 */ 79 virtual void clear() = 0; 80 81 /** 82 Called when there's a new value to be aggregated. 83 Updates the internal state of the aggregator to reflect the new value. 84 */ 85 virtual bool add() = 0; 86 87 /** 88 Called when there are no more data and the final value is to be retrieved. 89 Finalises the state of the aggregator, so the final result can be retrieved. 90 */ 91 virtual void endup() = 0; 92 93 /** Decimal value of being-aggregated argument */ 94 virtual my_decimal *arg_val_decimal(my_decimal * value) = 0; 95 /** Floating point value of being-aggregated argument */ 96 virtual double arg_val_real() = 0; 97 /** 98 NULLness of being-aggregated argument. 99 100 @param use_null_value Optimization: to determine if the argument is NULL 101 we must, in the general case, call is_null() on it, which itself might 102 call val_*() on it, which might be costly. If you just have called 103 arg_val*(), you can pass use_null_value=true; this way, arg_is_null() 104 might avoid is_null() and instead do a cheap read of the Item's null_value 105 (updated by arg_val*()). 106 */ 107 virtual bool arg_is_null(bool use_null_value) = 0; 108 }; 109 110 111 class st_select_lex; 112 class Window_spec; 113 114 /** 115 Class Item_sum is the base class used for special expressions that SQL calls 116 'set functions'. These expressions are formed with the help of aggregate 117 functions such as SUM, MAX, GROUP_CONCAT etc. 118 119 GENERAL NOTES 120 121 A set function cannot be used in certain positions where expressions are 122 accepted. There are some quite explicable restrictions for the usage of 123 set functions. 124 125 In the query: 126 SELECT AVG(b) FROM t1 WHERE SUM(b) > 20 GROUP by a 127 the usage of the set function AVG(b) is legal, while the usage of SUM(b) 128 is illegal. A WHERE condition must contain expressions that can be 129 evaluated for each row of the table. Yet the expression SUM(b) can be 130 evaluated only for each group of rows with the same value of column a. 131 In the query: 132 SELECT AVG(b) FROM t1 WHERE c > 30 GROUP BY a HAVING SUM(b) > 20 133 both set function expressions AVG(b) and SUM(b) are legal. 134 135 We can say that in a query without nested selects an occurrence of a 136 set function in an expression of the SELECT list or/and in the HAVING 137 clause is legal, while in the WHERE clause it's illegal. 138 139 The general rule to detect whether a set function is legal in a query with 140 nested subqueries is much more complicated. 141 142 Consider the the following query: 143 SELECT t1.a FROM t1 GROUP BY t1.a 144 HAVING t1.a > ALL (SELECT t2.c FROM t2 WHERE SUM(t1.b) < t2.c). 145 The set function SUM(b) is used here in the WHERE clause of the subquery. 146 Nevertheless it is legal since it is under the HAVING clause of the query 147 to which this function relates. The expression SUM(t1.b) is evaluated 148 for each group defined in the main query, not for groups of the subquery. 149 150 The problem of finding the query where to aggregate a particular 151 set function is not so simple as it seems to be. 152 153 In the query: 154 SELECT t1.a FROM t1 GROUP BY t1.a 155 HAVING t1.a > ALL(SELECT t2.c FROM t2 GROUP BY t2.c 156 HAVING SUM(t1.a) < t2.c) 157 the set function can be evaluated for both outer and inner selects. 158 If we evaluate SUM(t1.a) for the outer query then we get the value of t1.a 159 multiplied by the cardinality of a group in table t1. In this case 160 in each correlated subquery SUM(t1.a) is used as a constant. But we also 161 can evaluate SUM(t1.a) for the inner query. In this case t1.a will be a 162 constant for each correlated subquery and summation is performed 163 for each group of table t2. 164 (Here it makes sense to remind that the query 165 SELECT c FROM t GROUP BY a HAVING SUM(1) < a 166 is quite legal in our SQL). 167 168 So depending on what query we assign the set function to we 169 can get different result sets. 170 171 The general rule to detect the query where a set function is to be 172 evaluated can be formulated as follows. 173 Consider a set function S(E) where E is an expression with occurrences 174 of column references C1, ..., CN. Resolve these column references against 175 subqueries that contain the set function S(E). Let Q be the innermost 176 subquery of those subqueries. (It should be noted here that S(E) 177 in no way can be evaluated in the subquery embedding the subquery Q, 178 otherwise S(E) would refer to at least one unbound column reference) 179 If S(E) is used in a construct of Q where set functions are allowed then 180 we evaluate S(E) in Q. 181 Otherwise we look for a innermost subquery containing S(E) of those where 182 usage of S(E) is allowed. 183 184 Let's demonstrate how this rule is applied to the following queries. 185 186 1. SELECT t1.a FROM t1 GROUP BY t1.a 187 HAVING t1.a > ALL(SELECT t2.b FROM t2 GROUP BY t2.b 188 HAVING t2.b > ALL(SELECT t3.c FROM t3 GROUP BY t3.c 189 HAVING SUM(t1.a+t2.b) < t3.c)) 190 For this query the set function SUM(t1.a+t2.b) depends on t1.a and t2.b 191 with t1.a defined in the outermost query, and t2.b defined for its 192 subquery. The set function is in the HAVING clause of the subquery and can 193 be evaluated in this subquery. 194 195 2. SELECT t1.a FROM t1 GROUP BY t1.a 196 HAVING t1.a > ALL(SELECT t2.b FROM t2 197 WHERE t2.b > ALL (SELECT t3.c FROM t3 GROUP BY t3.c 198 HAVING SUM(t1.a+t2.b) < t3.c)) 199 Here the set function SUM(t1.a+t2.b)is in the WHERE clause of the second 200 subquery - the most upper subquery where t1.a and t2.b are defined. 201 If we evaluate the function in this subquery we violate the context rules. 202 So we evaluate the function in the third subquery (over table t3) where it 203 is used under the HAVING clause. 204 205 3. SELECT t1.a FROM t1 GROUP BY t1.a 206 HAVING t1.a > ALL(SELECT t2.b FROM t2 207 WHERE t2.b > ALL (SELECT t3.c FROM t3 208 WHERE SUM(t1.a+t2.b) < t3.c)) 209 In this query evaluation of SUM(t1.a+t2.b) is not legal neither in the second 210 nor in the third subqueries. So this query is invalid. 211 212 Mostly set functions cannot be nested. In the query 213 SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20 214 the expression SUM(b) is not acceptable, though it is under a HAVING clause. 215 Yet it is acceptable in the query: 216 SELECT t.1 FROM t1 GROUP BY t1.a HAVING SUM(t1.b) > 20. 217 218 An argument of a set function does not have to be a reference to a table 219 column as we saw it in examples above. This can be a more complex expression 220 SELECT t1.a FROM t1 GROUP BY t1.a HAVING SUM(t1.b+1) > 20. 221 The expression SUM(t1.b+1) has a very clear semantics in this context: 222 we sum up the values of t1.b+1 where t1.b varies for all values within a 223 group of rows that contain the same t1.a value. 224 225 A set function for an outer query yields a constant within a subquery. So 226 the semantics of the query 227 SELECT t1.a FROM t1 GROUP BY t1.a 228 HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c 229 HAVING AVG(t2.c+SUM(t1.b)) > 20) 230 is still clear. For a group of the rows with the same t1.a values we 231 calculate the value of SUM(t1.b). This value 's' is substituted in the 232 the subquery: 233 SELECT t2.c FROM t2 GROUP BY t2.c HAVING AVG(t2.c+s) 234 than returns some result set. 235 236 By the same reason the following query with a subquery 237 SELECT t1.a FROM t1 GROUP BY t1.a 238 HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c 239 HAVING AVG(SUM(t1.b)) > 20) 240 is also acceptable. 241 242 IMPLEMENTATION NOTES 243 244 Three methods were added to the class to check the constraints specified 245 in the previous section. These methods utilize several new members. 246 247 The field 'nest_level' contains the number of the level for the subquery 248 containing the set function. The main SELECT is of level 0, its subqueries 249 are of levels 1, the subqueries of the latter are of level 2 and so on. 250 251 The field 'aggr_level' is to contain the nest level of the subquery 252 where the set function is aggregated. 253 254 The field 'max_arg_level' is for the maximum of the nest levels of the 255 unbound column references occurred in the set function. A column reference 256 is unbound within a set function if it is not bound by any subquery 257 used as a subexpression in this function. A column reference is bound by 258 a subquery if it is a reference to the column by which the aggregation 259 of some set function that is used in the subquery is calculated. 260 For the set function used in the query 261 SELECT t1.a FROM t1 GROUP BY t1.a 262 HAVING t1.a > ALL(SELECT t2.b FROM t2 GROUP BY t2.b 263 HAVING t2.b > ALL(SELECT t3.c FROM t3 GROUP BY t3.c 264 HAVING SUM(t1.a+t2.b) < t3.c)) 265 the value of max_arg_level is equal to 1 since t1.a is bound in the main 266 query, and t2.b is bound by the first subquery whose nest level is 1. 267 Obviously a set function cannot be aggregated in the subquery whose 268 nest level is less than max_arg_level. (Yet it can be aggregated in the 269 subqueries whose nest level is greater than max_arg_level.) 270 In the query 271 SELECT t.a FROM t1 HAVING AVG(t1.a+(SELECT MIN(t2.c) FROM t2)) 272 the value of the max_arg_level for the AVG set function is 0 since 273 the reference t2.c is bound in the subquery. 274 275 The field 'max_sum_func_level' is to contain the maximum of the 276 nest levels of the set functions that are used as subexpressions of 277 the arguments of the given set function, but not aggregated in any 278 subquery within this set function. A nested set function s1 can be 279 used within set function s0 only if s1.max_sum_func_level < 280 s0.max_sum_func_level. Set function s1 is considered as nested 281 for set function s0 if s1 is not calculated in any subquery 282 within s0. 283 284 A set function that is used as a subexpression in an argument of another 285 set function refers to the latter via the field 'in_sum_func'. 286 287 The condition imposed on the usage of set functions are checked when 288 we traverse query subexpressions with the help of the recursive method 289 fix_fields. When we apply this method to an object of the class 290 Item_sum, first, on the descent, we call the method init_sum_func_check 291 that initialize members used at checking. Then, on the ascent, we 292 call the method check_sum_func that validates the set function usage 293 and reports an error if it is illegal. 294 The method register_sum_func serves to link the items for the set functions 295 that are aggregated in the embedding (sub)queries. Circular chains of such 296 functions are attached to the corresponding st_select_lex structures 297 through the field inner_sum_func_list. 298 299 Exploiting the fact that the members mentioned above are used in one 300 recursive function we could have allocated them on the thread stack. 301 Yet we don't do it now. 302 303 We assume that the nesting level of subquries does not exceed 127. 304 TODO: to catch queries where the limit is exceeded to make the 305 code clean here. 306 307 @note 308 The implementation takes into account the used strategy: 309 - Items resolved at optimization phase return 0 from Item_sum::used_tables(). 310 - Items that depend on the number of join output records, but not columns of 311 any particular table (like COUNT(*)), returm 0 from Item_sum::used_tables(), 312 but still return false from Item_sum::const_item(). 313 */ 314 315 class Item_sum :public Item_func_or_sum 316 { 317 friend class Aggregator_distinct; 318 friend class Aggregator_simple; 319 320 protected: 321 /** 322 Aggregator class instance. Not set initially. Allocated only after 323 it is determined if the incoming data are already distinct. 324 */ 325 Aggregator *aggr; 326 327 private: 328 /** 329 Used in making ROLLUP. Set for the ROLLUP copies of the original 330 Item_sum and passed to create_tmp_field() to cause it to work 331 over the temp table buffer that is referenced by 332 Item_result_field::result_field. 333 */ 334 bool force_copy_fields; 335 336 /** 337 Indicates how the aggregate function was specified by the parser : 338 1 if it was written as AGGREGATE(DISTINCT), 339 0 if it was AGGREGATE() 340 */ 341 bool with_distinct; 342 343 /* TRUE if this is aggregate function of a window function */ 344 bool window_func_sum_expr_flag; 345 346 public: 347 has_force_copy_fields()348 bool has_force_copy_fields() const { return force_copy_fields; } has_with_distinct()349 bool has_with_distinct() const { return with_distinct; } 350 351 enum Sumfunctype 352 { COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC, 353 AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC, 354 VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC, 355 ROW_NUMBER_FUNC, RANK_FUNC, DENSE_RANK_FUNC, PERCENT_RANK_FUNC, 356 CUME_DIST_FUNC, NTILE_FUNC, FIRST_VALUE_FUNC, LAST_VALUE_FUNC, 357 NTH_VALUE_FUNC, LEAD_FUNC, LAG_FUNC, PERCENTILE_CONT_FUNC, 358 PERCENTILE_DISC_FUNC, SP_AGGREGATE_FUNC 359 }; 360 361 Item **ref_by; /* pointer to a ref to the object used to register it */ 362 Item_sum *next; /* next in the circular chain of registered objects */ 363 Item_sum *in_sum_func; /* embedding set function if any */ 364 st_select_lex * aggr_sel; /* select where the function is aggregated */ 365 int8 nest_level; /* number of the nesting level of the set function */ 366 int8 aggr_level; /* nesting level of the aggregating subquery */ 367 int8 max_arg_level; /* max level of unbound column references */ 368 int8 max_sum_func_level;/* max level of aggregation for embedded functions */ 369 bool quick_group; /* If incremental update of fields */ 370 /* 371 This list is used by the check for mixing non aggregated fields and 372 sum functions in the ONLY_FULL_GROUP_BY_MODE. We save all outer fields 373 directly or indirectly used under this function it as it's unclear 374 at the moment of fixing outer field whether it's aggregated or not. 375 */ 376 List<Item_field> outer_fields; 377 378 protected: 379 /* 380 Copy of the arguments list to hold the original set of arguments. 381 Used in EXPLAIN EXTENDED instead of the current argument list because 382 the current argument list can be altered by usage of temporary tables. 383 */ 384 Item **orig_args, *tmp_orig_args[2]; 385 386 static size_t ram_limitation(THD *thd); 387 388 public: 389 390 void mark_as_sum_func(); Item_sum(THD * thd)391 Item_sum(THD *thd): Item_func_or_sum(thd), quick_group(1) 392 { 393 mark_as_sum_func(); 394 init_aggregator(); 395 } Item_sum(THD * thd,Item * a)396 Item_sum(THD *thd, Item *a): Item_func_or_sum(thd, a), quick_group(1), 397 orig_args(tmp_orig_args) 398 { 399 mark_as_sum_func(); 400 init_aggregator(); 401 } Item_sum(THD * thd,Item * a,Item * b)402 Item_sum(THD *thd, Item *a, Item *b): Item_func_or_sum(thd, a, b), 403 quick_group(1), orig_args(tmp_orig_args) 404 { 405 mark_as_sum_func(); 406 init_aggregator(); 407 } 408 Item_sum(THD *thd, List<Item> &list); 409 //Copy constructor, need to perform subselects with temporary tables 410 Item_sum(THD *thd, Item_sum *item); type()411 enum Type type() const { return SUM_FUNC_ITEM; } 412 virtual enum Sumfunctype sum_func () const=0; is_aggr_sum_func()413 bool is_aggr_sum_func() 414 { 415 switch (sum_func()) { 416 case COUNT_FUNC: 417 case COUNT_DISTINCT_FUNC: 418 case SUM_FUNC: 419 case SUM_DISTINCT_FUNC: 420 case AVG_FUNC: 421 case AVG_DISTINCT_FUNC: 422 case MIN_FUNC: 423 case MAX_FUNC: 424 case STD_FUNC: 425 case VARIANCE_FUNC: 426 case SUM_BIT_FUNC: 427 case UDF_SUM_FUNC: 428 case GROUP_CONCAT_FUNC: 429 return true; 430 default: 431 return false; 432 } 433 } 434 /** 435 Resets the aggregate value to its default and aggregates the current 436 value of its attribute(s). 437 */ reset_and_add()438 inline bool reset_and_add() 439 { 440 aggregator_clear(); 441 return aggregator_add(); 442 }; 443 444 /* 445 Called when new group is started and results are being saved in 446 a temporary table. Similarly to reset_and_add() it resets the 447 value to its default and aggregates the value of its 448 attribute(s), but must also store it in result_field. 449 This set of methods (result_item(), reset_field, update_field()) of 450 Item_sum is used only if quick_group is not null. Otherwise 451 copy_or_same() is used to obtain a copy of this item. 452 */ 453 virtual void reset_field()=0; 454 /* 455 Called for each new value in the group, when temporary table is in use. 456 Similar to add(), but uses temporary table field to obtain current value, 457 Updated value is then saved in the field. 458 */ 459 virtual void update_field()=0; fix_length_and_dec()460 virtual bool fix_length_and_dec() 461 { maybe_null=1; null_value=1; return FALSE; } 462 virtual Item *result_item(THD *thd, Field *field); 463 464 void update_used_tables (); build_equal_items(THD * thd,COND_EQUAL * inherited,bool link_item_fields,COND_EQUAL ** cond_equal_ref)465 COND *build_equal_items(THD *thd, COND_EQUAL *inherited, 466 bool link_item_fields, 467 COND_EQUAL **cond_equal_ref) 468 { 469 /* 470 Item_sum (and derivants) of the original WHERE/HAVING clauses 471 should already be replaced to Item_aggregate_ref by the time when 472 build_equal_items() is called. See Item::split_sum_func2(). 473 */ 474 DBUG_ASSERT(0); 475 return Item::build_equal_items(thd, inherited, link_item_fields, 476 cond_equal_ref); 477 } is_null()478 bool is_null() { return null_value; } 479 /** 480 make_const() 481 Called if we've managed to calculate the value of this Item in 482 opt_sum_query(), hence it can be considered constant at all subsequent 483 steps. 484 */ make_const()485 void make_const () 486 { 487 used_tables_cache= 0; 488 const_item_cache= true; 489 } reset_forced_const()490 void reset_forced_const() { const_item_cache= false; } const_during_execution()491 virtual bool const_during_execution() const { return false; } 492 virtual void print(String *str, enum_query_type query_type); 493 void fix_num_length_and_dec(); 494 495 /** 496 Mark an aggregate as having no rows. 497 498 This function is called by the execution engine to assign 'NO ROWS 499 FOUND' value to an aggregate item, when the underlying result set 500 has no rows. Such value, in a general case, may be different from 501 the default value of the item after 'clear()': e.g. a numeric item 502 may be initialized to 0 by clear() and to NULL by 503 no_rows_in_result(). 504 */ no_rows_in_result()505 virtual void no_rows_in_result() 506 { 507 set_aggregator(with_distinct ? 508 Aggregator::DISTINCT_AGGREGATOR : 509 Aggregator::SIMPLE_AGGREGATOR); 510 aggregator_clear(); 511 } make_unique()512 virtual void make_unique() { force_copy_fields= TRUE; } 513 Item *get_tmp_table_item(THD *thd); 514 Field *create_tmp_field(bool group, TABLE *table); 515 virtual bool collect_outer_ref_processor(void *param); 516 bool init_sum_func_check(THD *thd); 517 bool check_sum_func(THD *thd, Item **ref); 518 bool register_sum_func(THD *thd, Item **ref); depended_from()519 st_select_lex *depended_from() 520 { return (nest_level == aggr_level ? 0 : aggr_sel); } 521 get_arg(uint i)522 Item *get_arg(uint i) const { return args[i]; } 523 Item *set_arg(uint i, THD *thd, Item *new_val); get_arg_count()524 uint get_arg_count() const { return arg_count; } get_args()525 virtual Item **get_args() { return fixed ? orig_args : args; } 526 527 /* Initialization of distinct related members */ init_aggregator()528 void init_aggregator() 529 { 530 aggr= NULL; 531 with_distinct= FALSE; 532 force_copy_fields= FALSE; 533 } 534 535 /** 536 Called to initialize the aggregator. 537 */ 538 aggregator_setup(THD * thd)539 inline bool aggregator_setup(THD *thd) { return aggr->setup(thd); }; 540 541 /** 542 Called to cleanup the aggregator. 543 */ 544 aggregator_clear()545 inline void aggregator_clear() { aggr->clear(); } 546 547 /** 548 Called to add value to the aggregator. 549 */ 550 aggregator_add()551 inline bool aggregator_add() { return aggr->add(); }; 552 553 /* stores the declared DISTINCT flag (from the parser) */ set_distinct(bool distinct)554 void set_distinct(bool distinct) 555 { 556 with_distinct= distinct; 557 quick_group= with_distinct ? 0 : 1; 558 } 559 560 /* 561 Set the type of aggregation : DISTINCT or not. 562 563 May be called multiple times. 564 */ 565 566 int set_aggregator(Aggregator::Aggregator_type aggregator); 567 568 virtual void clear()= 0; 569 virtual bool add()= 0; setup(THD * thd)570 virtual bool setup(THD *thd) { return false; } 571 supports_removal()572 virtual bool supports_removal() const { return false; } remove()573 virtual void remove() { DBUG_ASSERT(0); } 574 575 virtual void cleanup(); 576 bool check_vcol_func_processor(void *arg); setup_window_func(THD * thd,Window_spec * window_spec)577 virtual void setup_window_func(THD *thd, Window_spec *window_spec) {} mark_as_window_func_sum_expr()578 void mark_as_window_func_sum_expr() { window_func_sum_expr_flag= true; } is_window_func_sum_expr()579 bool is_window_func_sum_expr() { return window_func_sum_expr_flag; } setup_caches(THD * thd)580 virtual void setup_caches(THD *thd) {}; set_partition_row_count(ulonglong count)581 virtual void set_partition_row_count(ulonglong count) { DBUG_ASSERT(0); } 582 }; 583 584 585 class Unique; 586 587 588 /** 589 The distinct aggregator. 590 Implements AGGFN (DISTINCT ..) 591 Collects all the data into an Unique (similarly to what Item_sum 592 does currently when with_distinct=true) and then (if applicable) iterates over 593 the list of unique values and pumps them back into its object 594 */ 595 596 class Aggregator_distinct : public Aggregator 597 { 598 friend class Item_sum_sum; 599 600 /* 601 flag to prevent consecutive runs of endup(). Normally in endup there are 602 expensive calculations (like walking the distinct tree for example) 603 which we must do only once if there are no data changes. 604 We can re-use the data for the second and subsequent val_xxx() calls. 605 endup_done set to TRUE also means that the calculated values for 606 the aggregate functions are correct and don't need recalculation. 607 */ 608 bool endup_done; 609 610 /* 611 Used depending on the type of the aggregate function and the presence of 612 blob columns in it: 613 - For COUNT(DISTINCT) and no blob fields this points to a real temporary 614 table. It's used as a hash table. 615 - For AVG/SUM(DISTINCT) or COUNT(DISTINCT) with blob fields only the 616 in-memory data structure of a temporary table is constructed. 617 It's used by the Field classes to transform data into row format. 618 */ 619 TABLE *table; 620 621 /* 622 An array of field lengths on row allocated and used only for 623 COUNT(DISTINCT) with multiple columns and no blobs. Used in 624 Aggregator_distinct::composite_key_cmp (called from Unique to compare 625 nodes 626 */ 627 uint32 *field_lengths; 628 629 /* 630 Used in conjunction with 'table' to support the access to Field classes 631 for COUNT(DISTINCT). Needed by copy_fields()/copy_funcs(). 632 */ 633 TMP_TABLE_PARAM *tmp_table_param; 634 635 /* 636 If there are no blobs in the COUNT(DISTINCT) arguments, we can use a tree, 637 which is faster than heap table. In that case, we still use the table 638 to help get things set up, but we insert nothing in it. 639 For AVG/SUM(DISTINCT) we always use this tree (as it takes a single 640 argument) to get the distinct rows. 641 */ 642 Unique *tree; 643 644 /* 645 The length of the temp table row. Must be a member of the class as it 646 gets passed down to simple_raw_key_cmp () as a compare function argument 647 to Unique. simple_raw_key_cmp () is used as a fast comparison function 648 when the entire row can be binary compared. 649 */ 650 uint tree_key_length; 651 652 /* 653 Set to true if the result is known to be always NULL. 654 If set deactivates creation and usage of the temporary table (in the 655 'table' member) and the Unique instance (in the 'tree' member) as well as 656 the calculation of the final value on the first call to 657 Item_[sum|avg|count]::val_xxx(). 658 */ 659 bool always_null; 660 661 /** 662 When feeding back the data in endup() from Unique/temp table back to 663 Item_sum::add() methods we must read the data from Unique (and not 664 recalculate the functions that are given as arguments to the aggregate 665 function. 666 This flag is to tell the arg_*() methods to take the data from the Unique 667 instead of calling the relevant val_..() method. 668 */ 669 bool use_distinct_values; 670 671 public: Aggregator_distinct(Item_sum * sum)672 Aggregator_distinct (Item_sum *sum) : 673 Aggregator(sum), table(NULL), tmp_table_param(NULL), tree(NULL), 674 always_null(false), use_distinct_values(false) {} 675 virtual ~Aggregator_distinct (); Aggrtype()676 Aggregator_type Aggrtype() { return DISTINCT_AGGREGATOR; } 677 678 bool setup(THD *); 679 void clear(); 680 bool add(); 681 void endup(); 682 virtual my_decimal *arg_val_decimal(my_decimal * value); 683 virtual double arg_val_real(); 684 virtual bool arg_is_null(bool use_null_value); 685 686 bool unique_walk_function(void *element); 687 bool unique_walk_function_for_count(void *element); 688 static int composite_key_cmp(void* arg, uchar* key1, uchar* key2); 689 }; 690 691 692 /** 693 The pass-through aggregator. 694 Implements AGGFN (DISTINCT ..) by knowing it gets distinct data on input. 695 So it just pumps them back to the Item_sum descendant class. 696 */ 697 class Aggregator_simple : public Aggregator 698 { 699 public: 700 Aggregator_simple(Item_sum * sum)701 Aggregator_simple (Item_sum *sum) : 702 Aggregator(sum) {} Aggrtype()703 Aggregator_type Aggrtype() { return Aggregator::SIMPLE_AGGREGATOR; } 704 setup(THD * thd)705 bool setup(THD * thd) { return item_sum->setup(thd); } clear()706 void clear() { item_sum->clear(); } add()707 bool add() { return item_sum->add(); } endup()708 void endup() {}; 709 virtual my_decimal *arg_val_decimal(my_decimal * value); 710 virtual double arg_val_real(); 711 virtual bool arg_is_null(bool use_null_value); 712 }; 713 714 715 class Item_sum_num :public Item_sum 716 { 717 public: Item_sum_num(THD * thd)718 Item_sum_num(THD *thd): Item_sum(thd) {} Item_sum_num(THD * thd,Item * item_par)719 Item_sum_num(THD *thd, Item *item_par): 720 Item_sum(thd, item_par) {} Item_sum_num(THD * thd,Item * a,Item * b)721 Item_sum_num(THD *thd, Item *a, Item* b): 722 Item_sum(thd, a, b) {} Item_sum_num(THD * thd,List<Item> & list)723 Item_sum_num(THD *thd, List<Item> &list): 724 Item_sum(thd, list) {} Item_sum_num(THD * thd,Item_sum_num * item)725 Item_sum_num(THD *thd, Item_sum_num *item): 726 Item_sum(thd, item) {} 727 bool fix_fields(THD *, Item **); 728 void reset_field(); 729 }; 730 731 732 class Item_sum_double :public Item_sum_num 733 { 734 public: Item_sum_double(THD * thd)735 Item_sum_double(THD *thd): Item_sum_num(thd) {} Item_sum_double(THD * thd,Item * item_par)736 Item_sum_double(THD *thd, Item *item_par): Item_sum_num(thd, item_par) {} Item_sum_double(THD * thd,List<Item> & list)737 Item_sum_double(THD *thd, List<Item> &list): Item_sum_num(thd, list) {} Item_sum_double(THD * thd,Item_sum_double * item)738 Item_sum_double(THD *thd, Item_sum_double *item) :Item_sum_num(thd, item) {} val_int()739 longlong val_int() 740 { 741 return val_int_from_real(); 742 } val_str(String * str)743 String *val_str(String*str) 744 { 745 return val_string_from_real(str); 746 } val_decimal(my_decimal * to)747 my_decimal *val_decimal(my_decimal *to) 748 { 749 return val_decimal_from_real(to); 750 } get_date(MYSQL_TIME * ltime,ulonglong fuzzydate)751 bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) 752 { 753 return get_date_from_real(ltime, fuzzydate); 754 } type_handler()755 const Type_handler *type_handler() const { return &type_handler_double; } 756 }; 757 758 759 class Item_sum_int :public Item_sum_num 760 { 761 public: Item_sum_int(THD * thd)762 Item_sum_int(THD *thd): Item_sum_num(thd) {} Item_sum_int(THD * thd,Item * item_par)763 Item_sum_int(THD *thd, Item *item_par): Item_sum_num(thd, item_par) {} Item_sum_int(THD * thd,List<Item> & list)764 Item_sum_int(THD *thd, List<Item> &list): Item_sum_num(thd, list) {} Item_sum_int(THD * thd,Item_sum_int * item)765 Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {} val_real()766 double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } 767 String *val_str(String*str); 768 my_decimal *val_decimal(my_decimal *); get_date(MYSQL_TIME * ltime,ulonglong fuzzydate)769 bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) 770 { 771 return get_date_from_int(ltime, fuzzydate); 772 } type_handler()773 const Type_handler *type_handler() const { return &type_handler_longlong; } fix_length_and_dec()774 bool fix_length_and_dec() 775 { decimals=0; max_length=21; maybe_null=null_value=0; return FALSE; } 776 }; 777 778 779 class Item_sum_sum :public Item_sum_num, 780 public Type_handler_hybrid_field_type 781 { 782 protected: 783 bool direct_added; 784 bool direct_reseted_field; 785 bool direct_sum_is_null; 786 double direct_sum_real; 787 double sum; 788 my_decimal direct_sum_decimal; 789 my_decimal dec_buffs[2]; 790 uint curr_dec_buff; 791 bool fix_length_and_dec(); 792 793 public: Item_sum_sum(THD * thd,Item * item_par,bool distinct)794 Item_sum_sum(THD *thd, Item *item_par, bool distinct): 795 Item_sum_num(thd, item_par), direct_added(FALSE), 796 direct_reseted_field(FALSE) 797 { 798 set_distinct(distinct); 799 } 800 Item_sum_sum(THD *thd, Item_sum_sum *item); sum_func()801 enum Sumfunctype sum_func () const 802 { 803 return has_with_distinct() ? SUM_DISTINCT_FUNC : SUM_FUNC; 804 } 805 void cleanup(); 806 void direct_add(my_decimal *add_sum_decimal); 807 void direct_add(double add_sum_real, bool add_sum_is_null); 808 void clear(); 809 bool add(); 810 double val_real(); 811 longlong val_int(); 812 String *val_str(String*str); 813 my_decimal *val_decimal(my_decimal *); get_date(MYSQL_TIME * ltime,ulonglong fuzzydate)814 bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) 815 { 816 return type_handler()->Item_get_date(this, ltime, fuzzydate); 817 } type_handler()818 const Type_handler *type_handler() const 819 { return Type_handler_hybrid_field_type::type_handler(); } 820 void fix_length_and_dec_double(); 821 void fix_length_and_dec_decimal(); 822 void reset_field(); 823 void update_field(); no_rows_in_result()824 void no_rows_in_result() {} func_name()825 const char *func_name() const 826 { 827 return has_with_distinct() ? "sum(distinct " : "sum("; 828 } 829 Item *copy_or_same(THD* thd); 830 void remove(); get_copy(THD * thd)831 Item *get_copy(THD *thd) 832 { return get_item_copy<Item_sum_sum>(thd, this); } 833 supports_removal()834 bool supports_removal() const 835 { 836 return true; 837 } 838 839 private: 840 void add_helper(bool perform_removal); 841 ulonglong count; 842 }; 843 844 845 class Item_sum_count :public Item_sum_int 846 { 847 bool direct_counted; 848 bool direct_reseted_field; 849 longlong direct_count; 850 longlong count; 851 852 friend class Aggregator_distinct; 853 854 void clear(); 855 bool add(); 856 void cleanup(); 857 void remove(); 858 859 public: Item_sum_count(THD * thd,Item * item_par)860 Item_sum_count(THD *thd, Item *item_par): 861 Item_sum_int(thd, item_par), direct_counted(FALSE), 862 direct_reseted_field(FALSE), count(0) 863 {} 864 865 /** 866 Constructs an instance for COUNT(DISTINCT) 867 868 @param list a list of the arguments to the aggregate function 869 870 This constructor is called by the parser only for COUNT (DISTINCT). 871 */ 872 Item_sum_count(THD * thd,List<Item> & list)873 Item_sum_count(THD *thd, List<Item> &list): 874 Item_sum_int(thd, list), direct_counted(FALSE), 875 direct_reseted_field(FALSE), count(0) 876 { 877 set_distinct(TRUE); 878 } Item_sum_count(THD * thd,Item_sum_count * item)879 Item_sum_count(THD *thd, Item_sum_count *item): 880 Item_sum_int(thd, item), direct_counted(FALSE), 881 direct_reseted_field(FALSE), count(item->count) 882 {} sum_func()883 enum Sumfunctype sum_func () const 884 { 885 return has_with_distinct() ? COUNT_DISTINCT_FUNC : COUNT_FUNC; 886 } no_rows_in_result()887 void no_rows_in_result() { count=0; } make_const(longlong count_arg)888 void make_const(longlong count_arg) 889 { 890 count=count_arg; 891 Item_sum::make_const(); 892 } 893 longlong val_int(); 894 void reset_field(); 895 void update_field(); 896 void direct_add(longlong add_count); func_name()897 const char *func_name() const 898 { 899 return has_with_distinct() ? "count(distinct " : "count("; 900 } 901 Item *copy_or_same(THD* thd); get_copy(THD * thd)902 Item *get_copy(THD *thd) 903 { return get_item_copy<Item_sum_count>(thd, this); } 904 supports_removal()905 bool supports_removal() const 906 { 907 return true; 908 } 909 }; 910 911 912 class Item_sum_avg :public Item_sum_sum 913 { 914 public: 915 // TODO-cvicentiu given that Item_sum_sum now uses a counter of its own, in 916 // order to implement remove(), it is possible to remove this member. 917 ulonglong count; 918 uint prec_increment; 919 uint f_precision, f_scale, dec_bin_size; 920 Item_sum_avg(THD * thd,Item * item_par,bool distinct)921 Item_sum_avg(THD *thd, Item *item_par, bool distinct): 922 Item_sum_sum(thd, item_par, distinct), count(0) 923 {} Item_sum_avg(THD * thd,Item_sum_avg * item)924 Item_sum_avg(THD *thd, Item_sum_avg *item) 925 :Item_sum_sum(thd, item), count(item->count), 926 prec_increment(item->prec_increment) {} 927 928 void fix_length_and_dec_double(); 929 void fix_length_and_dec_decimal(); 930 bool fix_length_and_dec(); sum_func()931 enum Sumfunctype sum_func () const 932 { 933 return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC; 934 } 935 void clear(); 936 bool add(); 937 void remove(); 938 double val_real(); 939 // In SPs we might force the "wrong" type with select into a declare variable val_int()940 longlong val_int() { return val_int_from_real(); } 941 my_decimal *val_decimal(my_decimal *); 942 String *val_str(String *str); 943 void reset_field(); 944 void update_field(); 945 Item *result_item(THD *thd, Field *field); no_rows_in_result()946 void no_rows_in_result() {} func_name()947 const char *func_name() const 948 { 949 return has_with_distinct() ? "avg(distinct " : "avg("; 950 } 951 Item *copy_or_same(THD* thd); 952 Field *create_tmp_field(bool group, TABLE *table); cleanup()953 void cleanup() 954 { 955 count= 0; 956 Item_sum_sum::cleanup(); 957 } get_copy(THD * thd)958 Item *get_copy(THD *thd) 959 { return get_item_copy<Item_sum_avg>(thd, this); } 960 supports_removal()961 bool supports_removal() const 962 { 963 return true; 964 } 965 }; 966 967 968 /* 969 variance(a) = 970 971 = sum (ai - avg(a))^2 / count(a) ) 972 = sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a) 973 = (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) = 974 = (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) = 975 = (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) = 976 = (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) = 977 = (sum(ai^2) - sum(a)^2/count(a))/count(a) 978 979 But, this falls prey to catastrophic cancellation. Instead, use the recurrence formulas 980 981 M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline 982 S_{1} = 0, ~ S_{k} = S_{k-1} + (x_{k} - M_{k-1}) times (x_{k} - M_{k}) newline 983 for 2 <= k <= n newline 984 ital variance = S_{n} / (n-1) 985 986 */ 987 988 class Item_sum_variance : public Item_sum_double 989 { 990 bool fix_length_and_dec(); 991 992 public: 993 double recurrence_m, recurrence_s; /* Used in recurrence relation. */ 994 ulonglong count; 995 uint sample; 996 uint prec_increment; 997 Item_sum_variance(THD * thd,Item * item_par,uint sample_arg)998 Item_sum_variance(THD *thd, Item *item_par, uint sample_arg): 999 Item_sum_double(thd, item_par), count(0), 1000 sample(sample_arg) 1001 {} 1002 Item_sum_variance(THD *thd, Item_sum_variance *item); sum_func()1003 enum Sumfunctype sum_func () const { return VARIANCE_FUNC; } 1004 void fix_length_and_dec_double(); 1005 void fix_length_and_dec_decimal(); 1006 void clear(); 1007 bool add(); 1008 double val_real(); 1009 void reset_field(); 1010 void update_field(); 1011 Item *result_item(THD *thd, Field *field); no_rows_in_result()1012 void no_rows_in_result() {} func_name()1013 const char *func_name() const 1014 { return sample ? "var_samp(" : "variance("; } 1015 Item *copy_or_same(THD* thd); 1016 Field *create_tmp_field(bool group, TABLE *table); cleanup()1017 void cleanup() 1018 { 1019 count= 0; 1020 Item_sum_double::cleanup(); 1021 } get_copy(THD * thd)1022 Item *get_copy(THD *thd) 1023 { return get_item_copy<Item_sum_variance>(thd, this); } 1024 }; 1025 1026 /* 1027 standard_deviation(a) = sqrt(variance(a)) 1028 */ 1029 1030 class Item_sum_std :public Item_sum_variance 1031 { 1032 public: Item_sum_std(THD * thd,Item * item_par,uint sample_arg)1033 Item_sum_std(THD *thd, Item *item_par, uint sample_arg): 1034 Item_sum_variance(thd, item_par, sample_arg) {} Item_sum_std(THD * thd,Item_sum_std * item)1035 Item_sum_std(THD *thd, Item_sum_std *item) 1036 :Item_sum_variance(thd, item) 1037 {} sum_func()1038 enum Sumfunctype sum_func () const { return STD_FUNC; } 1039 double val_real(); 1040 Item *result_item(THD *thd, Field *field); func_name()1041 const char *func_name() const { return "std("; } 1042 Item *copy_or_same(THD* thd); get_copy(THD * thd)1043 Item *get_copy(THD *thd) 1044 { return get_item_copy<Item_sum_std>(thd, this); } 1045 }; 1046 1047 1048 class Item_sum_hybrid: public Item_sum, 1049 public Type_handler_hybrid_field_type 1050 { 1051 public: Item_sum_hybrid(THD * thd,Item * item_par)1052 Item_sum_hybrid(THD *thd, Item *item_par): 1053 Item_sum(thd, item_par), 1054 Type_handler_hybrid_field_type(&type_handler_longlong) 1055 { collation.set(&my_charset_bin); } Item_sum_hybrid(THD * thd,Item * a,Item * b)1056 Item_sum_hybrid(THD *thd, Item *a, Item *b): 1057 Item_sum(thd, a, b), 1058 Type_handler_hybrid_field_type(&type_handler_longlong) 1059 { collation.set(&my_charset_bin); } Item_sum_hybrid(THD * thd,Item_sum_hybrid * item)1060 Item_sum_hybrid(THD *thd, Item_sum_hybrid *item) 1061 :Item_sum(thd, item), 1062 Type_handler_hybrid_field_type(item) 1063 { } type_handler()1064 const Type_handler *type_handler() const 1065 { return Type_handler_hybrid_field_type::type_handler(); } 1066 bool fix_length_and_dec_generic(); 1067 bool fix_length_and_dec_numeric(const Type_handler *h); 1068 bool fix_length_and_dec_string(); 1069 }; 1070 1071 1072 // This class is a string or number function depending on num_func 1073 class Arg_comparator; 1074 class Item_cache; 1075 class Item_sum_min_max :public Item_sum_hybrid 1076 { 1077 protected: 1078 bool direct_added; 1079 Item *direct_item; 1080 Item_cache *value, *arg_cache; 1081 Arg_comparator *cmp; 1082 int cmp_sign; 1083 bool was_values; // Set if we have found at least one row (for max/min only) 1084 bool was_null_value; 1085 1086 public: Item_sum_min_max(THD * thd,Item * item_par,int sign)1087 Item_sum_min_max(THD *thd, Item *item_par,int sign): 1088 Item_sum_hybrid(thd, item_par), 1089 direct_added(FALSE), value(0), arg_cache(0), cmp(0), 1090 cmp_sign(sign), was_values(TRUE) 1091 { collation.set(&my_charset_bin); } Item_sum_min_max(THD * thd,Item_sum_min_max * item)1092 Item_sum_min_max(THD *thd, Item_sum_min_max *item) 1093 :Item_sum_hybrid(thd, item), 1094 direct_added(FALSE), value(item->value), arg_cache(0), 1095 cmp_sign(item->cmp_sign), was_values(item->was_values) 1096 { } 1097 bool fix_fields(THD *, Item **); 1098 bool fix_length_and_dec(); 1099 void setup_hybrid(THD *thd, Item *item, Item *value_arg); 1100 void clear(); 1101 void direct_add(Item *item); 1102 double val_real(); 1103 longlong val_int(); 1104 my_decimal *val_decimal(my_decimal *); 1105 bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); 1106 void reset_field(); 1107 String *val_str(String *); real_type_handler()1108 const Type_handler *real_type_handler() const 1109 { 1110 return get_arg(0)->real_type_handler(); 1111 } get_typelib()1112 TYPELIB *get_typelib() const { return args[0]->get_typelib(); } 1113 void update_field(); 1114 void min_max_update_str_field(); 1115 void min_max_update_real_field(); 1116 void min_max_update_int_field(); 1117 void min_max_update_decimal_field(); 1118 void cleanup(); any_value()1119 bool any_value() { return was_values; } 1120 void no_rows_in_result(); 1121 void restore_to_before_no_rows_in_result(); 1122 Field *create_tmp_field(bool group, TABLE *table); setup_caches(THD * thd)1123 void setup_caches(THD *thd) { setup_hybrid(thd, arguments()[0], NULL); } 1124 }; 1125 1126 1127 class Item_sum_min :public Item_sum_min_max 1128 { 1129 public: Item_sum_min(THD * thd,Item * item_par)1130 Item_sum_min(THD *thd, Item *item_par): Item_sum_min_max(thd, item_par, 1) {} Item_sum_min(THD * thd,Item_sum_min * item)1131 Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_min_max(thd, item) {} sum_func()1132 enum Sumfunctype sum_func () const {return MIN_FUNC;} 1133 1134 bool add(); func_name()1135 const char *func_name() const { return "min("; } 1136 Item *copy_or_same(THD* thd); get_copy(THD * thd)1137 Item *get_copy(THD *thd) 1138 { return get_item_copy<Item_sum_min>(thd, this); } 1139 }; 1140 1141 1142 class Item_sum_max :public Item_sum_min_max 1143 { 1144 public: Item_sum_max(THD * thd,Item * item_par)1145 Item_sum_max(THD *thd, Item *item_par): Item_sum_min_max(thd, item_par, -1) {} Item_sum_max(THD * thd,Item_sum_max * item)1146 Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_min_max(thd, item) {} sum_func()1147 enum Sumfunctype sum_func () const {return MAX_FUNC;} 1148 1149 bool add(); func_name()1150 const char *func_name() const { return "max("; } 1151 Item *copy_or_same(THD* thd); get_copy(THD * thd)1152 Item *get_copy(THD *thd) 1153 { return get_item_copy<Item_sum_max>(thd, this); } 1154 }; 1155 1156 1157 class Item_sum_bit :public Item_sum_int 1158 { 1159 public: Item_sum_bit(THD * thd,Item * item_par,ulonglong reset_arg)1160 Item_sum_bit(THD *thd, Item *item_par, ulonglong reset_arg): 1161 Item_sum_int(thd, item_par), reset_bits(reset_arg), bits(reset_arg), 1162 as_window_function(FALSE), num_values_added(0) {} Item_sum_bit(THD * thd,Item_sum_bit * item)1163 Item_sum_bit(THD *thd, Item_sum_bit *item): 1164 Item_sum_int(thd, item), reset_bits(item->reset_bits), bits(item->bits), 1165 as_window_function(item->as_window_function), 1166 num_values_added(item->num_values_added) 1167 { 1168 if (as_window_function) 1169 memcpy(bit_counters, item->bit_counters, sizeof(bit_counters)); 1170 } sum_func()1171 enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;} 1172 void clear(); 1173 longlong val_int(); 1174 void reset_field(); 1175 void update_field(); fix_length_and_dec()1176 bool fix_length_and_dec() 1177 { 1178 decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; 1179 return FALSE; 1180 } cleanup()1181 void cleanup() 1182 { 1183 bits= reset_bits; 1184 if (as_window_function) 1185 clear_as_window(); 1186 Item_sum_int::cleanup(); 1187 } setup_window_func(THD * thd,Window_spec * window_spec)1188 void setup_window_func(THD *thd __attribute__((unused)), 1189 Window_spec *window_spec __attribute__((unused))) 1190 { 1191 as_window_function= TRUE; 1192 clear_as_window(); 1193 } remove()1194 void remove() 1195 { 1196 if (as_window_function) 1197 { 1198 remove_as_window(args[0]->val_int()); 1199 return; 1200 } 1201 // Unless we're counting bits, we can not remove anything. 1202 DBUG_ASSERT(0); 1203 } 1204 supports_removal()1205 bool supports_removal() const 1206 { 1207 return true; 1208 } 1209 1210 protected: 1211 enum bit_counters { NUM_BIT_COUNTERS= 64 }; 1212 ulonglong reset_bits,bits; 1213 /* 1214 Marks whether the function is to be computed as a window function. 1215 */ 1216 bool as_window_function; 1217 // When used as an aggregate window function, we need to store 1218 // this additional information. 1219 ulonglong num_values_added; 1220 ulonglong bit_counters[NUM_BIT_COUNTERS]; 1221 bool add_as_window(ulonglong value); 1222 bool remove_as_window(ulonglong value); 1223 bool clear_as_window(); 1224 virtual void set_bits_from_counters()= 0; 1225 }; 1226 1227 1228 class Item_sum_or :public Item_sum_bit 1229 { 1230 public: Item_sum_or(THD * thd,Item * item_par)1231 Item_sum_or(THD *thd, Item *item_par): Item_sum_bit(thd, item_par, 0) {} Item_sum_or(THD * thd,Item_sum_or * item)1232 Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {} 1233 bool add(); func_name()1234 const char *func_name() const { return "bit_or("; } 1235 Item *copy_or_same(THD* thd); get_copy(THD * thd)1236 Item *get_copy(THD *thd) 1237 { return get_item_copy<Item_sum_or>(thd, this); } 1238 1239 private: 1240 void set_bits_from_counters(); 1241 }; 1242 1243 1244 class Item_sum_and :public Item_sum_bit 1245 { 1246 public: Item_sum_and(THD * thd,Item * item_par)1247 Item_sum_and(THD *thd, Item *item_par): 1248 Item_sum_bit(thd, item_par, ULONGLONG_MAX) {} Item_sum_and(THD * thd,Item_sum_and * item)1249 Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {} 1250 bool add(); func_name()1251 const char *func_name() const { return "bit_and("; } 1252 Item *copy_or_same(THD* thd); get_copy(THD * thd)1253 Item *get_copy(THD *thd) 1254 { return get_item_copy<Item_sum_and>(thd, this); } 1255 1256 private: 1257 void set_bits_from_counters(); 1258 }; 1259 1260 class Item_sum_xor :public Item_sum_bit 1261 { 1262 public: Item_sum_xor(THD * thd,Item * item_par)1263 Item_sum_xor(THD *thd, Item *item_par): Item_sum_bit(thd, item_par, 0) {} Item_sum_xor(THD * thd,Item_sum_xor * item)1264 Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {} 1265 bool add(); func_name()1266 const char *func_name() const { return "bit_xor("; } 1267 Item *copy_or_same(THD* thd); get_copy(THD * thd)1268 Item *get_copy(THD *thd) 1269 { return get_item_copy<Item_sum_xor>(thd, this); } 1270 1271 private: 1272 void set_bits_from_counters(); 1273 }; 1274 1275 class sp_head; 1276 class sp_name; 1277 class Query_arena; 1278 struct st_sp_security_context; 1279 1280 /* 1281 Item_sum_sp handles STORED AGGREGATE FUNCTIONS 1282 1283 Each Item_sum_sp represents a custom aggregate function. Inside the 1284 function's body, we require at least one occurence of FETCH GROUP NEXT ROW 1285 instruction. This cursor is what makes custom stored aggregates possible. 1286 1287 During computation the function's add method is called. This in turn performs 1288 an execution of the function. The function will execute from the current 1289 function context (and instruction), if one exists, or from the start if not. 1290 See Item_sp for more details. 1291 1292 Upon encounter of FETCH GROUP NEXT ROW instruction, the function will pause 1293 execution. We assume that the user has performed the necessary additions for 1294 a row, between two encounters of FETCH GROUP NEXT ROW. 1295 1296 Example: 1297 create aggregate function f1(x INT) returns int 1298 begin 1299 declare continue handler for not found return s; 1300 declare s int default 0 1301 loop 1302 fetch group next row; 1303 set s = s + x; 1304 end loop; 1305 end 1306 1307 The function will always stop after an encounter of FETCH GROUP NEXT ROW, 1308 except (!) on first encounter, as the value for the first row in the 1309 group is already set in the argument x. This behaviour is done so when 1310 a user writes a function, he should "logically" include FETCH GROUP NEXT ROW 1311 before any "add" instructions in the stored function. This means however that 1312 internally, the first occurence doesn't stop the function. See the 1313 implementation of FETCH GROUP NEXT ROW for details as to how it happens. 1314 1315 Either way, one should assume that after calling "Item_sum_sp::add()" that 1316 the values for that particular row have been added to the aggregation. 1317 1318 To produce values for val_xxx methods we need an extra syntactic construct. 1319 We require a continue handler when "no more rows are available". val_xxx 1320 methods force a function return by executing the function again, while 1321 setting a server flag that no more rows have been found. This implies 1322 that val_xxx methods should only be called once per group however. 1323 1324 Example: 1325 DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN ret_val; 1326 */ 1327 class Item_sum_sp :public Item_sum, 1328 public Item_sp 1329 { 1330 private: 1331 bool execute(); 1332 1333 public: 1334 Item_sum_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name, 1335 sp_head *sp); 1336 1337 Item_sum_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name, 1338 sp_head *sp, List<Item> &list); 1339 Item_sum_sp(THD *thd, Item_sum_sp *item); 1340 sum_func()1341 enum Sumfunctype sum_func () const 1342 { 1343 return SP_AGGREGATE_FUNC; 1344 } create_field_for_create_select(TABLE * table)1345 Field *create_field_for_create_select(TABLE *table) 1346 { 1347 return create_table_field_from_handler(table); 1348 } 1349 bool fix_length_and_dec(); 1350 bool fix_fields(THD *thd, Item **ref); 1351 const char *func_name() const; 1352 const Type_handler *type_handler() const; 1353 bool add(); 1354 1355 /* val_xx functions */ val_int()1356 longlong val_int() 1357 { 1358 if(execute()) 1359 return 0; 1360 return sp_result_field->val_int(); 1361 } 1362 val_real()1363 double val_real() 1364 { 1365 if(execute()) 1366 return 0.0; 1367 return sp_result_field->val_real(); 1368 } 1369 val_decimal(my_decimal * dec_buf)1370 my_decimal *val_decimal(my_decimal *dec_buf) 1371 { 1372 if(execute()) 1373 return NULL; 1374 return sp_result_field->val_decimal(dec_buf); 1375 } 1376 val_str(String * str)1377 String *val_str(String *str) 1378 { 1379 String buf; 1380 char buff[20]; 1381 buf.set(buff, 20, str->charset()); 1382 buf.length(0); 1383 if (execute()) 1384 return NULL; 1385 /* 1386 result_field will set buf pointing to internal buffer 1387 of the resul_field. Due to this it will change any time 1388 when SP is executed. In order to prevent occasional 1389 corruption of returned value, we make here a copy. 1390 */ 1391 sp_result_field->val_str(&buf); 1392 str->copy(buf); 1393 return str; 1394 } reset_field()1395 void reset_field(){DBUG_ASSERT(0);} update_field()1396 void update_field(){DBUG_ASSERT(0);} 1397 void clear(); 1398 void cleanup(); get_date(MYSQL_TIME * ltime,ulonglong fuzzydate)1399 bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) 1400 { 1401 return execute() || sp_result_field->get_date(ltime, fuzzydate); 1402 } get_sp_result_field()1403 inline Field *get_sp_result_field() 1404 { 1405 return sp_result_field; 1406 } get_copy(THD * thd)1407 Item *get_copy(THD *thd) 1408 { return get_item_copy<Item_sum_sp>(thd, this); } 1409 Item *copy_or_same(THD *thd); 1410 }; 1411 1412 /* Items to get the value of a stored sum function */ 1413 1414 class Item_sum_field :public Item 1415 { 1416 protected: 1417 Field *field; 1418 public: Item_sum_field(THD * thd,Item_sum * item)1419 Item_sum_field(THD *thd, Item_sum *item) 1420 :Item(thd), field(item->result_field) 1421 { 1422 name= item->name; 1423 maybe_null= true; 1424 decimals= item->decimals; 1425 max_length= item->max_length; 1426 unsigned_flag= item->unsigned_flag; 1427 fixed= true; 1428 } used_tables()1429 table_map used_tables() const { return (table_map) 1L; } save_in_result_field(bool no_conversions)1430 void save_in_result_field(bool no_conversions) { DBUG_ASSERT(0); } check_vcol_func_processor(void * arg)1431 bool check_vcol_func_processor(void *arg) 1432 { 1433 return mark_unsupported_function(name.str, arg, VCOL_IMPOSSIBLE); 1434 } get_date(MYSQL_TIME * ltime,ulonglong fuzzydate)1435 bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) 1436 { 1437 return type_handler()->Item_get_date(this, ltime, fuzzydate); 1438 } 1439 }; 1440 1441 1442 class Item_avg_field :public Item_sum_field 1443 { 1444 protected: 1445 uint prec_increment; 1446 public: Item_avg_field(THD * thd,Item_sum_avg * item)1447 Item_avg_field(THD *thd, Item_sum_avg *item) 1448 :Item_sum_field(thd, item), prec_increment(item->prec_increment) 1449 { } type()1450 enum Type type() const { return FIELD_AVG_ITEM; } is_null()1451 bool is_null() { update_null_value(); return null_value; } 1452 }; 1453 1454 1455 class Item_avg_field_double :public Item_avg_field 1456 { 1457 public: Item_avg_field_double(THD * thd,Item_sum_avg * item)1458 Item_avg_field_double(THD *thd, Item_sum_avg *item) 1459 :Item_avg_field(thd, item) 1460 { } type_handler()1461 const Type_handler *type_handler() const { return &type_handler_double; } val_int()1462 longlong val_int() { return val_int_from_real(); } val_decimal(my_decimal * dec)1463 my_decimal *val_decimal(my_decimal *dec) { return val_decimal_from_real(dec); } val_str(String * str)1464 String *val_str(String *str) { return val_string_from_real(str); } 1465 double val_real(); get_copy(THD * thd)1466 Item *get_copy(THD *thd) 1467 { return get_item_copy<Item_avg_field_double>(thd, this); } 1468 }; 1469 1470 1471 class Item_avg_field_decimal :public Item_avg_field 1472 { 1473 uint f_precision, f_scale, dec_bin_size; 1474 public: Item_avg_field_decimal(THD * thd,Item_sum_avg * item)1475 Item_avg_field_decimal(THD *thd, Item_sum_avg *item) 1476 :Item_avg_field(thd, item), 1477 f_precision(item->f_precision), 1478 f_scale(item->f_scale), 1479 dec_bin_size(item->dec_bin_size) 1480 { } type_handler()1481 const Type_handler *type_handler() const { return &type_handler_newdecimal; } val_real()1482 double val_real() { return val_real_from_decimal(); } val_int()1483 longlong val_int() { return val_int_from_decimal(); } val_str(String * str)1484 String *val_str(String *str) { return val_string_from_decimal(str); } 1485 my_decimal *val_decimal(my_decimal *); get_copy(THD * thd)1486 Item *get_copy(THD *thd) 1487 { return get_item_copy<Item_avg_field_decimal>(thd, this); } 1488 }; 1489 1490 1491 class Item_variance_field :public Item_sum_field 1492 { 1493 uint sample; 1494 public: Item_variance_field(THD * thd,Item_sum_variance * item)1495 Item_variance_field(THD *thd, Item_sum_variance *item) 1496 :Item_sum_field(thd, item), sample(item->sample) 1497 { } type()1498 enum Type type() const {return FIELD_VARIANCE_ITEM; } 1499 double val_real(); val_int()1500 longlong val_int() { return val_int_from_real(); } val_str(String * str)1501 String *val_str(String *str) 1502 { return val_string_from_real(str); } val_decimal(my_decimal * dec_buf)1503 my_decimal *val_decimal(my_decimal *dec_buf) 1504 { return val_decimal_from_real(dec_buf); } is_null()1505 bool is_null() { update_null_value(); return null_value; } type_handler()1506 const Type_handler *type_handler() const { return &type_handler_double; } get_copy(THD * thd)1507 Item *get_copy(THD *thd) 1508 { return get_item_copy<Item_variance_field>(thd, this); } 1509 }; 1510 1511 1512 class Item_std_field :public Item_variance_field 1513 { 1514 public: Item_std_field(THD * thd,Item_sum_std * item)1515 Item_std_field(THD *thd, Item_sum_std *item) 1516 :Item_variance_field(thd, item) 1517 { } type()1518 enum Type type() const { return FIELD_STD_ITEM; } 1519 double val_real(); get_copy(THD * thd)1520 Item *get_copy(THD *thd) 1521 { return get_item_copy<Item_std_field>(thd, this); } 1522 }; 1523 1524 1525 /* 1526 User defined aggregates 1527 */ 1528 1529 #ifdef HAVE_DLOPEN 1530 1531 class Item_udf_sum : public Item_sum 1532 { 1533 protected: 1534 udf_handler udf; 1535 1536 public: Item_udf_sum(THD * thd,udf_func * udf_arg)1537 Item_udf_sum(THD *thd, udf_func *udf_arg): 1538 Item_sum(thd), udf(udf_arg) 1539 { quick_group=0; } Item_udf_sum(THD * thd,udf_func * udf_arg,List<Item> & list)1540 Item_udf_sum(THD *thd, udf_func *udf_arg, List<Item> &list): 1541 Item_sum(thd, list), udf(udf_arg) 1542 { quick_group=0;} Item_udf_sum(THD * thd,Item_udf_sum * item)1543 Item_udf_sum(THD *thd, Item_udf_sum *item) 1544 :Item_sum(thd, item), udf(item->udf) 1545 { udf.not_original= TRUE; } func_name()1546 const char *func_name() const { return udf.name(); } fix_fields(THD * thd,Item ** ref)1547 bool fix_fields(THD *thd, Item **ref) 1548 { 1549 DBUG_ASSERT(fixed == 0); 1550 1551 if (init_sum_func_check(thd)) 1552 return TRUE; 1553 1554 fixed= 1; 1555 /* 1556 We set const_item_cache to false in constructors. 1557 It can be later changed to "true", in a Item_sum::make_const() call. 1558 No make_const() calls should have happened so far. 1559 */ 1560 DBUG_ASSERT(!const_item_cache); 1561 if (udf.fix_fields(thd, this, this->arg_count, this->args)) 1562 return TRUE; 1563 /** 1564 The above call for udf.fix_fields() updates 1565 the Used_tables_and_const_cache part of "this" as if it was a regular 1566 non-aggregate UDF function and can change both const_item_cache and 1567 used_tables_cache members. 1568 - The used_tables_cache will be re-calculated in update_used_tables() 1569 which is called from check_sum_func() below. So we don't care about 1570 its current value. 1571 - The const_item_cache must stay "false" until a Item_sum::make_const() 1572 call happens, if ever. So we need to reset const_item_cache back to 1573 "false" here. 1574 */ 1575 const_item_cache= false; 1576 memcpy (orig_args, args, sizeof (Item *) * arg_count); 1577 return check_sum_func(thd, ref); 1578 } sum_func()1579 enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } have_field_update(void)1580 virtual bool have_field_update(void) const { return 0; } 1581 1582 void clear(); 1583 bool add(); reset_field()1584 void reset_field() {}; update_field()1585 void update_field() {}; 1586 void cleanup(); 1587 virtual void print(String *str, enum_query_type query_type); get_date(MYSQL_TIME * ltime,ulonglong fuzzydate)1588 bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) 1589 { 1590 return type_handler()->Item_get_date(this, ltime, fuzzydate); 1591 } 1592 }; 1593 1594 1595 class Item_sum_udf_float :public Item_udf_sum 1596 { 1597 public: Item_sum_udf_float(THD * thd,udf_func * udf_arg)1598 Item_sum_udf_float(THD *thd, udf_func *udf_arg): 1599 Item_udf_sum(thd, udf_arg) {} Item_sum_udf_float(THD * thd,udf_func * udf_arg,List<Item> & list)1600 Item_sum_udf_float(THD *thd, udf_func *udf_arg, List<Item> &list): 1601 Item_udf_sum(thd, udf_arg, list) {} Item_sum_udf_float(THD * thd,Item_sum_udf_float * item)1602 Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) 1603 :Item_udf_sum(thd, item) {} val_int()1604 longlong val_int() { return val_int_from_real(); } 1605 double val_real(); 1606 String *val_str(String*str); 1607 my_decimal *val_decimal(my_decimal *); type_handler()1608 const Type_handler *type_handler() const { return &type_handler_double; } fix_length_and_dec()1609 bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; } 1610 Item *copy_or_same(THD* thd); get_copy(THD * thd)1611 Item *get_copy(THD *thd) 1612 { return get_item_copy<Item_sum_udf_float>(thd, this); } 1613 }; 1614 1615 1616 class Item_sum_udf_int :public Item_udf_sum 1617 { 1618 public: Item_sum_udf_int(THD * thd,udf_func * udf_arg)1619 Item_sum_udf_int(THD *thd, udf_func *udf_arg): 1620 Item_udf_sum(thd, udf_arg) {} Item_sum_udf_int(THD * thd,udf_func * udf_arg,List<Item> & list)1621 Item_sum_udf_int(THD *thd, udf_func *udf_arg, List<Item> &list): 1622 Item_udf_sum(thd, udf_arg, list) {} Item_sum_udf_int(THD * thd,Item_sum_udf_int * item)1623 Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) 1624 :Item_udf_sum(thd, item) {} 1625 longlong val_int(); val_real()1626 double val_real() 1627 { DBUG_ASSERT(fixed == 1); return (double) Item_sum_udf_int::val_int(); } 1628 String *val_str(String*str); 1629 my_decimal *val_decimal(my_decimal *); type_handler()1630 const Type_handler *type_handler() const { return &type_handler_longlong; } fix_length_and_dec()1631 bool fix_length_and_dec() { decimals=0; max_length=21; return FALSE; } 1632 Item *copy_or_same(THD* thd); get_copy(THD * thd)1633 Item *get_copy(THD *thd) 1634 { return get_item_copy<Item_sum_udf_int>(thd, this); } 1635 }; 1636 1637 1638 class Item_sum_udf_str :public Item_udf_sum 1639 { 1640 public: Item_sum_udf_str(THD * thd,udf_func * udf_arg)1641 Item_sum_udf_str(THD *thd, udf_func *udf_arg): 1642 Item_udf_sum(thd, udf_arg) {} Item_sum_udf_str(THD * thd,udf_func * udf_arg,List<Item> & list)1643 Item_sum_udf_str(THD *thd, udf_func *udf_arg, List<Item> &list): 1644 Item_udf_sum(thd, udf_arg, list) {} Item_sum_udf_str(THD * thd,Item_sum_udf_str * item)1645 Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) 1646 :Item_udf_sum(thd, item) {} 1647 String *val_str(String *); val_real()1648 double val_real() 1649 { 1650 int err_not_used; 1651 char *end_not_used; 1652 String *res; 1653 res=val_str(&str_value); 1654 return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(), 1655 &end_not_used, &err_not_used) : 0.0; 1656 } val_int()1657 longlong val_int() 1658 { 1659 int err_not_used; 1660 char *end; 1661 String *res; 1662 CHARSET_INFO *cs; 1663 1664 if (!(res= val_str(&str_value))) 1665 return 0; /* Null value */ 1666 cs= res->charset(); 1667 end= (char*) res->ptr()+res->length(); 1668 return cs->cset->strtoll10(cs, res->ptr(), &end, &err_not_used); 1669 } 1670 my_decimal *val_decimal(my_decimal *dec); type_handler()1671 const Type_handler *type_handler() const { return string_type_handler(); } 1672 bool fix_length_and_dec(); 1673 Item *copy_or_same(THD* thd); get_copy(THD * thd)1674 Item *get_copy(THD *thd) 1675 { return get_item_copy<Item_sum_udf_str>(thd, this); } 1676 }; 1677 1678 1679 class Item_sum_udf_decimal :public Item_udf_sum 1680 { 1681 public: Item_sum_udf_decimal(THD * thd,udf_func * udf_arg)1682 Item_sum_udf_decimal(THD *thd, udf_func *udf_arg): 1683 Item_udf_sum(thd, udf_arg) {} Item_sum_udf_decimal(THD * thd,udf_func * udf_arg,List<Item> & list)1684 Item_sum_udf_decimal(THD *thd, udf_func *udf_arg, List<Item> &list): 1685 Item_udf_sum(thd, udf_arg, list) {} Item_sum_udf_decimal(THD * thd,Item_sum_udf_decimal * item)1686 Item_sum_udf_decimal(THD *thd, Item_sum_udf_decimal *item) 1687 :Item_udf_sum(thd, item) {} 1688 String *val_str(String *); 1689 double val_real(); 1690 longlong val_int(); 1691 my_decimal *val_decimal(my_decimal *); type_handler()1692 const Type_handler *type_handler() const { return &type_handler_newdecimal; } fix_length_and_dec()1693 bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; } 1694 Item *copy_or_same(THD* thd); get_copy(THD * thd)1695 Item *get_copy(THD *thd) 1696 { return get_item_copy<Item_sum_udf_decimal>(thd, this); } 1697 }; 1698 1699 #else /* Dummy functions to get sql_yacc.cc compiled */ 1700 1701 class Item_sum_udf_float :public Item_sum_double 1702 { 1703 public: Item_sum_udf_float(THD * thd,udf_func * udf_arg)1704 Item_sum_udf_float(THD *thd, udf_func *udf_arg): 1705 Item_sum_double(thd) {} Item_sum_udf_float(THD * thd,udf_func * udf_arg,List<Item> & list)1706 Item_sum_udf_float(THD *thd, udf_func *udf_arg, List<Item> &list): 1707 Item_sum_double(thd) {} Item_sum_udf_float(THD * thd,Item_sum_udf_float * item)1708 Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) 1709 :Item_sum_double(thd, item) {} sum_func()1710 enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } val_real()1711 double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } clear()1712 void clear() {} add()1713 bool add() { return 0; } update_field()1714 void update_field() {} 1715 }; 1716 1717 1718 class Item_sum_udf_int :public Item_sum_double 1719 { 1720 public: Item_sum_udf_int(THD * thd,udf_func * udf_arg)1721 Item_sum_udf_int(THD *thd, udf_func *udf_arg): 1722 Item_sum_double(thd) {} Item_sum_udf_int(THD * thd,udf_func * udf_arg,List<Item> & list)1723 Item_sum_udf_int(THD *thd, udf_func *udf_arg, List<Item> &list): 1724 Item_sum_double(thd) {} Item_sum_udf_int(THD * thd,Item_sum_udf_int * item)1725 Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) 1726 :Item_sum_double(thd, item) {} sum_func()1727 enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } val_int()1728 longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } val_real()1729 double val_real() { DBUG_ASSERT(fixed == 1); return 0; } clear()1730 void clear() {} add()1731 bool add() { return 0; } update_field()1732 void update_field() {} 1733 }; 1734 1735 1736 class Item_sum_udf_decimal :public Item_sum_double 1737 { 1738 public: Item_sum_udf_decimal(THD * thd,udf_func * udf_arg)1739 Item_sum_udf_decimal(THD *thd, udf_func *udf_arg): 1740 Item_sum_double(thd) {} Item_sum_udf_decimal(THD * thd,udf_func * udf_arg,List<Item> & list)1741 Item_sum_udf_decimal(THD *thd, udf_func *udf_arg, List<Item> &list): 1742 Item_sum_double(thd) {} Item_sum_udf_decimal(THD * thd,Item_sum_udf_float * item)1743 Item_sum_udf_decimal(THD *thd, Item_sum_udf_float *item) 1744 :Item_sum_double(thd, item) {} sum_func()1745 enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } val_real()1746 double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } val_decimal(my_decimal *)1747 my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; } clear()1748 void clear() {} add()1749 bool add() { return 0; } update_field()1750 void update_field() {} 1751 }; 1752 1753 1754 class Item_sum_udf_str :public Item_sum_double 1755 { 1756 public: Item_sum_udf_str(THD * thd,udf_func * udf_arg)1757 Item_sum_udf_str(THD *thd, udf_func *udf_arg): 1758 Item_sum_double(thd) {} Item_sum_udf_str(THD * thd,udf_func * udf_arg,List<Item> & list)1759 Item_sum_udf_str(THD *thd, udf_func *udf_arg, List<Item> &list): 1760 Item_sum_double(thd) {} Item_sum_udf_str(THD * thd,Item_sum_udf_str * item)1761 Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) 1762 :Item_sum_double(thd, item) {} val_str(String *)1763 String *val_str(String *) 1764 { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } val_real()1765 double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } val_int()1766 longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } fix_length_and_dec()1767 bool fix_length_and_dec() { maybe_null=1; max_length=0; return FALSE; } sum_func()1768 enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } clear()1769 void clear() {} add()1770 bool add() { return 0; } update_field()1771 void update_field() {} 1772 }; 1773 1774 #endif /* HAVE_DLOPEN */ 1775 1776 C_MODE_START 1777 int group_concat_key_cmp_with_distinct(void* arg, const void* key1, 1778 const void* key2); 1779 int group_concat_key_cmp_with_order(void* arg, const void* key1, 1780 const void* key2); 1781 int dump_leaf_key(void* key_arg, 1782 element_count count __attribute__((unused)), 1783 void* item_arg); 1784 C_MODE_END 1785 1786 class Item_func_group_concat : public Item_sum 1787 { 1788 TMP_TABLE_PARAM *tmp_table_param; 1789 String result; 1790 String *separator; 1791 TREE tree_base; 1792 TREE *tree; 1793 size_t tree_len; 1794 Item **ref_pointer_array; 1795 1796 /** 1797 If DISTINCT is used with this GROUP_CONCAT, this member is used to filter 1798 out duplicates. 1799 @see Item_func_group_concat::setup 1800 @see Item_func_group_concat::add 1801 @see Item_func_group_concat::clear 1802 */ 1803 Unique *unique_filter; 1804 TABLE *table; 1805 ORDER **order; 1806 Name_resolution_context *context; 1807 /** The number of ORDER BY items. */ 1808 uint arg_count_order; 1809 /** The number of selected items, aka the expr list. */ 1810 uint arg_count_field; 1811 uint row_count; 1812 bool distinct; 1813 bool warning_for_row; 1814 bool always_null; 1815 bool force_copy_fields; 1816 /** True if entire result of GROUP_CONCAT has been written to output buffer. */ 1817 bool result_finalized; 1818 /** Limits the rows in the result */ 1819 Item *row_limit; 1820 /** Skips a particular number of rows in from the result*/ 1821 Item *offset_limit; 1822 bool limit_clause; 1823 /* copy of the offset limit */ 1824 ulonglong copy_offset_limit; 1825 /*copy of the row limit */ 1826 ulonglong copy_row_limit; 1827 1828 /* 1829 Following is 0 normal object and pointer to original one for copy 1830 (to correctly free resources) 1831 */ 1832 Item_func_group_concat *original; 1833 1834 friend int group_concat_key_cmp_with_distinct(void* arg, const void* key1, 1835 const void* key2); 1836 friend int group_concat_key_cmp_with_order(void* arg, const void* key1, 1837 const void* key2); 1838 friend int dump_leaf_key(void* key_arg, 1839 element_count count __attribute__((unused)), 1840 void* item_arg); 1841 1842 bool repack_tree(THD *thd); 1843 1844 public: 1845 Item_func_group_concat(THD *thd, Name_resolution_context *context_arg, 1846 bool is_distinct, List<Item> *is_select, 1847 const SQL_I_List<ORDER> &is_order, String *is_separator, 1848 bool limit_clause, Item *row_limit, Item *offset_limit); 1849 1850 Item_func_group_concat(THD *thd, Item_func_group_concat *item); 1851 ~Item_func_group_concat(); 1852 void cleanup(); 1853 sum_func()1854 enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} func_name()1855 const char *func_name() const { return "group_concat("; } type_handler()1856 const Type_handler *type_handler() const 1857 { 1858 if (too_big_for_varchar()) 1859 return &type_handler_blob; 1860 return &type_handler_varchar; 1861 } 1862 void clear(); 1863 bool add(); reset_field()1864 void reset_field() { DBUG_ASSERT(0); } // not used update_field()1865 void update_field() { DBUG_ASSERT(0); } // not used 1866 bool fix_fields(THD *,Item **); 1867 bool setup(THD *thd); 1868 void make_unique(); val_real()1869 double val_real() 1870 { 1871 int error; 1872 const char *end; 1873 String *res; 1874 if (!(res= val_str(&str_value))) 1875 return 0.0; 1876 end= res->ptr() + res->length(); 1877 return (my_strtod(res->ptr(), (char**) &end, &error)); 1878 } val_int()1879 longlong val_int() 1880 { 1881 String *res; 1882 char *end_ptr; 1883 int error; 1884 if (!(res= val_str(&str_value))) 1885 return (longlong) 0; 1886 end_ptr= (char*) res->ptr()+ res->length(); 1887 return my_strtoll10(res->ptr(), &end_ptr, &error); 1888 } val_decimal(my_decimal * decimal_value)1889 my_decimal *val_decimal(my_decimal *decimal_value) 1890 { 1891 return val_decimal_from_string(decimal_value); 1892 } get_date(MYSQL_TIME * ltime,ulonglong fuzzydate)1893 bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) 1894 { 1895 return get_date_from_string(ltime, fuzzydate); 1896 } 1897 String* val_str(String* str); 1898 Item *copy_or_same(THD* thd); no_rows_in_result()1899 void no_rows_in_result() {} 1900 void print(String *str, enum_query_type query_type); change_context_processor(void * cntx)1901 bool change_context_processor(void *cntx) 1902 { context= (Name_resolution_context *)cntx; return FALSE; } get_copy(THD * thd)1903 Item *get_copy(THD *thd) 1904 { return get_item_copy<Item_func_group_concat>(thd, this); } 1905 }; 1906 1907 #endif /* ITEM_SUM_INCLUDED */ 1908