Skip to content

Commit 009c14b

Browse files
committed
fix: Don't include columns when completing FROM statements.
1 parent 3111377 commit 009c14b

2 files changed

Lines changed: 50 additions & 10 deletions

File tree

packages/server/src/complete/complete.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -255,20 +255,13 @@ class Completer {
255255
this.addCandidatesForExpectedLiterals(expectedLiteralNodes)
256256
this.addCandidatesForFunctions()
257257

258-
const { addedSome: addedSomeScopedColumnCandidates } =
259-
this.addCandidatesForScopedColumns(fromNodes, schemaAndSubqueries)
260-
if (!addedSomeScopedColumnCandidates) {
261-
this.addCandidatesForUnscopedColumns(fromNodes, schemaAndSubqueries)
262-
}
263-
264-
this.addCandidatesForAliases(fromNodes)
265-
258+
// Detect FROM clause context BEFORE adding column suggestions
266259
const fromNodesContainingCursor = fromNodes.filter((tableNode) =>
267260
isPosInLocation(tableNode.location, this.pos)
268261
)
269262
const isCursorInsideFromClause = fromNodesContainingCursor.length > 0
270263

271-
// Check if cursor is right after FROM keyword (no table typed yet)
264+
// Check if cursor is right after FROM keyword or typing a table name
272265
const afterFromClause = parsedFromClause.after?.trim().toUpperCase() || ''
273266
const isCursorAfterFromKeyword =
274267
afterFromClause === 'FROM' ||
@@ -277,7 +270,20 @@ class Completer {
277270
afterFromClause
278271
)
279272

280-
if (isCursorInsideFromClause || isCursorAfterFromKeyword) {
273+
const isTypingTableName = isCursorInsideFromClause || isCursorAfterFromKeyword
274+
275+
// Only add column suggestions if NOT typing a table name in FROM clause
276+
if (!isTypingTableName) {
277+
const { addedSome: addedSomeScopedColumnCandidates } =
278+
this.addCandidatesForScopedColumns(fromNodes, schemaAndSubqueries)
279+
if (!addedSomeScopedColumnCandidates) {
280+
this.addCandidatesForUnscopedColumns(fromNodes, schemaAndSubqueries)
281+
}
282+
}
283+
284+
this.addCandidatesForAliases(fromNodes)
285+
286+
if (isTypingTableName) {
281287
// add table candidates if the cursor is inside a FROM clause, JOIN clause,
282288
// or right after FROM/JOIN keyword waiting for a table name
283289
this.addCandidatesForTables(schemaAndSubqueries, true)

packages/server/test/complete/complete_table.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,38 @@ describe('TableName completion', () => {
112112
]
113113
expect(result.candidates).toEqual(expect.arrayContaining(expected))
114114
})
115+
116+
test('complete table name after FROM keyword with partial input', () => {
117+
const schema = {
118+
tables: [
119+
{
120+
catalog: null,
121+
database: null,
122+
tableName: 'notes',
123+
columns: [{ columnName: 'id', description: '' }],
124+
},
125+
{
126+
catalog: null,
127+
database: null,
128+
tableName: 'users',
129+
columns: [{ columnName: 'name', description: '' }],
130+
},
131+
],
132+
functions: [],
133+
}
134+
135+
const result = complete('SELECT * FROM not', { line: 0, column: 17 }, schema)
136+
137+
// Should suggest table names, not columns
138+
expect(result.candidates).toEqual(
139+
expect.arrayContaining([expect.objectContaining({ label: 'notes' })])
140+
)
141+
// Should NOT include column suggestions
142+
expect(result.candidates).not.toEqual(
143+
expect.arrayContaining([expect.objectContaining({ label: 'id' })])
144+
)
145+
expect(result.candidates).not.toEqual(
146+
expect.arrayContaining([expect.objectContaining({ label: 'name' })])
147+
)
148+
})
115149
})

0 commit comments

Comments
 (0)