mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
Merge branch '10.3' of github.com:MariaDB/server into 10.3
This commit is contained in:
commit
914e2c9ba8
11 changed files with 1077 additions and 8 deletions
|
@ -1 +1 @@
|
|||
#cmakedefine SOURCE_REVISION "@SOURCE_REVISION@"
|
||||
#define SOURCE_REVISION "@SOURCE_REVISION@"
|
||||
|
|
326
mysql-test/r/win_percentile.result
Normal file
326
mysql-test/r/win_percentile.result
Normal file
|
@ -0,0 +1,326 @@
|
|||
CREATE TABLE t1 (name CHAR(10), test double, score DECIMAL(19,4));
|
||||
INSERT INTO t1 VALUES
|
||||
('Chun', 0, 3), ('Chun', 0, 7),
|
||||
('Kaolin', 0.5, 3), ('Kaolin', 0.6, 7),
|
||||
('Kaolin', 0.5, 4),
|
||||
('Tatiana', 0.8, 4), ('Tata', 0.8, 4);
|
||||
#
|
||||
# Test invalid syntax
|
||||
#
|
||||
# Order by clause has more than one element
|
||||
select percentile_disc(0.5) within group(order by score,test) over (partition by name) from t1;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'test) over (partition by name) from t1' at line 1
|
||||
select percentile_cont(0.5) within group(order by score,test) over (partition by name) from t1;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'test) over (partition by name) from t1' at line 1
|
||||
# Order by clause has no element
|
||||
select percentile_disc(0.5) within group() over (partition by name) from t1;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') over (partition by name) from t1' at line 1
|
||||
select percentile_cont(0.5) within group() over (partition by name) from t1;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') over (partition by name) from t1' at line 1
|
||||
# No parameters to the percentile functions
|
||||
select percentile_disc() within group() over (partition by name) from t1;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') within group() over (partition by name) from t1' at line 1
|
||||
select percentile_cont() within group() over (partition by name) from t1;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') within group() over (partition by name) from t1' at line 1
|
||||
#
|
||||
# Test simple syntax
|
||||
#
|
||||
select name, percentile_cont(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
name c
|
||||
Chun 5.0000000000
|
||||
Chun 5.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Tatiana 4.0000000000
|
||||
Tata 4.0000000000
|
||||
select name, percentile_disc(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
name c
|
||||
Chun 3.0000000000
|
||||
Chun 3.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Tatiana 4.0000000000
|
||||
Tata 4.0000000000
|
||||
# no partition clause
|
||||
select name, percentile_disc(0.5) within group(order by score) over () from t1;
|
||||
name percentile_disc(0.5) within group(order by score) over ()
|
||||
Chun 4.0000000000
|
||||
Chun 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Tatiana 4.0000000000
|
||||
Tata 4.0000000000
|
||||
select name, percentile_cont(0.5) within group(order by score) over () from t1;
|
||||
name percentile_cont(0.5) within group(order by score) over ()
|
||||
Chun 4.0000000000
|
||||
Chun 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Tatiana 4.0000000000
|
||||
Tata 4.0000000000
|
||||
# argument set to null
|
||||
select name, percentile_cont(null) within group(order by score) over (partition by name) from t1;
|
||||
ERROR HY000: percentile_cont function only accepts arguments that can be converted to numerical types
|
||||
select name, percentile_disc(null) within group(order by score) over (partition by name) from t1;
|
||||
ERROR HY000: percentile_disc function only accepts arguments that can be converted to numerical types
|
||||
#subqueries having percentile functions
|
||||
select * from ( select name , percentile_cont(0.5) within group ( order by score) over (partition by name ) from t1 ) as t;
|
||||
name percentile_cont(0.5) within group ( order by score) over (partition by name )
|
||||
Chun 5.0000000000
|
||||
Chun 5.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Tatiana 4.0000000000
|
||||
Tata 4.0000000000
|
||||
select * from ( select name , percentile_disc(0.5) within group ( order by score) over (partition by name ) from t1 ) as t;
|
||||
name percentile_disc(0.5) within group ( order by score) over (partition by name )
|
||||
Chun 3.0000000000
|
||||
Chun 3.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Tatiana 4.0000000000
|
||||
Tata 4.0000000000
|
||||
select name from t1 a where (select percentile_disc(0.5) within group (order by score) over (partition by name) from t1 b limit 1) >= 0.5;
|
||||
name
|
||||
Chun
|
||||
Chun
|
||||
Kaolin
|
||||
Kaolin
|
||||
Kaolin
|
||||
Tatiana
|
||||
Tata
|
||||
#disallowed fields in order by
|
||||
select score, percentile_cont(0.5) within group(order by name) over (partition by score) from t1;
|
||||
ERROR HY000: Numeric datatype is required for percentile_cont function
|
||||
select score, percentile_disc(0.5) within group(order by name) over (partition by score) from t1;
|
||||
ERROR HY000: Numeric datatype is required for percentile_disc function
|
||||
#parameter value should be in the range of [0,1]
|
||||
select percentile_disc(1.5) within group(order by score) over (partition by name) from t1;
|
||||
ERROR HY000: Argument to the percentile_disc function does not belong to the range [0,1]
|
||||
select percentile_cont(1.5) within group(order by score) over (partition by name) from t1;
|
||||
ERROR HY000: Argument to the percentile_cont function does not belong to the range [0,1]
|
||||
#Argument should remain constant for the entire partition
|
||||
select name,percentile_cont(test) within group(order by score) over (partition by name) from t1;
|
||||
ERROR HY000: Argument to the percentile_cont function is not a constant for a partition
|
||||
select name, percentile_disc(test) within group(order by score) over (partition by name) from t1;
|
||||
ERROR HY000: Argument to the percentile_disc function is not a constant for a partition
|
||||
#only numerical types are allowed as argument to percentile functions
|
||||
select name, percentile_cont(name) within group(order by score) over (partition by name) from t1;
|
||||
ERROR HY000: percentile_cont function only accepts arguments that can be converted to numerical types
|
||||
select name, percentile_disc(name) within group(order by score) over (partition by name) from t1;
|
||||
ERROR HY000: percentile_disc function only accepts arguments that can be converted to numerical types
|
||||
#complete query with partition column
|
||||
select name,cume_dist() over (partition by name order by score), percentile_disc(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
name cume_dist() over (partition by name order by score) c
|
||||
Chun 0.5000000000 3.0000000000
|
||||
Chun 1.0000000000 3.0000000000
|
||||
Kaolin 0.3333333333 4.0000000000
|
||||
Kaolin 1.0000000000 4.0000000000
|
||||
Kaolin 0.6666666667 4.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select name, percentile_cont(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
name c
|
||||
Chun 5.0000000000
|
||||
Chun 5.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Kaolin 4.0000000000
|
||||
Tatiana 4.0000000000
|
||||
Tata 4.0000000000
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.1) within group(order by score) over (partition by name) as c from t1;
|
||||
name b c
|
||||
Chun 0.5000000000 3.0000000000
|
||||
Chun 1.0000000000 3.0000000000
|
||||
Kaolin 0.3333333333 3.0000000000
|
||||
Kaolin 1.0000000000 3.0000000000
|
||||
Kaolin 0.6666666667 3.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.2) within group(order by score) over (partition by name) as c from t1;
|
||||
name b c
|
||||
Chun 0.5000000000 3.0000000000
|
||||
Chun 1.0000000000 3.0000000000
|
||||
Kaolin 0.3333333333 3.0000000000
|
||||
Kaolin 1.0000000000 3.0000000000
|
||||
Kaolin 0.6666666667 3.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.3) within group(order by score) over (partition by name) as c from t1;
|
||||
name b c
|
||||
Chun 0.5000000000 3.0000000000
|
||||
Chun 1.0000000000 3.0000000000
|
||||
Kaolin 0.3333333333 3.0000000000
|
||||
Kaolin 1.0000000000 3.0000000000
|
||||
Kaolin 0.6666666667 3.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.4) within group(order by score) over (partition by name) as c from t1;
|
||||
name b c
|
||||
Chun 0.5000000000 3.0000000000
|
||||
Chun 1.0000000000 3.0000000000
|
||||
Kaolin 0.3333333333 4.0000000000
|
||||
Kaolin 1.0000000000 4.0000000000
|
||||
Kaolin 0.6666666667 4.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
name b c
|
||||
Chun 0.5000000000 3.0000000000
|
||||
Chun 1.0000000000 3.0000000000
|
||||
Kaolin 0.3333333333 4.0000000000
|
||||
Kaolin 1.0000000000 4.0000000000
|
||||
Kaolin 0.6666666667 4.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.6) within group(order by score) over (partition by name) as c from t1;
|
||||
name b c
|
||||
Chun 0.5000000000 7.0000000000
|
||||
Chun 1.0000000000 7.0000000000
|
||||
Kaolin 0.3333333333 4.0000000000
|
||||
Kaolin 1.0000000000 4.0000000000
|
||||
Kaolin 0.6666666667 4.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.7) within group(order by score) over (partition by name) as c from t1;
|
||||
name b c
|
||||
Chun 0.5000000000 7.0000000000
|
||||
Chun 1.0000000000 7.0000000000
|
||||
Kaolin 0.3333333333 7.0000000000
|
||||
Kaolin 1.0000000000 7.0000000000
|
||||
Kaolin 0.6666666667 7.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.8) within group(order by score) over (partition by name) as c from t1;
|
||||
name b c
|
||||
Chun 0.5000000000 7.0000000000
|
||||
Chun 1.0000000000 7.0000000000
|
||||
Kaolin 0.3333333333 7.0000000000
|
||||
Kaolin 1.0000000000 7.0000000000
|
||||
Kaolin 0.6666666667 7.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.9) within group(order by score) over (partition by name) as c from t1;
|
||||
name b c
|
||||
Chun 0.5000000000 7.0000000000
|
||||
Chun 1.0000000000 7.0000000000
|
||||
Kaolin 0.3333333333 7.0000000000
|
||||
Kaolin 1.0000000000 7.0000000000
|
||||
Kaolin 0.6666666667 7.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(1) within group(order by score) over (partition by name) as c from t1;
|
||||
name b c
|
||||
Chun 0.5000000000 7.0000000000
|
||||
Chun 1.0000000000 7.0000000000
|
||||
Kaolin 0.3333333333 7.0000000000
|
||||
Kaolin 1.0000000000 7.0000000000
|
||||
Kaolin 0.6666666667 7.0000000000
|
||||
Tatiana 1.0000000000 4.0000000000
|
||||
Tata 1.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(0) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 3.0000000000
|
||||
5.0000000000 3.0000000000
|
||||
4.0000000000 3.0000000000
|
||||
4.0000000000 3.0000000000
|
||||
4.0000000000 3.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(0.1) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 3.4000000000
|
||||
5.0000000000 3.4000000000
|
||||
4.0000000000 3.2000000000
|
||||
4.0000000000 3.2000000000
|
||||
4.0000000000 3.2000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(0.2) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 3.8000000000
|
||||
5.0000000000 3.8000000000
|
||||
4.0000000000 3.4000000000
|
||||
4.0000000000 3.4000000000
|
||||
4.0000000000 3.4000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(0.3) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 4.2000000000
|
||||
5.0000000000 4.2000000000
|
||||
4.0000000000 3.6000000000
|
||||
4.0000000000 3.6000000000
|
||||
4.0000000000 3.6000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(0.4) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 4.6000000000
|
||||
5.0000000000 4.6000000000
|
||||
4.0000000000 3.8000000000
|
||||
4.0000000000 3.8000000000
|
||||
4.0000000000 3.8000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 5.0000000000
|
||||
5.0000000000 5.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(0.6) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 5.4000000000
|
||||
5.0000000000 5.4000000000
|
||||
4.0000000000 4.6000000000
|
||||
4.0000000000 4.6000000000
|
||||
4.0000000000 4.6000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(0.7) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 5.8000000000
|
||||
5.0000000000 5.8000000000
|
||||
4.0000000000 5.2000000000
|
||||
4.0000000000 5.2000000000
|
||||
4.0000000000 5.2000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(0.8) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 6.2000000000
|
||||
5.0000000000 6.2000000000
|
||||
4.0000000000 5.8000000000
|
||||
4.0000000000 5.8000000000
|
||||
4.0000000000 5.8000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(0.9) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 6.6000000000
|
||||
5.0000000000 6.6000000000
|
||||
4.0000000000 6.4000000000
|
||||
4.0000000000 6.4000000000
|
||||
4.0000000000 6.4000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
select median(score) over (partition by name), percentile_cont(1) within group(order by score) over (partition by name) as c from t1;
|
||||
median(score) over (partition by name) c
|
||||
5.0000000000 7.0000000000
|
||||
5.0000000000 7.0000000000
|
||||
4.0000000000 7.0000000000
|
||||
4.0000000000 7.0000000000
|
||||
4.0000000000 7.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
4.0000000000 4.0000000000
|
||||
drop table t1;
|
104
mysql-test/t/win_percentile.test
Normal file
104
mysql-test/t/win_percentile.test
Normal file
|
@ -0,0 +1,104 @@
|
|||
CREATE TABLE t1 (name CHAR(10), test double, score DECIMAL(19,4));
|
||||
INSERT INTO t1 VALUES
|
||||
('Chun', 0, 3), ('Chun', 0, 7),
|
||||
('Kaolin', 0.5, 3), ('Kaolin', 0.6, 7),
|
||||
('Kaolin', 0.5, 4),
|
||||
('Tatiana', 0.8, 4), ('Tata', 0.8, 4);
|
||||
|
||||
--echo #
|
||||
--echo # Test invalid syntax
|
||||
--echo #
|
||||
|
||||
--echo # Order by clause has more than one element
|
||||
--error ER_PARSE_ERROR
|
||||
select percentile_disc(0.5) within group(order by score,test) over (partition by name) from t1;
|
||||
--error ER_PARSE_ERROR
|
||||
select percentile_cont(0.5) within group(order by score,test) over (partition by name) from t1;
|
||||
|
||||
--echo # Order by clause has no element
|
||||
--error ER_PARSE_ERROR
|
||||
select percentile_disc(0.5) within group() over (partition by name) from t1;
|
||||
--error ER_PARSE_ERROR
|
||||
select percentile_cont(0.5) within group() over (partition by name) from t1;
|
||||
|
||||
--echo # No parameters to the percentile functions
|
||||
--error ER_PARSE_ERROR
|
||||
select percentile_disc() within group() over (partition by name) from t1;
|
||||
--error ER_PARSE_ERROR
|
||||
select percentile_cont() within group() over (partition by name) from t1;
|
||||
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Test simple syntax
|
||||
--echo #
|
||||
|
||||
select name, percentile_cont(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
select name, percentile_disc(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
|
||||
--echo # no partition clause
|
||||
select name, percentile_disc(0.5) within group(order by score) over () from t1;
|
||||
select name, percentile_cont(0.5) within group(order by score) over () from t1;
|
||||
|
||||
--echo # argument set to null
|
||||
--error ER_WRONG_TYPE_OF_ARGUMENT
|
||||
select name, percentile_cont(null) within group(order by score) over (partition by name) from t1;
|
||||
--error ER_WRONG_TYPE_OF_ARGUMENT
|
||||
select name, percentile_disc(null) within group(order by score) over (partition by name) from t1;
|
||||
|
||||
--echo #subqueries having percentile functions
|
||||
select * from ( select name , percentile_cont(0.5) within group ( order by score) over (partition by name ) from t1 ) as t;
|
||||
select * from ( select name , percentile_disc(0.5) within group ( order by score) over (partition by name ) from t1 ) as t;
|
||||
select name from t1 a where (select percentile_disc(0.5) within group (order by score) over (partition by name) from t1 b limit 1) >= 0.5;
|
||||
|
||||
--echo #disallowed fields in order by
|
||||
--error ER_WRONG_TYPE_FOR_PERCENTILE_FUNC
|
||||
select score, percentile_cont(0.5) within group(order by name) over (partition by score) from t1;
|
||||
--error ER_WRONG_TYPE_FOR_PERCENTILE_FUNC
|
||||
select score, percentile_disc(0.5) within group(order by name) over (partition by score) from t1;
|
||||
|
||||
--echo #parameter value should be in the range of [0,1]
|
||||
--error ER_ARGUMENT_OUT_OF_RANGE
|
||||
select percentile_disc(1.5) within group(order by score) over (partition by name) from t1;
|
||||
--error ER_ARGUMENT_OUT_OF_RANGE
|
||||
select percentile_cont(1.5) within group(order by score) over (partition by name) from t1;
|
||||
|
||||
--echo #Argument should remain constant for the entire partition
|
||||
--error ER_ARGUMENT_NOT_CONSTANT
|
||||
select name,percentile_cont(test) within group(order by score) over (partition by name) from t1;
|
||||
--error ER_ARGUMENT_NOT_CONSTANT
|
||||
select name, percentile_disc(test) within group(order by score) over (partition by name) from t1;
|
||||
|
||||
--echo #only numerical types are allowed as argument to percentile functions
|
||||
--error ER_WRONG_TYPE_OF_ARGUMENT
|
||||
select name, percentile_cont(name) within group(order by score) over (partition by name) from t1;
|
||||
--error ER_WRONG_TYPE_OF_ARGUMENT
|
||||
select name, percentile_disc(name) within group(order by score) over (partition by name) from t1;
|
||||
|
||||
--echo #complete query with partition column
|
||||
select name,cume_dist() over (partition by name order by score), percentile_disc(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
select name, percentile_cont(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.1) within group(order by score) over (partition by name) as c from t1;
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.2) within group(order by score) over (partition by name) as c from t1;
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.3) within group(order by score) over (partition by name) as c from t1;
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.4) within group(order by score) over (partition by name) as c from t1;
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.6) within group(order by score) over (partition by name) as c from t1;
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.7) within group(order by score) over (partition by name) as c from t1;
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.8) within group(order by score) over (partition by name) as c from t1;
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(0.9) within group(order by score) over (partition by name) as c from t1;
|
||||
select name,cume_dist() over (partition by name order by score) as b, percentile_disc(1) within group(order by score) over (partition by name) as c from t1;
|
||||
|
||||
select median(score) over (partition by name), percentile_cont(0) within group(order by score) over (partition by name) as c from t1;
|
||||
select median(score) over (partition by name), percentile_cont(0.1) within group(order by score) over (partition by name) as c from t1;
|
||||
select median(score) over (partition by name), percentile_cont(0.2) within group(order by score) over (partition by name) as c from t1;
|
||||
select median(score) over (partition by name), percentile_cont(0.3) within group(order by score) over (partition by name) as c from t1;
|
||||
select median(score) over (partition by name), percentile_cont(0.4) within group(order by score) over (partition by name) as c from t1;
|
||||
select median(score) over (partition by name), percentile_cont(0.5) within group(order by score) over (partition by name) as c from t1;
|
||||
select median(score) over (partition by name), percentile_cont(0.6) within group(order by score) over (partition by name) as c from t1;
|
||||
select median(score) over (partition by name), percentile_cont(0.7) within group(order by score) over (partition by name) as c from t1;
|
||||
select median(score) over (partition by name), percentile_cont(0.8) within group(order by score) over (partition by name) as c from t1;
|
||||
select median(score) over (partition by name), percentile_cont(0.9) within group(order by score) over (partition by name) as c from t1;
|
||||
select median(score) over (partition by name), percentile_cont(1) within group(order by score) over (partition by name) as c from t1;
|
||||
drop table t1;
|
|
@ -354,7 +354,8 @@ public:
|
|||
VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC,
|
||||
ROW_NUMBER_FUNC, RANK_FUNC, DENSE_RANK_FUNC, PERCENT_RANK_FUNC,
|
||||
CUME_DIST_FUNC, NTILE_FUNC, FIRST_VALUE_FUNC, LAST_VALUE_FUNC,
|
||||
NTH_VALUE_FUNC, LEAD_FUNC, LAG_FUNC
|
||||
NTH_VALUE_FUNC, LEAD_FUNC, LAG_FUNC, PERCENTILE_CONT_FUNC,
|
||||
PERCENTILE_DISC_FUNC
|
||||
};
|
||||
|
||||
Item **ref_by; /* pointer to a ref to the object used to register it */
|
||||
|
|
|
@ -108,6 +108,7 @@ Item_window_func::fix_fields(THD *thd, Item **ref)
|
|||
my_error(ER_NO_ORDER_LIST_IN_WINDOW_SPEC, MYF(0), window_func()->func_name());
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: why the last parameter is 'ref' in this call? What if window_func
|
||||
decides to substitute itself for something else and does *ref=.... ?
|
||||
|
@ -168,10 +169,25 @@ void Item_window_func::split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
|
|||
window_func()->setup_caches(thd);
|
||||
}
|
||||
|
||||
bool Item_window_func::check_result_type_of_order_item()
|
||||
{
|
||||
if (only_single_element_order_list())
|
||||
{
|
||||
Item_result rtype= window_spec->order_list->first->item[0]->cmp_type();
|
||||
// TODO (varun) : support date type in percentile_cont function
|
||||
if (rtype != REAL_RESULT && rtype != INT_RESULT &&
|
||||
rtype != DECIMAL_RESULT && rtype != TIME_RESULT)
|
||||
{
|
||||
my_error(ER_WRONG_TYPE_FOR_PERCENTILE_FUNC, MYF(0), window_func()->func_name());
|
||||
return TRUE;
|
||||
}
|
||||
setting_handler_for_percentile_functions(rtype);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
This must be called before attempting to compute the window function values.
|
||||
|
||||
@detail
|
||||
If we attempt to do it in fix_fields(), partition_fields will refer
|
||||
to the original window function arguments.
|
||||
|
@ -194,6 +210,71 @@ void Item_sum_dense_rank::setup_window_func(THD *thd, Window_spec *window_spec)
|
|||
clear();
|
||||
}
|
||||
|
||||
void Item_sum_percentile_disc::setup_window_func(THD *thd, Window_spec *window_spec)
|
||||
{
|
||||
order_item= window_spec->order_list->first->item[0];
|
||||
if (!(value= order_item->get_cache(thd)))
|
||||
return;
|
||||
value->setup(thd, order_item);
|
||||
value->store(order_item);
|
||||
}
|
||||
|
||||
void Item_sum_percentile_cont::setup_window_func(THD *thd, Window_spec *window_spec)
|
||||
{
|
||||
order_item= window_spec->order_list->first->item[0];
|
||||
/* TODO(varun): need to discuss and finalise what type should we
|
||||
return for percentile cont functions
|
||||
*/
|
||||
if (!(ceil_value= order_item->get_cache(thd)))
|
||||
return;
|
||||
ceil_value->setup(thd, order_item);
|
||||
ceil_value->store(order_item);
|
||||
|
||||
if (!(floor_value= order_item->get_cache(thd)))
|
||||
return;
|
||||
floor_value->setup(thd, order_item);
|
||||
floor_value->store(order_item);
|
||||
}
|
||||
bool Item_sum_percentile_cont::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
bool res;
|
||||
res= Item_sum_num::fix_fields(thd, ref);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
switch(args[0]->cmp_type())
|
||||
{
|
||||
case DECIMAL_RESULT:
|
||||
case REAL_RESULT:
|
||||
case INT_RESULT:
|
||||
break;
|
||||
default:
|
||||
my_error(ER_WRONG_TYPE_OF_ARGUMENT, MYF(0), func_name());
|
||||
return TRUE;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
bool Item_sum_percentile_disc::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
bool res;
|
||||
res= Item_sum_num::fix_fields(thd, ref);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
switch(args[0]->cmp_type())
|
||||
{
|
||||
case DECIMAL_RESULT:
|
||||
case REAL_RESULT:
|
||||
case INT_RESULT:
|
||||
break;
|
||||
default:
|
||||
my_error(ER_WRONG_TYPE_OF_ARGUMENT, MYF(0), func_name());
|
||||
return TRUE;
|
||||
}
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
bool Item_sum_dense_rank::add()
|
||||
{
|
||||
if (peer_tracker->check_if_next_group() || first_add)
|
||||
|
|
|
@ -24,6 +24,7 @@ class Window_spec;
|
|||
|
||||
int test_if_group_changed(List<Cached_item> &list);
|
||||
|
||||
|
||||
/* A wrapper around test_if_group_changed */
|
||||
class Group_bound_tracker
|
||||
{
|
||||
|
@ -31,10 +32,10 @@ public:
|
|||
|
||||
Group_bound_tracker(THD *thd, SQL_I_List<ORDER> *list)
|
||||
{
|
||||
for (ORDER *curr = list->first; curr; curr=curr->next)
|
||||
for (ORDER *curr = list->first; curr; curr=curr->next)
|
||||
{
|
||||
Cached_item *tmp= new_Cached_item(thd, curr->item[0], TRUE);
|
||||
group_fields.push_back(tmp);
|
||||
Cached_item *tmp= new_Cached_item(thd, curr->item[0], TRUE);
|
||||
group_fields.push_back(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,6 +573,9 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
|
|||
Item_sum_cume_dist(THD *thd) : Item_sum_window_with_row_count(thd),
|
||||
current_row_count_(0) {}
|
||||
|
||||
Item_sum_cume_dist(THD *thd, Item *arg) : Item_sum_window_with_row_count(thd,arg),
|
||||
current_row_count_(0) {}
|
||||
|
||||
double val_real()
|
||||
{
|
||||
if (get_row_count() == 0)
|
||||
|
@ -618,6 +622,11 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
|
|||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_cume_dist>(thd, mem_root, this); }
|
||||
|
||||
ulonglong get_row_number()
|
||||
{
|
||||
return current_row_count_ ;
|
||||
}
|
||||
|
||||
private:
|
||||
ulonglong current_row_count_;
|
||||
};
|
||||
|
@ -693,6 +702,277 @@ class Item_sum_ntile : public Item_sum_window_with_row_count
|
|||
ulong current_row_count_;
|
||||
};
|
||||
|
||||
class Item_sum_percentile_disc : public Item_sum_cume_dist,
|
||||
public Type_handler_hybrid_field_type
|
||||
{
|
||||
public:
|
||||
Item_sum_percentile_disc(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg),
|
||||
Type_handler_hybrid_field_type(&type_handler_longlong),
|
||||
value(NULL), val_calculated(FALSE), first_call(TRUE),
|
||||
prev_value(0), order_item(NULL){}
|
||||
|
||||
double val_real()
|
||||
{
|
||||
if (get_row_count() == 0 || get_arg(0)->is_null())
|
||||
{
|
||||
null_value= true;
|
||||
return 0;
|
||||
}
|
||||
null_value= false;
|
||||
return value->val_real();
|
||||
}
|
||||
|
||||
longlong val_int()
|
||||
{
|
||||
if (get_row_count() == 0 || get_arg(0)->is_null())
|
||||
{
|
||||
null_value= true;
|
||||
return 0;
|
||||
}
|
||||
null_value= false;
|
||||
return value->val_int();
|
||||
}
|
||||
|
||||
my_decimal* val_decimal(my_decimal* dec)
|
||||
{
|
||||
if (get_row_count() == 0 || get_arg(0)->is_null())
|
||||
{
|
||||
null_value= true;
|
||||
return 0;
|
||||
}
|
||||
null_value= false;
|
||||
return value->val_decimal(dec);
|
||||
}
|
||||
|
||||
String* val_str(String *str)
|
||||
{
|
||||
if (get_row_count() == 0 || get_arg(0)->is_null())
|
||||
{
|
||||
null_value= true;
|
||||
return 0;
|
||||
}
|
||||
null_value= false;
|
||||
return value->val_str(str);
|
||||
}
|
||||
|
||||
bool add()
|
||||
{
|
||||
Item *arg= get_arg(0);
|
||||
if (arg->is_null())
|
||||
return false;
|
||||
|
||||
if (first_call)
|
||||
{
|
||||
prev_value= arg->val_real();
|
||||
if (prev_value > 1 || prev_value < 0)
|
||||
{
|
||||
my_error(ER_ARGUMENT_OUT_OF_RANGE, MYF(0), func_name());
|
||||
return true;
|
||||
}
|
||||
first_call= false;
|
||||
}
|
||||
|
||||
double arg_val= arg->val_real();
|
||||
|
||||
if (prev_value != arg_val)
|
||||
{
|
||||
my_error(ER_ARGUMENT_NOT_CONSTANT, MYF(0), func_name());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val_calculated)
|
||||
return false;
|
||||
|
||||
value->store(order_item);
|
||||
value->cache_value();
|
||||
if (value->null_value)
|
||||
return false;
|
||||
|
||||
Item_sum_cume_dist::add();
|
||||
double val= Item_sum_cume_dist::val_real();
|
||||
|
||||
if (val >= prev_value && !val_calculated)
|
||||
val_calculated= true;
|
||||
return false;
|
||||
}
|
||||
|
||||
enum Sumfunctype sum_func() const
|
||||
{
|
||||
return PERCENTILE_DISC_FUNC;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
val_calculated= false;
|
||||
first_call= true;
|
||||
value->clear();
|
||||
Item_sum_cume_dist::clear();
|
||||
}
|
||||
|
||||
const char*func_name() const
|
||||
{
|
||||
return "percentile_disc";
|
||||
}
|
||||
|
||||
void update_field() {}
|
||||
void set_type_handler(Window_spec *window_spec);
|
||||
const Type_handler *type_handler() const
|
||||
{return Type_handler_hybrid_field_type::type_handler();}
|
||||
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
decimals = 10; // TODO-cvicentiu find out how many decimals the standard
|
||||
// requires.
|
||||
}
|
||||
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_percentile_disc>(thd, mem_root, this); }
|
||||
void setup_window_func(THD *thd, Window_spec *window_spec);
|
||||
void setup_hybrid(THD *thd, Item *item);
|
||||
bool fix_fields(THD *thd, Item **ref);
|
||||
|
||||
private:
|
||||
Item_cache *value;
|
||||
bool val_calculated;
|
||||
bool first_call;
|
||||
double prev_value;
|
||||
Item *order_item;
|
||||
};
|
||||
|
||||
class Item_sum_percentile_cont : public Item_sum_cume_dist,
|
||||
public Type_handler_hybrid_field_type
|
||||
{
|
||||
public:
|
||||
Item_sum_percentile_cont(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg),
|
||||
Type_handler_hybrid_field_type(&type_handler_double),
|
||||
floor_value(NULL), ceil_value(NULL), first_call(TRUE),prev_value(0),
|
||||
ceil_val_calculated(FALSE), floor_val_calculated(FALSE), order_item(NULL){}
|
||||
|
||||
double val_real()
|
||||
{
|
||||
if (get_row_count() == 0 || get_arg(0)->is_null())
|
||||
{
|
||||
null_value= true;
|
||||
return 0;
|
||||
}
|
||||
null_value= false;
|
||||
double val= 1 + prev_value * (get_row_count()-1);
|
||||
|
||||
/*
|
||||
Applying the formula to get the value
|
||||
If (CRN = FRN = RN) then the result is (value of expression from row at RN)
|
||||
Otherwise the result is
|
||||
(CRN - RN) * (value of expression for row at FRN) +
|
||||
(RN - FRN) * (value of expression for row at CRN)
|
||||
*/
|
||||
|
||||
if(ceil(val) == floor(val))
|
||||
return floor_value->val_real();
|
||||
|
||||
double ret_val= ((val - floor(val)) * ceil_value->val_real()) +
|
||||
((ceil(val) - val) * floor_value->val_real());
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
bool add()
|
||||
{
|
||||
Item *arg= get_arg(0);
|
||||
if (arg->is_null())
|
||||
return false;
|
||||
|
||||
if (first_call)
|
||||
{
|
||||
first_call= false;
|
||||
prev_value= arg->val_real();
|
||||
if (prev_value > 1 || prev_value < 0)
|
||||
{
|
||||
my_error(ER_ARGUMENT_OUT_OF_RANGE, MYF(0), func_name());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
double arg_val= arg->val_real();
|
||||
if (prev_value != arg_val)
|
||||
{
|
||||
my_error(ER_ARGUMENT_NOT_CONSTANT, MYF(0), func_name());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!floor_val_calculated)
|
||||
{
|
||||
floor_value->store(order_item);
|
||||
floor_value->cache_value();
|
||||
if (floor_value->null_value)
|
||||
return false;
|
||||
}
|
||||
if (floor_val_calculated && !ceil_val_calculated)
|
||||
{
|
||||
ceil_value->store(order_item);
|
||||
ceil_value->cache_value();
|
||||
if (ceil_value->null_value)
|
||||
return false;
|
||||
}
|
||||
|
||||
Item_sum_cume_dist::add();
|
||||
double val= 1 + prev_value * (get_row_count()-1);
|
||||
|
||||
if (!floor_val_calculated && get_row_number() == floor(val))
|
||||
floor_val_calculated= true;
|
||||
|
||||
if (!ceil_val_calculated && get_row_number() == ceil(val))
|
||||
ceil_val_calculated= true;
|
||||
return false;
|
||||
}
|
||||
|
||||
enum Sumfunctype sum_func() const
|
||||
{
|
||||
return PERCENTILE_CONT_FUNC;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
first_call= true;
|
||||
floor_value->clear();
|
||||
ceil_value->clear();
|
||||
floor_val_calculated= false;
|
||||
ceil_val_calculated= false;
|
||||
Item_sum_cume_dist::clear();
|
||||
}
|
||||
|
||||
const char*func_name() const
|
||||
{
|
||||
return "percentile_cont";
|
||||
}
|
||||
void update_field() {}
|
||||
void set_type_handler(Window_spec *window_spec);
|
||||
const Type_handler *type_handler() const
|
||||
{return Type_handler_hybrid_field_type::type_handler();}
|
||||
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
decimals = 10; // TODO-cvicentiu find out how many decimals the standard
|
||||
// requires.
|
||||
}
|
||||
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_sum_percentile_cont>(thd, mem_root, this); }
|
||||
void setup_window_func(THD *thd, Window_spec *window_spec);
|
||||
void setup_hybrid(THD *thd, Item *item);
|
||||
bool fix_fields(THD *thd, Item **ref);
|
||||
|
||||
private:
|
||||
Item_cache *floor_value;
|
||||
Item_cache *ceil_value;
|
||||
bool first_call;
|
||||
double prev_value;
|
||||
bool ceil_val_calculated;
|
||||
bool floor_val_calculated;
|
||||
Item *order_item;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class Item_window_func : public Item_func_or_sum
|
||||
{
|
||||
|
@ -747,6 +1027,8 @@ public:
|
|||
case Item_sum::PERCENT_RANK_FUNC:
|
||||
case Item_sum::CUME_DIST_FUNC:
|
||||
case Item_sum::NTILE_FUNC:
|
||||
case Item_sum::PERCENTILE_CONT_FUNC:
|
||||
case Item_sum::PERCENTILE_DISC_FUNC:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -773,6 +1055,8 @@ public:
|
|||
case Item_sum::PERCENT_RANK_FUNC:
|
||||
case Item_sum::CUME_DIST_FUNC:
|
||||
case Item_sum::NTILE_FUNC:
|
||||
case Item_sum::PERCENTILE_CONT_FUNC:
|
||||
case Item_sum::PERCENTILE_DISC_FUNC:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -796,12 +1080,40 @@ public:
|
|||
case Item_sum::DENSE_RANK_FUNC:
|
||||
case Item_sum::PERCENT_RANK_FUNC:
|
||||
case Item_sum::CUME_DIST_FUNC:
|
||||
case Item_sum::PERCENTILE_CONT_FUNC:
|
||||
case Item_sum::PERCENTILE_DISC_FUNC:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool only_single_element_order_list() const
|
||||
{
|
||||
switch (window_func()->sum_func()){
|
||||
case Item_sum::PERCENTILE_CONT_FUNC:
|
||||
case Item_sum::PERCENTILE_DISC_FUNC:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void setting_handler_for_percentile_functions(Item_result rtype) const
|
||||
{
|
||||
switch (window_func()->sum_func()){
|
||||
case Item_sum::PERCENTILE_DISC_FUNC:
|
||||
((Item_sum_percentile_disc* ) window_func())->set_handler_by_cmp_type(rtype);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool check_result_type_of_order_item();
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Computation functions.
|
||||
TODO: consoder merging these with class Group_bound_tracker.
|
||||
|
|
|
@ -701,6 +701,7 @@ static SYMBOL symbols[] = {
|
|||
{ "WHILE", SYM(WHILE_SYM)},
|
||||
{ "WINDOW", SYM(WINDOW_SYM)},
|
||||
{ "WITH", SYM(WITH)},
|
||||
{ "WITHIN", SYM(WITHIN)},
|
||||
{ "WORK", SYM(WORK_SYM)},
|
||||
{ "WRAPPER", SYM(WRAPPER_SYM)},
|
||||
{ "WRITE", SYM(WRITE_SYM)},
|
||||
|
@ -736,6 +737,7 @@ static SYMBOL sql_functions[] = {
|
|||
{ "LAG", SYM(LAG_SYM)},
|
||||
{ "LEAD", SYM(LEAD_SYM)},
|
||||
{ "MAX", SYM(MAX_SYM)},
|
||||
{ "MEDIAN", SYM(MEDIAN_SYM)},
|
||||
{ "MID", SYM(SUBSTRING)}, /* unireg function */
|
||||
{ "MIN", SYM(MIN_SYM)},
|
||||
{ "NOW", SYM(NOW_SYM)},
|
||||
|
@ -743,6 +745,8 @@ static SYMBOL sql_functions[] = {
|
|||
{ "NTILE", SYM(NTILE_SYM)},
|
||||
{ "POSITION", SYM(POSITION_SYM)},
|
||||
{ "PERCENT_RANK", SYM(PERCENT_RANK_SYM)},
|
||||
{ "PERCENTILE_CONT", SYM(PERCENTILE_CONT_SYM)},
|
||||
{ "PERCENTILE_DISC", SYM(PERCENTILE_DISC_SYM)},
|
||||
{ "RANK", SYM(RANK_SYM)},
|
||||
{ "ROW_NUMBER", SYM(ROW_NUMBER_SYM)},
|
||||
{ "SESSION_USER", SYM(USER_SYM)},
|
||||
|
|
|
@ -7790,3 +7790,13 @@ ER_WRONG_NUMBER_OF_VALUES_IN_TVC
|
|||
eng "The used table value constructor has a different number of values"
|
||||
ER_FIELD_REFERENCE_IN_TVC
|
||||
eng "Field reference '%-.192s' can't be used in table value constructor"
|
||||
ER_NOT_SINGLE_ELEMENT_ORDER_LIST
|
||||
eng "Incorrect number of elements in the order list for '%s'"
|
||||
ER_WRONG_TYPE_FOR_PERCENTILE_FUNC
|
||||
eng "Numeric datatype is required for %s function"
|
||||
ER_ARGUMENT_NOT_CONSTANT
|
||||
eng "Argument to the %s function is not a constant for a partition"
|
||||
ER_ARGUMENT_OUT_OF_RANGE
|
||||
eng "Argument to the %s function does not belong to the range [0,1]"
|
||||
ER_WRONG_TYPE_OF_ARGUMENT
|
||||
eng "%s function only accepts arguments that can be converted to numerical types"
|
||||
|
|
|
@ -321,6 +321,12 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
|
|||
win_func_item->update_used_tables();
|
||||
}
|
||||
|
||||
li.rewind();
|
||||
while ((win_func_item= li++))
|
||||
{
|
||||
if (win_func_item->check_result_type_of_order_item())
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -968,6 +974,8 @@ private:
|
|||
bool end_of_partition;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
|
@ -1735,7 +1743,17 @@ public:
|
|||
/* Walk to the end of the partition, find how many rows there are. */
|
||||
while (!cursor.next())
|
||||
num_rows_in_partition++;
|
||||
set_win_funcs_row_count(num_rows_in_partition);
|
||||
}
|
||||
|
||||
ha_rows get_curr_rownum() const
|
||||
{
|
||||
return cursor.get_rownum();
|
||||
}
|
||||
|
||||
protected:
|
||||
void set_win_funcs_row_count(ha_rows num_rows_in_partition)
|
||||
{
|
||||
List_iterator_fast<Item_sum> it(sum_functions);
|
||||
Item_sum* item;
|
||||
while ((item= it++))
|
||||
|
@ -1745,11 +1763,43 @@ public:
|
|||
item_with_row_count->set_row_count(num_rows_in_partition);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Frame_unbounded_following_set_count_no_nulls:
|
||||
public Frame_unbounded_following_set_count
|
||||
{
|
||||
|
||||
public:
|
||||
Frame_unbounded_following_set_count_no_nulls(THD *thd,
|
||||
SQL_I_List<ORDER> *partition_list,
|
||||
SQL_I_List<ORDER> *order_list) :
|
||||
Frame_unbounded_following_set_count(thd,partition_list, order_list)
|
||||
{
|
||||
order_item= order_list->first->item[0];
|
||||
}
|
||||
void next_partition(ha_rows rownum)
|
||||
{
|
||||
ha_rows num_rows_in_partition= 0;
|
||||
if (cursor.fetch())
|
||||
return;
|
||||
|
||||
/* Walk to the end of the partition, find how many rows there are. */
|
||||
do
|
||||
{
|
||||
if (!order_item->is_null())
|
||||
num_rows_in_partition++;
|
||||
} while (!cursor.next());
|
||||
|
||||
set_win_funcs_row_count(num_rows_in_partition);
|
||||
}
|
||||
|
||||
ha_rows get_curr_rownum() const
|
||||
{
|
||||
return cursor.get_rownum();
|
||||
}
|
||||
|
||||
private:
|
||||
Item* order_item;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2490,6 +2540,21 @@ void add_special_frame_cursors(THD *thd, Cursor_manager *cursor_manager,
|
|||
cursor_manager->add_cursor(fc);
|
||||
break;
|
||||
}
|
||||
case Item_sum::PERCENTILE_CONT_FUNC:
|
||||
case Item_sum::PERCENTILE_DISC_FUNC:
|
||||
{
|
||||
fc= new Frame_unbounded_preceding(thd,
|
||||
spec->partition_list,
|
||||
spec->order_list);
|
||||
fc->add_sum_func(item_sum);
|
||||
cursor_manager->add_cursor(fc);
|
||||
fc= new Frame_unbounded_following(thd,
|
||||
spec->partition_list,
|
||||
spec->order_list);
|
||||
fc->add_sum_func(item_sum);
|
||||
cursor_manager->add_cursor(fc);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fc= new Frame_unbounded_preceding(
|
||||
thd, spec->partition_list, spec->order_list);
|
||||
|
@ -2514,6 +2579,8 @@ static bool is_computed_with_remove(Item_sum::Sumfunctype sum_func)
|
|||
case Item_sum::NTILE_FUNC:
|
||||
case Item_sum::FIRST_VALUE_FUNC:
|
||||
case Item_sum::LAST_VALUE_FUNC:
|
||||
case Item_sum::PERCENTILE_CONT_FUNC:
|
||||
case Item_sum::PERCENTILE_DISC_FUNC:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
|
@ -2544,9 +2611,18 @@ void get_window_functions_required_cursors(
|
|||
*/
|
||||
if (item_win_func->requires_partition_size())
|
||||
{
|
||||
fc= new Frame_unbounded_following_set_count(thd,
|
||||
if (item_win_func->only_single_element_order_list())
|
||||
{
|
||||
fc= new Frame_unbounded_following_set_count_no_nulls(thd,
|
||||
item_win_func->window_spec->partition_list,
|
||||
item_win_func->window_spec->order_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
fc= new Frame_unbounded_following_set_count(thd,
|
||||
item_win_func->window_spec->partition_list,
|
||||
item_win_func->window_spec->order_list);
|
||||
}
|
||||
fc->add_sum_func(sum_func);
|
||||
cursor_manager->add_cursor(fc);
|
||||
}
|
||||
|
@ -2727,6 +2803,13 @@ bool compute_window_func(THD *thd,
|
|||
{
|
||||
cursor_manager->notify_cursors_next_row();
|
||||
}
|
||||
|
||||
/* Check if we found any error in the window function while adding values
|
||||
through cursors. */
|
||||
if (thd->is_error() || thd->is_killed())
|
||||
break;
|
||||
|
||||
|
||||
/* Return to current row after notifying cursors for each window
|
||||
function. */
|
||||
tbl->file->ha_rnd_pos(tbl->record[0], rowid_buf);
|
||||
|
|
|
@ -1237,6 +1237,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token MAX_STATEMENT_TIME_SYM
|
||||
%token MAX_USER_CONNECTIONS_SYM
|
||||
%token MAXVALUE_SYM /* SQL-2003-N */
|
||||
%token MEDIAN_SYM
|
||||
%token MEDIUMBLOB
|
||||
%token MEDIUMINT
|
||||
%token MEDIUMTEXT
|
||||
|
@ -1329,6 +1330,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token PARTITIONING_SYM
|
||||
%token PASSWORD_SYM
|
||||
%token PERCENT_RANK_SYM
|
||||
%token PERCENTILE_CONT_SYM
|
||||
%token PERCENTILE_DISC_SYM
|
||||
%token PERSISTENT_SYM
|
||||
%token PHASE_SYM
|
||||
%token PLUGINS_SYM
|
||||
|
@ -1577,6 +1580,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token WINDOW_SYM
|
||||
%token WHILE_SYM
|
||||
%token WITH /* SQL-2003-R */
|
||||
%token WITHIN
|
||||
%token WITH_CUBE_SYM /* INTERNAL */
|
||||
%token WITH_ROLLUP_SYM /* INTERNAL */
|
||||
%token WORK_SYM /* SQL-2003-N */
|
||||
|
@ -1736,6 +1740,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
window_func_expr
|
||||
window_func
|
||||
simple_window_func
|
||||
inverse_distribution_function
|
||||
percentile_function
|
||||
inverse_distribution_function_def
|
||||
function_call_keyword
|
||||
function_call_nonkeyword
|
||||
function_call_generic
|
||||
|
@ -1958,7 +1965,6 @@ END_OF_INPUT
|
|||
|
||||
%type <spvar_definition> row_field_name row_field_definition
|
||||
%type <spvar_definition_list> row_field_definition_list row_type_body
|
||||
|
||||
%type <NONE> opt_window_clause window_def_list window_def window_spec
|
||||
%type <lex_str_ptr> window_name
|
||||
%type <NONE> opt_window_ref opt_window_frame_clause
|
||||
|
@ -9411,6 +9417,7 @@ column_default_non_parenthesized_expr:
|
|||
| variable
|
||||
| sum_expr
|
||||
| window_func_expr
|
||||
| inverse_distribution_function
|
||||
| ROW_SYM '(' expr ',' expr_list ')'
|
||||
{
|
||||
$5->push_front($3, thd->mem_root);
|
||||
|
@ -10269,6 +10276,11 @@ geometry_function:
|
|||
Geometry::wkb_polygon,
|
||||
Geometry::wkb_linestring));
|
||||
}
|
||||
| WITHIN '(' expr ',' expr ')'
|
||||
{
|
||||
$$= GEOM_NEW(thd, Item_func_spatial_precise_rel(thd, $3, $5,
|
||||
Item_func::SP_WITHIN_FUNC));
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
|
@ -10730,6 +10742,71 @@ simple_window_func:
|
|||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
inverse_distribution_function:
|
||||
percentile_function OVER_SYM
|
||||
'(' opt_window_partition_clause ')'
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (Select->add_window_spec(thd, lex->win_ref,
|
||||
Select->group_list,
|
||||
Select->order_list,
|
||||
NULL))
|
||||
MYSQL_YYABORT;
|
||||
$$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1,
|
||||
thd->lex->win_spec);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
if (Select->add_window_func((Item_window_func *) $$))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
percentile_function:
|
||||
inverse_distribution_function_def WITHIN GROUP_SYM '('
|
||||
{ Select->prepare_add_window_spec(thd); }
|
||||
order_by_single_element_list ')'
|
||||
{
|
||||
$$= $1;
|
||||
}
|
||||
| MEDIAN_SYM '(' expr ')'
|
||||
{
|
||||
Item *args= new (thd->mem_root) Item_decimal(thd, "0.5", 3,
|
||||
thd->charset());
|
||||
if (($$ == NULL) || (thd->is_error()))
|
||||
{
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
if (add_order_to_list(thd, $3,FALSE)) MYSQL_YYABORT;
|
||||
|
||||
$$= new (thd->mem_root) Item_sum_percentile_cont(thd, args);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
inverse_distribution_function_def:
|
||||
PERCENTILE_CONT_SYM '(' expr ')'
|
||||
{
|
||||
$$= new (thd->mem_root) Item_sum_percentile_cont(thd, $3);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| PERCENTILE_DISC_SYM '(' expr ')'
|
||||
{
|
||||
$$= new (thd->mem_root) Item_sum_percentile_disc(thd, $3);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
order_by_single_element_list:
|
||||
ORDER_SYM BY order_ident order_dir
|
||||
{ if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; }
|
||||
;
|
||||
|
||||
|
||||
window_name:
|
||||
ident
|
||||
{
|
||||
|
@ -14665,6 +14742,7 @@ keyword:
|
|||
| UNICODE_SYM {}
|
||||
| UNINSTALL_SYM {}
|
||||
| UNBOUNDED_SYM {}
|
||||
| WITHIN {}
|
||||
| WRAPPER_SYM {}
|
||||
| XA_SYM {}
|
||||
| UPGRADE_SYM {}
|
||||
|
|
|
@ -645,6 +645,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token MAX_STATEMENT_TIME_SYM
|
||||
%token MAX_USER_CONNECTIONS_SYM
|
||||
%token MAXVALUE_SYM /* SQL-2003-N */
|
||||
%token MEDIAN_SYM
|
||||
%token MEDIUMBLOB
|
||||
%token MEDIUMINT
|
||||
%token MEDIUMTEXT
|
||||
|
@ -737,6 +738,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token PARTITIONING_SYM
|
||||
%token PASSWORD_SYM
|
||||
%token PERCENT_RANK_SYM
|
||||
%token PERCENTILE_CONT_SYM
|
||||
%token PERCENTILE_DISC_SYM
|
||||
%token PERSISTENT_SYM
|
||||
%token PHASE_SYM
|
||||
%token PLUGINS_SYM
|
||||
|
@ -983,6 +986,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token WINDOW_SYM
|
||||
%token WHILE_SYM
|
||||
%token WITH /* SQL-2003-R */
|
||||
%token WITHIN
|
||||
%token WITH_CUBE_SYM /* INTERNAL */
|
||||
%token WITH_ROLLUP_SYM /* INTERNAL */
|
||||
%token WORK_SYM /* SQL-2003-N */
|
||||
|
@ -1147,6 +1151,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
window_func_expr
|
||||
window_func
|
||||
simple_window_func
|
||||
inverse_distribution_function
|
||||
percentile_function
|
||||
inverse_distribution_function_def
|
||||
explicit_cursor_attr
|
||||
function_call_keyword
|
||||
function_call_nonkeyword
|
||||
|
@ -9389,6 +9396,7 @@ column_default_non_parenthesized_expr:
|
|||
| variable
|
||||
| sum_expr
|
||||
| window_func_expr
|
||||
| inverse_distribution_function
|
||||
| ROW_SYM '(' expr ',' expr_list ')'
|
||||
{
|
||||
$5->push_front($3, thd->mem_root);
|
||||
|
@ -10717,6 +10725,67 @@ simple_window_func:
|
|||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
inverse_distribution_function:
|
||||
percentile_function OVER_SYM
|
||||
'(' opt_window_partition_clause ')'
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (Select->add_window_spec(thd, lex->win_ref,
|
||||
Select->group_list,
|
||||
Select->order_list,
|
||||
NULL))
|
||||
MYSQL_YYABORT;
|
||||
$$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1,
|
||||
thd->lex->win_spec);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
if (Select->add_window_func((Item_window_func *) $$))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
percentile_function:
|
||||
inverse_distribution_function_def WITHIN GROUP_SYM '('
|
||||
{ Select->prepare_add_window_spec(thd); }
|
||||
order_by_single_element_list ')'
|
||||
{
|
||||
$$= $1;
|
||||
}
|
||||
| MEDIAN_SYM '(' expr ')'
|
||||
{
|
||||
Item *args= new (thd->mem_root) Item_decimal(thd, "0.5", 3,
|
||||
thd->charset());
|
||||
if (($$ == NULL) || (thd->is_error()))
|
||||
{
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
if (add_order_to_list(thd, $3,FALSE)) MYSQL_YYABORT;
|
||||
|
||||
$$= new (thd->mem_root) Item_sum_percentile_cont(thd, args);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
inverse_distribution_function_def:
|
||||
PERCENTILE_CONT_SYM '(' expr ')'
|
||||
{
|
||||
$$= new (thd->mem_root) Item_sum_percentile_cont(thd, $3);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| PERCENTILE_DISC_SYM '(' expr ')'
|
||||
{
|
||||
$$= new (thd->mem_root) Item_sum_percentile_disc(thd, $3);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
order_by_single_element_list:
|
||||
ORDER_SYM BY order_ident order_dir
|
||||
{ if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; }
|
||||
;
|
||||
|
||||
window_name:
|
||||
ident
|
||||
|
@ -14703,6 +14772,7 @@ keyword_directly_assignable:
|
|||
| UNICODE_SYM {}
|
||||
| UNINSTALL_SYM {}
|
||||
| UNBOUNDED_SYM {}
|
||||
| WITHIN {}
|
||||
| WRAPPER_SYM {}
|
||||
| XA_SYM {}
|
||||
| UPGRADE_SYM {}
|
||||
|
|
Loading…
Reference in a new issue