@@ -317,12 +317,18 @@ class Item_context
317
317
NOTE: All two pass window functions need to implement
318
318
this interface.
319
319
*/
320
- class Item_sum_window_with_context : public Item_sum_num ,
321
- public Item_context
320
+ class Item_sum_window_with_row_count : public Item_sum_num
322
321
{
323
322
public:
324
- Item_sum_window_with_context (THD *thd)
325
- : Item_sum_num(thd), Item_context() {}
323
+ Item_sum_window_with_row_count (THD *thd) : Item_sum_num(thd),
324
+ partition_row_count_ (0 ){}
325
+
326
+ void set_row_count (ulonglong count) { partition_row_count_ = count; }
327
+
328
+ protected:
329
+ longlong get_row_count () { return partition_row_count_; }
330
+ private:
331
+ ulonglong partition_row_count_;
326
332
};
327
333
328
334
/*
@@ -336,12 +342,11 @@ class Item_sum_window_with_context : public Item_sum_num,
336
342
This is held within the row_count context.
337
343
- Second pass to compute rank of current row and the value of the function
338
344
*/
339
- class Item_sum_percent_rank : public Item_sum_window_with_context ,
340
- public Window_context_row_count
345
+ class Item_sum_percent_rank : public Item_sum_window_with_row_count
341
346
{
342
347
public:
343
348
Item_sum_percent_rank (THD *thd)
344
- : Item_sum_window_with_context (thd), cur_rank(1 ) {}
349
+ : Item_sum_window_with_row_count (thd), cur_rank(1 ) {}
345
350
346
351
longlong val_int ()
347
352
{
@@ -359,14 +364,9 @@ class Item_sum_percent_rank: public Item_sum_window_with_context,
359
364
We can not get the real value without knowing the number of rows
360
365
in the partition. Don't divide by 0.
361
366
*/
362
- if (!get_context_ ())
363
- {
364
- // Calling this kind of function with a context makes no sense.
365
- DBUG_ASSERT (0 );
366
- return 0 ;
367
- }
368
-
369
- longlong partition_rows = get_context_ ()->get_field_context (result_field);
367
+ ulonglong partition_rows = get_row_count ();
368
+ null_value= partition_rows > 0 ? false : true ;
369
+
370
370
return partition_rows > 1 ?
371
371
static_cast <double >(cur_rank - 1 ) / (partition_rows - 1 ) : 0 ;
372
372
}
@@ -381,25 +381,6 @@ class Item_sum_percent_rank: public Item_sum_window_with_context,
381
381
return " percent_rank" ;
382
382
}
383
383
384
- bool create_window_context ()
385
- {
386
- // TODO-cvicentiu: Currently this means we must make sure to delete
387
- // the window context. We can potentially allocate this on the THD memroot.
388
- // At the same time, this is only necessary for a small portion of the
389
- // query execution and it does not make sense to keep it for all of it.
390
- context_ = new Window_context_row_count ();
391
- if (context_ == NULL )
392
- return true ;
393
- return false ;
394
- }
395
-
396
- void delete_window_context ()
397
- {
398
- if (context_)
399
- delete get_context_ ();
400
- context_ = NULL ;
401
- }
402
-
403
384
void update_field () {}
404
385
405
386
void clear ()
@@ -428,13 +409,6 @@ class Item_sum_percent_rank: public Item_sum_window_with_context,
428
409
void cleanup ()
429
410
{
430
411
peer_tracker.cleanup ();
431
- Item_sum_window_with_context::cleanup ();
432
- }
433
-
434
- /* Helper function so that we don't cast the context every time. */
435
- Window_context_row_count* get_context_ ()
436
- {
437
- return static_cast <Window_context_row_count *>(context_);
438
412
}
439
413
};
440
414
@@ -448,27 +422,62 @@ class Item_sum_percent_rank: public Item_sum_window_with_context,
448
422
window ordering of the window partition of R
449
423
- NR is defined to be the number of rows in the window partition of R.
450
424
451
- Just like with Item_sum_percent_rank, compuation of this function requires
425
+ Just like with Item_sum_percent_rank, computation of this function requires
452
426
two passes.
453
427
*/
454
428
455
- class Item_sum_cume_dist : public Item_sum_percent_rank
429
+ class Item_sum_cume_dist : public Item_sum_window_with_row_count
456
430
{
457
431
public:
458
- Item_sum_cume_dist (THD *thd)
459
- : Item_sum_percent_rank(thd) {}
432
+ Item_sum_cume_dist (THD *thd) : Item_sum_window_with_row_count(thd),
433
+ current_row_count_ (0 ) {}
434
+
435
+ double val_real ()
436
+ {
437
+ if (get_row_count () == 0 )
438
+ {
439
+ null_value= true ;
440
+ return 0 ;
441
+ }
442
+ ulonglong partition_row_count= get_row_count ();
443
+ null_value= false ;
444
+ return static_cast <double >(current_row_count_) / partition_row_count;
445
+ }
460
446
461
- double val_real () { return 0 ; }
447
+ bool add ()
448
+ {
449
+ current_row_count_++;
450
+ return false ;
451
+ }
462
452
463
453
enum Sumfunctype sum_func () const
464
454
{
465
455
return CUME_DIST_FUNC;
466
456
}
467
457
458
+ void clear ()
459
+ {
460
+ current_row_count_= 0 ;
461
+ set_row_count (0 );
462
+ }
463
+
468
464
const char *func_name () const
469
465
{
470
466
return " cume_dist" ;
471
467
}
468
+
469
+ void update_field () {}
470
+ enum Item_result result_type () const { return REAL_RESULT; }
471
+ enum_field_types field_type () const { return MYSQL_TYPE_DOUBLE; }
472
+
473
+ void fix_length_and_dec ()
474
+ {
475
+ decimals = 10 ; // TODO-cvicentiu find out how many decimals the standard
476
+ // requires.
477
+ }
478
+
479
+ private:
480
+ ulonglong current_row_count_;
472
481
};
473
482
474
483
@@ -499,11 +508,11 @@ class Item_window_func : public Item_func_or_sum
499
508
force_return_blank(true ),
500
509
read_value_from_result_field(false ) {}
501
510
502
- Item_sum *window_func () { return (Item_sum *) args[0 ]; }
511
+ Item_sum *window_func () const { return (Item_sum *) args[0 ]; }
503
512
504
513
void update_used_tables ();
505
514
506
- bool is_frame_prohibited ()
515
+ bool is_frame_prohibited () const
507
516
{
508
517
switch (window_func ()->sum_func ()) {
509
518
case Item_sum::ROW_NUMBER_FUNC:
@@ -517,7 +526,28 @@ class Item_window_func : public Item_func_or_sum
517
526
}
518
527
}
519
528
520
- bool is_order_list_mandatory ()
529
+ bool requires_partition_size () const
530
+ {
531
+ switch (window_func ()->sum_func ()) {
532
+ case Item_sum::PERCENT_RANK_FUNC:
533
+ case Item_sum::CUME_DIST_FUNC:
534
+ return true ;
535
+ default :
536
+ return false ;
537
+ }
538
+ }
539
+
540
+ bool requires_peer_size () const
541
+ {
542
+ switch (window_func ()->sum_func ()) {
543
+ case Item_sum::CUME_DIST_FUNC:
544
+ return true ;
545
+ default :
546
+ return false ;
547
+ }
548
+ }
549
+
550
+ bool is_order_list_mandatory () const
521
551
{
522
552
switch (window_func ()->sum_func ()) {
523
553
case Item_sum::RANK_FUNC:
0 commit comments