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-1301 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: |
61 | Aggregator (Item_sum *arg): item_sum(arg) {} |
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 maximun 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 | |
348 | bool has_force_copy_fields() const { return force_copy_fields; } |
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(); |
391 | Item_sum(THD *thd): Item_func_or_sum(thd), quick_group(1) |
392 | { |
393 | mark_as_sum_func(); |
394 | init_aggregator(); |
395 | } |
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 | } |
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); |
411 | enum Type type() const { return SUM_FUNC_ITEM; } |
412 | virtual enum Sumfunctype sum_func () const=0; |
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 | */ |
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; |
460 | virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } |
461 | virtual Item *result_item(THD *thd, Field *field); |
462 | |
463 | void update_used_tables (); |
464 | COND *build_equal_items(THD *thd, COND_EQUAL *inherited, |
465 | bool link_item_fields, |
466 | COND_EQUAL **cond_equal_ref) |
467 | { |
468 | /* |
469 | Item_sum (and derivants) of the original WHERE/HAVING clauses |
470 | should already be replaced to Item_aggregate_ref by the time when |
471 | build_equal_items() is called. See Item::split_sum_func2(). |
472 | */ |
473 | DBUG_ASSERT(0); |
474 | return Item::build_equal_items(thd, inherited, link_item_fields, |
475 | cond_equal_ref); |
476 | } |
477 | bool is_null() { return null_value; } |
478 | /** |
479 | make_const() |
480 | Called if we've managed to calculate the value of this Item in |
481 | opt_sum_query(), hence it can be considered constant at all subsequent |
482 | steps. |
483 | */ |
484 | void make_const () |
485 | { |
486 | used_tables_cache= 0; |
487 | const_item_cache= true; |
488 | } |
489 | void reset_forced_const() { const_item_cache= false; } |
490 | virtual bool const_during_execution() const { return false; } |
491 | virtual void print(String *str, enum_query_type query_type); |
492 | void fix_num_length_and_dec(); |
493 | |
494 | /** |
495 | Mark an aggregate as having no rows. |
496 | |
497 | This function is called by the execution engine to assign 'NO ROWS |
498 | FOUND' value to an aggregate item, when the underlying result set |
499 | has no rows. Such value, in a general case, may be different from |
500 | the default value of the item after 'clear()': e.g. a numeric item |
501 | may be initialized to 0 by clear() and to NULL by |
502 | no_rows_in_result(). |
503 | */ |
504 | virtual void no_rows_in_result() |
505 | { |
506 | set_aggregator(with_distinct ? |
507 | Aggregator::DISTINCT_AGGREGATOR : |
508 | Aggregator::SIMPLE_AGGREGATOR); |
509 | aggregator_clear(); |
510 | } |
511 | virtual void make_unique() { force_copy_fields= TRUE; } |
512 | Item *get_tmp_table_item(THD *thd); |
513 | Field *create_tmp_field(bool group, TABLE *table); |
514 | virtual bool collect_outer_ref_processor(void *param); |
515 | bool init_sum_func_check(THD *thd); |
516 | bool check_sum_func(THD *thd, Item **ref); |
517 | bool register_sum_func(THD *thd, Item **ref); |
518 | st_select_lex *depended_from() |
519 | { return (nest_level == aggr_level ? 0 : aggr_sel); } |
520 | |
521 | Item *get_arg(uint i) const { return args[i]; } |
522 | Item *set_arg(uint i, THD *thd, Item *new_val); |
523 | uint get_arg_count() const { return arg_count; } |
524 | virtual Item **get_args() { return fixed ? orig_args : args; } |
525 | |
526 | /* Initialization of distinct related members */ |
527 | void init_aggregator() |
528 | { |
529 | aggr= NULL; |
530 | with_distinct= FALSE; |
531 | force_copy_fields= FALSE; |
532 | } |
533 | |
534 | /** |
535 | Called to initialize the aggregator. |
536 | */ |
537 | |
538 | inline bool aggregator_setup(THD *thd) { return aggr->setup(thd); }; |
539 | |
540 | /** |
541 | Called to cleanup the aggregator. |
542 | */ |
543 | |
544 | inline void aggregator_clear() { aggr->clear(); } |
545 | |
546 | /** |
547 | Called to add value to the aggregator. |
548 | */ |
549 | |
550 | inline bool aggregator_add() { return aggr->add(); }; |
551 | |
552 | /* stores the declared DISTINCT flag (from the parser) */ |
553 | void set_distinct(bool distinct) |
554 | { |
555 | with_distinct= distinct; |
556 | quick_group= with_distinct ? 0 : 1; |
557 | } |
558 | |
559 | /* |
560 | Set the type of aggregation : DISTINCT or not. |
561 | |
562 | May be called multiple times. |
563 | */ |
564 | |
565 | int set_aggregator(Aggregator::Aggregator_type aggregator); |
566 | |
567 | virtual void clear()= 0; |
568 | virtual bool add()= 0; |
569 | virtual bool setup(THD *thd) { return false; } |
570 | |
571 | virtual bool supports_removal() const { return false; } |
572 | virtual void remove() { DBUG_ASSERT(0); } |
573 | |
574 | virtual void cleanup(); |
575 | bool check_vcol_func_processor(void *arg); |
576 | virtual void setup_window_func(THD *thd, Window_spec *window_spec) {} |
577 | void mark_as_window_func_sum_expr() { window_func_sum_expr_flag= true; } |
578 | bool is_window_func_sum_expr() { return window_func_sum_expr_flag; } |
579 | virtual void setup_caches(THD *thd) {}; |
580 | }; |
581 | |
582 | |
583 | class Unique; |
584 | |
585 | |
586 | /** |
587 | The distinct aggregator. |
588 | Implements AGGFN (DISTINCT ..) |
589 | Collects all the data into an Unique (similarly to what Item_sum |
590 | does currently when with_distinct=true) and then (if applicable) iterates over |
591 | the list of unique values and pumps them back into its object |
592 | */ |
593 | |
594 | class Aggregator_distinct : public Aggregator |
595 | { |
596 | friend class Item_sum_sum; |
597 | |
598 | /* |
599 | flag to prevent consecutive runs of endup(). Normally in endup there are |
600 | expensive calculations (like walking the distinct tree for example) |
601 | which we must do only once if there are no data changes. |
602 | We can re-use the data for the second and subsequent val_xxx() calls. |
603 | endup_done set to TRUE also means that the calculated values for |
604 | the aggregate functions are correct and don't need recalculation. |
605 | */ |
606 | bool endup_done; |
607 | |
608 | /* |
609 | Used depending on the type of the aggregate function and the presence of |
610 | blob columns in it: |
611 | - For COUNT(DISTINCT) and no blob fields this points to a real temporary |
612 | table. It's used as a hash table. |
613 | - For AVG/SUM(DISTINCT) or COUNT(DISTINCT) with blob fields only the |
614 | in-memory data structure of a temporary table is constructed. |
615 | It's used by the Field classes to transform data into row format. |
616 | */ |
617 | TABLE *table; |
618 | |
619 | /* |
620 | An array of field lengths on row allocated and used only for |
621 | COUNT(DISTINCT) with multiple columns and no blobs. Used in |
622 | Aggregator_distinct::composite_key_cmp (called from Unique to compare |
623 | nodes |
624 | */ |
625 | uint32 *field_lengths; |
626 | |
627 | /* |
628 | Used in conjunction with 'table' to support the access to Field classes |
629 | for COUNT(DISTINCT). Needed by copy_fields()/copy_funcs(). |
630 | */ |
631 | TMP_TABLE_PARAM *tmp_table_param; |
632 | |
633 | /* |
634 | If there are no blobs in the COUNT(DISTINCT) arguments, we can use a tree, |
635 | which is faster than heap table. In that case, we still use the table |
636 | to help get things set up, but we insert nothing in it. |
637 | For AVG/SUM(DISTINCT) we always use this tree (as it takes a single |
638 | argument) to get the distinct rows. |
639 | */ |
640 | Unique *tree; |
641 | |
642 | /* |
643 | The length of the temp table row. Must be a member of the class as it |
644 | gets passed down to simple_raw_key_cmp () as a compare function argument |
645 | to Unique. simple_raw_key_cmp () is used as a fast comparison function |
646 | when the entire row can be binary compared. |
647 | */ |
648 | uint tree_key_length; |
649 | |
650 | /* |
651 | Set to true if the result is known to be always NULL. |
652 | If set deactivates creation and usage of the temporary table (in the |
653 | 'table' member) and the Unique instance (in the 'tree' member) as well as |
654 | the calculation of the final value on the first call to |
655 | Item_[sum|avg|count]::val_xxx(). |
656 | */ |
657 | bool always_null; |
658 | |
659 | /** |
660 | When feeding back the data in endup() from Unique/temp table back to |
661 | Item_sum::add() methods we must read the data from Unique (and not |
662 | recalculate the functions that are given as arguments to the aggregate |
663 | function. |
664 | This flag is to tell the arg_*() methods to take the data from the Unique |
665 | instead of calling the relevant val_..() method. |
666 | */ |
667 | bool use_distinct_values; |
668 | |
669 | public: |
670 | Aggregator_distinct (Item_sum *sum) : |
671 | Aggregator(sum), table(NULL), tmp_table_param(NULL), tree(NULL), |
672 | always_null(false), use_distinct_values(false) {} |
673 | virtual ~Aggregator_distinct (); |
674 | Aggregator_type Aggrtype() { return DISTINCT_AGGREGATOR; } |
675 | |
676 | bool setup(THD *); |
677 | void clear(); |
678 | bool add(); |
679 | void endup(); |
680 | virtual my_decimal *arg_val_decimal(my_decimal * value); |
681 | virtual double arg_val_real(); |
682 | virtual bool arg_is_null(bool use_null_value); |
683 | |
684 | bool unique_walk_function(void *element); |
685 | bool unique_walk_function_for_count(void *element); |
686 | static int composite_key_cmp(void* arg, uchar* key1, uchar* key2); |
687 | }; |
688 | |
689 | |
690 | /** |
691 | The pass-through aggregator. |
692 | Implements AGGFN (DISTINCT ..) by knowing it gets distinct data on input. |
693 | So it just pumps them back to the Item_sum descendant class. |
694 | */ |
695 | class Aggregator_simple : public Aggregator |
696 | { |
697 | public: |
698 | |
699 | Aggregator_simple (Item_sum *sum) : |
700 | Aggregator(sum) {} |
701 | Aggregator_type Aggrtype() { return Aggregator::SIMPLE_AGGREGATOR; } |
702 | |
703 | bool setup(THD * thd) { return item_sum->setup(thd); } |
704 | void clear() { item_sum->clear(); } |
705 | bool add() { return item_sum->add(); } |
706 | void endup() {}; |
707 | virtual my_decimal *arg_val_decimal(my_decimal * value); |
708 | virtual double arg_val_real(); |
709 | virtual bool arg_is_null(bool use_null_value); |
710 | }; |
711 | |
712 | |
713 | class Item_sum_num :public Item_sum |
714 | { |
715 | protected: |
716 | /* |
717 | val_xxx() functions may be called several times during the execution of a |
718 | query. Derived classes that require extensive calculation in val_xxx() |
719 | maintain cache of aggregate value. This variable governs the validity of |
720 | that cache. |
721 | */ |
722 | bool is_evaluated; |
723 | public: |
724 | Item_sum_num(THD *thd): Item_sum(thd), is_evaluated(FALSE) {} |
725 | Item_sum_num(THD *thd, Item *item_par): |
726 | Item_sum(thd, item_par), is_evaluated(FALSE) {} |
727 | Item_sum_num(THD *thd, Item *a, Item* b): |
728 | Item_sum(thd, a, b), is_evaluated(FALSE) {} |
729 | Item_sum_num(THD *thd, List<Item> &list): |
730 | Item_sum(thd, list), is_evaluated(FALSE) {} |
731 | Item_sum_num(THD *thd, Item_sum_num *item): |
732 | Item_sum(thd, item),is_evaluated(item->is_evaluated) {} |
733 | bool fix_fields(THD *, Item **); |
734 | longlong val_int() { return val_int_from_real(); /* Real as default */ } |
735 | String *val_str(String*str); |
736 | my_decimal *val_decimal(my_decimal *); |
737 | bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) |
738 | { |
739 | return type_handler()->Item_get_date(this, ltime, fuzzydate); |
740 | } |
741 | void reset_field(); |
742 | }; |
743 | |
744 | |
745 | class Item_sum_int :public Item_sum_num |
746 | { |
747 | public: |
748 | Item_sum_int(THD *thd): Item_sum_num(thd) {} |
749 | Item_sum_int(THD *thd, Item *item_par): Item_sum_num(thd, item_par) {} |
750 | Item_sum_int(THD *thd, List<Item> &list): Item_sum_num(thd, list) {} |
751 | Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {} |
752 | double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } |
753 | String *val_str(String*str); |
754 | my_decimal *val_decimal(my_decimal *); |
755 | const Type_handler *type_handler() const { return &type_handler_longlong; } |
756 | void fix_length_and_dec() |
757 | { decimals=0; max_length=21; maybe_null=null_value=0; } |
758 | }; |
759 | |
760 | |
761 | class Item_sum_sum :public Item_sum_num, |
762 | public Type_handler_hybrid_field_type |
763 | { |
764 | protected: |
765 | bool direct_added; |
766 | bool direct_reseted_field; |
767 | bool direct_sum_is_null; |
768 | double direct_sum_real; |
769 | double sum; |
770 | my_decimal direct_sum_decimal; |
771 | my_decimal dec_buffs[2]; |
772 | uint curr_dec_buff; |
773 | void fix_length_and_dec(); |
774 | |
775 | public: |
776 | Item_sum_sum(THD *thd, Item *item_par, bool distinct): |
777 | Item_sum_num(thd, item_par), direct_added(FALSE), |
778 | direct_reseted_field(FALSE) |
779 | { |
780 | set_distinct(distinct); |
781 | } |
782 | Item_sum_sum(THD *thd, Item_sum_sum *item); |
783 | enum Sumfunctype sum_func () const |
784 | { |
785 | return has_with_distinct() ? SUM_DISTINCT_FUNC : SUM_FUNC; |
786 | } |
787 | void cleanup(); |
788 | void direct_add(my_decimal *add_sum_decimal); |
789 | void direct_add(double add_sum_real, bool add_sum_is_null); |
790 | void clear(); |
791 | bool add(); |
792 | double val_real(); |
793 | longlong val_int(); |
794 | String *val_str(String*str); |
795 | my_decimal *val_decimal(my_decimal *); |
796 | const Type_handler *type_handler() const |
797 | { return Type_handler_hybrid_field_type::type_handler(); } |
798 | void fix_length_and_dec_double(); |
799 | void fix_length_and_dec_decimal(); |
800 | void reset_field(); |
801 | void update_field(); |
802 | void no_rows_in_result() {} |
803 | const char *func_name() const |
804 | { |
805 | return has_with_distinct() ? "sum(distinct " : "sum(" ; |
806 | } |
807 | Item *copy_or_same(THD* thd); |
808 | void remove(); |
809 | Item *get_copy(THD *thd) |
810 | { return get_item_copy<Item_sum_sum>(thd, this); } |
811 | |
812 | bool supports_removal() const |
813 | { |
814 | return true; |
815 | } |
816 | |
817 | private: |
818 | void add_helper(bool perform_removal); |
819 | ulonglong count; |
820 | }; |
821 | |
822 | |
823 | class Item_sum_count :public Item_sum_int |
824 | { |
825 | bool direct_counted; |
826 | bool direct_reseted_field; |
827 | longlong direct_count; |
828 | longlong count; |
829 | |
830 | friend class Aggregator_distinct; |
831 | |
832 | void clear(); |
833 | bool add(); |
834 | void cleanup(); |
835 | void remove(); |
836 | |
837 | public: |
838 | Item_sum_count(THD *thd, Item *item_par): |
839 | Item_sum_int(thd, item_par), direct_counted(FALSE), |
840 | direct_reseted_field(FALSE), count(0) |
841 | {} |
842 | |
843 | /** |
844 | Constructs an instance for COUNT(DISTINCT) |
845 | |
846 | @param list a list of the arguments to the aggregate function |
847 | |
848 | This constructor is called by the parser only for COUNT (DISTINCT). |
849 | */ |
850 | |
851 | Item_sum_count(THD *thd, List<Item> &list): |
852 | Item_sum_int(thd, list), direct_counted(FALSE), |
853 | direct_reseted_field(FALSE), count(0) |
854 | { |
855 | set_distinct(TRUE); |
856 | } |
857 | Item_sum_count(THD *thd, Item_sum_count *item): |
858 | Item_sum_int(thd, item), direct_counted(FALSE), |
859 | direct_reseted_field(FALSE), count(item->count) |
860 | {} |
861 | enum Sumfunctype sum_func () const |
862 | { |
863 | return has_with_distinct() ? COUNT_DISTINCT_FUNC : COUNT_FUNC; |
864 | } |
865 | void no_rows_in_result() { count=0; } |
866 | void make_const(longlong count_arg) |
867 | { |
868 | count=count_arg; |
869 | Item_sum::make_const(); |
870 | } |
871 | longlong val_int(); |
872 | void reset_field(); |
873 | void update_field(); |
874 | void direct_add(longlong add_count); |
875 | const char *func_name() const |
876 | { |
877 | return has_with_distinct() ? "count(distinct " : "count(" ; |
878 | } |
879 | Item *copy_or_same(THD* thd); |
880 | Item *get_copy(THD *thd) |
881 | { return get_item_copy<Item_sum_count>(thd, this); } |
882 | |
883 | bool supports_removal() const |
884 | { |
885 | return true; |
886 | } |
887 | }; |
888 | |
889 | |
890 | class Item_sum_avg :public Item_sum_sum |
891 | { |
892 | public: |
893 | // TODO-cvicentiu given that Item_sum_sum now uses a counter of its own, in |
894 | // order to implement remove(), it is possible to remove this member. |
895 | ulonglong count; |
896 | uint prec_increment; |
897 | uint f_precision, f_scale, dec_bin_size; |
898 | |
899 | Item_sum_avg(THD *thd, Item *item_par, bool distinct): |
900 | Item_sum_sum(thd, item_par, distinct), count(0) |
901 | {} |
902 | Item_sum_avg(THD *thd, Item_sum_avg *item) |
903 | :Item_sum_sum(thd, item), count(item->count), |
904 | prec_increment(item->prec_increment) {} |
905 | |
906 | void fix_length_and_dec_double(); |
907 | void fix_length_and_dec_decimal(); |
908 | void fix_length_and_dec(); |
909 | enum Sumfunctype sum_func () const |
910 | { |
911 | return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC; |
912 | } |
913 | void clear(); |
914 | bool add(); |
915 | void remove(); |
916 | double val_real(); |
917 | // In SPs we might force the "wrong" type with select into a declare variable |
918 | longlong val_int() { return val_int_from_real(); } |
919 | my_decimal *val_decimal(my_decimal *); |
920 | String *val_str(String *str); |
921 | void reset_field(); |
922 | void update_field(); |
923 | Item *result_item(THD *thd, Field *field); |
924 | void no_rows_in_result() {} |
925 | const char *func_name() const |
926 | { |
927 | return has_with_distinct() ? "avg(distinct " : "avg(" ; |
928 | } |
929 | Item *copy_or_same(THD* thd); |
930 | Field *create_tmp_field(bool group, TABLE *table); |
931 | void cleanup() |
932 | { |
933 | count= 0; |
934 | Item_sum_sum::cleanup(); |
935 | } |
936 | Item *get_copy(THD *thd) |
937 | { return get_item_copy<Item_sum_avg>(thd, this); } |
938 | |
939 | bool supports_removal() const |
940 | { |
941 | return true; |
942 | } |
943 | }; |
944 | |
945 | |
946 | /* |
947 | variance(a) = |
948 | |
949 | = sum (ai - avg(a))^2 / count(a) ) |
950 | = sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a) |
951 | = (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) = |
952 | = (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) = |
953 | = (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) = |
954 | = (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) = |
955 | = (sum(ai^2) - sum(a)^2/count(a))/count(a) |
956 | |
957 | But, this falls prey to catastrophic cancellation. Instead, use the recurrence formulas |
958 | |
959 | M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline |
960 | S_{1} = 0, ~ S_{k} = S_{k-1} + (x_{k} - M_{k-1}) times (x_{k} - M_{k}) newline |
961 | for 2 <= k <= n newline |
962 | ital variance = S_{n} / (n-1) |
963 | |
964 | */ |
965 | |
966 | class Item_sum_variance : public Item_sum_num |
967 | { |
968 | void fix_length_and_dec(); |
969 | |
970 | public: |
971 | double recurrence_m, recurrence_s; /* Used in recurrence relation. */ |
972 | ulonglong count; |
973 | uint sample; |
974 | uint prec_increment; |
975 | |
976 | Item_sum_variance(THD *thd, Item *item_par, uint sample_arg): |
977 | Item_sum_num(thd, item_par), count(0), |
978 | sample(sample_arg) |
979 | {} |
980 | Item_sum_variance(THD *thd, Item_sum_variance *item); |
981 | enum Sumfunctype sum_func () const { return VARIANCE_FUNC; } |
982 | void fix_length_and_dec_double(); |
983 | void fix_length_and_dec_decimal(); |
984 | void clear(); |
985 | bool add(); |
986 | double val_real(); |
987 | my_decimal *val_decimal(my_decimal *); |
988 | void reset_field(); |
989 | void update_field(); |
990 | Item *result_item(THD *thd, Field *field); |
991 | void no_rows_in_result() {} |
992 | const char *func_name() const |
993 | { return sample ? "var_samp(" : "variance(" ; } |
994 | Item *copy_or_same(THD* thd); |
995 | Field *create_tmp_field(bool group, TABLE *table); |
996 | const Type_handler *type_handler() const { return &type_handler_double; } |
997 | void cleanup() |
998 | { |
999 | count= 0; |
1000 | Item_sum_num::cleanup(); |
1001 | } |
1002 | Item *get_copy(THD *thd) |
1003 | { return get_item_copy<Item_sum_variance>(thd, this); } |
1004 | }; |
1005 | |
1006 | /* |
1007 | standard_deviation(a) = sqrt(variance(a)) |
1008 | */ |
1009 | |
1010 | class Item_sum_std :public Item_sum_variance |
1011 | { |
1012 | public: |
1013 | Item_sum_std(THD *thd, Item *item_par, uint sample_arg): |
1014 | Item_sum_variance(thd, item_par, sample_arg) {} |
1015 | Item_sum_std(THD *thd, Item_sum_std *item) |
1016 | :Item_sum_variance(thd, item) |
1017 | {} |
1018 | enum Sumfunctype sum_func () const { return STD_FUNC; } |
1019 | double val_real(); |
1020 | Item *result_item(THD *thd, Field *field); |
1021 | const char *func_name() const { return "std(" ; } |
1022 | Item *copy_or_same(THD* thd); |
1023 | Item *get_copy(THD *thd) |
1024 | { return get_item_copy<Item_sum_std>(thd, this); } |
1025 | }; |
1026 | |
1027 | // This class is a string or number function depending on num_func |
1028 | class Arg_comparator; |
1029 | class Item_cache; |
1030 | class Item_sum_hybrid :public Item_sum, public Type_handler_hybrid_field_type |
1031 | { |
1032 | protected: |
1033 | bool direct_added; |
1034 | Item *direct_item; |
1035 | Item_cache *value, *arg_cache; |
1036 | Arg_comparator *cmp; |
1037 | int cmp_sign; |
1038 | bool was_values; // Set if we have found at least one row (for max/min only) |
1039 | bool was_null_value; |
1040 | |
1041 | public: |
1042 | Item_sum_hybrid(THD *thd, Item *item_par,int sign): |
1043 | Item_sum(thd, item_par), |
1044 | Type_handler_hybrid_field_type(&type_handler_longlong), |
1045 | direct_added(FALSE), value(0), arg_cache(0), cmp(0), |
1046 | cmp_sign(sign), was_values(TRUE) |
1047 | { collation.set(&my_charset_bin); } |
1048 | Item_sum_hybrid(THD *thd, Item_sum_hybrid *item) |
1049 | :Item_sum(thd, item), |
1050 | Type_handler_hybrid_field_type(item), |
1051 | direct_added(FALSE), value(item->value), arg_cache(0), |
1052 | cmp_sign(item->cmp_sign), was_values(item->was_values) |
1053 | { } |
1054 | bool fix_fields(THD *, Item **); |
1055 | void fix_length_and_dec(); |
1056 | void setup_hybrid(THD *thd, Item *item, Item *value_arg); |
1057 | void clear(); |
1058 | void direct_add(Item *item); |
1059 | double val_real(); |
1060 | longlong val_int(); |
1061 | my_decimal *val_decimal(my_decimal *); |
1062 | bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); |
1063 | void reset_field(); |
1064 | String *val_str(String *); |
1065 | const Type_handler *real_type_handler() const |
1066 | { |
1067 | return get_arg(0)->real_type_handler(); |
1068 | } |
1069 | const Type_handler *type_handler() const |
1070 | { return Type_handler_hybrid_field_type::type_handler(); } |
1071 | TYPELIB *get_typelib() const { return args[0]->get_typelib(); } |
1072 | void update_field(); |
1073 | void min_max_update_str_field(); |
1074 | void min_max_update_real_field(); |
1075 | void min_max_update_int_field(); |
1076 | void min_max_update_decimal_field(); |
1077 | void cleanup(); |
1078 | bool any_value() { return was_values; } |
1079 | void no_rows_in_result(); |
1080 | void restore_to_before_no_rows_in_result(); |
1081 | Field *create_tmp_field(bool group, TABLE *table); |
1082 | void setup_caches(THD *thd) { setup_hybrid(thd, arguments()[0], NULL); } |
1083 | }; |
1084 | |
1085 | |
1086 | class Item_sum_min :public Item_sum_hybrid |
1087 | { |
1088 | public: |
1089 | Item_sum_min(THD *thd, Item *item_par): Item_sum_hybrid(thd, item_par, 1) {} |
1090 | Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_hybrid(thd, item) {} |
1091 | enum Sumfunctype sum_func () const {return MIN_FUNC;} |
1092 | |
1093 | bool add(); |
1094 | const char *func_name() const { return "min(" ; } |
1095 | Item *copy_or_same(THD* thd); |
1096 | Item *get_copy(THD *thd) |
1097 | { return get_item_copy<Item_sum_min>(thd, this); } |
1098 | }; |
1099 | |
1100 | |
1101 | class Item_sum_max :public Item_sum_hybrid |
1102 | { |
1103 | public: |
1104 | Item_sum_max(THD *thd, Item *item_par): Item_sum_hybrid(thd, item_par, -1) {} |
1105 | Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_hybrid(thd, item) {} |
1106 | enum Sumfunctype sum_func () const {return MAX_FUNC;} |
1107 | |
1108 | bool add(); |
1109 | const char *func_name() const { return "max(" ; } |
1110 | Item *copy_or_same(THD* thd); |
1111 | Item *get_copy(THD *thd) |
1112 | { return get_item_copy<Item_sum_max>(thd, this); } |
1113 | }; |
1114 | |
1115 | |
1116 | class Item_sum_bit :public Item_sum_int |
1117 | { |
1118 | public: |
1119 | Item_sum_bit(THD *thd, Item *item_par, ulonglong reset_arg): |
1120 | Item_sum_int(thd, item_par), reset_bits(reset_arg), bits(reset_arg), |
1121 | as_window_function(FALSE), num_values_added(0) {} |
1122 | Item_sum_bit(THD *thd, Item_sum_bit *item): |
1123 | Item_sum_int(thd, item), reset_bits(item->reset_bits), bits(item->bits), |
1124 | as_window_function(item->as_window_function), |
1125 | num_values_added(item->num_values_added) |
1126 | { |
1127 | if (as_window_function) |
1128 | memcpy(bit_counters, item->bit_counters, sizeof(bit_counters)); |
1129 | } |
1130 | enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;} |
1131 | void clear(); |
1132 | longlong val_int(); |
1133 | void reset_field(); |
1134 | void update_field(); |
1135 | void fix_length_and_dec() |
1136 | { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; } |
1137 | void cleanup() |
1138 | { |
1139 | bits= reset_bits; |
1140 | if (as_window_function) |
1141 | clear_as_window(); |
1142 | Item_sum_int::cleanup(); |
1143 | } |
1144 | void setup_window_func(THD *thd __attribute__((unused)), |
1145 | Window_spec *window_spec __attribute__((unused))) |
1146 | { |
1147 | as_window_function= TRUE; |
1148 | clear_as_window(); |
1149 | } |
1150 | void remove() |
1151 | { |
1152 | if (as_window_function) |
1153 | { |
1154 | remove_as_window(args[0]->val_int()); |
1155 | return; |
1156 | } |
1157 | // Unless we're counting bits, we can not remove anything. |
1158 | DBUG_ASSERT(0); |
1159 | } |
1160 | |
1161 | bool supports_removal() const |
1162 | { |
1163 | return true; |
1164 | } |
1165 | |
1166 | protected: |
1167 | enum bit_counters { NUM_BIT_COUNTERS= 64 }; |
1168 | ulonglong reset_bits,bits; |
1169 | /* |
1170 | Marks whether the function is to be computed as a window function. |
1171 | */ |
1172 | bool as_window_function; |
1173 | // When used as an aggregate window function, we need to store |
1174 | // this additional information. |
1175 | ulonglong num_values_added; |
1176 | ulonglong bit_counters[NUM_BIT_COUNTERS]; |
1177 | bool add_as_window(ulonglong value); |
1178 | bool remove_as_window(ulonglong value); |
1179 | bool clear_as_window(); |
1180 | virtual void set_bits_from_counters()= 0; |
1181 | }; |
1182 | |
1183 | |
1184 | class Item_sum_or :public Item_sum_bit |
1185 | { |
1186 | public: |
1187 | Item_sum_or(THD *thd, Item *item_par): Item_sum_bit(thd, item_par, 0) {} |
1188 | Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {} |
1189 | bool add(); |
1190 | const char *func_name() const { return "bit_or(" ; } |
1191 | Item *copy_or_same(THD* thd); |
1192 | Item *get_copy(THD *thd) |
1193 | { return get_item_copy<Item_sum_or>(thd, this); } |
1194 | |
1195 | private: |
1196 | void set_bits_from_counters(); |
1197 | }; |
1198 | |
1199 | |
1200 | class Item_sum_and :public Item_sum_bit |
1201 | { |
1202 | public: |
1203 | Item_sum_and(THD *thd, Item *item_par): |
1204 | Item_sum_bit(thd, item_par, ULONGLONG_MAX) {} |
1205 | Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {} |
1206 | bool add(); |
1207 | const char *func_name() const { return "bit_and(" ; } |
1208 | Item *copy_or_same(THD* thd); |
1209 | Item *get_copy(THD *thd) |
1210 | { return get_item_copy<Item_sum_and>(thd, this); } |
1211 | |
1212 | private: |
1213 | void set_bits_from_counters(); |
1214 | }; |
1215 | |
1216 | class Item_sum_xor :public Item_sum_bit |
1217 | { |
1218 | public: |
1219 | Item_sum_xor(THD *thd, Item *item_par): Item_sum_bit(thd, item_par, 0) {} |
1220 | Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {} |
1221 | bool add(); |
1222 | const char *func_name() const { return "bit_xor(" ; } |
1223 | Item *copy_or_same(THD* thd); |
1224 | Item *get_copy(THD *thd) |
1225 | { return get_item_copy<Item_sum_xor>(thd, this); } |
1226 | |
1227 | private: |
1228 | void set_bits_from_counters(); |
1229 | }; |
1230 | |
1231 | class sp_head; |
1232 | class sp_name; |
1233 | class Query_arena; |
1234 | struct st_sp_security_context; |
1235 | |
1236 | /* |
1237 | Item_sum_sp handles STORED AGGREGATE FUNCTIONS |
1238 | |
1239 | Each Item_sum_sp represents a custom aggregate function. Inside the |
1240 | function's body, we require at least one occurence of FETCH GROUP NEXT ROW |
1241 | instruction. This cursor is what makes custom stored aggregates possible. |
1242 | |
1243 | During computation the function's add method is called. This in turn performs |
1244 | an execution of the function. The function will execute from the current |
1245 | function context (and instruction), if one exists, or from the start if not. |
1246 | See Item_sp for more details. |
1247 | |
1248 | Upon encounter of FETCH GROUP NEXT ROW instruction, the function will pause |
1249 | execution. We assume that the user has performed the necessary additions for |
1250 | a row, between two encounters of FETCH GROUP NEXT ROW. |
1251 | |
1252 | Example: |
1253 | create aggregate function f1(x INT) returns int |
1254 | begin |
1255 | declare continue handler for not found return s; |
1256 | declare s int default 0 |
1257 | loop |
1258 | fetch group next row; |
1259 | set s = s + x; |
1260 | end loop; |
1261 | end |
1262 | |
1263 | The function will always stop after an encounter of FETCH GROUP NEXT ROW, |
1264 | except (!) on first encounter, as the value for the first row in the |
1265 | group is already set in the argument x. This behaviour is done so when |
1266 | a user writes a function, he should "logically" include FETCH GROUP NEXT ROW |
1267 | before any "add" instructions in the stored function. This means however that |
1268 | internally, the first occurence doesn't stop the function. See the |
1269 | implementation of FETCH GROUP NEXT ROW for details as to how it happens. |
1270 | |
1271 | Either way, one should assume that after calling "Item_sum_sp::add()" that |
1272 | the values for that particular row have been added to the aggregation. |
1273 | |
1274 | To produce values for val_xxx methods we need an extra syntactic construct. |
1275 | We require a continue handler when "no more rows are available". val_xxx |
1276 | methods force a function return by executing the function again, while |
1277 | setting a server flag that no more rows have been found. This implies |
1278 | that val_xxx methods should only be called once per group however. |
1279 | |
1280 | Example: |
1281 | DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN ret_val; |
1282 | */ |
1283 | class Item_sum_sp :public Item_sum, |
1284 | public Item_sp |
1285 | { |
1286 | private: |
1287 | bool execute(); |
1288 | |
1289 | public: |
1290 | Item_sum_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name, |
1291 | sp_head *sp); |
1292 | |
1293 | Item_sum_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name, |
1294 | sp_head *sp, List<Item> &list); |
1295 | Item_sum_sp(THD *thd, Item_sum_sp *item); |
1296 | |
1297 | enum Sumfunctype sum_func () const |
1298 | { |
1299 | return SP_AGGREGATE_FUNC; |
1300 | } |
1301 | Field *create_field_for_create_select(TABLE *table) |
1302 | { |
1303 | return create_table_field_from_handler(table); |
1304 | } |
1305 | void fix_length_and_dec(); |
1306 | bool fix_fields(THD *thd, Item **ref); |
1307 | const char *func_name() const; |
1308 | const Type_handler *type_handler() const; |
1309 | bool add(); |
1310 | |
1311 | /* val_xx functions */ |
1312 | longlong val_int() |
1313 | { |
1314 | if(execute()) |
1315 | return 0; |
1316 | return sp_result_field->val_int(); |
1317 | } |
1318 | |
1319 | double val_real() |
1320 | { |
1321 | if(execute()) |
1322 | return 0.0; |
1323 | return sp_result_field->val_real(); |
1324 | } |
1325 | |
1326 | my_decimal *val_decimal(my_decimal *dec_buf) |
1327 | { |
1328 | if(execute()) |
1329 | return NULL; |
1330 | return sp_result_field->val_decimal(dec_buf); |
1331 | } |
1332 | |
1333 | String *val_str(String *str) |
1334 | { |
1335 | String buf; |
1336 | char buff[20]; |
1337 | buf.set(buff, 20, str->charset()); |
1338 | buf.length(0); |
1339 | if (execute()) |
1340 | return NULL; |
1341 | /* |
1342 | result_field will set buf pointing to internal buffer |
1343 | of the resul_field. Due to this it will change any time |
1344 | when SP is executed. In order to prevent occasional |
1345 | corruption of returned value, we make here a copy. |
1346 | */ |
1347 | sp_result_field->val_str(&buf); |
1348 | str->copy(buf); |
1349 | return str; |
1350 | } |
1351 | void reset_field(){DBUG_ASSERT(0);} |
1352 | void update_field(){DBUG_ASSERT(0);} |
1353 | void clear(); |
1354 | void cleanup(); |
1355 | bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) |
1356 | { |
1357 | return execute() || sp_result_field->get_date(ltime, fuzzydate); |
1358 | } |
1359 | inline Field *get_sp_result_field() |
1360 | { |
1361 | return sp_result_field; |
1362 | } |
1363 | Item *get_copy(THD *thd) |
1364 | { return get_item_copy<Item_sum_sp>(thd, this); } |
1365 | Item *copy_or_same(THD *thd); |
1366 | }; |
1367 | |
1368 | /* Items to get the value of a stored sum function */ |
1369 | |
1370 | class Item_sum_field :public Item |
1371 | { |
1372 | protected: |
1373 | Field *field; |
1374 | public: |
1375 | Item_sum_field(THD *thd, Item_sum *item) |
1376 | :Item(thd), field(item->result_field) |
1377 | { |
1378 | name= item->name; |
1379 | maybe_null= true; |
1380 | decimals= item->decimals; |
1381 | max_length= item->max_length; |
1382 | unsigned_flag= item->unsigned_flag; |
1383 | fixed= true; |
1384 | } |
1385 | table_map used_tables() const { return (table_map) 1L; } |
1386 | void save_in_result_field(bool no_conversions) { DBUG_ASSERT(0); } |
1387 | bool check_vcol_func_processor(void *arg) |
1388 | { |
1389 | return mark_unsupported_function(name.str, arg, VCOL_IMPOSSIBLE); |
1390 | } |
1391 | bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) |
1392 | { |
1393 | return type_handler()->Item_get_date(this, ltime, fuzzydate); |
1394 | } |
1395 | }; |
1396 | |
1397 | |
1398 | class Item_avg_field :public Item_sum_field |
1399 | { |
1400 | protected: |
1401 | uint prec_increment; |
1402 | public: |
1403 | Item_avg_field(THD *thd, Item_sum_avg *item) |
1404 | :Item_sum_field(thd, item), prec_increment(item->prec_increment) |
1405 | { } |
1406 | enum Type type() const { return FIELD_AVG_ITEM; } |
1407 | bool is_null() { update_null_value(); return null_value; } |
1408 | }; |
1409 | |
1410 | |
1411 | class Item_avg_field_double :public Item_avg_field |
1412 | { |
1413 | public: |
1414 | Item_avg_field_double(THD *thd, Item_sum_avg *item) |
1415 | :Item_avg_field(thd, item) |
1416 | { } |
1417 | const Type_handler *type_handler() const { return &type_handler_double; } |
1418 | longlong val_int() { return val_int_from_real(); } |
1419 | my_decimal *val_decimal(my_decimal *dec) { return val_decimal_from_real(dec); } |
1420 | String *val_str(String *str) { return val_string_from_real(str); } |
1421 | double val_real(); |
1422 | Item *get_copy(THD *thd) |
1423 | { return get_item_copy<Item_avg_field_double>(thd, this); } |
1424 | }; |
1425 | |
1426 | |
1427 | class Item_avg_field_decimal :public Item_avg_field |
1428 | { |
1429 | uint f_precision, f_scale, dec_bin_size; |
1430 | public: |
1431 | Item_avg_field_decimal(THD *thd, Item_sum_avg *item) |
1432 | :Item_avg_field(thd, item), |
1433 | f_precision(item->f_precision), |
1434 | f_scale(item->f_scale), |
1435 | dec_bin_size(item->dec_bin_size) |
1436 | { } |
1437 | const Type_handler *type_handler() const { return &type_handler_newdecimal; } |
1438 | double val_real() { return val_real_from_decimal(); } |
1439 | longlong val_int() { return val_int_from_decimal(); } |
1440 | String *val_str(String *str) { return val_string_from_decimal(str); } |
1441 | my_decimal *val_decimal(my_decimal *); |
1442 | Item *get_copy(THD *thd) |
1443 | { return get_item_copy<Item_avg_field_decimal>(thd, this); } |
1444 | }; |
1445 | |
1446 | |
1447 | class Item_variance_field :public Item_sum_field |
1448 | { |
1449 | uint sample; |
1450 | public: |
1451 | Item_variance_field(THD *thd, Item_sum_variance *item) |
1452 | :Item_sum_field(thd, item), sample(item->sample) |
1453 | { } |
1454 | enum Type type() const {return FIELD_VARIANCE_ITEM; } |
1455 | double val_real(); |
1456 | longlong val_int() { return val_int_from_real(); } |
1457 | String *val_str(String *str) |
1458 | { return val_string_from_real(str); } |
1459 | my_decimal *val_decimal(my_decimal *dec_buf) |
1460 | { return val_decimal_from_real(dec_buf); } |
1461 | bool is_null() { update_null_value(); return null_value; } |
1462 | const Type_handler *type_handler() const { return &type_handler_double; } |
1463 | Item *get_copy(THD *thd) |
1464 | { return get_item_copy<Item_variance_field>(thd, this); } |
1465 | }; |
1466 | |
1467 | |
1468 | class Item_std_field :public Item_variance_field |
1469 | { |
1470 | public: |
1471 | Item_std_field(THD *thd, Item_sum_std *item) |
1472 | :Item_variance_field(thd, item) |
1473 | { } |
1474 | enum Type type() const { return FIELD_STD_ITEM; } |
1475 | double val_real(); |
1476 | Item *get_copy(THD *thd) |
1477 | { return get_item_copy<Item_std_field>(thd, this); } |
1478 | }; |
1479 | |
1480 | |
1481 | /* |
1482 | User defined aggregates |
1483 | */ |
1484 | |
1485 | #ifdef HAVE_DLOPEN |
1486 | |
1487 | class Item_udf_sum : public Item_sum |
1488 | { |
1489 | protected: |
1490 | udf_handler udf; |
1491 | |
1492 | public: |
1493 | Item_udf_sum(THD *thd, udf_func *udf_arg): |
1494 | Item_sum(thd), udf(udf_arg) |
1495 | { quick_group=0; } |
1496 | Item_udf_sum(THD *thd, udf_func *udf_arg, List<Item> &list): |
1497 | Item_sum(thd, list), udf(udf_arg) |
1498 | { quick_group=0;} |
1499 | Item_udf_sum(THD *thd, Item_udf_sum *item) |
1500 | :Item_sum(thd, item), udf(item->udf) |
1501 | { udf.not_original= TRUE; } |
1502 | const char *func_name() const { return udf.name(); } |
1503 | bool fix_fields(THD *thd, Item **ref) |
1504 | { |
1505 | DBUG_ASSERT(fixed == 0); |
1506 | |
1507 | if (init_sum_func_check(thd)) |
1508 | return TRUE; |
1509 | |
1510 | fixed= 1; |
1511 | /* |
1512 | We set const_item_cache to false in constructors. |
1513 | It can be later changed to "true", in a Item_sum::make_const() call. |
1514 | No make_const() calls should have happened so far. |
1515 | */ |
1516 | DBUG_ASSERT(!const_item_cache); |
1517 | if (udf.fix_fields(thd, this, this->arg_count, this->args)) |
1518 | return TRUE; |
1519 | /** |
1520 | The above call for udf.fix_fields() updates |
1521 | the Used_tables_and_const_cache part of "this" as if it was a regular |
1522 | non-aggregate UDF function and can change both const_item_cache and |
1523 | used_tables_cache members. |
1524 | - The used_tables_cache will be re-calculated in update_used_tables() |
1525 | which is called from check_sum_func() below. So we don't care about |
1526 | its current value. |
1527 | - The const_item_cache must stay "false" until a Item_sum::make_const() |
1528 | call happens, if ever. So we need to reset const_item_cache back to |
1529 | "false" here. |
1530 | */ |
1531 | const_item_cache= false; |
1532 | memcpy (orig_args, args, sizeof (Item *) * arg_count); |
1533 | return check_sum_func(thd, ref); |
1534 | } |
1535 | enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } |
1536 | virtual bool have_field_update(void) const { return 0; } |
1537 | |
1538 | void clear(); |
1539 | bool add(); |
1540 | void reset_field() {}; |
1541 | void update_field() {}; |
1542 | void cleanup(); |
1543 | virtual void print(String *str, enum_query_type query_type); |
1544 | bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) |
1545 | { |
1546 | return type_handler()->Item_get_date(this, ltime, fuzzydate); |
1547 | } |
1548 | }; |
1549 | |
1550 | |
1551 | class Item_sum_udf_float :public Item_udf_sum |
1552 | { |
1553 | public: |
1554 | Item_sum_udf_float(THD *thd, udf_func *udf_arg): |
1555 | Item_udf_sum(thd, udf_arg) {} |
1556 | Item_sum_udf_float(THD *thd, udf_func *udf_arg, List<Item> &list): |
1557 | Item_udf_sum(thd, udf_arg, list) {} |
1558 | Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) |
1559 | :Item_udf_sum(thd, item) {} |
1560 | longlong val_int() { return val_int_from_real(); } |
1561 | double val_real(); |
1562 | String *val_str(String*str); |
1563 | my_decimal *val_decimal(my_decimal *); |
1564 | const Type_handler *type_handler() const { return &type_handler_double; } |
1565 | void fix_length_and_dec() { fix_num_length_and_dec(); } |
1566 | Item *copy_or_same(THD* thd); |
1567 | Item *get_copy(THD *thd) |
1568 | { return get_item_copy<Item_sum_udf_float>(thd, this); } |
1569 | }; |
1570 | |
1571 | |
1572 | class Item_sum_udf_int :public Item_udf_sum |
1573 | { |
1574 | public: |
1575 | Item_sum_udf_int(THD *thd, udf_func *udf_arg): |
1576 | Item_udf_sum(thd, udf_arg) {} |
1577 | Item_sum_udf_int(THD *thd, udf_func *udf_arg, List<Item> &list): |
1578 | Item_udf_sum(thd, udf_arg, list) {} |
1579 | Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) |
1580 | :Item_udf_sum(thd, item) {} |
1581 | longlong val_int(); |
1582 | double val_real() |
1583 | { DBUG_ASSERT(fixed == 1); return (double) Item_sum_udf_int::val_int(); } |
1584 | String *val_str(String*str); |
1585 | my_decimal *val_decimal(my_decimal *); |
1586 | const Type_handler *type_handler() const { return &type_handler_longlong; } |
1587 | void fix_length_and_dec() { decimals=0; max_length=21; } |
1588 | Item *copy_or_same(THD* thd); |
1589 | Item *get_copy(THD *thd) |
1590 | { return get_item_copy<Item_sum_udf_int>(thd, this); } |
1591 | }; |
1592 | |
1593 | |
1594 | class Item_sum_udf_str :public Item_udf_sum |
1595 | { |
1596 | public: |
1597 | Item_sum_udf_str(THD *thd, udf_func *udf_arg): |
1598 | Item_udf_sum(thd, udf_arg) {} |
1599 | Item_sum_udf_str(THD *thd, udf_func *udf_arg, List<Item> &list): |
1600 | Item_udf_sum(thd, udf_arg, list) {} |
1601 | Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) |
1602 | :Item_udf_sum(thd, item) {} |
1603 | String *val_str(String *); |
1604 | double val_real() |
1605 | { |
1606 | int err_not_used; |
1607 | char *end_not_used; |
1608 | String *res; |
1609 | res=val_str(&str_value); |
1610 | return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(), |
1611 | &end_not_used, &err_not_used) : 0.0; |
1612 | } |
1613 | longlong val_int() |
1614 | { |
1615 | int err_not_used; |
1616 | char *end; |
1617 | String *res; |
1618 | CHARSET_INFO *cs; |
1619 | |
1620 | if (!(res= val_str(&str_value))) |
1621 | return 0; /* Null value */ |
1622 | cs= res->charset(); |
1623 | end= (char*) res->ptr()+res->length(); |
1624 | return cs->cset->strtoll10(cs, res->ptr(), &end, &err_not_used); |
1625 | } |
1626 | my_decimal *val_decimal(my_decimal *dec); |
1627 | const Type_handler *type_handler() const { return string_type_handler(); } |
1628 | void fix_length_and_dec(); |
1629 | Item *copy_or_same(THD* thd); |
1630 | Item *get_copy(THD *thd) |
1631 | { return get_item_copy<Item_sum_udf_str>(thd, this); } |
1632 | }; |
1633 | |
1634 | |
1635 | class Item_sum_udf_decimal :public Item_udf_sum |
1636 | { |
1637 | public: |
1638 | Item_sum_udf_decimal(THD *thd, udf_func *udf_arg): |
1639 | Item_udf_sum(thd, udf_arg) {} |
1640 | Item_sum_udf_decimal(THD *thd, udf_func *udf_arg, List<Item> &list): |
1641 | Item_udf_sum(thd, udf_arg, list) {} |
1642 | Item_sum_udf_decimal(THD *thd, Item_sum_udf_decimal *item) |
1643 | :Item_udf_sum(thd, item) {} |
1644 | String *val_str(String *); |
1645 | double val_real(); |
1646 | longlong val_int(); |
1647 | my_decimal *val_decimal(my_decimal *); |
1648 | const Type_handler *type_handler() const { return &type_handler_newdecimal; } |
1649 | void fix_length_and_dec() { fix_num_length_and_dec(); } |
1650 | Item *copy_or_same(THD* thd); |
1651 | Item *get_copy(THD *thd) |
1652 | { return get_item_copy<Item_sum_udf_decimal>(thd, this); } |
1653 | }; |
1654 | |
1655 | #else /* Dummy functions to get sql_yacc.cc compiled */ |
1656 | |
1657 | class Item_sum_udf_float :public Item_sum_num |
1658 | { |
1659 | public: |
1660 | Item_sum_udf_float(THD *thd, udf_func *udf_arg): |
1661 | Item_sum_num(thd) {} |
1662 | Item_sum_udf_float(THD *thd, udf_func *udf_arg, List<Item> &list): |
1663 | Item_sum_num(thd) {} |
1664 | Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) |
1665 | :Item_sum_num(thd, item) {} |
1666 | enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } |
1667 | double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } |
1668 | void clear() {} |
1669 | bool add() { return 0; } |
1670 | void update_field() {} |
1671 | }; |
1672 | |
1673 | |
1674 | class Item_sum_udf_int :public Item_sum_num |
1675 | { |
1676 | public: |
1677 | Item_sum_udf_int(THD *thd, udf_func *udf_arg): |
1678 | Item_sum_num(thd) {} |
1679 | Item_sum_udf_int(THD *thd, udf_func *udf_arg, List<Item> &list): |
1680 | Item_sum_num(thd) {} |
1681 | Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) |
1682 | :Item_sum_num(thd, item) {} |
1683 | enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } |
1684 | longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } |
1685 | double val_real() { DBUG_ASSERT(fixed == 1); return 0; } |
1686 | void clear() {} |
1687 | bool add() { return 0; } |
1688 | void update_field() {} |
1689 | }; |
1690 | |
1691 | |
1692 | class Item_sum_udf_decimal :public Item_sum_num |
1693 | { |
1694 | public: |
1695 | Item_sum_udf_decimal(THD *thd, udf_func *udf_arg): |
1696 | Item_sum_num(thd) {} |
1697 | Item_sum_udf_decimal(THD *thd, udf_func *udf_arg, List<Item> &list): |
1698 | Item_sum_num(thd) {} |
1699 | Item_sum_udf_decimal(THD *thd, Item_sum_udf_float *item) |
1700 | :Item_sum_num(thd, item) {} |
1701 | enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } |
1702 | double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } |
1703 | my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; } |
1704 | void clear() {} |
1705 | bool add() { return 0; } |
1706 | void update_field() {} |
1707 | }; |
1708 | |
1709 | |
1710 | class Item_sum_udf_str :public Item_sum_num |
1711 | { |
1712 | public: |
1713 | Item_sum_udf_str(THD *thd, udf_func *udf_arg): |
1714 | Item_sum_num(thd) {} |
1715 | Item_sum_udf_str(THD *thd, udf_func *udf_arg, List<Item> &list): |
1716 | Item_sum_num(thd) {} |
1717 | Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) |
1718 | :Item_sum_num(thd, item) {} |
1719 | String *val_str(String *) |
1720 | { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } |
1721 | double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } |
1722 | longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } |
1723 | void fix_length_and_dec() { maybe_null=1; max_length=0; } |
1724 | enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } |
1725 | void clear() {} |
1726 | bool add() { return 0; } |
1727 | void update_field() {} |
1728 | }; |
1729 | |
1730 | #endif /* HAVE_DLOPEN */ |
1731 | |
1732 | C_MODE_START |
1733 | int group_concat_key_cmp_with_distinct(void* arg, const void* key1, |
1734 | const void* key2); |
1735 | int group_concat_key_cmp_with_order(void* arg, const void* key1, |
1736 | const void* key2); |
1737 | int dump_leaf_key(void* key_arg, |
1738 | element_count count __attribute__((unused)), |
1739 | void* item_arg); |
1740 | C_MODE_END |
1741 | |
1742 | class Item_func_group_concat : public Item_sum |
1743 | { |
1744 | TMP_TABLE_PARAM *tmp_table_param; |
1745 | String result; |
1746 | String *separator; |
1747 | TREE tree_base; |
1748 | TREE *tree; |
1749 | Item **ref_pointer_array; |
1750 | |
1751 | /** |
1752 | If DISTINCT is used with this GROUP_CONCAT, this member is used to filter |
1753 | out duplicates. |
1754 | @see Item_func_group_concat::setup |
1755 | @see Item_func_group_concat::add |
1756 | @see Item_func_group_concat::clear |
1757 | */ |
1758 | Unique *unique_filter; |
1759 | TABLE *table; |
1760 | ORDER **order; |
1761 | Name_resolution_context *context; |
1762 | /** The number of ORDER BY items. */ |
1763 | uint arg_count_order; |
1764 | /** The number of selected items, aka the expr list. */ |
1765 | uint arg_count_field; |
1766 | uint row_count; |
1767 | bool distinct; |
1768 | bool warning_for_row; |
1769 | bool always_null; |
1770 | bool force_copy_fields; |
1771 | bool no_appended; |
1772 | /** Limits the rows in the result */ |
1773 | Item *row_limit; |
1774 | /** Skips a particular number of rows in from the result*/ |
1775 | Item *offset_limit; |
1776 | bool limit_clause; |
1777 | /* copy of the offset limit */ |
1778 | ulonglong copy_offset_limit; |
1779 | /*copy of the row limit */ |
1780 | ulonglong copy_row_limit; |
1781 | |
1782 | /* |
1783 | Following is 0 normal object and pointer to original one for copy |
1784 | (to correctly free resources) |
1785 | */ |
1786 | Item_func_group_concat *original; |
1787 | |
1788 | friend int group_concat_key_cmp_with_distinct(void* arg, const void* key1, |
1789 | const void* key2); |
1790 | friend int group_concat_key_cmp_with_order(void* arg, const void* key1, |
1791 | const void* key2); |
1792 | friend int dump_leaf_key(void* key_arg, |
1793 | element_count count __attribute__((unused)), |
1794 | void* item_arg); |
1795 | public: |
1796 | Item_func_group_concat(THD *thd, Name_resolution_context *context_arg, |
1797 | bool is_distinct, List<Item> *is_select, |
1798 | const SQL_I_List<ORDER> &is_order, String *is_separator, |
1799 | bool limit_clause, Item *row_limit, Item *offset_limit); |
1800 | |
1801 | Item_func_group_concat(THD *thd, Item_func_group_concat *item); |
1802 | ~Item_func_group_concat(); |
1803 | void cleanup(); |
1804 | |
1805 | enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} |
1806 | const char *func_name() const { return "group_concat(" ; } |
1807 | const Type_handler *type_handler() const |
1808 | { |
1809 | if (too_big_for_varchar()) |
1810 | return &type_handler_blob; |
1811 | return &type_handler_varchar; |
1812 | } |
1813 | void clear(); |
1814 | bool add(); |
1815 | void reset_field() { DBUG_ASSERT(0); } // not used |
1816 | void update_field() { DBUG_ASSERT(0); } // not used |
1817 | bool fix_fields(THD *,Item **); |
1818 | bool setup(THD *thd); |
1819 | void make_unique(); |
1820 | double val_real() |
1821 | { |
1822 | int error; |
1823 | const char *end; |
1824 | String *res; |
1825 | if (!(res= val_str(&str_value))) |
1826 | return 0.0; |
1827 | end= res->ptr() + res->length(); |
1828 | return (my_strtod(res->ptr(), (char**) &end, &error)); |
1829 | } |
1830 | longlong val_int() |
1831 | { |
1832 | String *res; |
1833 | char *end_ptr; |
1834 | int error; |
1835 | if (!(res= val_str(&str_value))) |
1836 | return (longlong) 0; |
1837 | end_ptr= (char*) res->ptr()+ res->length(); |
1838 | return my_strtoll10(res->ptr(), &end_ptr, &error); |
1839 | } |
1840 | my_decimal *val_decimal(my_decimal *decimal_value) |
1841 | { |
1842 | return val_decimal_from_string(decimal_value); |
1843 | } |
1844 | bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) |
1845 | { |
1846 | return get_date_from_string(ltime, fuzzydate); |
1847 | } |
1848 | String* val_str(String* str); |
1849 | Item *copy_or_same(THD* thd); |
1850 | void no_rows_in_result() {} |
1851 | virtual void print(String *str, enum_query_type query_type); |
1852 | virtual bool change_context_processor(void *cntx) |
1853 | { context= (Name_resolution_context *)cntx; return FALSE; } |
1854 | Item *get_copy(THD *thd) |
1855 | { return get_item_copy<Item_func_group_concat>(thd, this); } |
1856 | }; |
1857 | |
1858 | #endif /* ITEM_SUM_INCLUDED */ |
1859 | |