Repository navigation
feat(search): find a value in every table of a database - #3737
Conversation
… Server, use ANSI dates on Oracle
…ase where collation decides
…base # Conflicts: # apple/TablePro/Core/Utilities/SQL/ColumnTypeSQLQuoting.swift # apple/TablePro/Resources/Localizable.xcstrings
…base # Conflicts: # apple/TablePro/Views/Main/MainContentCoordinator.swift
J2TeamNNL
left a comment
There was a problem hiding this comment.
Code review: 7 findings, inline.
| guard characters.count == 10 else { return false } | ||
| return isCalendarDate(characters) | ||
| } | ||
|
|
There was a problem hiding this comment.
isDateTime accepts 1 to 9 fractional digits and a space separator for every engine. SQL Server datetime rejects more than 3 fractional digits and reads the space form by session language. Searching 2024-01-05 10:00:00.1234567 would fail the whole table query, so no column of that table gets searched.
| } | ||
|
|
||
| // MARK: - Catalog | ||
|
|
There was a problem hiding this comment.
loadTablesIfNeeded returns once the catalog is loaded, and the coordinator caches the session. After a table is dropped or created, reopening the sheet shows the old list: new tables are never searched and dropped ones come back as failed.
| let namespaces = try await ObjectCopyCatalog(manager: manager).namespaces(of: endpoint, connection: connection) | ||
| let systemSchemas = Set(PluginManager.shared.systemSchemaNames(for: connection.type)) | ||
| var found: [DatabaseSearchTarget] = [] | ||
| for namespace in namespaces { |
There was a problem hiding this comment.
tables() throws on the first schema whose fetchTables fails (no USAGE privilege, broken synonym). The catalog becomes failed and no table in any other schema can be searched.
| case .null: | ||
| return false | ||
| case .bytes(let data): | ||
| return data.contains { $0 != 0 } |
There was a problem hiding this comment.
isSet treats any non-zero byte in .bytes as set. A driver that returns the flag 0 as ASCII 0 (0x30) makes every column look matched, so the tab filters on columns that do not match.
| ) | ||
| databaseSearchSession = session | ||
| return session | ||
| } |
There was a problem hiding this comment.
openDatabaseSearchResult always calls session.stop(). Double-clicking a result while the search runs cancels the remaining tables, though the footer Open button is hidden during a run.
| ? String(format: String(localized: "%@ row"), count) | ||
| : String(format: String(localized: "%@ rows"), count) | ||
| } | ||
|
|
There was a problem hiding this comment.
The '%1$@ of %2$@ tables' formatting is duplicated in DatabaseSearchSummary.progress and DatabaseSearchSession.selectionSummary. A change to one leaves the other behind.
| guard characters.count >= 19, characters[10] == " " || characters[10] == "T", | ||
| [11, 12, 14, 15, 17, 18].allSatisfy(isDigit), characters[13] == ":", characters[16] == ":" | ||
| else { return nil } | ||
| let fraction = characters.dropFirst(19) |
There was a problem hiding this comment.
oracleTemporalLiteral turns every ANSI-shaped value on an Oracle date column into DATE '...', so = 2024-01-05 matches only midnight rows. This also changes the existing filter bar, not only search.
|
Follow-up on the review above. Fixed in J2TeamNNL@f0f5b53:
Skipped:
Checks: none run. SwiftLint fails here (sourcekitd missing) and there is no local Xcode build. Cherry-pick: |
Summary
=. Binary only when ticked. A column joins only where the engine can compare it, since one bad predicate fails the table.SELECTper table on a pooled, cancellable read with the connection's query timeout: aCASE WHENflag per searched column, conditions fromFilterSQLGenerator, at most 1,001 rows throughSQLRowLimitClause.FilterSQLGenerator, also used by the filter bar and row counts:REGEXP_LIKE(col, '(?i)…'); itsREGEXP_LIKEtakes two arguments. The five pinned Trino cases inFilterSQLGeneratorCaseSensitivityTestsare updated.[in a LIKE value is escaped.DATE/TIMESTAMPliterals instead of strings read throughNLS_DATE_FORMAT.ColumnTypeSQLQuoting.hasEqualityOperatortakes the engine family: SQL ServerTEXThas no=. The cell Filter menu passes it, so it no longer offers=on such a column.Test plan
DatabaseSearchColumnPlannerTests: which columns join per type, mode and engine family.DatabaseSearchQueryTests: flags, OR, cap + 1 on LIMIT and OFFSET/FETCH engines, escaping, cap reporting, the tab's filter state.DatabaseSearchSessionTests: preselection, order, a failing table, Stop at the next table, Edit Search fencing a late read.DatabaseSearchResultOpeningTests: the payload a result opens, and the session kept per scope.FilterSQLGeneratorColumnTypeTests,FilterSQLGeneratorCaseSensitivityTests,CellFilterMenuBuilderTests: the generator and equality fixes.DatabaseTreeMenuSpecTests,MainMenuBuilderTests: the commands and their gates.SearchDatabaseUITests: on the fixture, search "brook", open the result, the artist tab shows only Brook.Fixes #3601