diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2016-04-04 22:03:50 +0300 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2016-04-04 22:04:18 +0300 |
commit | 960b221c0bb4a35fd59d80b114f1833d51040cca (patch) | |
tree | 915403c7d671219d7254ef87b6b271dcf211c4bc | |
parent | be3902fceba95254d13e0f74741c3fa2d4a0c9f4 (diff) | |
download | mariadb-git-960b221c0bb4a35fd59d80b114f1833d51040cca.tar.gz |
Convert ntile to work with expressions as parameters.
-rw-r--r-- | mysql-test/r/win_ntile.result | 75 | ||||
-rw-r--r-- | mysql-test/t/win_ntile.test | 24 | ||||
-rw-r--r-- | sql/item_windowfunc.h | 29 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 7 |
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; |