MDEV-22269 GROUPING function - #5314
Conversation
|
Note: |
There was a problem hiding this comment.
Code Review
This pull request implements the SQL GROUPING() function, introducing the Item_func_grouping class, adding parser support for the GROUPING keyword, and integrating it with rollup processing. The feedback highlights critical safety improvements: initializing member variables in the Item_func_grouping constructor to prevent undefined behavior, limiting the number of arguments to 64 to avoid bit-shifting overflow, and adding a null-pointer check along with using bitwise OR operations in val_int() for safer bitmask construction.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
257f8c9 to
b1721fd
Compare
|
I created https://jira.mariadb.org/browse/MDEV-40611 |
f635cc0 to
7011078
Compare
ca4106a to
597b361
Compare
gkodinov
left a comment
There was a problem hiding this comment.
Thanks for your work. This is a preliminary review.
Couple of formal things to fix:
- rebase and resolve the merge conflicts please
- squash the two separate commits into a single one (or state the reason for having tw o commits instead of one)
- fix the P_S digest failures, e.g.
perfschema.start_server_low_digest_sql_length w17 [ fail ]
Test ended at 2026-08-10 23:46:51
CURRENT_TEST: perfschema.start_server_low_digest_sql_length
--- /home/buildbot/amd64-msan-clang-20/build/mysql-test/suite/perfschema/r/start_server_low_digest_sql_length.result 2026-08-10 23:25:32.000000000 +0000
+++ /home/buildbot/amd64-msan-clang-20/build/mysql-test/suite/perfschema/r/start_server_low_digest_sql_length.reject 2026-08-10 23:46:51.017149385 +0000
@@ -8,5 +8,5 @@
####################################
SELECT event_name, digest, digest_text, sql_text FROM events_statements_history_long;
event_name digest digest_text sql_text
-statement/sql/select bc85fb4e8188bed1c842f764ec9fb06a SELECT ? + ? + SELECT ...
-statement/sql/truncate 208418d9203df0b1b2cadb4d7196ea77 TRUNCATE TABLE truncat...
+statement/sql/select 2490fb0602b2ad29d2adc5923c6be917 SELECT ? + ? + SELECT ...
+statement/sql/truncate 8460b8b5a83d4357fcb94a1ccbb54817 TRUNCATE TABLE truncat...
597b361 to
4703752
Compare
gkodinov
left a comment
There was a problem hiding this comment.
Either fix everything that there is to fix in this one or keep it in "draft" until you do please.
There's still two commits, unresolved conflicts and spurious errors in buildbot.
4703752 to
13342cc
Compare
|
Sorry about that, I've resolved the merge conflicts and fixed the digest failures. the reason I have two commits is purely for attribution purposes: the first commit contains only test cases pulled from mysql, and the second commit contains my actual contributions |
gkodinov
left a comment
There was a problem hiding this comment.
I'd expand a little bit on the commit comments. Otherwise, LGTM.
Tests for the GROUPING() function taken from mysql-test/t/olap.test
SQL:2008 feature T431
13342cc to
3003500
Compare
| empty grouping set. Rollup level is set to 0 so that GROUPING() behaves | ||
| correctly. | ||
| */ | ||
| rollup_set_level(0); |
There was a problem hiding this comment.
you also need a complimentary join->rollup_set_level(0); in the send_row_on_empty_set() branch of do_select()
Add this to test
CREATE TABLE t1 (a INT PRIMARY KEY); INSERT INTO t1 VALUES (1);
SELECT a, GROUPING(a) FROM t1 WHERE a=1 AND rand() > 2 GROUP BY a WITH ROLLUP;
| if (Item_func::fix_fields(thd, ref)) | ||
| return true; | ||
|
|
||
| // longlong is 64 bits, so we can represent a maximum of 64 arguments |
There was a problem hiding this comment.
actually, longlong is 63 bits + sign bit. hint. hint.
There was a problem hiding this comment.
does the sign bit not count? MySQL does this, so that if you have all 64 arguments activated the value of GROUPING is -1
There was a problem hiding this comment.
Does it work with 64 args? I can see it working for 63.
There was a problem hiding this comment.
It works for 64, added a test to confirm this
|
|
||
| longlong Item_func_grouping::val_int() | ||
| { | ||
| if (!min_rollup_levels) |
There was a problem hiding this comment.
Is this the right thing to do here? We are trying to extract a value out a function that isn't resolved.
|
|
||
| bool Item_func_grouping::resolve_args(THD *thd, ORDER *group_list) | ||
| { | ||
| if (!(min_rollup_levels= thd->alloc<uint>(arg_count))) |
There was a problem hiding this comment.
This is allocated on execution memory. Is the first allocation freed before, say, second execution of a prepared statement?
There was a problem hiding this comment.
I'm not really sure. I thought allocating on the mem_root arena was standard for stuff like this, from just looking around the code.
|
|
||
| # Test with prepared statements | ||
| PREPARE ps FROM "SELECT a FROM t1 GROUP BY a WITH ROLLUP HAVING GROUPING(a)=0"; | ||
| EXECUTE ps; |
| EXECUTE ps; | ||
| PREPARE ps FROM | ||
| "SELECT a FROM t1 GROUP BY a WITH ROLLUP HAVING GROUPING(a)=1"; | ||
| EXECUTE ps; |
There was a problem hiding this comment.
+EXECUTE PS;
+DEALLOCATE PREPARE ps;
There was a problem hiding this comment.
Or for a single execution -EXECUTE IMMEDIATE .. that doesn't need deallocation.
| SELECT EXISTS (SELECT t0.x FROM t0 a WHERE 1=0 GROUP BY a.x WITH ROLLUP) AS e | ||
| FROM t0; | ||
| DROP TABLE t0; | ||
|
|
There was a problem hiding this comment.
please add a condition pushdown test, like this
SELECT * FROM (SELECT a, GROUPING(a) g FROM t1 GROUP BY a WITH ROLLUP) dt WHERE dt.g=1;
2da9b58 to
14d4b56
Compare
MDEV-22269: Add support for the GROUPING() function (SQL:2008 feature T431).