-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
MDEV-22269 GROUPING function #5314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -837,6 +837,49 @@ String *Item_int_func::val_str(String *str) | |
| } | ||
|
|
||
|
|
||
| bool Item_func_grouping::setup_rollup(THD *thd, ORDER *group_list, | ||
| uint send_group_parts) | ||
| { | ||
| if (!(min_rollup_levels= thd->alloc<uint>(arg_count))) | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| for (uint i= 0; i < arg_count; i++) | ||
| { | ||
| uint gp= 0; | ||
| ORDER *g; | ||
| for (g= group_list; g; g= g->next, gp++) | ||
| { | ||
| if (args[i]->eq(*g->item, 0)) | ||
| break; | ||
| } | ||
| if (!g) | ||
| { | ||
| my_error(ER_FIELD_IN_GROUPING_NOT_GROUP_BY, MYF(0), | ||
| args[i]->full_name()); | ||
| return true; | ||
| } | ||
| min_rollup_levels[i]= gp; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
|
|
||
| longlong Item_func_grouping::val_int() | ||
| { | ||
| longlong result= 0; | ||
| for (uint i= 0; i < arg_count; i++) | ||
| { | ||
| if (current_level <= min_rollup_levels[i]) | ||
| { | ||
| result+= 1ULL << (arg_count - i - 1); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
|
Comment on lines
+870
to
+881
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To ensure defensive programming and avoid potential null pointer dereferences (e.g., if longlong Item_func_grouping::val_int()
{
if (!min_rollup_levels)
return 0;
ulonglong result= 0;
for (uint i= 0; i < arg_count; i++)
{
if (current_level <= min_rollup_levels[i])
{
result|= 1ULL << (arg_count - i - 1);
}
}
return (longlong) result;
} |
||
|
|
||
| bool Item_func_connection_id::fix_length_and_dec(THD *thd) | ||
| { | ||
| if (Item_long_func::fix_length_and_dec(thd)) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -109,7 +109,8 @@ class Item_func :public Item_func_or_sum | |
| JSON_EXTRACT_FUNC, JSON_VALID_FUNC, ROWNUM_FUNC, | ||
| CASE_SEARCHED_FUNC, // Used by ColumnStore/Spider | ||
| CASE_SIMPLE_FUNC, // Used by ColumnStore/spider, | ||
| DATE_FUNC, YEAR_FUNC, SUBSTR_FUNC, LEFT_FUNC | ||
| DATE_FUNC, YEAR_FUNC, SUBSTR_FUNC, LEFT_FUNC, | ||
| GROUPING_FUNC | ||
| }; | ||
|
|
||
| /* | ||
|
|
@@ -1330,6 +1331,32 @@ class Item_int_func :public Item_func | |
| }; | ||
|
|
||
|
|
||
| class Item_func_grouping final : public Item_int_func | ||
| { | ||
| uint *min_rollup_levels; | ||
| uint current_level; | ||
|
|
||
| public: | ||
| Item_func_grouping(THD *thd, List<Item> &args) : Item_int_func(thd, args) {} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The member variables Item_func_grouping(THD *thd, List<Item> &args)
: Item_int_func(thd, args), min_rollup_levels(NULL), current_level(0) {} |
||
|
|
||
| bool setup_rollup(THD *thd, ORDER *group_list, uint send_group_parts); | ||
| void set_current_rollup_level(uint level) { current_level= level; } | ||
| longlong val_int() override; | ||
| const Type_handler *type_handler() const override | ||
| { return &type_handler_slonglong; } | ||
| enum Functype functype() const override { return GROUPING_FUNC; } | ||
| LEX_CSTRING func_name_cstring() const override | ||
| { | ||
| static LEX_CSTRING sum_name= {STRING_WITH_LEN("grouping") }; | ||
| return sum_name; | ||
| } | ||
|
|
||
| protected: | ||
| Item *shallow_copy(THD *thd) const override | ||
| { return get_item_copy<Item_func_grouping>(thd, this); } | ||
| }; | ||
|
|
||
|
|
||
| class Item_long_func: public Item_int_func | ||
| { | ||
| public: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
GROUPING()function returns a 64-bit integer bitmask. Ifarg_countexceeds 64, constructing the bitmask inval_int()will cause undefined behavior due to shifting by 64 or more bits (e.g.,1ULL << (arg_count - i - 1)). To prevent this, please add a check to limit the number of arguments to at most 64.