feat(query): support editing without selected primary keys

This commit is contained in:
zipg authored and GitHub committed 2026-07-10 18:57:37 +08:00
1 parent 7b47c81ad7
commit c35e5c560a
11 files changed
+935 -88

No files matched your search

@@ -0,0 +1,98 @@
import { describe, expect, it } from "vitest";
import { buildQueryWithHiddenPrimaryKeys, hiddenResultColumnIndexes } from "@/lib/sql/editableQueryHiddenKeys";
import { analyzeEditableQueryEditability } from "@/lib/sql/sqlAnalysis";
describe("editable query hidden primary keys", () => {
it("appends quoted MySQL primary keys without changing the visible projection", () => {
expect(
buildQueryWithHiddenPrimaryKeys({
sql: "SELECT name FROM users WHERE active = 1",
databaseType: "mysql",
primaryKeys: ["id"],
existingResultNames: ["name"],
}),
).toEqual({
sql: "SELECT name, `id` AS `__DBX_PK_0` FROM users WHERE active = 1",
projections: [{ sourceName: "id", alias: "__DBX_PK_0" }],
});
});
it("supports PostgreSQL composite primary keys and avoids alias collisions", () => {
const result = buildQueryWithHiddenPrimaryKeys({
sql: 'SELECT "value"\nFROM "items"',
databaseType: "postgres",
primaryKeys: ["tenant_id", "item_id"],
existingResultNames: ["value", "__DBX_PK_0"],
});
expect(result?.sql).toBe('SELECT "value", "tenant_id" AS "__DBX_PK_1", "item_id" AS "__DBX_PK_2"\nFROM "items"');
expect(result?.projections.map((projection) => projection.alias)).toEqual(["__DBX_PK_1", "__DBX_PK_2"]);
});
it("preserves SQL Server TOP and Oracle optimizer hints", () => {
expect(
buildQueryWithHiddenPrimaryKeys({
sql: "SELECT TOP 10 name FROM dbo.users ORDER BY name",
databaseType: "sqlserver",
primaryKeys: ["id"],
existingResultNames: ["name"],
})?.sql,
).toBe("SELECT TOP 10 name, [id] AS [__DBX_PK_0] FROM dbo.users ORDER BY name");
expect(
buildQueryWithHiddenPrimaryKeys({
sql: "SELECT /*+ INDEX(t IDX_USERS_NAME) */ t.NAME\nFROM USERS t",
databaseType: "oracle",
primaryKeys: ["ID"],
existingResultNames: ["NAME"],
})?.sql,
).toBe('SELECT /*+ INDEX(t IDX_USERS_NAME) */ t.NAME, "ID" AS "__DBX_PK_0"\nFROM USERS t');
});
it("inserts hidden keys before a trailing line comment", () => {
expect(
buildQueryWithHiddenPrimaryKeys({
sql: "SELECT name -- visible user name\nFROM users",
databaseType: "mysql",
primaryKeys: ["id"],
existingResultNames: ["name"],
})?.sql,
).toBe("SELECT name, `id` AS `__DBX_PK_0` -- visible user name\nFROM users");
});
it("analyzes SQL Server TOP projections as ordinary source columns", () => {
for (const sql of [
"SELECT TOP 2 name, note FROM dbo.users ORDER BY name",
"SELECT TOP(2) name, note FROM dbo.users ORDER BY name",
"SELECT TOP (2) name, note FROM dbo.users ORDER BY name",
"SELECT TOP 10 PERCENT name, note FROM dbo.users ORDER BY name",
"SELECT TOP (2) WITH TIES name, note FROM dbo.users ORDER BY name",
]) {
const result = analyzeEditableQueryEditability(sql);
expect(result.editable, sql).toBe(true);
if (result.editable) expect(result.analysis.columns.map((column) => column.sourceName)).toEqual(["name", "note"]);
}
});
it("resolves appended aliases to result indexes", () => {
expect(
hiddenResultColumnIndexes(
["name", "__DBX_PK_0", "__DBX_PK_1"],
[
{ sourceName: "tenant_id", alias: "__DBX_PK_0" },
{ sourceName: "item_id", alias: "__DBX_PK_1" },
],
),
).toEqual([1, 2]);
expect(hiddenResultColumnIndexes(["name"], [{ sourceName: "id", alias: "__DBX_PK_0" }])).toEqual([]);
expect(
hiddenResultColumnIndexes(
["name", "__DBX_PK_1"],
[
{ sourceName: "tenant_id", alias: "__DBX_PK_0" },
{ sourceName: "item_id", alias: "__DBX_PK_1" },
],
),
).toEqual([1]);
});
});