test(query): lock GROUP BY survival in MySQL pagination and count SQL

Refs: #7832
This commit is contained in:
t8y2 committed 2026-09-06 13:01:37 +08:00
1 parent 450d9fb9ee
commit c0b4fa09cc
2 files changed
+87

No files matched your search

@@ -353,6 +353,38 @@ describe("splitSqlStatementRanges", () => {
expect(rangeSqlTexts(splitSqlStatementRanges(sql))).toEqual(["SELECT 1", "SELECT 2", "SELECT 3"]);
});
// Issue #7832 shape: MySQL GROUP BY over a LEFT JOIN with an aggregated
// derived table, COUNT(DISTINCT IF(...)) in the projection, and inline
// `-- 中文` line comments. The splitter must keep it a single statement and
// cursor-statement extraction must always include the trailing GROUP BY, so
// the executed SQL keeps the query's row cardinality.
it("keeps a commented MySQL GROUP BY query as one statement including the GROUP BY (issue #7832)", () => {
const sql = [
"SELECT",
" base.brand_name",
" ,base.stall_id",
" ,base.floor",
" ,COUNT(1) total_invite -- 邀约数量",
" ,SUM(IFNULL(base.ver_status, 0)) sign_num -- 签到数量",
" ,SUM(IFNULL(dr.draw_count, 0)) draw_num -- 抽奖次数",
" ,SUM(IFNULL(dr.draw_user_num, 0)) draw_user_num -- 抽奖人数",
" ,COUNT(distinct IF(base.ver_status = 1, base.mobile, null)) sign_and_draw_user_num",
"FROM v_form_data_1786326962 base",
"LEFT JOIN (",
" SELECT id, SUM(IFNULL(hx_status, 0)) draw_count, COUNT(distinct IF(hx_status = 1, mobile, null)) draw_user_num",
" FROM v_form_data_1786326962_coupon",
" GROUP BY id",
") dr ON base.id = dr.id",
"GROUP BY base.brand_name, base.stall_id, base.floor",
].join("\n");
const ranges = splitSqlStatementRanges(sql, "mysql");
expect(rangeSqlTexts(ranges)).toEqual([sql.trim()]);
for (const position of [0, indexOf(sql, "total_invite"), indexOf(sql, "sign_and_draw_user_num"), sql.indexOf("GROUP BY") + 5, sql.length - 1]) {
const range = statementRangeAtCursor(sql, position, "mysql");
expect(range?.sql).toContain("GROUP BY base.brand_name, base.stall_id, base.floor");
}
});
it("keeps a trailing statement without a semicolon", () => {
const sql = "SELECT 1;\nSELECT 2";
const ranges = splitSqlStatementRanges(sql);