fix(editor): complete columns through table names
This commit is contained in:
parent
87ef514188
commit
62aeae5de4
|
|
@ -204,6 +204,19 @@ describe("semantic SQL completion candidates", () => {
|
|||
expect(items.filter((item) => item.type === "column").map((item) => item.label)).toEqual(["id", "name", "email"]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["table name", "SELECT orders.| FROM orders"],
|
||||
["schema-qualified table name", "SELECT public.orders.| FROM public.orders"],
|
||||
] as const)("completes PostgreSQL columns through a %s qualifier", (_label, markedSql) => {
|
||||
const columnsByTable = new Map<string, SqlCompletionColumn[]>([["orders", ["id", "customer_name", "total_amount"].map((name) => ({ name, table: "orders", schema: "public" }))]]);
|
||||
|
||||
const { context, items } = semanticCompletion(markedSql, { columnsByTable }, { databaseType: "postgres", dialect: "postgres" });
|
||||
|
||||
expect(context.contextKind).toBe("alias_column");
|
||||
expect(context.exclusiveColumnSuggestions).toBe(true);
|
||||
expect(items.filter((item) => item.type === "column").map((item) => item.label)).toEqual(["id", "customer_name", "total_amount"]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["PostgreSQL", "postgres", "postgres"],
|
||||
["SQL Server", "sqlserver", "sqlserver"],
|
||||
|
|
|
|||
|
|
@ -80,6 +80,17 @@ describe("sqlSemanticModel baseline fixtures", () => {
|
|||
expect(model.cursorIntent).toEqual(expect.objectContaining({ kind: "alias_column", qualifierParts: ["b"] }));
|
||||
});
|
||||
|
||||
it.each([
|
||||
["table name", "SELECT orders.| FROM orders", ["orders"]],
|
||||
["schema-qualified table name", "SELECT public.orders.| FROM public.orders", ["public", "orders"]],
|
||||
] as const)("resolves columns through a PostgreSQL %s qualifier before FROM", (_label, markedSql, qualifierParts) => {
|
||||
const { sql, cursor } = sqlFixtureCursor(markedSql);
|
||||
const model = buildSqlSemanticModel(sql, cursor, { databaseType: "postgres", dialect: "postgres" });
|
||||
|
||||
expect(model.rowSources).toEqual(expect.arrayContaining([expect.objectContaining({ name: "orders", alias: undefined })]));
|
||||
expect(model.cursorIntent).toEqual(expect.objectContaining({ kind: "alias_column", qualifierParts, targetSourceId: model.rowSources[0]?.id }));
|
||||
});
|
||||
|
||||
it("keeps nested EXISTS sources and outer correlated sources visible", () => {
|
||||
const { sql, cursor } = sqlFixtureCursor("SELECT * FROM aa.tb t WHERE EXISTS (SELECT 1 FROM aa.tb1 t1, aa.tb2 t2 WHERE t1.|)");
|
||||
const model = buildSqlSemanticModel(sql, cursor, { databaseType: "mysql", dialect: "mysql" });
|
||||
|
|
|
|||
|
|
@ -713,7 +713,7 @@ function buildCursorIntent(tokens: readonly SqlSemanticToken[], cursor: number,
|
|||
TABLE_INTRODUCERS.has(previous) ||
|
||||
TABLE_INTRODUCERS.has(wordBeforeReplacement) ||
|
||||
TABLE_INTRODUCERS.has(wordBeforeTrailing) ||
|
||||
(!!targetSource && !targetSource.alias && trailing.replacementRange.start <= targetSource.sourceSpan.end + 1 && TABLE_INTRODUCERS.has(wordBeforePosition(tokens, targetSource.sourceSpan.start))))
|
||||
(!!targetSource && !targetSource.alias && trailing.replacementRange.start >= targetSource.sourceSpan.start && trailing.replacementRange.start <= targetSource.sourceSpan.end + 1 && TABLE_INTRODUCERS.has(wordBeforePosition(tokens, targetSource.sourceSpan.start))))
|
||||
) {
|
||||
const role = dialect.qualifierRole(trailing.qualifierParts, "table");
|
||||
return { kind: role === "catalog" ? "catalog" : "table", prefix: trailing.prefix, replacementRange: trailing.replacementRange, qualifierParts: trailing.qualifierParts, expectedObjectKinds: ["table", "view"], confidence: "medium" };
|
||||
|
|
|
|||
Loading…
Reference in New Issue