Skip to content

Commit de35787

Browse files
committed
Merge branch 'cume_dist' into bb-10.2-mdev9543
2 parents 4fe6fbb + 3544fe0 commit de35787

File tree

5 files changed

+277
-181
lines changed

5 files changed

+277
-181
lines changed

mysql-test/r/win_percent_cume.result

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
create table t1 (
2+
pk int primary key,
3+
a int,
4+
b int
5+
);
6+
insert into t1 values
7+
( 1 , 0, 10),
8+
( 2 , 0, 10),
9+
( 3 , 1, 10),
10+
( 4 , 1, 10),
11+
( 8 , 2, 10),
12+
( 5 , 2, 20),
13+
( 6 , 2, 20),
14+
( 7 , 2, 20),
15+
( 9 , 4, 20),
16+
(10 , 4, 20);
17+
select pk, a, b,
18+
percent_rank() over (order by a),
19+
cume_dist() over (order by a)
20+
from t1;
21+
pk a b percent_rank() over (order by a) cume_dist() over (order by a)
22+
1 0 10 0.0000000000 0.2000000000
23+
2 0 10 0.0000000000 0.2000000000
24+
3 1 10 0.2222222222 0.4000000000
25+
4 1 10 0.2222222222 0.4000000000
26+
8 2 10 0.4444444444 0.8000000000
27+
5 2 20 0.4444444444 0.8000000000
28+
6 2 20 0.4444444444 0.8000000000
29+
7 2 20 0.4444444444 0.8000000000
30+
9 4 20 0.8888888889 1.0000000000
31+
10 4 20 0.8888888889 1.0000000000
32+
select pk, a, b,
33+
percent_rank() over (order by pk),
34+
cume_dist() over (order by pk)
35+
from t1 order by pk;
36+
pk a b percent_rank() over (order by pk) cume_dist() over (order by pk)
37+
1 0 10 0.0000000000 0.1000000000
38+
2 0 10 0.1111111111 0.2000000000
39+
3 1 10 0.2222222222 0.3000000000
40+
4 1 10 0.3333333333 0.4000000000
41+
5 2 20 0.4444444444 0.5000000000
42+
6 2 20 0.5555555556 0.6000000000
43+
7 2 20 0.6666666667 0.7000000000
44+
8 2 10 0.7777777778 0.8000000000
45+
9 4 20 0.8888888889 0.9000000000
46+
10 4 20 1.0000000000 1.0000000000
47+
select pk, a, b,
48+
percent_rank() over (partition by a order by a),
49+
cume_dist() over (partition by a order by a)
50+
from t1;
51+
pk a b percent_rank() over (partition by a order by a) cume_dist() over (partition by a order by a)
52+
1 0 10 0.0000000000 1.0000000000
53+
2 0 10 0.0000000000 1.0000000000
54+
3 1 10 0.0000000000 1.0000000000
55+
4 1 10 0.0000000000 1.0000000000
56+
8 2 10 0.0000000000 1.0000000000
57+
5 2 20 0.0000000000 1.0000000000
58+
6 2 20 0.0000000000 1.0000000000
59+
7 2 20 0.0000000000 1.0000000000
60+
9 4 20 0.0000000000 1.0000000000
61+
10 4 20 0.0000000000 1.0000000000
62+
drop table t1;

mysql-test/t/win_percent_cume.test

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
create table t1 (
2+
pk int primary key,
3+
a int,
4+
b int
5+
);
6+
7+
8+
insert into t1 values
9+
( 1 , 0, 10),
10+
( 2 , 0, 10),
11+
( 3 , 1, 10),
12+
( 4 , 1, 10),
13+
( 8 , 2, 10),
14+
( 5 , 2, 20),
15+
( 6 , 2, 20),
16+
( 7 , 2, 20),
17+
( 9 , 4, 20),
18+
(10 , 4, 20);
19+
20+
select pk, a, b,
21+
percent_rank() over (order by a),
22+
cume_dist() over (order by a)
23+
from t1;
24+
25+
select pk, a, b,
26+
percent_rank() over (order by pk),
27+
cume_dist() over (order by pk)
28+
from t1 order by pk;
29+
30+
select pk, a, b,
31+
percent_rank() over (partition by a order by a),
32+
cume_dist() over (partition by a order by a)
33+
from t1;
34+
35+
drop table t1;
36+

sql/item_windowfunc.h

Lines changed: 79 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,18 @@ class Item_context
317317
NOTE: All two pass window functions need to implement
318318
this interface.
319319
*/
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
322321
{
323322
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_;
326332
};
327333

328334
/*
@@ -336,12 +342,11 @@ class Item_sum_window_with_context : public Item_sum_num,
336342
This is held within the row_count context.
337343
- Second pass to compute rank of current row and the value of the function
338344
*/
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
341346
{
342347
public:
343348
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) {}
345350

346351
longlong val_int()
347352
{
@@ -359,14 +364,9 @@ class Item_sum_percent_rank: public Item_sum_window_with_context,
359364
We can not get the real value without knowing the number of rows
360365
in the partition. Don't divide by 0.
361366
*/
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+
370370
return partition_rows > 1 ?
371371
static_cast<double>(cur_rank - 1) / (partition_rows - 1) : 0;
372372
}
@@ -381,25 +381,6 @@ class Item_sum_percent_rank: public Item_sum_window_with_context,
381381
return "percent_rank";
382382
}
383383

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-
403384
void update_field() {}
404385

405386
void clear()
@@ -428,13 +409,6 @@ class Item_sum_percent_rank: public Item_sum_window_with_context,
428409
void cleanup()
429410
{
430411
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_);
438412
}
439413
};
440414

@@ -448,27 +422,62 @@ class Item_sum_percent_rank: public Item_sum_window_with_context,
448422
window ordering of the window partition of R
449423
- NR is defined to be the number of rows in the window partition of R.
450424
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
452426
two passes.
453427
*/
454428

455-
class Item_sum_cume_dist: public Item_sum_percent_rank
429+
class Item_sum_cume_dist: public Item_sum_window_with_row_count
456430
{
457431
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+
}
460446

461-
double val_real() { return 0; }
447+
bool add()
448+
{
449+
current_row_count_++;
450+
return false;
451+
}
462452

463453
enum Sumfunctype sum_func () const
464454
{
465455
return CUME_DIST_FUNC;
466456
}
467457

458+
void clear()
459+
{
460+
current_row_count_= 0;
461+
set_row_count(0);
462+
}
463+
468464
const char*func_name() const
469465
{
470466
return "cume_dist";
471467
}
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_;
472481
};
473482

474483

@@ -499,11 +508,11 @@ class Item_window_func : public Item_func_or_sum
499508
force_return_blank(true),
500509
read_value_from_result_field(false) {}
501510

502-
Item_sum *window_func() { return (Item_sum *) args[0]; }
511+
Item_sum *window_func() const { return (Item_sum *) args[0]; }
503512

504513
void update_used_tables();
505514

506-
bool is_frame_prohibited()
515+
bool is_frame_prohibited() const
507516
{
508517
switch (window_func()->sum_func()) {
509518
case Item_sum::ROW_NUMBER_FUNC:
@@ -517,7 +526,28 @@ class Item_window_func : public Item_func_or_sum
517526
}
518527
}
519528

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
521551
{
522552
switch (window_func()->sum_func()) {
523553
case Item_sum::RANK_FUNC:

0 commit comments

Comments
 (0)