From 6ecec6458849fa444ce99cada9a6bfd69210f2a7 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Fri, 26 Jun 2026 00:25:19 +0800 Subject: [PATCH] fix(editor): keep order/group column suggestions active --- apps/desktop/src/lib/sqlCompletion.ts | 2 ++ packages/app-tests/sqlCompletion.test.ts | 44 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/apps/desktop/src/lib/sqlCompletion.ts b/apps/desktop/src/lib/sqlCompletion.ts index 86538dbfd..a7eaf71f6 100644 --- a/apps/desktop/src/lib/sqlCompletion.ts +++ b/apps/desktop/src/lib/sqlCompletion.ts @@ -1716,6 +1716,7 @@ function isInColumnContext(beforeCursor: string): boolean { if (!beforeCursor) return false; if (isInSelectListContext(beforeCursor)) return true; + if (isInOrderOrGroupByContext(beforeCursor)) return true; // Strip string literals const cleaned = beforeCursor.replace(/'[^']*'/g, "''").replace(/"[^"]*"/g, "''"); @@ -2747,6 +2748,7 @@ function isFollowedByJoin(beforeToken: string): boolean { } function isInTableListContext(beforeToken: string): boolean { + if (isInOrderOrGroupByContext(beforeToken)) return false; return /,\s*$/.test(beforeToken) && /\b(?:from|join|update|into)\b/i.test(beforeToken); } diff --git a/packages/app-tests/sqlCompletion.test.ts b/packages/app-tests/sqlCompletion.test.ts index e798753c6..24aa6b68f 100644 --- a/packages/app-tests/sqlCompletion.test.ts +++ b/packages/app-tests/sqlCompletion.test.ts @@ -1890,6 +1890,50 @@ test("suggests columns after multiple select-list expressions", () => { assert.ok(!items.some((item) => item.type === "function" && item.label.startsWith("proc_"))); }); +test("suggests columns after multiple group by expressions", () => { + const sql = "select project_name, count(*) from ypmng_archive group by project_name, review"; + const cursor = sql.length; + const items = buildSqlCompletionItems(sql, cursor, { + tables: [{ name: "ypmng_archive", type: "table" }], + objects: [{ name: "proc_get_ypfmm_pd_score_list_with_template_doc_id", schema: "y_jnpf", type: "procedure" }], + columnsByTable: new Map([ + [ + "ypmng_archive", + [ + { name: "doc_id", table: "ypmng_archive", dataType: "bigint" }, + { name: "project_name", table: "ypmng_archive", dataType: "varchar" }, + { name: "review_accountant", table: "ypmng_archive", dataType: "varchar" }, + ], + ], + ]), + }); + + assert.ok(items.some((item) => item.label === "review_accountant" && item.type === "column")); + assert.ok(!items.some((item) => item.type === "function" && item.label.startsWith("proc_"))); +}); + +test("suggests columns after multiple order by expressions", () => { + const sql = "select project_name, review_accountant, doc_id from ypmng_archive order by project_name, review"; + const cursor = sql.length; + const items = buildSqlCompletionItems(sql, cursor, { + tables: [{ name: "ypmng_archive", type: "table" }], + objects: [{ name: "proc_get_ypfmm_pd_score_list_with_template_doc_id", schema: "y_jnpf", type: "procedure" }], + columnsByTable: new Map([ + [ + "ypmng_archive", + [ + { name: "doc_id", table: "ypmng_archive", dataType: "bigint" }, + { name: "project_name", table: "ypmng_archive", dataType: "varchar" }, + { name: "review_accountant", table: "ypmng_archive", dataType: "varchar" }, + ], + ], + ]), + }); + + assert.ok(items.some((item) => item.label === "review_accountant" && item.type === "column")); + assert.ok(!items.some((item) => item.type === "function" && item.label.startsWith("proc_"))); +}); + // --- Type-aware comparison hints --- test("suggests NULL and IS NULL after comparison operator", () => {