From c63a37358a123df1f77bbaf9d29a5a1bee8e8271 Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Thu, 18 Jun 2026 06:51:49 -0700 Subject: [PATCH 1/2] fix(tests): disambiguate EtcdFilterType.none in EtcdQueryBuilderTests `parsed?.filterType == .none` resolves `.none` to `Optional.none` under the current Swift toolchain, which (a) trips the warnings-as-errors build of the test target and (b) compares filterType against nil rather than the intended `EtcdFilterType.none` case. Since each call site already asserts `parsed != nil`, spell out `EtcdFilterType.none` so the assertion checks the enum case it means to. --- TableProTests/Plugins/EtcdQueryBuilderTests.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TableProTests/Plugins/EtcdQueryBuilderTests.swift b/TableProTests/Plugins/EtcdQueryBuilderTests.swift index c3001c222..4fadfd6d6 100644 --- a/TableProTests/Plugins/EtcdQueryBuilderTests.swift +++ b/TableProTests/Plugins/EtcdQueryBuilderTests.swift @@ -23,7 +23,7 @@ struct EtcdQueryBuilderBrowseTests { #expect(parsed?.limit == 100) #expect(parsed?.offset == 0) #expect(parsed?.sortAscending == true) - #expect(parsed?.filterType == .none) + #expect(parsed?.filterType == EtcdFilterType.none) #expect(parsed?.filterValue == "") } @@ -191,7 +191,7 @@ struct EtcdQueryBuilderFilteredTests { ) #expect(query != nil) let parsed = EtcdQueryBuilder.parseRangeQuery(query!) - #expect(parsed?.filterType == .none) + #expect(parsed?.filterType == EtcdFilterType.none) } } @@ -262,7 +262,7 @@ struct EtcdQueryBuilderCountTests { let parsed = EtcdQueryBuilder.parseCountQuery(query) #expect(parsed != nil) #expect(parsed?.prefix == "/myprefix/") - #expect(parsed?.filterType == .none) + #expect(parsed?.filterType == EtcdFilterType.none) #expect(parsed?.filterValue == "") } @@ -322,7 +322,7 @@ struct EtcdQueryBuilderTagTests { #expect(parsed?.limit == 42) #expect(parsed?.offset == 7) #expect(parsed?.sortAscending == false) - #expect(parsed?.filterType == .none) + #expect(parsed?.filterType == EtcdFilterType.none) #expect(parsed?.filterValue == "") } From 10bf73edcb0273a151fbe54a0b3de2ed5f54f1ed Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Fri, 19 Jun 2026 00:07:59 +0700 Subject: [PATCH 2/2] fix(editor): unquote backtick aliases and keep aliased CTE columns in autocomplete --- TablePro/Core/Autocomplete/DerivedTableParser.swift | 4 ++-- TablePro/Core/Autocomplete/SQLContextAnalyzer.swift | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/TablePro/Core/Autocomplete/DerivedTableParser.swift b/TablePro/Core/Autocomplete/DerivedTableParser.swift index 9eba0cad4..fec55b86b 100644 --- a/TablePro/Core/Autocomplete/DerivedTableParser.swift +++ b/TablePro/Core/Autocomplete/DerivedTableParser.swift @@ -263,8 +263,8 @@ internal struct DerivedTableParser { let c = ns.character(at: index) if c == Self.backtick || c == Self.doubleQuote { let end = matchingQuote(in: ns, from: index, limit: limit, quote: c) - guard end > index + 1 else { return nil } - return ns.substring(with: NSRange(location: index + 1, length: end - index - 1)) + guard end > index + 2 else { return nil } + return ns.substring(with: NSRange(location: index + 1, length: end - index - 2)) } if c == Self.openBracket { var j = index + 1 diff --git a/TablePro/Core/Autocomplete/SQLContextAnalyzer.swift b/TablePro/Core/Autocomplete/SQLContextAnalyzer.swift index 4043148cf..499e73c19 100644 --- a/TablePro/Core/Autocomplete/SQLContextAnalyzer.swift +++ b/TablePro/Core/Autocomplete/SQLContextAnalyzer.swift @@ -790,8 +790,9 @@ final class SQLContextAnalyzer { } /// Attach derived-table columns to references and add any derived table or - /// CTE not already in scope. A derived alias wins over a plain reference of - /// the same identifier (e.g. a CTE used directly in a FROM clause). + /// CTE not already in scope. Columns attach to a matching reference (e.g. a + /// CTE aliased in a FROM clause), and the derived table or CTE is still + /// registered under its own name so it resolves by either identifier. private func mergeDerivedTables( _ derivedTables: [DerivedTable], cteNames: [String], @@ -802,12 +803,10 @@ final class SQLContextAnalyzer { uniquingKeysWith: { first, _ in first } ) - var consumed = Set() for index in references.indices { let ref = references[index] for key in [ref.tableName.lowercased(), ref.identifier.lowercased()] { guard let columns = derivedColumnsByAlias[key] else { continue } - consumed.insert(key) references[index] = TableReference( tableName: ref.tableName, alias: ref.alias, schema: ref.schema, derivedColumns: columns ) @@ -815,7 +814,7 @@ final class SQLContextAnalyzer { } } - var present = Set(references.map { $0.identifier.lowercased() }).union(consumed) + var present = Set(references.map { $0.identifier.lowercased() }) for derived in derivedTables where present.insert(derived.alias.lowercased()).inserted { references.append( TableReference(tableName: derived.alias, alias: derived.alias, derivedColumns: derived.columns)