From e9ae53cc7e3dc54f11fdfb9cfbbd55fd2dbe7d01 Mon Sep 17 00:00:00 2001 From: Zhe Dong Date: Wed, 14 Oct 2015 13:23:22 -0400 Subject: [PATCH 1/2] Added 'grouping' function creator --- sql/item_create.cc | 20 ++++++++++++++++++++ sql/item_func.h | 17 ++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/sql/item_create.cc b/sql/item_create.cc index 0866256..7cf5b6e 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -2003,6 +2003,17 @@ class Create_func_greatest : public Create_native_func virtual ~Create_func_greatest() {} }; +class Create_func_grouping : public Create_func_arg1 +{ +public: + virtual Item *create(THD *thd, Item *arg1); + + static Create_func_grouping s_singleton; + +protected: + Create_func_grouping() {} + virtual ~Create_func_grouping() {} +}; class Create_func_gtid_subtract : public Create_func_arg2 { @@ -5428,6 +5439,14 @@ Create_func_greatest::create_native(THD *thd, LEX_STRING name, return new (thd->mem_root) Item_func_max(POS(), item_list); } +Create_func_grouping Create_func_grouping::s_singleton; + +Item* +Create_func_grouping::create(THD *thd, Item *arg1) +{ + return new (thd->mem_root) Item_func_grouping(arg1); +} + Create_func_gtid_subtract Create_func_gtid_subtract::s_singleton; @@ -7502,6 +7521,7 @@ static Native_func_registry func_array[] = { { C_STRING_WITH_LEN("GET_LOCK") }, BUILDER(Create_func_get_lock)}, { { C_STRING_WITH_LEN("GLENGTH") }, GEOM_BUILDER(Create_func_glength_deprecated)}, { { C_STRING_WITH_LEN("GREATEST") }, BUILDER(Create_func_greatest)}, + { { C_STRING_WITH_LEN("GROUPING") }, BUILDER(Create_func_grouping)}, { { C_STRING_WITH_LEN("GTID_SUBTRACT") }, BUILDER(Create_func_gtid_subtract) }, { { C_STRING_WITH_LEN("GTID_SUBSET") }, BUILDER(Create_func_gtid_subset) }, { { C_STRING_WITH_LEN("HEX") }, BUILDER(Create_func_hex)}, diff --git a/sql/item_func.h b/sql/item_func.h index a9c9726..21d2654 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -67,7 +67,7 @@ class Item_func :public Item_result_field NOW_FUNC, TRIG_COND_FUNC, SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, EXTRACT_FUNC, TYPECAST_FUNC, FUNC_SP, UDF_FUNC, - NEG_FUNC, GSYSVAR_FUNC }; + NEG_FUNC, GSYSVAR_FUNC, GROUPING_FUNC }; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL, OPTIMIZE_EQUAL }; enum Type type() const { return FUNC_ITEM; } @@ -1376,6 +1376,21 @@ class Item_func_max :public Item_func_min_max const char *func_name() const { return "greatest"; } }; +/* + Objects of this class are used as markers in ROLLUP queries + they get replaced by a literal int of 1 or 0 depending on + if the row is a subtotal +*/ +class Item_func_grouping :public Item_int_func +{ + int level; +public: + Item_func_grouping(Item *a) :Item_int_func(a), level(0) {} + Item *column() { return args[0]; } + const char *func_name() const { return "grouping"; } + enum Functype functype() const { return GROUPING_FUNC; } + longlong val_int() { return level; } +}; /* Objects of this class are used for ROLLUP queries to wrap up From d407a88f7001a447dcff4e039832a700a5ad18a9 Mon Sep 17 00:00:00 2001 From: Zhe Dong Date: Sat, 24 Oct 2015 01:05:21 -0400 Subject: [PATCH 2/2] grouping() function added and working. --- sql/item.h | 3 ++- sql/item_create.cc | 2 +- sql/item_func.cc | 20 ++++++++++++++++++++ sql/item_func.h | 12 +++++------- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/sql/item.h b/sql/item.h index 820b637..07cbd20 100644 --- a/sql/item.h +++ b/sql/item.h @@ -766,7 +766,7 @@ class Item : public Parse_tree_node SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER, PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM, XPATH_NODESET, XPATH_NODESET_CMP, - VIEW_FIXER_ITEM}; + VIEW_FIXER_ITEM, NULL_RESULT_ITEM}; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; @@ -2959,6 +2959,7 @@ class Item_null_result :public Item_null Item_result result_type() const { return res_type; } bool check_gcol_func_processor(uchar *int_arg) { return true; } + enum Type type() const { return NULL_RESULT_ITEM; } }; /* Item represents one placeholder ('?') of prepared statement */ diff --git a/sql/item_create.cc b/sql/item_create.cc index 7cf5b6e..9262b5b 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -5444,7 +5444,7 @@ Create_func_grouping Create_func_grouping::s_singleton; Item* Create_func_grouping::create(THD *thd, Item *arg1) { - return new (thd->mem_root) Item_func_grouping(arg1); + return new (thd->mem_root) Item_func_grouping(POS(), arg1); } diff --git a/sql/item_func.cc b/sql/item_func.cc index 81e2634..ca73a4c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3844,6 +3844,26 @@ my_decimal *Item_func_min_max::val_decimal(my_decimal *dec) return res; } +longlong Item_func_grouping::val_int() +{ + /* + Note: if the current input argument is an 'Item_null_result', + then we know it is generated by rollup handler to fill the + subtotal rows. See also the definition of 'Item_null_result' + and 'Item_ref' + */ + Item *real_item = args[0]; + while (real_item->type() == REF_ITEM) + { + real_item = *((static_cast(real_item))->ref); + } + if (real_item->type() == NULL_RESULT_ITEM) + { + return 1LL; + } + return 0LL; +} + double Item_func_rollup_const::val_real() { DBUG_ASSERT(fixed == 1); diff --git a/sql/item_func.h b/sql/item_func.h index 21d2654..61a42ae 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1377,19 +1377,17 @@ class Item_func_max :public Item_func_min_max }; /* - Objects of this class are used as markers in ROLLUP queries - they get replaced by a literal int of 1 or 0 depending on - if the row is a subtotal + GROUPING function is used in ROLLUP queries, they return + int 1 or 0 depending on if the row is a subtotal of a + specific column. */ class Item_func_grouping :public Item_int_func { - int level; public: - Item_func_grouping(Item *a) :Item_int_func(a), level(0) {} - Item *column() { return args[0]; } + Item_func_grouping(const POS &pos, Item *a) :Item_int_func(pos, a){} const char *func_name() const { return "grouping"; } enum Functype functype() const { return GROUPING_FUNC; } - longlong val_int() { return level; } + longlong val_int(); }; /*