summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2016-04-04 22:03:50 +0300
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2016-04-04 22:04:18 +0300
commit960b221c0bb4a35fd59d80b114f1833d51040cca (patch)
tree915403c7d671219d7254ef87b6b271dcf211c4bc
parentbe3902fceba95254d13e0f74741c3fa2d4a0c9f4 (diff)
downloadmariadb-git-960b221c0bb4a35fd59d80b114f1833d51040cca.tar.gz
Convert ntile to work with expressions as parameters.
-rw-r--r--mysql-test/r/win_ntile.result75
-rw-r--r--mysql-test/t/win_ntile.test24
-rw-r--r--sql/item_windowfunc.h29
-rw-r--r--sql/sql_yacc.yy7
4 files changed, 126 insertions, 9 deletions
diff --git a/mysql-test/r/win_ntile.result b/mysql-test/r/win_ntile.result
index c403e2937e6..41cb1a594bf 100644
--- a/mysql-test/r/win_ntile.result
+++ b/mysql-test/r/win_ntile.result
@@ -357,4 +357,79 @@ pk a b ntile(20) over (partition by b order by pk)
17 2 20 3
19 4 20 4
20 4 20 5
+select pk, a, b,
+ntile(1 + 3) over (partition by b order by pk)
+from t1;
+pk a b ntile(1 + 3) over (partition by b order by pk)
+11 0 10 1
+12 0 10 1
+13 1 10 2
+14 1 10 3
+18 2 10 4
+15 2 20 1
+16 2 20 1
+17 2 20 2
+19 4 20 3
+20 4 20 4
+select pk, a, b,
+ntile((select 4)) over (partition by b order by pk)
+from t1;
+pk a b ntile((select 4)) over (partition by b order by pk)
+11 0 10 1
+12 0 10 1
+13 1 10 2
+14 1 10 3
+18 2 10 4
+15 2 20 1
+16 2 20 1
+17 2 20 2
+19 4 20 3
+20 4 20 4
+select t1.a from t1 where pk = 11;
+a
+0
+select pk, a, b,
+ntile((select a from t1 where pk=11)) over (partition by b order by pk)
+from t1;
+ERROR HY000: Argument of NTILE must be greater than 0
+select t1.a from t1 where pk = 13;
+a
+1
+select pk, a, b,
+ntile((select a from t1 where pk=13)) over (partition by b order by pk)
+from t1;
+pk a b ntile((select a from t1 where pk=13)) over (partition by b order by pk)
+11 0 10 1
+12 0 10 1
+13 1 10 1
+14 1 10 1
+18 2 10 1
+15 2 20 1
+16 2 20 1
+17 2 20 1
+19 4 20 1
+20 4 20 1
+explain
+select pk, a, b,
+ntile((select a from t1 where pk=13)) over (partition by b order by pk)
+from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using temporary
+2 SUBQUERY t1 const PRIMARY PRIMARY 4 const 1
+select a from t1;
+a
+0
+0
+1
+1
+2
+2
+2
+2
+4
+4
+select pk, a, b,
+ntile((select a from t1)) over (partition by b order by pk)
+from t1;
+ERROR 21000: Subquery returns more than 1 row
drop table t1;
diff --git a/mysql-test/t/win_ntile.test b/mysql-test/t/win_ntile.test
index 0a6efa91c91..6f12e1f4005 100644
--- a/mysql-test/t/win_ntile.test
+++ b/mysql-test/t/win_ntile.test
@@ -137,11 +137,35 @@ select pk, a, b,
ntile(20) over (partition by b order by pk)
from t1;
+select pk, a, b,
+ ntile(1 + 3) over (partition by b order by pk)
+from t1;
+select pk, a, b,
+ ntile((select 4)) over (partition by b order by pk)
+from t1;
+select t1.a from t1 where pk = 11;
+--error ER_INVALID_NTILE_ARGUMENT
+select pk, a, b,
+ ntile((select a from t1 where pk=11)) over (partition by b order by pk)
+from t1;
+select t1.a from t1 where pk = 13;
+select pk, a, b,
+ ntile((select a from t1 where pk=13)) over (partition by b order by pk)
+from t1;
+explain
+select pk, a, b,
+ ntile((select a from t1 where pk=13)) over (partition by b order by pk)
+from t1;
+select a from t1;
+--error ER_SUBQUERY_NO_1_ROW
+select pk, a, b,
+ ntile((select a from t1)) over (partition by b order by pk)
+from t1;
drop table t1;
diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h
index 215ceb14aa7..4c7ca793cd1 100644
--- a/sql/item_windowfunc.h
+++ b/sql/item_windowfunc.h
@@ -235,7 +235,10 @@ class Item_sum_window_with_row_count : public Item_sum_num
{
public:
Item_sum_window_with_row_count(THD *thd) : Item_sum_num(thd),
- partition_row_count_(0){}
+ partition_row_count_(0) {}
+
+ Item_sum_window_with_row_count(THD *thd, Item *arg) :
+ Item_sum_num(thd, arg), partition_row_count_(0) {};
void set_row_count(ulonglong count) { partition_row_count_ = count; }
@@ -398,8 +401,9 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
class Item_sum_ntile : public Item_sum_window_with_row_count
{
public:
- Item_sum_ntile(THD* thd, ulong num_quantiles) :
- Item_sum_window_with_row_count(thd), num_quantiles_(num_quantiles),
+ Item_sum_ntile(THD* thd, Item* num_quantiles_expr) :
+ Item_sum_window_with_row_count(thd, num_quantiles_expr),
+ num_quantiles_expr_(num_quantiles_expr), num_quantiles_(0),
current_row_count_(0) {};
double val_real()
@@ -451,7 +455,26 @@ class Item_sum_ntile : public Item_sum_window_with_row_count
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
+ bool fix_fields(THD *thd, Item **ref)
+ {
+ if (Item_sum_window_with_row_count::fix_fields(thd, ref))
+ return true;
+ // TODO-cvicentiu is ref as a parameter here ok?
+ if (!num_quantiles_expr_->fixed)
+ num_quantiles_expr_->fix_fields(thd, ref);
+ longlong expr_value= num_quantiles_expr_->val_int();
+
+ if (expr_value <= 0) {
+ my_error(ER_INVALID_NTILE_ARGUMENT, MYF(0));
+ return true;
+ }
+
+ num_quantiles_= static_cast<ulong>(expr_value);
+ return false;
+ }
+
private:
+ Item* num_quantiles_expr_;
ulong num_quantiles_;
ulong current_row_count_;
};
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 25416100fb3..5e1f5dc5058 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -10541,13 +10541,8 @@ simple_window_func:
MYSQL_YYABORT;
}
|
- NTILE_SYM '(' int_num ')'
+ NTILE_SYM '(' expr ')'
{
- if ($3 <= 0)
- {
- my_error(ER_INVALID_NTILE_ARGUMENT, MYF(0));
- MYSQL_YYABORT;
- }
$$= new (thd->mem_root) Item_sum_ntile(thd, $3);
if ($$ == NULL)
MYSQL_YYABORT;